From ce096c874f97d490f563948f4d86e7c2c76a5050 Mon Sep 17 00:00:00 2001 From: LiuJiaNan <15703339975@163.com> Date: Wed, 14 Jan 2026 11:30:38 +0800 Subject: [PATCH] =?UTF-8?q?=E5=88=86=E5=85=AC=E5=8F=B8BI?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/assets/images/public/bigScreen/ico21.png | Bin 0 -> 3494 bytes .../branchOffice/IndexRight/echarts.js | 2 +- .../Content/branchOffice/QiXiang/index.js | 2 +- .../components/CenterPanel/echarts.js | 923 ++++++++++++++++++ .../components/CenterPanel/index.js | 263 +++++ .../components/CenterPanel/index.less | 217 +++- .../components/LeftPanel/index.less | 4 +- .../components/RightPanel/index.less | 6 +- .../Container/WhiteBranchOffice/index.js | 9 +- .../Container/WhiteBranchOffice/index.less | 20 +- 10 files changed, 1428 insertions(+), 18 deletions(-) create mode 100644 src/assets/images/public/bigScreen/ico21.png create mode 100644 src/pages/Container/WhiteBranchOffice/components/CenterPanel/echarts.js diff --git a/src/assets/images/public/bigScreen/ico21.png b/src/assets/images/public/bigScreen/ico21.png new file mode 100644 index 0000000000000000000000000000000000000000..91e271e0d2118873b7b8a46a734ef5b4925cc15d GIT binary patch literal 3494 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 { }, itemStyle: { normal: { - color: (params) => { + color: () => { return new echarts.graphic.LinearGradient(0, 0, 1, 1, [ { offset: 0, diff --git a/src/pages/Container/Map/components/Content/branchOffice/QiXiang/index.js b/src/pages/Container/Map/components/Content/branchOffice/QiXiang/index.js index b99f725..1fd8e57 100644 --- a/src/pages/Container/Map/components/Content/branchOffice/QiXiang/index.js +++ b/src/pages/Container/Map/components/Content/branchOffice/QiXiang/index.js @@ -1,8 +1,8 @@ import { useEffect, useState } from "react"; import SeamlessScroll from "zy-react-library/components/SeamlessScroll"; +import icon3 from "~/assets/images/public/bigScreen/ico21.png"; import icon1 from "~/assets/images/public/bigScreen/img10.png"; import icon2 from "~/assets/images/public/bigScreen/img11.png"; -import icon3 from "~/assets/images/public/bigScreen/img11.png"; import { getAlertColor, getWeatherIcon } from "~/pages/Container/Map/components/Content/branchOffice/IndexLeft"; import Title from "~/pages/Container/Map/components/Content/branchOffice/Title"; import "./index.less"; diff --git a/src/pages/Container/WhiteBranchOffice/components/CenterPanel/echarts.js b/src/pages/Container/WhiteBranchOffice/components/CenterPanel/echarts.js new file mode 100644 index 0000000..3979a2d --- /dev/null +++ b/src/pages/Container/WhiteBranchOffice/components/CenterPanel/echarts.js @@ -0,0 +1,923 @@ +import * as echarts from "echarts"; + +export const initEcharts1 = (mainRef, chartInstance, data) => { + chartInstance.current = echarts.init(mainRef.current); + + const angle = 0; + const outerRidus1 = 0.8; + const outerRidus2 = 0.85; + + const colors = { + 重大风险: "#FF0000", + 较大风险: "#FF7900", + 一般风险: "#FEAD00", + 低风险: "#0078FF", + }; + + const option = { + legend: { + data: ["重大风险", "较大风险", "一般风险", "低风险"], + orient: "vertical", + right: "20px", + y: "center", + itemGap: 30, + formatter: (params) => { + let value; + let valueStyle; + switch (params) { + case "重大风险": + value = data.majorRiskCount; + valueStyle = "major_value"; + break; + case "较大风险": + value = data.greaterRiskCount; + valueStyle = "greater_value"; + break; + case "一般风险": + value = data.generalRiskCount; + valueStyle = "general_value"; + break; + case "低风险": + value = data.lowRiskCount; + valueStyle = "low_value"; + break; + default: + value = 0; + valueStyle = "default_value"; + } + + return `{text|${params}: }{${valueStyle}|${value}}`; + }, + textStyle: { + rich: { + major_value: { + color: colors["重大风险"], + fontSize: 16, + fontWeight: "bold", + padding: [0, 0, 0, 2], + }, + greater_value: { + color: colors["较大风险"], + fontSize: 16, + fontWeight: "bold", + padding: [0, 0, 0, 2], + }, + general_value: { + color: colors["一般风险"], + fontSize: 16, + fontWeight: "bold", + padding: [0, 0, 0, 2], + }, + low_value: { + color: colors["低风险"], + fontSize: 16, + fontWeight: "bold", + padding: [0, 0, 0, 2], + }, + default_value: { + color: "#999", + fontSize: 16, + fontWeight: "bold", + padding: [0, 0, 0, 2], + }, + text: { + color: "#000", + fontSize: 16, + padding: [0, 0, 0, 5], + }, + }, + }, + }, + tooltip: { + show: true, + }, + series: [ + { + type: "pie", + radius: ["75%", "55%"], + center: ["35%", "50%"], + emphasis: { + scale: false, + }, + data: [ + { + value: data.majorRiskCount, + name: "重大风险", + itemStyle: { + color: colors["重大风险"], + }, + }, + { + value: data.greaterRiskCount, + name: "较大风险", + itemStyle: { + color: colors["较大风险"], + }, + }, + { + value: data.generalRiskCount, + name: "一般风险", + itemStyle: { + color: colors["一般风险"], + }, + }, + { + value: data.lowRiskCount, + name: "低风险", + itemStyle: { + color: colors["低风险"], + }, + }, + ], + label: { + show: false, + }, + }, + { + type: "pie", + radius: ["60%", "40%"], + center: ["35%", "50%"], + emphasis: { + scale: false, + }, + z: 10, + label: { + position: "center", + formatter: () => { + return ""; + }, + }, + data: [ + { + value: data.majorRiskCount, + name: "重大风险", + itemStyle: { + color: colors["重大风险"], + opacity: 0.5, + }, + }, + { + value: data.greaterRiskCount, + name: "较大风险", + itemStyle: { + color: colors["较大风险"], + opacity: 0.5, + }, + }, + { + value: data.generalRiskCount, + name: "一般风险", + itemStyle: { + color: colors["一般风险"], + opacity: 0.5, + }, + }, + { + value: data.lowRiskCount, + name: "低风险", + itemStyle: { + color: colors["低风险"], + opacity: 0.5, + }, + }, + ], + labelLine: { + show: false, + }, + }, + { + name: "ring5", + type: "custom", + coordinateSystem: "none", + renderItem(params, api) { + const pieCenterX = api.getWidth() * 0.35; + const pieCenterY = api.getHeight() * 0.5; + + return { + type: "arc", + shape: { + cx: pieCenterX, + cy: pieCenterY, + r: Math.min(api.getWidth(), api.getHeight()) / 2 * outerRidus1, + startAngle: ((0 + angle) * Math.PI) / 180, + endAngle: ((90 + angle) * Math.PI) / 180, + }, + style: { + stroke: colors["重大风险"], + fill: "transparent", + lineWidth: 1.5, + }, + silent: true, + }; + }, + data: [0], + }, + { + name: "ring5", + type: "custom", + coordinateSystem: "none", + renderItem(params, api) { + const pieCenterX = api.getWidth() * 0.35; + const pieCenterY = api.getHeight() * 0.5; + const r = Math.min(api.getWidth(), api.getHeight()) / 2 * outerRidus1; + const point = getCirlPoint(pieCenterX, pieCenterY, r, 0 + angle); + return { + type: "circle", + shape: { + cx: point.x, + cy: point.y, + r: 4, + }, + style: { + stroke: colors["重大风险"], + fill: colors["重大风险"], + }, + silent: true, + }; + }, + data: [0], + }, + { + name: "ring5", + type: "custom", + coordinateSystem: "none", + renderItem(params, api) { + const pieCenterX = api.getWidth() * 0.35; + const pieCenterY = api.getHeight() * 0.5; + + return { + type: "arc", + shape: { + cx: pieCenterX, + cy: pieCenterY, + r: Math.min(api.getWidth(), api.getHeight()) / 2 * outerRidus1, + startAngle: ((180 + angle) * Math.PI) / 180, + endAngle: ((270 + angle) * Math.PI) / 180, + }, + style: { + stroke: colors["较大风险"], + fill: "transparent", + lineWidth: 1.5, + }, + silent: true, + }; + }, + data: [0], + }, + { + name: "ring5", + type: "custom", + coordinateSystem: "none", + renderItem(params, api) { + const pieCenterX = api.getWidth() * 0.35; + const pieCenterY = api.getHeight() * 0.5; + const r = Math.min(api.getWidth(), api.getHeight()) / 2 * outerRidus1; + const point = getCirlPoint(pieCenterX, pieCenterY, r, 180 + angle); + return { + type: "circle", + shape: { + cx: point.x, + cy: point.y, + r: 4, + }, + style: { + stroke: colors["较大风险"], + fill: colors["较大风险"], + }, + silent: true, + }; + }, + data: [0], + }, + { + name: "ring5", + type: "custom", + coordinateSystem: "none", + renderItem(params, api) { + const pieCenterX = api.getWidth() * 0.35; + const pieCenterY = api.getHeight() * 0.5; + + return { + type: "arc", + shape: { + cx: pieCenterX, + cy: pieCenterY, + r: Math.min(api.getWidth(), api.getHeight()) / 2 * outerRidus2, + startAngle: ((250 + -angle) * Math.PI) / 180, + endAngle: ((10 + -angle) * Math.PI) / 180, + }, + style: { + stroke: colors["一般风险"], + fill: "transparent", + lineWidth: 1.5, + }, + silent: true, + }; + }, + data: [0], + }, + { + name: "ring5", + type: "custom", + coordinateSystem: "none", + renderItem(params, api) { + const pieCenterX = api.getWidth() * 0.35; + const pieCenterY = api.getHeight() * 0.5; + const r = Math.min(api.getWidth(), api.getHeight()) / 2 * outerRidus2; + const point = getCirlPoint(pieCenterX, pieCenterY, r, 250 + -angle); + return { + type: "circle", + shape: { + cx: point.x, + cy: point.y, + r: 4, + }, + style: { + stroke: colors["一般风险"], + fill: colors["一般风险"], + }, + silent: true, + }; + }, + data: [0], + }, + { + name: "ring5", + type: "custom", + coordinateSystem: "none", + renderItem(params, api) { + const pieCenterX = api.getWidth() * 0.35; + const pieCenterY = api.getHeight() * 0.5; + + return { + type: "arc", + shape: { + cx: pieCenterX, + cy: pieCenterY, + r: Math.min(api.getWidth(), api.getHeight()) / 2 * outerRidus2, + startAngle: ((70 + -angle) * Math.PI) / 180, + endAngle: ((200 + -angle) * Math.PI) / 180, + }, + style: { + stroke: colors["低风险"], + fill: "transparent", + lineWidth: 1.5, + }, + silent: true, + }; + }, + data: [0], + }, + { + name: "ring5", + type: "custom", + coordinateSystem: "none", + renderItem(params, api) { + const pieCenterX = api.getWidth() * 0.35; + const pieCenterY = api.getHeight() * 0.5; + const r = Math.min(api.getWidth(), api.getHeight()) / 2 * outerRidus2; + const point = getCirlPoint(pieCenterX, pieCenterY, r, 70 + -angle); + return { + type: "circle", + shape: { + cx: point.x, + cy: point.y, + r: 4, + }, + style: { + stroke: colors["低风险"], + fill: colors["低风险"], + }, + silent: true, + }; + }, + data: [0], + }, + ], + }; + + function getCirlPoint(x0, y0, r, angle) { + const x1 = x0 + r * Math.cos((angle * Math.PI) / 180); + const y1 = y0 + r * Math.sin((angle * Math.PI) / 180); + return { + x: x1, + y: y1, + }; + } + + chartInstance.current.setOption(option); +}; + +export const initEcharts2 = (mainRef, chartInstance, data) => { + chartInstance.current = echarts.init(mainRef.current); + + const option = { + color: ["#F1C416", "#0AFCFF"], + tooltip: { + trigger: "axis", + axisPointer: { + type: "shadow", + label: { + backgroundColor: "#6a7985", + }, + }, + }, + grid: { + left: "3%", + right: "4%", + bottom: "10%", + top: 40, + padding: "0 0 10 0", + containLabel: true, + }, + legend: { + right: 10, + top: 10, + itemGap: 16, + itemWidth: 18, + itemHeight: 10, + textStyle: { + color: "#465683", + fontStyle: "normal", + fontFamily: "微软雅黑", + fontSize: 12, + }, + }, + dataZoom: [ + { + type: "slider", + height: 6, + bottom: "6%", + show: true, + start: 0, + end: 50, + handleSize: 3, + handleStyle: { + color: "#465683", + }, + xAxisIndex: [0], + filterMode: "filter", + showDetail: false, + }, + ], + xAxis: [ + { + type: "category", + boundaryGap: true, + data: data.map(item => item.name), + axisLabel: { + interval: 0, + margin: 15, + color: "#465683", + fontStyle: "normal", + fontFamily: "微软雅黑", + fontSize: 12, + }, + axisTick: { + show: false, + }, + axisLine: { + lineStyle: { + color: "#465683", + opacity: 0.2, + }, + }, + splitLine: { + show: false, + }, + }, + ], + yAxis: [ + { + type: "value", + splitNumber: 5, + axisLabel: { + color: "#465683", + fontStyle: "normal", + fontFamily: "微软雅黑", + fontSize: 12, + }, + axisLine: { + show: false, + }, + axisTick: { + show: false, + }, + splitLine: { + show: true, + lineStyle: { + color: ["#465683"], + opacity: 0.06, + }, + }, + }, + ], + series: [ + { + name: "已整改", + type: "pictorialBar", + symbol: "roundRect", + symbolOffset: [-5, 0], + symbolMargin: "1", + barWidth: "10%", + barMaxWidth: "20%", + animationDelay: (dataIndex, params) => { + return params.index * 50; + }, + itemStyle: { + color: () => { + return new echarts.graphic.LinearGradient(0, 0, 1, 1, [ + { + offset: 0, + color: "#FF9600", + }, + { + offset: 1, + color: "#F0E203", + }, + ]); + }, + }, + z: 1, + barGap: 0, + symbolRepeat: true, + symbolSize: [14, 5], + data: data.map(item => item.unitCount), + animationEasing: "elasticOut", + stack: "2", + }, + { + name: "已验收", + type: "pictorialBar", + symbol: "roundRect", + barWidth: "10%", + symbolOffset: [5, 0], + barMaxWidth: "20%", + symbolMargin: "1", + animationDelay: (dataIndex, params) => { + return params.index * 50; + }, + itemStyle: { + color: () => { + return new echarts.graphic.LinearGradient(0, 0, 1, 1, [ + { + offset: 0, + color: "#19D4FE", + }, + { + offset: 1, + color: "#089FFD", + }, + ]); + }, + }, + z: 1, + barGap: 0, + symbolRepeat: true, + symbolSize: [14, 5], + data: data.map(item => item.personnelCount), + animationEasing: "elasticOut", + stack: "1", + }, + ], + }; + + chartInstance.current.setOption(option); +}; + +export const initEcharts3 = (mainRef, chartInstance, data) => { + chartInstance.current = echarts.init(mainRef.current); + + const colorList1 = ["#FF6B6B", "", "#FFD93D", "", "#6BCF7F", "", "#4ECDC4", "", "#A084CA", "", "#FF9AA2", ""]; + const colorList2 = ["rgba(255,107,107, 0.6)", "", "rgba(255,217,61, 0.6)", "", "rgba(107,207,127, 0.6)", "", "rgba(78,205,196, 0.6)", "", "rgba(160,132,202, 0.6)", "", "rgba(255,154,162, 0.6)", ""]; + + const optionData = []; + data.forEach((item) => { + optionData.push({ value: item.value, name: item.name }); + optionData.push({ name: "", value: 1, itemStyle: { color: "transparent" } }); + }); + + const option = { + tooltip: { + trigger: "item", + }, + legend: { + show: true, + orient: "vertical", + right: "10%", + top: "center", + textStyle: { + color: "#3F4554", + fontSize: 12, + }, + data: data.map(item => item.name), + }, + series: [ + { + type: "pie", + zlevel: 3, + radius: ["30%", "70%"], + center: ["25%", "50%"], + itemStyle: { + color(params) { + return colorList1[params.dataIndex]; + }, + }, + label: { + show: false, + }, + data: optionData, + }, + { + type: "pie", + zlevel: 1, + silent: true, + radius: ["73%", "80%"], + center: ["25%", "50%"], + itemStyle: { + color(params) { + return colorList2[params.dataIndex]; + }, + }, + label: { + show: false, + }, + data: optionData, + }, + { + type: "pie", + radius: ["85%", "86%"], + center: ["25%", "50%"], + emphasis: { + scale: false, + }, + clockwise: false, + itemStyle: { + shadowBlur: 1, + shadowColor: "rgba(15, 79, 150,1)", + color: "rgba(23,138,173,1)", + }, + label: { + show: false, + }, + data: [0], + }, + ], + }; + + chartInstance.current.setOption(option); +}; + +export const initEcharts4 = (mainRef, chartInstance, data) => { + chartInstance.current = echarts.init(mainRef.current); + + const option = { + grid: { + containLabel: true, + bottom: "5%", + left: "-15%", + top: "10%", + right: "5%", + }, + xAxis: { + type: "value", + max: 100, + axisLabel: { + show: false, + }, + axisLine: { + show: false, + }, + axisTick: { + show: false, + }, + splitLine: { + show: false, + }, + }, + yAxis: [ + { + type: "category", + data: data.map(item => item.name), + inverse: true, + position: "left", + axisLabel: { + show: false, + }, + axisLine: { + show: false, + }, + axisTick: { + show: false, + }, + splitLine: { + show: false, + }, + }, + { + type: "category", + data: data.map(item => item.value), + inverse: true, + position: "right", + axisLabel: { + show: true, + margin: -30, + fontSize: 14, + align: "top", + verticalAlign: "bottom", + padding: [0, 0, 10, 0], + color: "#465683", + formatter(value) { + return `${value}%`; + }, + }, + axisLine: { + show: false, + }, + axisTick: { + show: false, + }, + splitLine: { + show: false, + }, + }, + { + type: "category", + inverse: true, + position: "left", + axisLine: { + show: false, + }, + axisTick: { + show: false, + }, + data: data.map(item => item.name), + axisLabel: { + show: true, + margin: -2, + fontSize: 14, + align: "top", + verticalAlign: "bottom", + padding: [0, 0, 10, 0], + color: "#465683", + }, + }, + ], + series: [ + { + data: data.map(item => item.value), + itemStyle: { + color: new echarts.graphic.LinearGradient(0, 1, 1, 1, [ + { offset: 0, color: "#0096F8" }, + { offset: 1, color: "#1CD0E7" }, + ]), + borderRadius: 30, + }, + type: "bar", + barWidth: 10, + showBackground: true, + backgroundStyle: { + color: "rgba(255,255,255,0.5)", + borderRadius: 30, + }, + }, + ], + }; + + chartInstance.current.setOption(option); +}; + +export const initEcharts5 = (mainRef, chartInstance, data) => { + chartInstance.current = echarts.init(mainRef.current); + + const option = { + color: ["#007CFA", "#009944"], + title: [ + { + text: "同比:下降5%", + x: 10, + y: 10, + textStyle: { + fontSize: 14, + color: "#465683", + }, + }, + { + text: "环比:提升6%", + x: 150, + y: 10, + textStyle: { + fontSize: 14, + color: "#465683", + }, + }, + ], + tooltip: { + trigger: "axis", + }, + legend: { + right: 10, + top: 10, + itemGap: 16, + itemWidth: 18, + itemHeight: 10, + textStyle: { + color: "#465683", + fontStyle: "normal", + fontFamily: "微软雅黑", + fontSize: 12, + }, + }, + grid: { + left: "3%", + right: "4%", + bottom: "10%", + top: 40, + padding: "0 0 10 0", + containLabel: true, + }, + dataZoom: [ + { + type: "slider", + height: 6, + bottom: "6%", + show: true, + start: 0, + end: 50, + handleSize: 3, + handleStyle: { + color: "#465683", + }, + xAxisIndex: [0], + filterMode: "filter", + showDetail: false, + }, + ], + xAxis: [ + { + type: "category", + boundaryGap: true, + data: data.map(item => item.department), + axisLabel: { + interval: 0, + margin: 15, + color: "#465683", + fontStyle: "normal", + fontFamily: "微软雅黑", + fontSize: 12, + }, + axisTick: { + show: false, + }, + axisLine: { + lineStyle: { + color: "#465683", + opacity: 0.2, + }, + }, + splitLine: { + show: false, + }, + }, + ], + yAxis: [ + { + type: "value", + splitNumber: 5, + axisLabel: { + color: "#465683", + fontStyle: "normal", + fontFamily: "微软雅黑", + fontSize: 12, + }, + axisLine: { + show: false, + }, + axisTick: { + show: false, + }, + splitLine: { + show: true, + lineStyle: { + color: ["#465683"], + opacity: 0.06, + }, + }, + }, + ], + series: [ + { + name: "同比", + type: "line", + data: data.map(item => item.yearOnYear), + }, + { + name: "环比", + type: "line", + data: data.map(item => item.monthOnMonth), + }, + ], + }; + + chartInstance.current.setOption(option); +}; diff --git a/src/pages/Container/WhiteBranchOffice/components/CenterPanel/index.js b/src/pages/Container/WhiteBranchOffice/components/CenterPanel/index.js index 29e793b..25382f8 100644 --- a/src/pages/Container/WhiteBranchOffice/components/CenterPanel/index.js +++ b/src/pages/Container/WhiteBranchOffice/components/CenterPanel/index.js @@ -1,12 +1,275 @@ +import { useEventListener, useMount } from "ahooks"; +import { useEffect, useRef, useState } from "react"; +import SeamlessScroll from "zy-react-library/components/SeamlessScroll"; +import { getAlertColor, getWeatherIcon } from "~/pages/Container/Map/components/Content/branchOffice/IndexLeft"; import Title from "~/pages/Container/WhiteBranchOffice/components/Title"; +import { initEcharts1, initEcharts2, initEcharts3, initEcharts4, initEcharts5 } from "./echarts"; import "./index.less"; function CenterPanel() { + const [weatherData, setWeatherData] = useState({ + text: "晴天", + temp: "36.5", + wind_class: "3级", + wind_dir: "西南风", + wind_angle: 229, + prec_1h: 0, + }); + const [alert, setAlert] = useState([]); + const [block1_2List, setBlock1_2List] = useState([ + { department: "技术部", requiredDevices: 150, anchoredDevices: 142 }, + { department: "销售部", requiredDevices: 80, anchoredDevices: 76 }, + { department: "市场部", requiredDevices: 60, anchoredDevices: 58 }, + { department: "运营部", requiredDevices: 120, anchoredDevices: 115 }, + { department: "客服部", requiredDevices: 90, anchoredDevices: 88 }, + { department: "财务部", requiredDevices: 30, anchoredDevices: 29 }, + { department: "人事部", requiredDevices: 25, anchoredDevices: 24 }, + { department: "研发部", requiredDevices: 200, anchoredDevices: 195 }, + { department: "质量部", requiredDevices: 45, anchoredDevices: 42 }, + { department: "采购部", requiredDevices: 35, anchoredDevices: 33 }, + ]); + const [block1_3List, setBlock1_3List] = useState([ + { title: "股份", count1: 100, count2: 80 }, + { title: "领域", count1: 50, count2: 40 }, + { title: "自查", count1: 50, count2: 40 }, + { title: "专项", count1: 50, count2: 40 }, + ]); + + const chart1Instance = useRef(null); + const main1Ref = useRef(null); + const chart2Instance = useRef(null); + const main2Ref = useRef(null); + const chart3Instance = useRef(null); + const main3Ref = useRef(null); + const chart4Instance = useRef(null); + const main4Ref = useRef(null); + const chart5Instance = useRef(null); + const main5Ref = useRef(null); + + const getWeatherData = async () => { + try { + const response = await fetch("https://api.map.baidu.com/weather/v1/?district_id=130300&data_type=all&ak=dIqOi34IlTg5FkNck1vqoBpLhPAj36S1"); + const data = await response.json(); + setWeatherData(data.result.now); + setAlert(Array.isArray(data.result.alerts) ? data.result.alerts : []); + } + catch (error) { + console.error("获取天气数据失败:", error); + } + }; + + useEffect(() => { + getWeatherData(); + }, []); + + useEventListener("resize", () => { + setTimeout(() => { + if (chart1Instance.current) { + chart1Instance.current.resize(); + } + if (chart2Instance.current) { + chart2Instance.current.resize(); + } + if (chart3Instance.current) { + chart3Instance.current.resize(); + } + if (chart4Instance.current) { + chart4Instance.current.resize(); + } + if (chart5Instance.current) { + chart5Instance.current.resize(); + } + }, 0); + }); + + useMount(() => { + setTimeout(() => { + initEcharts1(main1Ref, chart1Instance, { + majorRiskCount: 1, + greaterRiskCount: 2, + generalRiskCount: 3, + lowRiskCount: 4, + }); + initEcharts2(main2Ref, chart2Instance, [ + { name: "技术部1", unitCount: 95, personnelCount: 92 }, + { name: "技术部2", unitCount: 95, personnelCount: 92 }, + { name: "技术部3", unitCount: 95, personnelCount: 92 }, + { name: "技术部4", unitCount: 95, personnelCount: 92 }, + { name: "技术部5", unitCount: 95, personnelCount: 92 }, + { name: "技术部6", unitCount: 95, personnelCount: 92 }, + { name: "技术部7", unitCount: 95, personnelCount: 92 }, + { name: "技术部8", unitCount: 95, personnelCount: 92 }, + { name: "技术部9", unitCount: 95, personnelCount: 92 }, + { name: "技术部0", unitCount: 95, personnelCount: 92 }, + ]); + initEcharts3(main3Ref, chart3Instance, [ + { name: "火灾隐患", value: "15" }, + { name: "电气隐患", value: "22" }, + { name: "机械伤害隐患", value: "18" }, + { name: "高空坠落隐患", value: "12" }, + { name: "化学品泄漏隐患", value: "8" }, + { name: "粉尘爆炸隐患", value: "5" }, + ]); + initEcharts4(main4Ref, chart4Instance, [ + { value: 44, name: "风险点检查覆盖率" }, + { value: 43, name: "自查清单检查率" }, + { value: 41, name: "安全环保检查完成率" }, + { value: 40, name: "隐患整改完成率" }, + ]); + initEcharts5(main5Ref, chart5Instance, [ + { department: "安全部", yearOnYear: 15, monthOnMonth: 8 }, + { department: "生产部", yearOnYear: -12, monthOnMonth: 6 }, + { department: "设备部", yearOnYear: 10, monthOnMonth: 5 }, + { department: "技术部", yearOnYear: 8, monthOnMonth: 3 }, + { department: "质检部", yearOnYear: 6, monthOnMonth: 4 }, + { department: "物流部", yearOnYear: 5, monthOnMonth: 2 }, + { department: "财务部", yearOnYear: 4, monthOnMonth: 1 }, + { department: "人力资源部", yearOnYear: 3, monthOnMonth: 1 }, + { department: "生产计划部", yearOnYear: 2, monthOnMonth: 1 }, + { department: "质量部", yearOnYear: 1, monthOnMonth: 1 }, + { department: "设备管理部", yearOnYear: 1, monthOnMonth: 1 }, + { department: "设备管理部", yearOnYear: 1, monthOnMonth: 1 }, + ]); + }, 0); + + return () => { + if (chart1Instance.current) { + chart1Instance.current.dispose(); + chart1Instance.current = null; + } + if (chart2Instance.current) { + chart2Instance.current.dispose(); + chart2Instance.current = null; + } + if (chart3Instance.current) { + chart3Instance.current.dispose(); + chart3Instance.current = null; + } + if (chart4Instance.current) { + chart4Instance.current.dispose(); + chart4Instance.current = null; + } + if (chart5Instance.current) { + chart5Instance.current.dispose(); + chart5Instance.current = null; + } + }; + }); + return (
<div className="container"> + <div> + <div className="block1_1"> + <div ref={main1Ref} style={{ width: "100%", height: "200px" }} /> + </div> + <div className="block1_2"> + <div className="alert"> + <div className="scroll"> + <SeamlessScroll list={alert} step={0.5} limitScrollNum={2} singleHeight={22}> + { + alert.map((item, index) => ( + <div className="item" key={index}> + <div className="title" style={{ color: getAlertColor(item.level) === "#fff" ? "#2E75C6" : getAlertColor(item.level) }}>{item.title}</div> + </div> + )) + } + </SeamlessScroll> + </div> + </div> + <div className="weather"> + <div className="icon"> + <div className="img"> + <img src={getWeatherIcon(weatherData.text)} alt="" /> + </div> + <div className="text">{weatherData.text}</div> + </div> + <div className="items"> + <div className="item"> + <div className="info"> + <div className="label">温度:</div> + <div className="value">{`${weatherData.temp}℃`}</div> + </div> + </div> + <div className="item"> + <div className="info"> + <div className="label">风速:</div> + <div className="value">{weatherData.wind_class}</div> + </div> + </div> + </div> + </div> + <div className="table"> + <div className="tr"> + <div className="td">部门名称</div> + <div className="td">需锚定设备数</div> + <div className="td">已锚定设备数</div> + </div> + <div className="scroll"> + <SeamlessScroll list={block1_2List} step={0.5}> + {block1_2List.map((item, index) => ( + <div key={index} className="tr"> + <div className="td">{item.department}</div> + <div className="td">{item.requiredDevices}</div> + <div className="td">{item.anchoredDevices}</div> + </div> + ))} + </SeamlessScroll> + </div> + </div> + </div> + </div> + <div className="block1_3"> + <div className="items"> + { + block1_3List.map((item, index) => ( + <div key={index} className="item"> + <div className="title">{item.title}</div> + <div className="info"> + <div> + <div className="label">发现数</div> + <div className="value" style={{ color: "#2D8EF3" }}>{item.count1}</div> + </div> + <div> + <div className="label">整改数</div> + <div className="value" style={{ color: "#F78F00" }}>{item.count1}</div> + </div> + </div> + </div> + )) + } + </div> + </div> + </div> + </div> + <div className="block2"> + <div className="block2_1"> + <Title title="发现整改验收情况" /> + <div className="container"> + <div ref={main2Ref} style={{ width: "100%", height: "225px" }} /> + </div> + </div> + <div className="block2_2"> + <Title title="隐患类型统计" /> + <div className="container"> + <div ref={main3Ref} style={{ width: "100%", height: "225px" }} /> + </div> + </div> + </div> + <div className="block3"> + <div className="block3_1"> + <Title title="隐患排查治理信息" /> + <div className="container"> + <div ref={main4Ref} style={{ width: "100%", height: "225px" }} /> + </div> + </div> + <div className="block3_2"> + <Title title="隐患治理的环比与同比情况" /> + <div className="container"> + <div ref={main5Ref} style={{ width: "100%", height: "225px" }} /> + </div> </div> </div> </div> diff --git a/src/pages/Container/WhiteBranchOffice/components/CenterPanel/index.less b/src/pages/Container/WhiteBranchOffice/components/CenterPanel/index.less index ae0675c..2675375 100644 --- a/src/pages/Container/WhiteBranchOffice/components/CenterPanel/index.less +++ b/src/pages/Container/WhiteBranchOffice/components/CenterPanel/index.less @@ -1,4 +1,6 @@ -.white_branch_office_center_container{ +@import "../../index.less"; + +.white_branch_office_center_container { flex: 1; .block1 { @@ -7,7 +9,218 @@ border: 1px solid #fff; border-top: none; background-color: #E0EDFD; - padding: 16px 20px; + padding: 16px 11px; + + > div { + display: flex; + gap: 10px; + } + + .block1_1 { + width: 50%; + border-radius: 4px; + border: 1px solid #fff; + background-image: linear-gradient(180deg, rgb(217, 239, 253) 0%, rgb(225, 243, 254) 58%, rgb(232, 246, 255) 100%); + box-shadow: inset 0 1px 3px 0 rgba(49, 122, 202, 0.48); + } + + .block1_2 { + width: 50%; + border-radius: 4px; + border: 1px solid #fff; + background-image: linear-gradient(180deg, rgb(217, 239, 253) 0%, rgb(225, 243, 254) 58%, rgb(232, 246, 255) 100%); + box-shadow: inset 0 1px 3px 0 rgba(49, 122, 202, 0.48); + padding: 10px 11px; + + .weather { + display: flex; + gap: 40px; + + .icon { + padding: 10px; + display: flex; + align-items: center; + gap: 5px; + + .img { + img { + width: 40px; + height: 40px; + } + } + + .text { + color: #2B4977; + writing-mode: vertical-lr; + letter-spacing: 5px; + font-size: 14px; + font-weight: bold; + } + } + + .items { + flex: 1; + display: flex; + align-items: center; + justify-content: space-between; + flex-wrap: wrap; + gap: 20px 10px; + + .item { + width: calc((100% / 2) - 10px); + display: flex; + align-items: center; + justify-content: center; + text-align: center; + gap: 10px; + + .info { + .label { + font-size: 14px; + color: #2B4977; + font-weight: bold; + } + + .value { + font-size: 20px; + color: #2E75C6; + font-weight: bold; + } + } + } + } + } + + .alert { + margin-top: 10px; + + .scroll { + height: 20px; + overflow-y: hidden; + + .item { + .title { + font-weight: bold; + font-size: 14px; + } + } + } + } + + .table-style(50px, repeat(3, 1fr)); + + .table { + margin-top: 5px; + } + } + + .block1_3 { + margin-top: 10px; + + .items { + width: 100%; + display: flex; + justify-content: space-between; + align-items: center; + gap: 9px; + + .item { + flex: 1; + border-radius: 4px; + border: 1px solid #fff; + background-image: linear-gradient(180deg, rgb(217, 239, 253) 0%, rgb(225, 243, 254) 58%, rgb(232, 246, 255) 100%); + box-shadow: inset 0 1px 3px 0 rgba(49, 122, 202, 0.48); + padding: 10px 20px; + text-align: center; + + .title { + color: #305683; + font-weight: bold; + font-size: 16px; + } + + .info { + margin-top: 10px; + display: flex; + justify-content: center; + + > div { + &:first-child { + margin-right: 30px; + position: relative; + &::before { + content: ""; + position: absolute; + width: 1px; + height: 60%; + background-color: rgba(48, 86, 131, 0.3); + top: 20%; + left: calc(100% + 30px); + } + } + + &:last-child { + margin-left: 30px; + } + } + + .label { + color: #305683; + font-size: 14px; + } + + .value { + font-size: 18px; + font-weight: bold; + } + } + } + } + } + } + } + + .block2{ + margin-top: 10px; + display: flex; + gap: 10px; + + .block2_1{ + width: 50%; + border-radius: 4px; + border: 1px solid #fff; + background-image: linear-gradient(180deg, rgb(217, 239, 253) 0%, rgb(225, 243, 254) 58%, rgb(232, 246, 255) 100%); + box-shadow: inset 0 1px 3px 0 rgba(49, 122, 202, 0.48); + } + + .block2_2{ + width: 50%; + border-radius: 4px; + border: 1px solid #fff; + background-image: linear-gradient(180deg, rgb(217, 239, 253) 0%, rgb(225, 243, 254) 58%, rgb(232, 246, 255) 100%); + box-shadow: inset 0 1px 3px 0 rgba(49, 122, 202, 0.48); + } + } + + .block3{ + margin-top: 10px; + display: flex; + gap: 10px; + + .block3_1{ + width: 50%; + border-radius: 4px; + border: 1px solid #fff; + background-image: linear-gradient(180deg, rgb(217, 239, 253) 0%, rgb(225, 243, 254) 58%, rgb(232, 246, 255) 100%); + box-shadow: inset 0 1px 3px 0 rgba(49, 122, 202, 0.48); + } + + .block3_2{ + width: 50%; + border-radius: 4px; + border: 1px solid #fff; + background-image: linear-gradient(180deg, rgb(217, 239, 253) 0%, rgb(225, 243, 254) 58%, rgb(232, 246, 255) 100%); + box-shadow: inset 0 1px 3px 0 rgba(49, 122, 202, 0.48); } } } diff --git a/src/pages/Container/WhiteBranchOffice/components/LeftPanel/index.less b/src/pages/Container/WhiteBranchOffice/components/LeftPanel/index.less index 495f053..8761a0c 100644 --- a/src/pages/Container/WhiteBranchOffice/components/LeftPanel/index.less +++ b/src/pages/Container/WhiteBranchOffice/components/LeftPanel/index.less @@ -73,7 +73,7 @@ border-top: none; background-color: #E0EDFD; padding: 10px; - .table-style(280px, 1.5fr 1fr 1fr 1fr 1.6fr); + .table-style(230px, 1.5fr 1fr 1fr 1fr 1.6fr); } } @@ -86,7 +86,7 @@ border-top: none; background-color: #E0EDFD; padding: 10px; - .table-style(280px, repeat(5, 1fr)); + .table-style(230px, repeat(5, 1fr)); } } } diff --git a/src/pages/Container/WhiteBranchOffice/components/RightPanel/index.less b/src/pages/Container/WhiteBranchOffice/components/RightPanel/index.less index 310b626..d06ed5d 100644 --- a/src/pages/Container/WhiteBranchOffice/components/RightPanel/index.less +++ b/src/pages/Container/WhiteBranchOffice/components/RightPanel/index.less @@ -10,7 +10,7 @@ border-top: none; background-color: #E0EDFD; padding: 10px; - .table-style(100px, repeat(4, 1fr)); + .table-style(70px, repeat(4, 1fr)); .info { color: #3B445C; @@ -133,7 +133,7 @@ border-top: none; background-color: #E0EDFD; padding: 10px; - .table-style(100px, repeat(5, 1fr)); + .table-style(70px, repeat(5, 1fr)); .info { color: #3B445C; @@ -164,7 +164,7 @@ border-top: none; background-color: #E0EDFD; padding: 10px; - .table-style(120px, 2fr 1fr 1fr 1fr); + .table-style(70px, 2fr 1fr 1fr 1fr); .info { color: #3B445C; diff --git a/src/pages/Container/WhiteBranchOffice/index.js b/src/pages/Container/WhiteBranchOffice/index.js index 275ab92..22f444a 100644 --- a/src/pages/Container/WhiteBranchOffice/index.js +++ b/src/pages/Container/WhiteBranchOffice/index.js @@ -13,9 +13,12 @@ function WhiteBranchOffice() { return ( <div className="white_branch_office" style={{ backgroundImage: `url(${bg})` }}> - <LeftPanel /> - <CenterPanel /> - <RightPanel /> + <div className="header"></div> + <div className="white_branch_office_container"> + <LeftPanel /> + <CenterPanel /> + <RightPanel /> + </div> </div> ); } diff --git a/src/pages/Container/WhiteBranchOffice/index.less b/src/pages/Container/WhiteBranchOffice/index.less index e399151..f7dae24 100644 --- a/src/pages/Container/WhiteBranchOffice/index.less +++ b/src/pages/Container/WhiteBranchOffice/index.less @@ -1,13 +1,21 @@ -.white_branch_office{ +.white_branch_office { width: 100vw; height: 100vh; background-size: 100% 100%; background-repeat: no-repeat; - display: flex; - gap: 15px; - justify-content: space-between; - align-items: stretch; - padding: 0 9px; + + .header { + height: 75px; + } + + .white_branch_office_container { + margin-top: 30px; + display: flex; + gap: 15px; + justify-content: space-between; + align-items: stretch; + padding: 0 9px; + } } .table-style(@height, @grid-template-columns) {