feat(platform): include evidence links in alert notifications

This commit is contained in:
lingniu
2026-07-04 13:00:10 +08:00
parent 783c8eba5e
commit 8c35bf9f2c
2 changed files with 22 additions and 2 deletions

View File

@@ -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');
}

View File

@@ -2495,7 +2495,11 @@ test('copies notification text from quality priority queue', async () => {
expect(writeText).toHaveBeenCalledWith(expect.stringContaining('SLA2 小时修复'));
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 () => {