import React, { useState, useEffect, useCallback, useMemo, useRef } from 'react'; import { Card, Row, Col, Statistic, message, Button, Tag, Typography, Progress, Spin } from 'antd'; import { DatabaseOutlined, CloudServerOutlined, WarningOutlined, HomeOutlined, SettingOutlined, ArrowUpOutlined, ArrowDownOutlined, DashboardOutlined, ReloadOutlined, EnvironmentOutlined, LineChartOutlined, SafetyOutlined, TeamOutlined, ThunderboltOutlined, AppstoreOutlined, BarChartOutlined } from '@ant-design/icons'; import api from '../api'; const { Title, Text } = Typography; const designTokens = { colors: { primary: { main: '#1890ff', light: '#40a9ff', dark: '#096dd9', gradient: 'linear-gradient(135deg, #1890ff 0%, #096dd9 100%)', bgGradient: 'linear-gradient(135deg, #1890ff15 0%, #096dd908 100%)' }, success: { main: '#52c41a', light: '#73d13d', dark: '#389e0d', gradient: 'linear-gradient(135deg, #52c41a 0%, #389e0d 100%)', bgGradient: 'linear-gradient(135deg, #52c41a15 0%, #389e0d08 100%)' }, warning: { main: '#faad14', light: '#ffc53d', dark: '#d48806', gradient: 'linear-gradient(135deg, #faad14 0%, #d48806 100%)', bgGradient: 'linear-gradient(135deg, #faad1415 0%, #d4880608 100%)' }, error: { main: '#ff4d4f', light: '#ff7875', dark: '#cf1322', gradient: 'linear-gradient(135deg, #ff4d4f 0%, #cf1322 100%)', bgGradient: 'linear-gradient(135deg, #ff4d4f15 0%, #cf132208 100%)' }, purple: { main: '#722ed1', light: '#9254de', dark: '#531dab', gradient: 'linear-gradient(135deg, #722ed1 0%, #531dab 100%)', bgGradient: 'linear-gradient(135deg, #722ed115 0%, #531dab08 100%)' }, cyan: { main: '#13c2c2', light: '#36cfc9', dark: '#08979c', gradient: 'linear-gradient(135deg, #13c2c2 0%, #08979c 100%)', bgGradient: 'linear-gradient(135deg, #13c2c215 0%, #08979c08 100%)' }, text: { primary: '#262626', secondary: '#8c8c8c', tertiary: '#bfbfbf' } }, shadows: { small: '0 2px 8px rgba(0, 0, 0, 0.06)', medium: '0 4px 16px rgba(0, 0, 0, 0.08)', large: '0 8px 24px rgba(0, 0, 0, 0.12)', hover: '0 12px 32px rgba(0, 0, 0, 0.15)' }, borderRadius: { small: '8px', medium: '12px', large: '16px', xl: '20px' }, transitions: { fast: '0.15s ease', normal: '0.3s cubic-bezier(0.4, 0, 0.2, 1)', slow: '0.5s cubic-bezier(0.4, 0, 0.2, 1)' } }; const responsiveConfig = { xs: { span: 24 }, sm: { span: 12 }, md: { span: 8 }, lg: { span: 6 }, xl: { span: 5 }, xxl: { span: 4 } }; 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 trendItemStyle = { display: 'flex', alignItems: 'center', justifyContent: 'space-between', padding: '12px 0', borderBottom: '1px solid #f0f0f0' }; const STAT_CARD_BASE_STYLE = { borderRadius: designTokens.borderRadius.large, border: 'none', boxShadow: designTokens.shadows.medium, background: '#fff', transition: `all ${designTokens.transitions.normal}`, overflow: 'hidden', cursor: 'pointer', height: '100%', animation: 'fadeInUp 0.6s ease-out backwards', borderLeft: '4px solid transparent' }; const STAT_ICON_CONTAINER_BASE = { width: 'clamp(40px, 8vw, 64px)', height: 'clamp(40px, 8vw, 64px)', borderRadius: designTokens.borderRadius.medium, display: 'flex', alignItems: 'center', justifyContent: 'center', fontSize: 'clamp(20px, 4vw, 32px)', transition: `all ${designTokens.transitions.normal}`, flexShrink: 0 }; const NAV_BUTTON_BASE = { height: 'auto', padding: 'clamp(16px, 4vw, 24px) clamp(12px, 3vw, 20px)', borderRadius: designTokens.borderRadius.medium, border: '2px solid #f0f0f0', background: '#fff', transition: `all ${designTokens.transitions.normal}`, display: 'flex', flexDirection: 'column', alignItems: 'center', gap: 'clamp(8px, 2vw, 12px)', cursor: 'pointer', boxShadow: designTokens.shadows.small, minWidth: '0' }; const NAV_ICON_CONTAINER_BASE = { width: 'clamp(44px, 10vw, 60px)', height: 'clamp(44px, 10vw, 60px)', borderRadius: designTokens.borderRadius.medium, display: 'flex', alignItems: 'center', justifyContent: 'center', fontSize: 'clamp(20px, 5vw, 28px)', transition: `all ${designTokens.transitions.normal}`, flexShrink: 0 }; const createStatCardStyle = (color) => ({ ...STAT_CARD_BASE_STYLE, borderLeftColor: color }); const createStatIconContainer = (color) => ({ ...STAT_ICON_CONTAINER_BASE, background: `linear-gradient(135deg, ${color}20 0%, ${color}10 100%)` }); const createNavButtonStyle = (color) => ({ ...NAV_BUTTON_BASE, borderColor: color }); const createNavIconContainer = (color) => ({ ...NAV_ICON_CONTAINER_BASE, background: `linear-gradient(135deg, ${color}20 0%, ${color}10 100%)` }); const overviewCardStyle = { borderRadius: designTokens.borderRadius.large, border: 'none', boxShadow: designTokens.shadows.medium, background: '#fff', animation: 'fadeInUp 0.6s ease-out 0.2s backwards' }; const navigationGridStyle = { display: 'grid', gridTemplateColumns: 'repeat(auto-fit, minmax(100px, 1fr))', gap: 'clamp(8px, 2vw, 16px)', marginBottom: '24px' }; const navButtonStyle = (color) => ({ height: 'auto', padding: '24px 20px', borderRadius: designTokens.borderRadius.medium, border: '2px solid #f0f0f0', background: '#fff', transition: `all ${designTokens.transitions.normal}`, display: 'flex', flexDirection: 'column', alignItems: 'center', gap: '12px', cursor: 'pointer', boxShadow: designTokens.shadows.small }); const navIconContainer = (color) => ({ width: '60px', height: '60px', borderRadius: designTokens.borderRadius.medium, display: 'flex', alignItems: 'center', justifyContent: 'center', background: `linear-gradient(135deg, ${color}20 0%, ${color}10 100%)`, fontSize: '28px', transition: `all ${designTokens.transitions.normal}` }); const navTextStyle = { fontSize: 'clamp(0.75rem, 2vw, 0.9rem)', fontWeight: '600', color: designTokens.colors.text.primary, textAlign: 'center', whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis', maxWidth: '100%' }; const systemInfoStyle = { background: 'linear-gradient(135deg, #f0f7ff 0%, #e6f7ff 100%)', borderRadius: designTokens.borderRadius.medium, padding: '20px', border: '1px solid #91d5ff' }; const quickStatsStyle = { display: 'grid', gridTemplateColumns: 'repeat(auto-fit, minmax(220px, 1fr))', gap: '16px', marginBottom: '24px' }; const quickStatItemStyle = { background: 'linear-gradient(135deg, #fff 0%, #fafafa 100%)', borderRadius: designTokens.borderRadius.medium, padding: '20px', display: 'flex', alignItems: 'center', gap: '16px', border: '1px solid #f0f0f0', boxShadow: designTokens.shadows.small }; const AnimatedCounter = ({ value, duration = 1500 }) => { const [displayValue, setDisplayValue] = useState(0); const animationRef = useRef(null); const startTimeRef = useRef(null); useEffect(() => { const animate = (currentTime) => { if (!startTimeRef.current) { startTimeRef.current = currentTime; } const elapsed = currentTime - startTimeRef.current; const progress = Math.min(elapsed / duration, 1); const easeOutQuart = 1 - Math.pow(1 - progress, 4); const currentValue = Math.floor(easeOutQuart * value); setDisplayValue(currentValue); if (progress < 1) { animationRef.current = requestAnimationFrame(animate); } }; animationRef.current = requestAnimationFrame(animate); return () => { if (animationRef.current) { cancelAnimationFrame(animationRef.current); } }; }, [value, duration]); return {displayValue}; }; const CircularProgress = ({ percentage, size = 120, strokeWidth = 10, color, label }) => { const circumference = 2 * Math.PI * ((size - strokeWidth) / 2); const offset = circumference - (percentage / 100) * circumference; return (
系统版本: v1.0.0
最后更新:{new Date().toLocaleDateString()}
实时监控 · 智能管理 · 高效运维
专业的机房设备管理解决方案,提供全方位的设备监控和管理能力