feat(platform): include evidence links in alert notifications
This commit is contained in:
@@ -4,6 +4,7 @@ import { useEffect, useState } from 'react';
|
||||
import { api } from '../api/client';
|
||||
import type { OpsHealth, QualitySummary, QualityIssueRow } from '../api/types';
|
||||
import { PageHeader } from '../components/PageHeader';
|
||||
import { buildAppHash } from '../domain/appRoute';
|
||||
import { qualityIssueLabel, qualityIssueOptions, qualityProtocolLabel, qualityProtocolOptions } from '../domain/qualityIssue';
|
||||
import { qualityIssueVehicleLookup } from '../domain/vehicleLookup';
|
||||
|
||||
@@ -121,6 +122,10 @@ function qualityShareURL() {
|
||||
return `${window.location.origin}${window.location.pathname}${window.location.hash}`;
|
||||
}
|
||||
|
||||
function appURL(hash: string) {
|
||||
return `${window.location.origin}${window.location.pathname}${hash}`;
|
||||
}
|
||||
|
||||
function issueEvidenceDate(value?: string) {
|
||||
const match = String(value ?? '').match(/^(\d{4})-(\d{2})-(\d{2})/);
|
||||
return match ? `${match[1]}-${match[2]}-${match[3]}` : '';
|
||||
@@ -237,6 +242,13 @@ function priorityIssueRows(rows: QualityIssueRow[]): PriorityIssueRow[] {
|
||||
}
|
||||
|
||||
function priorityIssueNotificationText(row: PriorityIssueRow) {
|
||||
const lookup = qualityIssueVehicleLookup(row);
|
||||
const dateFrom = issueEvidenceDate(row.lastSeen);
|
||||
const dateTo = nextDate(dateFrom);
|
||||
const evidenceFilters = {
|
||||
...(dateFrom ? { dateFrom } : {}),
|
||||
...(dateTo ? { dateTo } : {})
|
||||
};
|
||||
return [
|
||||
`【${row.priority} 告警通知】${qualityIssueLabel(row.issueType)}`,
|
||||
`车辆:${row.vehicleLabel}`,
|
||||
@@ -246,7 +258,11 @@ function priorityIssueNotificationText(row: PriorityIssueRow) {
|
||||
`SLA:${row.sla}`,
|
||||
`最后时间:${row.lastSeen || '-'}`,
|
||||
`详情:${row.detail || '-'}`,
|
||||
`证据入口:${qualityShareURL()}`
|
||||
`实时定位:${appURL(buildAppHash({ page: 'realtime', keyword: lookup.key, protocol: row.protocol }))}`,
|
||||
`轨迹证据:${appURL(buildAppHash({ page: 'history', keyword: lookup.key, protocol: row.protocol, filters: evidenceFilters }))}`,
|
||||
`RAW证据:${appURL(buildAppHash({ page: 'history', keyword: lookup.key, protocol: row.protocol, filters: { tab: 'raw', ...evidenceFilters, includeFields: 'true' } }))}`,
|
||||
`车辆服务:${appURL(buildAppHash({ page: 'detail', keyword: lookup.key, protocol: row.protocol }))}`,
|
||||
`告警筛选:${qualityShareURL()}`
|
||||
].join('\n');
|
||||
}
|
||||
|
||||
|
||||
@@ -2495,7 +2495,11 @@ test('copies notification text from quality priority queue', async () => {
|
||||
expect(writeText).toHaveBeenCalledWith(expect.stringContaining('SLA:2 小时修复'));
|
||||
expect(writeText).toHaveBeenCalledWith(expect.stringContaining('最后时间:2026-07-03 20:12:10'));
|
||||
expect(writeText).toHaveBeenCalledWith(expect.stringContaining('详情:手机号未映射 VIN,需要维护 binding'));
|
||||
expect(writeText).toHaveBeenCalledWith(expect.stringContaining('/#/quality'));
|
||||
expect(writeText).toHaveBeenCalledWith(expect.stringContaining('实时定位:http://localhost:3000/#/realtime?keyword=%E7%B2%A4A%E9%80%9A%E7%9F%A51&protocol=JT808'));
|
||||
expect(writeText).toHaveBeenCalledWith(expect.stringContaining('轨迹证据:http://localhost:3000/#/history?keyword=%E7%B2%A4A%E9%80%9A%E7%9F%A51&protocol=JT808&dateFrom=2026-07-03&dateTo=2026-07-04'));
|
||||
expect(writeText).toHaveBeenCalledWith(expect.stringContaining('RAW证据:http://localhost:3000/#/history?keyword=%E7%B2%A4A%E9%80%9A%E7%9F%A51&protocol=JT808&tab=raw&dateFrom=2026-07-03&dateTo=2026-07-04&includeFields=true'));
|
||||
expect(writeText).toHaveBeenCalledWith(expect.stringContaining('车辆服务:http://localhost:3000/#/detail?keyword=%E7%B2%A4A%E9%80%9A%E7%9F%A51&protocol=JT808'));
|
||||
expect(writeText).toHaveBeenCalledWith(expect.stringContaining('告警筛选:http://localhost:3000/#/quality'));
|
||||
});
|
||||
|
||||
test('opens realtime map context from quality priority queue', async () => {
|
||||
|
||||
Reference in New Issue
Block a user