From 775073a95c856b45f658bac0b6288f72d065fd14 Mon Sep 17 00:00:00 2001 From: lingniu Date: Sat, 4 Jul 2026 16:13:46 +0800 Subject: [PATCH] feat(platform): align shell with vehicle operations center --- .../apps/web/src/layout/AppShell.tsx | 8 ++--- .../apps/web/src/pages/Dashboard.tsx | 14 ++++----- .../apps/web/src/pages/Quality.tsx | 4 +-- .../apps/web/src/test/App.test.tsx | 30 +++++++++---------- 4 files changed, 28 insertions(+), 28 deletions(-) diff --git a/vehicle-data-platform/apps/web/src/layout/AppShell.tsx b/vehicle-data-platform/apps/web/src/layout/AppShell.tsx index a41ad758..7e314c71 100644 --- a/vehicle-data-platform/apps/web/src/layout/AppShell.tsx +++ b/vehicle-data-platform/apps/web/src/layout/AppShell.tsx @@ -17,13 +17,13 @@ import { isAMapConfigured } from '../config/appConfig'; export type PageKey = 'dashboard' | 'vehicles' | 'realtime' | 'detail' | 'history' | 'mileage' | 'quality'; const navItems = [ - { itemKey: 'dashboard', text: '运营总览', icon: }, + { itemKey: 'dashboard', text: '运营驾驶舱', icon: }, { itemKey: 'vehicles', text: '车辆中心', icon: }, { itemKey: 'realtime', text: '实时监控', icon: }, { itemKey: 'detail', text: '车辆档案', icon: }, { itemKey: 'history', text: '轨迹回放', icon: }, { itemKey: 'mileage', text: '统计分析', icon: }, - { itemKey: 'quality', text: '告警通知', icon: } + { itemKey: 'quality', text: '告警事件', icon: } ]; function linkHealthClassName(count: number | null) { @@ -118,11 +118,11 @@ export function AppShell({ diff --git a/vehicle-data-platform/apps/web/src/pages/Dashboard.tsx b/vehicle-data-platform/apps/web/src/pages/Dashboard.tsx index 7d2ff2f7..72fa8274 100644 --- a/vehicle-data-platform/apps/web/src/pages/Dashboard.tsx +++ b/vehicle-data-platform/apps/web/src/pages/Dashboard.tsx @@ -384,11 +384,11 @@ export function Dashboard({ onClick: () => onOpenHistory({ tab: 'raw' }) }, { - title: '告警通知', + title: '告警事件', value: `${formatCount(summary?.issueVehicles)} 车辆`, color: (summary?.issueVehicles ?? 0) > 0 ? 'orange' as const : 'green' as const, detail: '把断链、缺 VIN、字段缺失等问题进入通知和处置队列。', - action: '告警通知', + action: '告警事件', onClick: () => onOpenQuality() }, { @@ -403,7 +403,7 @@ export function Dashboard({ return (
- +
{kpis.map((item) => ( @@ -422,9 +422,9 @@ export function Dashboard({ {formatCount(serviceSummary?.multiSourceVehicles)} 多源覆盖 0 ? 'orange' : 'green'}> - {formatCount(summary?.issueVehicles)} 质量关注 + {formatCount(summary?.issueVehicles)} 告警事件 - + 0 ? 'orange' : 'green'}>Kafka Lag {formatLag(summary?.kafkaLag)} @@ -512,7 +512,7 @@ export function Dashboard({
) : null} - +
{capabilities.map((item) => (
@@ -530,7 +530,7 @@ export function Dashboard({
diff --git a/vehicle-data-platform/apps/web/src/pages/Quality.tsx b/vehicle-data-platform/apps/web/src/pages/Quality.tsx index fdb1db07..62361697 100644 --- a/vehicle-data-platform/apps/web/src/pages/Quality.tsx +++ b/vehicle-data-platform/apps/web/src/pages/Quality.tsx @@ -657,7 +657,7 @@ export function Quality({ return (
- +
{[ { label: '问题车辆', value: summary.issueVehicleCount.toLocaleString() }, @@ -702,7 +702,7 @@ export function Quality({ - +
{[ { label: '事件触发', value: `${activeRuleCount} 类活跃`, detail: '断链、无来源、VIN 缺失、字段缺失和容量异常进入告警池。' }, 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 fddb841f..18f2dd33 100644 --- a/vehicle-data-platform/apps/web/src/test/App.test.tsx +++ b/vehicle-data-platform/apps/web/src/test/App.test.tsx @@ -12,7 +12,7 @@ afterEach(() => { test('renders vehicle platform shell', () => { render(); expect(screen.getByText('车辆服务中台')).toBeInTheDocument(); - expect(screen.getAllByText('总览工作台').length).toBeGreaterThanOrEqual(1); + expect(screen.getAllByText('运营驾驶舱').length).toBeGreaterThanOrEqual(1); }); test('exposes AMap operations shortcuts when map key is configured', async () => { @@ -88,7 +88,7 @@ test('exposes AMap operations shortcuts when map key is configured', async () => expect(window.location.hash.startsWith('#/history')).toBe(true); fireEvent.click(screen.getByRole('button', { name: '顶部统计查询' })); expect(window.location.hash.startsWith('#/mileage')).toBe(true); - fireEvent.click(await screen.findByRole('button', { name: '顶部告警通知正常' })); + fireEvent.click(await screen.findByRole('button', { name: '顶部告警事件正常' })); expect(window.location.hash).toBe('#/quality'); }); @@ -286,7 +286,7 @@ test('dashboard presents one vehicle service operating posture', async () => { expect(await screen.findByText('统一车辆服务')).toBeInTheDocument(); expect(screen.getByText('208 / 1,033 在线')).toBeInTheDocument(); expect(screen.getByText('181 多源覆盖')).toBeInTheDocument(); - expect(screen.getByText('7 质量关注')).toBeInTheDocument(); + expect(screen.getByText('7 告警事件')).toBeInTheDocument(); }); test('dashboard exposes vehicle data center capability matrix', async () => { @@ -386,7 +386,7 @@ test('dashboard exposes vehicle data center capability matrix', async () => { const renderDashboard = async () => { window.history.replaceState(null, '', '/#/dashboard'); render(); - expect(await screen.findByText('车辆业务能力矩阵')).toBeInTheDocument(); + expect(await screen.findByText('车联网能力矩阵')).toBeInTheDocument(); }; await renderDashboard(); @@ -575,7 +575,7 @@ test('dashboard exposes vehicle command center map actions', async () => { render(); - expect(await screen.findByText('车辆态势指挥台')).toBeInTheDocument(); + expect(await screen.findByText('实时态势地图')).toBeInTheDocument(); expect(screen.getByText('在线 1 / 2')).toBeInTheDocument(); expect(screen.getAllByText('有效定位 1').length).toBeGreaterThanOrEqual(1); expect(screen.getByText('降级/离线 2')).toBeInTheDocument(); @@ -586,7 +586,7 @@ test('dashboard exposes vehicle command center map actions', async () => { window.history.replaceState(null, '', '/#/dashboard'); render(); - expect(await screen.findByText('车辆态势指挥台')).toBeInTheDocument(); + expect(await screen.findByText('实时态势地图')).toBeInTheDocument(); fireEvent.click(screen.getByRole('button', { name: '查看实时态势' })); expect(window.location.hash).toBe('#/realtime?online=online'); }); @@ -675,7 +675,7 @@ test('dashboard shows vehicle service action queue', async () => { test.each([ { buttonName: '查看在线车辆', expectedHash: '#/vehicles?online=online' }, { buttonName: '查看多源车辆', expectedHash: '#/vehicles?coverage=multi' }, - { buttonName: '查看质量关注', expectedHash: '#/quality' } + { buttonName: '查看告警事件', expectedHash: '#/quality' } ])('dashboard posture opens %s', async ({ buttonName, expectedHash }) => { window.history.replaceState(null, '', '/#/dashboard'); vi.spyOn(globalThis, 'fetch').mockImplementation(async (input) => { @@ -842,7 +842,7 @@ test('dashboard exposes end-to-end operations workflow entries', async () => { expect(screen.getByText('实时态势')).toBeInTheDocument(); expect(screen.getByText('轨迹复盘')).toBeInTheDocument(); expect(screen.getByText('历史证据')).toBeInTheDocument(); - expect(screen.getAllByText('告警通知').length).toBeGreaterThanOrEqual(1); + expect(screen.getAllByText('告警事件').length).toBeGreaterThanOrEqual(1); expect(screen.getByText('统计复核')).toBeInTheDocument(); fireEvent.click(screen.getByRole('button', { name: '闭环入口 轨迹复盘' })); @@ -8009,7 +8009,7 @@ test('opens quality issues from realtime vehicle row with source evidence', asyn await waitFor(() => { expect(window.location.hash).toBe('#/quality?keyword=VIN-RT-QUALITY&protocol=JT808'); }); - expect(await screen.findByRole('heading', { name: '告警通知' })).toBeInTheDocument(); + expect(await screen.findByRole('heading', { name: '告警事件' })).toBeInTheDocument(); }); test('loads realtime vehicles from shareable source filter hash', async () => { @@ -8711,7 +8711,7 @@ test('opens quality issues from source-filtered vehicle list with source evidenc await waitFor(() => { expect(window.location.hash).toBe('#/quality?keyword=VIN-LIST-QUALITY&protocol=JT808'); }); - expect(await screen.findByRole('heading', { name: '告警通知' })).toBeInTheDocument(); + expect(await screen.findByRole('heading', { name: '告警事件' })).toBeInTheDocument(); }); test('filters vehicle list by service status', async () => { @@ -8999,8 +8999,8 @@ test('opens quality governance from vehicle detail overview', async () => { await waitFor(() => { expect(window.location.hash).toBe('#/quality?keyword=VIN001'); }); - expect(await screen.findByRole('heading', { name: '告警通知' })).toBeInTheDocument(); - expect(screen.getByText('告警通知闭环')).toBeInTheDocument(); + expect(await screen.findByRole('heading', { name: '告警事件' })).toBeInTheDocument(); + expect(screen.getByText('告警事件闭环')).toBeInTheDocument(); expect(screen.getByText('事件触发')).toBeInTheDocument(); expect(fetchMock).toHaveBeenCalledWith(expect.stringContaining('/api/quality/issues?keyword=VIN001&limit=20&offset=0'), undefined); }); @@ -9026,7 +9026,7 @@ test('quality health storage card stays pending before ops health loads', async render(); - expect(await screen.findByRole('heading', { name: '告警通知' })).toBeInTheDocument(); + expect(await screen.findByRole('heading', { name: '告警事件' })).toBeInTheDocument(); expect(screen.getByText('存储读取')).toBeInTheDocument(); expect(screen.getByText('检测中')).toBeInTheDocument(); expect(screen.queryByText('异常')).not.toBeInTheDocument(); @@ -9052,7 +9052,7 @@ test('quality health shows active connection capacity metric', async () => { render(); - expect(await screen.findByRole('heading', { name: '告警通知' })).toBeInTheDocument(); + expect(await screen.findByRole('heading', { name: '告警事件' })).toBeInTheDocument(); expect(await screen.findByText('活跃连接')).toBeInTheDocument(); expect(screen.getByText('120,000')).toBeInTheDocument(); expect(screen.getByText('运行版本')).toBeInTheDocument(); @@ -9079,7 +9079,7 @@ test('quality health shows structured capacity findings', async () => { render(); - expect(await screen.findByRole('heading', { name: '告警通知' })).toBeInTheDocument(); + expect(await screen.findByRole('heading', { name: '告警事件' })).toBeInTheDocument(); expect(await screen.findByText('容量检查发现')).toBeInTheDocument(); expect(screen.getByText('kafka lag 42')).toBeInTheDocument(); });