Compare commits
13 Commits
master
...
311cdfc5f7
| Author | SHA1 | Date | |
|---|---|---|---|
| 311cdfc5f7 | |||
|
|
bc8b68e449 | ||
|
|
024f4bcf14 | ||
|
|
361aedd4ad | ||
|
|
60c6fdda79 | ||
|
|
15708c0eef | ||
|
|
2996c061dc | ||
|
|
9894aeca50 | ||
|
|
9f7652d9f3 | ||
|
|
e854b966dc | ||
|
|
dff017a5a2 | ||
|
|
e796a07e66 | ||
|
|
43635ff398 |
2
.gitignore
vendored
@@ -1,7 +1,7 @@
|
|||||||
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
|
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
|
||||||
|
|
||||||
# dependencies
|
# dependencies
|
||||||
/node_modules
|
**/node_modules
|
||||||
/.pnp
|
/.pnp
|
||||||
.pnp.js
|
.pnp.js
|
||||||
|
|
||||||
|
|||||||
@@ -70,6 +70,7 @@
|
|||||||
"scripts": {
|
"scripts": {
|
||||||
"start": "node scripts/start.js",
|
"start": "node scripts/start.js",
|
||||||
"build": "node scripts/build.js",
|
"build": "node scripts/build.js",
|
||||||
|
"server": "node websocket/server.js",
|
||||||
"test": "node scripts/test.js"
|
"test": "node scripts/test.js"
|
||||||
},
|
},
|
||||||
"eslintConfig": {
|
"eslintConfig": {
|
||||||
|
|||||||
@@ -29,6 +29,8 @@
|
|||||||
<body>
|
<body>
|
||||||
<noscript>You need to enable JavaScript to run this app.</noscript>
|
<noscript>You need to enable JavaScript to run this app.</noscript>
|
||||||
<div id="root"></div>
|
<div id="root"></div>
|
||||||
|
<!-- <div id="alarm-list-container"></div> -->
|
||||||
|
|
||||||
<!--
|
<!--
|
||||||
This HTML file is a template.
|
This HTML file is a template.
|
||||||
If you open it directly in the browser, you will see an empty page.
|
If you open it directly in the browser, you will see an empty page.
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ import { Switch } from "antd";
|
|||||||
import { createPortal } from "react-dom";
|
import { createPortal } from "react-dom";
|
||||||
|
|
||||||
const Menus = ["窑炉总览", "窑炉内部", "退火监测", "质检统计", "能耗分析"];
|
const Menus = ["窑炉总览", "窑炉内部", "退火监测", "质检统计", "能耗分析"];
|
||||||
|
const LUNBO_INTERVAL = 60 * 1000;
|
||||||
function App() {
|
function App() {
|
||||||
const { styles, value, setValue } = useSlider(100);
|
const { styles, value, setValue } = useSlider(100);
|
||||||
const [navActive, setNavActive] = useState("窑炉总览");
|
const [navActive, setNavActive] = useState("窑炉总览");
|
||||||
@@ -22,7 +22,7 @@ function App() {
|
|||||||
if (lunbo) {
|
if (lunbo) {
|
||||||
timer = setInterval(() => {
|
timer = setInterval(() => {
|
||||||
handleMenuChange(Menus[(Menus.indexOf(navActive) + 1) % Menus.length]);
|
handleMenuChange(Menus[(Menus.indexOf(navActive) + 1) % Menus.length]);
|
||||||
}, 5000);
|
}, LUNBO_INTERVAL);
|
||||||
}
|
}
|
||||||
return () => {
|
return () => {
|
||||||
clearInterval(timer);
|
clearInterval(timer);
|
||||||
|
|||||||
BIN
src/assets/Icon/dontknowwhatitis.png
Normal file
|
After Width: | Height: | Size: 5.9 KiB |
BIN
src/assets/Icon/lightnen.png
Normal file
|
After Width: | Height: | Size: 7.7 KiB |
BIN
src/assets/Icon/oilstation.png
Normal file
|
After Width: | Height: | Size: 5.3 KiB |
BIN
src/assets/warn-bg.png
Normal file
|
After Width: | Height: | Size: 2.0 KiB |
BIN
src/assets/warn-icon.png
Normal file
|
After Width: | Height: | Size: 2.2 KiB |
@@ -109,6 +109,7 @@ function WindFrequence(props) {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
} else {
|
} else {
|
||||||
|
console.log('runstate changeD!......')
|
||||||
dataList =
|
dataList =
|
||||||
runState != null
|
runState != null
|
||||||
? Object.keys(runState).map((fan) => ({
|
? Object.keys(runState).map((fan) => ({
|
||||||
|
|||||||
@@ -57,7 +57,7 @@ function WindFrequence(props) {
|
|||||||
currentTempList[1 + lines.indexOf(dataSource) + "#"]) ||
|
currentTempList[1 + lines.indexOf(dataSource) + "#"]) ||
|
||||||
[]
|
[]
|
||||||
);
|
);
|
||||||
}, [dataSource]);
|
}, [dataSource, currentTempList]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<GraphBase
|
<GraphBase
|
||||||
|
|||||||
@@ -35,10 +35,10 @@ const EnergyCostRealtime = () => {
|
|||||||
paddingRight: "6px",
|
paddingRight: "6px",
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
余热发电(实时)
|
余热发电(昨日)
|
||||||
</i>
|
</i>
|
||||||
<span style={{ fontSize: "17px", color: "#3ce8ff" }}>
|
<span style={{ fontSize: "17px", color: "#3ce8ff" }}>
|
||||||
{(+energyInfo?.elecQty2)?.toFixed(2) || 0}kWh
|
{(+energyInfo?.elecQty1)?.toFixed(2) || 0}kWh
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -66,7 +66,7 @@ const EnergyCostRealtime = () => {
|
|||||||
paddingRight: "6px",
|
paddingRight: "6px",
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
水耗量
|
水耗量(昨日)
|
||||||
</i>
|
</i>
|
||||||
<span style={{ fontSize: "17px", color: "#3ce8ff" }}>
|
<span style={{ fontSize: "17px", color: "#3ce8ff" }}>
|
||||||
{(+energyInfo?.waterQty)?.toFixed(2) || 0}Km³
|
{(+energyInfo?.waterQty)?.toFixed(2) || 0}Km³
|
||||||
@@ -80,7 +80,7 @@ const EnergyCostRealtime = () => {
|
|||||||
paddingRight: "6px",
|
paddingRight: "6px",
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
天然气I
|
天然气I(累计)
|
||||||
</i>
|
</i>
|
||||||
<span style={{ fontSize: "17px", color: "#3ce8ff" }}>
|
<span style={{ fontSize: "17px", color: "#3ce8ff" }}>
|
||||||
{energyInfo?.ngQty1 || "0Nm³"}
|
{energyInfo?.ngQty1 || "0Nm³"}
|
||||||
@@ -94,7 +94,7 @@ const EnergyCostRealtime = () => {
|
|||||||
paddingRight: "6px",
|
paddingRight: "6px",
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
电耗量
|
电耗量(昨日)
|
||||||
</i>
|
</i>
|
||||||
<span style={{ fontSize: "17px", color: "#3ce8ff" }}>
|
<span style={{ fontSize: "17px", color: "#3ce8ff" }}>
|
||||||
{(+energyInfo?.elecQty2)?.toFixed(2) || 0}kWh
|
{(+energyInfo?.elecQty2)?.toFixed(2) || 0}kWh
|
||||||
@@ -108,7 +108,7 @@ const EnergyCostRealtime = () => {
|
|||||||
paddingRight: "6px",
|
paddingRight: "6px",
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
天然气II
|
天然气II(累计)
|
||||||
</i>
|
</i>
|
||||||
<span style={{ fontSize: "17px", color: "#3ce8ff" }}>
|
<span style={{ fontSize: "17px", color: "#3ce8ff" }}>
|
||||||
{energyInfo?.ngQty2 || "0Nm³"}
|
{energyInfo?.ngQty2 || "0Nm³"}
|
||||||
|
|||||||
@@ -44,6 +44,7 @@ function GraphBase(props) {
|
|||||||
selectWidth,
|
selectWidth,
|
||||||
legend,
|
legend,
|
||||||
} = props;
|
} = props;
|
||||||
|
const descSmall = props.descSmall || false;
|
||||||
const iconSrc = useIcon(icon);
|
const iconSrc = useIcon(icon);
|
||||||
const colors = useMemo(() => ["#ffd160", "#2760ff", "#15e8f5"], []);
|
const colors = useMemo(() => ["#ffd160", "#2760ff", "#15e8f5"], []);
|
||||||
const [showChart, setShowChart] = useState(true);
|
const [showChart, setShowChart] = useState(true);
|
||||||
@@ -72,9 +73,9 @@ function GraphBase(props) {
|
|||||||
<span
|
<span
|
||||||
style={{
|
style={{
|
||||||
color: "#fff",
|
color: "#fff",
|
||||||
fontSize: "14px",
|
fontSize: "calc(14px * var(--scale))",
|
||||||
lineHeight: 1,
|
lineHeight: 1,
|
||||||
paddingLeft: "12px",
|
paddingLeft: "calc(12px * var(--scale))",
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
- 无 -
|
- 无 -
|
||||||
@@ -105,7 +106,7 @@ function GraphBase(props) {
|
|||||||
<div className={cls.graphBaseTitle}>
|
<div className={cls.graphBaseTitle}>
|
||||||
<img src={iconSrc} alt="#" />
|
<img src={iconSrc} alt="#" />
|
||||||
<h2>{title}</h2>
|
<h2>{title}</h2>
|
||||||
{desc && <div className={cls.graphBaseDesc}>{desc}</div>}
|
{desc && <div className={`${cls.graphBaseDesc} ${descSmall ? cls.graphBaseDescSmall : ''}`}>{desc}</div>}
|
||||||
</div>
|
</div>
|
||||||
<div className={cls.graphBaseContent}>
|
<div className={cls.graphBaseContent}>
|
||||||
{switchOptions && (
|
{switchOptions && (
|
||||||
|
|||||||
@@ -93,6 +93,11 @@
|
|||||||
color: #76fff9;
|
color: #76fff9;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.graphBaseDescSmall {
|
||||||
|
font-size: 16px;
|
||||||
|
color: #76fff9;
|
||||||
|
}
|
||||||
|
|
||||||
.graphBaseSwitch {
|
.graphBaseSwitch {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 30px;
|
top: 30px;
|
||||||
|
|||||||
@@ -9,6 +9,7 @@
|
|||||||
|
|
||||||
.xc-date-selector-menu .ant-select-item-option-content {
|
.xc-date-selector-menu .ant-select-item-option-content {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
|
font-size: calc(14px * var(--scale));
|
||||||
}
|
}
|
||||||
|
|
||||||
.xc-date-selector-menu .ant-select-item-option-selected {
|
.xc-date-selector-menu .ant-select-item-option-selected {
|
||||||
@@ -20,10 +21,16 @@
|
|||||||
background-color: #02457E !important;
|
background-color: #02457E !important;
|
||||||
color: #fff !important;
|
color: #fff !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.xc-date-selector-menu .ant-select-item-option {
|
||||||
|
/* padding: 5px 8px; */
|
||||||
|
padding: .3em .35em;
|
||||||
|
min-height: unset;
|
||||||
|
}
|
||||||
/*
|
/*
|
||||||
.ant-select-selector::after {
|
.ant-select-selector::after {
|
||||||
content: '\25BC' !important;
|
content: '\25BC' !important;
|
||||||
visibility: visible !important;
|
visibility: visible !important; L
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 2px;
|
top: 2px;
|
||||||
right: 22px;
|
right: 22px;
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
import * as echarts from "echarts";
|
import * as echarts from "echarts";
|
||||||
import { randomInt } from "../../../../utils";
|
|
||||||
|
|
||||||
export default function getOptions(seriesData, name) {
|
export default function getOptions(seriesData, name) {
|
||||||
const colors = [
|
const colors = [
|
||||||
|
|||||||
@@ -33,9 +33,9 @@ const SmokeTrendChart = (props) => {
|
|||||||
switch (period) {
|
switch (period) {
|
||||||
case "day":
|
case "day":
|
||||||
setDesc(
|
setDesc(
|
||||||
dayjs().subtract(1, "day").format("YYYY.MM.DD") +
|
dayjs().format("YYYY.MM.DD") +
|
||||||
" 7点 - " +
|
" 7点 - " +
|
||||||
dayjs().format("YYYY.MM.DD") +
|
dayjs().add(1, "day").format("YYYY.MM.DD") +
|
||||||
" 7点"
|
" 7点"
|
||||||
);
|
);
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -33,10 +33,9 @@ function FaultTotal(props) {
|
|||||||
|
|
||||||
// time hint
|
// time hint
|
||||||
let timeDesc = "";
|
let timeDesc = "";
|
||||||
const now = new Date();
|
|
||||||
switch (currentSelect) {
|
switch (currentSelect) {
|
||||||
case "日":
|
case "日":
|
||||||
timeDesc = dayjs().subtract(1, 'day').format('YYYY.MM.DD') + " 7点 - " + dayjs().format('YYYY.MM.DD') + " 7点";
|
timeDesc = dayjs().format('YYYY.MM.DD') + " 7点 - " + dayjs().add(1, 'day').format('YYYY.MM.DD') + " 7点";
|
||||||
break;
|
break;
|
||||||
case "周":
|
case "周":
|
||||||
timeDesc = dayjs().subtract(7, 'day').format('YYYY.MM.DD') + " - " + dayjs().subtract(1, 'day').format('YYYY.MM.DD') ;
|
timeDesc = dayjs().subtract(7, 'day').format('YYYY.MM.DD') + " - " + dayjs().subtract(1, 'day').format('YYYY.MM.DD') ;
|
||||||
@@ -52,7 +51,6 @@ function FaultTotal(props) {
|
|||||||
<GraphBase
|
<GraphBase
|
||||||
icon="chart"
|
icon="chart"
|
||||||
title="产线缺陷统计"
|
title="产线缺陷统计"
|
||||||
dateOptions={["日", "周", "月", "年"]}
|
|
||||||
defaultSelect={currentSelect}
|
defaultSelect={currentSelect}
|
||||||
onDateChange={handleDateChange}
|
onDateChange={handleDateChange}
|
||||||
size={bgSize}
|
size={bgSize}
|
||||||
|
|||||||
@@ -3,8 +3,8 @@ import GraphBase from "../GraphBase";
|
|||||||
import ReactECharts from "echarts-for-react";
|
import ReactECharts from "echarts-for-react";
|
||||||
import { useSelector } from "react-redux";
|
import { useSelector } from "react-redux";
|
||||||
import { useEffect, useState } from "react";
|
import { useEffect, useState } from "react";
|
||||||
import { randomInt } from "../../../utils";
|
|
||||||
import * as echarts from "echarts";
|
import * as echarts from "echarts";
|
||||||
|
import dayjs from "dayjs";
|
||||||
|
|
||||||
function FaultType(props) {
|
function FaultType(props) {
|
||||||
const [init, setInit] = useState(true);
|
const [init, setInit] = useState(true);
|
||||||
@@ -17,6 +17,11 @@ function FaultType(props) {
|
|||||||
: [];
|
: [];
|
||||||
const lines = currentStatistic.map((item) => item.name);
|
const lines = currentStatistic.map((item) => item.name);
|
||||||
const CHART_TYPE = "line"; // "pie" | "line";
|
const CHART_TYPE = "line"; // "pie" | "line";
|
||||||
|
const timestr =
|
||||||
|
dayjs().format("YYYY.MM.DD") +
|
||||||
|
" 7点 - " +
|
||||||
|
dayjs().add(1, "d").format("YYYY.MM.DD") +
|
||||||
|
" 7点";
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (init == false) return;
|
if (init == false) return;
|
||||||
@@ -47,6 +52,8 @@ function FaultType(props) {
|
|||||||
<GraphBase
|
<GraphBase
|
||||||
icon="default"
|
icon="default"
|
||||||
title="产线当日缺陷分类"
|
title="产线当日缺陷分类"
|
||||||
|
desc={timestr}
|
||||||
|
descSmall={true}
|
||||||
dateOptions={[...lines]}
|
dateOptions={[...lines]}
|
||||||
defaultSelect={currentLine}
|
defaultSelect={currentLine}
|
||||||
onDateChange={handleLineChange}
|
onDateChange={handleLineChange}
|
||||||
@@ -146,7 +153,7 @@ function getOptions(data, chart_type) {
|
|||||||
axisPointer: {
|
axisPointer: {
|
||||||
type: "shadow",
|
type: "shadow",
|
||||||
},
|
},
|
||||||
symbol: 'rect',
|
symbol: "rect",
|
||||||
className: "xc-chart-tooltip",
|
className: "xc-chart-tooltip",
|
||||||
// backgroundColor: ''
|
// backgroundColor: ''
|
||||||
},
|
},
|
||||||
@@ -210,7 +217,9 @@ function getOptions(data, chart_type) {
|
|||||||
color: "#fffc",
|
color: "#fffc",
|
||||||
},
|
},
|
||||||
data: (dataList || []).map((item) =>
|
data: (dataList || []).map((item) =>
|
||||||
item.value == null || isNaN(+item.value) ? null : (+item.value).toFixed(0)
|
item.value == null || isNaN(+item.value)
|
||||||
|
? null
|
||||||
|
: (+item.value).toFixed(0)
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
|||||||
@@ -29,9 +29,9 @@ const GoodRateChart = (props) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const [timestr, setTimestr] = useState(
|
const [timestr, setTimestr] = useState(
|
||||||
dayjs().subtract(1, "day").format("YYYY.MM.DD") +
|
dayjs().format("YYYY.MM.DD") +
|
||||||
" 7点 - " +
|
" 7点 - " +
|
||||||
dayjs().format("YYYY.MM.DD") +
|
dayjs().add(1, "day").format("YYYY.MM.DD") +
|
||||||
" 7点"
|
" 7点"
|
||||||
);
|
);
|
||||||
function handleDateChange(value) {
|
function handleDateChange(value) {
|
||||||
@@ -40,9 +40,9 @@ const GoodRateChart = (props) => {
|
|||||||
switch (value) {
|
switch (value) {
|
||||||
case "日":
|
case "日":
|
||||||
setTimestr(
|
setTimestr(
|
||||||
dayjs().subtract(1, "day").format("YYYY.MM.DD") +
|
dayjs().format("YYYY.MM.DD") +
|
||||||
" 7点 - " +
|
" 7点 - " +
|
||||||
dayjs().format("YYYY.MM.DD") +
|
dayjs().add(1, "day").format("YYYY.MM.DD") +
|
||||||
" 7点"
|
" 7点"
|
||||||
);
|
);
|
||||||
break;
|
break;
|
||||||
|
|||||||
16
src/components/Common/VideoMonitor/index.jsx
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
// import cls from "./index.module.css";
|
||||||
|
import "./video-monitor.css";
|
||||||
|
|
||||||
|
function VideoMonitor(props) {
|
||||||
|
return (
|
||||||
|
<div className="video-monitor">
|
||||||
|
<h2>泡界线监控</h2>
|
||||||
|
<div className="video-container">
|
||||||
|
<div></div>
|
||||||
|
<div></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default VideoMonitor;
|
||||||
30
src/components/Common/VideoMonitor/video-monitor.css
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
.video-monitor {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
margin-left: 80px;
|
||||||
|
height: 200px;
|
||||||
|
width: 500px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.video-monitor > h2 {
|
||||||
|
margin: 0;
|
||||||
|
padding: 10px 0;
|
||||||
|
background: #16253c;
|
||||||
|
color: #fff;
|
||||||
|
font-weight: 400;
|
||||||
|
letter-spacing: 2px;
|
||||||
|
font-size: 18px;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.video-monitor > .video-container {
|
||||||
|
display: flex;
|
||||||
|
gap: 8px;
|
||||||
|
flex: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.video-container > div {
|
||||||
|
flex: 1;
|
||||||
|
height: 100%;
|
||||||
|
background: #ccc1;
|
||||||
|
}
|
||||||
BIN
src/components/Common/WarnAlert/3.png
Normal file
|
After Width: | Height: | Size: 1.3 KiB |
130
src/components/Common/WarnAlert/ListContainer.jsx
Normal file
@@ -0,0 +1,130 @@
|
|||||||
|
import WarnAlert from ".";
|
||||||
|
import { useSelector } from "react-redux";
|
||||||
|
import posMap from "./position.json";
|
||||||
|
|
||||||
|
const total = `AN_1_1,助燃风故障报警
|
||||||
|
AN_1_2,压延机冷却风故障报警
|
||||||
|
AN_1_3,L吊墙冷却风机故障报警
|
||||||
|
AN_1_4,熔化带及部分澄清部冷却风机故障报警
|
||||||
|
AN_2_1,澄清带池壁冷却风机故障报警
|
||||||
|
AN_2_2,钢碴碴冷却风机故障报警
|
||||||
|
AN_2_3,支通路拐角冷却风机报警
|
||||||
|
AN_2_4,吊墙吊钩砖结构温升报警
|
||||||
|
AN_3_1,深层水包冷却水温升报警
|
||||||
|
AN_3_2,深层水包冷却水断水报警
|
||||||
|
AN_3_3,卡脖吊平冷却水断水报警
|
||||||
|
AN_3_4,卡脖吊平喧冷却水温升报警
|
||||||
|
AN_4_1,液面计冷却水断水报警
|
||||||
|
AN_4_2,液面计冷却水温升报警
|
||||||
|
AN_4_3,循环水入口压力低报警
|
||||||
|
AN_4_4,天然气压力高低报警
|
||||||
|
AN_5_1,助燃风风压低报警
|
||||||
|
AN_5_2,净化压缩气压力低报警
|
||||||
|
AN_5_3,普通压缩空气压力高低报警
|
||||||
|
AN_5_4,焦炉煤气气压力高低报警
|
||||||
|
AN_6_1,换向过程故障报警
|
||||||
|
AN_6_2,空交机换向不到位报警
|
||||||
|
AN_6_3,投料机故障报警
|
||||||
|
AN_6_4,备用
|
||||||
|
AN_7_1,1#压延机冷却水断水报警
|
||||||
|
AN_7_2,1#压延机冷却水温升报警
|
||||||
|
AN_7_3,1#过渡辊台冷却水断水报警
|
||||||
|
AN_7_4,1过渡辊台冷却水温升报警
|
||||||
|
AN_8_1,1#线唇砖冷却水断水报警
|
||||||
|
AN_8_2,1#线唇砖冷却水温升报警
|
||||||
|
AN_8_3,1#退火窑A区风机报警
|
||||||
|
AN_8_4,1#退火窑B区风机报警
|
||||||
|
AN_9_1,1#退火窑c区风机报警
|
||||||
|
AN_9_2,1#退火窑Ret1区风机报警
|
||||||
|
AN_9_3,1#退火窑Ret2区风机报警
|
||||||
|
AN_9_4,1#退火窑F1区风机报警
|
||||||
|
AN_10_1,1#退火窑F2区风机报警
|
||||||
|
AN_10_2,1#主传动报警
|
||||||
|
AN_10_3,1#压延机报警
|
||||||
|
AN_10_4,备用
|
||||||
|
AN_11_1,2#压延机冷却水断水报警
|
||||||
|
AN_11_2,2#压延机冷却水温升报警
|
||||||
|
AN_11_3,2#过渡辊台冷却水断水报警
|
||||||
|
AN_11_4,2#过渡辊台冷却水温升报警
|
||||||
|
AN_12_1,2#线唇砖冷却水断水报警
|
||||||
|
AN_12_2,2#线唇砖冷却水温升报警
|
||||||
|
AN_12_3,2#退火窑A区风机报警
|
||||||
|
AN_12_4,2#退火窑B区风机报警
|
||||||
|
AN_13_1,2#退火窑c区风机报警
|
||||||
|
AN_13_2,2#退火窑Ret1区风机报警
|
||||||
|
AN_13_3,2#退火窑Ret2区风机报警
|
||||||
|
AN_13_4,2#退火窑F1区风机报警
|
||||||
|
AN_14_1,2#退火窑F2区风机报警
|
||||||
|
AN_14_2,2#主传动报警
|
||||||
|
AN_14_3,2#压延机报警
|
||||||
|
AN_14_4,备用
|
||||||
|
AN_15_1,3#压延机冷却水断水报警
|
||||||
|
AN_15_2,3压延机冷却水温升报警
|
||||||
|
AN_15_3,3#过渡辊台冷却水断水报警
|
||||||
|
AN_15_4,3#过渡辊台冷却水温升报警
|
||||||
|
AN_16_1,3#线唇砖冷却水断水报警
|
||||||
|
AN_16_2,3#线唇砖冷却水温升报警
|
||||||
|
AN_16_3,3#退火窑A区风机报警
|
||||||
|
AN_16_4,3#退火窑B区风机报警
|
||||||
|
AN_17_1,3#退火窑c区风机报警
|
||||||
|
AN_17_2,3#退火窑Ret1区风机报警
|
||||||
|
AN_17_3,3#退火窑Ret2区风机报警
|
||||||
|
AN_17_4,3#退火窑F1区风机报警
|
||||||
|
AN_18_1,3#退火窑F2区风机报警
|
||||||
|
AN_18_2,3#主传动报警
|
||||||
|
AN_18_3,3#压延机报警
|
||||||
|
AN_18_4,备用
|
||||||
|
AN_19_1,4#压延机冷却水断水报警
|
||||||
|
AN_19_2,4压延机冷却水温升报警
|
||||||
|
AN_19_3,4#过渡辊台冷却水断水报警
|
||||||
|
AN_19_4,4#过渡辊台冷却水温升报警
|
||||||
|
AN_20_1,4#线唇砖冷却水断水报警
|
||||||
|
AN_20_2,4#线唇砖冷却水温升报警
|
||||||
|
AN_20_3,4#退火窑A区风机报警
|
||||||
|
AN_20_4,4#退火窑B区风机报警
|
||||||
|
AN_21_1,4#退火窑c区风机报警
|
||||||
|
AN_21_2,4#退火窑Ret1区风机报警
|
||||||
|
AN_21_3,4#退火窑Ret2区风机报警
|
||||||
|
AN_21_4,4#退火窑F1区风机报警
|
||||||
|
AN_22_1,4#退火窑F2区风机报警
|
||||||
|
AN_22_2,4#主传动报警
|
||||||
|
AN_22_3,4#压延机报警
|
||||||
|
AN_23_1,5#压延机冷却水断水报警
|
||||||
|
AN_23_2,5#压延机冷却水温升报警
|
||||||
|
AN_23_3,5#过渡辊台冷却水断水报警
|
||||||
|
AN_23_4,5#过渡台冷却水温升报警
|
||||||
|
AN_24_1,5#线唇砖冷却水断水报警
|
||||||
|
AN_24_2,5#线唇砖冷却水温升报警
|
||||||
|
AN_24_3,5#退火窑A区风机报警
|
||||||
|
AN_24_4,5#退火窑B区风机报警
|
||||||
|
AN_25_1,5#退火窑c区风机报警
|
||||||
|
AN_25_2,5#退火窑Ret1区风机报警
|
||||||
|
AN_25_3,5#退火窑Ret2区风机报警
|
||||||
|
AN_25_4,5#退火窑F1区风机报警
|
||||||
|
AN_26_1,5#退火窑F2区风机报警
|
||||||
|
AN_26_2,5#主传动报警
|
||||||
|
AN_26_3,5#压延机报警
|
||||||
|
`;
|
||||||
|
|
||||||
|
function AlarmListContainer(props) {
|
||||||
|
const alarmList = useSelector((state) => state.alarm.list);
|
||||||
|
// const alarmList = total
|
||||||
|
// .split("\n")
|
||||||
|
// .filter((str) => str.trim())
|
||||||
|
// .map((item) => ({
|
||||||
|
// id: item.split(",")[0],
|
||||||
|
// title: item.split(",")[0],
|
||||||
|
// content: item.split(",")[1],
|
||||||
|
// }));
|
||||||
|
return alarmList.map((alarm) => (
|
||||||
|
<WarnAlert
|
||||||
|
key={alarm.id}
|
||||||
|
title={alarm.title}
|
||||||
|
content={alarm.content}
|
||||||
|
x={posMap[alarm.title]?.x || 0}
|
||||||
|
y={posMap[alarm.title]?.y || 0}
|
||||||
|
/>
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
export default AlarmListContainer;
|
||||||
18
src/components/Common/WarnAlert/index.jsx
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
// import cls from "./index.module.css";
|
||||||
|
import "./warn-alert.css";
|
||||||
|
import AlertIcon from "./warn-icon.png";
|
||||||
|
|
||||||
|
function WarnAlert(props) {
|
||||||
|
const { x, y, title, content } = props;
|
||||||
|
return (
|
||||||
|
<div className="warn-alert" style={{ top: `${y}px`, left: `${x}px` }}>
|
||||||
|
<h1 className="">
|
||||||
|
<img src={AlertIcon} width={24} alt="icon" />
|
||||||
|
{title || "test"}
|
||||||
|
</h1>
|
||||||
|
<p>{content || "Lorem ipsum dolor sit amet consectetur."}</p>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default WarnAlert;
|
||||||
104
src/components/Common/WarnAlert/position.json
Normal file
@@ -0,0 +1,104 @@
|
|||||||
|
{
|
||||||
|
"AN_1_1": { "x": 650, "y": 645 },
|
||||||
|
"AN_1_2": { "x": 1450, "y": 540 },
|
||||||
|
"AN_1_3": { "x": 640, "y": 285 },
|
||||||
|
"AN_1_4": { "x": 720, "y": 645 },
|
||||||
|
"AN_2_1": { "x": 1250, "y": 540 },
|
||||||
|
"AN_2_2": { "x": 1200, "y": 540 },
|
||||||
|
"AN_2_3": { "x": 1460, "y": 410 },
|
||||||
|
"AN_2_4": { "x": 650, "y": 420 },
|
||||||
|
"AN_3_1": { "x": 1360, "y": 380 },
|
||||||
|
"AN_3_2": { "x": 1360, "y": 380 },
|
||||||
|
"AN_3_3": { "x": 1360, "y": 420 },
|
||||||
|
"AN_3_4": { "x": 1360, "y": 420 },
|
||||||
|
"AN_4_1": { "x": 1350, "y": 460 },
|
||||||
|
"AN_4_2": { "x": 1350, "y": 460 },
|
||||||
|
"AN_4_3": { "x": 1270, "y": 320 },
|
||||||
|
"AN_4_4": { "x": 900, "y": 420 },
|
||||||
|
"AN_5_1": { "x": 650, "y": 645 },
|
||||||
|
"AN_5_2": { "x": 980, "y": 420 },
|
||||||
|
"AN_5_3": { "x": 1050, "y": 420 },
|
||||||
|
"AN_5_4": { "x": 1130, "y": 420 },
|
||||||
|
"AN_6_1": { "x": 1220, "y": 420 },
|
||||||
|
"AN_6_2": { "x": 1290, "y": 420 },
|
||||||
|
"AN_6_3": { "x": 650, "y": 440 },
|
||||||
|
"AN_6_4": { "x": 1400, "y": 650 },
|
||||||
|
"AN_7_1": { "x": 1450, "y": 540 },
|
||||||
|
"AN_7_2": { "x": 1450, "y": 540 },
|
||||||
|
"AN_7_3": { "x": 1470, "y": 540 },
|
||||||
|
"AN_7_4": { "x": 1470, "y": 540 },
|
||||||
|
"AN_8_1": { "x": 1470, "y": 540 },
|
||||||
|
"AN_8_2": { "x": 1470, "y": 540 },
|
||||||
|
"AN_8_3": { "x": 1480, "y": 540 },
|
||||||
|
"AN_8_4": { "x": 1580, "y": 540 },
|
||||||
|
"AN_9_1": { "x": 1700, "y": 540 },
|
||||||
|
"AN_9_2": { "x": 1760, "y": 540 },
|
||||||
|
"AN_9_3": { "x": 1780, "y": 540 },
|
||||||
|
"AN_9_4": { "x": 1780, "y": 540 },
|
||||||
|
"AN_10_1": { "x": 1780, "y": 540 },
|
||||||
|
"AN_10_2": { "x": 1390, "y": 540 },
|
||||||
|
"AN_10_3": { "x": 1450, "y": 540 },
|
||||||
|
"AN_10_4": { "x": 1400, "y": 650 },
|
||||||
|
"AN_11_1": { "x": 1450, "y": 480 },
|
||||||
|
"AN_11_2": { "x": 1450, "y": 480 },
|
||||||
|
"AN_11_3": { "x": 1450, "y": 480 },
|
||||||
|
"AN_11_4": { "x": 1450, "y": 480 },
|
||||||
|
"AN_12_1": { "x": 1450, "y": 480 },
|
||||||
|
"AN_12_2": { "x": 1450, "y": 480 },
|
||||||
|
"AN_12_3": { "x": 1550, "y": 480 },
|
||||||
|
"AN_12_4": { "x": 1650, "y": 480 },
|
||||||
|
"AN_13_1": { "x": 1750, "y": 480 },
|
||||||
|
"AN_13_2": { "x": 1850, "y": 480 },
|
||||||
|
"AN_13_3": { "x": 1900, "y": 480 },
|
||||||
|
"AN_13_4": { "x": 1910, "y": 480 },
|
||||||
|
"AN_14_1": { "x": 1920, "y": 480 },
|
||||||
|
"AN_14_2": { "x": 1450, "y": 480 },
|
||||||
|
"AN_14_3": { "x": 1450, "y": 480 },
|
||||||
|
"AN_14_4": { "x": 1400, "y": 650 },
|
||||||
|
"AN_15_1": { "x": 1450, "y": 430 },
|
||||||
|
"AN_15_2": { "x": 1450, "y": 430 },
|
||||||
|
"AN_15_3": { "x": 1470, "y": 430 },
|
||||||
|
"AN_15_4": { "x": 1470, "y": 430 },
|
||||||
|
"AN_16_1": { "x": 1470, "y": 430 },
|
||||||
|
"AN_16_2": { "x": 1470, "y": 430 },
|
||||||
|
"AN_16_3": { "x": 1600, "y": 430 },
|
||||||
|
"AN_16_4": { "x": 1700, "y": 430 },
|
||||||
|
"AN_17_1": { "x": 1800, "y": 430 },
|
||||||
|
"AN_17_2": { "x": 1900, "y": 430 },
|
||||||
|
"AN_17_3": { "x": 1950, "y": 430 },
|
||||||
|
"AN_17_4": { "x": 1960, "y": 430 },
|
||||||
|
"AN_18_1": { "x": 1970, "y": 430 },
|
||||||
|
"AN_18_2": { "x": 1450, "y": 430 },
|
||||||
|
"AN_18_3": { "x": 1450, "y": 430 },
|
||||||
|
"AN_18_4": { "x": 1400, "y": 650 },
|
||||||
|
"AN_19_1": { "x": 1450, "y": 370 },
|
||||||
|
"AN_19_2": { "x": 1450, "y": 370 },
|
||||||
|
"AN_19_3": { "x": 1460, "y": 370 },
|
||||||
|
"AN_19_4": { "x": 1460, "y": 370 },
|
||||||
|
"AN_20_1": { "x": 1460, "y": 370 },
|
||||||
|
"AN_20_2": { "x": 1460, "y": 370 },
|
||||||
|
"AN_20_3": { "x": 1500, "y": 370 },
|
||||||
|
"AN_20_4": { "x": 1600, "y": 370 },
|
||||||
|
"AN_21_1": { "x": 1700, "y": 370 },
|
||||||
|
"AN_21_2": { "x": 1800, "y": 370 },
|
||||||
|
"AN_21_3": { "x": 1850, "y": 370 },
|
||||||
|
"AN_21_4": { "x": 1860, "y": 370 },
|
||||||
|
"AN_22_1": { "x": 1870, "y": 370 },
|
||||||
|
"AN_22_2": { "x": 1450, "y": 370 },
|
||||||
|
"AN_22_3": { "x": 1460, "y": 370 },
|
||||||
|
"AN_23_1": { "x": 1460, "y": 320 },
|
||||||
|
"AN_23_2": { "x": 1460, "y": 320 },
|
||||||
|
"AN_23_3": { "x": 1465, "y": 320 },
|
||||||
|
"AN_23_4": { "x": 1465, "y": 320 },
|
||||||
|
"AN_24_1": { "x": 1465, "y": 320 },
|
||||||
|
"AN_24_2": { "x": 1465, "y": 320 },
|
||||||
|
"AN_24_3": { "x": 1480, "y": 320 },
|
||||||
|
"AN_24_4": { "x": 1580, "y": 320 },
|
||||||
|
"AN_25_1": { "x": 1680, "y": 320 },
|
||||||
|
"AN_25_2": { "x": 1780, "y": 320 },
|
||||||
|
"AN_25_3": { "x": 1750, "y": 320 },
|
||||||
|
"AN_25_4": { "x": 1760, "y": 320 },
|
||||||
|
"AN_26_1": { "x": 1770, "y": 320 },
|
||||||
|
"AN_26_2": { "x": 1430, "y": 320 },
|
||||||
|
"AN_26_3": { "x": 1460, "y": 320 }
|
||||||
|
}
|
||||||
65
src/components/Common/WarnAlert/warn-alert.css
Normal file
@@ -0,0 +1,65 @@
|
|||||||
|
.warn-alert {
|
||||||
|
position: fixed;
|
||||||
|
top: 200px;
|
||||||
|
left: 200px;
|
||||||
|
/* height: 72px; */
|
||||||
|
z-index: 10000;
|
||||||
|
display: inline-block;
|
||||||
|
/* background: url(../../../assets/warn-bg.png) 0 0 / 116px 100% repeat-x; */
|
||||||
|
background: url(./3.png) 0 0 / 116px 100% repeat-x;
|
||||||
|
box-shadow: 0 0 24px 6px rgba(0, 0, 0, 0.5);
|
||||||
|
user-select: none;
|
||||||
|
transform: scale(0.64);
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.warn-alert:hover {
|
||||||
|
transform: scale(1.1);
|
||||||
|
box-shadow: 0 0 32px 12px rgba(0, 0, 0, 0.5);
|
||||||
|
z-index: 10001;
|
||||||
|
}
|
||||||
|
|
||||||
|
.warn-alert::before {
|
||||||
|
box-sizing: border-box;
|
||||||
|
content: "";
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: -24px;
|
||||||
|
width: 24px;
|
||||||
|
height: 100%;
|
||||||
|
display: inline-block;
|
||||||
|
border: 12px solid transparent;
|
||||||
|
border-right-color: #ff2c2c;
|
||||||
|
}
|
||||||
|
.warn-alert::after {
|
||||||
|
box-sizing: border-box;
|
||||||
|
content: "";
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
right: -24px;
|
||||||
|
width: 24px;
|
||||||
|
height: 100%;
|
||||||
|
display: inline-block;
|
||||||
|
border: 12px solid transparent;
|
||||||
|
border-left-color: #ff2c2c;
|
||||||
|
}
|
||||||
|
|
||||||
|
.warn-alert > h1 {
|
||||||
|
display: flex;
|
||||||
|
margin: 8px 0 0;
|
||||||
|
align-items: center;
|
||||||
|
color: #fff;
|
||||||
|
font-size: 16px;
|
||||||
|
text-transform: uppercase;
|
||||||
|
}
|
||||||
|
|
||||||
|
.warn-alert > h1 img {
|
||||||
|
padding-top: 3px;
|
||||||
|
margin-left: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.warn-alert > p {
|
||||||
|
color: #fff;
|
||||||
|
margin: 0 22px 16px 14px;
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
BIN
src/components/Common/WarnAlert/warn-icon.png
Normal file
|
After Width: | Height: | Size: 2.2 KiB |
@@ -2,33 +2,40 @@ import cls from "./index.module.css";
|
|||||||
import GradientText from "../../../Common/GradientText";
|
import GradientText from "../../../Common/GradientText";
|
||||||
import { useSelector } from "react-redux";
|
import { useSelector } from "react-redux";
|
||||||
import { useEffect, useState } from "react";
|
import { useEffect, useState } from "react";
|
||||||
|
import eIcon1 from "../../../../assets/Icon/dontknowwhatitis.png";
|
||||||
|
import eIcon2 from "../../../../assets/Icon/lightnen.png";
|
||||||
|
|
||||||
function Energy(props) {
|
function Energy(props) {
|
||||||
const [isPage1, setIsPage1] = useState(true);
|
const [isPage1] = useState(props.page === 1);
|
||||||
const energyInfo = useSelector((state) => state.energy?.info);
|
const energyInfo = useSelector((state) => state.energy?.info);
|
||||||
|
|
||||||
useEffect(() => {
|
// useEffect(() => {
|
||||||
const timer = setInterval(() => {
|
// const timer = setInterval(() => {
|
||||||
setIsPage1((pre) => !pre);
|
// setIsPage1((pre) => !pre);
|
||||||
}, 10000);
|
// }, 10000);
|
||||||
|
|
||||||
return () => {
|
// return () => {
|
||||||
clearInterval(timer);
|
// clearInterval(timer);
|
||||||
}
|
// }
|
||||||
}, []);
|
// }, []);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={" " + cls.layout} style={{ color: "#fff" }}>
|
<div className={" " + cls.layout} style={{ color: "#fff" }}>
|
||||||
<span
|
<span
|
||||||
className={cls.shadowBorder}
|
className={`${cls.shadowBorder} ${cls.border}`}
|
||||||
style={{
|
style={{
|
||||||
gridRow: "1 / 3",
|
gridRow: "1 / 3",
|
||||||
paddingTop: "104px",
|
|
||||||
paddingLeft: "32px",
|
|
||||||
userSelect: "none",
|
userSelect: "none",
|
||||||
|
textAlign: "center",
|
||||||
|
paddingTop: "96px",
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<GradientText text="能源" />
|
{isPage1 ? (
|
||||||
|
<img src={eIcon1} width={32} alt="eicon1" />
|
||||||
|
) : (
|
||||||
|
<img src={eIcon2} width={32} alt="eicon2" />
|
||||||
|
)}
|
||||||
|
<GradientText text={"\u2002\u2002能源"} />
|
||||||
</span>
|
</span>
|
||||||
{!isPage1 && (
|
{!isPage1 && (
|
||||||
<div
|
<div
|
||||||
@@ -65,7 +72,9 @@ function Energy(props) {
|
|||||||
{(+energyInfo?.elecQty7)?.toFixed(2) || 0}
|
{(+energyInfo?.elecQty7)?.toFixed(2) || 0}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<div className={cls.shadowBorder + " " + cls.infoText}>
|
<div
|
||||||
|
className={cls.shadowBorder + " " + cls.infoText + " " + cls.border}
|
||||||
|
>
|
||||||
<span style={{ lineHeight: 1.5 }}>智慧能源光伏发电(总量)/kWh</span>
|
<span style={{ lineHeight: 1.5 }}>智慧能源光伏发电(总量)/kWh</span>
|
||||||
<span
|
<span
|
||||||
style={{
|
style={{
|
||||||
@@ -77,7 +86,9 @@ function Energy(props) {
|
|||||||
{(+energyInfo?.elecQty4)?.toFixed(2) || 0}
|
{(+energyInfo?.elecQty4)?.toFixed(2) || 0}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<div className={cls.shadowBorder + " " + cls.infoText}>
|
<div
|
||||||
|
className={cls.shadowBorder + " " + cls.infoText + " " + cls.border}
|
||||||
|
>
|
||||||
<span style={{ lineHeight: 1.5 }}>许昌安彩光伏发电(总量)/kWh</span>
|
<span style={{ lineHeight: 1.5 }}>许昌安彩光伏发电(总量)/kWh</span>
|
||||||
<span
|
<span
|
||||||
style={{
|
style={{
|
||||||
@@ -105,7 +116,7 @@ function Energy(props) {
|
|||||||
style={{ flex: 1 }}
|
style={{ flex: 1 }}
|
||||||
className={cls.shadowBorder + " " + cls.infoText}
|
className={cls.shadowBorder + " " + cls.infoText}
|
||||||
>
|
>
|
||||||
<span style={{ lineHeight: 1.5 }}>余热发电(实时)/kWh</span>
|
<span style={{ lineHeight: 1.5 }}>余热发电(昨日)/kWh</span>
|
||||||
<span
|
<span
|
||||||
style={{
|
style={{
|
||||||
lineHeight: 1.5,
|
lineHeight: 1.5,
|
||||||
@@ -118,7 +129,9 @@ function Energy(props) {
|
|||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
style={{ flex: 1 }}
|
style={{ flex: 1 }}
|
||||||
className={cls.shadowBorder + " " + cls.infoText}
|
className={
|
||||||
|
cls.shadowBorder + " " + cls.infoText + " " + cls.border
|
||||||
|
}
|
||||||
>
|
>
|
||||||
<span style={{ lineHeight: 1.5 }}>余热发电(总量)/kWh</span>
|
<span style={{ lineHeight: 1.5 }}>余热发电(总量)/kWh</span>
|
||||||
<span
|
<span
|
||||||
@@ -133,25 +146,29 @@ function Energy(props) {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<span className={cls.shadowBorder + " " + cls.infoText}>
|
<span className={cls.shadowBorder + " " + cls.infoText}>
|
||||||
<span style={{ lineHeight: 1.5 }}>水耗量/Km³</span>
|
<span style={{ lineHeight: 1.5 }}>水耗量(昨日)/Km³</span>
|
||||||
<span style={{ lineHeight: 1.5 }}>
|
<span style={{ lineHeight: 1.5 }}>
|
||||||
{(+energyInfo?.waterQty)?.toFixed(2) || 0}
|
{(+energyInfo?.waterQty)?.toFixed(2) || 0}
|
||||||
</span>
|
</span>
|
||||||
</span>
|
</span>
|
||||||
<span className={cls.shadowBorder + " " + cls.infoText}>
|
<span className={cls.shadowBorder + " " + cls.infoText}>
|
||||||
<span style={{ lineHeight: 1.5 }}>天然气I/Nm³</span>
|
<span style={{ lineHeight: 1.5 }}>天然气I(累计)/Nm³</span>
|
||||||
<span style={{ lineHeight: 1.5 }}>
|
<span style={{ lineHeight: 1.5 }}>
|
||||||
{energyInfo?.ngQty1?.replace("Nm³", "") || "0Nm³"}
|
{energyInfo?.ngQty1?.replace("Nm³", "") || "0Nm³"}
|
||||||
</span>
|
</span>
|
||||||
</span>
|
</span>
|
||||||
<span className={cls.shadowBorder + " " + cls.infoText}>
|
<span
|
||||||
<span style={{ lineHeight: 1.5 }}>电耗量/kWh</span>
|
className={cls.shadowBorder + " " + cls.infoText + " " + cls.border}
|
||||||
|
>
|
||||||
|
<span style={{ lineHeight: 1.5 }}>电耗量(昨日)/kWh</span>
|
||||||
<span style={{ lineHeight: 1.5 }}>
|
<span style={{ lineHeight: 1.5 }}>
|
||||||
{(+energyInfo?.elecQty2)?.toFixed(2) || 0}
|
{(+energyInfo?.elecQty2)?.toFixed(2) || 0}
|
||||||
</span>
|
</span>
|
||||||
</span>
|
</span>
|
||||||
<span className={cls.shadowBorder + " " + cls.infoText}>
|
<span
|
||||||
<span style={{ lineHeight: 1.5 }}>天然气II/Nm³</span>
|
className={cls.shadowBorder + " " + cls.infoText + " " + cls.border}
|
||||||
|
>
|
||||||
|
<span style={{ lineHeight: 1.5 }}>天然气II(累计)/Nm³</span>
|
||||||
<span style={{ lineHeight: 1.5 }}>
|
<span style={{ lineHeight: 1.5 }}>
|
||||||
{energyInfo?.ngQty2?.replace("Nm³", "") || "0Nm³"}
|
{energyInfo?.ngQty2?.replace("Nm³", "") || "0Nm³"}
|
||||||
</span>
|
</span>
|
||||||
|
|||||||
@@ -4,7 +4,8 @@
|
|||||||
/* grid-template-columns: 133px 158px 292px 292px; */
|
/* grid-template-columns: 133px 158px 292px 292px; */
|
||||||
grid-template-columns: 125px 250px 250px 250px;
|
grid-template-columns: 125px 250px 250px 250px;
|
||||||
/* grid-template-rows: 60px 60px; */
|
/* grid-template-rows: 60px 60px; */
|
||||||
grid-template-rows: 129px 129px;
|
grid-template-rows: auto;
|
||||||
|
height: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.shadowBorder {
|
.shadowBorder {
|
||||||
@@ -13,6 +14,29 @@
|
|||||||
padding: 4px;
|
padding: 4px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.shadowBorder.border {
|
||||||
|
position: relative;
|
||||||
|
border-bottom: 2px solid #00fff7;
|
||||||
|
}
|
||||||
|
|
||||||
|
.shadowBorder.border::before,
|
||||||
|
.shadowBorder.border::after {
|
||||||
|
content: "";
|
||||||
|
position: absolute;
|
||||||
|
bottom: 0;
|
||||||
|
display: inline-block;
|
||||||
|
height: 100%;
|
||||||
|
width: 2px;
|
||||||
|
background: linear-gradient(to top, #00fff7, #00fff708, transparent);
|
||||||
|
}
|
||||||
|
|
||||||
|
.shadowBorder.border::before {
|
||||||
|
left: 0;
|
||||||
|
}
|
||||||
|
.shadowBorder.border::after {
|
||||||
|
right: 0;
|
||||||
|
}
|
||||||
|
|
||||||
.infoText {
|
.infoText {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
font-size: 22px;
|
font-size: 22px;
|
||||||
@@ -27,6 +51,6 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.infoText > span:last-child {
|
.infoText > span:last-child {
|
||||||
color: #00FFF7;
|
color: #00fff7;
|
||||||
font-size: 24px;
|
font-size: 24px;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,17 +6,38 @@ import { useState } from "react";
|
|||||||
import * as echarts from "echarts";
|
import * as echarts from "echarts";
|
||||||
import dayjs from "dayjs";
|
import dayjs from "dayjs";
|
||||||
|
|
||||||
|
function getTimeStr(period) {
|
||||||
|
return {
|
||||||
|
日:
|
||||||
|
dayjs().format("YYYY.MM.DD") +
|
||||||
|
" 7点 - " +
|
||||||
|
dayjs().add(1, "d").format("YYYY.MM.DD") +
|
||||||
|
" 7点",
|
||||||
|
年:
|
||||||
|
dayjs().subtract(1, "year").endOf("year").format("YYYY.MM.") +
|
||||||
|
"29 - " +
|
||||||
|
dayjs().endOf("year").format("YYYY.MM.") +
|
||||||
|
"28",
|
||||||
|
周:
|
||||||
|
dayjs().subtract(7, "day").format("YYYY.MM.DD") +
|
||||||
|
" - " +
|
||||||
|
dayjs().subtract(1, "day").format("YYYY.MM.DD"),
|
||||||
|
月:
|
||||||
|
dayjs().subtract(1, "month").format("YYYY.MM.") +
|
||||||
|
"29 - " +
|
||||||
|
dayjs().format("YYYY.MM.") +
|
||||||
|
"28",
|
||||||
|
}[period];
|
||||||
|
}
|
||||||
|
|
||||||
function NO(props) {
|
function NO(props) {
|
||||||
const dayTrend = useSelector((state) => state.smoke?.dayTrend);
|
const dayTrend = useSelector((state) => state.smoke?.dayTrend);
|
||||||
const weekTrend = useSelector((state) => state.smoke?.weekTrend);
|
const weekTrend = useSelector((state) => state.smoke?.weekTrend);
|
||||||
const monthTrend = useSelector((state) => state.smoke?.monthTrend);
|
const monthTrend = useSelector((state) => state.smoke?.monthTrend);
|
||||||
const yearTrend = useSelector((state) => state.smoke?.yearTrend);
|
const yearTrend = useSelector((state) => state.smoke?.yearTrend);
|
||||||
const [period, setPeriod] = useState("日");
|
const [period, setPeriod] = useState("日");
|
||||||
const [timestr, setTimestr] = useState(
|
|
||||||
dayjs().subtract(7, "day").format("YYYY.MM.DD") +
|
let timestr = getTimeStr(period);
|
||||||
" - " +
|
|
||||||
dayjs().subtract(1, "day").format("YYYY.MM.DD")
|
|
||||||
);
|
|
||||||
|
|
||||||
const currentTrend =
|
const currentTrend =
|
||||||
period === "日"
|
period === "日"
|
||||||
@@ -33,35 +54,13 @@ function NO(props) {
|
|||||||
|
|
||||||
function handleDateChange(value) {
|
function handleDateChange(value) {
|
||||||
setPeriod(value);
|
setPeriod(value);
|
||||||
setTimestr(
|
timestr = getTimeStr(value);
|
||||||
{
|
|
||||||
日:
|
|
||||||
dayjs().subtract(1, "day").format("YYYY.MM.DD") +
|
|
||||||
" 7点 - " +
|
|
||||||
dayjs().format("YYYY.MM.DD") +
|
|
||||||
" 7点",
|
|
||||||
年:
|
|
||||||
dayjs().subtract(1, "year").endOf("year").format("YYYY.MM.") +
|
|
||||||
"29 - " +
|
|
||||||
dayjs().endOf("year").format("YYYY.MM.") +
|
|
||||||
"28",
|
|
||||||
周:
|
|
||||||
dayjs().subtract(7, "day").format("YYYY.MM.DD") +
|
|
||||||
" - " +
|
|
||||||
dayjs().subtract(1, "day").format("YYYY.MM.DD"),
|
|
||||||
月:
|
|
||||||
dayjs().subtract(1, "month").format("YYYY.MM.") +
|
|
||||||
"29 - " +
|
|
||||||
dayjs().format("YYYY.MM.") +
|
|
||||||
"28",
|
|
||||||
}[value]
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
return (
|
return (
|
||||||
<GraphBase
|
<GraphBase
|
||||||
icon="smoke"
|
icon="smoke"
|
||||||
title="氮氧化物"
|
title="氮氧化物"
|
||||||
desc={`能耗趋势图 ${timestr}`}
|
desc={`烟气趋势图 ${timestr}`}
|
||||||
switchOptions={false}
|
switchOptions={false}
|
||||||
defaultSelect={period}
|
defaultSelect={period}
|
||||||
onSwitch={handleSwitch}
|
onSwitch={handleSwitch}
|
||||||
|
|||||||
@@ -6,17 +6,38 @@ import { useState } from "react";
|
|||||||
import * as echarts from "echarts";
|
import * as echarts from "echarts";
|
||||||
import dayjs from "dayjs";
|
import dayjs from "dayjs";
|
||||||
|
|
||||||
|
function getTimeStr(period) {
|
||||||
|
return {
|
||||||
|
日:
|
||||||
|
dayjs().format("YYYY.MM.DD") +
|
||||||
|
" 7点 - " +
|
||||||
|
dayjs().add(1, 'd').format("YYYY.MM.DD") +
|
||||||
|
" 7点",
|
||||||
|
年:
|
||||||
|
dayjs().subtract(1, "year").endOf("year").format("YYYY.MM.") +
|
||||||
|
"29 - " +
|
||||||
|
dayjs().endOf("year").format("YYYY.MM.") +
|
||||||
|
"28",
|
||||||
|
周:
|
||||||
|
dayjs().subtract(7, "day").format("YYYY.MM.DD") +
|
||||||
|
" - " +
|
||||||
|
dayjs().subtract(1, "day").format("YYYY.MM.DD"),
|
||||||
|
月:
|
||||||
|
dayjs().subtract(1, "month").format("YYYY.MM.") +
|
||||||
|
"29 - " +
|
||||||
|
dayjs().format("YYYY.MM.") +
|
||||||
|
"28",
|
||||||
|
}[period];
|
||||||
|
}
|
||||||
|
|
||||||
function Dust(props) {
|
function Dust(props) {
|
||||||
const dayTrend = useSelector((state) => state.smoke?.dayTrend);
|
const dayTrend = useSelector((state) => state.smoke?.dayTrend);
|
||||||
const weekTrend = useSelector((state) => state.smoke?.weekTrend);
|
const weekTrend = useSelector((state) => state.smoke?.weekTrend);
|
||||||
const monthTrend = useSelector((state) => state.smoke?.monthTrend);
|
const monthTrend = useSelector((state) => state.smoke?.monthTrend);
|
||||||
const yearTrend = useSelector((state) => state.smoke?.yearTrend);
|
const yearTrend = useSelector((state) => state.smoke?.yearTrend);
|
||||||
const [period, setPeriod] = useState("日");
|
const [period, setPeriod] = useState("日");
|
||||||
const [timestr, setTimestr] = useState(
|
|
||||||
dayjs().subtract(7, "day").format("YYYY.MM.DD") +
|
let timestr = getTimeStr(period);
|
||||||
" - " +
|
|
||||||
dayjs().subtract(1, "day").format("YYYY.MM.DD")
|
|
||||||
);
|
|
||||||
const currentTrend =
|
const currentTrend =
|
||||||
period === "日"
|
period === "日"
|
||||||
? dayTrend
|
? dayTrend
|
||||||
@@ -32,36 +53,14 @@ function Dust(props) {
|
|||||||
|
|
||||||
function handleDateChange(value) {
|
function handleDateChange(value) {
|
||||||
setPeriod(value);
|
setPeriod(value);
|
||||||
setTimestr(
|
timestr = getTimeStr(value);
|
||||||
{
|
|
||||||
日:
|
|
||||||
dayjs().subtract(1, "day").format("YYYY.MM.DD") +
|
|
||||||
" 7点 - " +
|
|
||||||
dayjs().format("YYYY.MM.DD") +
|
|
||||||
" 7点",
|
|
||||||
年:
|
|
||||||
dayjs().subtract(1, "year").endOf("year").format("YYYY.MM.") +
|
|
||||||
"29 - " +
|
|
||||||
dayjs().endOf("year").format("YYYY.MM.") +
|
|
||||||
"28",
|
|
||||||
周:
|
|
||||||
dayjs().subtract(7, "day").format("YYYY.MM.DD") +
|
|
||||||
" - " +
|
|
||||||
dayjs().subtract(1, "day").format("YYYY.MM.DD"),
|
|
||||||
月:
|
|
||||||
dayjs().subtract(1, "month").format("YYYY.MM.") +
|
|
||||||
"29 - " +
|
|
||||||
dayjs().format("YYYY.MM.") +
|
|
||||||
"28",
|
|
||||||
}[value]
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<GraphBase
|
<GraphBase
|
||||||
icon="smoke"
|
icon="smoke"
|
||||||
title="颗粒物"
|
title="颗粒物"
|
||||||
desc={`能耗趋势图 ${timestr}`}
|
desc={`烟气趋势图 ${timestr}`}
|
||||||
switchOptions={false}
|
switchOptions={false}
|
||||||
defaultSelect={period}
|
defaultSelect={period}
|
||||||
onSwitch={handleSwitch}
|
onSwitch={handleSwitch}
|
||||||
|
|||||||
@@ -8,7 +8,8 @@ import { lunarYear } from "../../../../utils/energeChartOption";
|
|||||||
import dayjs from "dayjs";
|
import dayjs from "dayjs";
|
||||||
|
|
||||||
function NatGas(props) {
|
function NatGas(props) {
|
||||||
const elecTrend = useSelector((state) => state.energy.trend.natGas1);
|
const natGasTrend = useSelector((state) => state.energy.trend.natGas1);
|
||||||
|
const gasTrend = useSelector((state) => state.energy.trend.natGas2);
|
||||||
const [period, setPeriod] = useState("周");
|
const [period, setPeriod] = useState("周");
|
||||||
const [timestr, setTimestr] = useState(
|
const [timestr, setTimestr] = useState(
|
||||||
dayjs().subtract(7, "day").format("YYYY.MM.DD") +
|
dayjs().subtract(7, "day").format("YYYY.MM.DD") +
|
||||||
@@ -18,7 +19,7 @@ function NatGas(props) {
|
|||||||
|
|
||||||
const options = getOptions(
|
const options = getOptions(
|
||||||
{ 周: "week", 月: "month", 年: "year" }[period],
|
{ 周: "week", 月: "month", 年: "year" }[period],
|
||||||
elecTrend ?? { week: [], month: [], year: [] }
|
[natGasTrend, gasTrend] ?? { week: [], month: [], year: [] }
|
||||||
);
|
);
|
||||||
|
|
||||||
function handleSwitch(v) {
|
function handleSwitch(v) {
|
||||||
@@ -50,7 +51,7 @@ function NatGas(props) {
|
|||||||
return (
|
return (
|
||||||
<GraphBase
|
<GraphBase
|
||||||
icon="battery"
|
icon="battery"
|
||||||
title="天然气I"
|
title="天然气"
|
||||||
desc={`能耗趋势图 ${timestr}`}
|
desc={`能耗趋势图 ${timestr}`}
|
||||||
switchOptions={false}
|
switchOptions={false}
|
||||||
onSwitch={handleSwitch}
|
onSwitch={handleSwitch}
|
||||||
@@ -60,6 +61,45 @@ function NatGas(props) {
|
|||||||
onDateChange={handleDateChange}
|
onDateChange={handleDateChange}
|
||||||
size={["long", "middle"]}
|
size={["long", "middle"]}
|
||||||
>
|
>
|
||||||
|
<div
|
||||||
|
className="nat-gas-legend"
|
||||||
|
style={{
|
||||||
|
position: "absolute",
|
||||||
|
top: 28,
|
||||||
|
right: 144,
|
||||||
|
display: "flex",
|
||||||
|
gap: "24px",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<div className="legend-item">
|
||||||
|
<div
|
||||||
|
className="legend-color"
|
||||||
|
style={{
|
||||||
|
display: "inline-block",
|
||||||
|
width: "12px",
|
||||||
|
height: "12px",
|
||||||
|
borderRadius: "2px",
|
||||||
|
marginRight: "8px",
|
||||||
|
backgroundColor: "#FFD160",
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
<span style={{ color: "#fff" }}>天然气I</span>
|
||||||
|
</div>
|
||||||
|
<div className="legend-item">
|
||||||
|
<div
|
||||||
|
className="legend-color"
|
||||||
|
style={{
|
||||||
|
display: "inline-block",
|
||||||
|
width: "12px",
|
||||||
|
height: "12px",
|
||||||
|
borderRadius: "2px",
|
||||||
|
marginRight: "8px",
|
||||||
|
backgroundColor: "#12FFF5",
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
<span style={{ color: "#fff" }}>天然气II</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
{/* real echarts here */}
|
{/* real echarts here */}
|
||||||
{options && (
|
{options && (
|
||||||
<ReactECharts
|
<ReactECharts
|
||||||
@@ -89,8 +129,9 @@ function NatGas(props) {
|
|||||||
|
|
||||||
export default NatGas;
|
export default NatGas;
|
||||||
|
|
||||||
function getOptions(period, trend) {
|
function getOptions(period, trendArr) {
|
||||||
if (trend[period].length === 0) return null;
|
if (trendArr[0][period].length === 0 || trendArr[1][period].length === 0)
|
||||||
|
return null;
|
||||||
// export default function getOptions(seriesData, name) {
|
// export default function getOptions(seriesData, name) {
|
||||||
const today = new Date();
|
const today = new Date();
|
||||||
const currentYear = today.getFullYear();
|
const currentYear = today.getFullYear();
|
||||||
@@ -185,21 +226,38 @@ function getOptions(period, trend) {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
series: {
|
series: [
|
||||||
data: trend[period].map((item) =>
|
{
|
||||||
item != null ? (+item).toFixed(2) : null
|
data: trendArr[0][period].map((item) =>
|
||||||
),
|
item != null ? (+item).toFixed(2) : null
|
||||||
type: "line",
|
),
|
||||||
symbol: "circle",
|
type: "line",
|
||||||
symbolSize: 6,
|
symbol: "circle",
|
||||||
areaStyle: {
|
symbolSize: 6,
|
||||||
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
|
areaStyle: {
|
||||||
{ offset: 0, color: colors[0] + "40" },
|
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
|
||||||
{ offset: 0.5, color: colors[0] + "20" },
|
{ offset: 0, color: colors[0] + "40" },
|
||||||
{ offset: 1, color: colors[0] + "00" },
|
{ offset: 0.5, color: colors[0] + "20" },
|
||||||
]),
|
{ offset: 1, color: colors[0] + "00" },
|
||||||
|
]),
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
{
|
||||||
|
data: trendArr[1][period].map((item) =>
|
||||||
|
item != null ? (+item).toFixed(2) : null
|
||||||
|
),
|
||||||
|
type: "line",
|
||||||
|
symbol: "circle",
|
||||||
|
symbolSize: 6,
|
||||||
|
areaStyle: {
|
||||||
|
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
|
||||||
|
{ offset: 0, color: colors[1] + "40" },
|
||||||
|
{ offset: 0.5, color: colors[1] + "20" },
|
||||||
|
{ offset: 1, color: colors[1] + "00" },
|
||||||
|
]),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
// series: seriesData.map((arr, index) => ({
|
// series: seriesData.map((arr, index) => ({
|
||||||
// name: index + 1 + '#' + name,
|
// name: index + 1 + '#' + name,
|
||||||
// data: arr,
|
// data: arr,
|
||||||
|
|||||||
@@ -6,17 +6,37 @@ import { useState } from "react";
|
|||||||
import * as echarts from "echarts";
|
import * as echarts from "echarts";
|
||||||
import dayjs from "dayjs";
|
import dayjs from "dayjs";
|
||||||
|
|
||||||
|
function getTimeStr(period) {
|
||||||
|
return {
|
||||||
|
日:
|
||||||
|
dayjs().format("YYYY.MM.DD") +
|
||||||
|
" 7点 - " +
|
||||||
|
dayjs().add(1, "d").format("YYYY.MM.DD") +
|
||||||
|
" 7点",
|
||||||
|
年:
|
||||||
|
dayjs().subtract(1, "year").endOf("year").format("YYYY.MM.") +
|
||||||
|
"29 - " +
|
||||||
|
dayjs().endOf("year").format("YYYY.MM.") +
|
||||||
|
"28",
|
||||||
|
周:
|
||||||
|
dayjs().subtract(7, "day").format("YYYY.MM.DD") +
|
||||||
|
" - " +
|
||||||
|
dayjs().subtract(1, "day").format("YYYY.MM.DD"),
|
||||||
|
月:
|
||||||
|
dayjs().subtract(1, "month").format("YYYY.MM.") +
|
||||||
|
"29 - " +
|
||||||
|
dayjs().format("YYYY.MM.") +
|
||||||
|
"28",
|
||||||
|
}[period];
|
||||||
|
}
|
||||||
|
|
||||||
function Oxygen(props) {
|
function Oxygen(props) {
|
||||||
const dayTrend = useSelector((state) => state.smoke?.dayTrend);
|
const dayTrend = useSelector((state) => state.smoke?.dayTrend);
|
||||||
const weekTrend = useSelector((state) => state.smoke?.weekTrend);
|
const weekTrend = useSelector((state) => state.smoke?.weekTrend);
|
||||||
const monthTrend = useSelector((state) => state.smoke?.monthTrend);
|
const monthTrend = useSelector((state) => state.smoke?.monthTrend);
|
||||||
const yearTrend = useSelector((state) => state.smoke?.yearTrend);
|
const yearTrend = useSelector((state) => state.smoke?.yearTrend);
|
||||||
const [period, setPeriod] = useState("日");
|
const [period, setPeriod] = useState("日");
|
||||||
const [timestr, setTimestr] = useState(
|
let timestr = getTimeStr(period);
|
||||||
dayjs().subtract(7, "day").format("YYYY.MM.DD") +
|
|
||||||
" - " +
|
|
||||||
dayjs().subtract(1, "day").format("YYYY.MM.DD")
|
|
||||||
);
|
|
||||||
|
|
||||||
const currentTrend =
|
const currentTrend =
|
||||||
period === "日"
|
period === "日"
|
||||||
@@ -33,35 +53,13 @@ function Oxygen(props) {
|
|||||||
|
|
||||||
function handleDateChange(value) {
|
function handleDateChange(value) {
|
||||||
setPeriod(value);
|
setPeriod(value);
|
||||||
setTimestr(
|
timestr = getTimeStr(value);
|
||||||
{
|
|
||||||
日:
|
|
||||||
dayjs().subtract(1, "day").format("YYYY.MM.DD") +
|
|
||||||
" 7点 - " +
|
|
||||||
dayjs().format("YYYY.MM.DD") +
|
|
||||||
" 7点",
|
|
||||||
年:
|
|
||||||
dayjs().subtract(1, "year").endOf("year").format("YYYY.MM.") +
|
|
||||||
"29 - " +
|
|
||||||
dayjs().endOf("year").format("YYYY.MM.") +
|
|
||||||
"28",
|
|
||||||
周:
|
|
||||||
dayjs().subtract(7, "day").format("YYYY.MM.DD") +
|
|
||||||
" - " +
|
|
||||||
dayjs().subtract(1, "day").format("YYYY.MM.DD"),
|
|
||||||
月:
|
|
||||||
dayjs().subtract(1, "month").format("YYYY.MM.") +
|
|
||||||
"29 - " +
|
|
||||||
dayjs().format("YYYY.MM.") +
|
|
||||||
"28",
|
|
||||||
}[value]
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
return (
|
return (
|
||||||
<GraphBase
|
<GraphBase
|
||||||
icon="smoke"
|
icon="smoke"
|
||||||
title="氧气含量"
|
title="氧气含量"
|
||||||
desc={`能耗趋势图 ${timestr}`}
|
desc={`烟气趋势图 ${timestr}`}
|
||||||
switchOptions={false}
|
switchOptions={false}
|
||||||
defaultSelect={period}
|
defaultSelect={period}
|
||||||
onSwitch={handleSwitch}
|
onSwitch={handleSwitch}
|
||||||
|
|||||||
@@ -6,6 +6,30 @@ import { useState } from "react";
|
|||||||
import * as echarts from "echarts";
|
import * as echarts from "echarts";
|
||||||
import dayjs from "dayjs";
|
import dayjs from "dayjs";
|
||||||
|
|
||||||
|
function getTimeStr(period) {
|
||||||
|
return {
|
||||||
|
日:
|
||||||
|
dayjs().format("YYYY.MM.DD") +
|
||||||
|
" 7点 - " +
|
||||||
|
dayjs().add(1, 'd').format("YYYY.MM.DD") +
|
||||||
|
" 7点",
|
||||||
|
年:
|
||||||
|
dayjs().subtract(1, "year").endOf("year").format("YYYY.MM.") +
|
||||||
|
"29 - " +
|
||||||
|
dayjs().endOf("year").format("YYYY.MM.") +
|
||||||
|
"28",
|
||||||
|
周:
|
||||||
|
dayjs().subtract(7, "day").format("YYYY.MM.DD") +
|
||||||
|
" - " +
|
||||||
|
dayjs().subtract(1, "day").format("YYYY.MM.DD"),
|
||||||
|
月:
|
||||||
|
dayjs().subtract(1, "month").format("YYYY.MM.") +
|
||||||
|
"29 - " +
|
||||||
|
dayjs().format("YYYY.MM.") +
|
||||||
|
"28",
|
||||||
|
}[period];
|
||||||
|
}
|
||||||
|
|
||||||
function SO2(props) {
|
function SO2(props) {
|
||||||
const dayTrend = useSelector((state) => state.smoke?.dayTrend);
|
const dayTrend = useSelector((state) => state.smoke?.dayTrend);
|
||||||
const weekTrend = useSelector((state) => state.smoke?.weekTrend);
|
const weekTrend = useSelector((state) => state.smoke?.weekTrend);
|
||||||
@@ -21,47 +45,22 @@ function SO2(props) {
|
|||||||
: period === "月"
|
: period === "月"
|
||||||
? monthTrend
|
? monthTrend
|
||||||
: yearTrend;
|
: yearTrend;
|
||||||
const [timestr, setTimestr] = useState(
|
|
||||||
dayjs().subtract(7, "day").format("YYYY.MM.DD") +
|
let timestr = getTimeStr(period);
|
||||||
" - " +
|
|
||||||
dayjs().subtract(1, "day").format("YYYY.MM.DD")
|
|
||||||
);
|
|
||||||
const options = getOptions("SO2_float", period, currentTrend);
|
const options = getOptions("SO2_float", period, currentTrend);
|
||||||
|
|
||||||
function handleSwitch(v) {}
|
function handleSwitch(v) {}
|
||||||
|
|
||||||
function handleDateChange(value) {
|
function handleDateChange(value) {
|
||||||
setPeriod(value);
|
setPeriod(value);
|
||||||
setTimestr(
|
timestr = getTimeStr(value);
|
||||||
{
|
|
||||||
日:
|
|
||||||
dayjs().subtract(1, "day").format("YYYY.MM.DD") +
|
|
||||||
" 7点 - " +
|
|
||||||
dayjs().format("YYYY.MM.DD") +
|
|
||||||
" 7点",
|
|
||||||
年:
|
|
||||||
dayjs().subtract(1, "year").endOf("year").format("YYYY.MM.") +
|
|
||||||
"29 - " +
|
|
||||||
dayjs().endOf("year").format("YYYY.MM.") +
|
|
||||||
"28",
|
|
||||||
周:
|
|
||||||
dayjs().subtract(7, "day").format("YYYY.MM.DD") +
|
|
||||||
" - " +
|
|
||||||
dayjs().subtract(1, "day").format("YYYY.MM.DD"),
|
|
||||||
月:
|
|
||||||
dayjs().subtract(1, "month").format("YYYY.MM.") +
|
|
||||||
"29 - " +
|
|
||||||
dayjs().format("YYYY.MM.") +
|
|
||||||
"28",
|
|
||||||
}[value]
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<GraphBase
|
<GraphBase
|
||||||
icon="smoke"
|
icon="smoke"
|
||||||
title="二氧化硫"
|
title="二氧化硫"
|
||||||
desc={`能耗趋势图 ${timestr}`}
|
desc={`烟气趋势图 ${timestr}`}
|
||||||
switchOptions={false}
|
switchOptions={false}
|
||||||
defaultSelect={period}
|
defaultSelect={period}
|
||||||
onSwitch={handleSwitch}
|
onSwitch={handleSwitch}
|
||||||
|
|||||||
@@ -1,21 +1,23 @@
|
|||||||
import cls from "./index.module.css";
|
import cls from "./index.module.css";
|
||||||
import GradientText from "../../../Common/GradientText";
|
import GradientText from "../../../Common/GradientText";
|
||||||
import { useSelector } from "react-redux";
|
import { useSelector } from "react-redux";
|
||||||
|
import eIcon1 from '../../../../assets/Icon/oilstation.png';
|
||||||
|
|
||||||
function SmokeHandle(props) {
|
function SmokeHandle(props) {
|
||||||
const smokeInfo = useSelector((state) => state.smoke?.info);
|
const smokeInfo = useSelector((state) => state.smoke?.info);
|
||||||
return (
|
return (
|
||||||
<div className={" " + cls.smoke} style={{ color: "#fff" }}>
|
<div className={" " + cls.smoke} style={{ color: "#fff" }}>
|
||||||
<span
|
<span
|
||||||
className={cls.shadowBorder}
|
className={cls.shadowBorder + " " + cls.border}
|
||||||
style={{
|
style={{
|
||||||
gridRow: "1 / 3",
|
gridRow: "1 / 3",
|
||||||
paddingTop: "96px",
|
paddingTop: "96px",
|
||||||
paddingLeft: "32px",
|
|
||||||
userSelect: "none",
|
userSelect: "none",
|
||||||
|
textAlign: "center",
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<GradientText text="烟气处理" />
|
<img src={eIcon1} width={32} alt="eIcon1" />
|
||||||
|
<GradientText text={"\u2002\u2002烟气处理"} />
|
||||||
</span>
|
</span>
|
||||||
<span
|
<span
|
||||||
className={cls.shadowBorder + " " + cls.infoText}
|
className={cls.shadowBorder + " " + cls.infoText}
|
||||||
@@ -32,13 +34,13 @@ function SmokeHandle(props) {
|
|||||||
{(+smokeInfo?.NOX_float)?.toFixed(2) || 0}
|
{(+smokeInfo?.NOX_float)?.toFixed(2) || 0}
|
||||||
</span>
|
</span>
|
||||||
</span>
|
</span>
|
||||||
<span className={cls.shadowBorder + " " + cls.infoText}>
|
<span className={cls.shadowBorder + " " + cls.infoText + " " + cls.border}>
|
||||||
<span style={{ lineHeight: 1.5 }}>二氧化硫浓度 mg/m³</span>
|
<span style={{ lineHeight: 1.5 }}>二氧化硫浓度 mg/m³</span>
|
||||||
<span style={{ lineHeight: 1.5 }}>
|
<span style={{ lineHeight: 1.5 }}>
|
||||||
{(+smokeInfo?.SO2_float)?.toFixed(2) || 0}
|
{(+smokeInfo?.SO2_float)?.toFixed(2) || 0}
|
||||||
</span>
|
</span>
|
||||||
</span>
|
</span>
|
||||||
<span className={cls.shadowBorder + " " + cls.infoText}>
|
<span className={cls.shadowBorder + " " + cls.infoText + " " + cls.border}>
|
||||||
<span style={{ lineHeight: 1.5 }}>颗粒物浓度 mg/m³</span>
|
<span style={{ lineHeight: 1.5 }}>颗粒物浓度 mg/m³</span>
|
||||||
<span style={{ lineHeight: 1.5 }}>
|
<span style={{ lineHeight: 1.5 }}>
|
||||||
{(+smokeInfo?.dust_float)?.toFixed(2) || 0}
|
{(+smokeInfo?.dust_float)?.toFixed(2) || 0}
|
||||||
|
|||||||
@@ -3,7 +3,8 @@
|
|||||||
gap: 6px;
|
gap: 6px;
|
||||||
grid-template-columns: 187px 347px 347px;
|
grid-template-columns: 187px 347px 347px;
|
||||||
/* grid-template-rows: 60px 60px; */
|
/* grid-template-rows: 60px 60px; */
|
||||||
grid-template-rows: 129px 129px;
|
/* grid-template-rows: 129px 129px; */
|
||||||
|
grid-template-rows: auto;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -13,6 +14,29 @@
|
|||||||
padding: 4px;
|
padding: 4px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.shadowBorder.border {
|
||||||
|
position: relative;
|
||||||
|
border-bottom: 2px solid #00fff7;
|
||||||
|
}
|
||||||
|
|
||||||
|
.shadowBorder.border::before,
|
||||||
|
.shadowBorder.border::after {
|
||||||
|
content: "";
|
||||||
|
position: absolute;
|
||||||
|
bottom: 0;
|
||||||
|
display: inline-block;
|
||||||
|
height: 100%;
|
||||||
|
width: 2px;
|
||||||
|
background: linear-gradient(to top, #00fff7, #00fff708, transparent);
|
||||||
|
}
|
||||||
|
|
||||||
|
.shadowBorder.border::before {
|
||||||
|
left: 0;
|
||||||
|
}
|
||||||
|
.shadowBorder.border::after {
|
||||||
|
right: 0;
|
||||||
|
}
|
||||||
|
|
||||||
.infoText {
|
.infoText {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
font-size: 24px;
|
font-size: 24px;
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import Item2 from './RightTable';
|
import Item2 from './RightTable';
|
||||||
import Item1 from '../../../Common/TimeFireDir';
|
// import Item1 from '../../../Common/TimeFireDir';
|
||||||
|
import Item1 from '../../../Common/VideoMonitor';
|
||||||
|
|
||||||
import cls from './index.module.scss';
|
import cls from './index.module.scss';
|
||||||
|
|
||||||
|
|||||||
@@ -17,6 +17,10 @@ export default function useSlider(defaultSize) {
|
|||||||
|
|
||||||
const v = (value / 100).toFixed(2);
|
const v = (value / 100).toFixed(2);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
document.documentElement.style.setProperty('--scale', v);
|
||||||
|
}, [v])
|
||||||
|
|
||||||
const styles = {
|
const styles = {
|
||||||
transform: `scale(${v})`,
|
transform: `scale(${v})`,
|
||||||
// transform: `scale(${v * 24 / 33}, ${v})`,
|
// transform: `scale(${v * 24 / 33}, ${v})`,
|
||||||
|
|||||||
@@ -37,19 +37,22 @@ function EnergyAnalysis(props) {
|
|||||||
<NatGas />
|
<NatGas />
|
||||||
</div>
|
</div>
|
||||||
<div style={{ gridRow: 3 }}>
|
<div style={{ gridRow: 3 }}>
|
||||||
<Gas />
|
{/* <Gas /> */}
|
||||||
|
<ElecCost />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className={cls.vvgrid + " col-4"}>
|
<div className={cls.vvgrid + " col-4"}>
|
||||||
<div className=" electronic">
|
<div className=" electronic">
|
||||||
<Energy />
|
<Energy key="2" page={2} />
|
||||||
</div>
|
</div>
|
||||||
<div className=" gas">
|
<div className=" gas">
|
||||||
<SmokeHandle />
|
<Energy key="1" page={1} />
|
||||||
|
{/* <SmokeHandle /> */}
|
||||||
</div>
|
</div>
|
||||||
<div style={{ height: "100%" }}>
|
<div style={{ height: "100%" }}>
|
||||||
<ElecCost />
|
{/* <ElecCost /> */}
|
||||||
|
<SmokeHandle />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -27,10 +27,18 @@
|
|||||||
gap: 24px;
|
gap: 24px;
|
||||||
grid-template-rows: 128px 389px 389px;
|
grid-template-rows: 128px 389px 389px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.vvgrid {
|
.vvgrid {
|
||||||
display: grid;
|
display: flex;
|
||||||
gap: 24px;
|
flex-direction: column;
|
||||||
grid-template-rows: 258px 258px 389px;
|
gap: 32px;
|
||||||
|
/* display: grid;
|
||||||
|
gap: 32px;
|
||||||
|
grid-template-rows: 280px 280px 410px; */
|
||||||
|
}
|
||||||
|
|
||||||
|
.vvgrid > div {
|
||||||
|
flex: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
.shadowBorder {
|
.shadowBorder {
|
||||||
|
|||||||
@@ -13,6 +13,9 @@ import QualityCheckRight from "../../components/Modules/QualityCheck/RightSide";
|
|||||||
import { useSelector } from "react-redux";
|
import { useSelector } from "react-redux";
|
||||||
import { useEffect, useRef } from "react";
|
import { useEffect, useRef } from "react";
|
||||||
import useRefresh from "../../hooks/useRefresh";
|
import useRefresh from "../../hooks/useRefresh";
|
||||||
|
import TimeFireDir from "../../components/Common/TimeFireDir";
|
||||||
|
|
||||||
|
import WarnAlertList from "../../components/Common/WarnAlert/ListContainer";
|
||||||
|
|
||||||
export default function Home({ active }) {
|
export default function Home({ active }) {
|
||||||
useRefresh(true);
|
useRefresh(true);
|
||||||
@@ -33,8 +36,22 @@ export default function Home({ active }) {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="Main">
|
<div className="Main">
|
||||||
|
{active == "窑炉总览" && (
|
||||||
|
<div
|
||||||
|
style={{
|
||||||
|
position: "fixed",
|
||||||
|
top: "210px",
|
||||||
|
left: "50%",
|
||||||
|
transform: "translateX(-40%)",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<TimeFireDir />
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
{active != "窑炉总览" && <div className="bgDitu"></div>}
|
{active != "窑炉总览" && <div className="bgDitu"></div>}
|
||||||
{active == "窑炉总览" && <div className="bgOverview"></div>}
|
{active == "窑炉总览" && (
|
||||||
|
<div className="bgOverview" id="bgOverview"></div>
|
||||||
|
)}
|
||||||
<AnimatePresence mode="wait">
|
<AnimatePresence mode="wait">
|
||||||
<div
|
<div
|
||||||
className="left-side"
|
className="left-side"
|
||||||
@@ -54,6 +71,9 @@ export default function Home({ active }) {
|
|||||||
<div className="Center">
|
<div className="Center">
|
||||||
{active == "窑炉总览" && (
|
{active == "窑炉总览" && (
|
||||||
<>
|
<>
|
||||||
|
<div id="alarm-list-container">
|
||||||
|
<WarnAlertList />
|
||||||
|
</div>
|
||||||
<AnimatePresence>
|
<AnimatePresence>
|
||||||
<motion.div
|
<motion.div
|
||||||
key="center-top"
|
key="center-top"
|
||||||
@@ -103,38 +123,6 @@ export default function Home({ active }) {
|
|||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* {fireDir && fireDir == "东火" && (
|
|
||||||
<video
|
|
||||||
src="/video/fire_little_top.webm"
|
|
||||||
muted
|
|
||||||
autoPlay
|
|
||||||
loop
|
|
||||||
width={4200}
|
|
||||||
style={{
|
|
||||||
position: "absolute",
|
|
||||||
top: "-160px",
|
|
||||||
left: "-910px",
|
|
||||||
zIndex: -1,
|
|
||||||
}}
|
|
||||||
></video>
|
|
||||||
)}
|
|
||||||
|
|
||||||
{fireDir && fireDir == "西火" && (
|
|
||||||
<video
|
|
||||||
src="/video/fire_little_down.webm"
|
|
||||||
muted
|
|
||||||
autoPlay
|
|
||||||
loop
|
|
||||||
width={4200}
|
|
||||||
style={{
|
|
||||||
position: "absolute",
|
|
||||||
top: "-180px",
|
|
||||||
left: "-910px",
|
|
||||||
zIndex: -1,
|
|
||||||
}}
|
|
||||||
></video>
|
|
||||||
)} */}
|
|
||||||
|
|
||||||
<div key="bottom-bar" className="Button">
|
<div key="bottom-bar" className="Button">
|
||||||
<BottomBar />
|
<BottomBar />
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
30
src/store/features/alarmSlice.js
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
import { createSlice } from "@reduxjs/toolkit";
|
||||||
|
|
||||||
|
export const initialState = {
|
||||||
|
list: [],
|
||||||
|
};
|
||||||
|
|
||||||
|
const alarmSlice = createSlice({
|
||||||
|
name: "alarm",
|
||||||
|
initialState,
|
||||||
|
reducers: {
|
||||||
|
setList(state, action) {
|
||||||
|
// action.payload 是 { 'A1_1_1': 'detail' } 的结构
|
||||||
|
console.log("[alarm store] setting list ---> ", action);
|
||||||
|
const rawData = action.payload;
|
||||||
|
const list = [];
|
||||||
|
Object.entries(rawData).forEach(([key, value]) => {
|
||||||
|
const n = [key, value];
|
||||||
|
list.push({
|
||||||
|
id: key,
|
||||||
|
title: n[0],
|
||||||
|
content: n[1],
|
||||||
|
});
|
||||||
|
});
|
||||||
|
state.list = list;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
export default alarmSlice.reducer;
|
||||||
|
export const { setList } = alarmSlice.actions;
|
||||||
@@ -14,9 +14,12 @@ import annealFanFrequenceReducer from "./features/annealFanFrequenceSlice";
|
|||||||
import annealFanInfoReducer from "./features/annealFanInfoSlice";
|
import annealFanInfoReducer from "./features/annealFanInfoSlice";
|
||||||
import cuttingReducer from "./features/cuttingSlice";
|
import cuttingReducer from "./features/cuttingSlice";
|
||||||
import smokeReducer from "./features/smokeSlice";
|
import smokeReducer from "./features/smokeSlice";
|
||||||
|
import alarmSlice from "./features/alarmSlice";
|
||||||
|
|
||||||
export const store = configureStore({
|
export const store = configureStore({
|
||||||
reducer: {
|
reducer: {
|
||||||
|
// 报警信息
|
||||||
|
alarm: alarmSlice,
|
||||||
// 窑炉信息
|
// 窑炉信息
|
||||||
kiln: kilnReducer,
|
kiln: kilnReducer,
|
||||||
// 投料机信息
|
// 投料机信息
|
||||||
|
|||||||
@@ -1,8 +1,7 @@
|
|||||||
import { store } from "../store";
|
import { store } from "../store";
|
||||||
import { MessageItem } from "./checkTypeHelper";
|
|
||||||
|
|
||||||
export default function handler(msg: MessageEvent) {
|
export default function handler(msg) {
|
||||||
let serializedData: MessageItem | null = null;
|
let serializedData = null;
|
||||||
try {
|
try {
|
||||||
serializedData = JSON.parse(msg.data);
|
serializedData = JSON.parse(msg.data);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
@@ -1,26 +0,0 @@
|
|||||||
type CheckTypeItem = {
|
|
||||||
checkDiscard?: boolean;
|
|
||||||
checkType: string;
|
|
||||||
checkNum: number;
|
|
||||||
ip?: string;
|
|
||||||
israDefectType?: string;
|
|
||||||
israSeriousGrade?: string;
|
|
||||||
};
|
|
||||||
|
|
||||||
type ProductLineItem = {
|
|
||||||
name: string;
|
|
||||||
sum: number;
|
|
||||||
data: CheckTypeItem[];
|
|
||||||
};
|
|
||||||
|
|
||||||
export type MessageItem = {
|
|
||||||
type: string;
|
|
||||||
name: string;
|
|
||||||
detData: {
|
|
||||||
checkType: string[];
|
|
||||||
dayStatistic?: ProductLineItem[];
|
|
||||||
weekStatistic?: ProductLineItem[];
|
|
||||||
monthStatistic?: ProductLineItem[];
|
|
||||||
yearStatistic?: ProductLineItem[];
|
|
||||||
};
|
|
||||||
};
|
|
||||||
@@ -1,30 +1,14 @@
|
|||||||
import { store } from "../store";
|
import { store } from "../store";
|
||||||
type TableDataType = {
|
|
||||||
name: "table";
|
|
||||||
type: "cutting";
|
|
||||||
data: any[];
|
|
||||||
};
|
|
||||||
type ChartDataType = {
|
|
||||||
name: "chart";
|
|
||||||
type: "cutting";
|
|
||||||
nightPushData: any[];
|
|
||||||
dayPushData: any[];
|
|
||||||
allPushData: any[];
|
|
||||||
dateType: "day" | "week" | "month" | "year";
|
|
||||||
};
|
|
||||||
|
|
||||||
export default function handler(msg: MessageEvent) {
|
export default function handler(msg) {
|
||||||
let serializedData: TableDataType | ChartDataType | null = null;
|
let serializedData = null;
|
||||||
try {
|
try {
|
||||||
serializedData = JSON.parse(msg.data);
|
serializedData = JSON.parse(msg.data);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.log("[*] websocket: [unable to serialize] ---> ", msg);
|
console.log("[*] websocket: [unable to serialize] ---> ", msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log("[CUTTING DATA] ---> ", serializedData);
|
|
||||||
|
|
||||||
if (serializedData == null) return;
|
if (serializedData == null) return;
|
||||||
|
|
||||||
switch (serializedData.name) {
|
switch (serializedData.name) {
|
||||||
case "table":
|
case "table":
|
||||||
store.dispatch({
|
store.dispatch({
|
||||||
@@ -1,13 +1,18 @@
|
|||||||
import { store } from "../store";
|
import { store } from "../store";
|
||||||
|
import { setList } from "../store/features/alarmSlice";
|
||||||
|
|
||||||
export default function handler(msg: MessageEvent) {
|
export default function handler(msg) {
|
||||||
let serializedData: { type: string; data: any } | null = null;
|
let serializedData = null;
|
||||||
try {
|
try {
|
||||||
serializedData = JSON.parse(msg.data);
|
serializedData = JSON.parse(msg.data);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.log("[*] websocket: [unable to serialize] ---> ", msg);
|
console.log("[*] websocket: [unable to serialize] ---> ", msg);
|
||||||
}
|
}
|
||||||
switch (serializedData?.type) {
|
switch (serializedData?.type) {
|
||||||
|
case "alarmList": {
|
||||||
|
store.dispatch(setList(serializedData.data));
|
||||||
|
break;
|
||||||
|
}
|
||||||
case "KilnInfo": {
|
case "KilnInfo": {
|
||||||
store.dispatch({
|
store.dispatch({
|
||||||
type: "kiln/setKilnInfo",
|
type: "kiln/setKilnInfo",
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
import { store } from "../store";
|
import { store } from "../store";
|
||||||
|
|
||||||
export default function handler(msg: MessageEvent) {
|
export default function handler(msg) {
|
||||||
let serializedData: { type: string; data: any } | null = null;
|
let serializedData = null;
|
||||||
try {
|
try {
|
||||||
serializedData = JSON.parse(msg.data);
|
serializedData = JSON.parse(msg.data);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
@@ -88,9 +88,6 @@ export function getOptions(period, source, trend, options = {}) {
|
|||||||
color: "#213259a0",
|
color: "#213259a0",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
// interval: 10,
|
|
||||||
// min: 0,
|
|
||||||
// max: 100,
|
|
||||||
},
|
},
|
||||||
series: [
|
series: [
|
||||||
{
|
{
|
||||||
@@ -123,7 +120,6 @@ export function getOptions(period, source, trend, options = {}) {
|
|||||||
type: "shadow",
|
type: "shadow",
|
||||||
},
|
},
|
||||||
className: "xc-chart-tooltip",
|
className: "xc-chart-tooltip",
|
||||||
// backgroundColor: ''
|
|
||||||
},
|
},
|
||||||
...options,
|
...options,
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -9,28 +9,22 @@ import smokeHandler from "./smoke";
|
|||||||
* new XClient('ws://192.168.1.12:8081/xc-screen/websocket/xc001', 'DCS')
|
* new XClient('ws://192.168.1.12:8081/xc-screen/websocket/xc001', 'DCS')
|
||||||
*/
|
*/
|
||||||
class XClient {
|
class XClient {
|
||||||
url: string;
|
// url;
|
||||||
name: string;
|
// name;
|
||||||
ws: WebSocket;
|
// ws;
|
||||||
timeout: number = 1000 * 5;
|
// timeout = 1000 * 5;
|
||||||
heartbeatDelay: number = 1000 * 60 * 3;
|
// heartbeatDelay = 1000 * 60 * 3;
|
||||||
reconnectCount: number = 0;
|
// reconnectCount = 0;
|
||||||
onmessage: (msg: MessageEvent) => void;
|
// onmessage = (msg) => console.log(msg);
|
||||||
hb: number = 0;
|
// hb = 0;
|
||||||
|
|
||||||
constructor(
|
constructor(config, onmessage = (msg) => console.log(msg)) {
|
||||||
config: {
|
|
||||||
url: string;
|
|
||||||
name: string;
|
|
||||||
timeout?: number;
|
|
||||||
reconnectCount?: number;
|
|
||||||
},
|
|
||||||
onmessage: (msg: MessageEvent) => void
|
|
||||||
) {
|
|
||||||
this.url = config.url;
|
this.url = config.url;
|
||||||
this.name = config.name;
|
this.name = config.name;
|
||||||
this.ws = new WebSocket(config.url);
|
this.ws = new WebSocket(config.url);
|
||||||
this.timeout = config.timeout || 1000 * 5;
|
this.timeout = config.timeout || 1000 * 5;
|
||||||
|
this.heartbeatDelay = 1000 * 60 * 3;
|
||||||
|
this.reconnectCount = 0;
|
||||||
|
|
||||||
this.ws.onopen = () => {
|
this.ws.onopen = () => {
|
||||||
console.log(`[*] ${this.name} 初始化连接成功`);
|
console.log(`[*] ${this.name} 初始化连接成功`);
|
||||||
@@ -113,6 +107,7 @@ const newUser = uuidv4();
|
|||||||
new XClient(
|
new XClient(
|
||||||
{
|
{
|
||||||
url: "ws://10.70.180.10:8081/xc-screen/websocket/xc001" + newUser,
|
url: "ws://10.70.180.10:8081/xc-screen/websocket/xc001" + newUser,
|
||||||
|
// url: "ws://127.0.0.1:9800/alarm?user=" + newUser,
|
||||||
name: "DCS_DATA",
|
name: "DCS_DATA",
|
||||||
// "ws://m306416y13.yicp.fun:35441/xc-screen/websocket/xc001",
|
// "ws://m306416y13.yicp.fun:35441/xc-screen/websocket/xc001",
|
||||||
// "ws://192.168.1.114:8081/xc-screen/websocket/xc001",
|
// "ws://192.168.1.114:8081/xc-screen/websocket/xc001",
|
||||||
@@ -164,7 +159,7 @@ new XClient(
|
|||||||
smokeHandler
|
smokeHandler
|
||||||
);
|
);
|
||||||
|
|
||||||
export function randomInt(min: number, max: number, includeMax = false) {
|
export function randomInt(min, max, includeMax = false) {
|
||||||
let Fn = includeMax ? Math.ceil : Math.floor;
|
let Fn = includeMax ? Math.ceil : Math.floor;
|
||||||
let num = Fn(Math.random() * max);
|
let num = Fn(Math.random() * max);
|
||||||
while (num < min) {
|
while (num < min) {
|
||||||
@@ -1,4 +0,0 @@
|
|||||||
export type MessageEvent = {
|
|
||||||
type: string;
|
|
||||||
data: any;
|
|
||||||
}
|
|
||||||
32
src/utils/smoke.js
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
import { store } from "../store";
|
||||||
|
|
||||||
|
export default function handler(msg) {
|
||||||
|
let serializedData = null;
|
||||||
|
try {
|
||||||
|
serializedData = JSON.parse(msg.data);
|
||||||
|
} catch (error) {
|
||||||
|
console.log("[*] websocket: [unable to serialize] ---> ", msg);
|
||||||
|
}
|
||||||
|
switch (serializedData?.type) {
|
||||||
|
case "exhaustGas": {
|
||||||
|
store.dispatch({
|
||||||
|
type: "smoke/setInfo",
|
||||||
|
payload: serializedData.realtime,
|
||||||
|
});
|
||||||
|
store.dispatch({
|
||||||
|
type: "smoke/setTrend",
|
||||||
|
payload: {
|
||||||
|
dayTrend: serializedData.dayTrend,
|
||||||
|
weekTrend: serializedData.weekTrend,
|
||||||
|
monthTrend: serializedData.monthTrend,
|
||||||
|
yearTrend: serializedData.yearTrend,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
default: {
|
||||||
|
console.log("websocket message: [unknown] ---> ", msg.data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,114 +0,0 @@
|
|||||||
import { store } from "../store";
|
|
||||||
|
|
||||||
type SmokeMessageItem = {
|
|
||||||
type: string;
|
|
||||||
realtime: {
|
|
||||||
SO2_float: number;
|
|
||||||
NOX_float: number;
|
|
||||||
O2_float: number;
|
|
||||||
dust_float: number;
|
|
||||||
};
|
|
||||||
dayTrend: {
|
|
||||||
SO2_float: Array<{
|
|
||||||
time: string;
|
|
||||||
value: number;
|
|
||||||
}>;
|
|
||||||
NOX_float: Array<{
|
|
||||||
time: string;
|
|
||||||
value: number;
|
|
||||||
}>;
|
|
||||||
O2_float: Array<{
|
|
||||||
time: string;
|
|
||||||
value: number;
|
|
||||||
}>;
|
|
||||||
dust_float: Array<{
|
|
||||||
time: string;
|
|
||||||
value: number;
|
|
||||||
}>;
|
|
||||||
};
|
|
||||||
weekTrend: {
|
|
||||||
SO2_float: Array<{
|
|
||||||
time: string;
|
|
||||||
value: number;
|
|
||||||
}>;
|
|
||||||
NOX_float: Array<{
|
|
||||||
time: string;
|
|
||||||
value: number;
|
|
||||||
}>;
|
|
||||||
O2_float: Array<{
|
|
||||||
time: string;
|
|
||||||
value: number;
|
|
||||||
}>;
|
|
||||||
dust_float: Array<{
|
|
||||||
time: string;
|
|
||||||
value: number;
|
|
||||||
}>;
|
|
||||||
};
|
|
||||||
monthTrend: {
|
|
||||||
SO2_float: Array<{
|
|
||||||
time: string;
|
|
||||||
value: number;
|
|
||||||
}>;
|
|
||||||
NOX_float: Array<{
|
|
||||||
time: string;
|
|
||||||
value: number;
|
|
||||||
}>;
|
|
||||||
O2_float: Array<{
|
|
||||||
time: string;
|
|
||||||
value: number;
|
|
||||||
}>;
|
|
||||||
dust_float: Array<{
|
|
||||||
time: string;
|
|
||||||
value: number;
|
|
||||||
}>;
|
|
||||||
};
|
|
||||||
yearTrend: {
|
|
||||||
SO2_float: Array<{
|
|
||||||
time: string;
|
|
||||||
value: number;
|
|
||||||
}>;
|
|
||||||
NOX_float: Array<{
|
|
||||||
time: string;
|
|
||||||
value: number;
|
|
||||||
}>;
|
|
||||||
O2_float: Array<{
|
|
||||||
time: string;
|
|
||||||
value: number;
|
|
||||||
}>;
|
|
||||||
dust_float: Array<{
|
|
||||||
time: string;
|
|
||||||
value: number;
|
|
||||||
}>;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
export default function handler(msg: MessageEvent) {
|
|
||||||
let serializedData: SmokeMessageItem | null = null;
|
|
||||||
try {
|
|
||||||
serializedData = JSON.parse(msg.data);
|
|
||||||
} catch (error) {
|
|
||||||
console.log("[*] websocket: [unable to serialize] ---> ", msg);
|
|
||||||
}
|
|
||||||
switch (serializedData?.type) {
|
|
||||||
case "exhaustGas": {
|
|
||||||
store.dispatch({
|
|
||||||
type: "smoke/setInfo",
|
|
||||||
payload: serializedData.realtime,
|
|
||||||
});
|
|
||||||
store.dispatch({
|
|
||||||
type: "smoke/setTrend",
|
|
||||||
payload: {
|
|
||||||
dayTrend: serializedData.dayTrend,
|
|
||||||
weekTrend: serializedData.weekTrend,
|
|
||||||
monthTrend: serializedData.monthTrend,
|
|
||||||
yearTrend: serializedData.yearTrend,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
default: {
|
|
||||||
console.log("websocket message: [unknown] ---> ", msg.data);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
109
tsconfig.json
@@ -1,109 +0,0 @@
|
|||||||
{
|
|
||||||
"compilerOptions": {
|
|
||||||
/* Visit https://aka.ms/tsconfig to read more about this file */
|
|
||||||
|
|
||||||
/* Projects */
|
|
||||||
// "incremental": true, /* Save .tsbuildinfo files to allow for incremental compilation of projects. */
|
|
||||||
// "composite": true, /* Enable constraints that allow a TypeScript project to be used with project references. */
|
|
||||||
// "tsBuildInfoFile": "./.tsbuildinfo", /* Specify the path to .tsbuildinfo incremental compilation file. */
|
|
||||||
// "disableSourceOfProjectReferenceRedirect": true, /* Disable preferring source files instead of declaration files when referencing composite projects. */
|
|
||||||
// "disableSolutionSearching": true, /* Opt a project out of multi-project reference checking when editing. */
|
|
||||||
// "disableReferencedProjectLoad": true, /* Reduce the number of projects loaded automatically by TypeScript. */
|
|
||||||
|
|
||||||
/* Language and Environment */
|
|
||||||
"target": "es2016", /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */
|
|
||||||
// "lib": [], /* Specify a set of bundled library declaration files that describe the target runtime environment. */
|
|
||||||
"jsx": "preserve", /* Specify what JSX code is generated. */
|
|
||||||
// "experimentalDecorators": true, /* Enable experimental support for legacy experimental decorators. */
|
|
||||||
// "emitDecoratorMetadata": true, /* Emit design-type metadata for decorated declarations in source files. */
|
|
||||||
// "jsxFactory": "", /* Specify the JSX factory function used when targeting React JSX emit, e.g. 'React.createElement' or 'h'. */
|
|
||||||
// "jsxFragmentFactory": "", /* Specify the JSX Fragment reference used for fragments when targeting React JSX emit e.g. 'React.Fragment' or 'Fragment'. */
|
|
||||||
// "jsxImportSource": "", /* Specify module specifier used to import the JSX factory functions when using 'jsx: react-jsx*'. */
|
|
||||||
// "reactNamespace": "", /* Specify the object invoked for 'createElement'. This only applies when targeting 'react' JSX emit. */
|
|
||||||
// "noLib": true, /* Disable including any library files, including the default lib.d.ts. */
|
|
||||||
// "useDefineForClassFields": true, /* Emit ECMAScript-standard-compliant class fields. */
|
|
||||||
// "moduleDetection": "auto", /* Control what method is used to detect module-format JS files. */
|
|
||||||
|
|
||||||
/* Modules */
|
|
||||||
"module": "commonjs", /* Specify what module code is generated. */
|
|
||||||
// "rootDir": "./", /* Specify the root folder within your source files. */
|
|
||||||
// "moduleResolution": "node10", /* Specify how TypeScript looks up a file from a given module specifier. */
|
|
||||||
// "baseUrl": "./", /* Specify the base directory to resolve non-relative module names. */
|
|
||||||
// "paths": {}, /* Specify a set of entries that re-map imports to additional lookup locations. */
|
|
||||||
// "rootDirs": [], /* Allow multiple folders to be treated as one when resolving modules. */
|
|
||||||
// "typeRoots": [], /* Specify multiple folders that act like './node_modules/@types'. */
|
|
||||||
// "types": [], /* Specify type package names to be included without being referenced in a source file. */
|
|
||||||
// "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */
|
|
||||||
// "moduleSuffixes": [], /* List of file name suffixes to search when resolving a module. */
|
|
||||||
// "allowImportingTsExtensions": true, /* Allow imports to include TypeScript file extensions. Requires '--moduleResolution bundler' and either '--noEmit' or '--emitDeclarationOnly' to be set. */
|
|
||||||
// "resolvePackageJsonExports": true, /* Use the package.json 'exports' field when resolving package imports. */
|
|
||||||
// "resolvePackageJsonImports": true, /* Use the package.json 'imports' field when resolving imports. */
|
|
||||||
// "customConditions": [], /* Conditions to set in addition to the resolver-specific defaults when resolving imports. */
|
|
||||||
// "resolveJsonModule": true, /* Enable importing .json files. */
|
|
||||||
// "allowArbitraryExtensions": true, /* Enable importing files with any extension, provided a declaration file is present. */
|
|
||||||
// "noResolve": true, /* Disallow 'import's, 'require's or '<reference>'s from expanding the number of files TypeScript should add to a project. */
|
|
||||||
|
|
||||||
/* JavaScript Support */
|
|
||||||
"allowJs": true, /* Allow JavaScript files to be a part of your program. Use the 'checkJS' option to get errors from these files. */
|
|
||||||
// "checkJs": true, /* Enable error reporting in type-checked JavaScript files. */
|
|
||||||
// "maxNodeModuleJsDepth": 1, /* Specify the maximum folder depth used for checking JavaScript files from 'node_modules'. Only applicable with 'allowJs'. */
|
|
||||||
|
|
||||||
/* Emit */
|
|
||||||
// "declaration": true, /* Generate .d.ts files from TypeScript and JavaScript files in your project. */
|
|
||||||
// "declarationMap": true, /* Create sourcemaps for d.ts files. */
|
|
||||||
// "emitDeclarationOnly": true, /* Only output d.ts files and not JavaScript files. */
|
|
||||||
// "sourceMap": true, /* Create source map files for emitted JavaScript files. */
|
|
||||||
// "inlineSourceMap": true, /* Include sourcemap files inside the emitted JavaScript. */
|
|
||||||
// "outFile": "./", /* Specify a file that bundles all outputs into one JavaScript file. If 'declaration' is true, also designates a file that bundles all .d.ts output. */
|
|
||||||
// "outDir": "./", /* Specify an output folder for all emitted files. */
|
|
||||||
// "removeComments": true, /* Disable emitting comments. */
|
|
||||||
// "noEmit": true, /* Disable emitting files from a compilation. */
|
|
||||||
// "importHelpers": true, /* Allow importing helper functions from tslib once per project, instead of including them per-file. */
|
|
||||||
// "importsNotUsedAsValues": "remove", /* Specify emit/checking behavior for imports that are only used for types. */
|
|
||||||
// "downlevelIteration": true, /* Emit more compliant, but verbose and less performant JavaScript for iteration. */
|
|
||||||
// "sourceRoot": "", /* Specify the root path for debuggers to find the reference source code. */
|
|
||||||
// "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */
|
|
||||||
// "inlineSources": true, /* Include source code in the sourcemaps inside the emitted JavaScript. */
|
|
||||||
// "emitBOM": true, /* Emit a UTF-8 Byte Order Mark (BOM) in the beginning of output files. */
|
|
||||||
// "newLine": "crlf", /* Set the newline character for emitting files. */
|
|
||||||
// "stripInternal": true, /* Disable emitting declarations that have '@internal' in their JSDoc comments. */
|
|
||||||
// "noEmitHelpers": true, /* Disable generating custom helper functions like '__extends' in compiled output. */
|
|
||||||
// "noEmitOnError": true, /* Disable emitting files if any type checking errors are reported. */
|
|
||||||
// "preserveConstEnums": true, /* Disable erasing 'const enum' declarations in generated code. */
|
|
||||||
// "declarationDir": "./", /* Specify the output directory for generated declaration files. */
|
|
||||||
// "preserveValueImports": true, /* Preserve unused imported values in the JavaScript output that would otherwise be removed. */
|
|
||||||
|
|
||||||
/* Interop Constraints */
|
|
||||||
// "isolatedModules": true, /* Ensure that each file can be safely transpiled without relying on other imports. */
|
|
||||||
// "verbatimModuleSyntax": true, /* Do not transform or elide any imports or exports not marked as type-only, ensuring they are written in the output file's format based on the 'module' setting. */
|
|
||||||
// "allowSyntheticDefaultImports": true, /* Allow 'import x from y' when a module doesn't have a default export. */
|
|
||||||
"esModuleInterop": true, /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables 'allowSyntheticDefaultImports' for type compatibility. */
|
|
||||||
// "preserveSymlinks": true, /* Disable resolving symlinks to their realpath. This correlates to the same flag in node. */
|
|
||||||
"forceConsistentCasingInFileNames": true, /* Ensure that casing is correct in imports. */
|
|
||||||
|
|
||||||
/* Type Checking */
|
|
||||||
"strict": true, /* Enable all strict type-checking options. */
|
|
||||||
// "noImplicitAny": true, /* Enable error reporting for expressions and declarations with an implied 'any' type. */
|
|
||||||
// "strictNullChecks": true, /* When type checking, take into account 'null' and 'undefined'. */
|
|
||||||
// "strictFunctionTypes": true, /* When assigning functions, check to ensure parameters and the return values are subtype-compatible. */
|
|
||||||
// "strictBindCallApply": true, /* Check that the arguments for 'bind', 'call', and 'apply' methods match the original function. */
|
|
||||||
// "strictPropertyInitialization": true, /* Check for class properties that are declared but not set in the constructor. */
|
|
||||||
// "noImplicitThis": true, /* Enable error reporting when 'this' is given the type 'any'. */
|
|
||||||
// "useUnknownInCatchVariables": true, /* Default catch clause variables as 'unknown' instead of 'any'. */
|
|
||||||
// "alwaysStrict": true, /* Ensure 'use strict' is always emitted. */
|
|
||||||
// "noUnusedLocals": true, /* Enable error reporting when local variables aren't read. */
|
|
||||||
// "noUnusedParameters": true, /* Raise an error when a function parameter isn't read. */
|
|
||||||
// "exactOptionalPropertyTypes": true, /* Interpret optional property types as written, rather than adding 'undefined'. */
|
|
||||||
// "noImplicitReturns": true, /* Enable error reporting for codepaths that do not explicitly return in a function. */
|
|
||||||
// "noFallthroughCasesInSwitch": true, /* Enable error reporting for fallthrough cases in switch statements. */
|
|
||||||
// "noUncheckedIndexedAccess": true, /* Add 'undefined' to a type when accessed using an index. */
|
|
||||||
// "noImplicitOverride": true, /* Ensure overriding members in derived classes are marked with an override modifier. */
|
|
||||||
// "noPropertyAccessFromIndexSignature": true, /* Enforces using indexed accessors for keys declared using an indexed type. */
|
|
||||||
// "allowUnusedLabels": true, /* Disable error reporting for unused labels. */
|
|
||||||
// "allowUnreachableCode": true, /* Disable error reporting for unreachable code. */
|
|
||||||
|
|
||||||
/* Completeness */
|
|
||||||
// "skipDefaultLibCheck": true, /* Skip type checking .d.ts files that are included with TypeScript. */
|
|
||||||
"skipLibCheck": true /* Skip type checking all .d.ts files. */
|
|
||||||
}
|
|
||||||
}
|
|
||||||
120
websocket/fakedata/alarmList.js
Normal file
@@ -0,0 +1,120 @@
|
|||||||
|
const total = `AN_1_1,助燃风故障报警
|
||||||
|
AN_1_2,压延机冷却风故障报警
|
||||||
|
AN_1_3,L吊墙冷却风机故障报警
|
||||||
|
AN_1_4,熔化带及部分澄清部冷却风机故障报警
|
||||||
|
AN_2_1,澄清带池壁冷却风机故障报警
|
||||||
|
AN_2_2,钢碴碴冷却风机故障报警
|
||||||
|
AN_2_3,支通路拐角冷却风机报警
|
||||||
|
AN_2_4,吊墙吊钩砖结构温升报警
|
||||||
|
AN_3_1,深层水包冷却水温升报警
|
||||||
|
AN_3_2,深层水包冷却水断水报警
|
||||||
|
AN_3_3,卡脖吊平冷却水断水报警
|
||||||
|
AN_3_4,卡脖吊平喧冷却水温升报警
|
||||||
|
AN_4_1,液面计冷却水断水报警
|
||||||
|
AN_4_2,液面计冷却水温升报警
|
||||||
|
AN_4_3,循环水入口压力低报警
|
||||||
|
AN_4_4,天然气压力高低报警
|
||||||
|
AN_5_1,助燃风风压低报警
|
||||||
|
AN_5_2,净化压缩气压力低报警
|
||||||
|
AN_5_3,普通压缩空气压力高低报警
|
||||||
|
AN_5_4,焦炉煤气气压力高低报警
|
||||||
|
AN_6_1,换向过程故障报警
|
||||||
|
AN_6_2,空交机换向不到位报警
|
||||||
|
AN_6_3,投料机故障报警
|
||||||
|
AN_6_4,备用
|
||||||
|
AN_7_1,1#压延机冷却水断水报警
|
||||||
|
AN_7_2,1#压延机冷却水温升报警
|
||||||
|
AN_7_3,1#过渡辊台冷却水断水报警
|
||||||
|
AN_7_4,1过渡辊台冷却水温升报警
|
||||||
|
AN_8_1,1#线唇砖冷却水断水报警
|
||||||
|
AN_8_2,1#线唇砖冷却水温升报警
|
||||||
|
AN_8_3,1#退火窑A区风机报警
|
||||||
|
AN_8_4,1#退火窑B区风机报警
|
||||||
|
AN_9_1,1#退火窑c区风机报警
|
||||||
|
AN_9_2,1#退火窑Ret1区风机报警
|
||||||
|
AN_9_3,1#退火窑Ret2区风机报警
|
||||||
|
AN_9_4,1#退火窑F1区风机报警
|
||||||
|
AN_10_1,1#退火窑F2区风机报警
|
||||||
|
AN_10_2,1#主传动报警
|
||||||
|
AN_10_3,1#压延机报警
|
||||||
|
AN_10_4,备用
|
||||||
|
AN_11_1,2#压延机冷却水断水报警
|
||||||
|
AN_11_2,2#压延机冷却水温升报警
|
||||||
|
AN_11_3,2#过渡辊台冷却水断水报警
|
||||||
|
AN_11_4,2#过渡辊台冷却水温升报警
|
||||||
|
AN_12_1,2#线唇砖冷却水断水报警
|
||||||
|
AN_12_2,2#线唇砖冷却水温升报警
|
||||||
|
AN_12_3,2#退火窑A区风机报警
|
||||||
|
AN_12_4,2#退火窑B区风机报警
|
||||||
|
AN_13_1,2#退火窑c区风机报警
|
||||||
|
AN_13_2,2#退火窑Ret1区风机报警
|
||||||
|
AN_13_3,2#退火窑Ret2区风机报警
|
||||||
|
AN_13_4,2#退火窑F1区风机报警
|
||||||
|
AN_14_1,2#退火窑F2区风机报警
|
||||||
|
AN_14_2,2#主传动报警
|
||||||
|
AN_14_3,2#压延机报警
|
||||||
|
AN_14_4,备用
|
||||||
|
AN_15_1,3#压延机冷却水断水报警
|
||||||
|
AN_15_2,3压延机冷却水温升报警
|
||||||
|
AN_15_3,3#过渡辊台冷却水断水报警
|
||||||
|
AN_15_4,3#过渡辊台冷却水温升报警
|
||||||
|
AN_16_1,3#线唇砖冷却水断水报警
|
||||||
|
AN_16_2,3#线唇砖冷却水温升报警
|
||||||
|
AN_16_3,3#退火窑A区风机报警
|
||||||
|
AN_16_4,3#退火窑B区风机报警
|
||||||
|
AN_17_1,3#退火窑c区风机报警
|
||||||
|
AN_17_2,3#退火窑Ret1区风机报警
|
||||||
|
AN_17_3,3#退火窑Ret2区风机报警
|
||||||
|
AN_17_4,3#退火窑F1区风机报警
|
||||||
|
AN_18_1,3#退火窑F2区风机报警
|
||||||
|
AN_18_2,3#主传动报警
|
||||||
|
AN_18_3,3#压延机报警
|
||||||
|
AN_18_4,备用
|
||||||
|
AN_19_1,4#压延机冷却水断水报警
|
||||||
|
AN_19_2,4压延机冷却水温升报警
|
||||||
|
AN_19_3,4#过渡辊台冷却水断水报警
|
||||||
|
AN_19_4,4#过渡辊台冷却水温升报警
|
||||||
|
AN_20_1,4#线唇砖冷却水断水报警
|
||||||
|
AN_20_2,4#线唇砖冷却水温升报警
|
||||||
|
AN_20_3,4#退火窑A区风机报警
|
||||||
|
AN_20_4,4#退火窑B区风机报警
|
||||||
|
AN_21_1,4#退火窑c区风机报警
|
||||||
|
AN_21_2,4#退火窑Ret1区风机报警
|
||||||
|
AN_21_3,4#退火窑Ret2区风机报警
|
||||||
|
AN_21_4,4#退火窑F1区风机报警
|
||||||
|
AN_22_1,4#退火窑F2区风机报警
|
||||||
|
AN_22_2,4#主传动报警
|
||||||
|
AN_22_3,4#压延机报警
|
||||||
|
AN_23_1,5#压延机冷却水断水报警
|
||||||
|
AN_23_2,5#压延机冷却水温升报警
|
||||||
|
AN_23_3,5#过渡辊台冷却水断水报警
|
||||||
|
AN_23_4,5#过渡台冷却水温升报警
|
||||||
|
AN_24_1,5#线唇砖冷却水断水报警
|
||||||
|
AN_24_2,5#线唇砖冷却水温升报警
|
||||||
|
AN_24_3,5#退火窑A区风机报警
|
||||||
|
AN_24_4,5#退火窑B区风机报警
|
||||||
|
AN_25_1,5#退火窑c区风机报警
|
||||||
|
AN_25_2,5#退火窑Ret1区风机报警
|
||||||
|
AN_25_3,5#退火窑Ret2区风机报警
|
||||||
|
AN_25_4,5#退火窑F1区风机报警
|
||||||
|
AN_26_1,5#退火窑F2区风机报警
|
||||||
|
AN_26_2,5#主传动报警
|
||||||
|
AN_26_3,5#压延机报警
|
||||||
|
`;
|
||||||
|
|
||||||
|
// const totalAlarmList = total.split("\n");
|
||||||
|
const getRandomAlarmList = function (num) {
|
||||||
|
const totalAlarmList = total.split("\n");
|
||||||
|
let alarmList = [];
|
||||||
|
for (let i = 0; i < num; i++) {
|
||||||
|
let index = Math.floor(Math.random() * totalAlarmList.length);
|
||||||
|
const chosen = totalAlarmList[index];
|
||||||
|
totalAlarmList.splice(index, 1);
|
||||||
|
alarmList.push(chosen);
|
||||||
|
}
|
||||||
|
return alarmList;
|
||||||
|
};
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
getRandomAlarmList,
|
||||||
|
};
|
||||||
@@ -1,18 +0,0 @@
|
|||||||
import utils from '../utils';
|
|
||||||
|
|
||||||
function genKilnInfo() {
|
|
||||||
return {
|
|
||||||
kilnPressure: utils.rand(0, 100) + 'Kpa',
|
|
||||||
waterTemp: utils.rand(0, 100) + '℃',
|
|
||||||
waterFlow: utils.rand(30, 90) + 'm³/h',
|
|
||||||
waterPressure: utils.rand(10, 50) + 'Kpa',
|
|
||||||
windPressure: utils.rand(10, 30) + 'Kpa',
|
|
||||||
gasPressure: utils.rand(10, 30) + 'Kpa',
|
|
||||||
// 碹顶加权温度
|
|
||||||
topTemp: utils.rand(30, 60) + '℃',
|
|
||||||
// 融化加权温度
|
|
||||||
meltTemp: utils.rand(100, 200) + '℃',
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
export default genKilnInfo;
|
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
// 天然气
|
|
||||||
import utils from '../utils';
|
|
||||||
|
|
||||||
function getNavGasInfo(type: 'history' | 'realtime') {
|
|
||||||
switch (type) {
|
|
||||||
case 'history':
|
|
||||||
break;
|
|
||||||
case 'realtime':
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export default getNavGasInfo;
|
|
||||||
44
websocket/package-lock.json
generated
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
{
|
||||||
|
"name": "ws-server",
|
||||||
|
"version": "0.0.1",
|
||||||
|
"lockfileVersion": 2,
|
||||||
|
"requires": true,
|
||||||
|
"packages": {
|
||||||
|
"": {
|
||||||
|
"name": "ws-server",
|
||||||
|
"version": "0.0.1",
|
||||||
|
"license": "ISC",
|
||||||
|
"dependencies": {
|
||||||
|
"ws": "^8.16.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/ws": {
|
||||||
|
"version": "8.16.0",
|
||||||
|
"resolved": "https://registry.npmmirror.com/ws/-/ws-8.16.0.tgz",
|
||||||
|
"integrity": "sha512-HS0c//TP7Ina87TfiPUz1rQzMhHrl/SG2guqRcTOIUYD2q8uhUdNHZYJUaQ8aTGPzCh+c6oawMKW35nFl1dxyQ==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=10.0.0"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"bufferutil": "^4.0.1",
|
||||||
|
"utf-8-validate": ">=5.0.2"
|
||||||
|
},
|
||||||
|
"peerDependenciesMeta": {
|
||||||
|
"bufferutil": {
|
||||||
|
"optional": true
|
||||||
|
},
|
||||||
|
"utf-8-validate": {
|
||||||
|
"optional": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"ws": {
|
||||||
|
"version": "8.16.0",
|
||||||
|
"resolved": "https://registry.npmmirror.com/ws/-/ws-8.16.0.tgz",
|
||||||
|
"integrity": "sha512-HS0c//TP7Ina87TfiPUz1rQzMhHrl/SG2guqRcTOIUYD2q8uhUdNHZYJUaQ8aTGPzCh+c6oawMKW35nFl1dxyQ==",
|
||||||
|
"requires": {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
15
websocket/package.json
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
{
|
||||||
|
"name": "ws-server",
|
||||||
|
"version": "0.0.1",
|
||||||
|
"description": "a simple dev ws-server",
|
||||||
|
"main": "server.js",
|
||||||
|
"scripts": {
|
||||||
|
"test": "echo \"Error: no test specified\" && exit 1",
|
||||||
|
"start": "node server.js"
|
||||||
|
},
|
||||||
|
"author": "",
|
||||||
|
"license": "ISC",
|
||||||
|
"dependencies": {
|
||||||
|
"ws": "^8.16.0"
|
||||||
|
}
|
||||||
|
}
|
||||||
105
websocket/server copy.js
Normal file
@@ -0,0 +1,105 @@
|
|||||||
|
import { WebSocket, WebSocketServer } from "ws";
|
||||||
|
import template from "./template.json";
|
||||||
|
import utils from "./utils";
|
||||||
|
|
||||||
|
const wss = new WebSocketServer({ port: 9800 });
|
||||||
|
const frequency = 10; // seconds
|
||||||
|
const frequency1 = 1200; // seconds
|
||||||
|
wss.on("connection", function (ws, req) {
|
||||||
|
// console.log("ws", ws);
|
||||||
|
console.log(
|
||||||
|
"Client in: ",
|
||||||
|
req.socket.remoteAddress,
|
||||||
|
"current users:",
|
||||||
|
wss.clients.size
|
||||||
|
);
|
||||||
|
// ws.on("error", console.error);
|
||||||
|
// ws.emit("message", "connected");
|
||||||
|
ws.on("open", function () {
|
||||||
|
console.log("connected");
|
||||||
|
ws.send("connected");
|
||||||
|
});
|
||||||
|
ws.on("message", function (msg) {
|
||||||
|
console.log("message from client", msg);
|
||||||
|
ws.send("echo " + msg.toString());
|
||||||
|
});
|
||||||
|
ws.on("error", console.error);
|
||||||
|
|
||||||
|
const timer = setInterval(() => {
|
||||||
|
sendMsg(ws, "kiln-info"); // 窑炉信息
|
||||||
|
sendMsg(ws, "energy-cost"); // 运行状态
|
||||||
|
sendMsg(ws, "run-state"); // 运行状态
|
||||||
|
sendMsg(ws, "realtime");
|
||||||
|
sendMsg(ws, "his-trend");
|
||||||
|
// sendMsg(ws, 'gas');
|
||||||
|
// sendMsg(ws, 'kiln-top');
|
||||||
|
// sendMsg(ws, 'kiln-bottom');
|
||||||
|
}, frequency * 1000);
|
||||||
|
|
||||||
|
const timer1 = setInterval(() => {
|
||||||
|
// sendMsg(ws, 'run-state'); // 运行状态
|
||||||
|
}, frequency1 * 1000);
|
||||||
|
|
||||||
|
ws.on("close", function () {
|
||||||
|
console.log("停止监听");
|
||||||
|
clearInterval(timer);
|
||||||
|
clearInterval(timer1);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
function sendMsg(ws, type) {
|
||||||
|
let data = {};
|
||||||
|
switch (type) {
|
||||||
|
case "kiln-info":
|
||||||
|
for (const key in template.kilnInfo) {
|
||||||
|
data[key] = utils.getRandom(template.kilnInfo[key]);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case "energy-cost":
|
||||||
|
for (const key in template.energyCost) {
|
||||||
|
data[key] = utils.getRandom(template.energyCost[key]);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case "run-state":
|
||||||
|
data = template.runState;
|
||||||
|
data.fireDirection =
|
||||||
|
Math.floor(Math.random() * 10) % 2 === 0 ? "南火" : "北火";
|
||||||
|
break;
|
||||||
|
case "realtime":
|
||||||
|
/** 天然气 实时流量 */
|
||||||
|
data.gasii = template.realtime.gasii.map((v) => utils.getRandom(v));
|
||||||
|
/** 助燃风 实时流量 */
|
||||||
|
data.wind = template.realtime.wind.map((v) => utils.getRandom(v));
|
||||||
|
break;
|
||||||
|
case "his-trend":
|
||||||
|
const hisTrend = {
|
||||||
|
gas: {},
|
||||||
|
wind: {},
|
||||||
|
};
|
||||||
|
Object.keys(template.hisTrend.gas).forEach((key) => {
|
||||||
|
hisTrend.gas[key] = template.hisTrend.gas[key].map((v) =>
|
||||||
|
utils.getRandom(v)
|
||||||
|
);
|
||||||
|
});
|
||||||
|
Object.keys(template.hisTrend.wind).forEach((key) => {
|
||||||
|
hisTrend.wind[key] = template.hisTrend.wind[key].map((v) =>
|
||||||
|
utils.getRandom(v)
|
||||||
|
);
|
||||||
|
});
|
||||||
|
data = hisTrend;
|
||||||
|
break;
|
||||||
|
case "gas":
|
||||||
|
// data = template.gas;
|
||||||
|
break;
|
||||||
|
case "kiln-top":
|
||||||
|
// data = template.kilnTop;
|
||||||
|
break;
|
||||||
|
case "kiln-bottom":
|
||||||
|
// data = template.kilnBottom;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
// data = 'You are connected!';
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
ws.send(JSON.stringify({ type, data }));
|
||||||
|
}
|
||||||
95
websocket/server.js
Normal file
@@ -0,0 +1,95 @@
|
|||||||
|
const { WebSocket } = require("ws");
|
||||||
|
const { getRandomAlarmList } = require("./fakedata/alarmList");
|
||||||
|
|
||||||
|
const wss = new WebSocket.Server({ port: 9800 });
|
||||||
|
console.log('[websocket] server created');
|
||||||
|
|
||||||
|
wss.on("connection", function (ws, req) {
|
||||||
|
console.log(
|
||||||
|
"[用户连接]: ",
|
||||||
|
req.socket.remoteAddress,
|
||||||
|
"当前总用户数:",
|
||||||
|
wss.clients.size
|
||||||
|
);
|
||||||
|
ws.on("open", function () {
|
||||||
|
console.log('[websocket] opened');
|
||||||
|
ws.send("connected");
|
||||||
|
});
|
||||||
|
ws.on("message", function (msg) {
|
||||||
|
console.log("[==>]", msg);
|
||||||
|
});
|
||||||
|
ws.on("error", console.error);
|
||||||
|
|
||||||
|
const timer = setInterval(() => {
|
||||||
|
sendMsg(ws, "alarmList"); // 报警信息
|
||||||
|
}, 10 * 1000);
|
||||||
|
|
||||||
|
ws.on("close", function () {
|
||||||
|
console.log("停止监听");
|
||||||
|
clearInterval(timer);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
function sendMsg(ws, type) {
|
||||||
|
let data = {};
|
||||||
|
switch (type) {
|
||||||
|
case "alarmList":
|
||||||
|
const alarmList = getRandomAlarmList(Math.floor(Math.random() * 10) + 1);
|
||||||
|
alarmList.forEach((str) => {
|
||||||
|
const [code, detail] = str.split(",");
|
||||||
|
data[code] = detail;
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
case "kiln-info":
|
||||||
|
for (const key in template.kilnInfo) {
|
||||||
|
data[key] = utils.getRandom(template.kilnInfo[key]);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case "energy-cost":
|
||||||
|
for (const key in template.energyCost) {
|
||||||
|
data[key] = utils.getRandom(template.energyCost[key]);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case "run-state":
|
||||||
|
data = template.runState;
|
||||||
|
data.fireDirection =
|
||||||
|
Math.floor(Math.random() * 10) % 2 === 0 ? "南火" : "北火";
|
||||||
|
break;
|
||||||
|
case "realtime":
|
||||||
|
/** 天然气 实时流量 */
|
||||||
|
data.gasii = template.realtime.gasii.map((v) => utils.getRandom(v));
|
||||||
|
/** 助燃风 实时流量 */
|
||||||
|
data.wind = template.realtime.wind.map((v) => utils.getRandom(v));
|
||||||
|
break;
|
||||||
|
case "his-trend":
|
||||||
|
const hisTrend = {
|
||||||
|
gas: {},
|
||||||
|
wind: {},
|
||||||
|
};
|
||||||
|
Object.keys(template.hisTrend.gas).forEach((key) => {
|
||||||
|
hisTrend.gas[key] = template.hisTrend.gas[key].map((v) =>
|
||||||
|
utils.getRandom(v)
|
||||||
|
);
|
||||||
|
});
|
||||||
|
Object.keys(template.hisTrend.wind).forEach((key) => {
|
||||||
|
hisTrend.wind[key] = template.hisTrend.wind[key].map((v) =>
|
||||||
|
utils.getRandom(v)
|
||||||
|
);
|
||||||
|
});
|
||||||
|
data = hisTrend;
|
||||||
|
break;
|
||||||
|
case "gas":
|
||||||
|
// data = template.gas;
|
||||||
|
break;
|
||||||
|
case "kiln-top":
|
||||||
|
// data = template.kilnTop;
|
||||||
|
break;
|
||||||
|
case "kiln-bottom":
|
||||||
|
// data = template.kilnBottom;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
// data = 'You are connected!';
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
ws.send(JSON.stringify({ type, data }));
|
||||||
|
}
|
||||||
@@ -1,133 +0,0 @@
|
|||||||
import { WebSocket, WebSocketServer } from 'ws';
|
|
||||||
import template from './template.json';
|
|
||||||
import utils from './utils';
|
|
||||||
|
|
||||||
const wss = new WebSocketServer({ port: 9800 });
|
|
||||||
const frequency = 10; // seconds
|
|
||||||
const frequency1 = 1200; // seconds
|
|
||||||
wss.on('connection', function (ws, req) {
|
|
||||||
// console.log("ws", ws);
|
|
||||||
console.log(
|
|
||||||
'Client in: ',
|
|
||||||
req.socket.remoteAddress,
|
|
||||||
'current users:',
|
|
||||||
wss.clients.size,
|
|
||||||
);
|
|
||||||
// ws.on("error", console.error);
|
|
||||||
// ws.emit("message", "connected");
|
|
||||||
ws.on('open', function () {
|
|
||||||
console.log('connected');
|
|
||||||
ws.send('connected');
|
|
||||||
});
|
|
||||||
ws.on('message', function (msg) {
|
|
||||||
console.log('message from client', msg);
|
|
||||||
ws.send('echo ' + msg.toString());
|
|
||||||
});
|
|
||||||
ws.on('error', console.error);
|
|
||||||
|
|
||||||
const timer = setInterval(() => {
|
|
||||||
sendMsg(ws, 'kiln-info'); // 窑炉信息
|
|
||||||
sendMsg(ws, 'energy-cost'); // 运行状态
|
|
||||||
sendMsg(ws, 'run-state'); // 运行状态
|
|
||||||
sendMsg(ws, 'realtime');
|
|
||||||
sendMsg(ws, 'his-trend');
|
|
||||||
// sendMsg(ws, 'gas');
|
|
||||||
// sendMsg(ws, 'kiln-top');
|
|
||||||
// sendMsg(ws, 'kiln-bottom');
|
|
||||||
}, frequency * 1000);
|
|
||||||
|
|
||||||
const timer1 = setInterval(() => {
|
|
||||||
// sendMsg(ws, 'run-state'); // 运行状态
|
|
||||||
}, frequency1 * 1000);
|
|
||||||
|
|
||||||
ws.on('close', function () {
|
|
||||||
console.log('停止监听');
|
|
||||||
clearInterval(timer);
|
|
||||||
clearInterval(timer1);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
type MsgType =
|
|
||||||
| 'kiln-info'
|
|
||||||
| 'run-state'
|
|
||||||
| 'energy-cost'
|
|
||||||
| 'realtime'
|
|
||||||
| 'his-trend'
|
|
||||||
| 'fan'
|
|
||||||
| 'gas'
|
|
||||||
| 'kiln-top'
|
|
||||||
| 'kiln-bottom';
|
|
||||||
|
|
||||||
type ResponseData = {
|
|
||||||
[key: string]: string | string[];
|
|
||||||
};
|
|
||||||
|
|
||||||
type ResponseDataComplex = {
|
|
||||||
[key: string]: ResponseData;
|
|
||||||
};
|
|
||||||
|
|
||||||
function sendMsg(ws: WebSocket, type: MsgType) {
|
|
||||||
let data: ResponseData | ResponseDataComplex = {};
|
|
||||||
switch (type) {
|
|
||||||
case 'kiln-info':
|
|
||||||
for (const key in template.kilnInfo) {
|
|
||||||
data[key] = utils.getRandom(
|
|
||||||
template.kilnInfo[key as keyof typeof template.kilnInfo],
|
|
||||||
);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 'energy-cost':
|
|
||||||
for (const key in template.energyCost) {
|
|
||||||
data[key] = utils.getRandom(
|
|
||||||
template.energyCost[key as keyof typeof template.energyCost],
|
|
||||||
);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 'run-state':
|
|
||||||
data = template.runState;
|
|
||||||
data.fireDirection =
|
|
||||||
Math.floor(Math.random() * 10) % 2 === 0 ? '南火' : '北火';
|
|
||||||
break;
|
|
||||||
case 'realtime':
|
|
||||||
/** 天然气 实时流量 */
|
|
||||||
data.gasii = template.realtime.gasii.map((v) => utils.getRandom(v));
|
|
||||||
/** 助燃风 实时流量 */
|
|
||||||
data.wind = template.realtime.wind.map((v) => utils.getRandom(v));
|
|
||||||
break;
|
|
||||||
case 'his-trend':
|
|
||||||
const hisTrend: {
|
|
||||||
gas: ResponseData;
|
|
||||||
wind: ResponseData;
|
|
||||||
} = {
|
|
||||||
gas: {},
|
|
||||||
wind: {},
|
|
||||||
};
|
|
||||||
Object.keys(template.hisTrend.gas).forEach((key) => {
|
|
||||||
hisTrend.gas[key] = template.hisTrend.gas[
|
|
||||||
key as keyof typeof template.hisTrend.gas
|
|
||||||
].map((v) => utils.getRandom(v));
|
|
||||||
});
|
|
||||||
Object.keys(template.hisTrend.wind).forEach((key) => {
|
|
||||||
hisTrend.wind[key] = template.hisTrend.wind[
|
|
||||||
key as keyof typeof template.hisTrend.wind
|
|
||||||
].map((v) => utils.getRandom(v));
|
|
||||||
});
|
|
||||||
data = hisTrend;
|
|
||||||
break;
|
|
||||||
case 'gas':
|
|
||||||
// data = template.gas;
|
|
||||||
break;
|
|
||||||
case 'kiln-top':
|
|
||||||
// data = template.kilnTop;
|
|
||||||
break;
|
|
||||||
case 'kiln-bottom':
|
|
||||||
// data = template.kilnBottom;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
// data = 'You are connected!';
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
// console.log("sendMsg: ", ws);
|
|
||||||
// ws.emit("message", JSON.stringify(data));
|
|
||||||
ws.send(JSON.stringify({ type, data }));
|
|
||||||
}
|
|
||||||
@@ -1,109 +0,0 @@
|
|||||||
{
|
|
||||||
"compilerOptions": {
|
|
||||||
/* Visit https://aka.ms/tsconfig to read more about this file */
|
|
||||||
|
|
||||||
/* Projects */
|
|
||||||
// "incremental": true, /* Save .tsbuildinfo files to allow for incremental compilation of projects. */
|
|
||||||
// "composite": true, /* Enable constraints that allow a TypeScript project to be used with project references. */
|
|
||||||
// "tsBuildInfoFile": "./.tsbuildinfo", /* Specify the path to .tsbuildinfo incremental compilation file. */
|
|
||||||
// "disableSourceOfProjectReferenceRedirect": true, /* Disable preferring source files instead of declaration files when referencing composite projects. */
|
|
||||||
// "disableSolutionSearching": true, /* Opt a project out of multi-project reference checking when editing. */
|
|
||||||
// "disableReferencedProjectLoad": true, /* Reduce the number of projects loaded automatically by TypeScript. */
|
|
||||||
|
|
||||||
/* Language and Environment */
|
|
||||||
"target": "es2016" /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */,
|
|
||||||
// "lib": [], /* Specify a set of bundled library declaration files that describe the target runtime environment. */
|
|
||||||
// "jsx": "preserve", /* Specify what JSX code is generated. */
|
|
||||||
// "experimentalDecorators": true, /* Enable experimental support for legacy experimental decorators. */
|
|
||||||
// "emitDecoratorMetadata": true, /* Emit design-type metadata for decorated declarations in source files. */
|
|
||||||
// "jsxFactory": "", /* Specify the JSX factory function used when targeting React JSX emit, e.g. 'React.createElement' or 'h'. */
|
|
||||||
// "jsxFragmentFactory": "", /* Specify the JSX Fragment reference used for fragments when targeting React JSX emit e.g. 'React.Fragment' or 'Fragment'. */
|
|
||||||
// "jsxImportSource": "", /* Specify module specifier used to import the JSX factory functions when using 'jsx: react-jsx*'. */
|
|
||||||
// "reactNamespace": "", /* Specify the object invoked for 'createElement'. This only applies when targeting 'react' JSX emit. */
|
|
||||||
// "noLib": true, /* Disable including any library files, including the default lib.d.ts. */
|
|
||||||
// "useDefineForClassFields": true, /* Emit ECMAScript-standard-compliant class fields. */
|
|
||||||
// "moduleDetection": "auto", /* Control what method is used to detect module-format JS files. */
|
|
||||||
|
|
||||||
/* Modules */
|
|
||||||
"module": "commonjs" /* Specify what module code is generated. */,
|
|
||||||
// "rootDir": "./", /* Specify the root folder within your source files. */
|
|
||||||
// "moduleResolution": "node10", /* Specify how TypeScript looks up a file from a given module specifier. */
|
|
||||||
// "baseUrl": "./", /* Specify the base directory to resolve non-relative module names. */
|
|
||||||
// "paths": {}, /* Specify a set of entries that re-map imports to additional lookup locations. */
|
|
||||||
// "rootDirs": [], /* Allow multiple folders to be treated as one when resolving modules. */
|
|
||||||
// "typeRoots": [], /* Specify multiple folders that act like './node_modules/@types'. */
|
|
||||||
// "types": [], /* Specify type package names to be included without being referenced in a source file. */
|
|
||||||
// "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */
|
|
||||||
// "moduleSuffixes": [], /* List of file name suffixes to search when resolving a module. */
|
|
||||||
// "allowImportingTsExtensions": true, /* Allow imports to include TypeScript file extensions. Requires '--moduleResolution bundler' and either '--noEmit' or '--emitDeclarationOnly' to be set. */
|
|
||||||
// "resolvePackageJsonExports": true, /* Use the package.json 'exports' field when resolving package imports. */
|
|
||||||
// "resolvePackageJsonImports": true, /* Use the package.json 'imports' field when resolving imports. */
|
|
||||||
// "customConditions": [], /* Conditions to set in addition to the resolver-specific defaults when resolving imports. */
|
|
||||||
"resolveJsonModule": true /* Enable importing .json files. */,
|
|
||||||
// "allowArbitraryExtensions": true, /* Enable importing files with any extension, provided a declaration file is present. */
|
|
||||||
// "noResolve": true, /* Disallow 'import's, 'require's or '<reference>'s from expanding the number of files TypeScript should add to a project. */
|
|
||||||
|
|
||||||
/* JavaScript Support */
|
|
||||||
// "allowJs": true, /* Allow JavaScript files to be a part of your program. Use the 'checkJS' option to get errors from these files. */
|
|
||||||
// "checkJs": true, /* Enable error reporting in type-checked JavaScript files. */
|
|
||||||
// "maxNodeModuleJsDepth": 1, /* Specify the maximum folder depth used for checking JavaScript files from 'node_modules'. Only applicable with 'allowJs'. */
|
|
||||||
|
|
||||||
/* Emit */
|
|
||||||
// "declaration": true, /* Generate .d.ts files from TypeScript and JavaScript files in your project. */
|
|
||||||
// "declarationMap": true, /* Create sourcemaps for d.ts files. */
|
|
||||||
// "emitDeclarationOnly": true, /* Only output d.ts files and not JavaScript files. */
|
|
||||||
// "sourceMap": true, /* Create source map files for emitted JavaScript files. */
|
|
||||||
// "inlineSourceMap": true, /* Include sourcemap files inside the emitted JavaScript. */
|
|
||||||
// "outFile": "./", /* Specify a file that bundles all outputs into one JavaScript file. If 'declaration' is true, also designates a file that bundles all .d.ts output. */
|
|
||||||
// "outDir": "./", /* Specify an output folder for all emitted files. */
|
|
||||||
// "removeComments": true, /* Disable emitting comments. */
|
|
||||||
// "noEmit": true, /* Disable emitting files from a compilation. */
|
|
||||||
// "importHelpers": true, /* Allow importing helper functions from tslib once per project, instead of including them per-file. */
|
|
||||||
// "importsNotUsedAsValues": "remove", /* Specify emit/checking behavior for imports that are only used for types. */
|
|
||||||
// "downlevelIteration": true, /* Emit more compliant, but verbose and less performant JavaScript for iteration. */
|
|
||||||
// "sourceRoot": "", /* Specify the root path for debuggers to find the reference source code. */
|
|
||||||
// "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */
|
|
||||||
// "inlineSources": true, /* Include source code in the sourcemaps inside the emitted JavaScript. */
|
|
||||||
// "emitBOM": true, /* Emit a UTF-8 Byte Order Mark (BOM) in the beginning of output files. */
|
|
||||||
// "newLine": "crlf", /* Set the newline character for emitting files. */
|
|
||||||
// "stripInternal": true, /* Disable emitting declarations that have '@internal' in their JSDoc comments. */
|
|
||||||
// "noEmitHelpers": true, /* Disable generating custom helper functions like '__extends' in compiled output. */
|
|
||||||
// "noEmitOnError": true, /* Disable emitting files if any type checking errors are reported. */
|
|
||||||
// "preserveConstEnums": true, /* Disable erasing 'const enum' declarations in generated code. */
|
|
||||||
// "declarationDir": "./", /* Specify the output directory for generated declaration files. */
|
|
||||||
// "preserveValueImports": true, /* Preserve unused imported values in the JavaScript output that would otherwise be removed. */
|
|
||||||
|
|
||||||
/* Interop Constraints */
|
|
||||||
// "isolatedModules": true, /* Ensure that each file can be safely transpiled without relying on other imports. */
|
|
||||||
// "verbatimModuleSyntax": true, /* Do not transform or elide any imports or exports not marked as type-only, ensuring they are written in the output file's format based on the 'module' setting. */
|
|
||||||
// "allowSyntheticDefaultImports": true, /* Allow 'import x from y' when a module doesn't have a default export. */
|
|
||||||
"esModuleInterop": true /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables 'allowSyntheticDefaultImports' for type compatibility. */,
|
|
||||||
// "preserveSymlinks": true, /* Disable resolving symlinks to their realpath. This correlates to the same flag in node. */
|
|
||||||
"forceConsistentCasingInFileNames": true /* Ensure that casing is correct in imports. */,
|
|
||||||
|
|
||||||
/* Type Checking */
|
|
||||||
"strict": true /* Enable all strict type-checking options. */,
|
|
||||||
// "noImplicitAny": true, /* Enable error reporting for expressions and declarations with an implied 'any' type. */
|
|
||||||
// "strictNullChecks": true, /* When type checking, take into account 'null' and 'undefined'. */
|
|
||||||
// "strictFunctionTypes": true, /* When assigning functions, check to ensure parameters and the return values are subtype-compatible. */
|
|
||||||
// "strictBindCallApply": true, /* Check that the arguments for 'bind', 'call', and 'apply' methods match the original function. */
|
|
||||||
// "strictPropertyInitialization": true, /* Check for class properties that are declared but not set in the constructor. */
|
|
||||||
// "noImplicitThis": true, /* Enable error reporting when 'this' is given the type 'any'. */
|
|
||||||
// "useUnknownInCatchVariables": true, /* Default catch clause variables as 'unknown' instead of 'any'. */
|
|
||||||
// "alwaysStrict": true, /* Ensure 'use strict' is always emitted. */
|
|
||||||
// "noUnusedLocals": true, /* Enable error reporting when local variables aren't read. */
|
|
||||||
// "noUnusedParameters": true, /* Raise an error when a function parameter isn't read. */
|
|
||||||
// "exactOptionalPropertyTypes": true, /* Interpret optional property types as written, rather than adding 'undefined'. */
|
|
||||||
// "noImplicitReturns": true, /* Enable error reporting for codepaths that do not explicitly return in a function. */
|
|
||||||
// "noFallthroughCasesInSwitch": true, /* Enable error reporting for fallthrough cases in switch statements. */
|
|
||||||
// "noUncheckedIndexedAccess": true, /* Add 'undefined' to a type when accessed using an index. */
|
|
||||||
// "noImplicitOverride": true, /* Ensure overriding members in derived classes are marked with an override modifier. */
|
|
||||||
// "noPropertyAccessFromIndexSignature": true, /* Enforces using indexed accessors for keys declared using an indexed type. */
|
|
||||||
// "allowUnusedLabels": true, /* Disable error reporting for unused labels. */
|
|
||||||
// "allowUnreachableCode": true, /* Disable error reporting for unreachable code. */
|
|
||||||
|
|
||||||
/* Completeness */
|
|
||||||
// "skipDefaultLibCheck": true, /* Skip type checking .d.ts files that are included with TypeScript. */
|
|
||||||
"skipLibCheck": true /* Skip type checking all .d.ts files. */
|
|
||||||
}
|
|
||||||
}
|
|
||||||
49
websocket/utils/index.js
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
export default {
|
||||||
|
// 生成随机数
|
||||||
|
randomNum({ min, max }, isFloat = false) {
|
||||||
|
if (isFloat) return (Math.random() * (max - min) + min).toFixed(2);
|
||||||
|
return Math.floor(Math.random() * (max - min + 1) + min);
|
||||||
|
},
|
||||||
|
getMinmax(type) {
|
||||||
|
// : '*' | '.' | '+' | '$'
|
||||||
|
let min, max;
|
||||||
|
switch (type) {
|
||||||
|
case "*":
|
||||||
|
min = 30;
|
||||||
|
max = 150;
|
||||||
|
break;
|
||||||
|
case ".":
|
||||||
|
min = 60;
|
||||||
|
max = 200;
|
||||||
|
break;
|
||||||
|
case "+":
|
||||||
|
min = 20;
|
||||||
|
max = 70;
|
||||||
|
break;
|
||||||
|
case "$":
|
||||||
|
min = 1;
|
||||||
|
max = 100;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return { min, max };
|
||||||
|
},
|
||||||
|
getRandom(value) {
|
||||||
|
value = value.replace(
|
||||||
|
"***",
|
||||||
|
"" + this.randomNum({ ...this.getMinmax("*") })
|
||||||
|
);
|
||||||
|
value = value.replace(
|
||||||
|
"...",
|
||||||
|
"" + this.randomNum({ ...this.getMinmax(".") })
|
||||||
|
);
|
||||||
|
value = value.replace(
|
||||||
|
"+++",
|
||||||
|
"" + this.randomNum({ ...this.getMinmax("+") })
|
||||||
|
);
|
||||||
|
value = value.replace(
|
||||||
|
"$$$",
|
||||||
|
"" + this.randomNum({ ...this.getMinmax("$") }, true)
|
||||||
|
);
|
||||||
|
return value;
|
||||||
|
},
|
||||||
|
};
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
function rand(min: number, max: number) {
|
|
||||||
return Math.floor(Math.random() * (max - min + 1)) + min;
|
|
||||||
}
|
|
||||||
|
|
||||||
export default {
|
|
||||||
rand,
|
|
||||||
};
|
|
||||||
@@ -1,48 +0,0 @@
|
|||||||
export default {
|
|
||||||
// 生成随机数
|
|
||||||
randomNum({ min, max }: { min: number; max: number }, isFloat = false) {
|
|
||||||
if (isFloat) return (Math.random() * (max - min) + min).toFixed(2);
|
|
||||||
return Math.floor(Math.random() * (max - min + 1) + min);
|
|
||||||
},
|
|
||||||
getMinmax(type: '*' | '.' | '+' | '$') {
|
|
||||||
let min: number, max: number;
|
|
||||||
switch (type) {
|
|
||||||
case '*':
|
|
||||||
min = 30;
|
|
||||||
max = 150;
|
|
||||||
break;
|
|
||||||
case '.':
|
|
||||||
min = 60;
|
|
||||||
max = 200;
|
|
||||||
break;
|
|
||||||
case '+':
|
|
||||||
min = 20;
|
|
||||||
max = 70;
|
|
||||||
break;
|
|
||||||
case '$':
|
|
||||||
min = 1;
|
|
||||||
max = 100;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return { min, max };
|
|
||||||
},
|
|
||||||
getRandom(value: string) {
|
|
||||||
value = value.replace(
|
|
||||||
'***',
|
|
||||||
'' + this.randomNum({ ...this.getMinmax('*') }),
|
|
||||||
);
|
|
||||||
value = value.replace(
|
|
||||||
'...',
|
|
||||||
'' + this.randomNum({ ...this.getMinmax('.') }),
|
|
||||||
);
|
|
||||||
value = value.replace(
|
|
||||||
'+++',
|
|
||||||
'' + this.randomNum({ ...this.getMinmax('+') }),
|
|
||||||
);
|
|
||||||
value = value.replace(
|
|
||||||
'$$$',
|
|
||||||
'' + this.randomNum({ ...this.getMinmax('$') }, true),
|
|
||||||
);
|
|
||||||
return value;
|
|
||||||
},
|
|
||||||
};
|
|
||||||