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 (
数据概览
采集与存储整体状态
更新时间:{updateTime}
{overviewMetrics.map((m) => (
{m.icon}
{formatNumber(m.value)} {m.suffix}
{m.label}
))}
实时采集状态} 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.deviceName}
缺失时间: {c.missingTime}
持续时间: {c.duration}
采集频率: {c.frequency}
缺失数据量: {c.missingCount}
处理状态: {c.status}
))}
数据来源分布}>
来源
分布
{sourceSegments.map((s) => (
{s.name} {s.value}%
))}
存储空间使用预测} extra={已用总量} >
已用总量 54TB
近30天预测 54TB
近60天预测 54TB
'54TB'} />
''} />
''} />
); }; export default Cjgl;