import React, { useState, useCallback, useMemo } from 'react'; import { Card, Row, Col, Typography, message } from 'antd'; import { DatabaseOutlined, CloudServerOutlined, WarningOutlined, HomeOutlined, TeamOutlined, BarChartOutlined, DashboardOutlined } from '@ant-design/icons'; import api from '../api'; import { designTokens } from '../config/theme'; import { useFetch } from '../hooks/useSWR'; import ErrorBoundary from '../components/ErrorBoundary'; import { AnimatedCounter, CircularProgress, PowerGauge, DeviceTrendChart, StatusLegend, StatCard, NavigationGrid, QuickStats, SystemInfo, } from '../components/dashboard'; const { Title } = Typography; const containerStyle = { minHeight: '100vh', background: 'linear-gradient(180deg, #f5f7fa 0%, #e8ecf1 100%)', padding: 'clamp(12px, 3vw, 20px)', }; const headerStyle = { textAlign: 'center', marginBottom: '32px', padding: 'clamp(20px, 5vw, 32px) clamp(16px, 4vw, 48px)', background: 'linear-gradient(135deg, #667eea 0%, #764ba2 100%)', borderRadius: 'clamp(12px, 3vw, 20px)', color: '#fff', boxShadow: '0 8px 32px rgba(102, 126, 234, 0.3)', animation: 'fadeInDown 0.6s ease-out', }; const titleStyle = { fontSize: 'clamp(1.4rem, 4vw, 2.2rem)', fontWeight: '700', color: '#fff', margin: '0 0 8px 0', display: 'flex', alignItems: 'center', justifyContent: 'center', gap: 'clamp(8px, 2vw, 16px)', flexWrap: 'wrap', textAlign: 'center', }; const subtitleStyle = { fontSize: 'clamp(0.85rem, 2.5vw, 1.1rem)', color: 'rgba(255, 255, 255, 0.85)', margin: '0', textAlign: 'center', }; const progressCardStyle = { borderRadius: designTokens.borderRadius.large, border: 'none', boxShadow: designTokens.shadows.medium, background: '#fff', height: '100%', animation: 'fadeInUp 0.6s ease-out 0.3s backwards', }; const chartContainerStyle = { padding: '20px', borderRadius: designTokens.borderRadius.medium, background: 'linear-gradient(135deg, #fafafa 0%, #f5f5f5 100%)', border: '1px solid #f0f0f0', }; const PIE_CHART_COLORS = { success: designTokens.colors.success.main, warning: designTokens.colors.warning.main, error: designTokens.colors.error.main, primary: designTokens.colors.primary.main, }; const pieChartStyle = { width: '180px', height: '180px', borderRadius: '50%', background: `conic-gradient( ${PIE_CHART_COLORS.success} 0deg 216deg, ${PIE_CHART_COLORS.warning} 216deg 288deg, ${PIE_CHART_COLORS.error} 288deg 324deg, ${PIE_CHART_COLORS.primary} 324deg 360deg )`, position: 'relative', display: 'flex', alignItems: 'center', justifyContent: 'center', }; const pieChartInner = { width: '120px', height: '120px', borderRadius: '50%', background: '#fff', display: 'flex', alignItems: 'center', justifyContent: 'center', flexDirection: 'column', }; const overviewCardStyle = { borderRadius: designTokens.borderRadius.large, border: 'none', boxShadow: designTokens.shadows.medium, background: '#fff', animation: 'fadeInUp 0.6s ease-out 0.2s backwards', }; function Dashboard() { const [hoveredCard, setHoveredCard] = useState(null); const [animatedKey, setAnimatedKey] = useState(0); const { data: devicesData, isLoading: devicesLoading, mutate: mutateDevices } = useFetch( '/devices?pageSize=1' ); const { data: racksData, isLoading: racksLoading } = useFetch('/racks?pageSize=1'); const { data: roomsData, isLoading: roomsLoading } = useFetch('/rooms'); const { data: usersData, isLoading: usersLoading } = useFetch('/users?pageSize=1'); const { data: ticketsData, isLoading: ticketsLoading } = useFetch('/tickets?pageSize=1&status=open'); const { data: faultData, isLoading: faultLoading } = useFetch('/devices?status=fault&pageSize=1'); const loading = devicesLoading || racksLoading || roomsLoading || usersLoading || ticketsLoading; const isRefreshing = devicesLoading && devicesData; const stats = useMemo(() => { const totalDevices = devicesData?.total || 0; const totalRacks = racksData?.total || 0; const rooms = roomsData || []; const totalRooms = Array.isArray(rooms) ? rooms.length : 0; const totalUsers = usersData?.total || 0; const activeTickets = ticketsData?.total || 0; const faultDevices = faultData?.total || 0; return { totalDevices, totalRacks, totalRooms, totalUsers, activeTickets, faultDevices, deviceGrowth: 2.5, faultTrend: -12.3, onlineRate: totalDevices > 0 ? (((totalDevices - faultDevices) / totalDevices) * 100).toFixed(1) : 100, powerUsage: Math.floor(Math.random() * 5000) + 2000, }; }, [devicesData, racksData, roomsData, usersData, ticketsData, faultData]); const handleRefresh = useCallback(async () => { setAnimatedKey((prev) => prev + 1); await Promise.all([ mutateDevices(), ]); }, [mutateDevices]); const handleHover = useCallback((key) => { setHoveredCard(key); }, []); const statCards = useMemo( () => [ { key: 'devices', xs: 12, sm: 12, md: 8, lg: 6, xl: 4, icon: CloudServerOutlined, color: designTokens.colors.primary.main, statKey: 'totalDevices', title: '总设备数', trend: stats.deviceGrowth, tagColor: 'blue', delay: 0, }, { key: 'racks', xs: 12, sm: 12, md: 8, lg: 6, xl: 4, icon: DatabaseOutlined, color: '#722ed1', statKey: 'totalRacks', title: '总机柜数', trend: 0, tagColor: 'green', customStatus: true, delay: 1, }, { key: 'rooms', xs: 12, sm: 12, md: 8, lg: 6, xl: 4, icon: HomeOutlined, color: designTokens.colors.success.main, statKey: 'totalRooms', title: '总机房数', trend: 0, tagColor: 'green', customStatus: true, delay: 2, }, { key: 'faults', xs: 12, sm: 12, md: 8, lg: 6, xl: 4, icon: WarningOutlined, color: designTokens.colors.error.main, statKey: 'faultDevices', title: '故障设备', trend: stats.faultTrend, tagColor: 'red', delay: 3, }, { key: 'users', xs: 12, sm: 12, md: 8, lg: 6, xl: 4, icon: TeamOutlined, color: '#13c2c2', statKey: 'totalUsers', title: '用户总数', trend: 5.2, tagColor: 'cyan', delay: 4, }, { key: 'tickets', xs: 12, sm: 12, md: 8, lg: 6, xl: 4, icon: BarChartOutlined, color: '#fa8c16', statKey: 'activeTickets', title: '待处理工单', trend: -8.5, tagColor: 'orange', delay: 5, }, ], [stats.deviceGrowth, stats.faultTrend] ); const deviceTrendData = useMemo( () => [ { label: '周一', value: 45, color: designTokens.colors.primary.main }, { label: '周二', value: 52, color: designTokens.colors.primary.main }, { label: '周三', value: 48, color: designTokens.colors.primary.main }, { label: '周四', value: 60, color: designTokens.colors.success.main }, { label: '周五', value: 55, color: designTokens.colors.success.main }, { label: '周六', value: 42, color: designTokens.colors.warning.main }, { label: '周日', value: 58, color: designTokens.colors.primary.main }, ], [] ); const styles = ` @keyframes fadeInDown { from { opacity: 0; transform: translateY(-20px); } to { opacity: 1; transform: translateY(0); } } @keyframes fadeInUp { from { opacity: 0; transform: translateY(20px); } to { opacity: 1; transform: translateY(0); } } `; return ( <>

IDC设备管理系统

实时监控 · 智能管理 · 高效运维

{statCards.map((config) => ( ))}
设备状态分布
{stats.totalDevices} 设备总数
系统健康指标
在线率图表加载失败
} > 功率仪表加载失败
} >
周设备趋势
趋势图表加载失败
} >
周一 至 周日 设备变化趋势

欢迎使用IDC设备管理系统

专业的机房设备管理解决方案,提供全方位的设备监控和管理能力

); } export default React.memo(Dashboard);