From 7348cc6186564357a6756c3d3408bec4cdbbe4a2 Mon Sep 17 00:00:00 2001 From: lingniu Date: Sun, 5 Jul 2026 20:28:29 +0800 Subject: [PATCH] feat(platform): anchor dashboard on amap vehicle service --- .../apps/web/src/pages/Dashboard.tsx | 64 ++++++++++++++++ .../apps/web/src/styles/global.css | 73 +++++++++++++++++++ .../apps/web/src/test/App.test.tsx | 6 ++ 3 files changed, 143 insertions(+) diff --git a/vehicle-data-platform/apps/web/src/pages/Dashboard.tsx b/vehicle-data-platform/apps/web/src/pages/Dashboard.tsx index 148ead8c..4b2cbde7 100644 --- a/vehicle-data-platform/apps/web/src/pages/Dashboard.tsx +++ b/vehicle-data-platform/apps/web/src/pages/Dashboard.tsx @@ -1468,6 +1468,40 @@ export function Dashboard({ onClick: () => onOpenQuality(highPriorityIssue?.issueType ? { issueType: highPriorityIssue.issueType } : {}) } ]; + const amapVehicleServiceItems = [ + { + label: '实时看车', + value: `${commandLocatedCount.toLocaleString()} 有定位`, + detail: '高德底图承接车辆在线、最新位置、速度和最后上报时间。', + action: '打开地图', + color: commandLocatedCount > 0 ? 'green' as const : 'orange' as const, + onClick: () => onOpenMap({ online: 'online' }) + }, + { + label: '路线回放', + value: dayRangeText(timeMonitorScopeValue.dateFrom, timeMonitorScopeValue.dateTo), + detail: '同一车辆和时间窗回放路径,核对速度、停留、里程和断点。', + action: '轨迹回放', + color: 'blue' as const, + onClick: openTimeMonitorHistory + }, + { + label: '区域告警', + value: `${formatCount(summary?.issueVehicles)} 告警`, + detail: highPriorityIssue ? `${qualityIssueLabel(highPriorityIssue.issueType)} / ${priorityIssueVehicleLabel(highPriorityIssue)}` : '围栏、断链、定位异常后续统一进入告警通知。', + action: '告警通知', + color: (summary?.issueVehicles ?? 0) > 0 ? 'orange' as const : 'green' as const, + onClick: () => onOpenQuality(highPriorityIssue?.issueType ? { issueType: highPriorityIssue.issueType } : {}) + }, + { + label: '时间窗导出', + value: `${formatCount(summary?.frameToday)} 今日数据`, + detail: '按车辆、时间和字段导出位置、原始记录、解析字段和统计证据。', + action: '历史导出', + color: 'blue' as const, + onClick: openTimeMonitorRaw + } + ]; const customerQuestionActions = [ { question: '这辆车现在在哪里?', @@ -1855,6 +1889,36 @@ export function Dashboard({ ))} +
+
+ + 高德地图车辆服务底座 + {amapConfigured ? 'Web JS 已配置' : '坐标预览'} + {amapApiConfigured ? '服务端 API 已配置' : '服务端 API 待配置'} + {amapSecurityProxyEnabled ? '安全代理已启用' : '安全代理未启用'} + + 高德能力不单独成为页面目标,而是支撑同一辆车的实时看车、路线回放、区域告警和时间窗数据交付。 + + 客户看到的是车辆服务动作;32960、808、MQTT 只作为位置、轨迹、告警和统计可信度的来源证据。 + +
+
+ {amapVehicleServiceItems.map((item) => ( + + ))} +
+
diff --git a/vehicle-data-platform/apps/web/src/styles/global.css b/vehicle-data-platform/apps/web/src/styles/global.css index 24225766..b3e989e9 100644 --- a/vehicle-data-platform/apps/web/src/styles/global.css +++ b/vehicle-data-platform/apps/web/src/styles/global.css @@ -1586,6 +1586,71 @@ body { white-space: nowrap; } +.vp-amap-service-foundation { + margin-bottom: 16px; + padding: 18px; + border: 1px solid rgba(22, 100, 255, 0.16); + border-radius: 8px; + background: linear-gradient(180deg, #ffffff 0%, #f6f9ff 100%); + display: grid; + grid-template-columns: minmax(280px, 0.9fr) minmax(0, 1.4fr); + gap: 16px; +} + +.vp-amap-service-foundation-copy { + min-width: 0; + display: grid; + align-content: start; + gap: 10px; +} + +.vp-amap-service-foundation-grid { + min-width: 0; + display: grid; + grid-template-columns: repeat(4, minmax(0, 1fr)); + gap: 10px; +} + +.vp-amap-service-foundation-item { + min-height: 138px; + padding: 13px; + border: 1px solid var(--vp-border); + border-radius: 8px; + background: #ffffff; + cursor: pointer; + text-align: left; + font: inherit; + display: grid; + align-content: space-between; + gap: 8px; +} + +.vp-amap-service-foundation-item:hover, +.vp-amap-service-foundation-item:focus-visible { + border-color: rgba(22, 100, 255, 0.45); + box-shadow: var(--vp-shadow-sm); + outline: none; +} + +.vp-amap-service-foundation-item strong { + color: var(--vp-text); + font-size: 20px; + line-height: 25px; +} + +.vp-amap-service-foundation-item span { + color: var(--vp-text-muted); + font-size: 12px; + line-height: 18px; +} + +.vp-amap-service-foundation-item em { + color: #1664ff; + font-style: normal; + font-size: 12px; + font-weight: 700; +} + .vp-customer-cockpit-trust { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); @@ -9618,6 +9683,8 @@ button.vp-realtime-command-item:focus-visible { .vp-customer-service-command-grid, .vp-customer-cockpit, .vp-customer-cockpit-actions, + .vp-amap-service-foundation, + .vp-amap-service-foundation-grid, .vp-customer-vehicle-monitor, .vp-customer-vehicle-monitor-grid, .vp-vehicle-priority-queue-grid, @@ -9823,6 +9890,12 @@ button.vp-realtime-command-item:focus-visible { border-bottom: 1px solid var(--vp-border); } + .vp-amap-service-foundation-copy { + border-right: 0; + border-bottom: 1px solid var(--vp-border); + padding-bottom: 12px; + } + .vp-vehicle-asset-console-summary { border-right: 0; border-bottom: 1px solid var(--vp-border); 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 5e258310..a4890833 100644 --- a/vehicle-data-platform/apps/web/src/test/App.test.tsx +++ b/vehicle-data-platform/apps/web/src/test/App.test.tsx @@ -914,6 +914,12 @@ test('dashboard exposes vehicle data center capability matrix', async () => { expect(screen.getByRole('button', { name: '现代车队运营台 Mileage 1,033 车辆 查统计' })).toBeInTheDocument(); expect(screen.getByRole('button', { name: '现代车队运营台 Export 1,286,320 今日数据 导出数据' })).toBeInTheDocument(); expect(screen.getByRole('button', { name: '现代车队运营台 Alerts 7 告警 通知闭环' })).toBeInTheDocument(); + expect(screen.getByText('高德地图车辆服务底座')).toBeInTheDocument(); + expect(screen.getByText('高德能力不单独成为页面目标,而是支撑同一辆车的实时看车、路线回放、区域告警和时间窗数据交付。')).toBeInTheDocument(); + expect(screen.getByRole('button', { name: '高德地图车辆服务底座 实时看车 0 有定位 打开地图' })).toBeInTheDocument(); + expect(screen.getByRole('button', { name: '高德地图车辆服务底座 路线回放 1 天窗口 轨迹回放' })).toBeInTheDocument(); + expect(screen.getByRole('button', { name: '高德地图车辆服务底座 区域告警 7 告警 告警通知' })).toBeInTheDocument(); + expect(screen.getByRole('button', { name: '高德地图车辆服务底座 时间窗导出 1,286,320 今日数据 历史导出' })).toBeInTheDocument(); expect(screen.getByText('车辆监控中心')).toBeInTheDocument(); expect(screen.getByText('先看车在哪里,再处理轨迹、统计、告警和导出')).toBeInTheDocument(); expect(screen.getByText('客户主流程围绕车辆本身:地图看车、实时状态、时间窗复盘、统计查询、历史数据导出和告警通知。接入来源只作为追溯证据。')).toBeInTheDocument();