From 7c81285be8e13cac70e7531a01f62a5b3a4a3b18 Mon Sep 17 00:00:00 2001 From: lingniu Date: Sat, 4 Jul 2026 08:30:12 +0800 Subject: [PATCH] feat(platform): show active history filters --- vehicle-data-platform/apps/web/src/App.tsx | 7 ++- .../apps/web/src/pages/History.tsx | 30 ++++++++- .../apps/web/src/test/App.test.tsx | 61 +++++++++++++++++++ 3 files changed, 95 insertions(+), 3 deletions(-) diff --git a/vehicle-data-platform/apps/web/src/App.tsx b/vehicle-data-platform/apps/web/src/App.tsx index 6b197465..cc0fd648 100644 --- a/vehicle-data-platform/apps/web/src/App.tsx +++ b/vehicle-data-platform/apps/web/src/App.tsx @@ -196,7 +196,12 @@ export default function App() { } setActiveProtocol(nextFilters.protocol ?? ''); setHistoryTab(tab); - replaceHistoryHash(nextFilters, tab); + const { keyword, protocol, ...restFilters } = nextFilters; + const routeFilters = { ...restFilters }; + if (tab && tab !== 'location') { + routeFilters.tab = tab; + } + replaceHash('history', keyword ?? analysisVin, protocol, routeFilters); }; const replaceHistoryHash = (filters: Record = {}, tab = historyTab) => { diff --git a/vehicle-data-platform/apps/web/src/pages/History.tsx b/vehicle-data-platform/apps/web/src/pages/History.tsx index 288de426..83747b4b 100644 --- a/vehicle-data-platform/apps/web/src/pages/History.tsx +++ b/vehicle-data-platform/apps/web/src/pages/History.tsx @@ -139,14 +139,18 @@ export function History({ loadRawFrames(nextFilters, 1, rawPagination.pageSize); }; - const reset = () => { - const nextFilters = mergeInitialFilters(initialVin, initialProtocol, {}); + const applyFilters = (nextFilters: HistoryFilters) => { setFilters(nextFilters); onFiltersChange?.(nextFilters, activeTab); loadLocations(nextFilters, 1, locationPagination.pageSize); loadRawFrames(nextFilters, 1, rawPagination.pageSize); }; + const reset = () => { + const nextFilters = mergeInitialFilters(initialVin, initialProtocol, {}); + applyFilters(nextFilters); + }; + useEffect(() => { const nextFilters = mergeInitialFilters(initialVin, initialProtocol, initialFilters); setFilters(nextFilters); @@ -164,6 +168,18 @@ export function History({ const rawFieldCount = useMemo(() => Object.keys(selectedRaw?.parsedFields ?? {}).length, [selectedRaw]); const currentVehicleKeyword = filters.keyword?.trim() ?? ''; const currentProtocol = filters.protocol?.trim() ?? ''; + const selectedFieldCount = splitFields(filters.fields).length; + const filterSummary = [ + currentVehicleKeyword ? `车辆:${currentVehicleKeyword}` : '', + currentProtocol ? `数据来源:${currentProtocol}` : '', + filters.dateFrom?.trim() ? `开始时间:${filters.dateFrom.trim()}` : '', + filters.dateTo?.trim() ? `结束时间:${filters.dateTo.trim()}` : '', + isIncludeFieldsEnabled(filters.includeFields) ? '返回解析字段' : '', + selectedFieldCount > 0 ? `字段裁剪:${selectedFieldCount} 个` : '' + ].filter(Boolean); + const clearRangeFilters = () => { + applyFilters(currentVehicleKeyword ? { keyword: currentVehicleKeyword } : {}); + }; return (
@@ -207,6 +223,16 @@ export function History({ + {filterSummary.length > 0 ? ( + + + {filterSummary.map((item) => ( + {item} + ))} + + + + ) : null} changeTab(String(key))}> 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 f0a080d9..57a2b6ef 100644 --- a/vehicle-data-platform/apps/web/src/test/App.test.tsx +++ b/vehicle-data-platform/apps/web/src/test/App.test.tsx @@ -2294,6 +2294,67 @@ test('applies protocol from shareable history hash to API requests', async () => expect(screen.getByText('当前来源:JT808')).toBeInTheDocument(); }); +test('shows and clears current history filters while keeping vehicle scope', async () => { + window.history.replaceState(null, '', '/#/history?keyword=VIN-HISTORY-001&protocol=JT808&dateFrom=2026-07-01+00%3A00%3A00&dateTo=2026-07-01+23%3A59%3A59&includeFields=true&fields=jt808.location.longitude%2Cjt808.location.latitude&tab=raw'); + const fetchMock = vi.spyOn(globalThis, 'fetch').mockImplementation(async (input, init) => { + const path = String(input); + if (path.includes('/api/ops/health')) { + return { + ok: true, + json: async () => ({ + data: { linkHealth: [], kafkaLag: 0, redisOnlineKeys: 0, tdengineWritable: true, mysqlWritable: true, runtime: { requestTimeoutMs: 5000 } }, + traceId: 'trace-test', + timestamp: 1783094400000 + }) + } as Response; + } + if (path.includes('/api/history/locations')) { + return { + ok: true, + json: async () => ({ + data: { items: [], total: 0, limit: 10, offset: 0 }, + traceId: 'trace-test', + timestamp: 1783094400000 + }) + } as Response; + } + if (path.includes('/api/history/raw-frames/query')) { + return { + ok: true, + json: async () => ({ + data: { items: [], total: 0, limit: 10, offset: 0 }, + traceId: 'trace-test', + timestamp: 1783094400000 + }) + } as Response; + } + return { + ok: true, + json: async () => ({ + data: { items: [], total: 0, limit: 10, offset: 0 }, + traceId: 'trace-test', + timestamp: 1783094400000 + }) + } as Response; + }); + + render(); + + expect(await screen.findByText('当前历史筛选')).toBeInTheDocument(); + expect(screen.getByText('车辆:VIN-HISTORY-001')).toBeInTheDocument(); + expect(screen.getByText('数据来源:JT808')).toBeInTheDocument(); + expect(screen.getByText('开始时间:2026-07-01 00:00:00')).toBeInTheDocument(); + expect(screen.getByText('结束时间:2026-07-01 23:59:59')).toBeInTheDocument(); + expect(screen.getAllByText('返回解析字段').length).toBeGreaterThanOrEqual(2); + expect(screen.getByText('字段裁剪:2 个')).toBeInTheDocument(); + fireEvent.click(screen.getByRole('button', { name: '清空筛选' })); + + await waitFor(() => { + expect(fetchMock).toHaveBeenCalledWith(expect.stringContaining('/api/history/locations?limit=10&offset=0&keyword=VIN-HISTORY-001'), undefined); + }); + expect(window.location.hash).toBe('#/history?keyword=VIN-HISTORY-001&tab=raw'); +}); + test('updates history hash when vehicle history filters are submitted', async () => { window.history.replaceState(null, '', '/#/history'); const fetchMock = vi.spyOn(globalThis, 'fetch').mockImplementation(async (input, init) => {