From 9fa647e40e0321b3f209519d09a6d9d261c77064 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=B6=85=E7=BA=A7=E8=80=81=E7=99=BD=E5=85=94?= Date: Mon, 8 Sep 2025 18:19:03 +0800 Subject: [PATCH] =?UTF-8?q?feat(ckbox):=20=E9=87=8D=E6=9E=84=E7=9B=91?= =?UTF-8?q?=E6=8E=A7=E9=A1=B5=E9=9D=A2=E4=B8=BA=E4=BB=AA=E8=A1=A8=E7=9B=98?= =?UTF-8?q?=E5=B9=B6=E6=B7=BB=E5=8A=A0=E5=9B=BE=E8=A1=A8=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 将监控页面重命名为仪表盘,保留原有功能组件的同时新增多个图表展示模块 使用echarts实现消息趋势、功能分布等数据可视化 优化布局和样式,提升用户体验 --- .../index.module.scss | 65 ++- .../src/pages/pc/ckbox/dashboard/index.tsx | 473 ++++++++++++++++++ Cunkebao/src/pages/pc/ckbox/index.tsx | 9 +- .../src/pages/pc/ckbox/monitoring/index.tsx | 186 ------- Cunkebao/src/router/module/ckbox.tsx | 9 + 5 files changed, 539 insertions(+), 203 deletions(-) rename Cunkebao/src/pages/pc/ckbox/{monitoring => dashboard}/index.module.scss (70%) create mode 100644 Cunkebao/src/pages/pc/ckbox/dashboard/index.tsx delete mode 100644 Cunkebao/src/pages/pc/ckbox/monitoring/index.tsx diff --git a/Cunkebao/src/pages/pc/ckbox/monitoring/index.module.scss b/Cunkebao/src/pages/pc/ckbox/dashboard/index.module.scss similarity index 70% rename from Cunkebao/src/pages/pc/ckbox/monitoring/index.module.scss rename to Cunkebao/src/pages/pc/ckbox/dashboard/index.module.scss index 07a906b5..88a1b2e6 100644 --- a/Cunkebao/src/pages/pc/ckbox/monitoring/index.module.scss +++ b/Cunkebao/src/pages/pc/ckbox/dashboard/index.module.scss @@ -97,22 +97,59 @@ } } + .chartsRow { + margin-top: 24px; + } + + .chartCard { + border-radius: 12px; + box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1); + transition: all 0.3s ease; + + &:hover { + box-shadow: 0 8px 24px rgba(0, 0, 0, 0.15); + transform: translateY(-2px); + } + + .ant-card-body { + padding: 16px; + } + + // ECharts容器样式 + .echarts-for-react { + width: 100% !important; + } +} + .tableRow { - .tableCard { - border-radius: 8px; - box-shadow: 0 2px 8px rgba(0, 0, 0, 0.06); + margin-top: 24px; + } + + .tableCard { + .ant-card-head { + background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); + color: white; - .ant-table { - .ant-table-thead > tr > th { - background-color: #fafafa; - border-bottom: 1px solid #f0f0f0; - font-weight: 600; - } - - .ant-table-tbody > tr { - &:hover { - background-color: #f5f5f5; - } + .ant-card-head-title { + color: white; + } + } + } + + .tableCard { + border-radius: 8px; + box-shadow: 0 2px 8px rgba(0, 0, 0, 0.06); + + .ant-table { + .ant-table-thead > tr > th { + background-color: #fafafa; + border-bottom: 1px solid #f0f0f0; + font-weight: 600; + } + + .ant-table-tbody > tr { + &:hover { + background-color: #f5f5f5; } } } diff --git a/Cunkebao/src/pages/pc/ckbox/dashboard/index.tsx b/Cunkebao/src/pages/pc/ckbox/dashboard/index.tsx new file mode 100644 index 00000000..5d72bb4a --- /dev/null +++ b/Cunkebao/src/pages/pc/ckbox/dashboard/index.tsx @@ -0,0 +1,473 @@ +import React from "react"; +import { Card, Row, Col, Statistic, Progress, Table, Tag } from "antd"; +import { + UserOutlined, + MessageOutlined, + TeamOutlined, + TrophyOutlined, + ArrowUpOutlined, + ArrowDownOutlined, +} from "@ant-design/icons"; +import * as echarts from "echarts"; +import ReactECharts from "echarts-for-react"; +import styles from "./index.module.scss"; + +interface DashboardProps { + // 预留接口属性 +} + +const Dashboard: React.FC = () => { + // 模拟数据 + const statsData = [ + { + title: "在线设备数", + value: 128, + prefix: , + suffix: "台", + valueStyle: { color: "#3f8600" }, + }, + { + title: "今日消息量", + value: 2456, + prefix: , + suffix: "条", + valueStyle: { color: "#1890ff" }, + }, + { + title: "活跃群组", + value: 89, + prefix: , + suffix: "个", + valueStyle: { color: "#722ed1" }, + }, + { + title: "成功率", + value: 98.5, + prefix: , + suffix: "%", + valueStyle: { color: "#f5222d" }, + }, + ]; + + const tableColumns = [ + { + title: "设备名称", + dataIndex: "deviceName", + key: "deviceName", + }, + { + title: "状态", + dataIndex: "status", + key: "status", + render: (status: string) => ( + {status} + ), + }, + { + title: "消息数", + dataIndex: "messageCount", + key: "messageCount", + }, + { + title: "最后活跃时间", + dataIndex: "lastActive", + key: "lastActive", + }, + ]; + + const tableData = [ + { + key: "1", + deviceName: "设备001", + status: "在线", + messageCount: 245, + lastActive: "2024-01-15 14:30:25", + }, + { + key: "2", + deviceName: "设备002", + status: "离线", + messageCount: 156, + lastActive: "2024-01-15 12:15:10", + }, + { + key: "3", + deviceName: "设备003", + status: "在线", + messageCount: 389, + lastActive: "2024-01-15 14:28:45", + }, + ]; + + // 图表数据 + const lineData = [ + { time: "00:00", value: 120 }, + { time: "02:00", value: 132 }, + { time: "04:00", value: 101 }, + { time: "06:00", value: 134 }, + { time: "08:00", value: 190 }, + { time: "10:00", value: 230 }, + { time: "12:00", value: 210 }, + { time: "14:00", value: 220 }, + { time: "16:00", value: 165 }, + { time: "18:00", value: 127 }, + { time: "20:00", value: 82 }, + { time: "22:00", value: 91 }, + ]; + + const columnData = [ + { type: "消息发送", value: 27 }, + { type: "消息接收", value: 25 }, + { type: "群组管理", value: 18 }, + { type: "设备监控", value: 15 }, + { type: "数据同步", value: 10 }, + { type: "其他", value: 5 }, + ]; + + const pieData = [ + { type: "在线设备", value: 128 }, + { type: "离线设备", value: 32 }, + { type: "维护中", value: 8 }, + ]; + + const areaData = [ + { time: "1月", value: 3000 }, + { time: "2月", value: 4000 }, + { time: "3月", value: 3500 }, + { time: "4月", value: 5000 }, + { time: "5月", value: 4900 }, + { time: "6月", value: 6000 }, + ]; + + // ECharts配置 + const lineOption = { + title: { + text: "24小时消息趋势", + left: "center", + textStyle: { + color: "#333", + fontSize: 16, + }, + }, + tooltip: { + trigger: "axis", + backgroundColor: "rgba(0,0,0,0.8)", + textStyle: { + color: "#fff", + }, + }, + grid: { + left: "3%", + right: "4%", + bottom: "3%", + containLabel: true, + }, + xAxis: { + type: "category", + data: lineData.map(item => item.time), + axisLine: { + lineStyle: { + color: "#ccc", + }, + }, + }, + yAxis: { + type: "value", + axisLine: { + lineStyle: { + color: "#ccc", + }, + }, + }, + series: [ + { + data: lineData.map(item => item.value), + type: "line", + smooth: true, + lineStyle: { + color: "#1890ff", + width: 3, + }, + itemStyle: { + color: "#1890ff", + }, + areaStyle: { + color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [ + { offset: 0, color: "rgba(24, 144, 255, 0.3)" }, + { offset: 1, color: "rgba(24, 144, 255, 0.1)" }, + ]), + }, + }, + ], + }; + + const columnOption = { + title: { + text: "功能使用分布", + left: "center", + textStyle: { + color: "#333", + fontSize: 16, + }, + }, + tooltip: { + trigger: "axis", + backgroundColor: "rgba(0,0,0,0.8)", + textStyle: { + color: "#fff", + }, + }, + grid: { + left: "3%", + right: "4%", + bottom: "3%", + containLabel: true, + }, + xAxis: { + type: "category", + data: columnData.map(item => item.type), + axisLabel: { + rotate: 45, + }, + axisLine: { + lineStyle: { + color: "#ccc", + }, + }, + }, + yAxis: { + type: "value", + axisLine: { + lineStyle: { + color: "#ccc", + }, + }, + }, + series: [ + { + data: columnData.map(item => item.value), + type: "bar", + itemStyle: { + color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [ + { offset: 0, color: "#52c41a" }, + { offset: 1, color: "#389e0d" }, + ]), + }, + }, + ], + }; + + const pieOption = { + title: { + text: "设备状态分布", + left: "center", + textStyle: { + color: "#333", + fontSize: 16, + }, + }, + tooltip: { + trigger: "item", + backgroundColor: "rgba(0,0,0,0.8)", + textStyle: { + color: "#fff", + }, + }, + legend: { + orient: "vertical", + left: "left", + }, + series: [ + { + name: "设备状态", + type: "pie", + radius: "50%", + data: pieData.map(item => ({ name: item.type, value: item.value })), + emphasis: { + itemStyle: { + shadowBlur: 10, + shadowOffsetX: 0, + shadowColor: "rgba(0, 0, 0, 0.5)", + }, + }, + itemStyle: { + borderRadius: 5, + borderColor: "#fff", + borderWidth: 2, + }, + }, + ], + }; + + const areaOption = { + title: { + text: "月度数据趋势", + left: "center", + textStyle: { + color: "#333", + fontSize: 16, + }, + }, + tooltip: { + trigger: "axis", + backgroundColor: "rgba(0,0,0,0.8)", + textStyle: { + color: "#fff", + }, + }, + grid: { + left: "3%", + right: "4%", + bottom: "3%", + containLabel: true, + }, + xAxis: { + type: "category", + data: areaData.map(item => item.time), + axisLine: { + lineStyle: { + color: "#ccc", + }, + }, + }, + yAxis: { + type: "value", + axisLine: { + lineStyle: { + color: "#ccc", + }, + }, + }, + series: [ + { + data: areaData.map(item => item.value), + type: "line", + smooth: true, + lineStyle: { + color: "#722ed1", + width: 3, + }, + itemStyle: { + color: "#722ed1", + }, + areaStyle: { + color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [ + { offset: 0, color: "rgba(114, 46, 209, 0.6)" }, + { offset: 1, color: "rgba(114, 46, 209, 0.1)" }, + ]), + }, + }, + ], + }; + + return ( +
+
+

