From 96aab1bea1dac4c696b92d5448f5606fb8227d3e Mon Sep 17 00:00:00 2001 From: lb Date: Thu, 9 Nov 2023 16:26:00 +0800 Subject: [PATCH 1/4] add redux --- src/components/Common/KilnInfo/Kiln.jsx | 72 ++++++++++++++++--------- src/store/features/kilnSlice.js | 38 +++++++++++++ src/store/index.js | 4 +- 3 files changed, 87 insertions(+), 27 deletions(-) create mode 100644 src/store/features/kilnSlice.js diff --git a/src/components/Common/KilnInfo/Kiln.jsx b/src/components/Common/KilnInfo/Kiln.jsx index 0635538..3b195c6 100644 --- a/src/components/Common/KilnInfo/Kiln.jsx +++ b/src/components/Common/KilnInfo/Kiln.jsx @@ -1,31 +1,53 @@ -import React from "react"; -import { useContext } from "react"; -import Container from "../../Container"; -// import SocketContext from '../../../store/socket-data-provider'; - - import cls from "./kiln.module.scss"; - +import Container from "../../Container"; +import { useSelector } from "react-redux"; +import { stateNameMap } from "../../../store/features/kilnSlice"; +import { useEffect } from "react"; +import { useDispatch } from "react-redux"; export default function Kiln() { - // const ctx = useContext(SocketContext); - const ctx = null; + const kilnInfo = useSelector((state) => state.kiln); + const dispatch = useDispatch(); + console.log("state: ", kilnInfo, stateNameMap); - const infos = [ - { label: "窑炉压力", value: ctx?.runState?.kilnPressure || "0Pa" }, - { label: "循环水温度", value: ctx?.runState?.waterTemp || "0℃" }, - { label: "循环水流量", value: ctx?.runState?.waterFlow || "0㎡/h" }, - { label: "循环水压力", value: ctx?.runState?.waterPressure || "0Pa" }, - { - label: "助燃风压力", - value: ctx?.runState?.combustionAirPressure || "0℃", - }, - { label: "碹顶加权温度", value: ctx?.runState?.topTemp || "0℃" }, - { - label: "压缩气压力", - value: ctx?.runState?.compressedAirPressure || "0Pa", - }, - { label: "融化加权温度", value: ctx?.runState?.meltTemp || "0℃" }, - ]; + const infos = Object.keys(kilnInfo).map((key) => ({ + label: stateNameMap[key], + value: kilnInfo[key], + })); + + useEffect(() => { + setTimeout(() => { + dispatch({ + type: "kiln/setKilnInfo", + payload: { + kilnPressure: "100Pa", + waterTemp: "100℃", + waterFlow: "100m³/h", + waterPressure: "100Pa", + combustionAirPressure: "100Pa", + topTemp: "100℃", + compressedAirPressure: "100Pa", + meltTemp: "100℃", + }, + }); + }, 3000); + }, []); + + // const infos = [ + // { label: "窑炉压力", value: ctx?.runState?.kilnPressure || "0Pa" }, + // { label: "循环水温度", value: ctx?.runState?.waterTemp || "0℃" }, + // { label: "循环水流量", value: ctx?.runState?.waterFlow || "0㎡/h" }, + // { label: "循环水压力", value: ctx?.runState?.waterPressure || "0Pa" }, + // { + // label: "助燃风压力", + // value: ctx?.runState?.combustionAirPressure || "0℃", + // }, + // { label: "碹顶加权温度", value: ctx?.runState?.topTemp || "0℃" }, + // { + // label: "压缩气压力", + // value: ctx?.runState?.compressedAirPressure || "0Pa", + // }, + // { label: "融化加权温度", value: ctx?.runState?.meltTemp || "0℃" }, + // ]; return ( diff --git a/src/store/features/kilnSlice.js b/src/store/features/kilnSlice.js new file mode 100644 index 0000000..8f163ed --- /dev/null +++ b/src/store/features/kilnSlice.js @@ -0,0 +1,38 @@ +import { createSlice } from "@reduxjs/toolkit"; + +export const initialState = { + kilnPressure: "0Pa", + waterTemp: "0℃", + waterFlow: "0m³/h", + waterPressure: "0Pa", + combustionAirPressure: "0Pa", + topTemp: "0℃", + compressedAirPressure: "0Pa", + meltTemp: "0℃", +}; + +export const stateNameMap = { + kilnPressure: "窑炉压力", + waterTemp: "循环水温度", + waterFlow: "循环水流量", + waterPressure: "循环水压力", + combustionAirPressure: "助燃风压力", + topTemp: "碹顶加权温度", + compressedAirPressure: "压缩气压力", + meltTemp: "融化加权温度", +}; + +const kilnSlice = createSlice({ + name: "kiln", + initialState, + reducers: { + setKilnInfo: (state, action) => { + Object.keys(action.payload).forEach((key) => { + state[key] = action.payload[key]; + }); + }, + }, +}); + +export default kilnSlice.reducer; +export const { setKilnInfo } = kilnSlice.actions; diff --git a/src/store/index.js b/src/store/index.js index e2e04b0..a3be550 100644 --- a/src/store/index.js +++ b/src/store/index.js @@ -1,8 +1,8 @@ import { configureStore } from "@reduxjs/toolkit"; -// import counterReducer from '../features/kiln/KilnSlice' +import kilnReducer from "./features/kilnSlice"; export const store = configureStore({ reducer: { - // counter: counterReducer, + kiln: kilnReducer, }, }); From c16a52a20e82922549f416468019687f7974873b Mon Sep 17 00:00:00 2001 From: lb Date: Thu, 9 Nov 2023 16:30:27 +0800 Subject: [PATCH 2/4] update --- src/components/Common/KilnInfo/Kiln.jsx | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/src/components/Common/KilnInfo/Kiln.jsx b/src/components/Common/KilnInfo/Kiln.jsx index 3b195c6..d72b08d 100644 --- a/src/components/Common/KilnInfo/Kiln.jsx +++ b/src/components/Common/KilnInfo/Kiln.jsx @@ -4,6 +4,7 @@ import { useSelector } from "react-redux"; import { stateNameMap } from "../../../store/features/kilnSlice"; import { useEffect } from "react"; import { useDispatch } from "react-redux"; + export default function Kiln() { const kilnInfo = useSelector((state) => state.kiln); const dispatch = useDispatch(); @@ -15,21 +16,21 @@ export default function Kiln() { })); useEffect(() => { - setTimeout(() => { + setInterval(() => { dispatch({ type: "kiln/setKilnInfo", payload: { - kilnPressure: "100Pa", - waterTemp: "100℃", - waterFlow: "100m³/h", - waterPressure: "100Pa", - combustionAirPressure: "100Pa", - topTemp: "100℃", - compressedAirPressure: "100Pa", - meltTemp: "100℃", + kilnPressure: Math.ceil(Math.random() * 100) + "Pa", + waterTemp: Math.ceil(Math.random() * 100) + "℃", + waterFlow: Math.ceil(Math.random() * 100) + "m³/h", + waterPressure: Math.ceil(Math.random() * 100) + "Pa", + combustionAirPressure: Math.ceil(Math.random() * 100) + "Pa", + topTemp: Math.ceil(Math.random() * 100) + "℃", + compressedAirPressure: Math.ceil(Math.random() * 100) + "Pa", + meltTemp: Math.ceil(Math.random() * 100) + "℃", }, }); - }, 3000); + }, 30000); }, []); // const infos = [ From a18cb7a1c77f17ca529c59fa32f6cc3e27409a45 Mon Sep 17 00:00:00 2001 From: lb Date: Thu, 9 Nov 2023 17:01:25 +0800 Subject: [PATCH 3/4] update fire redux --- src/components/Common/KilnInfo/Kiln.jsx | 5 +- src/components/Common/TimeFireDir/index.jsx | 164 ++++++++++-------- .../Common/TimeFireDir/leftbox.module.scss | 9 +- src/hooks/useTimeCounter.js | 68 ++++++++ src/store/features/fireSlice.js | 28 +++ src/store/index.js | 2 + 6 files changed, 199 insertions(+), 77 deletions(-) create mode 100644 src/hooks/useTimeCounter.js create mode 100644 src/store/features/fireSlice.js diff --git a/src/components/Common/KilnInfo/Kiln.jsx b/src/components/Common/KilnInfo/Kiln.jsx index d72b08d..05c8a65 100644 --- a/src/components/Common/KilnInfo/Kiln.jsx +++ b/src/components/Common/KilnInfo/Kiln.jsx @@ -1,9 +1,8 @@ import cls from "./kiln.module.scss"; import Container from "../../Container"; -import { useSelector } from "react-redux"; -import { stateNameMap } from "../../../store/features/kilnSlice"; import { useEffect } from "react"; -import { useDispatch } from "react-redux"; +import { useSelector, useDispatch } from "react-redux"; +import { stateNameMap } from "../../../store/features/kilnSlice"; export default function Kiln() { const kilnInfo = useSelector((state) => state.kiln); diff --git a/src/components/Common/TimeFireDir/index.jsx b/src/components/Common/TimeFireDir/index.jsx index 8174493..765a0bf 100644 --- a/src/components/Common/TimeFireDir/index.jsx +++ b/src/components/Common/TimeFireDir/index.jsx @@ -1,99 +1,121 @@ +import cls from "./leftbox.module.scss"; import React, { useState, useContext, useEffect } from "react"; -// import SocketContext from '../../../store/socket-data-provider'; +import { useSelector, useDispatch } from "react-redux"; + import icon1 from "../../../assets/CenterChart2icon1.svg"; import icon2 from "../../../assets/CenterChart2icon2.svg"; import icon3 from "../../../assets/CenterChart2icon3.svg"; -import icon4 from "../../../assets/CenterChart2icon4.svg"; +// import icon4 from "../../../assets/CenterChart2icon4.svg"; -import cls from "./leftbox.module.scss"; +import useTimeCounter from "../../../hooks/useTimeCounter"; -const Chart2 = () => { - // const ctx = useContext(SocketContext); - const ctx = null; +const FireInfo = () => { + const dispatch = useDispatch(); + const fireInfo = useSelector((state) => state.fireInfo); + const time = fireInfo.lastFireChangeTime || "0分0秒"; + const [min, sec] = useTimeCounter(time); - let [time, setTime] = useState([0, 0]); + // useEffect(() => { + // const restTime = ctx?.runState?.lastFireChangeTime; + // if (restTime == null) return; + // let timer = null; + // if (/分/.test(restTime) && /秒/.test(restTime)) { + // let [min, sec] = restTime.replace(/分/, ":").replace(/秒/, "").split(":"); + // timer = setInterval(() => { + // if (Number(sec) === 0 && Number(min) === 0) { + // clearInterval(timer); + // return; + // } + // if (Number(sec) === 0) { + // sec = 59; + // min--; + // } else { + // sec--; + // } + // setTime([min, sec]); + // }, 1000); + // } else if (/分/.test(restTime)) { + // let sec, + // min = restTime.replace(/分/, ":"); + // sec = 0; + + // timer = setInterval(() => { + // if (Number(sec) === 0 && Number(min) === 0) { + // clearInterval(timer); + // return; + // } + // if (Number(sec) === 0) { + // sec = 59; + // min--; + // } else { + // sec--; + // } + // setTime([min, sec]); + // }, 1000); + // } else if (/秒/.test(restTime)) { + // let min, + // sec = restTime.replace(/秒/, ""); + // min = 0; + + // timer = setInterval(() => { + // if (Number(sec) === 0 && Number(min) === 0) { + // clearInterval(timer); + // return; + // } + // if (Number(sec) === 0) { + // sec = 59; + // min--; + // } else { + // sec--; + // } + // setTime([min, sec]); + // }, 1000); + // } + // return () => { + // clearInterval(timer); + // }; + // }, [ctx?.runState?.lastFireChangeTime]); useEffect(() => { - const restTime = ctx?.runState?.lastFireChangeTime; - if (restTime == null) return; - let timer = null; - if (/分/.test(restTime) && /秒/.test(restTime)) { - let [min, sec] = restTime.replace(/分/, ":").replace(/秒/, "").split(":"); - timer = setInterval(() => { - if (Number(sec) === 0 && Number(min) === 0) { - clearInterval(timer); - return; - } - if (Number(sec) === 0) { - sec = 59; - min--; - } else { - sec--; - } - setTime([min, sec]); - }, 1000); - } else if (/分/.test(restTime)) { - let sec, - min = restTime.replace(/分/, ":"); - sec = 0; - - timer = setInterval(() => { - if (Number(sec) === 0 && Number(min) === 0) { - clearInterval(timer); - return; - } - if (Number(sec) === 0) { - sec = 59; - min--; - } else { - sec--; - } - setTime([min, sec]); - }, 1000); - } else if (/秒/.test(restTime)) { - let min, - sec = restTime.replace(/秒/, ""); - min = 0; - - timer = setInterval(() => { - if (Number(sec) === 0 && Number(min) === 0) { - clearInterval(timer); - return; - } - if (Number(sec) === 0) { - sec = 59; - min--; - } else { - sec--; - } - setTime([min, sec]); - }, 1000); - } - return () => { - clearInterval(timer); - }; - }, [ctx?.runState?.lastFireChangeTime]); + setInterval(() => { + dispatch({ + type: "fireInfo/setFireInfo", + payload: { + fireChangeTime: `${Math.ceil(Math.random() * 10)}:${Math.ceil( + Math.random() * 10 + )}`, + fireDirection: Math.random * 10 < 5 ? "东火" : "西火", + lastFireChangeTime: `${Math.ceil(Math.random() * 60)}分${Math.ceil( + Math.random() * 50 + )}秒`, + }, + }); + }, 10000); + }, []); const data = [ { icon: icon1, label: "换火时间", - value: ctx?.runState?.fireChangeTime || "00:00", + // value: ctx?.runState?.fireChangeTime || "00:00", + value: fireInfo.fireChangeTime || "00:00", }, { icon: icon3, label: "剩余时间", - value: `${time[0]}分${time[1]}秒`, + // value: `${time[0]}分${time[1]}秒`, + value: `${min}分${sec}秒`, }, { icon: icon2, label: "当前火向", - value: ctx?.runState?.fireDirection || "东火", + // value: ctx?.runState?.fireDirection || "东火", + value: fireInfo.fireDirection || "东火", }, ]; return ( -
+
{data.map((item) => (
Error @@ -107,4 +129,4 @@ const Chart2 = () => { ); }; -export default Chart2; +export default FireInfo; diff --git a/src/components/Common/TimeFireDir/leftbox.module.scss b/src/components/Common/TimeFireDir/leftbox.module.scss index 23273fa..8e8ceae 100644 --- a/src/components/Common/TimeFireDir/leftbox.module.scss +++ b/src/components/Common/TimeFireDir/leftbox.module.scss @@ -1,8 +1,11 @@ .leftbox { + // height: 128px; + height: 110px; + .box { margin-right: 16px; width: 200px; - padding: 12px; + padding: 12px 8px; background: url(../../../assets/CenterChart2ItemBg.png); background-repeat: no-repeat; background-size: 100% 100%; @@ -22,8 +25,8 @@ .box__value { color: #fff; font-weight: 400; - font-size: 30px; - line-height: 56px; + font-size: 28px; + line-height: 54px; } } } diff --git a/src/hooks/useTimeCounter.js b/src/hooks/useTimeCounter.js new file mode 100644 index 0000000..0da16b7 --- /dev/null +++ b/src/hooks/useTimeCounter.js @@ -0,0 +1,68 @@ +import { useEffect, useState } from "react"; + +function useTimeCounter(time) { + // time: 8分12秒 这种 + const [timeTuple, setTimeTuple] = useState([0, 0]); + + useEffect(() => { + if (time == null) return; + let timer = null; + if (/分/.test(time) && /秒/.test(time)) { + let [min, sec] = time.replace(/分/, ":").replace(/秒/, "").split(":"); + timer = setInterval(() => { + if (Number(sec) === 0 && Number(min) === 0) { + clearInterval(timer); + return; + } + if (Number(sec) === 0) { + sec = 59; + min--; + } else { + sec--; + } + setTimeTuple([min, sec]); + }, 1000); + } else if (/分/.test(time)) { + let sec, + min = time.replace(/分/, ":"); + sec = 0; + timer = setInterval(() => { + if (Number(sec) === 0 && Number(min) === 0) { + clearInterval(timer); + return; + } + if (Number(sec) === 0) { + sec = 59; + min--; + } else { + sec--; + } + setTimeTuple([min, sec]); + }, 1000); + } else if (/秒/.test(time)) { + let min, + sec = time.replace(/秒/, ""); + min = 0; + timer = setInterval(() => { + if (Number(sec) === 0 && Number(min) === 0) { + clearInterval(timer); + return; + } + if (Number(sec) === 0) { + sec = 59; + min--; + } else { + sec--; + } + setTimeTuple([min, sec]); + }, 1000); + } + return () => { + clearInterval(timer); + }; + }, [time]); + + return timeTuple; +} + +export default useTimeCounter; diff --git a/src/store/features/fireSlice.js b/src/store/features/fireSlice.js new file mode 100644 index 0000000..66ef453 --- /dev/null +++ b/src/store/features/fireSlice.js @@ -0,0 +1,28 @@ +import { createSlice } from "@reduxjs/toolkit"; + +export const initialState = { + lastFireChangeTime: "10分20秒", + fireChangeTime: "10:23", + fireDirection: "东火", +}; + +// export const stateNameMap = { +// lastFireChangeTime: "10分20秒", +// fireChangeTime: "10:23", +// fireDirection: "东火", +// }; + +const fireSlice = createSlice({ + name: "fireInfo", + initialState, + reducers: { + setFireInfo: (state, action) => { + Object.keys(action.payload).forEach((key) => { + state[key] = action.payload[key]; + }); + }, + }, +}); + +export default fireSlice.reducer; +export const { setFireInfo } = fireSlice.actions; diff --git a/src/store/index.js b/src/store/index.js index a3be550..8988efa 100644 --- a/src/store/index.js +++ b/src/store/index.js @@ -1,8 +1,10 @@ import { configureStore } from "@reduxjs/toolkit"; import kilnReducer from "./features/kilnSlice"; +import fireReducer from "./features/fireSlice"; export const store = configureStore({ reducer: { kiln: kilnReducer, + fireInfo: fireReducer, }, }); From 3821121a6f13916725c7561c2bbd4f83da31eded Mon Sep 17 00:00:00 2001 From: lb Date: Fri, 10 Nov 2023 10:09:50 +0800 Subject: [PATCH 4/4] add more slices --- .../Common/FanRunFrequence/index.jsx | 163 +++++--- src/components/Common/GasFlow/index.jsx | 388 ++++++++++-------- src/components/Common/KilnInfo/Kiln.jsx | 3 +- .../Common/NatGasFlow/gridList/index.jsx | 89 ++-- src/hooks/useTimeCounter.js | 1 + src/store/features/fanFrequenceSlice.js | 74 ++++ src/store/features/gasSlice.js | 50 +++ src/store/index.js | 4 + 8 files changed, 487 insertions(+), 285 deletions(-) create mode 100644 src/store/features/fanFrequenceSlice.js create mode 100644 src/store/features/gasSlice.js diff --git a/src/components/Common/FanRunFrequence/index.jsx b/src/components/Common/FanRunFrequence/index.jsx index 8751cce..a2db858 100644 --- a/src/components/Common/FanRunFrequence/index.jsx +++ b/src/components/Common/FanRunFrequence/index.jsx @@ -2,17 +2,59 @@ import cls from "./index.module.css"; import ReactECharts from "echarts-for-react"; import * as echarts from "echarts"; -import { Switch } from "antd"; import GraphBase from "../../Common/GraphBase"; -import { useState, useContext } from "react"; -// import SocketContext from '../../../store/socket-data-provider'; +import { useEffect, useState } from "react"; +import { useSelector, useDispatch } from "react-redux"; + +function mockData(type = "runtime") { + const RUNTIME_DATA_LENGTH = 16; + const MAX_HISTORY_DATA_LENGTH = 10; + const WEEK = 7; + + switch (type) { + case "runtime": + return [ + ...Array.from( + { length: RUNTIME_DATA_LENGTH }, + () => Math.floor(Math.random() * 100) + "m³/h" + ), + ]; + case "history": + return { + ...Array.from( + { length: Math.floor(Math.random() * MAX_HISTORY_DATA_LENGTH) }, + (_, index) => ({ + ["FAIIA" + index]: [ + ...Array.from({ length: WEEK }, () => + Math.floor(Math.random() * 100) + ), + ], + }) + ).reduce((arr, curr) => ({ ...arr, ...curr }), {}), + }; + default: + break; + } +} function WindFrequence(props) { const [showChart, setShowChart] = useState(true); - // const { runState, hisState } = useContext(SocketContext); + const dispath = useDispatch(); + const runState = useSelector((state) => state.fanFrequence.runtime); + const hisState = useSelector((state) => state.fanFrequence.history); - const runState = null; - const hisState = null; + useEffect(() => { + setInterval(() => { + dispath({ + type: "fanFrequence/setRuntime", + payload: mockData("runtime"), + }); + dispath({ + type: "fanFrequence/setHistory", + payload: mockData("history"), + }); + }, 50000); + }, [dispath]); let dataList = []; let seriesData = []; @@ -29,20 +71,15 @@ function WindFrequence(props) { let options = null; if (showChart) { // keys() 结果不是按照顺序,需要 sort() - seriesData = hisState?.combustionAir - ? Object.keys(hisState.combustionAir) - .sort() - .map((key) => hisState.combustionAir[key]) - : Array(8) - .fill(1) - .map((_) => Array(7).fill(0)); + seriesData = + hisState != null + ? Object.keys(hisState) + .sort() + .map((key) => hisState[key]) + : Array(8) + .fill(1) + .map((_) => Array(7).fill(0)); - // debug - console.log( - "助燃风 chart series data", - hisState?.combustionAir, - seriesData - ); options = { color: colors, grid: { top: 32, right: 12, bottom: 20, left: 48 }, @@ -104,9 +141,10 @@ function WindFrequence(props) { symbol: "circle", areaStyle: { color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [ - { offset: 0, color: colors[i] + "40" }, - { offset: 0.5, color: colors[i] + "20" }, - { offset: 1, color: colors[i] + "00" }, + // i % 8 避免超过8个数据时无颜色的问题 + { offset: 0, color: colors[i % 8] + "40" }, + { offset: 0.5, color: colors[i % 8] + "20" }, + { offset: 1, color: colors[i % 8] + "00" }, ]), }, })), @@ -115,46 +153,47 @@ function WindFrequence(props) { }, }; } else { - dataList = runState?.combustionAirPressureArr - ? [ - { id: 1, name: "1#风机", value: "0m³/h" }, - { id: 2, name: "2#风机", value: "0m³/h" }, - { id: 3, name: "3#风机", value: "0m³/h" }, - { id: 4, name: "4#风机", value: "0m³/h" }, - { id: 5, name: "5#风机", value: "0m³/h" }, - { id: 6, name: "6#风机", value: "0m³/h" }, - { id: 7, name: "7#风机", value: "0m³/h" }, - { id: 8, name: "8#风机", value: "0m³/h" }, - { id: 9, name: "9#风机", value: "0m³/h" }, - { id: 10, name: "10#风机", value: "0m³/h" }, - { id: 11, name: "11#风机", value: "0m³/h" }, - { id: 12, name: "12#风机", value: "0m³/h" }, - { id: 13, name: "13#风机", value: "0m³/h" }, - { id: 14, name: "14#风机", value: "0m³/h" }, - { id: 15, name: "15#风机", value: "0m³/h" }, - { id: 16, name: "16#风机", value: "0m³/h" }, - ].map((item, index) => ({ - ...item, - value: runState.combustionAirPressureArr[index] ?? "/", - })) - : [ - { id: 1, name: "1#风机", value: "0m³/h" }, - { id: 2, name: "2#风机", value: "0m³/h" }, - { id: 3, name: "3#风机", value: "0m³/h" }, - { id: 4, name: "4#风机", value: "0m³/h" }, - { id: 5, name: "5#风机", value: "0m³/h" }, - { id: 6, name: "6#风机", value: "0m³/h" }, - { id: 7, name: "7#风机", value: "0m³/h" }, - { id: 8, name: "8#风机", value: "0m³/h" }, - { id: 9, name: "9#风机", value: "0m³/h" }, - { id: 10, name: "10#风机", value: "0m³/h" }, - { id: 11, name: "11#风机", value: "0m³/h" }, - { id: 12, name: "12#风机", value: "0m³/h" }, - { id: 13, name: "13#风机", value: "0m³/h" }, - { id: 14, name: "14#风机", value: "0m³/h" }, - { id: 15, name: "15#风机", value: "0m³/h" }, - { id: 16, name: "16#风机", value: "0m³/h" }, - ]; + dataList = + runState != null + ? [ + { id: 1, name: "1#风机", value: "0m³/h" }, + { id: 2, name: "2#风机", value: "0m³/h" }, + { id: 3, name: "3#风机", value: "0m³/h" }, + { id: 4, name: "4#风机", value: "0m³/h" }, + { id: 5, name: "5#风机", value: "0m³/h" }, + { id: 6, name: "6#风机", value: "0m³/h" }, + { id: 7, name: "7#风机", value: "0m³/h" }, + { id: 8, name: "8#风机", value: "0m³/h" }, + { id: 9, name: "9#风机", value: "0m³/h" }, + { id: 10, name: "10#风机", value: "0m³/h" }, + { id: 11, name: "11#风机", value: "0m³/h" }, + { id: 12, name: "12#风机", value: "0m³/h" }, + { id: 13, name: "13#风机", value: "0m³/h" }, + { id: 14, name: "14#风机", value: "0m³/h" }, + { id: 15, name: "15#风机", value: "0m³/h" }, + { id: 16, name: "16#风机", value: "0m³/h" }, + ].map((item, index) => ({ + ...item, + value: runState[index] ?? "/", + })) + : [ + { id: 1, name: "1#风机", value: "0m³/h" }, + { id: 2, name: "2#风机", value: "0m³/h" }, + { id: 3, name: "3#风机", value: "0m³/h" }, + { id: 4, name: "4#风机", value: "0m³/h" }, + { id: 5, name: "5#风机", value: "0m³/h" }, + { id: 6, name: "6#风机", value: "0m³/h" }, + { id: 7, name: "7#风机", value: "0m³/h" }, + { id: 8, name: "8#风机", value: "0m³/h" }, + { id: 9, name: "9#风机", value: "0m³/h" }, + { id: 10, name: "10#风机", value: "0m³/h" }, + { id: 11, name: "11#风机", value: "0m³/h" }, + { id: 12, name: "12#风机", value: "0m³/h" }, + { id: 13, name: "13#风机", value: "0m³/h" }, + { id: 14, name: "14#风机", value: "0m³/h" }, + { id: 15, name: "15#风机", value: "0m³/h" }, + { id: 16, name: "16#风机", value: "0m³/h" }, + ]; } function handleSwitchChange(val) { diff --git a/src/components/Common/GasFlow/index.jsx b/src/components/Common/GasFlow/index.jsx index c9124a1..9905e28 100644 --- a/src/components/Common/GasFlow/index.jsx +++ b/src/components/Common/GasFlow/index.jsx @@ -1,187 +1,223 @@ // 助燃风流量 -import cls from './index.module.css'; -import BottomBarItem from '../BottomItemBackground'; -import ReactECharts from 'echarts-for-react'; -import * as echarts from 'echarts'; -import { randomInt } from '../../../utils'; -import { Switch } from 'antd'; -import { useState, useContext } from 'react'; -// import SocketContext from '../../../store/socket-data-provider'; +import cls from "./index.module.css"; +import BottomBarItem from "../BottomItemBackground"; +import ReactECharts from "echarts-for-react"; +import * as echarts from "echarts"; +import { Switch } from "antd"; +import { useState, useEffect } from "react"; +import { useSelector, useDispatch } from "react-redux"; + +function mockData(type = "runtime") { + const RUNTIME_DATA_LENGTH = 8; + const MAX_HISTORY_DATA_LENGTH = 8; + const WEEK = 7; + + switch (type) { + case "runtime": + return [ + ...Array.from( + { length: RUNTIME_DATA_LENGTH }, + () => Math.floor(Math.random() * 100) + "m³/h" + ), + ]; + case "history": + return { + ...Array.from( + { length: Math.floor(Math.random() * MAX_HISTORY_DATA_LENGTH) }, + (_, index) => ({ + ["GAS_" + index]: [ + ...Array.from({ length: WEEK }, () => + Math.floor(Math.random() * 100) + ), + ], + }) + ).reduce((arr, curr) => ({ ...arr, ...curr }), {}), + }; + default: + break; + } +} function GasI(props) { - const [showChart, setShowChart] = useState(true); - // const { runState, hisState } = useContext(SocketContext); + const [showChart, setShowChart] = useState(true); + const dispath = useDispatch(); + const runState = useSelector((state) => state.wind.runtime); + const hisState = useSelector((state) => state.wind.history); - const runState = null; - const hisState = null; + useEffect(() => { + setInterval(() => { + dispath({ + type: "fanFrequence/setRuntime", + payload: mockData("runtime"), + }); + dispath({ + type: "fanFrequence/setHistory", + payload: mockData("history"), + }); + }, 60000); + }, [dispath]); - let dataList = []; - let seriesData = []; - const colors = [ - '#12FFF5', - '#2760FF', - '#FFD160', - '#E80091', - '#8064ff', - '#ff8a3b', - '#8cd26d', - '#2aa1ff', - ]; - let options = null; - if (showChart) { - // keys() 结果不是按照顺序,需要 sort() - seriesData = hisState?.combustionAir - ? Object.keys(hisState.combustionAir) - .sort() - .map((key) => hisState.combustionAir[key]) - : Array(8) - .fill(1) - .map((_) => Array(7).fill(0)); + let dataList = []; + let seriesData = []; + const colors = [ + "#12FFF5", + "#2760FF", + "#FFD160", + "#E80091", + "#8064ff", + "#ff8a3b", + "#8cd26d", + "#2aa1ff", + ]; + let options = null; + if (showChart) { + // keys() 结果不是按照顺序,需要 sort() + seriesData = + hisState != null + ? Object.keys(hisState) + .sort() + .map((key) => hisState[key]) + : Array(8) + .fill(1) + .map((_) => Array(7).fill(0)); - // debug - console.log( - '助燃风 chart series data', - hisState?.combustionAir, - seriesData, - ); - options = { - color: colors, - grid: { top: 32, right: 12, bottom: 20, left: 48 }, - xAxis: { - type: 'category', - data: Array(7) - .fill(1) - .map((_, index) => { - const today = new Date(); - const dtimestamp = today - index * 24 * 60 * 60 * 1000; - return `${new Date(dtimestamp).getMonth() + 1}.${new Date( - dtimestamp, - ).getDate()}`; - }) - .reverse(), - axisLabel: { - color: '#fff', - fontSize: 12, - }, - axisTick: { show: false }, - axisLine: { - lineStyle: { - width: 1, - color: '#213259', - }, - }, - }, - yAxis: { - name: '单位/m³', - nameTextStyle: { - color: '#fff', - fontSize: 10, - align: 'right', - }, - type: 'value', - axisLabel: { - color: '#fff', - fontSize: 12, - }, - axisLine: { - show: true, - lineStyle: { - color: '#213259', - }, - }, - splitLine: { - lineStyle: { - color: '#213259a0', - }, - }, - // interval: 10, - // min: 0, - // max: 100, - }, - series: seriesData.map((v, i) => ({ - name: i + 1 + '#助燃风', - data: v, - type: 'line', - symbol: 'circle', - areaStyle: { - color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [ - { offset: 0, color: colors[i] + '40' }, - { offset: 0.5, color: colors[i] + '20' }, - { offset: 1, color: colors[i] + '00' }, - ]), - }, - })), - tooltip: { - trigger: 'axis', - }, - }; - } else { - dataList = runState?.combustionAirPressureArr - ? [ - { id: 1, name: '1#助燃风', value: '0m³/h' }, - { id: 2, name: '2#助燃风', value: '0m³/h' }, - { id: 3, name: '3#助燃风', value: '0m³/h' }, - { id: 4, name: '4#助燃风', value: '0m³/h' }, - { id: 5, name: '5#助燃风', value: '0m³/h' }, - { id: 6, name: '6#助燃风', value: '0m³/h' }, - { id: 7, name: '7#助燃风', value: '0m³/h' }, - { id: 8, name: '8#助燃风', value: '0m³/h' }, - ].map((item, index) => ({ - ...item, - value: runState.combustionAirPressureArr[index] ?? '/', - })) - : [ - { id: 1, name: '1#助燃风', value: '0m³/h' }, - { id: 2, name: '2#助燃风', value: '0m³/h' }, - { id: 3, name: '3#助燃风', value: '0m³/h' }, - { id: 4, name: '4#助燃风', value: '0m³/h' }, - { id: 5, name: '5#助燃风', value: '0m³/h' }, - { id: 6, name: '6#助燃风', value: '0m³/h' }, - { id: 7, name: '7#助燃风', value: '0m³/h' }, - { id: 8, name: '8#助燃风', value: '0m³/h' }, - ]; - // debug - console.log('助燃风 实时 data', runState?.combustionAirPressureArr); - } + options = { + color: colors, + grid: { top: 32, right: 12, bottom: 20, left: 48 }, + xAxis: { + type: "category", + data: Array(7) + .fill(1) + .map((_, index) => { + const today = new Date(); + const dtimestamp = today - index * 24 * 60 * 60 * 1000; + return `${new Date(dtimestamp).getMonth() + 1}.${new Date( + dtimestamp + ).getDate()}`; + }) + .reverse(), + axisLabel: { + color: "#fff", + fontSize: 12, + }, + axisTick: { show: false }, + axisLine: { + lineStyle: { + width: 1, + color: "#213259", + }, + }, + }, + yAxis: { + name: "单位/m³", + nameTextStyle: { + color: "#fff", + fontSize: 10, + align: "right", + }, + type: "value", + axisLabel: { + color: "#fff", + fontSize: 12, + }, + axisLine: { + show: true, + lineStyle: { + color: "#213259", + }, + }, + splitLine: { + lineStyle: { + color: "#213259a0", + }, + }, + // interval: 10, + // min: 0, + // max: 100, + }, + series: seriesData.map((v, i) => ({ + name: i + 1 + "#助燃风", + data: v, + type: "line", + symbol: "circle", + areaStyle: { + color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [ + { offset: 0, color: colors[i % colors.length] + "40" }, + { offset: 0.5, color: colors[i % colors.length] + "20" }, + { offset: 1, color: colors[i % colors.length] + "00" }, + ]), + }, + })), + tooltip: { + trigger: "axis", + }, + }; + } else { + dataList = + runState != null + ? [ + { id: 1, name: "1#助燃风", value: "0m³/h" }, + { id: 2, name: "2#助燃风", value: "0m³/h" }, + { id: 3, name: "3#助燃风", value: "0m³/h" }, + { id: 4, name: "4#助燃风", value: "0m³/h" }, + { id: 5, name: "5#助燃风", value: "0m³/h" }, + { id: 6, name: "6#助燃风", value: "0m³/h" }, + { id: 7, name: "7#助燃风", value: "0m³/h" }, + { id: 8, name: "8#助燃风", value: "0m³/h" }, + ].map((item, index) => ({ + ...item, + value: runState[index] ?? "/", + })) + : [ + { id: 1, name: "1#助燃风", value: "0m³/h" }, + { id: 2, name: "2#助燃风", value: "0m³/h" }, + { id: 3, name: "3#助燃风", value: "0m³/h" }, + { id: 4, name: "4#助燃风", value: "0m³/h" }, + { id: 5, name: "5#助燃风", value: "0m³/h" }, + { id: 6, name: "6#助燃风", value: "0m³/h" }, + { id: 7, name: "7#助燃风", value: "0m³/h" }, + { id: 8, name: "8#助燃风", value: "0m³/h" }, + ]; + } - function handleSwitchChange(val) { - if (val) { - setShowChart(true); - } else { - setShowChart(false); - } - } - return ( - -
-
- - {showChart && 历史详情} - {!showChart && 实时流量} -
-
+ function handleSwitchChange(val) { + if (val) { + setShowChart(true); + } else { + setShowChart(false); + } + } + return ( + +
+
+ + {showChart && 历史详情} + {!showChart && 实时流量} +
+
-
- {showChart && ( - - )} - {!showChart && ( -
- {dataList.map((item) => ( -
- {item.name}: {item.value} -
- ))} -
- )} -
-
- ); +
+ {showChart && ( + + )} + {!showChart && ( +
+ {dataList.map((item) => ( +
+ {item.name}: {item.value} +
+ ))} +
+ )} +
+
+ ); } export default GasI; diff --git a/src/components/Common/KilnInfo/Kiln.jsx b/src/components/Common/KilnInfo/Kiln.jsx index 05c8a65..fdb94cc 100644 --- a/src/components/Common/KilnInfo/Kiln.jsx +++ b/src/components/Common/KilnInfo/Kiln.jsx @@ -7,7 +7,6 @@ import { stateNameMap } from "../../../store/features/kilnSlice"; export default function Kiln() { const kilnInfo = useSelector((state) => state.kiln); const dispatch = useDispatch(); - console.log("state: ", kilnInfo, stateNameMap); const infos = Object.keys(kilnInfo).map((key) => ({ label: stateNameMap[key], @@ -30,7 +29,7 @@ export default function Kiln() { }, }); }, 30000); - }, []); + }, [dispatch]); // const infos = [ // { label: "窑炉压力", value: ctx?.runState?.kilnPressure || "0Pa" }, diff --git a/src/components/Common/NatGasFlow/gridList/index.jsx b/src/components/Common/NatGasFlow/gridList/index.jsx index 90c9908..194c0da 100644 --- a/src/components/Common/NatGasFlow/gridList/index.jsx +++ b/src/components/Common/NatGasFlow/gridList/index.jsx @@ -1,55 +1,54 @@ -import cls from './index.module.css'; -import { useContext, useEffect, useState } from 'react'; -// import SocketContext from '../../../../store/socket-data-provider'; +import cls from "./index.module.css"; +import { useEffect, useState } from "react"; function getData(type) { - let data = []; - switch (type) { - case 'gas-i': - data = [ - { id: 1, name: '1#天然气I', value: '0m³/h' }, - { id: 2, name: '2#天然气I', value: '0m³/h' }, - { id: 3, name: '3#天然气I', value: '0m³/h' }, - { id: 4, name: '4#天然气I', value: '0m³/h' }, - { id: 5, name: '5#天然气I', value: '0m³/h' }, - { id: 6, name: '6#天然气I', value: '0m³/h' }, - { id: 7, name: '7#天然气I', value: '0m³/h' }, - { id: 8, name: '8#天然气I', value: '0m³/h' }, - ]; - break; - case 'gas-ii': - data = [ - { id: 11, name: '1#天然气II', value: '0m³/h' }, - { id: 12, name: '2#天然气II', value: '0m³/h' }, - { id: 13, name: '3#天然气II', value: '0m³/h' }, - { id: 14, name: '4#天然气II', value: '0m³/h' }, - // { id: 15, name: '5#天然气II', value: '0m³/h' }, - ]; - break; - } - return data; + let data = []; + switch (type) { + case "gas-i": + data = [ + { id: 1, name: "1#天然气I", value: "0m³/h" }, + { id: 2, name: "2#天然气I", value: "0m³/h" }, + { id: 3, name: "3#天然气I", value: "0m³/h" }, + { id: 4, name: "4#天然气I", value: "0m³/h" }, + { id: 5, name: "5#天然气I", value: "0m³/h" }, + { id: 6, name: "6#天然气I", value: "0m³/h" }, + { id: 7, name: "7#天然气I", value: "0m³/h" }, + { id: 8, name: "8#天然气I", value: "0m³/h" }, + ]; + break; + case "gas-ii": + data = [ + { id: 11, name: "1#天然气II", value: "0m³/h" }, + { id: 12, name: "2#天然气II", value: "0m³/h" }, + { id: 13, name: "3#天然气II", value: "0m³/h" }, + { id: 14, name: "4#天然气II", value: "0m³/h" }, + // { id: 15, name: '5#天然气II', value: '0m³/h' }, + ]; + break; + } + return data; } function GridList(props) { - // const { runState } = useContext(SocketContext); - const runState = null; - - const key = props.dataSource == 'gas-i' ? 'gasFlowArr' : 'furnaceGasFlowArr'; + // const { runState } = useContext(SocketContext); + const runState = null; - let dataList = getData(props.dataSource); - dataList = runState?.[key] - ? dataList.map((v, i) => ({ ...v, value: runState[key][i] ?? '/' })) - : dataList; + const key = props.dataSource == "gas-i" ? "gasFlowArr" : "furnaceGasFlowArr"; - return ( -
- {dataList.map((item) => ( -
- {item.name}: {item.value} -
- ))} -
- ); + let dataList = getData(props.dataSource); + dataList = runState?.[key] + ? dataList.map((v, i) => ({ ...v, value: runState[key][i] ?? "/" })) + : dataList; + + return ( +
+ {dataList.map((item) => ( +
+ {item.name}: {item.value} +
+ ))} +
+ ); } export default GridList; diff --git a/src/hooks/useTimeCounter.js b/src/hooks/useTimeCounter.js index 0da16b7..55274f4 100644 --- a/src/hooks/useTimeCounter.js +++ b/src/hooks/useTimeCounter.js @@ -1,6 +1,7 @@ import { useEffect, useState } from "react"; function useTimeCounter(time) { + console.log('time counter executed...') // time: 8分12秒 这种 const [timeTuple, setTimeTuple] = useState([0, 0]); diff --git a/src/store/features/fanFrequenceSlice.js b/src/store/features/fanFrequenceSlice.js new file mode 100644 index 0000000..0a3e8c6 --- /dev/null +++ b/src/store/features/fanFrequenceSlice.js @@ -0,0 +1,74 @@ +// 风机运行频率 +import { createSlice } from "@reduxjs/toolkit"; + +/** + * 由于接口并没有经过合理的评审,所以这里的数据结构是不确定的,需要根据实际情况进行调整 + */ + +export const initialState = { + history: { + // 历史数据 + FLIIA1: [ + // 帮我生成7个随机整数 + ...Array.from({ length: 7 }, () => Math.floor(Math.random() * 100)), + ], + // 帮我重复上面的模式十次 + FLIIA2: [ + ...Array.from({ length: 7 }, () => Math.floor(Math.random() * 100)), + ], + FLIIA3: [ + ...Array.from({ length: 7 }, () => Math.floor(Math.random() * 100)), + ], + FLIIA4: [ + ...Array.from({ length: 7 }, () => Math.floor(Math.random() * 100)), + ], + FLIIA5: [ + ...Array.from({ length: 7 }, () => Math.floor(Math.random() * 100)), + ], + FLIIA6: [ + ...Array.from({ length: 7 }, () => Math.floor(Math.random() * 100)), + ], + FLIIA7: [ + ...Array.from({ length: 7 }, () => Math.floor(Math.random() * 100)), + ], + FLIIA8: [ + ...Array.from({ length: 7 }, () => Math.floor(Math.random() * 100)), + ], + FLIIB1: [ + ...Array.from({ length: 7 }, () => Math.floor(Math.random() * 100)), + ], + FLIIB2: [ + ...Array.from({ length: 7 }, () => Math.floor(Math.random() * 100)), + ], + }, + + runtime: [ + // 实时数据 + ...Array.from( + { length: 16 }, + () => Math.floor(Math.random() * 100) + "m³/h" + ), + ], +}; + +// export const stateNameMap = { +// lastFireChangeTime: "10分20秒", +// fireChangeTime: "10:23", +// fireDirection: "东火", +// }; + +const fanFrequenceSlice = createSlice({ + name: "fanFrequence", + initialState, + reducers: { + setHistory: (state, action) => { + state.history = action.payload; + }, + setRuntime: (state, action) => { + state.runtime = action.payload; + }, + }, +}); + +export default fanFrequenceSlice.reducer; +export const { setHistory, setRuntime } = fanFrequenceSlice.actions; diff --git a/src/store/features/gasSlice.js b/src/store/features/gasSlice.js new file mode 100644 index 0000000..c1533af --- /dev/null +++ b/src/store/features/gasSlice.js @@ -0,0 +1,50 @@ +// 风机运行频率 +import { createSlice } from "@reduxjs/toolkit"; + +/** + * 由于接口并没有经过合理的评审,所以这里的数据结构是不确定的,需要根据实际情况进行调整 + */ + +export const initialState = { + history: { + // 历史数据 + GAS1: [...Array.from({ length: 7 }, () => Math.floor(Math.random() * 100))], + GAS2: [...Array.from({ length: 7 }, () => Math.floor(Math.random() * 100))], + GAS3: [...Array.from({ length: 7 }, () => Math.floor(Math.random() * 100))], + GAS4: [...Array.from({ length: 7 }, () => Math.floor(Math.random() * 100))], + GAS5: [...Array.from({ length: 7 }, () => Math.floor(Math.random() * 100))], + GAS6: [...Array.from({ length: 7 }, () => Math.floor(Math.random() * 100))], + GAS7: [...Array.from({ length: 7 }, () => Math.floor(Math.random() * 100))], + GAS8: [...Array.from({ length: 7 }, () => Math.floor(Math.random() * 100))], + }, + + runtime: [ + // 实时数据 + ...Array.from( + { length: 8 }, + () => Math.floor(Math.random() * 100) + "m³/h" + ), + ], +}; + +// export const stateNameMap = { +// lastFireChangeTime: "10分20秒", +// fireChangeTime: "10:23", +// fireDirection: "东火", +// }; + +const gasSlice = createSlice({ + name: "wind", + initialState, + reducers: { + setHistory: (state, action) => { + state.history = action.payload; + }, + setRuntime: (state, action) => { + state.runtime = action.payload; + }, + }, +}); + +export default gasSlice.reducer; +export const { setHistory, setRuntime } = gasSlice.actions; diff --git a/src/store/index.js b/src/store/index.js index 8988efa..3b9edc0 100644 --- a/src/store/index.js +++ b/src/store/index.js @@ -1,10 +1,14 @@ import { configureStore } from "@reduxjs/toolkit"; import kilnReducer from "./features/kilnSlice"; import fireReducer from "./features/fireSlice"; +import fanFrequenceReducer from "./features/fanFrequenceSlice"; +import gasReducer from "./features/gasSlice"; export const store = configureStore({ reducer: { kiln: kilnReducer, fireInfo: fireReducer, + fanFrequence: fanFrequenceReducer, + wind: gasReducer, }, });