From 4eda7b7e1b3b504068cd7262aea96666ebc0b5e2 Mon Sep 17 00:00:00 2001 From: lingniu Date: Sun, 5 Jul 2026 23:09:33 +0800 Subject: [PATCH] feat(platform): add alert action conclusion --- .../apps/web/src/pages/Quality.tsx | 69 +++++++++++++++ .../apps/web/src/styles/global.css | 84 +++++++++++++++++++ .../apps/web/src/test/App.test.tsx | 7 ++ 3 files changed, 160 insertions(+) diff --git a/vehicle-data-platform/apps/web/src/pages/Quality.tsx b/vehicle-data-platform/apps/web/src/pages/Quality.tsx index 28a720d1..03c01f8f 100644 --- a/vehicle-data-platform/apps/web/src/pages/Quality.tsx +++ b/vehicle-data-platform/apps/web/src/pages/Quality.tsx @@ -1128,6 +1128,48 @@ export function Quality({ onClick: copyAlertRecoveryReceipt } ]; + const alertActionConclusionItems = [ + { + label: '影响范围', + value: `${issueVehicleCount.toLocaleString()} 辆`, + detail: `${issueRecordCount.toLocaleString()} 条告警记录,先判断是否影响客户看车、轨迹和里程。`, + color: issueVehicleCount > 0 ? 'orange' as const : 'green' as const, + action: '复制影响', + onClick: () => copyBusinessImpact() + }, + { + label: '通知策略', + value: `P0 ${priorityP0Count.toLocaleString()} / P1 ${priorityP1Count.toLocaleString()}`, + detail: priorityRows.length > 0 ? '已进入责任团队通知队列。' : '当前没有待通知车辆。', + color: priorityP0Count > 0 ? 'red' as const : priorityP1Count > 0 ? 'orange' as const : 'green' as const, + action: '复制通知', + onClick: () => copyPriorityDigest() + }, + { + label: 'SLA策略', + value: customerDecision.label, + detail: primaryPolicy ? `${primaryPolicy.name} / ${formatEscalationMinutes(primaryPolicy.escalationMinutes) || '未配置升级'}` : '需要补充通知策略和升级时限。', + color: customerDecision.color, + action: '通知闭环', + onClick: () => onOpenNotificationRules?.() + }, + { + label: '证据闭环', + value: storageWritable ? '可复核' : '先修复存储', + detail: '通知必须带上实时、轨迹、里程和历史证据入口。', + color: storageWritable ? 'green' as const : 'red' as const, + action: '复制交接', + onClick: () => copyNotificationHandoff() + }, + { + label: '恢复回执', + value: primaryPolicy?.acceptanceCriteria ? '有标准' : '待补充', + detail: primaryPolicy?.acceptanceCriteria || '恢复后确认车辆服务状态、轨迹、历史和里程证据可查询。', + color: primaryPolicy?.acceptanceCriteria ? 'green' as const : 'orange' as const, + action: '复制回执', + onClick: () => copyAlertRecoveryReceipt() + } + ]; const alertCustomerServiceItems = [ { label: '影响车辆', @@ -1226,6 +1268,33 @@ export function Quality({ return (
+
+
+ + 告警处置结论栏 + 0 ? 'red' : priorityP1Count > 0 ? 'orange' : 'green'}> + P0 {priorityP0Count.toLocaleString()} / P1 {priorityP1Count.toLocaleString()} + + + 先判断客户受影响车辆,再确认通知、SLA、证据和恢复回执,避免告警停留在技术表格里。 +
+
+ {alertActionConclusionItems.map((item) => ( + + ))} +
+
diff --git a/vehicle-data-platform/apps/web/src/styles/global.css b/vehicle-data-platform/apps/web/src/styles/global.css index 59b63473..20677b71 100644 --- a/vehicle-data-platform/apps/web/src/styles/global.css +++ b/vehicle-data-platform/apps/web/src/styles/global.css @@ -6132,6 +6132,88 @@ button.vp-realtime-command-item:focus-visible { gap: 12px; } +.vp-alert-action-conclusion { + margin-top: 16px; + margin-bottom: 16px; + border: 1px solid rgba(239, 68, 68, 0.18); + border-radius: var(--vp-radius); + background: #fff; + display: grid; + grid-template-columns: minmax(280px, 0.42fr) minmax(0, 1.58fr); + overflow: hidden; + box-shadow: var(--vp-shadow-sm); +} + +.vp-alert-action-conclusion-summary { + padding: 18px; + border-right: 1px solid var(--vp-border); + background: #fff7f7; + display: grid; + gap: 10px; + align-content: center; +} + +.vp-alert-action-conclusion-summary strong { + color: var(--vp-text); + font-size: 18px; + line-height: 26px; + word-break: break-word; +} + +.vp-alert-action-conclusion-grid { + padding: 14px; + display: grid; + grid-template-columns: repeat(5, minmax(0, 1fr)); + gap: 10px; +} + +.vp-alert-action-conclusion-item { + min-height: 132px; + padding: 12px; + border: 1px solid rgba(239, 68, 68, 0.14); + border-radius: 8px; + background: #fbfcff; + color: inherit; + cursor: pointer; + font: inherit; + text-align: left; + display: grid; + gap: 8px; + align-content: start; +} + +.vp-alert-action-conclusion-item:hover, +.vp-alert-action-conclusion-item:focus-visible { + border-color: rgba(239, 68, 68, 0.42); + background: #fff7f7; + box-shadow: 0 0 0 3px rgba(239, 68, 68, 0.08); + outline: none; +} + +.vp-alert-action-conclusion-item strong { + color: var(--vp-text); + font-size: 17px; + line-height: 24px; + font-weight: 800; + word-break: break-word; +} + +.vp-alert-action-conclusion-item span { + color: var(--vp-text-muted); + font-size: 12px; + line-height: 18px; + word-break: break-word; +} + +.vp-alert-action-conclusion-item em { + align-self: end; + color: var(--vp-primary); + font-size: 12px; + font-style: normal; + font-weight: 800; + line-height: 18px; +} + .vp-alert-customer-service-desk { margin-top: 16px; margin-bottom: 16px; @@ -11526,6 +11608,8 @@ button.vp-realtime-command-item:focus-visible { .vp-conclusion-grid, .vp-monitor-layout, .vp-alert-flow, + .vp-alert-action-conclusion, + .vp-alert-action-conclusion-grid, .vp-alert-customer-service-desk, .vp-alert-customer-service-grid, .vp-alert-decision-board, diff --git a/vehicle-data-platform/apps/web/src/test/App.test.tsx b/vehicle-data-platform/apps/web/src/test/App.test.tsx index 503f6578..1e2a3caa 100644 --- a/vehicle-data-platform/apps/web/src/test/App.test.tsx +++ b/vehicle-data-platform/apps/web/src/test/App.test.tsx @@ -11746,6 +11746,13 @@ test('opens realtime status from quality issue row with source evidence', async render(); expect(await screen.findByText('13307795425')).toBeInTheDocument(); + expect(screen.getByText('告警处置结论栏')).toBeInTheDocument(); + expect(screen.getByText('先判断客户受影响车辆,再确认通知、SLA、证据和恢复回执,避免告警停留在技术表格里。')).toBeInTheDocument(); + expect(screen.getByRole('button', { name: '告警处置结论栏 影响范围 1 辆 复制影响' })).toBeInTheDocument(); + expect(screen.getByRole('button', { name: '告警处置结论栏 通知策略 P0 1 / P1 0 复制通知' })).toBeInTheDocument(); + expect(screen.getByRole('button', { name: '告警处置结论栏 SLA策略 立即处置 通知闭环' })).toBeInTheDocument(); + expect(screen.getByRole('button', { name: '告警处置结论栏 证据闭环 可复核 复制交接' })).toBeInTheDocument(); + expect(screen.getByRole('button', { name: '告警处置结论栏 恢复回执 有标准 复制回执' })).toBeInTheDocument(); expect(screen.getByText('客户告警服务台')).toBeInTheDocument(); expect(screen.getByText('客户先看到哪些车受影响、是否要通知、证据是否齐全、恢复后如何验收。')).toBeInTheDocument(); expect(screen.getByRole('button', { name: '客户告警服务台 影响车辆 1 辆 复制影响' })).toBeInTheDocument();