diff --git a/vehicle-data-platform/apps/web/src/pages/Dashboard.tsx b/vehicle-data-platform/apps/web/src/pages/Dashboard.tsx index 0255173e..0d0d0e33 100644 --- a/vehicle-data-platform/apps/web/src/pages/Dashboard.tsx +++ b/vehicle-data-platform/apps/web/src/pages/Dashboard.tsx @@ -1416,102 +1416,6 @@ export function Dashboard({ ))} - -
- {customerHeroActions.map((item) => ( - - ))} -
-
- -
- {customerTaskBoard.map((item) => ( -
-
- {item.title} - {item.value} -
- {item.detail} - - - - -
- ))} -
-
-
- {kpis.map((item) => ( - - - - ))} -
- -
-
- - 客户服务路径 - {vehicleServiceOnlineText(serviceSummary, summary)} - 0 ? 'orange' : 'green'}>{formatCount(summary?.issueVehicles)} 告警事件 - - 从车辆出发,完成监控、复盘、统计、导出和告警闭环 - - 客户看到的是车辆服务结果;接入来源只在需要追溯时作为证据通道出现。 - - - - - - - -
-
- {customerServicePathItems.map((item) => ( - - ))} -
-
-
自定义时间监控{timeMonitorSummary}} @@ -1542,7 +1446,7 @@ export function Dashboard({
- +
@@ -1638,6 +1542,110 @@ export function Dashboard({ ))}
+
+ + 更多车辆服务入口 + 常用服务、今日任务、KPI 和车辆入口默认收起,主页面优先保留地图、指挥台和时间窗监控。 + +
+ +
+ {customerHeroActions.map((item) => ( + + ))} +
+
+ +
+ {customerTaskBoard.map((item) => ( +
+
+ {item.title} + {item.value} +
+ {item.detail} + + + + +
+ ))} +
+
+
+ {kpis.map((item) => ( + + + + ))} +
+ +
+
+ + 客户服务路径 + {vehicleServiceOnlineText(serviceSummary, summary)} + 0 ? 'orange' : 'green'}>{formatCount(summary?.issueVehicles)} 告警事件 + + 从车辆出发,完成监控、复盘、统计、导出和告警闭环 + + 客户看到的是车辆服务结果;接入来源只在需要追溯时作为数据通道出现。 + + + + + + + +
+
+ {customerServicePathItems.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 71c8370c..9dc55478 100644 --- a/vehicle-data-platform/apps/web/src/styles/global.css +++ b/vehicle-data-platform/apps/web/src/styles/global.css @@ -303,10 +303,12 @@ body { font-size: 13px; } +.vp-dashboard-secondary-details, .vp-dashboard-evidence-details { margin-bottom: 16px; } +.vp-dashboard-secondary-details > summary, .vp-dashboard-evidence-details > summary { min-height: 56px; padding: 12px 14px; @@ -318,10 +320,17 @@ body { gap: 4px; } +.vp-dashboard-secondary-details > summary { + border-color: rgba(22, 100, 255, 0.18); + background: #f7fbff; +} + +.vp-dashboard-secondary-details > summary::marker, .vp-dashboard-evidence-details > summary::marker { color: var(--vp-primary); } +.vp-dashboard-secondary-details > summary span, .vp-dashboard-evidence-details > summary span { color: var(--vp-text); font-size: 15px; @@ -329,12 +338,14 @@ body { line-height: 22px; } +.vp-dashboard-secondary-details > summary small, .vp-dashboard-evidence-details > summary small { color: var(--vp-text-muted); font-size: 12px; line-height: 18px; } +.vp-dashboard-secondary-body, .vp-dashboard-evidence-body { margin-top: 12px; } 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 ddb1811f..2376d061 100644 --- a/vehicle-data-platform/apps/web/src/test/App.test.tsx +++ b/vehicle-data-platform/apps/web/src/test/App.test.tsx @@ -822,10 +822,11 @@ 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('客户看到的是车辆服务结果;接入来源只在需要追溯时作为证据通道出现。')).toBeInTheDocument(); + expect(screen.getByText('客户看到的是车辆服务结果;接入来源只在需要追溯时作为数据通道出现。')).toBeInTheDocument(); expect(screen.getByText('找车')).toBeInTheDocument(); expect(screen.getByText('看位置')).toBeInTheDocument(); expect(screen.getAllByText('复盘时间').length).toBeGreaterThanOrEqual(1); @@ -853,7 +854,7 @@ test('dashboard exposes vehicle data center capability matrix', async () => { expect(screen.getByText('这个范围会同步带入轨迹、里程、历史证据和告警复盘,适合客户问询、BI 核对和异常解释。')).toBeInTheDocument(); expect(screen.getByText('查看轨迹')).toBeInTheDocument(); expect(screen.getAllByText('统计里程').length).toBeGreaterThanOrEqual(1); - expect(screen.getByText('导出原始记录')).toBeInTheDocument(); + expect(screen.getByText('历史查询导出')).toBeInTheDocument(); expect(screen.getAllByText('轨迹回放').length).toBeGreaterThanOrEqual(1); expect(screen.getByText('里程核对')).toBeInTheDocument(); expect(screen.getAllByText('历史证据').length).toBeGreaterThanOrEqual(1); @@ -967,7 +968,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('#/history-query')).toBe(true); expect(new URLSearchParams(window.location.hash.split('?')[1] ?? '').get('tab')).toBe('raw'); expect(new URLSearchParams(window.location.hash.split('?')[1] ?? '').get('includeFields')).toBe('true'); diff --git a/vehicle-data-platform/docs/fleet-platform-product-research.md b/vehicle-data-platform/docs/fleet-platform-product-research.md new file mode 100644 index 00000000..438c34f4 --- /dev/null +++ b/vehicle-data-platform/docs/fleet-platform-product-research.md @@ -0,0 +1,23 @@ +# 车辆数据中台产品化参考 + +## 参考产品共性 + +- Samsara、Geotab、Verizon Connect、Motive 这类车队平台都把实时车辆位置放在主入口,地图是调度、监控和异常处置的第一视角。 +- 主导航通常围绕车辆业务组织:实时地图、车辆/资产、轨迹回放、告警、安全或维护、报表统计,而不是围绕接入协议组织。 +- 历史数据查询通常服务于 trip history、route replay、reports 和 alerts 的复核,原始接入数据不应成为客户主路径。 +- 告警和通知需要从“发现异常”延伸到“责任人、升级、闭环”,而不是只展示技术链路状态。 +- 运维链路、消息队列、存储状态适合放在内部视图,作为客户问题排查的支撑层。 + +## 本项目采用的产品原则 + +- 三个接入来源只是数据通道,最终服务对象是车辆。 +- 第一屏必须回答客户最关心的问题:有多少车在线、车在哪里、哪些车异常、如何按时间复盘。 +- 车辆服务主路径固定为:车辆地图 -> 实时监控 -> 轨迹回放 -> 里程统计 -> 历史查询导出 -> 告警通知。 +- 自定义时间窗要贯穿轨迹、里程、历史查询和告警,避免用户在多个页面重复录入条件。 +- 协议、来源覆盖、Kafka、Redis、TDEngine、MySQL 等信息只在内部运维或复核层展示。 + +## 当前迭代落点 + +- 首页保留客户主路径:实时地图总览、车辆服务指挥台、自定义时间监控。 +- 重复入口、KPI 和辅助服务收进“更多车辆服务入口”。 +- 来源覆盖、地图配置、告警预览和链路状态继续放在“运维和依据层”折叠区。