feat(platform): center console on vehicle service

This commit is contained in:
lingniu
2026-07-04 18:40:36 +08:00
parent bdad6f7bf7
commit 48642726aa
5 changed files with 161 additions and 16 deletions

View File

@@ -1,4 +1,4 @@
import { Button, Card, Space, Table, Tag, Toast } from '@douyinfe/semi-ui';
import { Button, Card, Space, Table, Tag, Toast, Typography } from '@douyinfe/semi-ui';
import { useEffect, useState } from 'react';
import { api } from '../api/client';
import type { LinkHealth, OpsHealth } from '../api/types';
@@ -37,6 +37,89 @@ function amapSecurityColor(health: OpsHealth | null): 'green' | 'orange' | 'red'
return 'orange';
}
type CapacityRisk = {
key: string;
title: string;
value: string;
category: string;
severity: 'warning' | 'error';
finding: string;
action: string;
};
function firstNumber(value: string) {
const match = value.match(/[\d,.]+/);
return match ? match[0] : '-';
}
function capacityRisk(finding: string): CapacityRisk {
const lower = finding.toLowerCase();
if (lower.includes('bridge') && lower.includes('ack pending')) {
return {
key: finding,
title: 'NATS 桥接 ACK 未确认',
value: firstNumber(finding),
category: 'NATS -> Kafka',
severity: 'error',
finding,
action: '优先检查 Kafka 是否监听 9092、磁盘是否打满以及桥接服务是否持续写入成功。'
};
}
if (lower.includes('bridge') && lower.includes('consumer pending')) {
return {
key: finding,
title: 'NATS 桥接待消费',
value: firstNumber(finding),
category: 'NATS -> Kafka',
severity: 'warning',
finding,
action: '确认 Kafka 已恢复后观察 pending 是否持续下降;若不下降,扩容桥接或降低 Kafka topic 保留压力。'
};
}
if (lower.includes('kafka') || lower.includes('lag')) {
return {
key: finding,
title: 'Kafka 消费积压',
value: firstNumber(finding),
category: 'Kafka',
severity: 'warning',
finding,
action: '检查消费者组 lag、topic retention、broker 磁盘和生产写入错误。'
};
}
if (lower.includes('redis')) {
return {
key: finding,
title: 'Redis 在线投影异常',
value: firstNumber(finding),
category: 'Redis',
severity: 'warning',
finding,
action: '核对 realtime KV、online TTL 和协议实时帧过滤,确认车辆在线统计来源。'
};
}
if (lower.includes('connection')) {
return {
key: finding,
title: '网关连接压力',
value: firstNumber(finding),
category: 'Gateway',
severity: 'warning',
finding,
action: '查看 32960、808、MQTT 连接数、系统 FD、CPU 和接入端口队列。'
};
}
return {
key: finding,
title: '容量风险',
value: firstNumber(finding),
category: 'General',
severity: 'warning',
finding,
action: '进入对应链路日志和指标继续定位,确认是否影响车辆实时服务。'
};
}
export function OpsQuality() {
const [health, setHealth] = useState<OpsHealth | null>(null);
const [loading, setLoading] = useState(true);
@@ -54,6 +137,8 @@ export function OpsQuality() {
}, []);
const runtime = health?.runtime;
const capacityRisks = (health?.capacityFindings ?? []).map(capacityRisk);
const bridgeRisks = capacityRisks.filter((item) => item.category === 'NATS -> Kafka');
return (
<div className="vp-page">
@@ -111,13 +196,29 @@ export function OpsQuality() {
</Space>
</Card>
{health?.capacityFindings?.length ? (
{capacityRisks.length ? (
<Card bordered title="容量与风险发现" style={{ marginTop: 16 }}>
<Space wrap>
{health.capacityFindings.map((item) => (
<Tag key={item} color="orange">{item}</Tag>
<div className="vp-risk-grid">
{capacityRisks.map((item) => (
<div key={item.key} className="vp-risk-item">
<Space wrap>
<Tag color={item.severity === 'error' ? 'red' : 'orange'}>{item.category}</Tag>
<Tag color="grey">{item.finding}</Tag>
</Space>
<div className="vp-risk-value">{item.value}</div>
<Typography.Title heading={6} style={{ margin: 0 }}>{item.title}</Typography.Title>
<Typography.Text type="secondary">{item.action}</Typography.Text>
</div>
))}
</Space>
</div>
{bridgeRisks.length ? (
<div className="vp-risk-runbook">
<Tag color="blue"></Tag>
<Typography.Text>
Kafka broker ACK pending 0 consumer pending
</Typography.Text>
</div>
) : null}
</Card>
) : null}