diff --git a/vehicle-data-platform/apps/web/src/pages/Vehicles.tsx b/vehicle-data-platform/apps/web/src/pages/Vehicles.tsx index 986d54cb..595e3eca 100644 --- a/vehicle-data-platform/apps/web/src/pages/Vehicles.tsx +++ b/vehicle-data-platform/apps/web/src/pages/Vehicles.tsx @@ -34,6 +34,18 @@ function sourceEvidenceText(row: VehicleCoverageRow) { return `${row.onlineSourceCount}/${row.sourceCount} 来源在线`; } +function sourceDiagnosisText(row: VehicleCoverageRow) { + const parts = [sourceEvidenceText(row)]; + if ((row.missingProtocols ?? []).length > 0) { + parts.push(`缺 ${row.missingProtocols.join('、')}`); + } else if (row.sourceCount > 0) { + parts.push('来源完整'); + } else { + parts.push('暂无来源'); + } + return parts.join(','); +} + function sourceConsistencyAction(row: VehicleCoverageRow, onFilter: (filters: Record) => void) { const consistency = row.sourceConsistency; if (!consistency) { @@ -180,6 +192,7 @@ export function Vehicles({ width: 140, render: (_: unknown, row: VehicleCoverageRow) => sourceConsistencyAction(row, (nextFilters) => applyFilters({ ...filters, ...nextFilters })) }, + { title: '诊断摘要', width: 240, render: (_: unknown, row: VehicleCoverageRow) => sourceDiagnosisText(row) }, { title: '证据覆盖', width: 120, render: (_: unknown, row: VehicleCoverageRow) => sourceEvidenceText(row) }, { title: '在线', width: 90, render: (_: unknown, row: VehicleCoverageRow) => }, { title: '最后在线', dataIndex: 'lastSeen', width: 170 }, diff --git a/vehicle-data-platform/apps/web/src/test/App.test.tsx b/vehicle-data-platform/apps/web/src/test/App.test.tsx index ea864386..b67ca9e6 100644 --- a/vehicle-data-platform/apps/web/src/test/App.test.tsx +++ b/vehicle-data-platform/apps/web/src/test/App.test.tsx @@ -344,6 +344,7 @@ test('shows vehicle service result summary on vehicle list filters', async () => expect(screen.getByText('JT808 离线')).toBeInTheDocument(); expect(screen.getByText('YUTONG_MQTT 未接入')).toBeInTheDocument(); expect(screen.getByText('1/2 来源在线')).toBeInTheDocument(); + expect(screen.getByText('1/2 来源在线,缺 YUTONG_MQTT')).toBeInTheDocument(); }); test('filters vehicle list from result summary actions', async () => {