Просмотр исходного кода

✨ feat(dashboard): 重构大屏仪表板UI与图标系统

- 集成lucide-react图标库(v0.535.0)替代ant-design/icons
- 重构统计卡片组件,采用渐变背景和现代化设计
- 实现自定义进度条组件,提升视觉效果
- 优化信息卡片布局,增强数据可读性
- 改进实时活动展示样式,提升用户体验

💄 style(dashboard): 优化大屏仪表板视觉设计

- 采用grid布局替代antd Row/Col组件,提升响应式表现
- 优化颜色方案,增强数据可视化对比度
- 调整字体大小和间距,提升整体视觉层次感
- 改进图表容器样式,增强数据展示清晰度
- 添加卡片悬停效果和过渡动画,提升交互体验
yourname 7 месяцев назад
Родитель
Сommit
b1b444aeac
3 измененных файлов с 215 добавлено и 165 удалено
  1. 1 0
      package.json
  2. 12 0
      pnpm-lock.yaml
  3. 202 165
      src/client/admin/pages/BigScreenDashboard.tsx

+ 1 - 0
package.json

@@ -31,6 +31,7 @@
     "hono": "^4.7.11",
     "ioredis": "^5.6.1",
     "jsonwebtoken": "^9.0.2",
+    "lucide-react": "^0.535.0",
     "minio": "^8.0.5",
     "mysql2": "^3.14.1",
     "node-fetch": "^3.3.2",

+ 12 - 0
pnpm-lock.yaml

@@ -77,6 +77,9 @@ importers:
       jsonwebtoken:
         specifier: ^9.0.2
         version: 9.0.2
+      lucide-react:
+        specifier: ^0.535.0
+        version: 0.535.0(react@19.1.0)
       minio:
         specifier: ^8.0.5
         version: 8.0.5
@@ -2293,6 +2296,11 @@ packages:
     resolution: {integrity: sha512-Nv9KddBcQSlQopmBHXSsZVY5xsdlZkdH/Iey0BlcBYggMd4two7cZnKOK9vmy3nY0O5RGH99z1PCeTpPqszUYg==}
     engines: {bun: '>=1.0.0', deno: '>=1.30.0', node: '>=8.0.0'}
 
+  lucide-react@0.535.0:
+    resolution: {integrity: sha512-2E3+YWGLpjZ8ejIYrdqxVjWMSMiRQHmU6xZYE9xA2SC5j2m0NeB4/acjhRdhxbfniBKoNEukDDQnmShTxwOQ4g==}
+    peerDependencies:
+      react: ^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0
+
   magic-string@0.30.17:
     resolution: {integrity: sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA==}
 
@@ -5327,6 +5335,10 @@ snapshots:
 
   lru.min@1.1.2: {}
 
+  lucide-react@0.535.0(react@19.1.0):
+    dependencies:
+      react: 19.1.0
+
   magic-string@0.30.17:
     dependencies:
       '@jridgewell/sourcemap-codec': 1.5.0

+ 202 - 165
src/client/admin/pages/BigScreenDashboard.tsx

@@ -1,28 +1,28 @@
 import React, { useState, useEffect } from 'react';
-import { Card, Row, Col, Statistic, Typography, Space, Timeline, List, Avatar, Progress, Tag } from 'antd';
-import {
-  UserOutlined,
-  TeamOutlined,
-  BookOutlined,
-  FileTextOutlined,
-  RiseOutlined,
-  ClockCircleOutlined,
-  BarChartOutlined,
-  PieChartOutlined,
-  EyeOutlined,
-  HeartOutlined,
-  StarOutlined,
-  DownloadOutlined,
-  UploadOutlined,
-  DatabaseOutlined,
-  CloudOutlined,
-  ThunderboltOutlined,
-  FireOutlined,
-  RocketOutlined
-} from '@ant-design/icons';
 import { Line, Pie, Column } from '@ant-design/plots';
 import { useQuery } from '@tanstack/react-query';
 import dayjs from 'dayjs';
