diff --git a/vehicle-data-platform/apps/web/src/layout/AppShell.tsx b/vehicle-data-platform/apps/web/src/layout/AppShell.tsx index b9ca492b..179f9ca2 100644 --- a/vehicle-data-platform/apps/web/src/layout/AppShell.tsx +++ b/vehicle-data-platform/apps/web/src/layout/AppShell.tsx @@ -67,6 +67,14 @@ const navGroups = [ } ]; +const customerPrimaryPath = [ + { label: '车辆地图', page: 'map' as const }, + { label: '轨迹回放', page: 'history' as const }, + { label: '统计查询', page: 'mileage' as const }, + { label: '数据导出', page: 'history-query' as const }, + { label: '告警通知', page: 'alert-events' as const } +]; + function linkHealthClassName(count: number | null) { if (count == null) { return ''; @@ -167,6 +175,25 @@ export function AppShell({ 实时地图 / 轨迹统计 / 告警通知 +
+
+ 客户主线 + 先看车,再查时间窗,最后导出和通知。 +
+
+ {customerPrimaryPath.map((item) => ( + + ))} +
+
{navGroups.map((group) => (
diff --git a/vehicle-data-platform/apps/web/src/styles/global.css b/vehicle-data-platform/apps/web/src/styles/global.css index 3d433952..1563a75c 100644 --- a/vehicle-data-platform/apps/web/src/styles/global.css +++ b/vehicle-data-platform/apps/web/src/styles/global.css @@ -69,6 +69,63 @@ body { white-space: nowrap; } +.vp-customer-primary-path { + margin: 0 4px 14px; + padding: 12px; + border: 1px solid rgba(22, 100, 255, 0.16); + border-radius: 8px; + background: #f8fbff; + display: grid; + gap: 10px; +} + +.vp-customer-primary-path-head { + display: grid; + gap: 3px; +} + +.vp-customer-primary-path-head strong { + color: var(--vp-text); + font-size: 13px; + line-height: 18px; +} + +.vp-customer-primary-path-head span { + color: var(--vp-text-muted); + font-size: 11px; + line-height: 16px; +} + +.vp-customer-primary-path-actions { + display: grid; + grid-template-columns: repeat(2, minmax(0, 1fr)); + gap: 6px; +} + +.vp-customer-primary-path-action { + min-height: 30px; + padding: 5px 8px; + border: 1px solid var(--vp-border); + border-radius: 7px; + background: #ffffff; + color: var(--vp-text-muted); + cursor: pointer; + font: inherit; + font-size: 12px; + font-weight: 600; + line-height: 18px; + text-align: center; +} + +.vp-customer-primary-path-action:hover, +.vp-customer-primary-path-action:focus-visible, +.vp-customer-primary-path-action-active { + border-color: rgba(22, 100, 255, 0.38); + background: #ffffff; + color: var(--vp-primary); + outline: none; +} + .vp-nav-groups { display: grid; gap: 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 a33211cc..9cffc627 100644 --- a/vehicle-data-platform/apps/web/src/test/App.test.tsx +++ b/vehicle-data-platform/apps/web/src/test/App.test.tsx @@ -22,6 +22,13 @@ test('renders vehicle platform shell', () => { render(); expect(screen.getByText('车辆服务中台')).toBeInTheDocument(); expect(screen.getByText('实时地图 / 轨迹统计 / 告警通知')).toBeInTheDocument(); + 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(); + expect(screen.getByRole('button', { name: '客户主线 告警通知' })).toBeInTheDocument(); expect(screen.getByText('实时运营')).toBeInTheDocument(); expect(screen.getByText('地图看车、在线监控、异常优先')).toBeInTheDocument(); expect(screen.getAllByText('车辆服务').length).toBeGreaterThanOrEqual(1);