From d72da88c3fa12f431a6c7550c56e531f4428a430 Mon Sep 17 00:00:00 2001 From: lingniu Date: Sat, 4 Jul 2026 15:37:48 +0800 Subject: [PATCH] feat(platform): show release in topbar --- vehicle-data-platform/apps/web/src/App.tsx | 9 +++++++-- vehicle-data-platform/apps/web/src/layout/AppShell.tsx | 3 +++ vehicle-data-platform/apps/web/src/test/App.test.tsx | 10 +++++++++- 3 files changed, 19 insertions(+), 3 deletions(-) diff --git a/vehicle-data-platform/apps/web/src/App.tsx b/vehicle-data-platform/apps/web/src/App.tsx index d915770b..4e60e286 100644 --- a/vehicle-data-platform/apps/web/src/App.tsx +++ b/vehicle-data-platform/apps/web/src/App.tsx @@ -36,6 +36,7 @@ export default function App() { initialRoute.page === 'quality' ? qualityFiltersFromRoute(initialRoute) : {} ); const [linkIssueCount, setLinkIssueCount] = useState(null); + const [platformRelease, setPlatformRelease] = useState(''); const [currentVehicleStatus, setCurrentVehicleStatus] = useState(); const [currentVehicleLabel, setCurrentVehicleLabel] = useState(''); const [currentVehicleConsistency, setCurrentVehicleConsistency] = useState(); @@ -63,6 +64,7 @@ export default function App() { return api.opsHealth() .then((health) => { setLinkIssueCount(health.linkHealth.filter((item) => item.status !== 'ok').length); + setPlatformRelease(health.runtime?.platformRelease ?? ''); return health; }) .catch((error: Error) => { @@ -404,11 +406,14 @@ export default function App() { detail: , history: , mileage: , - quality: setLinkIssueCount(health.linkHealth.filter((item) => item.status !== 'ok').length)} onFiltersChange={updateQualityFilters} initialFilters={qualityFilters} /> + quality: { + setLinkIssueCount(health.linkHealth.filter((item) => item.status !== 'ok').length); + setPlatformRelease(health.runtime?.platformRelease ?? ''); + }} onFiltersChange={updateQualityFilters} initialFilters={qualityFilters} /> }; return ( - + {pages[activePage]} ); diff --git a/vehicle-data-platform/apps/web/src/layout/AppShell.tsx b/vehicle-data-platform/apps/web/src/layout/AppShell.tsx index d5a9e0e6..a41ad758 100644 --- a/vehicle-data-platform/apps/web/src/layout/AppShell.tsx +++ b/vehicle-data-platform/apps/web/src/layout/AppShell.tsx @@ -36,6 +36,7 @@ function linkHealthClassName(count: number | null) { export function AppShell({ activePage, linkIssueCount, + platformRelease, currentVehicleStatus, currentVehicleLabel, currentVehicleConsistency, @@ -45,6 +46,7 @@ export function AppShell({ }: { activePage: PageKey; linkIssueCount: number | null; + platformRelease?: string; currentVehicleStatus?: VehicleServiceStatus; currentVehicleLabel?: string; currentVehicleConsistency?: VehicleSourceConsistency; @@ -107,6 +109,7 @@ export function AppShell({ ) : null} 生产环境 + {platformRelease ? 版本 {platformRelease} : null} 多源接入 / 一个车辆服务 {amapConfigured ? '地图就绪' : '地图待配置'} 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 794fc74b..e7735a3a 100644 --- a/vehicle-data-platform/apps/web/src/test/App.test.tsx +++ b/vehicle-data-platform/apps/web/src/test/App.test.tsx @@ -23,7 +23,14 @@ test('exposes AMap operations shortcuts when map key is configured', async () => return { ok: true, json: async () => ({ - data: { linkHealth: [], kafkaLag: 0, redisOnlineKeys: 0, tdengineWritable: true, mysqlWritable: true, runtime: { requestTimeoutMs: 5000 } }, + data: { + linkHealth: [], + kafkaLag: 0, + redisOnlineKeys: 0, + tdengineWritable: true, + mysqlWritable: true, + runtime: { requestTimeoutMs: 5000, platformRelease: 'platform-20260704153357' } + }, traceId: 'trace-test', timestamp: 1783094400000 }) @@ -72,6 +79,7 @@ test('exposes AMap operations shortcuts when map key is configured', async () => render(); expect(await screen.findByText('地图就绪')).toBeInTheDocument(); + expect(screen.getByText('版本 platform-20260704153357')).toBeInTheDocument(); fireEvent.click(screen.getByRole('button', { name: '顶部实时监控' })); expect(window.location.hash).toBe('#/realtime'); fireEvent.click(screen.getByRole('button', { name: '顶部轨迹回放' }));