diff --git a/vehicle-data-platform/apps/web/src/pages/Quality.tsx b/vehicle-data-platform/apps/web/src/pages/Quality.tsx
index 1ea28934..f126e079 100644
--- a/vehicle-data-platform/apps/web/src/pages/Quality.tsx
+++ b/vehicle-data-platform/apps/web/src/pages/Quality.tsx
@@ -145,6 +145,11 @@ export function Quality({
const drillIssueType = (issueType: string) => {
applyFilters({ ...filters, issueType });
};
+ const filterSummary = [
+ filters.keyword ? `关键词:${filters.keyword}` : '',
+ filters.protocol ? `数据来源:${qualityProtocolLabel(filters.protocol)}` : '',
+ filters.issueType ? `问题类型:${qualityIssueLabel(filters.issueType)}` : ''
+ ].filter(Boolean);
return (
@@ -190,6 +195,16 @@ export function Quality({
+ {filterSummary.length > 0 ? (
+
+
+ {filterSummary.map((item) => (
+ {item}
+ ))}
+
+
+
+ ) : null}
{
expect(fetchMock).toHaveBeenCalledWith(expect.stringContaining('/api/quality/summary?keyword=%E7%B2%A4A&protocol=VEHICLE_SERVICE&issueType=NO_SOURCE'), undefined);
});
+test('shows and clears current quality filters', async () => {
+ window.history.replaceState(null, '', '/#/quality?keyword=%E7%B2%A4A&protocol=VEHICLE_SERVICE&issueType=NO_SOURCE');
+ const fetchMock = vi.spyOn(globalThis, 'fetch').mockImplementation(async (input) => {
+ 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/quality/summary')) {
+ return {
+ ok: true,
+ json: async () => ({
+ data: {
+ issueVehicleCount: 1,
+ issueRecordCount: 1,
+ errorCount: 0,
+ warningCount: 1,
+ protocols: [{ name: 'VEHICLE_SERVICE', count: 1 }],
+ issueTypes: [{ name: 'NO_SOURCE', count: 1 }]
+ },
+ traceId: 'trace-test',
+ timestamp: 1783094400000
+ })
+ } as Response;
+ }
+ if (path.includes('/api/quality/issues')) {
+ return {
+ ok: true,
+ json: async () => ({
+ data: { items: [], total: 1, limit: 20, offset: 0 },
+ traceId: 'trace-test',
+ timestamp: 1783094400000
+ })
+ } as Response;
+ }
+ return {
+ ok: true,
+ json: async () => ({
+ data: { items: [], total: 0, limit: 20, offset: 0 },
+ traceId: 'trace-test',
+ timestamp: 1783094400000
+ })
+ } as Response;
+ });
+
+ render();
+
+ expect(await screen.findByText('当前筛选')).toBeInTheDocument();
+ expect(screen.getByText('关键词:粤A')).toBeInTheDocument();
+ expect(screen.getByText('数据来源:车辆服务')).toBeInTheDocument();
+ expect(screen.getByText('问题类型:暂无数据来源')).toBeInTheDocument();
+ fireEvent.click(screen.getByRole('button', { name: '清空筛选' }));
+
+ await waitFor(() => {
+ expect(fetchMock).toHaveBeenCalledWith(expect.stringContaining('/api/quality/issues?limit=20&offset=0'), undefined);
+ });
+ expect(window.location.hash).toBe('#/quality');
+});
+
test('copies shareable quality filter link', async () => {
window.history.replaceState(null, '', '/#/quality?keyword=%E7%B2%A4A&protocol=VEHICLE_SERVICE&issueType=NO_SOURCE');
const writeText = vi.fn().mockResolvedValue(undefined);