import React, { useMemo, useState } from 'react';
import {
Badge,
Button,
Card,
Col,
List,
Progress,
Row,
Space,
Statistic,
Tag,
Typography,
} from 'antd';
import {
CloudSyncOutlined,
DatabaseOutlined,
ExclamationCircleOutlined,
HddOutlined,
ReloadOutlined,
} from '@ant-design/icons';
import styles from './Cjgl.less';
const { Text } = Typography;
const formatNumber = (value) => {
if (value === null || value === undefined) return '--';
const str = String(value);
return str.replace(/\B(?=(\d{3})+(?!\d))/g, ',');
};
const buildConicGradient = (segments) => {
const total = segments.reduce((sum, s) => sum + (Number(s.value) || 0), 0) || 1;
let start = 0;
const stops = segments
.map((s) => {
const ratio = (Number(s.value) || 0) / total;
const end = start + ratio;
const result = `${s.color} ${Math.round(start * 360)}deg ${Math.round(end * 360)}deg`;
start = end;
return result;
})
.join(', ');
return `conic-gradient(${stops})`;
};
const Cjgl = () => {
const [activeAnomaly, setActiveAnomaly] = useState('missing');
const overviewMetrics = useMemo(
() => [
{
key: 'deviceTotal',
label: '采集设备',
value: 52,
suffix: '台',
tone: 'primary',
icon: ,
},
{
key: 'deviceOnline',
label: '在线设备',
value: 45,
suffix: '台',
tone: 'primary',
icon: ,
},
{
key: 'todayCount',
label: '今日采集量',
value: 151235,
suffix: '',
tone: 'primary',
icon: ,
},
{
key: 'manualCount',
label: '手工录入',
value: 87,
suffix: '条',
tone: 'primary',
icon: ,
},
{
key: 'successRate',
label: '采集成功率',
value: 68,
suffix: '%',
tone: 'success',
icon: ,
},
{
key: 'storageRate',
label: '存储使用率',
value: 89,
suffix: '%',
tone: 'warning',
icon: ,
},
],
[],
);
const realtimeSummary = useMemo(
() => [
{ label: '运行中', value: 52, unit: '台', tone: 'primary' },
{ label: '设备类型', value: 5, unit: '种', tone: 'primary' },
{ label: '警告数', value: 3, unit: '条', tone: 'danger' },
],
[],
);
const devices = useMemo(
() =>
new Array(8).fill(0).map((_, idx) => ({
id: `SDO292938387-${idx + 1}`,
name: `变压器#${(idx % 3) + 1}`, // 仅作演示
frequency: '1分钟',
lastTime: '2024-06-10 14:29:30',
status: idx === 5 ? '异常' : '正常',
})),
[],
);
const anomalyTypes = useMemo(
() => [
{ key: 'missing', title: '数据缺失', desc: '范围超限', badge: 5 },
{ key: 'logic', title: '逻辑矛盾', desc: '', badge: 0 },
{ key: 'time', title: '时间异常', desc: '', badge: 0 },
],
[],
);
const anomalyCards = useMemo(
() =>
new Array(3).fill(0).map((_, idx) => ({
id: `anomaly-${activeAnomaly}-${idx}`,
deviceName: '变压器#1 (TR-001)',
missingTime: '14:20:00 至 14:25:00',
duration: '5分钟',
frequency: '10秒/次',
missingCount: '30条记录',
status: idx === 2 ? '待处理' : '已自动恢复',
})),
[activeAnomaly],
);
const sourceSegments = useMemo(
() => [
{ name: '自动采集', value: 23, color: '#3b82f6' },
{ name: '手工录入', value: 39, color: '#22c55e' },
{ name: '手工补录', value: 48, color: '#f59e0b' },
],
[],
);
const donutBg = useMemo(() => buildConicGradient(sourceSegments), [sourceSegments]);
const updateTime = useMemo(() => '2024-05-10 14:00:00', []);
return (
{overviewMetrics.map((m) => (
{m.icon}
{formatNumber(m.value)}
{m.suffix}
{m.label}
))}
实时采集状态}
extra={
} className={styles.iconBtn} />
}
>
{realtimeSummary.map((s) => (
{s.value}
{s.unit}
{s.label}
))}
(
{item.name}
#{item.id}
采集频率:
{item.frequency}
最后采集时间:
{item.lastTime}
{item.status}
)}
/>
今日数据异常统计}
extra={
}
>
{anomalyTypes.map((t) => (
setActiveAnomaly(t.key)}
role="button"
tabIndex={0}
>
{t.title}
{t.badge ? (
) : null}
{t.desc ?
{t.desc}
: null}
))}
{anomalyCards.map((c) => (
缺失时间:
{c.missingTime}
持续时间:
{c.duration}
采集频率:
{c.frequency}
缺失数据量:
{c.missingCount}
处理状态:
{c.status}
))}
数据来源分布}>
{sourceSegments.map((s) => (
{s.name}
{s.value}%
))}
存储空间使用预测}
extra={已用总量}
>
已用总量
54TB
近30天预测
54TB
近60天预测
54TB
);
};
export default Cjgl;