feat(platform): prioritize alert handling

This commit is contained in:
lingniu
2026-07-04 11:22:06 +08:00
parent e94d0e348f
commit 02011035ae
2 changed files with 196 additions and 2 deletions

View File

@@ -2210,7 +2210,7 @@ test('renders quality issues as vehicle-service governance labels', async () =>
expect(await screen.findByText('VIN-NO-SOURCE-001')).toBeInTheDocument();
expect(screen.getAllByText('暂无数据来源').length).toBeGreaterThanOrEqual(1);
expect(screen.getAllByText('车辆服务').length).toBeGreaterThanOrEqual(1);
expect(screen.getByText('确认平台转发')).toBeInTheDocument();
expect(screen.getAllByText('确认平台转发').length).toBeGreaterThan(0);
expect(screen.getByText('车辆已绑定但没有任何来源证据,先确认平台转发、端口和订阅。')).toBeInTheDocument();
});
@@ -2296,6 +2296,123 @@ test('shows alert rule and notification policy workspace on quality page', async
expect(screen.getByText('站内告警 / 邮件 / 企业微信')).toBeInTheDocument();
});
test('shows actionable priority queue on quality page', async () => {
window.history.replaceState(null, '', '/#/quality');
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, activeConnections: 120000, capacityFindings: [], redisOnlineKeys: 368, 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: 2,
issueRecordCount: 2,
errorCount: 1,
warningCount: 1,
protocols: [{ name: 'VEHICLE_SERVICE', count: 1 }, { name: 'JT808', count: 1 }],
issueTypes: [{ name: 'NO_SOURCE', count: 1 }, { name: 'VIN_MISSING', count: 1 }]
},
traceId: 'trace-test',
timestamp: 1783094400000
})
} as Response;
}
if (path.includes('/api/quality/issues')) {
return {
ok: true,
json: async () => ({
data: {
items: [
{
vin: 'VIN-P0-001',
plate: '粤A优先1',
phone: '13307795425',
sourceEndpoint: '115.231.168.135:43625',
protocol: 'VEHICLE_SERVICE',
issueType: 'NO_SOURCE',
severity: 'error',
lastSeen: '2026-07-03 20:12:10',
detail: '车辆无任何来源'
},
{
vin: '',
plate: '粤A优先2',
phone: '13307795426',
sourceEndpoint: '115.231.168.135:43626',
protocol: 'JT808',
issueType: 'VIN_MISSING',
severity: 'warning',
lastSeen: '2026-07-03 20:10:10',
detail: '手机号未映射 VIN'
}
],
total: 2,
limit: 20,
offset: 0
},
traceId: 'trace-test',
timestamp: 1783094400000
})
} as Response;
}
if (path.includes('/api/vehicle-service/overview')) {
return {
ok: true,
json: async () => ({
data: {
vin: 'VIN-P0-001',
plate: '粤A优先1',
sourceCount: 0,
onlineSourceCount: 0,
coverageStatus: 'no_data',
primaryProtocol: 'VEHICLE_SERVICE',
lastSeen: '2026-07-03 20:12:10',
historyCount: 0,
rawCount: 0,
mileageCount: 0,
qualityIssueCount: 1
},
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(<App />);
expect(await screen.findByText('处置优先队列')).toBeInTheDocument();
expect(screen.getAllByText('P0').length).toBeGreaterThan(0);
expect(screen.getByText('粤A优先1 / VIN-P0-001')).toBeInTheDocument();
expect(screen.getAllByText('确认平台转发').length).toBeGreaterThan(0);
expect(screen.getAllByText('30 分钟确认').length).toBeGreaterThan(0);
expect(screen.getAllByText('P1').length).toBeGreaterThan(0);
expect(screen.getByText('粤A优先2 / 13307795426')).toBeInTheDocument();
fireEvent.click(screen.getAllByRole('button', { name: '进入车辆服务' })[0]);
await waitFor(() => {
expect(window.location.hash).toBe('#/detail?keyword=VIN-P0-001&protocol=VEHICLE_SERVICE');
});
});
test('opens vehicle service from quality issue with issue source evidence', async () => {
window.history.replaceState(null, '', '/#/quality');
vi.spyOn(globalThis, 'fetch').mockImplementation(async (input) => {
@@ -2387,7 +2504,7 @@ test('opens vehicle service from quality issue with issue source evidence', asyn
render(<App />);
expect(await screen.findByText('13307795425')).toBeInTheDocument();
expect(screen.getByText('维护身份绑定')).toBeInTheDocument();
expect(screen.getAllByText('维护身份绑定').length).toBeGreaterThan(0);
expect(screen.getByText('数据已有来源但无法归并到 VIN优先用车牌/手机号补齐绑定。')).toBeInTheDocument();
fireEvent.click(screen.getByRole('button', { name: '按车牌查车' }));