From 40b55600c7fc3a28d33b48f370973bc6e360c797 Mon Sep 17 00:00:00 2001 From: lingniu Date: Sat, 4 Jul 2026 04:28:27 +0800 Subject: [PATCH] feat(platform): include no-data service status --- .../apps/api/internal/platform/handler_test.go | 12 ++++++++++++ .../apps/api/internal/platform/mock_store.go | 10 +++++++++- .../apps/api/internal/platform/production_store.go | 2 ++ .../apps/web/src/api/client.test.ts | 6 +++++- 4 files changed, 28 insertions(+), 2 deletions(-) diff --git a/vehicle-data-platform/apps/api/internal/platform/handler_test.go b/vehicle-data-platform/apps/api/internal/platform/handler_test.go index 8fffa94c..2db1849b 100644 --- a/vehicle-data-platform/apps/api/internal/platform/handler_test.go +++ b/vehicle-data-platform/apps/api/internal/platform/handler_test.go @@ -326,6 +326,18 @@ func TestHandlerVehicleServiceSummaryEndpoint(t *testing.T) { if len(body.Data.ServiceStatuses) == 0 || len(body.Data.Protocols) == 0 { t.Fatalf("summary should expose service status and protocol distributions, got %+v", body.Data) } + noDataStatusFound := false + for _, status := range body.Data.ServiceStatuses { + if status.Status == "no_data" { + noDataStatusFound = true + if status.Title != "暂无数据来源" || status.Count != body.Data.NoDataVehicles { + t.Fatalf("no_data service status should mirror noDataVehicles, got status=%+v summary=%+v", status, body.Data) + } + } + } + if !noDataStatusFound { + t.Fatalf("summary service status distribution should include no_data, got %+v", body.Data.ServiceStatuses) + } } func TestHandlerVehicleServiceOverviewsEndpoint(t *testing.T) { diff --git a/vehicle-data-platform/apps/api/internal/platform/mock_store.go b/vehicle-data-platform/apps/api/internal/platform/mock_store.go index 6c318eb1..3e595596 100644 --- a/vehicle-data-platform/apps/api/internal/platform/mock_store.go +++ b/vehicle-data-platform/apps/api/internal/platform/mock_store.go @@ -180,7 +180,13 @@ func (m *MockStore) VehicleServiceSummary(ctx context.Context) (VehicleServiceSu ServiceStatuses: []ServiceStatusStat{}, Protocols: []ProtocolStat{}, } - statusCounts := map[string]*ServiceStatusStat{} + statusCounts := map[string]*ServiceStatusStat{ + "healthy": {Status: "healthy", Title: "服务正常"}, + "degraded": {Status: "degraded", Title: "部分来源离线"}, + "offline": {Status: "offline", Title: "车辆离线"}, + "no_data": {Status: "no_data", Title: "暂无数据来源"}, + "identity_required": {Status: "identity_required", Title: "身份未绑定"}, + } protocolCounts := map[string]*ProtocolStat{} for _, row := range coverage.Items { if row.BindingStatus == "bound" { @@ -678,6 +684,8 @@ func keepServiceStatus(status *VehicleServiceStatus, raw string) bool { return status != nil && status.Status == "identity_required" case "offline": return status != nil && status.Status == "offline" + case "no_data": + return status != nil && status.Status == "no_data" case "degraded": return status != nil && status.Status == "degraded" case "healthy": diff --git a/vehicle-data-platform/apps/api/internal/platform/production_store.go b/vehicle-data-platform/apps/api/internal/platform/production_store.go index 588110fa..8e0da362 100644 --- a/vehicle-data-platform/apps/api/internal/platform/production_store.go +++ b/vehicle-data-platform/apps/api/internal/platform/production_store.go @@ -79,6 +79,7 @@ func (s *ProductionStore) serviceStatusStats(ctx context.Context) ([]ServiceStat {Status: "healthy", Title: "服务正常"}, {Status: "degraded", Title: "部分来源离线"}, {Status: "offline", Title: "车辆离线"}, + {Status: "no_data", Title: "暂无数据来源"}, {Status: "identity_required", Title: "身份未绑定"}, } out := make([]ServiceStatusStat, 0, len(definitions)) @@ -150,6 +151,7 @@ GROUP BY v.vin {Status: "healthy", Title: "服务正常", Count: healthy}, {Status: "degraded", Title: "部分来源离线", Count: degraded}, {Status: "offline", Title: "车辆离线", Count: offline}, + {Status: "no_data", Title: "暂无数据来源", Count: summary.NoDataVehicles}, {Status: "identity_required", Title: "身份未绑定", Count: summary.IdentityRequiredVehicles}, } protocols, err := s.protocolStats(ctx) diff --git a/vehicle-data-platform/apps/web/src/api/client.test.ts b/vehicle-data-platform/apps/web/src/api/client.test.ts index 85195388..5ec5aa48 100644 --- a/vehicle-data-platform/apps/web/src/api/client.test.ts +++ b/vehicle-data-platform/apps/web/src/api/client.test.ts @@ -153,7 +153,10 @@ test('vehicleServiceSummary reads the vehicle service summary endpoint', async ( multiSourceVehicles: 181, noDataVehicles: 461, identityRequiredVehicles: 9, - serviceStatuses: [{ status: 'healthy', title: '服务正常', count: 161 }], + serviceStatuses: [ + { status: 'healthy', title: '服务正常', count: 161 }, + { status: 'no_data', title: '暂无数据来源', count: 461 } + ], protocols: [{ protocol: 'JT808', online: 157, total: 388 }] }, traceId: 'trace-test', @@ -166,6 +169,7 @@ test('vehicleServiceSummary reads the vehicle service summary endpoint', async ( expect(fetchMock).toHaveBeenCalledWith('/api/vehicle-service/summary', undefined); expect(result.totalVehicles).toBe(1033); expect(result.multiSourceVehicles).toBe(181); + expect(result.serviceStatuses.find((item) => item.status === 'no_data')?.count).toBe(461); }); test('api errors include backend message, detail, and trace id', async () => {