数据监控看板

+

实时监控系统运行状态和数据指标

+
+ + {/* 统计卡片 */} + + {statsData.map((stat, index) => ( + + + + + + ))} + + + {/* 进度指标 */} + + + +
+ CPU使用率 + +
+
+ 内存使用率 + +
+
+ 磁盘使用率 + +
+
+ + + +
+ 消息处理速度 +
+ 1,245 + +
+
+
+ 错误率 +
+ 0.2% + +
+
+
+ 响应时间 +
+ 125ms + +
+
+
+ +
+ + {/* 图表区域 - 四栏布局 */} + + + + + + + + + + + + + + + + + + + + + + + + {/* 设备状态表格 */} + + + + + + + + + ); +}; + +export default Dashboard; diff --git a/Cunkebao/src/pages/pc/ckbox/index.tsx b/Cunkebao/src/pages/pc/ckbox/index.tsx index 5eebff47..2ff2022a 100644 --- a/Cunkebao/src/pages/pc/ckbox/index.tsx +++ b/Cunkebao/src/pages/pc/ckbox/index.tsx @@ -1,12 +1,15 @@ import React from "react"; -import { Layout } from "antd"; +import Layout from "@/components/Layout/Layout"; import { Outlet } from "react-router-dom"; import NavCommon from "./components/NavCommon"; import styles from "./index.module.scss"; const CkboxPage: React.FC = () => { return ( - - + + } + > ); diff --git a/Cunkebao/src/pages/pc/ckbox/monitoring/index.tsx b/Cunkebao/src/pages/pc/ckbox/monitoring/index.tsx deleted file mode 100644 index 21efed53..00000000 --- a/Cunkebao/src/pages/pc/ckbox/monitoring/index.tsx +++ /dev/null @@ -1,186 +0,0 @@ -import React from 'react'; -import { Card, Row, Col, Statistic, Progress, Table, Tag } from 'antd'; -import { - UserOutlined, - MessageOutlined, - TeamOutlined, - TrophyOutlined, - ArrowUpOutlined, - ArrowDownOutlined -} from '@ant-design/icons'; -import styles from './index.module.scss'; - -interface MonitoringProps { - // 预留接口属性 -} - -const Monitoring: React.FC = () => { - // 模拟数据 - const statsData = [ - { - title: '在线设备数', - value: 128, - prefix: , - suffix: '台', - valueStyle: { color: '#3f8600' }, - }, - { - title: '今日消息量', - value: 2456, - prefix: , - suffix: '条', - valueStyle: { color: '#1890ff' }, - }, - { - title: '活跃群组', - value: 89, - prefix: , - suffix: '个', - valueStyle: { color: '#722ed1' }, - }, - { - title: '成功率', - value: 98.5, - prefix: , - suffix: '%', - valueStyle: { color: '#f5222d' }, - }, - ]; - - const tableColumns = [ - { - title: '设备名称', - dataIndex: 'deviceName', - key: 'deviceName', - }, - { - title: '状态', - dataIndex: 'status', - key: 'status', - render: (status: string) => ( - {status} - ), - }, - { - title: '消息数', - dataIndex: 'messageCount', - key: 'messageCount', - }, - { - title: '最后活跃时间', - dataIndex: 'lastActive', - key: 'lastActive', - }, - ]; - - const tableData = [ - { - key: '1', - deviceName: '设备001', - status: '在线', - messageCount: 245, - lastActive: '2024-01-15 14:30:25', - }, - { - key: '2', - deviceName: '设备002', - status: '离线', - messageCount: 156, - lastActive: '2024-01-15 12:15:10', - }, - { - key: '3', - deviceName: '设备003', - status: '在线', - messageCount: 389, - lastActive: '2024-01-15 14:28:45', - }, - ]; - - return ( -
-
-

数据监控看板

-

实时监控系统运行状态和数据指标

-
- - {/* 统计卡片 */} - - {statsData.map((stat, index) => ( -
- - - - - ))} - - - {/* 进度指标 */} - - - -
- CPU使用率 - -
-
- 内存使用率 - -
-
- 磁盘使用率 - -
-
- - - -
- 消息处理速度 -
- 1,245 - -
-
-
- 错误率 -
- 0.2% - -
-
-
- 响应时间 -
- 125ms - -
-
-
- - - - {/* 设备状态表格 */} - - - -
- - - - - ); -}; - -export default Monitoring; \ No newline at end of file diff --git a/Cunkebao/src/router/module/ckbox.tsx b/Cunkebao/src/router/module/ckbox.tsx index 7a5ae294..4ca69087 100644 --- a/Cunkebao/src/router/module/ckbox.tsx +++ b/Cunkebao/src/router/module/ckbox.tsx @@ -1,6 +1,7 @@ import type { RouteObject } from "react-router-dom"; import CkboxPage from "@/pages/pc/ckbox"; import WeChatPage from "@/pages/pc/ckbox/weChat"; +import Dashboard from "@/pages/pc/ckbox/dashboard"; const ckboxRoutes: (RouteObject & { auth?: boolean; requiredRole?: string })[] = [ @@ -10,6 +11,14 @@ const ckboxRoutes: (RouteObject & { auth?: boolean; requiredRole?: string })[] = auth: true, requiredRole: "user", children: [ + { + path: "", + element: , + }, + { + path: "dashboard", + element: , + }, { path: "weChat", element: ,