diff --git a/vehicle-data-platform/apps/web/src/pages/Dashboard.tsx b/vehicle-data-platform/apps/web/src/pages/Dashboard.tsx index 21dd2b19..d0cd7691 100644 --- a/vehicle-data-platform/apps/web/src/pages/Dashboard.tsx +++ b/vehicle-data-platform/apps/web/src/pages/Dashboard.tsx @@ -149,7 +149,7 @@ function priorityIssueNotificationText(row: QualityIssueRow) { `详情:${row.detail || '-'}`, `实时定位:${appURL(buildAppHash({ page: 'realtime', keyword: lookup.key, protocol: row.protocol }))}`, `轨迹证据:${appURL(buildAppHash({ page: 'history', keyword: filters.keyword, protocol: filters.protocol, filters }))}`, - `RAW证据:${appURL(buildAppHash({ page: 'history-query', keyword: rawFilters.keyword, protocol: rawFilters.protocol, filters: rawFilters }))}`, + `原始记录:${appURL(buildAppHash({ page: 'history-query', keyword: rawFilters.keyword, protocol: rawFilters.protocol, filters: rawFilters }))}`, `车辆服务:${appURL(buildAppHash({ page: 'detail', keyword: lookup.key, protocol: row.protocol }))}`, `告警筛选:${appURL(buildAppHash({ page: 'alert-events', protocol: row.protocol, filters: { issueType: row.issueType } }))}` ].join('\n'); @@ -169,7 +169,7 @@ function focusVehicleFromIssue(row: QualityIssueRow): FocusVehicleService { realtimeEvidence: `来源 ${qualityProtocolLabel(row.protocol)} / 最后 ${row.lastSeen || '-'}`, historyEvidence: filters.dateFrom ? `${filters.dateFrom} 至 ${filters.dateTo}` : '待确认时间窗', alertEvidence: row.detail || qualityIssueLabel(row.issueType), - statisticEvidence: '统计查询需回溯车辆口径', + statisticEvidence: '里程统计需回溯车辆口径', issueType: row.issueType }; } @@ -385,7 +385,7 @@ export function Dashboard({ { title: '历史数据导出', value: `${formatCount(summary?.frameToday)} 今日数据`, - detail: '按车辆、时间和字段裁剪查询历史位置与 RAW 证据。', + detail: '按车辆、时间和字段裁剪查询历史位置与原始记录。', action: '查询导出', onClick: () => onOpenHistory({ tab: 'raw', includeFields: 'true' }) } @@ -441,7 +441,7 @@ export function Dashboard({ title: '轨迹回放', status: `有效定位 ${formatCount(commandLocatedCount)}`, color: commandLocatedCount > 0 ? 'blue' as const : 'grey' as const, - description: '围绕车辆回放历史位置轨迹,结合高德线路和 RAW 证据定位异常。', + description: '围绕车辆回放历史位置轨迹,结合高德线路和原始记录定位异常。', action: '打开轨迹', onClick: () => onOpenHistory() }, @@ -449,7 +449,7 @@ export function Dashboard({ title: '历史数据查询', status: `今日帧 ${formatCount(summary?.frameToday)}`, color: 'blue' as const, - description: '查询位置历史、RAW 帧和解析字段,为车辆问题复盘提供证据链。', + description: '查询位置历史和原始记录字段,为车辆问题复盘提供依据。', action: '查询历史', onClick: () => onOpenHistory({ tab: 'raw' }) }, @@ -462,10 +462,10 @@ export function Dashboard({ onClick: () => onOpenQuality() }, { - title: '统计查询', + title: '里程统计', status: `统计车辆 ${formatCount(serviceSummary?.totalVehicles)}`, color: 'green' as const, - description: '提供里程等运营统计查询,保证区间总值与每日统计口径闭合。', + description: '提供里程等运营统计,保证区间总值与每日统计口径闭合。', action: '查看统计', onClick: () => onOpenMileage() } @@ -497,7 +497,7 @@ export function Dashboard({ title: '接入巡检', value: unhealthyLinkCount > 0 ? `${unhealthyLinkCount.toLocaleString()} 项关注` : '链路正常', color: unhealthyLinkCount > 0 ? 'orange' as const : 'green' as const, - detail: '检查平台转发、Kafka、Redis、MySQL、TDengine 等关键链路。', + detail: '检查平台转发、消息队列、缓存和存储等关键链路。', action: '查看告警', onClick: () => onOpenQuality() }, @@ -521,7 +521,7 @@ export function Dashboard({ title: '历史证据', value: `${formatCount(summary?.frameToday)} 帧`, color: 'blue' as const, - detail: '查询 RAW 帧和解析字段,形成可追溯的数据证据。', + detail: '查询原始记录和字段明细,形成可追溯的数据依据。', action: '历史查询', onClick: () => onOpenHistory({ tab: 'raw' }) }, @@ -538,7 +538,7 @@ export function Dashboard({ value: `${formatCount(serviceSummary?.totalVehicles)} 车辆`, color: 'green' as const, detail: '核对里程统计口径,保证区间统计和每日统计闭合。', - action: '统计查询', + action: '里程统计', onClick: () => onOpenMileage() } ]; @@ -579,7 +579,7 @@ export function Dashboard({ { title: '轨迹回放', value: `${formatCount(summary?.activeToday)} 今日活跃`, - detail: '按车辆和时间窗回放历史位置,支持打开高德线路和 RAW 证据。', + detail: '按车辆和时间窗回放历史位置,支持打开高德线路和原始记录。', action: '轨迹回放', onClick: () => onOpenHistory() }, @@ -618,7 +618,7 @@ export function Dashboard({ detail: '按车辆回看位置、速度、里程和断点,用于定位异常复盘。', actions: [ { label: '打开轨迹回放', onClick: () => onOpenHistory() }, - { label: '查 RAW 证据', onClick: () => onOpenHistory({ tab: 'raw', includeFields: 'true' }) } + { label: '查原始记录', onClick: () => onOpenHistory({ tab: 'raw', includeFields: 'true' }) } ] }, { @@ -626,7 +626,7 @@ export function Dashboard({ value: `${formatCount(summary?.frameToday)} 今日帧`, meta: '字段裁剪与导出', color: 'blue' as const, - detail: '查询位置历史、RAW 帧和解析字段,为车辆服务提供可追溯证据。', + detail: '查询位置历史、原始记录和字段明细,为车辆服务提供可追溯依据。', actions: [ { label: '查询历史数据', onClick: () => onOpenHistory({ tab: 'location' }) }, { label: '查询解析字段', onClick: () => onOpenHistory({ tab: 'raw', includeFields: 'true' }) } @@ -644,13 +644,13 @@ export function Dashboard({ ] }, { - title: '统计查询', + title: '里程统计', value: `${formatCount(serviceSummary?.totalVehicles)} 车辆口径`, meta: '区间闭合复核', color: 'green' as const, - detail: '里程等指标先按车辆口径闭合,再回溯轨迹和 RAW 证据。', + detail: '里程等指标先按车辆口径闭合,再回溯轨迹和原始记录。', actions: [ - { label: '打开统计查询', onClick: () => onOpenMileage() }, + { label: '打开里程统计', onClick: () => onOpenMileage() }, { label: '查看车辆中心', onClick: () => onOpenVehicles({}) } ] } @@ -707,7 +707,7 @@ export function Dashboard({ owner: '告警 / 统计', evidence: `告警 ${formatCount(summary?.issueVehicles)},统计车辆 ${formatCount(serviceSummary?.totalVehicles)}`, detail: '断链、缺字段、里程异常和离线时长进入通知、统计和复核工作流。', - action: '统计查询', + action: '里程统计', onClick: () => onOpenMileage() } ]; @@ -728,13 +728,13 @@ export function Dashboard({ evidence: `高德轨迹底座 / 今日活跃 ${formatCount(summary?.activeToday)}`, sla: '支持按车辆和时间窗快速回放', primaryAction: '轨迹回放', - secondaryAction: 'RAW证据', + secondaryAction: '原始记录', onPrimary: () => onOpenHistory(), onSecondary: () => onOpenHistory({ tab: 'raw', includeFields: 'true' }) }, { title: '历史数据查询', - objective: '围绕车辆查询位置、RAW、解析字段,给 BI、运维和业务复盘提供证据。', + objective: '围绕车辆查询位置、原始记录和字段明细,给 BI、运维和业务复盘提供依据。', evidence: `今日数据 ${formatCount(summary?.frameToday)} / 支持字段裁剪与导出`, sla: '优先返回必要字段,避免大 JSON 拖慢查询', primaryAction: '历史查询', @@ -753,11 +753,11 @@ export function Dashboard({ onSecondary: () => onOpenQuality(highPriorityIssue?.issueType ? { issueType: highPriorityIssue.issueType } : {}) }, { - title: '统计查询', + title: '里程统计', objective: '按车辆口径查询里程等指标,保证区间统计和日统计可闭合。', evidence: `车辆口径 ${formatCount(serviceSummary?.totalVehicles)} / 区间统计可追溯轨迹证据`, - sla: '统计值必须能追溯轨迹和 RAW 证据', - primaryAction: '统计查询', + sla: '统计值必须能追溯轨迹和原始记录', + primaryAction: '里程统计', secondaryAction: '车辆中心', onPrimary: () => onOpenMileage(), onSecondary: () => onOpenVehicles({}) @@ -782,9 +782,9 @@ export function Dashboard({ `实时监控:${appURL(buildAppHash({ page: 'realtime', filters: { online: 'online' } }))}`, `实时地图:${appURL(buildAppHash({ page: 'map', filters: { online: 'online' } }))}`, `轨迹回放:${appURL(buildAppHash({ page: 'history', keyword: highPriorityFilters?.keyword, protocol: highPriorityFilters?.protocol, filters: highPriorityFilters }))}`, - `历史RAW:${appURL(buildAppHash({ page: 'history-query', keyword: highPriorityFilters?.keyword, protocol: highPriorityFilters?.protocol, filters: { ...highPriorityFilters, tab: 'raw', includeFields: 'true' } }))}`, + `原始记录:${appURL(buildAppHash({ page: 'history-query', keyword: highPriorityFilters?.keyword, protocol: highPriorityFilters?.protocol, filters: { ...highPriorityFilters, tab: 'raw', includeFields: 'true' } }))}`, `告警事件:${appURL(buildAppHash({ page: 'alert-events', filters: highPriorityIssue?.issueType ? { issueType: highPriorityIssue.issueType } : {} }))}`, - `统计查询:${appURL(buildAppHash({ page: 'mileage', keyword: highPriorityLookupKey, protocol: highPriorityIssue?.protocol }))}`, + `里程统计:${appURL(buildAppHash({ page: 'mileage', keyword: highPriorityLookupKey, protocol: highPriorityIssue?.protocol }))}`, `车辆服务:${appURL(buildAppHash({ page: 'detail', keyword: highPriorityLookupKey, protocol: highPriorityIssue?.protocol }))}` ].filter(Boolean); copyText(lines.join('\n'), '运营交接摘要'); @@ -824,7 +824,7 @@ export function Dashboard({ `轨迹回放:${appURL(buildAppHash({ page: 'history' }))}`, `历史查询:${appURL(buildAppHash({ page: 'history-query', filters: { tab: 'raw', includeFields: 'true' } }))}`, `告警事件:${appURL(buildAppHash({ page: 'alert-events' }))}`, - `统计查询:${appURL(buildAppHash({ page: 'mileage' }))}`, + `里程统计:${appURL(buildAppHash({ page: 'mileage' }))}`, `运维质量:${appURL(buildAppHash({ page: 'ops-quality' }))}` ]; copyText(lines.join('\n'), '数据流转图'); @@ -847,8 +847,8 @@ export function Dashboard({ `车辆服务:${appURL(buildAppHash({ page: 'detail', keyword: focusVehicle.lookupKey, protocol: focusVehicle.protocol }))}`, `实时监控:${appURL(buildAppHash({ page: 'realtime', keyword: focusVehicle.lookupKey, protocol: focusVehicle.protocol }))}`, `轨迹回放:${appURL(buildAppHash({ page: 'history', keyword: focusVehicle.lookupKey, protocol: focusVehicle.protocol }))}`, - `RAW证据:${appURL(buildAppHash({ page: 'history-query', keyword: focusVehicle.lookupKey, protocol: focusVehicle.protocol, filters: { ...commonFilters, tab: 'raw', includeFields: 'true' } }))}`, - `统计查询:${appURL(buildAppHash({ page: 'mileage', keyword: focusVehicle.lookupKey, protocol: focusVehicle.protocol }))}`, + `原始记录:${appURL(buildAppHash({ page: 'history-query', keyword: focusVehicle.lookupKey, protocol: focusVehicle.protocol, filters: { ...commonFilters, tab: 'raw', includeFields: 'true' } }))}`, + `里程统计:${appURL(buildAppHash({ page: 'mileage', keyword: focusVehicle.lookupKey, protocol: focusVehicle.protocol }))}`, `告警事件:${appURL(buildAppHash({ page: 'alert-events', keyword: focusVehicle.lookupKey, protocol: focusVehicle.protocol, filters: focusVehicle.issueType ? { issueType: focusVehicle.issueType } : {} }))}` ]; copyText(lines.join('\n'), '重点车辆服务处置卡'); @@ -1013,8 +1013,8 @@ export function Dashboard({
{[ { title: '今天车辆轨迹', detail: '查看当天活跃车辆的轨迹、速度和里程断点。', action: '查今天', onClick: () => onOpenHistory() }, - { title: '历史时间窗', detail: '按任意起止时间查询位置历史、RAW 字段和证据。', action: '自定义查询', onClick: () => onOpenHistory({ tab: 'raw', includeFields: 'true' }) }, - { title: '区间里程', detail: '按车辆和时间范围核对区间里程、日统计和异常点。', action: '统计查询', onClick: () => onOpenMileage() }, + { title: '历史时间窗', detail: '按任意起止时间查询位置历史、原始记录和字段明细。', action: '自定义查询', onClick: () => onOpenHistory({ tab: 'raw', includeFields: 'true' }) }, + { title: '区间里程', detail: '按车辆和时间范围核对区间里程、日统计和异常点。', action: '里程统计', onClick: () => onOpenMileage() }, { title: '告警复盘', detail: '按车辆或事件回放告警发生前后的轨迹和数据证据。', action: '告警事件', onClick: () => onOpenQuality() } ].map((item) => ( - - + +
) : null} - +
{operationWorkbench.map((item) => (
@@ -1195,7 +1195,7 @@ export function Dashboard({ disabled={!highPriorityEvidenceFilters?.keyword} onClick={() => highPriorityEvidenceFilters && onOpenHistory({ ...highPriorityEvidenceFilters, tab: 'raw', includeFields: 'true' })} > - RAW证据 + 原始记录 } + title={告警事件预览} bordered style={{ marginTop: 16 }} > 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 6ec98292..01eac874 100644 --- a/vehicle-data-platform/apps/web/src/test/App.test.tsx +++ b/vehicle-data-platform/apps/web/src/test/App.test.tsx @@ -426,7 +426,7 @@ test('shows vehicle service status distribution on dashboard', async () => { expect(await screen.findByText('车辆服务覆盖')).toBeInTheDocument(); expect(screen.getAllByText('服务状态').length).toBeGreaterThanOrEqual(1); - expect(screen.getByText('质量问题预览')).toBeInTheDocument(); + expect(screen.getByText('告警事件预览')).toBeInTheDocument(); }); test('dashboard renders vehicle service summary metrics', async () => { @@ -781,7 +781,7 @@ test('dashboard exposes vehicle data center capability matrix', async () => { const renderDashboard = async () => { window.history.replaceState(null, '', '/#/dashboard'); render(); - expect(await screen.findByText('车辆服务能力矩阵')).toBeInTheDocument(); + expect(await screen.findByText('车辆运营能力矩阵')).toBeInTheDocument(); }; await renderDashboard(); @@ -796,7 +796,7 @@ test('dashboard exposes vehicle data center capability matrix', async () => { expect(screen.getByText('历史时间窗')).toBeInTheDocument(); expect(screen.getByText('区间里程')).toBeInTheDocument(); expect(screen.getByText('告警复盘')).toBeInTheDocument(); - expect(screen.getByText('车辆服务作业台')).toBeInTheDocument(); + expect(screen.getByText('车辆运营工作台')).toBeInTheDocument(); expect(screen.getByText('地图运营能力')).toBeInTheDocument(); expect(screen.getByText('车联网场景导航')).toBeInTheDocument(); expect(screen.getByText('高德 Web JS')).toBeInTheDocument(); @@ -812,7 +812,7 @@ test('dashboard exposes vehicle data center capability matrix', async () => { expect(screen.getAllByText('轨迹回放').length).toBeGreaterThanOrEqual(1); expect(screen.getAllByText('历史数据查询').length).toBeGreaterThanOrEqual(1); expect(screen.getAllByText('告警事件触发与通知').length).toBeGreaterThanOrEqual(1); - expect(screen.getAllByText('统计查询').length).toBeGreaterThanOrEqual(1); + expect(screen.getAllByText('里程统计').length).toBeGreaterThanOrEqual(1); expect(screen.getByText('告警事件与通知')).toBeInTheDocument(); expect(screen.getByText('区间闭合复核')).toBeInTheDocument(); expect(screen.getByText('高德轨迹证据')).toBeInTheDocument(); @@ -878,7 +878,7 @@ test('dashboard exposes vehicle data center capability matrix', async () => { cleanup(); await renderDashboard(); - fireEvent.click(screen.getByRole('button', { name: '场景导航 轨迹回放 RAW证据' })); + fireEvent.click(screen.getByRole('button', { name: '场景导航 轨迹回放 原始记录' })); expect(window.location.hash.startsWith('#/history-query')).toBe(true); expect(new URLSearchParams(window.location.hash.split('?')[1] ?? '').get('includeFields')).toBe('true'); cleanup(); @@ -911,7 +911,7 @@ test('dashboard exposes vehicle data center capability matrix', async () => { cleanup(); await renderDashboard(); - fireEvent.click(screen.getByRole('button', { name: '能力入口 统计查询' })); + fireEvent.click(screen.getByRole('button', { name: '能力入口 里程统计' })); expect(window.location.hash.startsWith('#/mileage')).toBe(true); }); @@ -1447,7 +1447,7 @@ test('dashboard surfaces highest priority quality issue with evidence shortcuts' render(); expect(await screen.findByText('重点车辆服务')).toBeInTheDocument(); - expect(screen.getByText('把数据来源作为证据,把实时、轨迹、RAW、统计和告警集中到同一辆车处理。')).toBeInTheDocument(); + expect(screen.getByText('把实时、轨迹、原始记录、里程和告警集中到同一辆车处理。')).toBeInTheDocument(); expect(screen.getByText('实时证据')).toBeInTheDocument(); expect(screen.getAllByText('轨迹证据').length).toBeGreaterThanOrEqual(1); expect(screen.getByText('告警证据')).toBeInTheDocument(); @@ -1456,7 +1456,7 @@ test('dashboard surfaces highest priority quality issue with evidence shortcuts' expect(writeText).toHaveBeenCalledWith(expect.stringContaining('【重点车辆服务处置卡】')); expect(writeText).toHaveBeenCalledWith(expect.stringContaining('车辆:粤A告警1 / 13307795425')); expect(writeText).toHaveBeenCalledWith(expect.stringContaining('实时监控:http://localhost:3000/#/realtime?keyword=%E7%B2%A4A%E5%91%8A%E8%AD%A61&protocol=JT808')); - expect(writeText).toHaveBeenCalledWith(expect.stringContaining('RAW证据:http://localhost:3000/#/history-query?keyword=%E7%B2%A4A%E5%91%8A%E8%AD%A61&protocol=JT808&tab=raw&includeFields=true')); + expect(writeText).toHaveBeenCalledWith(expect.stringContaining('原始记录:http://localhost:3000/#/history-query?keyword=%E7%B2%A4A%E5%91%8A%E8%AD%A61&protocol=JT808&tab=raw&includeFields=true')); expect(await screen.findByText('最高优先级告警')).toBeInTheDocument(); expect(screen.getAllByText('粤A告警1 / 13307795425').length).toBeGreaterThanOrEqual(1); expect(screen.getByText('VIN 缺失')).toBeInTheDocument(); @@ -1589,7 +1589,7 @@ test('dashboard copies highest priority quality issue notification text', async expect(writeText).toHaveBeenCalledWith(expect.stringContaining('数据来源:JT808')); expect(writeText).toHaveBeenCalledWith(expect.stringContaining('详情:JT808 数据缺少 VIN 映射')); expect(writeText).toHaveBeenCalledWith(expect.stringContaining('轨迹证据:http://localhost:3000/#/history?keyword=%E7%B2%A4A%E5%91%8A%E8%AD%A61&protocol=JT808&dateFrom=2026-07-03&dateTo=2026-07-04')); - expect(writeText).toHaveBeenCalledWith(expect.stringContaining('RAW证据:http://localhost:3000/#/history-query?keyword=%E7%B2%A4A%E5%91%8A%E8%AD%A61&protocol=JT808&tab=raw&dateFrom=2026-07-03&dateTo=2026-07-04&includeFields=true')); + expect(writeText).toHaveBeenCalledWith(expect.stringContaining('原始记录:http://localhost:3000/#/history-query?keyword=%E7%B2%A4A%E5%91%8A%E8%AD%A61&protocol=JT808&tab=raw&dateFrom=2026-07-03&dateTo=2026-07-04&includeFields=true')); fireEvent.click(screen.getByRole('button', { name: '复制运营交接摘要' })); @@ -1603,7 +1603,7 @@ test('dashboard copies highest priority quality issue notification text', async expect(writeText).toHaveBeenCalledWith(expect.stringContaining('实时监控:http://localhost:3000/#/realtime?online=online')); expect(writeText).toHaveBeenCalledWith(expect.stringContaining('实时地图:http://localhost:3000/#/map?online=online')); expect(writeText).toHaveBeenCalledWith(expect.stringContaining('轨迹回放:http://localhost:3000/#/history?keyword=%E7%B2%A4A%E5%91%8A%E8%AD%A61&protocol=JT808&dateFrom=2026-07-03&dateTo=2026-07-04')); - expect(writeText).toHaveBeenCalledWith(expect.stringContaining('历史RAW:http://localhost:3000/#/history-query?keyword=%E7%B2%A4A%E5%91%8A%E8%AD%A61&protocol=JT808&tab=raw&dateFrom=2026-07-03&dateTo=2026-07-04&includeFields=true')); + expect(writeText).toHaveBeenCalledWith(expect.stringContaining('原始记录:http://localhost:3000/#/history-query?keyword=%E7%B2%A4A%E5%91%8A%E8%AD%A61&protocol=JT808&tab=raw&dateFrom=2026-07-03&dateTo=2026-07-04&includeFields=true')); expect(writeText).toHaveBeenCalledWith(expect.stringContaining('告警事件:http://localhost:3000/#/alert-events?issueType=VIN_MISSING')); expect(writeText).toHaveBeenCalledWith(expect.stringContaining('车辆服务:http://localhost:3000/#/detail?keyword=%E7%B2%A4A%E5%91%8A%E8%AD%A61&protocol=JT808'));