diff --git a/vehicle-data-platform/apps/web/src/pages/Dashboard.tsx b/vehicle-data-platform/apps/web/src/pages/Dashboard.tsx index 4a086745..c150de64 100644 --- a/vehicle-data-platform/apps/web/src/pages/Dashboard.tsx +++ b/vehicle-data-platform/apps/web/src/pages/Dashboard.tsx @@ -1665,6 +1665,32 @@ export function Dashboard({ onClick: openTimeMonitorRaw } ]; + const amapCapabilityItems = [ + { + label: '实时底图', + value: amapConfigured ? '可用' : '降级', + detail: amapConfigured ? '车辆在线分布、最后位置和地图选车可直接使用高德底图。' : '未配置 Web JS Key 时保留坐标预览。', + color: amapConfigured ? 'green' as const : 'orange' as const + }, + { + label: '轨迹路径', + value: amapConfigured ? '可回放' : '坐标线', + detail: amapConfigured ? '轨迹回放可叠加道路底图,辅助判断停留、绕行和断点。' : '缺少底图时只展示历史坐标证据。', + color: amapConfigured ? 'green' as const : 'orange' as const + }, + { + label: '区域围栏', + value: amapApiConfigured ? '可扩展' : '待接入', + detail: amapApiConfigured ? '服务端 API 可承接围栏、区域、路线和位置服务扩展。' : '围栏和区域能力需要服务端地图 API。', + color: amapApiConfigured ? 'blue' as const : 'orange' as const + }, + { + label: '地址解析', + value: amapSecurityProxyEnabled ? '代理可用' : '待代理', + detail: amapSecurityProxyEnabled ? '逆地理和路线请求可通过安全代理收敛密钥。' : '生产环境建议通过 /_AMapService 代理服务端能力。', + color: amapSecurityProxyEnabled ? 'green' as const : 'orange' as const + } + ]; const customerQuestionActions = [ { question: '这辆车现在在哪里?', @@ -2676,6 +2702,21 @@ export function Dashboard({ 客户看到的是车辆服务动作;32960、808、MQTT 只作为位置、轨迹、告警和统计可信度的来源证据。 +
+
+ 地图服务能力清单 + 把高德 Web JS 和服务端 API 翻译成客户能使用的车辆服务能力。 +
+
+ {amapCapabilityItems.map((item) => ( +
+ {item.label} + {item.value} + {item.detail} +
+ ))} +
+
{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 b808d337..27f317bb 100644 --- a/vehicle-data-platform/apps/web/src/styles/global.css +++ b/vehicle-data-platform/apps/web/src/styles/global.css @@ -2593,6 +2593,60 @@ body { gap: 10px; } +.vp-amap-capability-list { + padding: 12px; + border: 1px solid rgba(22, 100, 255, 0.14); + border-radius: 8px; + background: rgba(255, 255, 255, 0.78); + display: grid; + gap: 10px; +} + +.vp-amap-capability-head { + display: grid; + gap: 3px; +} + +.vp-amap-capability-head strong { + color: var(--vp-text); + font-size: 14px; + line-height: 20px; +} + +.vp-amap-capability-head span { + color: var(--vp-text-muted); + font-size: 12px; + line-height: 18px; +} + +.vp-amap-capability-grid { + display: grid; + grid-template-columns: repeat(2, minmax(0, 1fr)); + gap: 8px; +} + +.vp-amap-capability-item { + min-width: 0; + padding: 10px; + border: 1px solid var(--vp-border); + border-radius: 8px; + background: #ffffff; + display: grid; + gap: 6px; +} + +.vp-amap-capability-item strong { + color: var(--vp-text); + font-size: 14px; + line-height: 20px; +} + +.vp-amap-capability-item span { + color: var(--vp-text-muted); + font-size: 12px; + line-height: 18px; +} + .vp-amap-service-foundation-grid { min-width: 0; display: grid; @@ -11749,6 +11803,7 @@ button.vp-realtime-command-item:focus-visible { .vp-customer-cockpit, .vp-customer-cockpit-actions, .vp-amap-service-foundation, + .vp-amap-capability-grid, .vp-amap-service-foundation-grid, .vp-customer-vehicle-monitor, .vp-customer-vehicle-monitor-grid, 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 8f7f4e6a..71d85565 100644 --- a/vehicle-data-platform/apps/web/src/test/App.test.tsx +++ b/vehicle-data-platform/apps/web/src/test/App.test.tsx @@ -778,6 +778,12 @@ test('dashboard prioritizes customer vehicle service command over data sources', expect(screen.getByRole('button', { name: '车辆健康与能耗工作台 SOC/氢能字段 1,286,320 今日数据 字段证据' })).toBeInTheDocument(); expect(screen.getByRole('button', { name: '车辆健康与能耗工作台 异常维护 7 告警 告警事件' })).toBeInTheDocument(); expect(screen.getByRole('button', { name: '车辆健康与能耗工作台 里程能耗 1 天窗口 统计查询' })).toBeInTheDocument(); + expect(screen.getByText('地图服务能力清单')).toBeInTheDocument(); + expect(screen.getByText('把高德 Web JS 和服务端 API 翻译成客户能使用的车辆服务能力。')).toBeInTheDocument(); + expect(screen.getByText('实时底图')).toBeInTheDocument(); + expect(screen.getByText('轨迹路径')).toBeInTheDocument(); + expect(screen.getByText('区域围栏')).toBeInTheDocument(); + expect(screen.getByText('地址解析')).toBeInTheDocument(); }); test('dashboard presents a customer dispatch operations home', async () => {