diff --git a/vehicle-data-platform/apps/web/src/pages/Realtime.tsx b/vehicle-data-platform/apps/web/src/pages/Realtime.tsx index 31aa09a7..49321eb9 100644 --- a/vehicle-data-platform/apps/web/src/pages/Realtime.tsx +++ b/vehicle-data-platform/apps/web/src/pages/Realtime.tsx @@ -1367,6 +1367,53 @@ export function Realtime({ ))} +
+
+ + 选中车辆服务 + {selectedMapRow ? ( + <> + {vehicleServiceStatus(selectedMapRow).label} + {dataFreshness(selectedMapRow).detail} + + ) : ( + 等待选车 + )} + + {selectedVehicleLabel} + + 客户在地图上选中车辆后,直接进入车辆档案、轨迹回放、里程核对、数据导出和告警处置。 + +
+
+ {mapVehicleWorkItems.map((item) => ( + + ))} + +
+
+
{mapCustomerTasks.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 a1fe4491..5080183c 100644 --- a/vehicle-data-platform/apps/web/src/styles/global.css +++ b/vehicle-data-platform/apps/web/src/styles/global.css @@ -1937,6 +1937,76 @@ button.vp-realtime-command-item:focus-visible { line-height: 18px; } +.vp-map-selected-service-strip { + padding: 14px; + border: 1px solid rgba(22, 100, 255, 0.18); + border-radius: var(--vp-radius); + background: #ffffff; + display: grid; + grid-template-columns: minmax(280px, 0.64fr) minmax(0, 1.36fr); + gap: 14px; + align-items: stretch; +} + +.vp-map-selected-service-summary { + min-width: 0; + display: grid; + align-content: start; + gap: 8px; +} + +.vp-map-selected-service-summary .semi-typography { + font-size: 13px; + line-height: 20px; +} + +.vp-map-selected-service-actions { + min-width: 0; + display: grid; + grid-template-columns: repeat(5, minmax(0, 1fr)); + gap: 10px; +} + +.vp-map-selected-service-action { + min-width: 0; + min-height: 104px; + padding: 12px; + border: 1px solid var(--vp-border); + border-radius: 8px; + background: #fbfcff; + cursor: pointer; + text-align: left; + font: inherit; + display: grid; + align-content: space-between; + gap: 8px; +} + +.vp-map-selected-service-action:hover, +.vp-map-selected-service-action:focus-visible { + border-color: rgba(22, 100, 255, 0.45); + background: #f5f9ff; + outline: none; +} + +.vp-map-selected-service-action:disabled { + cursor: not-allowed; + opacity: 0.58; +} + +.vp-map-selected-service-action strong { + color: var(--vp-primary); + font-size: 14px; + line-height: 20px; +} + +.vp-map-selected-service-action span { + color: var(--vp-text-muted); + font-size: 12px; + line-height: 18px; + word-break: break-word; +} + .vp-map-task-strip { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); @@ -5242,6 +5312,8 @@ button.vp-realtime-command-item:focus-visible { .vp-map-decision-board, .vp-map-decision-grid, .vp-map-kpi-strip, + .vp-map-selected-service-strip, + .vp-map-selected-service-actions, .vp-map-task-strip, .vp-map-customer-package, .vp-map-customer-package-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 94c7c92f..bb25108e 100644 --- a/vehicle-data-platform/apps/web/src/test/App.test.tsx +++ b/vehicle-data-platform/apps/web/src/test/App.test.tsx @@ -9330,6 +9330,12 @@ test('shows realtime freshness status for recently updated and stale vehicles', expect(screen.getAllByText('选中车辆').length).toBeGreaterThanOrEqual(1); expect(screen.getByText('车辆列表')).toBeInTheDocument(); expect(screen.getAllByText('1 辆更新超时').length).toBeGreaterThanOrEqual(1); + expect(screen.getByText('选中车辆服务')).toBeInTheDocument(); + expect(screen.getByText('客户在地图上选中车辆后,直接进入车辆档案、轨迹回放、里程核对、数据导出和告警处置。')).toBeInTheDocument(); + expect(screen.getByRole('button', { name: '地图选中车辆 车辆服务 车辆档案' })).toBeInTheDocument(); + expect(screen.getByRole('button', { name: '地图选中车辆 轨迹复盘 打开轨迹' })).toBeInTheDocument(); + expect(screen.getByRole('button', { name: '地图选中车辆 里程核对 查看里程' })).toBeInTheDocument(); + expect(screen.getByRole('button', { name: '地图选中车辆 数据导出 历史导出' })).toBeInTheDocument(); fireEvent.click(screen.getByRole('button', { name: /复制地图监控包/ })); await waitFor(() => { expect(writeText).toHaveBeenCalledWith(expect.stringContaining('【客户地图监控包】'));