From 8f446722da41d710b1c168c8c74dcef10d729c07 Mon Sep 17 00:00:00 2001 From: zjlnb666 <14659021+zhangjianlong666@user.noreply.gitee.com> Date: Mon, 19 Jan 2026 18:50:26 +0800 Subject: [PATCH] =?UTF-8?q?=E6=8A=A5=E8=A1=A8=E6=95=B0=E6=8D=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- config/routes.js | 6 + src/pages/analyzeReports_data/Data.css | 199 ++++ src/pages/analyzeReports_data/Data.js | 874 ++++++++++++++++++ src/pages/analyzeReports_data/Data.less | 256 +++++ .../nav_system_content/SystemContentList.js | 6 + src/pages/topnavbar/TopNavBar.js | 5 + 6 files changed, 1346 insertions(+) create mode 100644 src/pages/analyzeReports_data/Data.css create mode 100644 src/pages/analyzeReports_data/Data.js create mode 100644 src/pages/analyzeReports_data/Data.less diff --git a/config/routes.js b/config/routes.js index 2b7e78e..b9af675 100644 --- a/config/routes.js +++ b/config/routes.js @@ -189,6 +189,12 @@ export default [ name: 'set', component: './analyzeReports_set/Set', }, + // 分析报表数据 + { + path: '/topnavbar00/business/analyzeReports/data', + name: 'data', + component: './analyzeReports_data/Data', + }, ] }, ], diff --git a/src/pages/analyzeReports_data/Data.css b/src/pages/analyzeReports_data/Data.css new file mode 100644 index 0000000..5ed4e1a --- /dev/null +++ b/src/pages/analyzeReports_data/Data.css @@ -0,0 +1,199 @@ +.analyze-reports-data { + padding: 16px; + background-color: rgba(15, 121, 120, 0.05); + min-height: 100vh; + /* 响应式调整 */ +} +.analyze-reports-data .search-button { + background-image: url('../../assets/img/assetmangement1.png'); + background-repeat: no-repeat; + background-size: cover; + background-position: center; + color: #fff; + border-radius: 4px; + height: 36px; + border-color: #d9d9d9; +} +.analyze-reports-data .reset-button { + background-image: url('../../assets/img/assetmangement2.png'); + background-repeat: no-repeat; + background-size: cover; + background-position: center; + color: #006665; + border-radius: 4px; + height: 36px; + border-color: #d9d9d9; +} +.analyze-reports-data .del-button { + background-image: url('../../assets/img/assetmangement3.png'); + background-repeat: no-repeat; + background-size: cover; + background-position: center; + color: #000; + border-radius: 4px; + height: 36px; + width: 88px; + border-color: #d9d9d9; + background-color: #E5B7B733; +} +.analyze-reports-data .content-row { + margin-bottom: 16px; +} +.analyze-reports-data .content-row .content-item { + background-color: #fff; + padding: 16px; + border-radius: 6px; + box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1); + transition: all 0.3s ease; +} +.analyze-reports-data .content-row .content-item:hover { + box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15); +} +.first-row .analyze-reports-data .content-row .content-item { + position: relative; + overflow: hidden; + background: linear-gradient(#fff, #fff) padding-box, /* 外层渐变背景作为边框 */ conic-gradient(from 102.21deg at 52.75% 38.75%, rgba(249, 249, 249, 0.5) -32.95deg, rgba(64, 64, 64, 0.5) 10.52deg, rgba(64, 64, 64, 0.35) 32.12deg, #FFFFFF 60.28deg, rgba(255, 255, 255, 0.5) 107.79deg, rgba(64, 64, 64, 0.35) 187.59deg, #F9F9F9 207.58deg, #FFFFFF 287.31deg, rgba(249, 249, 249, 0.5) 327.05deg, rgba(64, 64, 64, 0.5) 370.52deg); + /* 关键:设置透明边框,让渐变背景透出来 */ + border: 2px solid transparent; +} +.analyze-reports-data .content-row .content-item.common-bg { + background-image: none; + background-size: auto; + background-position: initial; +} +.analyze-reports-data .content-row .content-item .item-inner { + display: flex; + justify-content: space-between; + align-items: center; + height: 100%; + width: 100%; +} +.analyze-reports-data .content-row .content-item .data-value { + font-size: 26px; + font-weight: 600; + line-height: 32px; + color: #333333; +} +.analyze-reports-data .content-row .content-item .data-title { + font-size: 16px; + font-weight: 400; + line-height: 24px; + margin-top: 20px; + color: #666666; + white-space: nowrap; +} +.analyze-reports-data .content-row .content-item .data-desc { + font-size: 12px; + color: #999; + margin-top: 4px; +} +.analyze-reports-data .content-row .content-item .data-section { + flex: 1; + padding-right: 12px; + text-align: left; +} +.analyze-reports-data .content-row .content-item .chart-section { + flex: 1; + display: flex; + justify-content: center; + align-items: center; +} +.analyze-reports-data .content-row .content-item .chart-container { + width: 100%; + height: 200px; +} +.analyze-reports-data .content-row .content-item .progress-container { + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + height: 200px; +} +.analyze-reports-data .content-row .content-item .progress-container .progress-title { + font-size: 16px; + font-weight: 500; + margin-bottom: 20px; + color: #333; +} +.analyze-reports-data .content-row .content-item .progress-container .ant-progress { + width: 80%; + margin-bottom: 16px; +} +.analyze-reports-data .content-row .content-item .progress-container .progress-text { + font-size: 24px; + font-weight: bold; + color: #006665; +} +.analyze-reports-data .content-row .content-item .data-form { + display: flex; + align-items: center; + flex-wrap: wrap; +} +.analyze-reports-data .content-row .content-item .data-form .ant-form-item { + margin-bottom: 16px; + margin-right: 16px; +} +@media (max-width: 1200px) { + .analyze-reports-data .content-row .content-item .chart-container { + height: 180px; + } + .analyze-reports-data .content-row .content-item .progress-container { + height: 180px; + } + .analyze-reports-data .content-row .content-item .item-inner { + flex-direction: column; + } + .analyze-reports-data .content-row .content-item .data-section { + padding-right: 0; + margin-bottom: 12px; + } + .analyze-reports-data .content-row .content-item .data-value { + font-size: 24px; + } + .analyze-reports-data .content-row .content-item .chart-section { + width: 100%; + } +} +@media (max-width: 768px) { + .analyze-reports-data { + padding: 8px; + } + .analyze-reports-data .content-row { + margin-bottom: 8px; + } + .analyze-reports-data .content-row .content-item { + padding: 8px; + } + .analyze-reports-data .content-row .content-item .chart-container { + height: 150px; + } + .analyze-reports-data .content-row .content-item .progress-container { + height: 150px; + } + .analyze-reports-data .content-row .content-item .progress-container .progress-title { + font-size: 14px; + margin-bottom: 12px; + } + .analyze-reports-data .content-row .content-item .progress-container .progress-text { + font-size: 20px; + } + .analyze-reports-data .content-row .content-item .item-inner { + flex-direction: column; + } + .analyze-reports-data .content-row .content-item .data-section { + padding-right: 0; + margin-bottom: 8px; + } + .analyze-reports-data .content-row .content-item .data-title { + font-size: 12px; + } + .analyze-reports-data .content-row .content-item .data-value { + font-size: 20px; + } + .analyze-reports-data .content-row .content-item .data-desc { + font-size: 10px; + } + .analyze-reports-data .content-row .content-item .chart-section { + width: 100%; + } +} diff --git a/src/pages/analyzeReports_data/Data.js b/src/pages/analyzeReports_data/Data.js new file mode 100644 index 0000000..77293d4 --- /dev/null +++ b/src/pages/analyzeReports_data/Data.js @@ -0,0 +1,874 @@ +import React, { useEffect, useRef } from 'react'; +import { Row, Col, Progress, Form, Input, Button, Select } from 'antd'; +import * as echarts from 'echarts'; +import Title from '../../pages/homepage/compontent/title'; +import './Data.less'; + +const AnalyzeReportsData = () => { + // 图表引用 + const chartRefs = { + row1Chart1: useRef(null), + row1Chart2: useRef(null), + row1Chart4: useRef(null), + row1Chart5: useRef(null), + row2Chart1: useRef(null), + row2Chart2: useRef(null), + row3Chart1: useRef(null), + row3Chart2: useRef(null), + row3Chart3: useRef(null) + }; + + // 初始化图表 + const initChart = (ref, option) => { + if (ref.current) { + const chart = echarts.init(ref.current); + chart.setOption(option); + return chart; + } + return null; + }; + + // 通用图表配置 + const getBasicChartOption = () => ({ + title: { + text: '', + }, + tooltip: { + trigger: 'axis', + axisPointer: { + type: 'shadow', + }, + }, + grid: { + top: '10%', + left: '3%', + right: '4%', + bottom: '3%', + containLabel: true, + }, + xAxis: [ + { + type: 'category', + data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'], + axisTick: { + alignWithLabel: true, + }, + }, + ], + yAxis: [ + { + type: 'value', + }, + ], + series: [ + { + name: '数据', + type: 'bar', + barWidth: '60%', + data: [10, 52, 200, 334, 390, 330, 220], + }, + ], + }); + + // 折线图配置 - 绿色 (#006665) + const getGreenLineChartOption = () => ({ + title: { + text: '', + }, + tooltip: { + trigger: 'axis', + }, + grid: { + top: '10%', + left: '0%', + right: '6%', + bottom: '10%', + containLabel: true + }, + xAxis: [ + { + type: 'category', + boundaryGap: false, + data: ['5月', '6月', '7月', '8月', '9月', '10月', '11月'], + axisTick: { + alignWithLabel: true + } + } + ], + yAxis: [ + { + type: 'value', + } + ], + series: [ + { + name: '工单数量', + type: 'line', + data: [120, 132, 101, 134, 90, 230, 210], + lineStyle: { + color: '#006665' + }, + itemStyle: { + color: '#006665' + }, + areaStyle: { + color: '#DFEAE5' + } + } + ] + }); + + // 折线图配置 - 红色 (#FF826D) + const getRedLineChartOption = () => ({ + title: { + text: '', + }, + tooltip: { + trigger: 'axis', + }, + grid: { + top: '10%', + left: '0%', + right: '6%', + bottom: '10%', + containLabel: true + }, + xAxis: [ + { + type: 'category', + boundaryGap: false, + data: ['5月', '6月', '7月', '8月', '9月', '10月', '11月'], + axisTick: { + alignWithLabel: true + } + } + ], + yAxis: [ + { + type: 'value', + } + ], + series: [ + { + name: '工单数量', + type: 'line', + data: [120, 132, 101, 134, 90, 230, 210], + lineStyle: { + color: '#FF826D' + }, + itemStyle: { + color: '#FF826D' + }, + areaStyle: { + color: '#F4EDED' + } + } + ] + }); + + // 环形图配置 - 故障等级分布 + const getRingChartOption = () => ({ + title: { + text: '', + }, + tooltip: { + trigger: 'item', + formatter: '{b}: {c} ({d}%)' + }, + grid: { + left: 0, + right: 0, + top: 0, + bottom: 0, + containLabel: true + }, + legend: [ + { + orient: 'horizontal', + left: 0, + top: '20%', + width: '60%', + textStyle: { + fontSize: 12, + color: '#666' + }, + itemGap: 5, + itemWidth: 10, + itemHeight: 10, + formatter: (name, dataIndex) => { + const data = [15, 25, 40, 20]; + const names = ['紧急', '严重', '警告', '提示']; + const index = names.indexOf(name); + return index !== -1 ? `${name} ${data[index]}%` : `${name} 0%`; + }, + data: ['紧急', '严重'] + }, + { + orient: 'horizontal', + left: 0, + top: '40%', + width: '60%', + textStyle: { + fontSize: 12, + color: '#666' + }, + itemGap: 15, + itemWidth: 10, + itemHeight: 10, + formatter: (name, dataIndex) => { + const data = [15, 25, 40, 20]; + const names = ['紧急', '严重', '警告', '提示']; + const index = names.indexOf(name); + return index !== -1 ? `${name} ${data[index]}%` : `${name} 0%`; + }, + data: ['警告', '提示'] + } + ], + graphic: [ + { + type: 'text', + left: '5%', + bottom: '15%', + style: { + text: '故障等级分布', + fontSize: 16, + fontWeight: '400', + fill: '#666' + } + } + ], + series: [ + { + name: '故障等级分布', + type: 'pie', + radius: ['50%', '70%'], + center: ['80%', '50%'], + avoidLabelOverlap: false, + itemStyle: { + borderRadius: 10, + borderColor: '#291a1aff', + borderWidth: 0 + }, + label: { + show: false + }, + emphasis: { + label: { + show: false + } + }, + labelLine: { + show: false + }, + data: [ + { value: 15, name: '紧急', itemStyle: { color: '#006665' } }, + { value: 25, name: '严重', itemStyle: { color: '#faad14' } }, + { value: 40, name: '警告', itemStyle: { color: '#ff4d4f' } }, + { value: 20, name: '提示', itemStyle: { color: '#1890ff' } } + ] + } + ] + }); + + // 饼图配置 - 故障类型分布 + const getPieChartOption = () => ({ + title: { + text: '', + }, + tooltip: { + trigger: 'item', + formatter: '{b}: {c} ({d}%)' + }, + legend: { + orient: 'vertical', + left: 0, + top: 'center', + textStyle: { + fontSize: 12, + color: '#666' + }, + itemGap: 15, + itemWidth: 10, + itemHeight: 10, + formatter: (name) => { + // 根据name从series数据中查找对应的value + const seriesData = [ + { value: 30, name: '软件故障' }, + { value: 40, name: '硬件故障' }, + { value: 20, name: '人为操作' }, + { value: 10, name: '网络故障' } + ]; + const item = seriesData.find(item => item.name === name); + return `${name} ${item ? item.value : 0}%`; + } + // 移除静态data,让ECharts自动从series中获取 + }, + series: [ + { + name: '故障类型', + type: 'pie', + radius: ['60%', '80%'], + center: ['75%', '50%'], + avoidLabelOverlap: false, + itemStyle: { + borderRadius: 10, + borderColor: '#fff', + borderWidth: 2 + }, + label: { + show: false + }, + emphasis: { + label: { + show: true, + fontSize: '14', + fontWeight: 'bold' + } + }, + labelLine: { + show: false + }, + data: [ + { value: 30, name: '软件故障', itemStyle: { color: '#006665' } }, + { value: 40, name: '硬件故障', itemStyle: { color: '#ff4d4f' } }, + { value: 20, name: '人为操作', itemStyle: { color: '#faad14' } }, + { value: 10, name: '网络故障', itemStyle: { color: '#1890ff' } } + ] + } + ] + }); + + // 折线图配置 - 故障时间趋势 + const getDoubleLineChartOption = () => ({ + title: { + text: '', + }, + tooltip: { + trigger: 'axis', + axisPointer: { + type: 'cross', + label: { + backgroundColor: '#6a7985' + } + } + }, + grid: { + left: '3%', + right: '4%', + bottom: '3%', + top: '10%', + containLabel: true + }, + xAxis: [ + { + type: 'category', + boundaryGap: false, + data: ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12', '13', '14', '15', '16', '17', '18', '19', '20', '21', '22', '23', '24', '25', '26', '27', '28', '29', '30'], + axisLabel: { + fontSize: 10 + } + } + ], + yAxis: [ + { + type: 'value', + axisLabel: { + fontSize: 10 + } + } + ], + series: [ + { + name: '故障个数', + type: 'line', + data: [95, 96, 97, 98, 96, 97, 95, 98, 97, 96, 98, 99, 97, 96, 98, 97, 95, 96, 97, 98, 96, 97, 95, 98, 97, 96, 98, 99, 97, 96], + lineStyle: { + color: '#faad14', + width: 2 + }, + itemStyle: { + color: '#faad14' + }, + symbol: 'none', + smooth: true + }, + { + name: '处理效率', + type: 'line', + data: [85, 86, 87, 85, 86, 87, 88, 86, 85, 87, 88, 86, 85, 87, 88, 86, 85, 87, 86, 85, 87, 88, 86, 85, 87, 88, 86, 85, 87, 86], + lineStyle: { + color: '#006665', + width: 2 + }, + itemStyle: { + color: '#006665' + }, + symbol: 'none', + smooth: true, + areaStyle: { + color: { + type: 'linear', + x: 0, + y: 0, + x2: 0, + y2: 1, + colorStops: [{ + offset: 0, color: 'rgba(0, 102, 101, 0.3)' + }, { + offset: 1, color: 'rgba(0, 102, 101, 0.05)' + }] + } + } + } + ] + }); + + // 柱状图配置 - 设备类型故障 + const getDeviceTypeBarChartOption = () => ({ + tooltip: { + trigger: 'axis', + axisPointer: { + type: 'shadow' + } + }, + grid: { + left: '3%', + right: '4%', + bottom: 0, + top: '10%', + containLabel: true + }, + xAxis: [ + { + type: 'category', + data: ['传感器', '服务器', '网络设备', '安全设备', '网关', '摄像头', '执行器', '机房环境类', '其他'], + axisLabel: { + fontSize: 10, + // rotate: 45 + } + } + ], + yAxis: [ + { + type: 'value' + } + ], + series: [ + { + name: '故障数量', + type: 'bar', + data: [ + {value: 74, itemStyle: {color: '#C1D3D1'}}, + {value: 86, itemStyle: {color: '#045F5E80'}}, + {value: 95, itemStyle: {color: '#FFBC00'}}, + {value: 65, itemStyle: {color: '#FF826D'}}, + {value: 47, itemStyle: {color: '#C1D3D1'}}, + {value: 61, itemStyle: {color: '#045F5E80'}}, + {value: 71, itemStyle: {color: '#FFBC00'}}, + {value: 45, itemStyle: {color: '#FF826D'}}, + {value: 83, itemStyle: {color: '#C1D3D1'}} + ], + itemStyle: { + borderRadius: [4, 4, 0, 0] + }, + barWidth: '60%', + label: { + show: true, + position: 'top', + fontSize: 10, + color: '#666' + } + } + ] + }); + + // 仪表盘图配置 - 故障处理效率 + const getGaugeChartOption = () => ({ + tooltip: { + formatter: '{b}
当前平均处理时长: {c} 小时\n目标时长: 2 小时' + }, + series: [ + { + name: '处理效率', + type: 'gauge', + startAngle: 180, + endAngle: 0, + min: 0, + max: 120, + splitNumber: 6, + center: ['50%', '70%'], // 调整垂直位置向下移动 + axisLine: { + lineStyle: { + width: 10, + color: [ + [0.66, '#52c41a'], + [0.83, '#faad14'], + [1, '#ff4d4f'] + ] + } + }, + pointer: { + icon: 'path://M12.8,0.7l12,40.1H0.7L12.8,0.7z', + length: '12%', + width: 6, + offsetCenter: [0, '-60%'], + itemStyle: { + color: 'auto' + } + }, + axisTick: { + length: 12, + lineStyle: { + color: 'auto', + width: 2 + } + }, + splitLine: { + length: 20, + lineStyle: { + color: 'auto', + width: 5 + } + }, + axisLabel: { + color: '#464646', + fontSize: 12, + distance: -60, + formatter: function (value) { + return value + '分钟'; + } + }, + title: { + offsetCenter: [0, 50], + fontSize: 14 + }, + detail: { + fontSize: 12, + offsetCenter: [0, '30%'], + formatter: function(value) { + // 将分钟转换为小时 + const hours = (value / 60).toFixed(1); + return `当前平均处理时长(${hours} 小时)`; + }, + color: 'auto' + }, + data: [ + { + value: 78, + name: '目标时长(2小时)' + } + ] + } + ] + }); + + // 柱状图配置 - 各处理人故障处理数量(带虚线隔离) + const getHandlerBarChartOption = () => ({ + tooltip: { + trigger: 'axis', + axisPointer: { + type: 'shadow' + } + }, + grid: { + left: '3%', + right: '4%', + bottom: 0, + top: '10%', + containLabel: true + }, + xAxis: [ + { + type: 'category', + data: ['张工', '李工', '王工', '刘工', '陈工', '张工', '周工', '吴工', '郑工'], + axisLabel: { + fontSize: 10, + // rotate: 45 + } + } + ], + yAxis: [ + { + type: 'value' + } + ], + series: [ + { + name: '处理数量', + type: 'bar', + data: [ + {value: 74, itemStyle: {color: '#C1D3D1'}}, + {value: 86, itemStyle: {color: '#045F5E80'}}, + {value: 95, itemStyle: {color: '#FFBC00'}}, + {value: 65, itemStyle: {color: '#FF826D'}}, + {value: 47, itemStyle: {color: '#C1D3D1'}}, + {value: 61, itemStyle: {color: '#045F5E80'}}, + {value: 71, itemStyle: {color: '#FFBC00'}}, + {value: 45, itemStyle: {color: '#FF826D'}}, + {value: 83, itemStyle: {color: '#C1D3D1'}} + ], + itemStyle: { + borderRadius: [4, 4, 0, 0] + }, + barWidth: '60%', + label: { + show: true, + position: 'top', + fontSize: 10, + color: '#666' + }, + // 柱子之间添加虚线分隔 + markLine: { + silent: true, + lineStyle: { + color: '#e8e8e8', + type: 'dashed' + }, + data: [ + [{ xAxis: 0.5 }, { xAxis: 0.5 }], + [{ xAxis: 1.5 }, { xAxis: 1.5 }], + [{ xAxis: 2.5 }, { xAxis: 2.5 }], + [{ xAxis: 3.5 }, { xAxis: 3.5 }], + [{ xAxis: 4.5 }, { xAxis: 4.5 }], + [{ xAxis: 5.5 }, { xAxis: 5.5 }], + [{ xAxis: 6.5 }, { xAxis: 6.5 }], + [{ xAxis: 7.5 }, { xAxis: 7.5 }], + [{ xAxis: 8.5 }, { xAxis: 8.5 }] + ] + } + } + ] + }); + + // 初始化所有图表 + useEffect(() => { + const charts = []; + + // 第一行图表 + charts.push(initChart(chartRefs.row1Chart1, getGreenLineChartOption())); // 绿色折线图 + charts.push(initChart(chartRefs.row1Chart2, getRedLineChartOption())); // 红色折线图 + charts.push(initChart(chartRefs.row1Chart4, getGreenLineChartOption())); // 绿色折线图 + charts.push(initChart(chartRefs.row1Chart5, getRingChartOption())); // 环形图 + + // 第二行图表 + charts.push(initChart(chartRefs.row2Chart1, getPieChartOption())); // 饼图 - 故障类型分布 + charts.push(initChart(chartRefs.row2Chart2, getDoubleLineChartOption())); // 双折线图 - 故障时间趋势 + + // 第三行图表 + charts.push(initChart(chartRefs.row3Chart1, getDeviceTypeBarChartOption())); // 柱状图 - 设备类型故障 + charts.push(initChart(chartRefs.row3Chart2, getGaugeChartOption())); // 仪表盘图 - 故障处理效率 + charts.push(initChart(chartRefs.row3Chart3, getHandlerBarChartOption())); // 柱状图 - 各处理人故障处理数量 + + // 响应式处理 + const handleResize = () => { + charts.forEach(chart => chart && chart.resize()); + }; + + window.addEventListener('resize', handleResize); + + return () => { + window.removeEventListener('resize', handleResize); + charts.forEach(chart => chart && chart.dispose()); + }; + }, []); + + return ( +
+ + {/* 第一行:运维工单统计分析 */} + + +
+ + +
+
1234
+
总故障数
+
+ + +
月环比增长 15%
+
+ +
+
+ + +
+ + +
+
234
+
未处理故障
+
+ + +
月环比下降 8%
+
+ +
+
+ + +
+ + +
+
85%
+
故障处理完成率
+
+ + +
目标 95%,差距 10%
+ + +
+
+ + +
+ + +
+
2.5h
+
平均处理时间
+
+ + +
+ +
+
+ + +
+ + {/* +
+
100
+
故障等级分布
+
+ */} + {/* */} +
+ {/* */} +
+
+ +
+ + {/* 第二行:两个图表 */} + + +
+ {/* 故障类型分布 - 饼图 */} + + <div ref={chartRefs.row2Chart1} className="chart-container"></div> + </div> + </Col> + <Col span={18} > + <div className="content-item common-bg" style={{ height: '100%' }}> + {/* 故障时间趋势 - 折线图 */} + <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginBottom: '20px' }}> + <Title title="故障时间趋势" /> + <div style={{ display: 'flex', alignItems: 'center' }}> + <div style={{ display: 'flex', alignItems: 'center', marginRight: '20px' }}> + <span style={{ display: 'inline-block', width: '8px', height: '8px', backgroundColor: '#faad14', borderRadius: '50%', marginRight: '6px' }}></span> + <span style={{ fontSize: '12px', color: '#666' }}>故障个数</span> + </div> + <div style={{ display: 'flex', alignItems: 'center' }}> + <span style={{ display: 'inline-block', width: '8px', height: '8px', backgroundColor: '#006665', borderRadius: '50%', marginRight: '6px' }}></span> + <span style={{ fontSize: '12px', color: '#666' }}>处理效率</span> + </div> + </div> + </div> + <div ref={chartRefs.row2Chart2} className="chart-container"></div> + </div> + </Col> + </Row> + + {/* 第三行:两个图表 */} + <Row gutter={[20, 16]} className="content-row third-row"> + <Col span={12} > + <div className="content-item common-bg" style={{ height: '100%' }}> + {/* 设备类型故障 - 柱状图 */} + <Title title="设备类型故障" /> + <div ref={chartRefs.row3Chart1} className="chart-container"></div> + </div> + </Col> + <Col span={12} > + <div className="content-item common-bg" style={{ height: '100%' }}> + <Row gutter={[16, 16]} style={{ height: '100%' }}> + <Col span={8} style={{ height: '100%' }}> + {/* 故障处理效率 - 仪表盘 */} + <div style={{ height: '100%' }}> + <Title title="故障处理效率" /> + <div ref={chartRefs.row3Chart2} style={{ width: '100%', height: '200px' }} className="chart-container"></div> + </div> + </Col> + <Col span={16} style={{ height: '100%' }}> + {/* 各处理人故障处理数量 - 柱状图 */} + <div style={{ height: '100%' }}> + <Title title="各处理人故障处理数量" /> + <div ref={chartRefs.row3Chart3} style={{ width: '100%', height: '200px' }} className="chart-container"></div> + </div> + </Col> + </Row> + </div> + </Col> + </Row> + + {/* 第四行:表单 */} + <Row className="content-row"> + <Col span={24} > + <div style={{ height: '100%' }} className="content-item common-bg"> + <Title title="筛选导出" /> + <Form layout="inline" className="data-form" style={{ marginTop: '20px', width: '100%', flexDirection: 'column',alignItems: 'start' }}> + <div style={{ display: 'flex', alignItems: 'center' }}> + <Form.Item label="分析周期" name="analysisPeriod"> + <Select style={{ width: 120 }} placeholder="请选择"> + <Select.Option value="day">按天</Select.Option> + <Select.Option value="week">按周</Select.Option> + <Select.Option value="month">按月</Select.Option> + <Select.Option value="quarter">按季度</Select.Option> + </Select> + </Form.Item> + <Form.Item label="故障类型" name="faultType"> + <Select style={{ width: 120 }} placeholder="请选择"> + <Select.Option value="software">软件故障</Select.Option> + <Select.Option value="hardware">硬件故障</Select.Option> + <Select.Option value="human">人为操作</Select.Option> + <Select.Option value="network">网络故障</Select.Option> + </Select> + </Form.Item> + <Form.Item label="设备类型" name="deviceType"> + <Select style={{ width: 120 }} placeholder="请选择"> + <Select.Option value="sensor">传感器</Select.Option> + <Select.Option value="server">服务器</Select.Option> + <Select.Option value="network">网络设备</Select.Option> + <Select.Option value="security">安全设备</Select.Option> + </Select> + </Form.Item> + <Form.Item label="处理状态" name="handleStatus"> + <Select style={{ width: 120 }} placeholder="请选择"> + <Select.Option value="pending">未处理</Select.Option> + <Select.Option value="processing">处理中</Select.Option> + <Select.Option value="completed">已完成</Select.Option> + </Select> + </Form.Item> + </div> + <div style={{ display: 'flex', alignItems: 'center',justifyContent: 'flex-end', width: '100%' }}> + <Form.Item> + <Button className="search-button" type="primary" style={{ marginRight: '10px' }}>导出报表</Button> + <Button className="reset-button">导出数据</Button> + </Form.Item> + </div> + </Form> + </div> + </Col> + </Row> + </div> + ); +}; + +export default AnalyzeReportsData; \ No newline at end of file diff --git a/src/pages/analyzeReports_data/Data.less b/src/pages/analyzeReports_data/Data.less new file mode 100644 index 0000000..ae83f68 --- /dev/null +++ b/src/pages/analyzeReports_data/Data.less @@ -0,0 +1,256 @@ +.analyze-reports-data { + padding: 16px; + background-color: rgba(15, 121, 120, 0.05); + min-height: 100vh; +.search-button{ + background-image: url('../../assets/img/assetmangement1.png'); + background-repeat: no-repeat; + background-size: cover; + background-position:center; + color: #fff; + border-radius: 4px; + height: 36px; + border-color:#d9d9d9 ; +} +.reset-button{ + background-image: url('../../assets/img/assetmangement2.png'); + background-repeat: no-repeat; + background-size: cover; + background-position:center; + color: rgba(0, 102, 101, 1); + border-radius: 4px; + height: 36px; + border-color:#d9d9d9 ; +} +.del-button{ + background-image: url('../../assets/img/assetmangement3.png'); + background-repeat: no-repeat; + background-size: cover; + background-position:center; + color: #000; + border-radius: 4px; + height: 36px; + width:88px; + border-color:#d9d9d9 ; + background-color: #E5B7B733; +} + + + + .content-row { + margin-bottom: 16px; + + .content-item { + background-color: #fff; + padding: 16px; + border-radius: 6px; + box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1); + transition: all 0.3s ease; + + &:hover { + box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15); + } + + // 只有第一行有渐变边框 + .first-row & { + position: relative; + overflow: hidden; + background: linear-gradient(#fff, #fff) padding-box, + /* 外层渐变背景作为边框 */ + conic-gradient(from 102.21deg at 52.75% 38.75%, + rgba(249, 249, 249, 0.5) -32.95deg, + rgba(64, 64, 64, 0.5) 10.52deg, + rgba(64, 64, 64, 0.35) 32.12deg, + #FFFFFF 60.28deg, + rgba(255, 255, 255, 0.5) 107.79deg, + rgba(64, 64, 64, 0.35) 187.59deg, + #F9F9F9 207.58deg, + #FFFFFF 287.31deg, + rgba(249, 249, 249, 0.5) 327.05deg, + rgba(64, 64, 64, 0.5) 370.52deg + ); + /* 关键:设置透明边框,让渐变背景透出来 */ + border: 2px solid transparent; + } + + &.common-bg { + // 仅设置背景图片相关属性,不覆盖渐变边框 + background-image: none; + background-size: auto; + background-position: initial; + } + + .item-inner { + display: flex; + justify-content: space-between; + align-items: center; + height: 100%; + width: 100%; + } + + // 数据显示样式 + .data-value { + font-size: 26px; + font-weight: 600; + line-height: 32px; + color: #333333; + } + + .data-title { + font-size: 16px; + font-weight: 400; + line-height: 24px; + margin-top: 20px; + color: #666666; + white-space: nowrap; + } + + .data-desc { + font-size: 12px; + color: #999; + margin-top: 4px; + } + + .data-section { + flex: 1; + padding-right: 12px; + text-align: left; + } + + .chart-section { + flex: 1; + display: flex; + justify-content: center; + align-items: center; + } + + .chart-container { + width: 100%; + height: 200px; + } + + .progress-container { + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + height: 200px; + + .progress-title { + font-size: 16px; + font-weight: 500; + margin-bottom: 20px; + color: #333; + } + + .ant-progress { + width: 80%; + margin-bottom: 16px; + } + + .progress-text { + font-size: 24px; + font-weight: bold; + color: #006665; + } + } + + .data-form { + display: flex; + align-items: center; + flex-wrap: wrap; + + .ant-form-item { + margin-bottom: 16px; + margin-right: 16px; + } + } + } + } + + /* 响应式调整 */ + @media (max-width: 1200px) { + .content-row { + .content-item { + .chart-container { + height: 180px; + } + + .progress-container { + height: 180px; + } + + .item-inner { + flex-direction: column; + } + + .data-section { + padding-right: 0; + margin-bottom: 12px; + } + + .data-value { + font-size: 24px; + } + + .chart-section { + width: 100%; + } + } + } + } + + @media (max-width: 768px) { + padding: 8px; + + .content-row { + margin-bottom: 8px; + + .content-item { + padding: 8px; + + .chart-container { + height: 150px; + } + + .progress-container { + height: 150px; + + .progress-title { + font-size: 14px; + margin-bottom: 12px; + } + + .progress-text { + font-size: 20px; + } + } + + .item-inner { + flex-direction: column; + } + + .data-section { + padding-right: 0; + margin-bottom: 8px; + } + + .data-title { + font-size: 12px; + } + + .data-value { + font-size: 20px; + } + + .data-desc { + font-size: 10px; + } + + .chart-section { + width: 100%; + } + } + } + } +} \ No newline at end of file diff --git a/src/pages/nav_system_content/SystemContentList.js b/src/pages/nav_system_content/SystemContentList.js index 713b797..3d27c83 100644 --- a/src/pages/nav_system_content/SystemContentList.js +++ b/src/pages/nav_system_content/SystemContentList.js @@ -307,6 +307,12 @@ const SystemContentList = (props) => { key: "/topnavbar00/business/analyzeReports/set", "label": "报表设置" }, + // 分析报表数据 + { + path: '/topnavbar00/business/analyzeReports/data', + key: "/topnavbar00/business/analyzeReports/data", + "label": "报表数据" + }, ] }, ] diff --git a/src/pages/topnavbar/TopNavBar.js b/src/pages/topnavbar/TopNavBar.js index f919bc2..1029a6a 100644 --- a/src/pages/topnavbar/TopNavBar.js +++ b/src/pages/topnavbar/TopNavBar.js @@ -110,6 +110,11 @@ const menuItem = [ label: '分析报表', key: '/topnavbar00/business/analyzeReports/set', }, + // 分析报表数据 + { + label: '数据可视化和统计报表', + key: '/topnavbar00/business/analyzeReports/data', + }, ] const TopNavBar = (props) => {