From 59d55e7bd603d2a811594860b56b6647ebc0e6d6 Mon Sep 17 00:00:00 2001 From: lingniu Date: Sun, 5 Jul 2026 20:33:58 +0800 Subject: [PATCH] feat(platform): add customer fleet group views --- .../apps/web/src/pages/Dashboard.tsx | 63 ++++++++++++++++ .../apps/web/src/styles/global.css | 73 +++++++++++++++++++ .../apps/web/src/test/App.test.tsx | 6 ++ 3 files changed, 142 insertions(+) diff --git a/vehicle-data-platform/apps/web/src/pages/Dashboard.tsx b/vehicle-data-platform/apps/web/src/pages/Dashboard.tsx index 4b2cbde7..8a6ae2b4 100644 --- a/vehicle-data-platform/apps/web/src/pages/Dashboard.tsx +++ b/vehicle-data-platform/apps/web/src/pages/Dashboard.tsx @@ -1822,6 +1822,40 @@ export function Dashboard({ onClick: () => onOpenQuality(highPriorityIssue?.issueType ? { issueType: highPriorityIssue.issueType } : {}) } ]; + const customerFleetGroupItems = [ + { + label: '在线运营组', + value: `${formatCount(serviceSummary?.onlineVehicles ?? summary?.onlineVehicles)} 在线`, + detail: '给调度和客服复用:默认进入在线车辆地图,先回答客户车辆在哪里。', + action: '打开地图', + color: 'green' as const, + onClick: () => onOpenMap({ online: 'online' }) + }, + { + label: '告警处置组', + value: `${formatCount(summary?.issueVehicles)} 告警`, + detail: '给运维和业务负责人复用:只看需要通知、升级和验收的车辆。', + action: '告警通知', + color: (summary?.issueVehicles ?? 0) > 0 ? 'orange' as const : 'green' as const, + onClick: () => onOpenQuality(highPriorityIssue?.issueType ? { issueType: highPriorityIssue.issueType } : {}) + }, + { + label: '身份维护组', + value: `${formatCount(serviceSummary?.identityRequiredVehicles)} 待绑定`, + detail: '给数据维护人员复用:补齐 VIN、车牌、手机号和客户可查身份。', + action: '维护车辆', + color: (serviceSummary?.identityRequiredVehicles ?? 0) > 0 ? 'orange' as const : 'green' as const, + onClick: () => onOpenVehicles({ serviceStatus: 'identity_required' }) + }, + { + label: '报表交付组', + value: `${formatCount(summary?.frameToday)} 今日数据`, + detail: '给客户交付人员复用:按同一车辆范围导出历史、轨迹、字段和统计证据。', + action: '历史导出', + color: 'blue' as const, + onClick: openTimeMonitorRaw + } + ]; return (
@@ -1863,6 +1897,35 @@ export function Dashboard({ ))}
+
+
+ + 客户车队分组工作台 + {formatCount(serviceSummary?.onlineVehicles ?? summary?.onlineVehicles)} 在线 + 0 ? 'orange' : 'green'}>{formatCount(summary?.issueVehicles)} 告警 + + 按客户责任范围组织车辆池:在线运营、告警处置、身份维护和报表交付都能保存成复用视图。 + + 客户不是每次都从全量车辆开始筛选;常用车队视图应该直接带到地图、通知、车辆中心和历史导出。 + +
+
+ {customerFleetGroupItems.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 b3e989e9..cf0db422 100644 --- a/vehicle-data-platform/apps/web/src/styles/global.css +++ b/vehicle-data-platform/apps/web/src/styles/global.css @@ -1302,6 +1302,71 @@ body { line-height: 18px; } +.vp-customer-fleet-groups { + margin-bottom: 16px; + padding: 18px; + border: 1px solid rgba(22, 100, 255, 0.16); + border-radius: 8px; + background: #ffffff; + display: grid; + grid-template-columns: minmax(280px, 0.82fr) minmax(0, 1.5fr); + gap: 16px; +} + +.vp-customer-fleet-groups-copy { + min-width: 0; + display: grid; + align-content: start; + gap: 10px; +} + +.vp-customer-fleet-groups-grid { + min-width: 0; + display: grid; + grid-template-columns: repeat(4, minmax(0, 1fr)); + gap: 10px; +} + +.vp-customer-fleet-group-item { + min-height: 136px; + padding: 13px; + border: 1px solid var(--vp-border); + border-radius: 8px; + background: linear-gradient(180deg, #ffffff 0%, #f8fbff 100%); + cursor: pointer; + text-align: left; + font: inherit; + display: grid; + align-content: space-between; + gap: 8px; +} + +.vp-customer-fleet-group-item:hover, +.vp-customer-fleet-group-item:focus-visible { + border-color: rgba(22, 100, 255, 0.45); + box-shadow: var(--vp-shadow-sm); + outline: none; +} + +.vp-customer-fleet-group-item strong { + color: var(--vp-text); + font-size: 20px; + line-height: 25px; +} + +.vp-customer-fleet-group-item span { + color: var(--vp-text-muted); + font-size: 12px; + line-height: 18px; +} + +.vp-customer-fleet-group-item em { + color: #1664ff; + font-style: normal; + font-size: 12px; + font-weight: 700; +} + .vp-customer-cockpit-summary { padding: 18px; border-right: 1px solid var(--vp-border); @@ -9681,6 +9746,8 @@ button.vp-realtime-command-item:focus-visible { .vp-map-ops-work, .vp-customer-service-command-main, .vp-customer-service-command-grid, + .vp-customer-fleet-groups, + .vp-customer-fleet-groups-grid, .vp-customer-cockpit, .vp-customer-cockpit-actions, .vp-amap-service-foundation, @@ -9880,6 +9947,12 @@ button.vp-realtime-command-item:focus-visible { border-bottom: 1px solid var(--vp-border); } + .vp-customer-fleet-groups-copy { + border-right: 0; + border-bottom: 1px solid var(--vp-border); + padding-bottom: 12px; + } + .vp-history-export-center-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 a4890833..db35f807 100644 --- a/vehicle-data-platform/apps/web/src/test/App.test.tsx +++ b/vehicle-data-platform/apps/web/src/test/App.test.tsx @@ -712,6 +712,12 @@ test('dashboard prioritizes customer vehicle service command over data sources', expect(screen.getByRole('button', { name: '客户车辆服务总控台 数据导出 1,286,320 今日数据 查询导出' })).toBeInTheDocument(); expect(screen.getByRole('button', { name: '客户车辆服务总控台 告警通知 7 告警 闭环告警' })).toBeInTheDocument(); expect(screen.getByText('来源证据:GB32960 / JT808 / YUTONG_MQTT')).toBeInTheDocument(); + expect(screen.getByText('客户车队分组工作台')).toBeInTheDocument(); + expect(screen.getByText('按客户责任范围组织车辆池:在线运营、告警处置、身份维护和报表交付都能保存成复用视图。')).toBeInTheDocument(); + expect(screen.getByRole('button', { name: '客户车队分组工作台 在线运营组 208 在线 打开地图' })).toBeInTheDocument(); + expect(screen.getByRole('button', { name: '客户车队分组工作台 告警处置组 7 告警 告警通知' })).toBeInTheDocument(); + expect(screen.getByRole('button', { name: '客户车队分组工作台 身份维护组 9 待绑定 维护车辆' })).toBeInTheDocument(); + expect(screen.getByRole('button', { name: '客户车队分组工作台 报表交付组 1,286,320 今日数据 历史导出' })).toBeInTheDocument(); }); test('dashboard exposes vehicle data center capability matrix', async () => {