+import {
+  Users,
+  Users2,
+  BookOpen,
+  FileText,
+  TrendingUp,
+  Clock,
+  BarChart3,
+  PieChart,
+  Eye,
+  Heart,
+  Star,
+  Download,
+  Upload,
+  Database,
+  Cloud,
+  Zap,
+  Flame,
+  Rocket,
+  Activity
+} from 'lucide-react';
 import {
   userClient,
   silverTalentsClient,
@@ -33,8 +33,6 @@ import {
   companyCertificationClient
 } from '@/client/api';
 
-const { Title, Text } = Typography;
-
 // 大屏幕仪表板组件
 const BigScreenDashboard: React.FC = () => {
   const [currentTime, setCurrentTime] = useState(dayjs());
@@ -136,11 +134,11 @@ const BigScreenDashboard: React.FC = () => {
   // 模拟实时活动数据
   useEffect(() => {
     const activities = [
-      { user: '张大爷', action: '发布了新技能', time: '刚刚', icon: <RocketOutlined className="text-blue-500" /> },
-      { user: '李奶奶', action: '收藏了政策资讯', time: '1分钟前', icon: <HeartOutlined className="text-red-500" /> },
-      { user: '王教授', action: '上传了教学视频', time: '3分钟前', icon: <UploadOutlined className="text-green-500" /> },
-      { user: '刘阿姨', action: '申请了银龄岗位', time: '5分钟前', icon: <FileTextOutlined className="text-purple-500" /> },
-      { user: '陈师傅', action: '完成了时间银行任务', time: '8分钟前', icon: <ClockCircleOutlined className="text-orange-500" /> },
+      { user: '张大爷', action: '发布了新技能', time: '刚刚', icon: <Rocket className="w-4 h-4 text-blue-500" />, color: 'text-blue-500' },
+      { user: '李奶奶', action: '收藏了政策资讯', time: '1分钟前', icon: <Heart className="w-4 h-4 text-red-500" />, color: 'text-red-500' },
+      { user: '王教授', action: '上传了教学视频', time: '3分钟前', icon: <Upload className="w-4 h-4 text-green-500" />, color: 'text-green-500' },
+      { user: '刘阿姨', action: '申请了银龄岗位', time: '5分钟前', icon: <FileText className="w-4 h-4 text-purple-500" />, color: 'text-purple-500' },
+      { user: '陈师傅', action: '完成了时间银行任务', time: '8分钟前', icon: <Clock className="w-4 h-4 text-orange-500" />, color: 'text-orange-500' },
     ];
     
     const interval = setInterval(() => {
@@ -215,18 +213,99 @@ const BigScreenDashboard: React.FC = () => {
     animation: { appear: { animation: 'scale-in-y', duration: 2000 } },
   };
 
+  // 统计卡片组件
+  const StatCard = ({ 
+    title, 
+    value, 
+    icon, 
+    color, 
+    suffix = '', 
+    trend = '' 
+  }: { 
+    title: string; 
+    value: number | string; 
+    icon: React.ReactNode; 
+    color: string; 
+    suffix?: string; 
+    trend?: string;
+  }) => (
+    <div className={`bg-gradient-to-r ${color} rounded-lg shadow-2xl p-6 text-white`}>
+      <div className="flex items-center justify-between">
+        <div>
+          <h3 className="text-lg font-medium mb-2">{title}</h3>
+          <div className="text-4xl font-bold">{value}</div>
+          {suffix && <span className="text-sm opacity-80 ml-2">{suffix}</span>}
+        </div>
+        <div className="text-3xl opacity-80">
+          {icon}
+        </div>
+      </div>
+      {trend && (
+        <div className="mt-2 text-sm opacity-80 flex items-center">
+          <TrendingUp className="w-4 h-4 mr-1" />
+          {trend}
+        </div>
+      )}
+    </div>
+  );
+
+  // 自定义进度条组件
+  const ProgressBar = ({ value, color }: { value: number; color: string }) => (
+    <div className="w-full bg-gray-700 rounded-full h-2">
+      <div 
+        className={`h-2 rounded-full transition-all duration-300`} 
+        style={{ 
+          width: `${value}%`,
+          backgroundColor: color 
+        }}
+      />
+    </div>
+  );
+
+  // 信息卡片组件
+  const InfoCard = ({ 
+    title, 
+    value, 
+    icon, 
+    iconColor, 
+    progress 
+  }: { 
+    title: string; 
+    value: string | number; 
+    icon: React.ReactNode; 
+    iconColor: string;
+    progress?: { value: number; color: string };
+  }) => (
+    <div className="bg-white bg-opacity-10 border-0 backdrop-blur-sm rounded-lg p-4">
+      <div className="flex items-center justify-between">
+        <div>
+          <h4 className="text-white text-sm">{title}</h4>
+          <div className="text-2xl font-bold text-white">{value}</div>
+        </div>
+        <div className={`text-4xl ${iconColor}`}>
+          {icon}
+        </div>
+      </div>
+      {progress && (
+        <div className="mt-3">
+          <ProgressBar value={progress.value} color={progress.color} />
+        </div>
+      )}
+    </div>
+  );
+
   return (
     <div className="min-h-screen bg-gradient-to-br from-gray-900 via-blue-900 to-purple-900 p-6">
       {/* 顶部标题栏 */}
       <div className="mb-6 flex items-center justify-between">
         <div>
-          <Title level={1} className="text-white !mb-2">
-            <ThunderboltOutlined className="mr-3 text-yellow-400" />
+          <h1 className="text-white text-3xl font-bold mb-2 flex items-center">
+            <Zap className="mr-3 text-yellow-400 w-8 h-8" />
             银龄人才大数据监控中心
-          </Title>
-          <Text className="text-gray-300 text-lg">
+          </h1>
+          <p className="text-gray-300 text-lg">
             实时数据监控 · 智能分析决策 · 精准服务匹配
-          </Text>
+          </p>
         </div>
         <div className="text-right">
           <div className="text-3xl font-bold text-white">
@@ -239,143 +318,101 @@ const BigScreenDashboard: React.FC = () => {
       </div>
 
       {/* 核心数据卡片 */}
-      <Row gutter={[24, 24]} className="mb-6">
-        <Col span={6}>
-          <Card className="bg-gradient-to-r from-blue-500 to-blue-600 border-0 shadow-2xl">
-            <Statistic
-              title={<span className="text-white text-lg">总用户数</span>}
-              value={userStats?.total || 0}
-              valueStyle={{ color: 'white', fontSize: 36, fontWeight: 'bold' }}
-              prefix={<UserOutlined className="text-white text-2xl" />}
-              suffix={<Tag color="blue" className="ml-2">人</Tag>}
-            />
-            <div className="mt-2 text-white opacity-80">
-              <RiseOutlined /> 今日新增: +12人
-            </div>
-          </Card>
-        </Col>
-        <Col span={6}>
-          <Card className="bg-gradient-to-r from-green-500 to-green-600 border-0 shadow-2xl">
-            <Statistic
-              title={<span className="text-white text-lg">银龄人才</span>}
-              value={talentStats?.total || 0}
-              valueStyle={{ color: 'white', fontSize: 36, fontWeight: 'bold' }}
-              prefix={<TeamOutlined className="text-white text-2xl" />}
-              suffix={<Tag color="green" className="ml-2">人</Tag>}
-            />
-            <div className="mt-2 text-white opacity-80">
-              <RiseOutlined /> 活跃占比: 78%
-            </div>
-          </Card>
-        </Col>
-        <Col span={6}>
-          <Card className="bg-gradient-to-r from-orange-500 to-orange-600 border-0 shadow-2xl">
-            <Statistic
-              title={<span className="text-white text-lg">岗位机会</span>}
-              value={jobStats?.total || 0}
-              valueStyle={{ color: 'white', fontSize: 36, fontWeight: 'bold' }}
-              prefix={<FileTextOutlined className="text-white text-2xl" />}
-              suffix={<Tag color="orange" className="ml-2">个</Tag>}
-            />
-            <div className="mt-2 text-white opacity-80">
-              <RiseOutlined /> 匹配成功率: 85%
-            </div>
-          </Card>
-        </Col>
-        <Col span={6}>
-          <Card className="bg-gradient-to-r from-purple-500 to-purple-600 border-0 shadow-2xl">
-            <Statistic
-              title={<span className="text-white text-lg">知识库</span>}
-              value={knowledgeStats?.total || 0}
-              valueStyle={{ color: 'white', fontSize: 36, fontWeight: 'bold' }}
-              prefix={<BookOutlined className="text-white text-2xl" />}
-              suffix={<Tag color="purple" className="ml-2">篇</Tag>}
-            />
-            <div className="mt-2 text-white opacity-80">
-              <RiseOutlined /> 本月新增: 156篇
-            </div>
-          </Card>
-        </Col>
-      </Row>
+      <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-6 mb-6">
+        <StatCard
+          title="总用户数"
+          value={userStats?.total || 0}
+          icon={<Users className="w-8 h-8" />}
+          color="from-blue-500 to-blue-600"
+          suffix="人"
+          trend="今日新增: +12人"
+        />
+        <StatCard
+          title="银龄人才"
+          value={talentStats?.total || 0}
+          icon={<Users2 className="w-8 h-8" />}
+          color="from-green-500 to-green-600"
+          suffix="人"
+          trend="活跃占比: 78%"
+        />
+        <StatCard
+          title="岗位机会"
+          value={jobStats?.total || 0}
+          icon={<FileText className="w-8 h-8" />}
+          color="from-orange-500 to-orange-600"
+          suffix="个"
+          trend="匹配成功率: 85%"
+        />
+        <StatCard
+          title="知识库"
+          value={knowledgeStats?.total || 0}
+          icon={<BookOpen className="w-8 h-8" />}
+          color="from-purple-500 to-purple-600"
+          suffix="篇"
+          trend="本月新增: 156篇"
+        />
+      </div>
 
       {/* 图表区域 */}
-      <Row gutter={[24, 24]} className="mb-6">
-        <Col span={12}>
-          <Card title="24小时活跃度趋势" className="bg-white bg-opacity-10 border-0 backdrop-blur-sm">
-            <Line {...lineConfig} />
-          </Card>
-        </Col>
-        <Col span={12}>
-          <Card title="内容类型分布" className="bg-white bg-opacity-10 border-0 backdrop-blur-sm">
-            <Pie {...pieConfig} />
-          </Card>
-        </Col>
-      </Row>
+      <div className="grid grid-cols-1 lg:grid-cols-2 gap-6 mb-6">
+        <div className="bg-white bg-opacity-10 border-0 backdrop-blur-sm rounded-lg p-4">
+          <h3 className="text-white text-lg font-semibold mb-4">24小时活跃度趋势</h3>
+          <Line {...lineConfig} />
+        </div>
+        <div className="bg-white bg-opacity-10 border-0 backdrop-blur-sm rounded-lg p-4">
+          <h3 className="text-white text-lg font-semibold mb-4">内容类型分布</h3>
+          <Pie {...pieConfig} />
+        </div>
+      </div>
 
-      <Row gutter={[24, 24]} className="mb-6">
-        <Col span={16}>
-          <Card title="周活跃度统计" className="bg-white bg-opacity-10 border-0 backdrop-blur-sm">
-            <Column {...columnConfig} />
-          </Card>
-        </Col>
-        <Col span={8}>
-          <Card title="实时活动" className="bg-white bg-opacity-10 border-0 backdrop-blur-sm">
-            <Timeline
-              items={realtimeData.map((item, index) => ({
-                color: index === 0 ? 'green' : 'gray',
-                dot: item.icon,
-                children: (
-                  <div className="text-white">
-                    <div className="font-semibold">{item.user}</div>
-                    <div className="text-sm opacity-80">{item.action}</div>
-                    <div className="text-xs opacity-60">{item.time}</div>
-                  </div>
-                ),
-              }))}
-            />
-          </Card>
-        </Col>
-      </Row>
+      <div className="grid grid-cols-1 lg:grid-cols-3 gap-6 mb-6">
+        <div className="lg:col-span-2 bg-white bg-opacity-10 border-0 backdrop-blur-sm rounded-lg p-4">
+          <h3 className="text-white text-lg font-semibold mb-4">周活跃度统计</h3>
+          <Column {...columnConfig} />
+        </div>
+        <div className="bg-white bg-opacity-10 border-0 backdrop-blur-sm rounded-lg p-4">
+          <h3 className="text-white text-lg font-semibold mb-4">实时活动</h3>
+          <div className="space-y-3">
+            {realtimeData.map((item, index) => (
+              <div key={index} className="flex items-start space-x-3">
+                <div className={`mt-1 ${item.color}`}>
+                  {item.icon}
+                </div>
+                <div className="flex-1">
+                  <div className="font-semibold text-white text-sm">{item.user}</div>
+                  <div className="text-white opacity-80 text-sm">{item.action}</div>
+                  <div className="text-white opacity-60 text-xs">{item.time}</div>
+                </div>
+              </div>
+            ))}
+          </div>
+        </div>
+      </div>
 
       {/* 底部状态栏 */}
-      <Row gutter={[24, 24]}>
-        <Col span={8}>
-          <Card className="bg-white bg-opacity-10 border-0 backdrop-blur-sm">
-            <div className="flex items-center justify-between">
-              <div>
-                <Text className="text-white">文件总数</Text>
-                <div className="text-2xl font-bold text-white">{fileStats?.total || 0}</div>
-              </div>
-              <DatabaseOutlined className="text-4xl text-blue-400" />
-            </div>
-            <Progress percent={75} strokeColor="#1890ff" showInfo={false} />
-          </Card>
-        </Col>
-        <Col span={8}>
-          <Card className="bg-white bg-opacity-10 border-0 backdrop-blur-sm">
-            <div className="flex items-center justify-between">
-              <div>
-                <Text className="text-white">系统健康度</Text>
-                <div className="text-2xl font-bold text-white">99.8%</div>
-              </div>
-              <CloudOutlined className="text-4xl text-green-400" />
-            </div>
-            <Progress percent={99.8} strokeColor="#52c41a" showInfo={false} />
-          </Card>
-        </Col>
-        <Col span={8}>
-          <Card className="bg-white bg-opacity-10 border-0 backdrop-blur-sm">
-            <div className="flex items-center justify-between">
-              <div>
-                <Text className="text-white">今日访问</Text>
-                <div className="text-2xl font-bold text-white">1,234</div>
-              </div>
-              <EyeOutlined className="text-4xl text-orange-400" />
-            </div>
-            <Progress percent={85} strokeColor="#faad14" showInfo={false} />
-          </Card>
-        </Col>
-      </Row>
+      <div className="grid grid-cols-1 md:grid-cols-3 gap-6">
+        <InfoCard
+          title="文件总数"
+          value={fileStats?.total || 0}
+          icon={<Database />}
+          iconColor="text-blue-400"
+          progress={{ value: 75, color: '#1890ff' }}
+        />
+        <InfoCard
+          title="系统健康度"
+          value="99.8%"
+          icon={<Cloud />}
+          iconColor="text-green-400"
+          progress={{ value: 99.8, color: '#52c41a' }}
+        />
+        <InfoCard
+          title="今日访问"
+          value="1,234"
+          icon={<Eye />}
+          iconColor="text-orange-400"
+          progress={{ value: 85, color: '#faad14' }}
+        />
+      </div>
     </div>
   );
 };