feat(platform): refine customer alert evidence copy
This commit is contained in:
@@ -67,7 +67,7 @@ const alertRuleTemplates = [
|
||||
level: 'P1',
|
||||
owner: '协议解析',
|
||||
trigger: '核心字段缺失导致定位、里程或统计不可用',
|
||||
notify: '通知解析负责人核对字段映射和 RAW 样本',
|
||||
notify: '通知解析负责人核对字段映射和原始记录样本',
|
||||
sla: '当日闭环'
|
||||
}
|
||||
];
|
||||
@@ -87,7 +87,7 @@ const notificationPolicies = [
|
||||
channel: '站内告警 / 每日汇总邮件',
|
||||
condition: '字段缺失、链路间断、容量风险',
|
||||
escalationMinutes: 120,
|
||||
acceptanceCriteria: '核心字段恢复解析,影响车辆可通过 RAW 与历史证据复核'
|
||||
acceptanceCriteria: '核心字段恢复解析,影响车辆可通过原始记录与历史证据复核'
|
||||
},
|
||||
{
|
||||
name: 'P2 趋势关注',
|
||||
@@ -187,7 +187,7 @@ function qualityActionRecommendation(row: QualityIssueRow) {
|
||||
return {
|
||||
label: '核对解析字段',
|
||||
color: 'orange' as const,
|
||||
detail: '字段缺失会影响统计和展示,优先核对解析映射和原始 RAW。'
|
||||
detail: '字段缺失会影响统计和展示,优先核对解析映射和原始记录。'
|
||||
};
|
||||
}
|
||||
return {
|
||||
@@ -317,7 +317,7 @@ function priorityIssueNotificationText(row: PriorityIssueRow) {
|
||||
`详情:${row.detail || '-'}`,
|
||||
`实时定位:${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-query', keyword: lookup.key, protocol: row.protocol, filters: { tab: 'raw', ...evidenceFilters, includeFields: 'true' } }))}`,
|
||||
`原始记录:${appURL(buildAppHash({ page: 'history-query', 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');
|
||||
@@ -329,10 +329,10 @@ function alertRuleTemplate(issueType: string) {
|
||||
|
||||
function acceptanceCriteria(row: PriorityIssueRow) {
|
||||
if (row.issueType === 'VIN_MISSING') {
|
||||
return '车辆能解析到 VIN,实时/历史/RAW 证据可通过同一车辆服务查询';
|
||||
return '车辆能解析到 VIN,实时、历史和原始记录可通过同一车辆服务查询';
|
||||
}
|
||||
if (row.issueType === 'NO_SOURCE') {
|
||||
return '至少一个生产来源恢复在线,车辆实时状态、历史轨迹和 RAW 证据可查询';
|
||||
return '至少一个生产来源恢复在线,车辆实时状态、历史轨迹和原始记录可查询';
|
||||
}
|
||||
if (row.issueType === 'LINK_GAP') {
|
||||
return '来源恢复连续上报,实时在线窗口和历史轨迹无异常断点';
|
||||
@@ -369,12 +369,12 @@ function priorityIssueTicketText(row: PriorityIssueRow) {
|
||||
`处置说明:${row.actionDetail || '-'}`,
|
||||
'处置步骤:',
|
||||
'1. 打开车辆服务核对当前身份解析结果',
|
||||
'2. 核对实时定位、轨迹证据和 RAW 证据',
|
||||
'2. 核对实时定位、轨迹证据和原始记录',
|
||||
'3. 完成后确认车辆服务状态恢复,问题不再命中当前告警',
|
||||
`验收标准:${acceptanceCriteria(row)}`,
|
||||
`实时定位:${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-query', keyword: lookup.key, protocol: row.protocol, filters: { tab: 'raw', ...evidenceFilters, includeFields: 'true' } }))}`,
|
||||
`原始记录:${appURL(buildAppHash({ page: 'history-query', 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');
|
||||
@@ -402,7 +402,7 @@ function priorityIssueEvidencePackageText(row: PriorityIssueRow) {
|
||||
`验收标准:${acceptanceCriteria(row)}`,
|
||||
`实时定位:${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-query', keyword: lookup.key, protocol: row.protocol, filters: { tab: 'raw', ...evidenceFilters, includeFields: 'true' } }))}`,
|
||||
`原始记录:${appURL(buildAppHash({ page: 'history-query', keyword: lookup.key, protocol: row.protocol, filters: { tab: 'raw', ...evidenceFilters, includeFields: 'true' } }))}`,
|
||||
`里程复核:${appURL(buildAppHash({ page: 'mileage', keyword: lookup.key, protocol: row.protocol, filters: evidenceFilters }))}`,
|
||||
`车辆服务:${appURL(buildAppHash({ page: 'detail', keyword: lookup.key, protocol: row.protocol }))}`,
|
||||
`告警筛选:${qualityShareURL()}`
|
||||
@@ -580,7 +580,7 @@ function notificationHandoffText({
|
||||
` 详情:${row.detail || '-'}`,
|
||||
` 实时:${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-query', keyword: lookup.key, protocol: row.protocol, filters: { tab: 'raw', ...evidenceFilters, includeFields: 'true' } }))}`,
|
||||
` 原始记录:${appURL(buildAppHash({ page: 'history-query', keyword: lookup.key, protocol: row.protocol, filters: { tab: 'raw', ...evidenceFilters, includeFields: 'true' } }))}`,
|
||||
` 车辆服务:${appURL(buildAppHash({ page: 'detail', keyword: lookup.key, protocol: row.protocol }))}`
|
||||
].join('\n');
|
||||
})
|
||||
@@ -593,7 +593,7 @@ function notificationHandoffText({
|
||||
`优先级:P0 ${p0Rows.length.toLocaleString()} 条 / P1 ${p1Rows.length.toLocaleString()} 条`,
|
||||
`活跃规则:${activeRules.length.toLocaleString()} 类${activeRules.length > 0 ? `(${activeRules.map((row) => `${row.level} ${row.title || qualityIssueLabel(row.issueType)} ${row.count}`).join(';')})` : ''}`,
|
||||
primaryPolicy ? `主通知策略:${[primaryPolicy.name, primaryPolicy.target, primaryPolicy.channel, formatEscalationMinutes(primaryPolicy.escalationMinutes)].filter(Boolean).join(' / ')}` : '主通知策略:-',
|
||||
primaryPolicy?.acceptanceCriteria ? `统一验收:${primaryPolicy.acceptanceCriteria}` : '统一验收:车辆服务状态恢复,实时、轨迹、RAW 证据可查询',
|
||||
primaryPolicy?.acceptanceCriteria ? `统一验收:${primaryPolicy.acceptanceCriteria}` : '统一验收:车辆服务状态恢复,实时、轨迹和原始记录可查询',
|
||||
'',
|
||||
'待通知车辆:',
|
||||
...issueLines,
|
||||
@@ -708,7 +708,7 @@ function alertCustomerDecisionText({
|
||||
'客户处置路径:',
|
||||
'1. 先确认影响车辆和 P0/P1 数量。',
|
||||
'2. P0 立即通知责任团队,超过 SLA 自动升级。',
|
||||
'3. 每辆焦点车都要打开实时、轨迹、RAW、里程证据闭环。',
|
||||
'3. 每辆焦点车都要打开实时、轨迹、原始记录、里程证据闭环。',
|
||||
'4. 恢复后确认告警不再命中,并保留交接包。',
|
||||
'',
|
||||
`告警事件:${qualityShareURL()}`,
|
||||
@@ -1031,7 +1031,7 @@ export function Quality({
|
||||
},
|
||||
{
|
||||
label: '证据闭环',
|
||||
value: '实时/轨迹/RAW/里程',
|
||||
value: '实时/轨迹/原始/里程',
|
||||
detail: '所有通知都必须回到车辆证据,不只停留在来源或链路指标。',
|
||||
color: 'blue' as const,
|
||||
action: '交接包',
|
||||
@@ -1067,7 +1067,7 @@ export function Quality({
|
||||
</Space>
|
||||
<strong>{issueVehicleCount.toLocaleString()} 辆车受影响</strong>
|
||||
<span>
|
||||
告警中心面向客户处置:先判断影响车辆和优先级,再通知责任团队,并用实时、轨迹、RAW、里程证据闭环。
|
||||
告警中心面向客户处置:先判断影响车辆和优先级,再通知责任团队,并用实时、轨迹、原始记录、里程证据闭环。
|
||||
</span>
|
||||
<Space wrap>
|
||||
<Button size="small" theme="solid" type="primary" disabled={priorityRows.length === 0} onClick={copyNotificationHandoff}>复制中心交接包</Button>
|
||||
@@ -1147,7 +1147,7 @@ export function Quality({
|
||||
<strong>{focusIssue?.vehicleLabel || '暂无优先车辆'}</strong>
|
||||
<span>
|
||||
{focusIssue
|
||||
? `${focusIssue.actionLabel}:${focusIssue.actionDetail || focusIssue.detail || '请结合实时、轨迹、RAW 和里程证据闭环。'}`
|
||||
? `${focusIssue.actionLabel}:${focusIssue.actionDetail || focusIssue.detail || '请结合实时、轨迹、原始记录和里程证据闭环。'}`
|
||||
: '当前没有进入优先队列的车辆,保持实时监控并定期复核告警规则。'}
|
||||
</span>
|
||||
<Space wrap>
|
||||
@@ -1190,9 +1190,9 @@ export function Quality({
|
||||
},
|
||||
{
|
||||
label: '原始证据',
|
||||
value: focusIssue ? '查RAW' : '待命',
|
||||
value: focusIssue ? '查原始' : '待命',
|
||||
detail: '保留原始帧和解析字段,给平台、客户和研发确认责任边界。',
|
||||
action: 'RAW证据',
|
||||
action: '原始记录',
|
||||
color: focusIssue ? 'blue' as const : 'grey' as const,
|
||||
disabled: !focusIssue || !focusLookup?.key || !onOpenRaw,
|
||||
onClick: () => focusIssue && openIssueRaw(focusIssue)
|
||||
@@ -1357,7 +1357,7 @@ export function Quality({
|
||||
<Space spacing={4} wrap>
|
||||
<Button size="small" disabled={!lookup.key || !onOpenRealtime} onClick={() => openIssueRealtime(row)}>实时定位</Button>
|
||||
<Button size="small" disabled={!lookup.key || !onOpenHistory} onClick={() => openIssueHistory(row)}>轨迹证据</Button>
|
||||
<Button size="small" disabled={!lookup.key || !onOpenRaw} onClick={() => openIssueRaw(row)}>RAW证据</Button>
|
||||
<Button size="small" disabled={!lookup.key || !onOpenRaw} onClick={() => openIssueRaw(row)}>原始记录</Button>
|
||||
<Button size="small" onClick={() => copyText(row.notificationText || priorityIssueNotificationText(row), '告警通知')}>复制通知</Button>
|
||||
<Button size="small" onClick={() => copyText(priorityIssueEvidencePackageText(row), '告警证据包')}>复制证据包</Button>
|
||||
<Button size="small" onClick={() => copyText(priorityIssueTicketText(row), '处置工单')}>复制工单</Button>
|
||||
@@ -1566,7 +1566,7 @@ export function Quality({
|
||||
<Button size="small" icon={<IconCopy />} onClick={() => copyText(row.sourceEndpoint, '来源')}>来源</Button>
|
||||
<Button size="small" disabled={!lookup.key || !onOpenRealtime} onClick={() => openIssueRealtime(row)}>实时状态</Button>
|
||||
<Button size="small" disabled={!lookup.key || !onOpenHistory} onClick={() => openIssueHistory(row)}>核对历史</Button>
|
||||
<Button size="small" disabled={!lookup.key || !onOpenRaw} onClick={() => openIssueRaw(row)}>核对 RAW</Button>
|
||||
<Button size="small" disabled={!lookup.key || !onOpenRaw} onClick={() => openIssueRaw(row)}>核对原始</Button>
|
||||
<Button size="small" disabled={!lookup.key || !onOpenMileage} onClick={() => openIssueMileage(row)}>核对里程</Button>
|
||||
<Button size="small" onClick={() => copyText(priorityIssueNotificationText(priorityIssueFromRow(row)), '告警通知')}>复制通知</Button>
|
||||
<Button size="small" onClick={() => copyText(priorityIssueEvidencePackageText(priorityIssueFromRow(row)), '告警证据包')}>复制证据包</Button>
|
||||
|
||||
Reference in New Issue
Block a user