feat(platform): diagnose source consistency

This commit is contained in:
lingniu
2026-07-04 04:12:23 +08:00
parent 7b801b6f71
commit e077d99a5e
9 changed files with 104 additions and 5 deletions

View File

@@ -251,6 +251,12 @@ func TestHandlerVehicleServiceIncludesSourceConsistency(t *testing.T) {
if consistency.MileageDeltaKm <= 0 || consistency.SourceTimeDeltaSeconds <= 0 {
t.Fatalf("sourceConsistency should expose mileage and source time deltas, got %+v", consistency)
}
if consistency.Status == "" || consistency.Severity == "" || consistency.Title == "" || consistency.Detail == "" {
t.Fatalf("sourceConsistency should expose actionable diagnosis, got %+v", consistency)
}
if consistency.Status != "degraded" || consistency.Title != "部分来源离线" {
t.Fatalf("sourceConsistency should diagnose partial source health, got %+v", consistency)
}
}
func TestHandlerVehicleServiceOverviewEndpoint(t *testing.T) {
@@ -279,6 +285,9 @@ func TestHandlerVehicleServiceOverviewEndpoint(t *testing.T) {
if body.Data.SourceConsistency == nil || body.Data.SourceConsistency.SourceCount != 2 || body.Data.SourceConsistency.OnlineSourceCount != 1 {
t.Fatalf("overview endpoint should expose source consistency, got %+v", body.Data.SourceConsistency)
}
if body.Data.SourceConsistency.Status != "degraded" || body.Data.SourceConsistency.Title != "部分来源离线" {
t.Fatalf("overview source consistency should expose diagnosis, got %+v", body.Data.SourceConsistency)
}
if strings.Contains(rec.Body.String(), `"raw"`) || strings.Contains(rec.Body.String(), `"history"`) {
t.Fatalf("overview endpoint should not return heavy detail pages: %s", rec.Body.String())
}

View File

@@ -110,6 +110,10 @@ type VehicleSourceConsistency struct {
MileageDeltaKm float64 `json:"mileageDeltaKm"`
SourceTimeDeltaSeconds float64 `json:"sourceTimeDeltaSeconds"`
Scope string `json:"scope"`
Status string `json:"status"`
Severity string `json:"severity"`
Title string `json:"title"`
Detail string `json:"detail"`
}
type VehicleServiceOverview struct {

View File

@@ -376,9 +376,53 @@ func buildVehicleSourceConsistency(statuses []VehicleSourceStatus, realtime []Re
if hasTime {
consistency.SourceTimeDeltaSeconds = maxTime.Sub(minTime).Seconds()
}
applyVehicleSourceConsistencyDiagnosis(consistency)
return consistency
}
func applyVehicleSourceConsistencyDiagnosis(consistency *VehicleSourceConsistency) {
if consistency == nil {
return
}
switch {
case consistency.SourceCount <= 0:
consistency.Status = "no_source"
consistency.Severity = "warning"
consistency.Title = "暂无来源"
consistency.Detail = "当前车辆没有可用于交叉校验的数据来源。"
case consistency.SourceCount == 1:
consistency.Status = "single_source"
consistency.Severity = "warning"
consistency.Title = "单一来源"
consistency.Detail = "当前车辆只有一个数据来源,无法做跨来源一致性校验。"
case consistency.OnlineSourceCount <= 0:
consistency.Status = "offline"
consistency.Severity = "error"
consistency.Title = "全部来源离线"
consistency.Detail = sourceCoverageDetail(consistency.SourceCount, consistency.OnlineSourceCount, "无法判断实时一致性。")
case consistency.OnlineSourceCount < consistency.SourceCount:
consistency.Status = "degraded"
consistency.Severity = "warning"
consistency.Title = "部分来源离线"
consistency.Detail = sourceCoverageDetail(consistency.SourceCount, consistency.OnlineSourceCount, "车辆服务可用但需要关注离线来源。")
case consistency.MileageDeltaKm > 5:
consistency.Status = "mileage_divergent"
consistency.Severity = "warning"
consistency.Title = "里程差异偏大"
consistency.Detail = "多个来源的实时总里程差异超过 5 km请核对来源解析、单位和上报时间。"
case consistency.SourceTimeDeltaSeconds > 300:
consistency.Status = "time_divergent"
consistency.Severity = "warning"
consistency.Title = "来源时间差偏大"
consistency.Detail = "多个来源的最新上报时间相差超过 5 分钟,请关注转发延迟或链路断点。"
default:
consistency.Status = "consistent"
consistency.Severity = "ok"
consistency.Title = "来源一致"
consistency.Detail = sourceCoverageDetail(consistency.SourceCount, consistency.OnlineSourceCount, "多源实时状态一致。")
}
}
func parseVehicleServiceTime(value string) (time.Time, bool) {
value = strings.TrimSpace(value)
if value == "" {
@@ -477,6 +521,7 @@ func applyVehicleServiceOverviewDerivedFields(overview *VehicleServiceOverview,
OnlineSourceCount: overview.OnlineSourceCount,
Scope: "all_sources",
}
applyVehicleSourceConsistencyDiagnosis(overview.SourceConsistency)
}
func statusesForOverview(overview *VehicleServiceOverview) []VehicleSourceStatus {