import React from 'react'; import { Card, Col, Tag, Spin } from 'antd'; import { ArrowUpOutlined, ArrowDownOutlined } from '@ant-design/icons'; import { designTokens } from '../../config/theme'; import AnimatedCounter from './AnimatedCounter'; const createStatCardStyle = color => ({ 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 ${color}`, }); const createStatIconContainer = color => ({ 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, background: `linear-gradient(135deg, ${color}20 0%, ${color}10 100%)`, }); const StatCard = ({ config, stats, loading, animatedKey, hoveredCard, onHover }) => { const { icon: Icon, color, statKey, title, trend, tagColor, customStatus, hideTrend, xs, sm, lg, xl, delay, } = config; const colProps = { xs, sm, lg, xl }; const cardStyle = { ...createStatCardStyle(color), ...(hoveredCard === statKey ? { transform: 'translateY(-6px)', boxShadow: designTokens.shadows.xl } : {}), animationDelay: `${delay * 0.1}s`, }; return ( onHover(statKey)} onMouseLeave={() => onHover(null)} styles={{ body: { padding: 'clamp(16px, 3vw, 24px)' } }} >
{title}
{loading ? ( ) : ( )}
{customStatus ? (
{statKey === 'totalRacks' ? '正常运行中' : '全部在线'}
) : !hideTrend ? (
0 ? designTokens.colors.success.main : designTokens.colors.error.main, flexWrap: 'wrap', gap: '4px', }} > {trend > 0 ? ( ) : ( )} {Math.abs(trend)}% 环比
) : null}
); }; export default React.memo(StatCard);