feat(platform): add alert dispatch board
This commit is contained in:
@@ -123,6 +123,16 @@ type PriorityIssueRow = QualityIssueRow & {
|
||||
notificationText?: string;
|
||||
};
|
||||
|
||||
type AlertDispatchOwnerRow = {
|
||||
owner: string;
|
||||
activeRuleCount: number;
|
||||
hitCount: number;
|
||||
p0Count: number;
|
||||
primaryIssueType: string;
|
||||
primarySla: string;
|
||||
primaryHitCount: number;
|
||||
};
|
||||
|
||||
function qualityParams(values: Record<string, string>) {
|
||||
const params = new URLSearchParams();
|
||||
if (values?.keyword) params.set('keyword', values.keyword);
|
||||
@@ -217,6 +227,35 @@ function alertRuleRows(summary: QualitySummary, health: OpsHealth | null): Alert
|
||||
return rows;
|
||||
}
|
||||
|
||||
function alertDispatchOwnerRows(rules: AlertRuleRow[]): AlertDispatchOwnerRow[] {
|
||||
const ownerMap = new Map<string, AlertDispatchOwnerRow>();
|
||||
rules.forEach((rule) => {
|
||||
const owner = rule.owner || '未分配';
|
||||
const current = ownerMap.get(owner) ?? {
|
||||
owner,
|
||||
activeRuleCount: 0,
|
||||
hitCount: 0,
|
||||
p0Count: 0,
|
||||
primaryIssueType: rule.issueType,
|
||||
primarySla: rule.sla,
|
||||
primaryHitCount: 0
|
||||
};
|
||||
current.activeRuleCount += rule.count > 0 ? 1 : 0;
|
||||
current.hitCount += rule.count;
|
||||
current.p0Count += rule.count > 0 && rule.level === 'P0' ? 1 : 0;
|
||||
const shouldReplacePrimary = rule.count > current.primaryHitCount || (rule.count === current.primaryHitCount && rule.level === 'P0');
|
||||
if (shouldReplacePrimary) {
|
||||
current.primaryIssueType = rule.issueType;
|
||||
current.primarySla = rule.sla;
|
||||
current.primaryHitCount = rule.count;
|
||||
}
|
||||
ownerMap.set(owner, current);
|
||||
});
|
||||
return [...ownerMap.values()]
|
||||
.filter((row) => row.hitCount > 0 || row.activeRuleCount > 0)
|
||||
.sort((left, right) => right.p0Count - left.p0Count || right.hitCount - left.hitCount || left.owner.localeCompare(right.owner));
|
||||
}
|
||||
|
||||
function issueSla(issueType: string) {
|
||||
return alertRuleTemplates.find((item) => item.issueType === issueType)?.sla ?? '当日闭环';
|
||||
}
|
||||
@@ -627,6 +666,7 @@ export function Quality({
|
||||
const activeRuleCount = notificationPlan?.activeRuleCount ?? rules.filter((item) => item.count > 0).length;
|
||||
const p0RuleCount = notificationPlan?.p0RuleCount ?? rules.filter((item) => item.count > 0 && item.level === 'P0').length;
|
||||
const priorityRows = normalizePriorityIssues(notificationPlan?.priorityIssues) ?? priorityIssueRows(issues);
|
||||
const dispatchOwnerRows = alertDispatchOwnerRows(rules);
|
||||
|
||||
const loadIssues = (values: Record<string, string> = filters, page = pagination.currentPage, pageSize = pagination.pageSize) => {
|
||||
setLoadingIssues(true);
|
||||
@@ -836,6 +876,33 @@ export function Quality({
|
||||
))}
|
||||
</div>
|
||||
</Card>
|
||||
<Card bordered title="告警分派看板" style={{ marginTop: 16 }}>
|
||||
<div className="vp-alert-dispatch-grid">
|
||||
{dispatchOwnerRows.length === 0 ? (
|
||||
<Tag color="green">暂无待分派告警</Tag>
|
||||
) : dispatchOwnerRows.map((item) => (
|
||||
<button
|
||||
key={item.owner}
|
||||
type="button"
|
||||
className="vp-alert-dispatch-item"
|
||||
aria-label={`分派团队 ${item.owner}`}
|
||||
onClick={() => drillIssueType(item.primaryIssueType)}
|
||||
>
|
||||
<div className="vp-alert-dispatch-head">
|
||||
<Tag color={item.p0Count > 0 ? 'red' : 'orange'}>{item.owner}</Tag>
|
||||
<strong>{item.hitCount.toLocaleString()} 条</strong>
|
||||
</div>
|
||||
<div className="vp-alert-policy-detail">
|
||||
活跃规则 {item.activeRuleCount.toLocaleString()} 类 / P0 {item.p0Count.toLocaleString()} 类
|
||||
</div>
|
||||
<div className="vp-alert-policy-detail">
|
||||
主问题:{item.primaryIssueType === 'CAPACITY_RISK' ? '容量与存储风险' : qualityIssueLabel(item.primaryIssueType)}
|
||||
</div>
|
||||
<div className="vp-alert-policy-detail">SLA:{item.primarySla}</div>
|
||||
</button>
|
||||
))}
|
||||
</div>
|
||||
</Card>
|
||||
<Card
|
||||
bordered
|
||||
title={(
|
||||
|
||||
Reference in New Issue
Block a user