commit
bff87fbcee
25357
package-lock.json
generated
25357
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@ -22,6 +22,7 @@
|
|||||||
"@types/node": "^16.11.56",
|
"@types/node": "^16.11.56",
|
||||||
"@types/react": "^18.0.17",
|
"@types/react": "^18.0.17",
|
||||||
"@types/react-dom": "^18.0.6",
|
"@types/react-dom": "^18.0.6",
|
||||||
|
"antd": "^5.22.2",
|
||||||
"axios": "^1.3.3",
|
"axios": "^1.3.3",
|
||||||
"babel-jest": "^27.4.2",
|
"babel-jest": "^27.4.2",
|
||||||
"babel-loader": "^8.2.3",
|
"babel-loader": "^8.2.3",
|
||||||
|
BIN
public/png/numberBox.png
Normal file
BIN
public/png/numberBox.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 16 KiB |
BIN
public/png/rect/ld_center_down.png
Normal file
BIN
public/png/rect/ld_center_down.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 33 KiB |
BIN
public/png/rect/ld_left_up_innerbox.png
Normal file
BIN
public/png/rect/ld_left_up_innerbox.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 113 KiB |
75
public/svg/topbackLD.svg
Normal file
75
public/svg/topbackLD.svg
Normal file
@ -0,0 +1,75 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<svg width="1920px" height="93.0031818px" viewBox="0 0 1920 93.0031818" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||||
|
<title>编组 11</title>
|
||||||
|
<defs>
|
||||||
|
<linearGradient x1="50%" y1="-2.22044605e-14%" x2="50%" y2="100%" id="linearGradient-1">
|
||||||
|
<stop stop-color="#081C43" stop-opacity="0" offset="0%"></stop>
|
||||||
|
<stop stop-color="#27778E" stop-opacity="0.205883769" offset="57.0640297%"></stop>
|
||||||
|
<stop stop-color="#37A5B4" stop-opacity="0.311188811" offset="100%"></stop>
|
||||||
|
</linearGradient>
|
||||||
|
<linearGradient x1="98.361014%" y1="49.8254916%" x2="-6.66133815e-14%" y2="49.7796521%" id="linearGradient-2">
|
||||||
|
<stop stop-color="#3797C6" stop-opacity="0.31441215" offset="0%"></stop>
|
||||||
|
<stop stop-color="#52FFF1" offset="100%"></stop>
|
||||||
|
</linearGradient>
|
||||||
|
<linearGradient x1="103.601203%" y1="50.6276601%" x2="-6.66133815e-14%" y2="49.5379248%" id="linearGradient-3">
|
||||||
|
<stop stop-color="#31A6AE" stop-opacity="0" offset="0%"></stop>
|
||||||
|
<stop stop-color="#31A6AE" offset="100%"></stop>
|
||||||
|
</linearGradient>
|
||||||
|
<linearGradient x1="98.361014%" y1="49.8437805%" x2="-6.66133815e-14%" y2="49.8027451%" id="linearGradient-4">
|
||||||
|
<stop stop-color="#3797C6" stop-opacity="0.31441215" offset="0%"></stop>
|
||||||
|
<stop stop-color="#52FFF1" offset="100%"></stop>
|
||||||
|
</linearGradient>
|
||||||
|
<linearGradient x1="103.601203%" y1="51.0279165%" x2="-6.66133815e-14%" y2="49.2432614%" id="linearGradient-5">
|
||||||
|
<stop stop-color="#3797C6" stop-opacity="0" offset="0%"></stop>
|
||||||
|
<stop stop-color="#31A6AE" offset="100%"></stop>
|
||||||
|
</linearGradient>
|
||||||
|
<linearGradient x1="103.601203%" y1="50.0057357%" x2="-6.66133815e-14%" y2="49.9957774%" id="linearGradient-6">
|
||||||
|
<stop stop-color="#31A6AE" offset="0%"></stop>
|
||||||
|
<stop stop-color="#3797C6" stop-opacity="0" offset="100%"></stop>
|
||||||
|
</linearGradient>
|
||||||
|
<linearGradient x1="103.601203%" y1="50.03033%" x2="-6.66133815e-14%" y2="49.9776715%" id="linearGradient-7">
|
||||||
|
<stop stop-color="#31A6AE" offset="0%"></stop>
|
||||||
|
<stop stop-color="#3797C6" stop-opacity="0" offset="100%"></stop>
|
||||||
|
</linearGradient>
|
||||||
|
</defs>
|
||||||
|
<g id="洛阳" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||||
|
<g id="编组-11">
|
||||||
|
<polygon id="路径-5" fill="url(#linearGradient-1)" points="1.90545852e-13 -4.50993001e-15 2.88853814e-14 31.7045455 82.7768328 31.7045455 120.694098 57.9834285 585.064327 57.9834285 633.594326 93 1284.71703 93 1333.41502 57.5262217 1517.36351 57.5262217 1554.66659 31.7045455 1866 31.7045455 1866 1.08915917e-12"></polygon>
|
||||||
|
<g id="编组-12">
|
||||||
|
<g id="编组-8" transform="translate(711.263222, 24.306818)"></g>
|
||||||
|
<g id="编组-4" transform="translate(0.750956, 31.704545)">
|
||||||
|
<polyline id="路径-9" stroke="url(#linearGradient-2)" stroke-width="2.12" points="1866.47546 1.64272616e-13 1556.20507 -1.48645149e-14 1518.30238 26.2788831 1332.03314 26.2788831 1284.10896 60.2386364 959.060954 60.2386364"></polyline>
|
||||||
|
<g id="编组-29" transform="translate(1426.559836, 49.142045) scale(-1, 1) translate(-1426.559836, -49.142045) translate(1331.116205, 38.045455)">
|
||||||
|
<polyline id="路径-10" stroke="url(#linearGradient-3)" stroke-width="2.12" points="190.887262 22.1931818 166.031081 4.22727273 4.00078371 4.22727273"></polyline>
|
||||||
|
<ellipse id="椭圆形" fill="#31A6AE" cx="4.00078371" cy="4.22727273" rx="4.00078371" ry="4.22727273"></ellipse>
|
||||||
|
</g>
|
||||||
|
<polyline id="路径-9" stroke="url(#linearGradient-4)" stroke-width="2.12" transform="translate(479.530477, 30.119318) scale(-1, 1) translate(-479.530477, -30.119318) " points="959.060954 -1.33756642e-14 876.066883 -4.67997966e-14 838.164187 26.2788831 373.972385 26.2788831 326.048198 60.2386364 -4.54174955e-13 60.2386364"></polyline>
|
||||||
|
<g id="编组-28" transform="translate(114.894416, 36.988636)">
|
||||||
|
<polyline id="路径-10" stroke="url(#linearGradient-5)" stroke-width="2.12" points="472.111287 23.25 447.255105 5.28409091 326.074844 5.28409091"></polyline>
|
||||||
|
<ellipse id="椭圆形" fill="#31A6AE" cx="321.073864" cy="5.28409091" rx="4.00078371" ry="4.22727273"></ellipse>
|
||||||
|
<ellipse id="椭圆形备份" fill="#31A6AE" cx="233.056623" cy="5.28409091" rx="4.00078371" ry="4.22727273"></ellipse>
|
||||||
|
<g id="编组-2" transform="translate(247.059366, 0.000000)" fill="#31A6AE">
|
||||||
|
<polygon id="路径-11" points="51.8543795 6.33584094e-14 48.0094045 0 56.5647535 10.5681818 60.0117556 10.5681818"></polygon>
|
||||||
|
<polygon id="路径-11备份" opacity="0.8" points="39.8520284 6.33584094e-14 36.0070534 0 44.5624024 10.5681818 48.0094045 10.5681818"></polygon>
|
||||||
|
<polygon id="路径-11备份-3" opacity="0.4" points="15.8473261 6.33584094e-14 12.0023511 0 20.5577001 10.5681818 24.0047022 10.5681818"></polygon>
|
||||||
|
<polygon id="路径-11备份-2" opacity="0.601434" points="27.8496773 6.33584094e-14 24.0047022 0 32.5600513 10.5681818 36.0070534 10.5681818"></polygon>
|
||||||
|
<polygon id="路径-11备份-4" opacity="0.201434" points="3.84497501 6.33584094e-14 4.67611706e-16 0 8.55534901 10.5681818 12.0023511 10.5681818"></polygon>
|
||||||
|
</g>
|
||||||
|
<line x1="229.055839" y1="4.75568182" x2="0.354627912" y2="5.28409091" id="路径-12" stroke="url(#linearGradient-6)" stroke-width="2.12"></line>
|
||||||
|
</g>
|
||||||
|
<g id="编组-3" transform="translate(117.896179, 0.000000)">
|
||||||
|
<g id="编组-2备份" fill="#31A6AE">
|
||||||
|
<polygon id="路径-11" points="77.7815693 9.50376141e-14 72.0141067 0 84.8471303 15.8522727 90.0176334 15.8522727"></polygon>
|
||||||
|
<polygon id="路径-11备份" opacity="0.8" points="59.7780426 9.50376141e-14 54.0105801 0 66.8436036 15.8522727 72.0141067 15.8522727"></polygon>
|
||||||
|
<polygon id="路径-11备份-3" opacity="0.4" points="23.7709892 9.50376141e-14 18.0035267 0 30.8365502 15.8522727 36.0070534 15.8522727"></polygon>
|
||||||
|
<polygon id="路径-11备份-2" opacity="0.601434" points="41.7745159 9.50376141e-14 36.0070534 0 48.8400769 15.8522727 54.0105801 15.8522727"></polygon>
|
||||||
|
<polygon id="路径-11备份-4" opacity="0.201434" points="5.76746252 9.50376141e-14 7.01417559e-16 0 12.8330235 15.8522727 18.0035267 15.8522727"></polygon>
|
||||||
|
</g>
|
||||||
|
<line x1="103.02018" y1="7.92613636" x2="203.018671" y2="8.45454545" id="路径-13" stroke="url(#linearGradient-7)" stroke-width="2.12"></line>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
<rect id="矩形" stroke="#979797" stroke-width="1.06" opacity="0" x="0.53" y="0.53" width="1918.94" height="91.94"></rect>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 7.1 KiB |
@ -1,3 +1,3 @@
|
|||||||
{
|
{
|
||||||
"url": "192.168.1.40:48080"
|
"url": "172.16.32.40:48080"
|
||||||
}
|
}
|
114
src/App.tsx
114
src/App.tsx
@ -1,80 +1,82 @@
|
|||||||
import React, { useEffect, useState, useContext } from "react";
|
import { useEffect } from "react";
|
||||||
import intl from "react-intl-universal";
|
|
||||||
import locales from "./locales/locales";
|
|
||||||
import "./App.css";
|
import "./App.css";
|
||||||
import { useAppSelector } from "./store/hooks";
|
|
||||||
import { selectChangeLangAndCss } from "./store/ChangeLangAndCss";
|
|
||||||
// import { createBrowserRouter, RouterProvider } from "react-router-dom";
|
|
||||||
import { createHashRouter, RouterProvider } from "react-router-dom";
|
import { createHashRouter, RouterProvider } from "react-router-dom";
|
||||||
|
|
||||||
import ErrorPage from "./page/ErrorPage";
|
import ErrorPage from "./page/ErrorPage";
|
||||||
import { MyObservable } from "./context/MyObservable";
|
import { MyObservable } from "./context/MyObservable";
|
||||||
import { Observable } from "@babylonjs/core";
|
import { Observable } from "@babylonjs/core";
|
||||||
import { selectGlassStatus } from "./store/ProductionMonitoringEntity";
|
|
||||||
import TestPage from "./page/TestPage";
|
|
||||||
import LDPage from "./page/LDPage";
|
import LDPage from "./page/LDPage";
|
||||||
import LinePage from "./page/LinePage";
|
import LinePageOneOne from "./page/LinePage1-1";
|
||||||
|
import LinePageOneTwo from "./page/LinePage1-2";
|
||||||
// const LOCALES_LIST = [
|
import LinePageTwoOne from "./page/LinePage2-1";
|
||||||
// {
|
import LinePageTwoTwo from "./page/LinePage2-2";
|
||||||
// label: "English",
|
import LinePageThreeOne from "./page/LinePage3-1";
|
||||||
// value: "en-US",
|
import LinePageThreeTwo from "./page/LinePage3-2";
|
||||||
// },
|
import LinePageFourOne from "./page/LinePage4-1";
|
||||||
// {
|
import LinePageFourTwo from "./page/LinePage4-2";
|
||||||
// label: "简体中文",
|
import LinePageFiveOne from "./page/LinePage5-1";
|
||||||
// value: "zh-CN",
|
import LinePageFiveTwo from "./page/LinePage5-2";
|
||||||
// },
|
|
||||||
// ];
|
|
||||||
|
|
||||||
const onGlassObservable = new Observable();
|
const onGlassObservable = new Observable();
|
||||||
|
|
||||||
function App() {
|
function App() {
|
||||||
const thisLineGlassStatus = useAppSelector(selectGlassStatus);
|
|
||||||
onGlassObservable.notifyObservers(thisLineGlassStatus);
|
|
||||||
|
|
||||||
const Locale = useAppSelector(selectChangeLangAndCss).Locale;
|
|
||||||
|
|
||||||
const setCurrentLocale = (currentLocale: string) => {
|
|
||||||
intl
|
|
||||||
.init({
|
|
||||||
currentLocale,
|
|
||||||
locales: locales,
|
|
||||||
})
|
|
||||||
.then(() => {
|
|
||||||
console.log("Language Changed to " + currentLocale);
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
setCurrentLocale(Locale);
|
|
||||||
|
|
||||||
const router = createHashRouter([
|
const router = createHashRouter([
|
||||||
{
|
|
||||||
path: "/:LineID?",
|
|
||||||
element: <LinePage />,
|
|
||||||
errorElement: <ErrorPage />,
|
|
||||||
},
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
|
||||||
{
|
|
||||||
path: "/TP/:LineID?",
|
|
||||||
element: <TestPage />,
|
|
||||||
errorElement: <ErrorPage />,
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
path: "/LD",
|
path: "/LD",
|
||||||
element: <LDPage />,
|
element: <LDPage />,
|
||||||
errorElement: <ErrorPage />,
|
errorElement: <ErrorPage />,
|
||||||
},
|
},
|
||||||
///////////////////////////////////////////////////////////////
|
|
||||||
{
|
{
|
||||||
path: "/LP/:LineID?",
|
path: "/LP/1-1",
|
||||||
element: <LinePage />,
|
element: <LinePageOneOne />,
|
||||||
|
errorElement: <ErrorPage />,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: "/LP/1-2",
|
||||||
|
element: <LinePageOneTwo />,
|
||||||
|
errorElement: <ErrorPage />,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: "/LP/2-1",
|
||||||
|
element: <LinePageTwoOne />,
|
||||||
|
errorElement: <ErrorPage />,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: "/LP/2-2",
|
||||||
|
element: <LinePageTwoTwo />,
|
||||||
|
errorElement: <ErrorPage />,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: "/LP/3-1",
|
||||||
|
element: <LinePageThreeOne />,
|
||||||
|
errorElement: <ErrorPage />,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: "/LP/3-2",
|
||||||
|
element: <LinePageThreeTwo />,
|
||||||
|
errorElement: <ErrorPage />,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: "/LP/4-1",
|
||||||
|
element: <LinePageFourOne />,
|
||||||
|
errorElement: <ErrorPage />,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: "/LP/4-2",
|
||||||
|
element: <LinePageFourTwo />,
|
||||||
|
errorElement: <ErrorPage />,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: "/LP/5-1",
|
||||||
|
element: <LinePageFiveOne />,
|
||||||
|
errorElement: <ErrorPage />,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: "/LP/5-2",
|
||||||
|
element: <LinePageFiveTwo />,
|
||||||
errorElement: <ErrorPage />,
|
errorElement: <ErrorPage />,
|
||||||
},
|
},
|
||||||
// {
|
|
||||||
// path: "/TP/:LineID?",
|
|
||||||
// element: <TestPage/>,
|
|
||||||
// errorElement: <ErrorPage/>
|
|
||||||
// },
|
|
||||||
]);
|
]);
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const timerId = setInterval(() => {
|
const timerId = setInterval(() => {
|
||||||
|
441
src/babylonjs/AllLinePageBabylon.tsx
Normal file
441
src/babylonjs/AllLinePageBabylon.tsx
Normal file
@ -0,0 +1,441 @@
|
|||||||
|
import { useEffect, useRef, useState } from "react";
|
||||||
|
import * as BABYLON from "@babylonjs/core";
|
||||||
|
import "@babylonjs/core/Debug/debugLayer";
|
||||||
|
import "@babylonjs/inspector";
|
||||||
|
import "@babylonjs/loaders/glTF";
|
||||||
|
import { GridMaterial } from "@babylonjs/materials/";
|
||||||
|
import { HemisphericLight, Vector3 } from "@babylonjs/core";
|
||||||
|
import { useAppSelector } from "../store/hooks";
|
||||||
|
import "../page/style/standard.css";
|
||||||
|
import AlarmTipGreen from "./../page/assets/icon/g.png";
|
||||||
|
import AlarmTipYellow from "./../page/assets/icon/y.png";
|
||||||
|
import AlarmTipRed from "./../page/assets/icon/r.png";
|
||||||
|
import { selectLine1Before } from "../store/LinePageSlice";
|
||||||
|
import { selectAllLine } from "../store/LeaderPageSlice";
|
||||||
|
|
||||||
|
const myStyle = {
|
||||||
|
width: "1041px",
|
||||||
|
height: "599px",
|
||||||
|
outline: "none",
|
||||||
|
};
|
||||||
|
interface MybabylonJSProps {
|
||||||
|
modelPath: string; // 明确 modelPath 属性的类型为 string
|
||||||
|
}
|
||||||
|
interface EqListType {
|
||||||
|
[key: string]: EqMsg
|
||||||
|
}
|
||||||
|
interface EqMsg {
|
||||||
|
equipmentName?:string;
|
||||||
|
run?:boolean;
|
||||||
|
error?:boolean;
|
||||||
|
inputNum?:number;
|
||||||
|
outputNum?:number;
|
||||||
|
quantityTime?:number;
|
||||||
|
status?:string;
|
||||||
|
statusTime?:number;
|
||||||
|
localDateTime?:number;
|
||||||
|
equipmentCode?:string;
|
||||||
|
equipmentId?:number;
|
||||||
|
num?:number;
|
||||||
|
}
|
||||||
|
function MybabylonJS({ modelPath }: MybabylonJSProps) {
|
||||||
|
const [eqList, setEqList] = useState<EqListType>({});
|
||||||
|
const allEquStatus = useAppSelector(selectLine1Before) as any;
|
||||||
|
const allData = useAppSelector(selectAllLine) as any; // 使用`any`来绕过类型检查
|
||||||
|
const canvasRef = useRef(null);
|
||||||
|
const resetRef = useRef<(() => void) | null>(null);
|
||||||
|
const [numAlarm, setNumAlarm] = useState('0');
|
||||||
|
const [monthNum, setMonthNum] = useState('0');
|
||||||
|
const [todayNum, setTodayNum] = useState('0');
|
||||||
|
const [yieldNum, setYieldNum] = useState('0');
|
||||||
|
const [selectedMeshName, setSelectedMeshName] = useState<string | null>(null);
|
||||||
|
const [selectedMeshId, setSelectedMeshId] = useState<string | null>(null);
|
||||||
|
const [selectedMeshObj, setSelectedMeshObj] = useState<EqMsg>({
|
||||||
|
equipmentName: "",
|
||||||
|
run: true,
|
||||||
|
error: false,
|
||||||
|
num: 0,
|
||||||
|
});
|
||||||
|
// 使用 useRef 来存储当前加载的模型引用
|
||||||
|
const currentMeshesRef = useRef<Array<BABYLON.AbstractMesh>>([]);
|
||||||
|
useEffect(() => {
|
||||||
|
const equStatus = allEquStatus?.equStatus;
|
||||||
|
if (equStatus) {
|
||||||
|
setEqList(equStatus);
|
||||||
|
}
|
||||||
|
},[allEquStatus])
|
||||||
|
// 中间顶部数据
|
||||||
|
useEffect(() => {
|
||||||
|
const numAlarm = allData?.numAlarm;
|
||||||
|
setNumAlarm(numAlarm || '0');
|
||||||
|
const monthMap = allData?.monthMap;
|
||||||
|
setMonthNum(monthMap?.output || '0');
|
||||||
|
const todayMap = allData?.todayMap;
|
||||||
|
setTodayNum(todayMap?.output || '0');
|
||||||
|
setYieldNum(todayMap?.Yield || '0');
|
||||||
|
},[allData])
|
||||||
|
useEffect(() => {
|
||||||
|
if (selectedMeshId && eqList[selectedMeshId]) {
|
||||||
|
setSelectedMeshObj({
|
||||||
|
equipmentName:eqList[selectedMeshId].equipmentName,
|
||||||
|
run:eqList[selectedMeshId].run ? eqList[selectedMeshId].run : true,
|
||||||
|
error:eqList[selectedMeshId].error ? eqList[selectedMeshId].error : false,
|
||||||
|
num:eqList[selectedMeshId].inputNum ? eqList[selectedMeshId].inputNum : (eqList[selectedMeshId].outputNum ? eqList[selectedMeshId].outputNum : 0),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},[selectedMeshId])
|
||||||
|
useEffect(() => {
|
||||||
|
// 确保 canvas 引用存在
|
||||||
|
if (!canvasRef.current) return;
|
||||||
|
const canvas = canvasRef.current;
|
||||||
|
const engine = new BABYLON.Engine(canvas, true, {
|
||||||
|
preserveDrawingBuffer: true,
|
||||||
|
stencil: true,
|
||||||
|
});
|
||||||
|
|
||||||
|
const createScene = async function () {
|
||||||
|
// This creates a basic Babylon Scene object (non-mesh)
|
||||||
|
const scene = new BABYLON.Scene(engine);
|
||||||
|
scene.clearColor = new BABYLON.Color4(0, 0, 0, 0);
|
||||||
|
const baseLight = new HemisphericLight(
|
||||||
|
"hemiLight",
|
||||||
|
new Vector3(-1, 1, 0),
|
||||||
|
scene
|
||||||
|
);
|
||||||
|
baseLight.intensity = 1;
|
||||||
|
baseLight.diffuse = new BABYLON.Color3(1, 1, 1);
|
||||||
|
baseLight.specular = new BABYLON.Color3(0.25, 0.25, 0.25);
|
||||||
|
baseLight.groundColor = new BABYLON.Color3(0.5, 0.5, 0.5);
|
||||||
|
|
||||||
|
//add an arcRotateCamera to the scene
|
||||||
|
const camera = new BABYLON.ArcRotateCamera(
|
||||||
|
"camera",
|
||||||
|
BABYLON.Tools.ToRadians(270),
|
||||||
|
BABYLON.Tools.ToRadians(25),
|
||||||
|
220,
|
||||||
|
new BABYLON.Vector3(0, 0, 10)
|
||||||
|
);
|
||||||
|
camera.lowerRadiusLimit = 10;
|
||||||
|
camera.upperRadiusLimit = 600;
|
||||||
|
|
||||||
|
// This attaches the camera to the canvas
|
||||||
|
camera.attachControl(canvas, true);
|
||||||
|
|
||||||
|
//创建一个材质
|
||||||
|
const newMt = new BABYLON.StandardMaterial("newMt");
|
||||||
|
newMt.diffuseColor = BABYLON.Color3.Blue();
|
||||||
|
|
||||||
|
const ground = BABYLON.MeshBuilder.CreateGround(
|
||||||
|
"ground",
|
||||||
|
{
|
||||||
|
width: 1000,
|
||||||
|
height: 1000,
|
||||||
|
subdivisions: 1,
|
||||||
|
},
|
||||||
|
scene
|
||||||
|
);
|
||||||
|
|
||||||
|
ground.scaling.x = 100;
|
||||||
|
ground.scaling.z = ground.scaling.x;
|
||||||
|
ground.isPickable = false;
|
||||||
|
|
||||||
|
let grid = new GridMaterial("grid", scene);
|
||||||
|
|
||||||
|
grid.majorUnitFrequency = 10;
|
||||||
|
grid.minorUnitVisibility = 0.3;
|
||||||
|
grid.gridRatio = 0.04;
|
||||||
|
grid.backFaceCulling = !1;
|
||||||
|
grid.mainColor = new BABYLON.Color3(1, 1, 1);
|
||||||
|
grid.lineColor = new BABYLON.Color3(1, 1, 1);
|
||||||
|
grid.opacity = 0;
|
||||||
|
grid.zOffset = 1;
|
||||||
|
grid.opacityTexture = new BABYLON.Texture(
|
||||||
|
"/public/png/backgroundGround.png",
|
||||||
|
scene
|
||||||
|
);
|
||||||
|
ground.material = grid;
|
||||||
|
|
||||||
|
let hl = new BABYLON.HighlightLayer("hl1", scene);
|
||||||
|
|
||||||
|
// 定义一个函数来加载或重新加载模型
|
||||||
|
const loadOrReloadModel = async () => {
|
||||||
|
// 在加载新模型之前卸载已加载的模型
|
||||||
|
currentMeshesRef.current.forEach((mesh) => {
|
||||||
|
if (mesh && mesh.parent) {
|
||||||
|
scene.removeMesh(mesh, true);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
currentMeshesRef.current = []; // 重置模型数组
|
||||||
|
try {
|
||||||
|
// 使用 ImportMeshAsync 加载新模型
|
||||||
|
var LOD0MESH1 = await BABYLON.SceneLoader.ImportMeshAsync(
|
||||||
|
"",
|
||||||
|
"/Line/",
|
||||||
|
"part1.babylon",
|
||||||
|
scene
|
||||||
|
);
|
||||||
|
// 将新加载的模型添加到 currentMeshesRef 中
|
||||||
|
currentMeshesRef.current.push(...LOD0MESH1.meshes);
|
||||||
|
var LOD0MESH2 = await BABYLON.SceneLoader.ImportMeshAsync(
|
||||||
|
"",
|
||||||
|
"/Line/",
|
||||||
|
"part2.babylon",
|
||||||
|
scene
|
||||||
|
);
|
||||||
|
currentMeshesRef.current.push(...LOD0MESH2.meshes);
|
||||||
|
// ...为新加载的模型设置交互逻辑
|
||||||
|
|
||||||
|
LOD0MESH1.meshes.map((mesh) => {
|
||||||
|
mesh.isPickable = true;
|
||||||
|
mesh.actionManager = new BABYLON.ActionManager(scene);
|
||||||
|
if (modelPath.slice(-1) === "1") {
|
||||||
|
if (
|
||||||
|
mesh.name.includes("磨边") ||
|
||||||
|
mesh.name.includes("清洗") ||
|
||||||
|
mesh.name.includes("镀膜") ||
|
||||||
|
mesh.name.includes("固化") ||
|
||||||
|
mesh.name.includes("丝印") ||
|
||||||
|
mesh.name.includes("打孔")
|
||||||
|
) {
|
||||||
|
// @ts-ignore
|
||||||
|
hl.addMesh(mesh, BABYLON.Color3.Green());
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (
|
||||||
|
mesh.name.includes("钢化") ||
|
||||||
|
mesh.name.includes("包装") ||
|
||||||
|
mesh.name.includes("铺纸") ||
|
||||||
|
mesh.name.includes("下片机械手")
|
||||||
|
) {
|
||||||
|
// @ts-ignore
|
||||||
|
hl.addMesh(mesh, BABYLON.Color3.Green());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 模型点击事件
|
||||||
|
mesh._scene.onPointerDown = async (event, _pickResult) => {
|
||||||
|
console.log('_pickResult',_pickResult)
|
||||||
|
const pickInfo = mesh._scene.pick(
|
||||||
|
mesh._scene.pointerX,
|
||||||
|
mesh._scene.pointerY
|
||||||
|
);
|
||||||
|
//判断是否是右键
|
||||||
|
if (!(event.buttons === 1 && pickInfo.pickedMesh)) return;
|
||||||
|
const MeshName = pickInfo.pickedMesh.name;
|
||||||
|
const MeshNameId = pickInfo.pickedMesh.metadata.tags;
|
||||||
|
|
||||||
|
setSelectedMeshName(MeshName);
|
||||||
|
setSelectedMeshId(MeshNameId);
|
||||||
|
};
|
||||||
|
});
|
||||||
|
LOD0MESH2.meshes.map((mesh) => {
|
||||||
|
mesh.isPickable = true;
|
||||||
|
mesh.actionManager = new BABYLON.ActionManager(scene);
|
||||||
|
if (modelPath.slice(-1) === "1") {
|
||||||
|
if (
|
||||||
|
mesh.name.includes("磨边") ||
|
||||||
|
mesh.name.includes("清洗") ||
|
||||||
|
mesh.name.includes("镀膜") ||
|
||||||
|
mesh.name.includes("固化") ||
|
||||||
|
mesh.name.includes("丝印") ||
|
||||||
|
mesh.name.includes("打孔")
|
||||||
|
) {
|
||||||
|
// @ts-ignore
|
||||||
|
hl.addMesh(mesh, BABYLON.Color3.Green());
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (
|
||||||
|
mesh.name.includes("钢化") ||
|
||||||
|
mesh.name.includes("包装") ||
|
||||||
|
mesh.name.includes("铺纸") ||
|
||||||
|
mesh.name.includes("下片机械手")
|
||||||
|
) {
|
||||||
|
// @ts-ignore
|
||||||
|
hl.addMesh(mesh, BABYLON.Color3.Green());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 模型点击事件
|
||||||
|
mesh._scene.onPointerDown = async (event, _pickResult) => {
|
||||||
|
console.log('_pickResult',_pickResult)
|
||||||
|
const pickInfo = mesh._scene.pick(
|
||||||
|
mesh._scene.pointerX,
|
||||||
|
mesh._scene.pointerY
|
||||||
|
);
|
||||||
|
//判断是否是右键
|
||||||
|
if (!(event.buttons === 1 && pickInfo.pickedMesh)) return;
|
||||||
|
const MeshName = pickInfo.pickedMesh.name;
|
||||||
|
const MeshNameId = pickInfo.pickedMesh.metadata.tags;
|
||||||
|
|
||||||
|
setSelectedMeshName(MeshName);
|
||||||
|
setSelectedMeshId(MeshNameId);
|
||||||
|
};
|
||||||
|
});
|
||||||
|
} catch (error) {
|
||||||
|
console.error("加载模型失败:", error);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// 调用函数以加载或重新加载模型
|
||||||
|
loadOrReloadModel();
|
||||||
|
|
||||||
|
function reset() {
|
||||||
|
camera.target = new BABYLON.Vector3(0, 0, 10);
|
||||||
|
camera.alpha = BABYLON.Tools.ToRadians(270);
|
||||||
|
camera.beta = BABYLON.Tools.ToRadians(25);
|
||||||
|
camera.radius = 220;
|
||||||
|
setSelectedMeshName(null);
|
||||||
|
}
|
||||||
|
// 外部初始位置按钮
|
||||||
|
resetRef.current = reset;
|
||||||
|
|
||||||
|
let resetCamera = setTimeout(reset, 15000);
|
||||||
|
scene.onPointerObservable.add((pointerInfo) => {
|
||||||
|
switch (pointerInfo.type) {
|
||||||
|
case BABYLON.PointerEventTypes.POINTERMOVE:
|
||||||
|
clearTimeout(resetCamera);
|
||||||
|
resetCamera = setTimeout(reset, 15000);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return scene;
|
||||||
|
};
|
||||||
|
|
||||||
|
// call the createScene function
|
||||||
|
const scene = createScene();
|
||||||
|
|
||||||
|
// run the render loop
|
||||||
|
scene.then(
|
||||||
|
(scene) => {
|
||||||
|
console.log("createScene被调用了=====", scene);
|
||||||
|
engine.runRenderLoop(function () {
|
||||||
|
scene.render();
|
||||||
|
});
|
||||||
|
},
|
||||||
|
(reason) => {
|
||||||
|
console.log("reason=============", reason);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
// Resize
|
||||||
|
window.addEventListener("resize", function () {
|
||||||
|
engine.resize();
|
||||||
|
});
|
||||||
|
// 组件卸载时的清理逻辑
|
||||||
|
return () => {
|
||||||
|
// 清理场景和引擎资源
|
||||||
|
engine.dispose();
|
||||||
|
};
|
||||||
|
}, [modelPath]);
|
||||||
|
const resetModel = () => {
|
||||||
|
//模型初始位置
|
||||||
|
if (resetRef.current) {
|
||||||
|
resetRef.current();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
function formatNumber(str: string, separator = ',') {
|
||||||
|
// 使用正则表达式从右到左每隔3位添加分隔符
|
||||||
|
str = str.toString();
|
||||||
|
return str.replace(/\B(?=(\d{3})+(?!\d))/g, separator);
|
||||||
|
}
|
||||||
|
function toPercentage(decimalStr: string) {
|
||||||
|
let decimal = parseFloat(decimalStr);
|
||||||
|
if (isNaN(decimal)) {
|
||||||
|
throw new Error('Invalid decimal number provided.');
|
||||||
|
}
|
||||||
|
let percent = decimal * 100;
|
||||||
|
let formattedPercent = percent.toFixed(2);
|
||||||
|
return formattedPercent + '%';
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div style={myStyle}>
|
||||||
|
<div className="model_top_container">
|
||||||
|
<div className="model_top_style1">
|
||||||
|
<div className="model_top_num">{toPercentage(yieldNum)}</div>
|
||||||
|
<div className="model_top_text">成品率</div>
|
||||||
|
</div>
|
||||||
|
<div className="model_top_style2">
|
||||||
|
<div className="model_top_num">{formatNumber(todayNum)}</div>
|
||||||
|
<div className="model_top_text">今日产量</div>
|
||||||
|
</div>
|
||||||
|
<div className="model_top_style2">
|
||||||
|
<div className="model_top_num">{formatNumber(monthNum)}</div>
|
||||||
|
<div className="model_top_text">本月产量</div>
|
||||||
|
</div>
|
||||||
|
<div className="model_top_style1">
|
||||||
|
<div className="model_top_num">{formatNumber(numAlarm)}</div>
|
||||||
|
<div className="model_top_text">设备报警数</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{selectedMeshName && (
|
||||||
|
<div className="eq_detail_info">
|
||||||
|
<div>
|
||||||
|
<span className="left_name">设备名称:</span>
|
||||||
|
<span className="right_value">{selectedMeshObj.equipmentName}</span>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<span className="left_name">进/出口数量:</span>
|
||||||
|
<span className="right_value">{selectedMeshObj.num}</span>
|
||||||
|
</div>
|
||||||
|
{/* <div>
|
||||||
|
<span className="left_name">出口数量:</span>
|
||||||
|
<span className="right_value">1,312</span>
|
||||||
|
</div> */}
|
||||||
|
<div>
|
||||||
|
<span className="left_name">报警状态:</span>
|
||||||
|
<span className="right_value">
|
||||||
|
{selectedMeshObj.error ? (
|
||||||
|
<>
|
||||||
|
<img
|
||||||
|
src={AlarmTipRed}
|
||||||
|
alt=""
|
||||||
|
width={17}
|
||||||
|
style={{ position: "relative", top: "2px", marginRight: 5 }}
|
||||||
|
/>
|
||||||
|
<span>报警</span>
|
||||||
|
</>
|
||||||
|
) : (
|
||||||
|
<>
|
||||||
|
<img
|
||||||
|
src={AlarmTipGreen}
|
||||||
|
alt=""
|
||||||
|
width={17}
|
||||||
|
style={{ position: "relative", top: "2px", marginRight: 5 }}
|
||||||
|
/>
|
||||||
|
<span>正常</span>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<span className="left_name">在线状态:</span>
|
||||||
|
<span className="right_value">
|
||||||
|
{selectedMeshObj.run ? (
|
||||||
|
<>
|
||||||
|
<img
|
||||||
|
src={AlarmTipGreen}
|
||||||
|
alt=""
|
||||||
|
width={17}
|
||||||
|
style={{ position: "relative", top: "2px", marginRight: 5 }}
|
||||||
|
/>
|
||||||
|
<span>在线</span>
|
||||||
|
</>
|
||||||
|
) : (
|
||||||
|
<>
|
||||||
|
<img
|
||||||
|
src={AlarmTipYellow}
|
||||||
|
alt=""
|
||||||
|
width={17}
|
||||||
|
style={{ position: "relative", top: "2px", marginRight: 5 }}
|
||||||
|
/>
|
||||||
|
<span>离线</span>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
<canvas ref={canvasRef} style={myStyle} />
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default MybabylonJS;
|
445
src/babylonjs/EqInfoData.ts
Normal file
445
src/babylonjs/EqInfoData.ts
Normal file
@ -0,0 +1,445 @@
|
|||||||
|
interface EqInfoInterface {
|
||||||
|
name: string;
|
||||||
|
data: Array<{ name: string; value: number, code:string, label:string}>;
|
||||||
|
position: Array<number>;
|
||||||
|
}
|
||||||
|
interface EqInfoDataInterface {
|
||||||
|
[key: string]: Array<EqInfoInterface>;
|
||||||
|
}
|
||||||
|
const EqInfoData:EqInfoDataInterface = {
|
||||||
|
"Line1-1": [
|
||||||
|
{
|
||||||
|
name: "磨边进口",
|
||||||
|
data: [
|
||||||
|
{ name: "1支线", value: 0, code:'1-edge1', label:'inputNum' },
|
||||||
|
{ name: "2支线", value: 0, code:'1-edge2', label:'inputNum' },
|
||||||
|
{ name: "3支线", value: 0, code:'1-edge3', label:'inputNum' },
|
||||||
|
],
|
||||||
|
position: [180, 210],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "磨边清洗出口",
|
||||||
|
data: [
|
||||||
|
{ name: "1支线", value: 0, code:'1-edgeclean1', label:'outputNum' },
|
||||||
|
{ name: "2支线", value: 0, code:'1-edgeclean2', label:'outputNum' },
|
||||||
|
{ name: "3支线", value: 0, code:'1-edgeclean3', label:'outputNum' },
|
||||||
|
],
|
||||||
|
position: [340, 130],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "打孔出口",
|
||||||
|
data: [
|
||||||
|
{ name: "1支线", value: 0, code:'1-punch1', label:'outputNum' },
|
||||||
|
{ name: "2支线", value: 0, code:'1-punch2', label:'outputNum' },
|
||||||
|
{ name: "3支线", value: 0, code:'1-punch3', label:'outputNum' },
|
||||||
|
],
|
||||||
|
position: [590, 300],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "丝印进口",
|
||||||
|
data: [
|
||||||
|
{ name: "1支线", value: 0, code:'1-silk1', label:'inputNum' },
|
||||||
|
{ name: "2支线", value: 0, code:'1-silk2', label:'inputNum' },
|
||||||
|
{ name: "3支线", value: 0, code:'1-silk3', label:'inputNum' },
|
||||||
|
],
|
||||||
|
position: [510, 65],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "二次固化出口",
|
||||||
|
data: [
|
||||||
|
{ name: "1支线", value: 0, code:'1-secsolid1', label:'outputNum' },
|
||||||
|
{ name: "2支线", value: 0, code:'1-secsolid2', label:'outputNum' },
|
||||||
|
{ name: "3支线", value: 0, code:'1-secsolid3', label:'outputNum' },
|
||||||
|
],
|
||||||
|
position: [850, 190],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "钢化进口",
|
||||||
|
data: [{ name: "钢化进口", value: 0, code:'1-temper1', label:'inputNum' }],
|
||||||
|
position: [750, 10],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
"Line1-2": [
|
||||||
|
{
|
||||||
|
name: "钢化出口",
|
||||||
|
data: [{ name: "钢化出口", value: 0, code:'1-temper1', label:'outputNum' }],
|
||||||
|
position: [140, 250],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "包装清洗机入口",
|
||||||
|
data: [
|
||||||
|
{ name: "包装清洗机1_1", value: 0, code:'1-packclean1', label:'inputNum' },
|
||||||
|
{ name: "包装清洗机1_2", value: 0, code:'1-packclean2', label:'inputNum' },
|
||||||
|
],
|
||||||
|
position: [450, 320],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "包装清洗机出口",
|
||||||
|
data: [
|
||||||
|
{ name: "包装清洗机1_1", value: 0, code:'1-packclean1', label:'outputNum' },
|
||||||
|
{ name: "包装清洗机1_2", value: 0, code:'1-packclean2', label:'outputNum' },
|
||||||
|
],
|
||||||
|
position: [350, 130],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "铺纸机",
|
||||||
|
data: [
|
||||||
|
{ name: "铺纸机1_1", value: 0, code:'1-paper1', label:'outputNum' },
|
||||||
|
{ name: "铺纸机1_2", value: 0, code:'1-paper2', label:'outputNum' },
|
||||||
|
],
|
||||||
|
position: [640, 240],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "下片机械手",
|
||||||
|
data: [
|
||||||
|
{ name: "下片机械手1_1", value: 0, code:'1-down1', label:'outputNum'},
|
||||||
|
{ name: "下片机械手1_2", value: 0, code:'1-down2', label:'outputNum'},
|
||||||
|
{ name: "下片机械手1_3", value: 0, code:'1-down3', label:'outputNum'},
|
||||||
|
],
|
||||||
|
position: [570, 10],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
"Line2-1": [
|
||||||
|
{
|
||||||
|
name: "磨边进口",
|
||||||
|
data: [
|
||||||
|
{ name: "1支线", value: 0, code:'2-edge1', label:'inputNum' },
|
||||||
|
{ name: "2支线", value: 0, code:'2-edge2', label:'inputNum' },
|
||||||
|
],
|
||||||
|
position: [150, 245],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "磨边清洗出口",
|
||||||
|
data: [
|
||||||
|
{ name: "1支线", value: 0, code:'2-edgeclean1', label:'outputNum' },
|
||||||
|
{ name: "2支线", value: 0, code:'2-edgeclean2', label:'outputNum' },
|
||||||
|
],
|
||||||
|
position: [310, 180],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "打孔出口",
|
||||||
|
data: [
|
||||||
|
{ name: "1支线", value: 0, code:'2-punch1', label:'outputNum' },
|
||||||
|
{ name: "2支线", value: 0, code:'2-punch2', label:'outputNum' },
|
||||||
|
],
|
||||||
|
position: [540, 300],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "丝印进口",
|
||||||
|
data: [
|
||||||
|
{ name: "1支线", value: 0, code:'2-silk1', label:'inputNum' },
|
||||||
|
{ name: "2支线", value: 0, code:'2-silk2', label:'inputNum' },
|
||||||
|
],
|
||||||
|
position: [530, 100],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "二次固化出口",
|
||||||
|
data: [
|
||||||
|
{ name: "1支线", value: 0, code:'2-secsolid1', label:'outputNum' },
|
||||||
|
{ name: "2支线", value: 0, code:'2-secsolid2', label:'outputNum' },
|
||||||
|
],
|
||||||
|
position: [850, 170],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "钢化进口",
|
||||||
|
data: [{ name: "钢化进口", value: 0, code:'2-temper1', label:'inputNum' }],
|
||||||
|
position: [810, 10],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
"Line2-2": [
|
||||||
|
{
|
||||||
|
name: "钢化出口",
|
||||||
|
data: [{ name: "钢化出口", value: 0, code:'2-temper1', label:'outputNum' }],
|
||||||
|
position: [305, 260],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "包装清洗机入口",
|
||||||
|
data: [
|
||||||
|
{ name: "包装清洗机", value: 0, code:'2-packclean1', label:'inputNum' },
|
||||||
|
],
|
||||||
|
position: [640, 270],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "包装清洗机出口",
|
||||||
|
data: [
|
||||||
|
{ name: "包装清洗机", value: 0, code:'2-packclean1', label:'outputNum' },
|
||||||
|
],
|
||||||
|
position: [550, 140],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "铺纸机",
|
||||||
|
data: [
|
||||||
|
{ name: "铺纸机", value: 0, code:'2-paper1', label:'outputNum' },
|
||||||
|
],
|
||||||
|
position: [810, 210],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "下片机械手",
|
||||||
|
data: [
|
||||||
|
{ name: "下片机械手2_1", value: 0, code:'2-down1', label:'outputNum'},
|
||||||
|
{ name: "下片机械手2_2", value: 0, code:'2-down2', label:'outputNum'},
|
||||||
|
],
|
||||||
|
position: [630, 10],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
"Line3-1": [
|
||||||
|
{
|
||||||
|
name: "磨边进口",
|
||||||
|
data: [
|
||||||
|
{ name: "1支线", value: 0, code:'3-edge1', label:'inputNum' },
|
||||||
|
{ name: "2支线", value: 0, code:'3-edge2', label:'inputNum' },
|
||||||
|
],
|
||||||
|
position: [150, 225],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "磨边清洗出口",
|
||||||
|
data: [
|
||||||
|
{ name: "1支线", value: 0, code:'3-edgeclean1', label:'outputNum' },
|
||||||
|
{ name: "2支线", value: 0, code:'3-edgeclean2', label:'outputNum' },
|
||||||
|
],
|
||||||
|
position: [380, 150],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "打孔出口",
|
||||||
|
data: [
|
||||||
|
{ name: "1支线", value: 0, code:'3-punch1', label:'outputNum' },
|
||||||
|
{ name: "2支线", value: 0, code:'3-punch2', label:'outputNum' },
|
||||||
|
],
|
||||||
|
position: [620, 280],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "丝印进口",
|
||||||
|
data: [
|
||||||
|
{ name: "1支线", value: 0, code:'3-silk1', label:'inputNum' },
|
||||||
|
{ name: "2支线", value: 0, code:'3-silk2', label:'inputNum' },
|
||||||
|
],
|
||||||
|
position: [560, 90],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "二次固化出口",
|
||||||
|
data: [
|
||||||
|
{ name: "1支线", value: 0, code:'3-secsolid1', label:'outputNum' },
|
||||||
|
{ name: "2支线", value: 0, code:'3-secsolid2', label:'outputNum' },
|
||||||
|
],
|
||||||
|
position: [870, 170],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "钢化进口",
|
||||||
|
data: [{ name: "钢化进口", value: 0, code:'3-temper1', label:'inputNum' }],
|
||||||
|
position: [820, 28],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
"Line3-2": [
|
||||||
|
{
|
||||||
|
name: "钢化出口",
|
||||||
|
data: [{ name: "钢化出口", value: 0, code:'3-temper1', label:'outputNum' }],
|
||||||
|
position: [300, 190],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "包装清洗机入口",
|
||||||
|
data: [
|
||||||
|
{ name: "包装清洗机", value: 0, code:'3-packclean1', label:'inputNum' },
|
||||||
|
],
|
||||||
|
position: [580, 250],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "包装清洗机出口",
|
||||||
|
data: [
|
||||||
|
{ name: "包装清洗机", value: 0, code:'3-packclean1', label:'outputNum' },
|
||||||
|
],
|
||||||
|
position: [520, 100],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "铺纸机",
|
||||||
|
data: [
|
||||||
|
{ name: "铺纸机", value: 0, code:'3-paper1', label:'outputNum' },
|
||||||
|
],
|
||||||
|
position: [760, 190],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "下片机械手",
|
||||||
|
data: [
|
||||||
|
{ name: "下片机械手3_1", value: 0, code:'3-down1', label:'outputNum'},
|
||||||
|
{ name: "下片机械手3_2", value: 0, code:'3-down2', label:'outputNum'},
|
||||||
|
],
|
||||||
|
position: [670, 10],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
"Line4-1": [
|
||||||
|
{
|
||||||
|
name: "磨边进口",
|
||||||
|
data: [
|
||||||
|
{ name: "1支线", value: 0, code:'4-edge1', label:'inputNum' },
|
||||||
|
{ name: "2支线", value: 0, code:'4-edge2', label:'inputNum' },
|
||||||
|
],
|
||||||
|
position: [200, 150],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "磨边清洗出口",
|
||||||
|
data: [
|
||||||
|
{ name: "1支线", value: 0, code:'4-edgeclean1', label:'outputNum' },
|
||||||
|
{ name: "2支线", value: 0, code:'4-edgeclean2', label:'outputNum' },
|
||||||
|
],
|
||||||
|
position: [420, 150],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "一次镀膜进口",
|
||||||
|
data: [
|
||||||
|
{ name: "1支线", value: 0, code:'4-fircoat1', label:'inputNum' },
|
||||||
|
{ name: "2支线", value: 0, code:'4-fircoat2', label:'inputNum' },
|
||||||
|
],
|
||||||
|
position: [650, 290],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "二次镀膜进口",
|
||||||
|
data: [
|
||||||
|
{ name: "1支线", value: 0, code:'4-seccoat1', label:'inputNum' },
|
||||||
|
{ name: "2支线", value: 0, code:'4-seccoat2', label:'inputNum' },
|
||||||
|
],
|
||||||
|
position: [640, 60],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "二次固化出口",
|
||||||
|
data: [
|
||||||
|
{ name: "1支线", value: 0, code:'4-secsolid1', label:'outputNum' },
|
||||||
|
{ name: "2支线", value: 0, code:'4-secsolid2', label:'outputNum' },
|
||||||
|
],
|
||||||
|
position: [860, 190],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "钢化进口",
|
||||||
|
data: [{ name: "钢化进口", value: 0, code:'4-temper1', label:'inputNum' }],
|
||||||
|
position: [820, 20],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
"Line4-2": [
|
||||||
|
{
|
||||||
|
name: "钢化出口",
|
||||||
|
data: [{ name: "钢化出口", value: 0, code:'4-temper1', label:'outputNum' }],
|
||||||
|
position: [290, 230],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "包装清洗机入口",
|
||||||
|
data: [
|
||||||
|
{ name: "包装清洗机", value: 0, code:'4-packclean1', label:'inputNum' },
|
||||||
|
],
|
||||||
|
position: [550, 280],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "包装清洗机出口",
|
||||||
|
data: [
|
||||||
|
{ name: "包装清洗机", value: 0, code:'4-packclean1', label:'outputNum' },
|
||||||
|
],
|
||||||
|
position: [500, 130],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "铺纸机",
|
||||||
|
data: [
|
||||||
|
{ name: "铺纸机4_1", value: 0, code:'4-paper1', label:'outputNum'},
|
||||||
|
{ name: "铺纸机4_2", value: 0, code:'4-paper2', label:'outputNum'},
|
||||||
|
],
|
||||||
|
position: [765, 210],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "下片机械手",
|
||||||
|
data: [
|
||||||
|
{ name: "下片机械手4_1", value: 0, code:'4-down1', label:'outputNum' },
|
||||||
|
{ name: "下片机械手4_2", value: 0, code:'4-down2', label:'outputNum' },
|
||||||
|
],
|
||||||
|
position: [560, 10],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
"Line5-1": [
|
||||||
|
{
|
||||||
|
name: "磨边进口",
|
||||||
|
data: [
|
||||||
|
{ name: "1支线", value: 0, code:'5-edge1', label:'inputNum' },
|
||||||
|
{ name: "2支线", value: 0, code:'5-edge2', label:'inputNum' },
|
||||||
|
{ name: "3支线", value: 0, code:'5-edge3', label:'inputNum' },
|
||||||
|
],
|
||||||
|
position: [150, 370],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "磨边清洗出口",
|
||||||
|
data: [
|
||||||
|
{ name: "1支线", value: 0, code:'5-edgeclean1', label:'outputNum' },
|
||||||
|
{ name: "2支线", value: 0, code:'5-edgeclean2', label:'outputNum' },
|
||||||
|
{ name: "3支线", value: 0, code:'5-edgeclean3', label:'outputNum' },
|
||||||
|
],
|
||||||
|
position: [380, 130],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "一次镀膜进口",
|
||||||
|
data: [
|
||||||
|
{ name: "1支线", value: 0, code:'5-fircoat1', label:'inputNum' },
|
||||||
|
{ name: "2支线", value: 0, code:'5-fircoat2', label:'inputNum' },
|
||||||
|
{ name: "3支线", value: 0, code:'5-fircoat3', label:'inputNum' },
|
||||||
|
],
|
||||||
|
position: [650, 310],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "二次镀膜进口",
|
||||||
|
data: [
|
||||||
|
{ name: "1支线", value: 0, code:'5-seccoat1', label:'inputNum' },
|
||||||
|
{ name: "2支线", value: 0, code:'5-seccoat2', label:'inputNum' },
|
||||||
|
{ name: "3支线", value: 0, code:'5-seccoat3', label:'inputNum' },
|
||||||
|
],
|
||||||
|
position: [640, 20],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "二次固化出口",
|
||||||
|
data: [
|
||||||
|
{ name: "1支线", value: 0, code:'5-secsolid1', label:'outputNum' },
|
||||||
|
{ name: "2支线", value: 0, code:'5-secsolid2', label:'outputNum' },
|
||||||
|
{ name: "3支线", value: 0, code:'5-secsolid3', label:'outputNum' },
|
||||||
|
],
|
||||||
|
position: [850, 220],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "钢化进口",
|
||||||
|
data: [{ name: "钢化进口", value: 0, code:'5-temper1', label:'inputNum' }],
|
||||||
|
position: [830, 10],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
"Line5-2": [
|
||||||
|
{
|
||||||
|
name: "钢化出口",
|
||||||
|
data: [{ name: "钢化出口", value: 0, code:'5-temper1', label:'outputNum' }],
|
||||||
|
position: [260, 255],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "包装清洗机入口",
|
||||||
|
data: [
|
||||||
|
{ name: "包装清洗机5_1", value: 0, code:'5-packclean1', label:'inputNum' },
|
||||||
|
{ name: "包装清洗机5_2", value: 0, code:'5-packclean2', label:'inputNum' },
|
||||||
|
],
|
||||||
|
position: [508, 350],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "包装清洗机出口",
|
||||||
|
data: [
|
||||||
|
{ name: "包装清洗机5_1", value: 0, code:'5-packclean1', label:'outputNum' },
|
||||||
|
{ name: "包装清洗机5_2", value: 0, code:'5-packclean2', label:'outputNum' },
|
||||||
|
],
|
||||||
|
position: [444, 120],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "铺纸机",
|
||||||
|
data: [
|
||||||
|
{ name: "铺纸机5_1", value: 0, code:'5-paper1', label:'outputNum' },
|
||||||
|
{ name: "铺纸机5_2", value: 0, code:'5-paper2', label:'outputNum' },
|
||||||
|
],
|
||||||
|
position: [710, 272],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "下片机械手",
|
||||||
|
data: [
|
||||||
|
{ name: "下片机械手5_1", value: 0, code:'5-down1', label:'outputNum'},
|
||||||
|
{ name: "下片机械手5_2", value: 0, code:'5-down2', label:'outputNum'},
|
||||||
|
{ name: "下片机械手5_3", value: 0, code:'5-down3', label:'outputNum'},
|
||||||
|
],
|
||||||
|
position: [700, 10],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
}
|
||||||
|
export default EqInfoData
|
@ -1,59 +0,0 @@
|
|||||||
const EquMap = {
|
|
||||||
CleanAfterEdge1_1: ['object_1_003'],
|
|
||||||
CleanAfterEdge1_2: ['object_1_004'],
|
|
||||||
CleanAfterEdge2_1: ['object_2_003'],
|
|
||||||
CleanAfterEdge2_2: ['object_2_004'],
|
|
||||||
CleanAfterEdge3_1: ['object_3_003'],
|
|
||||||
CleanAfterEdge3_2: ['object_3_004'],
|
|
||||||
CleanAfterEdge4_1: ['object_4_003'],
|
|
||||||
CleanAfterEdge4_2: ['object_4_004'],
|
|
||||||
CleanAfterTemper1_1: ['object_1_026', 'object_1_027'],
|
|
||||||
CleanAfterTemper2_1: ['object_2_022', 'object_2_023'],
|
|
||||||
CleanAfterTemper3_1: ['object_3_022', 'object_3_023'],
|
|
||||||
CleanAfterTemper4_1: ['object_4_026', 'object_4_027'],
|
|
||||||
CleanBeforCoat1_1: ['object_1_009'],
|
|
||||||
CleanBeforCoat1_2: ['object_1_010'],
|
|
||||||
CleanBeforCoat4_1: ['object_4_009'],
|
|
||||||
CleanBeforCoat4_2: ['object_4_010'],
|
|
||||||
Edge1_1: ['object_1_001'],
|
|
||||||
Edge1_2: ['object_1_002'],
|
|
||||||
Edge2_1: ['object_2_001'],
|
|
||||||
Edge2_2: ['object_2_002'],
|
|
||||||
Edge3_1: ['object_3_001'],
|
|
||||||
Edge3_2: ['object_3_002'],
|
|
||||||
Edge4_1: ['object_4_001'],
|
|
||||||
Edge4_2: ['object_4_002'],
|
|
||||||
FirstCoat1_1: ['object_1_011'],
|
|
||||||
FirstCoat1_2: ['object_1_012'],
|
|
||||||
FirstCoat2_1: ['object_2_007'],
|
|
||||||
FirstCoat2_2: ['object_2_008'],
|
|
||||||
FirstCoat3_1: ['object_3_007'],
|
|
||||||
FirstCoat3_2: ['object_3_008'],
|
|
||||||
FirstCoat4_1: ['object_4_011'],
|
|
||||||
FirstCoat4_2: ['object_4_012'],
|
|
||||||
Punch1_1: ['object_1_007'],
|
|
||||||
Punch1_2: ['object_1_008'],
|
|
||||||
Punch4_1: ['object_4_007'],
|
|
||||||
Punch4_2: ['object_4_008'],
|
|
||||||
SecondCoat1_1: ['object_1_013'],
|
|
||||||
SecondCoat1_2: ['object_1_014'],
|
|
||||||
SecondCoat2_1: ['object_2_009'],
|
|
||||||
SecondCoat2_2: ['object_2_010'],
|
|
||||||
SecondCoat3_1: ['object_3_009'],
|
|
||||||
SecondCoat3_2: ['object_3_010'],
|
|
||||||
SecondCoat4_1: ['object_4_013'],
|
|
||||||
SecondCoat4_2: ['object_4_014'],
|
|
||||||
Temper1_1: ['object_1_017', 'object_1_018', 'object_1_019', 'object_1_020', 'object_1_021', 'object_1_022', 'object_1_023', 'object_1_024', 'object_1_025'],
|
|
||||||
Temper2_1: ['object_2_013', 'object_2_014', 'object_2_015', 'object_2_016', 'object_2_017', 'object_2_018', 'object_2_019', 'object_2_020', 'object_2_021'],
|
|
||||||
Temper3_1: ['object_3_013', 'object_3_014', 'object_3_015', 'object_3_016', 'object_3_017', 'object_3_018', 'object_3_019', 'object_3_020', 'object_3_021'],
|
|
||||||
Temper4_1: ['object_4_017', 'object_4_018', 'object_4_019', 'object_4_020', 'object_4_021', 'object_4_022', 'object_4_023', 'object_4_024', 'object_4_025'],
|
|
||||||
Unload1_1: ['object_1_028'],
|
|
||||||
Unload1_2: ['object_1_029'],
|
|
||||||
Unload2_1: ['object_2_024'],
|
|
||||||
Unload2_2: ['object_2_025'],
|
|
||||||
Unload3_1: ['object_3_024'],
|
|
||||||
Unload3_2: ['object_3_025'],
|
|
||||||
Unload4_1: ['object_4_028'],
|
|
||||||
Unload4_2: ['object_4_029']
|
|
||||||
}
|
|
||||||
export default EquMap;
|
|
File diff suppressed because it is too large
Load Diff
@ -1,656 +0,0 @@
|
|||||||
import React, { useEffect, useRef, useState, useContext, useMemo } from "react";
|
|
||||||
import * as BABYLON from "@babylonjs/core";
|
|
||||||
import "@babylonjs/core/Debug/debugLayer";
|
|
||||||
import "@babylonjs/inspector";
|
|
||||||
import "@babylonjs/loaders/glTF";
|
|
||||||
import { GridMaterial } from "@babylonjs/materials/";
|
|
||||||
import {
|
|
||||||
Animatable,
|
|
||||||
HemisphericLight,
|
|
||||||
Mesh,
|
|
||||||
Observable,
|
|
||||||
Vector3,
|
|
||||||
} from "@babylonjs/core";
|
|
||||||
import { useAppSelector } from "../store/hooks";
|
|
||||||
import "../page/style/standard.css";
|
|
||||||
import { EquStatusInterface, selectEquStatus } from "../store/EquStatusEntity";
|
|
||||||
import EquMap from "./EquMap";
|
|
||||||
import AlarmTipGreen from "./../page/LinePage/assets/icon/g.png";
|
|
||||||
import AlarmTipYellow from "./../page/LinePage/assets/icon/y.png";
|
|
||||||
import AlarmTipRed from "./../page/LinePage/assets/icon/r.png";
|
|
||||||
|
|
||||||
// const onEquObservable = new Observable();
|
|
||||||
// const lineNameNo = {
|
|
||||||
// "1":"一",
|
|
||||||
// "2":"二",
|
|
||||||
// "3":"三",
|
|
||||||
// "4":"四",
|
|
||||||
// "5":"五",
|
|
||||||
// }
|
|
||||||
const lineNameNo = ["一","二","三","四","五"]
|
|
||||||
|
|
||||||
const myStyle = {
|
|
||||||
width: "1041px",
|
|
||||||
height: "562px",
|
|
||||||
outline: "none",
|
|
||||||
};
|
|
||||||
interface MybabylonJSProps {
|
|
||||||
modelPath: string; // 明确 modelPath 属性的类型为 string
|
|
||||||
}
|
|
||||||
interface EqInfoListInterface {
|
|
||||||
[key: string]: EqInfo[];
|
|
||||||
}
|
|
||||||
interface EqInfo {
|
|
||||||
name: string;
|
|
||||||
inputNum: number;
|
|
||||||
outPut: number;
|
|
||||||
position: [number, number];
|
|
||||||
}
|
|
||||||
const eqInfoList: EqInfoListInterface = {
|
|
||||||
"Line1-1": [
|
|
||||||
{ name: "磨边机", inputNum: 100, outPut: 100, position: [134, 202] },
|
|
||||||
{ name: "磨边机", inputNum: 101, outPut: 101, position: [82, 306] },
|
|
||||||
{ name: "磨边机", inputNum: 105, outPut: 105, position: [342, 400] },
|
|
||||||
{ name: "打孔机", inputNum: 100, outPut: 100, position: [337, 51] },
|
|
||||||
{ name: "打孔机", inputNum: 101, outPut: 101, position: [338, 156] },
|
|
||||||
{ name: "打孔机", inputNum: 105, outPut: 105, position: [510, 310] },
|
|
||||||
{ name: "丝印机", inputNum: 100, outPut: 100, position: [521, 4] },
|
|
||||||
{ name: "丝印机", inputNum: 101, outPut: 101, position: [520, 90] },
|
|
||||||
{ name: "丝印机", inputNum: 105, outPut: 105, position: [672, 226] },
|
|
||||||
{ name: "一次固化", inputNum: 100, outPut: 100, position: [756, 2] },
|
|
||||||
{ name: "一次固化", inputNum: 101, outPut: 101, position: [833, 90] },
|
|
||||||
{ name: "一次固化", inputNum: 105, outPut: 105, position: [835, 186] },
|
|
||||||
],
|
|
||||||
"Line1-2": [
|
|
||||||
{ name: "退火", inputNum: 100, outPut: 100, position: [100, 210] },
|
|
||||||
{ name: "铺纸机", inputNum: 100, outPut: 100, position: [410, 58] },
|
|
||||||
{ name: "铺纸机", inputNum: 100, outPut: 100, position: [594, 252] },
|
|
||||||
{ name: "下片机", inputNum: 100, outPut: 100, position: [610, 5] },
|
|
||||||
{ name: "下片机", inputNum: 100, outPut: 100, position: [838, 1] },
|
|
||||||
{ name: "下片机", inputNum: 100, outPut: 100, position: [837, 145] },
|
|
||||||
],
|
|
||||||
"Line2-1": [
|
|
||||||
{ name: "磨边机", inputNum: 100, outPut: 100, position: [134, 202] },
|
|
||||||
{ name: "磨边机", inputNum: 105, outPut: 105, position: [342, 400] },
|
|
||||||
{ name: "打孔机", inputNum: 101, outPut: 101, position: [338, 156] },
|
|
||||||
{ name: "打孔机", inputNum: 105, outPut: 105, position: [510, 310] },
|
|
||||||
{ name: "丝印机", inputNum: 101, outPut: 101, position: [520, 90] },
|
|
||||||
{ name: "丝印机", inputNum: 105, outPut: 105, position: [672, 226] },
|
|
||||||
{ name: "一次固化", inputNum: 100, outPut: 100, position: [724, 38] },
|
|
||||||
{ name: "一次固化", inputNum: 105, outPut: 105, position: [835, 186] },
|
|
||||||
],
|
|
||||||
"Line2-2": [
|
|
||||||
{ name: "退火", inputNum: 100, outPut: 100, position: [215, 247] },
|
|
||||||
{ name: "铺纸机", inputNum: 100, outPut: 100, position: [710, 237] },
|
|
||||||
{ name: "下片机", inputNum: 100, outPut: 100, position: [502, 58] },
|
|
||||||
{ name: "下片机", inputNum: 100, outPut: 100, position: [733, 3] },
|
|
||||||
],
|
|
||||||
"Line3-1": [
|
|
||||||
{ name: "磨边机", inputNum: 100, outPut: 100, position: [134, 202] },
|
|
||||||
{ name: "磨边机", inputNum: 105, outPut: 105, position: [342, 400] },
|
|
||||||
{ name: "打孔机", inputNum: 101, outPut: 101, position: [338, 156] },
|
|
||||||
{ name: "打孔机", inputNum: 105, outPut: 105, position: [510, 310] },
|
|
||||||
{ name: "丝印机", inputNum: 101, outPut: 101, position: [520, 90] },
|
|
||||||
{ name: "丝印机", inputNum: 105, outPut: 105, position: [672, 226] },
|
|
||||||
{ name: "一次固化", inputNum: 100, outPut: 100, position: [724, 38] },
|
|
||||||
{ name: "一次固化", inputNum: 105, outPut: 105, position: [835, 186] },
|
|
||||||
],
|
|
||||||
"Line3-2": [
|
|
||||||
{ name: "退火", inputNum: 100, outPut: 100, position: [187, 247] },
|
|
||||||
{ name: "铺纸机", inputNum: 100, outPut: 100, position: [502, 58] },
|
|
||||||
{ name: "下片机", inputNum: 100, outPut: 100, position: [733, 3] },
|
|
||||||
{ name: "下片机", inputNum: 100, outPut: 100, position: [710, 237] },
|
|
||||||
],
|
|
||||||
"Line4-1": [
|
|
||||||
{ name: "磨边机", inputNum: 100, outPut: 100, position: [231, 216] },
|
|
||||||
{ name: "磨边机", inputNum: 105, outPut: 105, position: [403, 400] },
|
|
||||||
{ name: "一次固化", inputNum: 101, outPut: 101, position: [520, 90] },
|
|
||||||
{ name: "一次固化", inputNum: 105, outPut: 105, position: [643, 276] },
|
|
||||||
{ name: "二次固化", inputNum: 100, outPut: 100, position: [724, 38] },
|
|
||||||
{ name: "二次固化", inputNum: 105, outPut: 105, position: [835, 186] },
|
|
||||||
],
|
|
||||||
"Line4-2": [
|
|
||||||
{ name: "退火", inputNum: 100, outPut: 100, position: [187, 247] },
|
|
||||||
{ name: "铺纸机", inputNum: 100, outPut: 100, position: [710, 237] },
|
|
||||||
{ name: "铺纸机", inputNum: 100, outPut: 100, position: [820, 237] },
|
|
||||||
{ name: "下片机", inputNum: 100, outPut: 100, position: [553, 7] },
|
|
||||||
{ name: "下片机", inputNum: 100, outPut: 100, position: [839, 137] },
|
|
||||||
],
|
|
||||||
"Line5-1": [
|
|
||||||
{ name: "磨边机", inputNum: 100, outPut: 100, position: [134, 202] },
|
|
||||||
{ name: "磨边机", inputNum: 101, outPut: 101, position: [82, 306] },
|
|
||||||
{ name: "磨边机", inputNum: 105, outPut: 105, position: [342, 400] },
|
|
||||||
{ name: "一次固化", inputNum: 100, outPut: 100, position: [521, 4] },
|
|
||||||
{ name: "一次固化", inputNum: 101, outPut: 101, position: [520, 90] },
|
|
||||||
{ name: "一次固化", inputNum: 105, outPut: 105, position: [672, 287] },
|
|
||||||
{ name: "二次固化", inputNum: 100, outPut: 100, position: [756, 2] },
|
|
||||||
{ name: "二次固化", inputNum: 101, outPut: 101, position: [833, 90] },
|
|
||||||
{ name: "二次固化", inputNum: 105, outPut: 105, position: [835, 186] },
|
|
||||||
],
|
|
||||||
"Line5-2": [
|
|
||||||
{ name: "退火", inputNum: 100, outPut: 100, position: [100, 270] },
|
|
||||||
{ name: "铺纸机", inputNum: 100, outPut: 100, position: [434, 133] },
|
|
||||||
{ name: "铺纸机", inputNum: 100, outPut: 100, position: [640, 305] },
|
|
||||||
{ name: "下片机", inputNum: 100, outPut: 100, position: [645, 54] },
|
|
||||||
{ name: "下片机", inputNum: 100, outPut: 100, position: [838, 1] },
|
|
||||||
{ name: "下片机", inputNum: 100, outPut: 100, position: [837, 226] },
|
|
||||||
],
|
|
||||||
};
|
|
||||||
interface EqInfoInterface {
|
|
||||||
name: string;
|
|
||||||
data: Array<{ name: string; value: number }>;
|
|
||||||
position: Array<number>;
|
|
||||||
}
|
|
||||||
interface EqInfoDataInterface {
|
|
||||||
[key: string]: Array<EqInfoInterface>;
|
|
||||||
}
|
|
||||||
const eqInfoData: EqInfoDataInterface = {
|
|
||||||
"Line5-1": [
|
|
||||||
{
|
|
||||||
name: "磨边进口",
|
|
||||||
data: [
|
|
||||||
{ name: "1支线", value: 413 },
|
|
||||||
{ name: "2支线", value: 435 },
|
|
||||||
{ name: "3支线", value: 397 },
|
|
||||||
],
|
|
||||||
position: [154, 266],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "磨边清洗出口",
|
|
||||||
data: [
|
|
||||||
{ name: "1支线", value: 401 },
|
|
||||||
{ name: "2支线", value: 418 },
|
|
||||||
{ name: "3支线", value: 389 },
|
|
||||||
],
|
|
||||||
position: [331, 177],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "一次镀膜进口",
|
|
||||||
data: [
|
|
||||||
{ name: "1支线", value: 400 },
|
|
||||||
{ name: "2支线", value: 418 },
|
|
||||||
{ name: "3支线", value: 388 },
|
|
||||||
],
|
|
||||||
position: [555, 329],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "二次镀膜进口",
|
|
||||||
data: [
|
|
||||||
{ name: "1支线", value: 387 },
|
|
||||||
{ name: "2支线", value: 399 },
|
|
||||||
{ name: "3支线", value: 381 },
|
|
||||||
],
|
|
||||||
position: [550, 85],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "二次固化出口",
|
|
||||||
data: [
|
|
||||||
{ name: "1支线", value: 384 },
|
|
||||||
{ name: "2支线", value: 398 },
|
|
||||||
{ name: "3支线", value: 377 },
|
|
||||||
],
|
|
||||||
position: [857, 184],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "钢化进口",
|
|
||||||
data: [{ name: "钢化进口", value: 1157 }],
|
|
||||||
position: [870, 48],
|
|
||||||
},
|
|
||||||
],
|
|
||||||
"Line5-2": [
|
|
||||||
{
|
|
||||||
name: "钢化出口",
|
|
||||||
data: [{ name: "钢化出口", value: 1124 }],
|
|
||||||
position: [305, 255],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "包装清洗机入口",
|
|
||||||
data: [
|
|
||||||
{ name: "包装清洗机5_1", value: 515 },
|
|
||||||
{ name: "包装清洗机5_2", value: 507 },
|
|
||||||
],
|
|
||||||
position: [508, 319],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "包装清洗机出口",
|
|
||||||
data: [
|
|
||||||
{ name: "包装清洗机5_1", value: 515 },
|
|
||||||
{ name: "包装清洗机5_2", value: 505 },
|
|
||||||
],
|
|
||||||
position: [444, 159],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "铺纸机",
|
|
||||||
data: [
|
|
||||||
{ name: "铺纸机5_1", value: 509 },
|
|
||||||
{ name: "铺纸机5_2", value: 504 },
|
|
||||||
],
|
|
||||||
position: [696, 272],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "下片机械手",
|
|
||||||
data: [
|
|
||||||
{ name: "下片机械手5_1", value: 347 },
|
|
||||||
{ name: "下片机械手5_2", value: 334 },
|
|
||||||
{ name: "下片机械手5_3", value: 316 },
|
|
||||||
],
|
|
||||||
position: [712, 28],
|
|
||||||
},
|
|
||||||
],
|
|
||||||
};
|
|
||||||
interface EqStatusListInterface {
|
|
||||||
[key: string]: Array<{
|
|
||||||
equipment: string;
|
|
||||||
alarm: boolean;
|
|
||||||
online: boolean;
|
|
||||||
}>;
|
|
||||||
}
|
|
||||||
const eqStatusList: EqStatusListInterface = {
|
|
||||||
"Line5-1": [
|
|
||||||
{ equipment: "磨边机5_1", alarm: false, online: true },
|
|
||||||
{ equipment: "磨边机5_2", alarm: false, online: true },
|
|
||||||
{ equipment: "磨边机5_3", alarm: false, online: true },
|
|
||||||
{ equipment: "清洗机5_1", alarm: false, online: true },
|
|
||||||
{ equipment: "清洗机5_2", alarm: false, online: true },
|
|
||||||
{ equipment: "清洗机5_3", alarm: false, online: true },
|
|
||||||
{ equipment: "一次镀膜5_2", alarm: false, online: true },
|
|
||||||
{ equipment: "一次镀膜5_3", alarm: false, online: true },
|
|
||||||
{ equipment: "一次固化5_1", alarm: false, online: true },
|
|
||||||
{ equipment: "一次镀膜5_1", alarm: false, online: true },
|
|
||||||
{ equipment: "一次固化5_2", alarm: false, online: true },
|
|
||||||
{ equipment: "一次固化5_3", alarm: false, online: true },
|
|
||||||
{ equipment: "二次镀膜5_1", alarm: false, online: true },
|
|
||||||
{ equipment: "二次镀膜5_2", alarm: false, online: true },
|
|
||||||
{ equipment: "二次镀膜5_3", alarm: false, online: true },
|
|
||||||
{ equipment: "二次固化5_1", alarm: false, online: true },
|
|
||||||
{ equipment: "二次固化5_2", alarm: false, online: true },
|
|
||||||
{ equipment: "二次固化5_3", alarm: false, online: true },
|
|
||||||
],
|
|
||||||
"Line5-2": [
|
|
||||||
{ equipment: "钢化炉5", alarm: false, online: true },
|
|
||||||
{ equipment: "包装清洗机5_1", alarm: false, online: true },
|
|
||||||
{ equipment: "包装清洗机5_2", alarm: false, online: true },
|
|
||||||
{ equipment: "在线铺纸机5_1", alarm: false, online: true },
|
|
||||||
{ equipment: "在线铺纸机5_2", alarm: false, online: true },
|
|
||||||
{ equipment: "下片机械手5_1", alarm: false, online: true },
|
|
||||||
{ equipment: "下片机械手5_2", alarm: false, online: true },
|
|
||||||
{ equipment: "下片机械手5_3", alarm: false, online: true },
|
|
||||||
],
|
|
||||||
};
|
|
||||||
function MybabylonJS({ modelPath }: MybabylonJSProps) {
|
|
||||||
console.log("modelPath:;;;;;;", modelPath);
|
|
||||||
// const EquStatus = useAppSelector(selectEquStatus);
|
|
||||||
const canvasRef = useRef(null);
|
|
||||||
const resetRef = useRef<(() => void) | null>(null);
|
|
||||||
// onEquObservable.notifyObservers(EquStatus);
|
|
||||||
const [selectedMeshName, setSelectedMeshName] = useState<string | null>(null);
|
|
||||||
const [selectedMeshObj, setSelectedMeshObj] = useState({
|
|
||||||
equipment: "",
|
|
||||||
alarm: false,
|
|
||||||
online: true,
|
|
||||||
});
|
|
||||||
const [showInfo, setShowInfo] = useState(true);
|
|
||||||
|
|
||||||
// 使用 useRef 来存储当前加载的模型引用
|
|
||||||
const currentMeshesRef = useRef<Array<BABYLON.AbstractMesh>>([]);
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
console.log("canvasRef++++++", canvasRef);
|
|
||||||
console.log("resetRef++++++", resetRef);
|
|
||||||
// 确保 canvas 引用存在
|
|
||||||
if (!canvasRef.current) return;
|
|
||||||
const canvas = canvasRef.current;
|
|
||||||
const engine = new BABYLON.Engine(canvas, true, {
|
|
||||||
preserveDrawingBuffer: true,
|
|
||||||
stencil: true,
|
|
||||||
});
|
|
||||||
|
|
||||||
const createScene = async function () {
|
|
||||||
// This creates a basic Babylon Scene object (non-mesh)
|
|
||||||
const scene = new BABYLON.Scene(engine);
|
|
||||||
scene.clearColor = new BABYLON.Color4(0, 0, 0, 0);
|
|
||||||
const baseLight = new HemisphericLight(
|
|
||||||
"hemiLight",
|
|
||||||
new Vector3(-1, 1, 0),
|
|
||||||
scene
|
|
||||||
);
|
|
||||||
baseLight.intensity = 1;
|
|
||||||
baseLight.diffuse = new BABYLON.Color3(1, 1, 1);
|
|
||||||
baseLight.specular = new BABYLON.Color3(0.25, 0.25, 0.25);
|
|
||||||
baseLight.groundColor = new BABYLON.Color3(0.5, 0.5, 0.5);
|
|
||||||
|
|
||||||
//add an arcRotateCamera to the scene
|
|
||||||
const camera = new BABYLON.ArcRotateCamera(
|
|
||||||
"camera",
|
|
||||||
BABYLON.Tools.ToRadians(245),
|
|
||||||
BABYLON.Tools.ToRadians(25),
|
|
||||||
modelPath.slice(-1) === "1"
|
|
||||||
? 110
|
|
||||||
: modelPath.slice(-3) === "5-2"
|
|
||||||
? 100
|
|
||||||
: 75,
|
|
||||||
new BABYLON.Vector3(-13, 0, 0)
|
|
||||||
);
|
|
||||||
camera.lowerRadiusLimit = 10;
|
|
||||||
camera.upperRadiusLimit = 600;
|
|
||||||
|
|
||||||
// This attaches the camera to the canvas
|
|
||||||
camera.attachControl(canvas, true);
|
|
||||||
|
|
||||||
//创建一个材质
|
|
||||||
const newMt = new BABYLON.StandardMaterial("newMt");
|
|
||||||
newMt.diffuseColor = BABYLON.Color3.Blue();
|
|
||||||
|
|
||||||
const ground = BABYLON.MeshBuilder.CreateGround(
|
|
||||||
"ground",
|
|
||||||
{
|
|
||||||
width: 1000,
|
|
||||||
height: 1000,
|
|
||||||
subdivisions: 1,
|
|
||||||
},
|
|
||||||
scene
|
|
||||||
);
|
|
||||||
|
|
||||||
ground.scaling.x = 100;
|
|
||||||
ground.scaling.z = ground.scaling.x;
|
|
||||||
ground.isPickable = false;
|
|
||||||
|
|
||||||
let grid = new GridMaterial("grid", scene);
|
|
||||||
|
|
||||||
grid.majorUnitFrequency = 10;
|
|
||||||
grid.minorUnitVisibility = 0.3;
|
|
||||||
grid.gridRatio = 0.04;
|
|
||||||
grid.backFaceCulling = !1;
|
|
||||||
grid.mainColor = new BABYLON.Color3(1, 1, 1);
|
|
||||||
grid.lineColor = new BABYLON.Color3(1, 1, 1);
|
|
||||||
grid.opacity = 0;
|
|
||||||
grid.zOffset = 1;
|
|
||||||
grid.opacityTexture = new BABYLON.Texture(
|
|
||||||
"/public/png/backgroundGround.png",
|
|
||||||
scene
|
|
||||||
);
|
|
||||||
ground.material = grid;
|
|
||||||
|
|
||||||
let hl = new BABYLON.HighlightLayer("hl1", scene);
|
|
||||||
let hl2 = new BABYLON.HighlightLayer("hl2", scene);
|
|
||||||
|
|
||||||
// 定义一个函数来加载或重新加载模型
|
|
||||||
const loadOrReloadModel = async () => {
|
|
||||||
// 在加载新模型之前卸载已加载的模型
|
|
||||||
currentMeshesRef.current.forEach((mesh) => {
|
|
||||||
if (mesh && mesh.parent) {
|
|
||||||
scene.removeMesh(mesh, true);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
currentMeshesRef.current = []; // 重置模型数组
|
|
||||||
try {
|
|
||||||
// 使用 ImportMeshAsync 加载新模型
|
|
||||||
var LOD0MESH = await BABYLON.SceneLoader.ImportMeshAsync(
|
|
||||||
"",
|
|
||||||
"/Line/",
|
|
||||||
`${modelPath}.babylon`,
|
|
||||||
scene
|
|
||||||
);
|
|
||||||
// 将新加载的模型添加到 currentMeshesRef 中
|
|
||||||
currentMeshesRef.current.push(...LOD0MESH.meshes);
|
|
||||||
|
|
||||||
// ...为新加载的模型设置交互逻辑
|
|
||||||
|
|
||||||
LOD0MESH.meshes.map((mesh) => {
|
|
||||||
mesh.isPickable = true;
|
|
||||||
mesh.actionManager = new BABYLON.ActionManager(scene);
|
|
||||||
// console.log("mesh==========", mesh);
|
|
||||||
if (modelPath.slice(-1) === "1") {
|
|
||||||
if (
|
|
||||||
mesh.name.includes("磨边") ||
|
|
||||||
mesh.name.includes("清洗") ||
|
|
||||||
mesh.name.includes("镀膜") ||
|
|
||||||
mesh.name.includes("固化")
|
|
||||||
) {
|
|
||||||
// @ts-ignore
|
|
||||||
hl.addMesh(mesh, BABYLON.Color3.Green());
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (
|
|
||||||
mesh.name.includes("钢化") ||
|
|
||||||
mesh.name.includes("包装") ||
|
|
||||||
mesh.name.includes("铺纸") ||
|
|
||||||
mesh.name.includes("下片机械手")
|
|
||||||
) {
|
|
||||||
// @ts-ignore
|
|
||||||
hl.addMesh(mesh, BABYLON.Color3.Green());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//鼠标移动到物体上亮显
|
|
||||||
// mesh.actionManager.registerAction(
|
|
||||||
// new BABYLON.ExecuteCodeAction(
|
|
||||||
// BABYLON.ActionManager.OnPointerOverTrigger,
|
|
||||||
// (a) => {
|
|
||||||
// console.log("================", a);
|
|
||||||
// // @ts-ignore
|
|
||||||
// hl.addMesh(mesh, BABYLON.Color3.Green());
|
|
||||||
// }
|
|
||||||
// )
|
|
||||||
// );
|
|
||||||
// 鼠标移出物体上不亮
|
|
||||||
// mesh.actionManager.registerAction(
|
|
||||||
// new BABYLON.ExecuteCodeAction(
|
|
||||||
// BABYLON.ActionManager.OnPointerOutTrigger,
|
|
||||||
// () => {
|
|
||||||
// // @ts-ignore
|
|
||||||
// hl.removeMesh(mesh);
|
|
||||||
// }
|
|
||||||
// )
|
|
||||||
// );
|
|
||||||
|
|
||||||
mesh._scene.onPointerDown = async (event, _pickResult) => {
|
|
||||||
const pickInfo = mesh._scene.pick(
|
|
||||||
mesh._scene.pointerX,
|
|
||||||
mesh._scene.pointerY
|
|
||||||
);
|
|
||||||
|
|
||||||
const clickedPosition = _pickResult.pickedPoint;
|
|
||||||
//如果需要获取吗模型根节点,而不是模型中某个组件,请用一下方法
|
|
||||||
// getRootNode(pickInfo.pickedMesh as BABYLON.Node) 如上篇文章getRootNode函数
|
|
||||||
|
|
||||||
//判断是否是右键
|
|
||||||
if (!(event.buttons === 1 && pickInfo.pickedMesh)) return;
|
|
||||||
const MeshName1 = pickInfo.pickedMesh.name.split(".")[0];
|
|
||||||
|
|
||||||
setSelectedMeshName(MeshName1);
|
|
||||||
eqStatusList[modelPath].map((item: any) => {
|
|
||||||
if (item.equipment === MeshName1) {
|
|
||||||
setSelectedMeshObj(item);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
};
|
|
||||||
});
|
|
||||||
|
|
||||||
// onEquObservable.add((eventData, eventState) => {
|
|
||||||
// LOD0MESH.meshes.find((mesh) => {
|
|
||||||
// // @ts-ignore
|
|
||||||
// hl2.removeMesh(mesh);
|
|
||||||
// });
|
|
||||||
// Object.keys(eventData as EquStatusInterface).map((key) => {
|
|
||||||
// // @ts-ignore
|
|
||||||
// if (eventData[key] == 2) {
|
|
||||||
// // @ts-ignore
|
|
||||||
// EquMap[key].map((name) => {
|
|
||||||
// LOD0MESH.meshes.find((mesh) => {
|
|
||||||
// if (mesh.name == name) {
|
|
||||||
// // @ts-ignore
|
|
||||||
// hl2.addMesh(mesh, BABYLON.Color3.Red());
|
|
||||||
// }
|
|
||||||
// });
|
|
||||||
// });
|
|
||||||
// }
|
|
||||||
// });
|
|
||||||
// });
|
|
||||||
} catch (error) {
|
|
||||||
console.error("加载模型失败:", error);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// 调用函数以加载或重新加载模型
|
|
||||||
loadOrReloadModel();
|
|
||||||
|
|
||||||
function reset() {
|
|
||||||
camera.target = new BABYLON.Vector3(-13, 0, 0);
|
|
||||||
camera.alpha = BABYLON.Tools.ToRadians(245);
|
|
||||||
camera.beta = BABYLON.Tools.ToRadians(25);
|
|
||||||
camera.radius =
|
|
||||||
modelPath.slice(-1) === "1"
|
|
||||||
? 110
|
|
||||||
: modelPath.slice(-3) === "5-2"
|
|
||||||
? 100
|
|
||||||
: 75;
|
|
||||||
setShowInfo(true);
|
|
||||||
setSelectedMeshName(null);
|
|
||||||
}
|
|
||||||
// 外部初始位置按钮
|
|
||||||
resetRef.current = reset;
|
|
||||||
|
|
||||||
let resetCamera = setTimeout(reset, 15000);
|
|
||||||
scene.onPointerObservable.add((pointerInfo) => {
|
|
||||||
switch (pointerInfo.type) {
|
|
||||||
case BABYLON.PointerEventTypes.POINTERMOVE:
|
|
||||||
clearTimeout(resetCamera);
|
|
||||||
resetCamera = setTimeout(reset, 15000);
|
|
||||||
setShowInfo(false);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
return scene;
|
|
||||||
};
|
|
||||||
|
|
||||||
// call the createScene function
|
|
||||||
const scene = createScene();
|
|
||||||
|
|
||||||
// run the render loop
|
|
||||||
scene.then(
|
|
||||||
(scene) => {
|
|
||||||
console.log("createScene被调用了=====", scene);
|
|
||||||
engine.runRenderLoop(function () {
|
|
||||||
scene.render();
|
|
||||||
});
|
|
||||||
},
|
|
||||||
(reason) => {
|
|
||||||
console.log("reason=============", reason);
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
// Resize
|
|
||||||
window.addEventListener("resize", function () {
|
|
||||||
engine.resize();
|
|
||||||
});
|
|
||||||
// 组件卸载时的清理逻辑
|
|
||||||
return () => {
|
|
||||||
// 清理场景和引擎资源
|
|
||||||
engine.dispose();
|
|
||||||
};
|
|
||||||
}, [modelPath]);
|
|
||||||
const resetModel = () => {
|
|
||||||
//模型初始位置
|
|
||||||
console.log("回到初始位置");
|
|
||||||
if (resetRef.current) {
|
|
||||||
resetRef.current();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
return (
|
|
||||||
<div style={myStyle}>
|
|
||||||
{/* <h2 className="model_name">当前选择: {selectedMeshName}</h2> */}
|
|
||||||
<div className="model_info">
|
|
||||||
<span className="reset_btn" onClick={resetModel}></span>
|
|
||||||
<span className="title">
|
|
||||||
第{lineNameNo[Number(modelPath.slice(-3,-2))-1]}产线钢化{modelPath.slice(-1) === "1" ? "前段" : "后段"}
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
{selectedMeshName && (
|
|
||||||
<div className="eq_detail_info">
|
|
||||||
<div>
|
|
||||||
<span className="left_name">设备名称:</span>
|
|
||||||
<span className="right_value">{selectedMeshObj.equipment}</span>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<span className="left_name">报警状态:</span>
|
|
||||||
<span className="right_value">
|
|
||||||
{selectedMeshObj.alarm ? (
|
|
||||||
<>
|
|
||||||
<img
|
|
||||||
src={AlarmTipRed}
|
|
||||||
alt=""
|
|
||||||
width={17}
|
|
||||||
style={{ position: "relative", top: "2px", marginRight: 5 }}
|
|
||||||
/>
|
|
||||||
<span>报警</span>
|
|
||||||
</>
|
|
||||||
) : (
|
|
||||||
<>
|
|
||||||
<img
|
|
||||||
src={AlarmTipGreen}
|
|
||||||
alt=""
|
|
||||||
width={17}
|
|
||||||
style={{ position: "relative", top: "2px", marginRight: 5 }}
|
|
||||||
/>
|
|
||||||
<span>正常</span>
|
|
||||||
</>
|
|
||||||
)}
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<span className="left_name">在线状态:</span>
|
|
||||||
<span className="right_value">
|
|
||||||
{selectedMeshObj.online ? (
|
|
||||||
<>
|
|
||||||
<img
|
|
||||||
src={AlarmTipGreen}
|
|
||||||
alt=""
|
|
||||||
width={17}
|
|
||||||
style={{ position: "relative", top: "2px", marginRight: 5 }}
|
|
||||||
/>
|
|
||||||
<span>在线</span>
|
|
||||||
</>
|
|
||||||
) : (
|
|
||||||
<>
|
|
||||||
<img
|
|
||||||
src={AlarmTipYellow}
|
|
||||||
alt=""
|
|
||||||
width={17}
|
|
||||||
style={{ position: "relative", top: "2px", marginRight: 5 }}
|
|
||||||
/>
|
|
||||||
<span>离线</span>
|
|
||||||
</>
|
|
||||||
)}
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
{showInfo &&
|
|
||||||
eqInfoData[modelPath] &&
|
|
||||||
eqInfoData[modelPath].map((item, index) => {
|
|
||||||
return (
|
|
||||||
<div
|
|
||||||
className="eq_info"
|
|
||||||
key={index}
|
|
||||||
style={{ left: item.position[0], top: item.position[1] }}
|
|
||||||
>
|
|
||||||
<div className="eq_info_inner" style={{ color: "#00FFF0" }}>
|
|
||||||
{item.name}
|
|
||||||
</div>
|
|
||||||
{item.data.map((info, index) => {
|
|
||||||
return (
|
|
||||||
<div className="eq_info_inner">
|
|
||||||
{info.name}:{info.value}
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
})}
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
})}
|
|
||||||
|
|
||||||
<canvas ref={canvasRef} style={myStyle} />
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
export default MybabylonJS;
|
|
396
src/babylonjs/LinePageBabylonNew.tsx
Normal file
396
src/babylonjs/LinePageBabylonNew.tsx
Normal file
@ -0,0 +1,396 @@
|
|||||||
|
import { useEffect, useRef, useState } from "react";
|
||||||
|
import * as BABYLON from "@babylonjs/core";
|
||||||
|
import "@babylonjs/core/Debug/debugLayer";
|
||||||
|
import "@babylonjs/inspector";
|
||||||
|
import "@babylonjs/loaders/glTF";
|
||||||
|
import { GridMaterial } from "@babylonjs/materials/";
|
||||||
|
import { HemisphericLight, Vector3 } from "@babylonjs/core";
|
||||||
|
import { useAppSelector } from "../store/hooks";
|
||||||
|
import "../page/style/standard.css";
|
||||||
|
import EqInfoData from "./EqInfoData";
|
||||||
|
import AlarmTipGreen from "./../page/assets/icon/g.png";
|
||||||
|
import AlarmTipYellow from "./../page/assets/icon/y.png";
|
||||||
|
import AlarmTipRed from "./../page/assets/icon/r.png";
|
||||||
|
import {selectLine1Before} from "../store/LinePageSlice";
|
||||||
|
|
||||||
|
const lineNameNo = ["一","二","三","四","五"]
|
||||||
|
const myStyle = {
|
||||||
|
width: "1041px",
|
||||||
|
height: "562px",
|
||||||
|
outline: "none",
|
||||||
|
};
|
||||||
|
interface MybabylonJSProps {
|
||||||
|
modelPath: string; // 明确 modelPath 属性的类型为 string
|
||||||
|
}
|
||||||
|
interface EqListType {
|
||||||
|
[key: string]: EqMsg
|
||||||
|
}
|
||||||
|
interface EqMsg {
|
||||||
|
equipmentName?:string;
|
||||||
|
run?:boolean;
|
||||||
|
error?:boolean;
|
||||||
|
inputNum?:number;
|
||||||
|
outputNum?:number;
|
||||||
|
quantityTime?:number;
|
||||||
|
status?:string;
|
||||||
|
statusTime?:number;
|
||||||
|
localDateTime?:number;
|
||||||
|
equipmentCode?:string;
|
||||||
|
equipmentId?:number;
|
||||||
|
}
|
||||||
|
function MybabylonJS({ modelPath }: MybabylonJSProps) {
|
||||||
|
const [eqList, setEqList] = useState<EqListType>({});
|
||||||
|
const allData = useAppSelector(selectLine1Before) as any; // 使用`any`来绕过类型检查
|
||||||
|
const canvasRef = useRef(null);
|
||||||
|
const resetRef = useRef<(() => void) | null>(null);
|
||||||
|
const [selectedMeshName, setSelectedMeshName] = useState<string | null>(null);
|
||||||
|
const [selectedMeshId, setSelectedMeshId] = useState<string | null>(null);
|
||||||
|
const [selectedMeshObj, setSelectedMeshObj] = useState<EqMsg>({
|
||||||
|
equipmentName: "",
|
||||||
|
run: true,
|
||||||
|
error: false,
|
||||||
|
});
|
||||||
|
const [showInfo, setShowInfo] = useState(true);
|
||||||
|
|
||||||
|
// 使用 useRef 来存储当前加载的模型引用
|
||||||
|
const currentMeshesRef = useRef<Array<BABYLON.AbstractMesh>>([]);
|
||||||
|
useEffect(() => {
|
||||||
|
const equStatus = allData?.equStatus;
|
||||||
|
if (equStatus) {
|
||||||
|
setEqList(equStatus);
|
||||||
|
}
|
||||||
|
},[allData])
|
||||||
|
useEffect(() => {
|
||||||
|
const equStatus = allData?.equStatus;
|
||||||
|
if (equStatus) {
|
||||||
|
for (let i = 0; i < EqInfoData[modelPath].length; i++) {
|
||||||
|
for (let j = 0; j < EqInfoData[modelPath][i].data.length; j++) {
|
||||||
|
EqInfoData[modelPath][i].data[j].value = equStatus[EqInfoData[modelPath][i].data[j].code][EqInfoData[modelPath][i].data[j].label] ? equStatus[EqInfoData[modelPath][i].data[j].code][EqInfoData[modelPath][i].data[j].label] : 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},[allData,modelPath])
|
||||||
|
useEffect(() => {
|
||||||
|
if (selectedMeshId && eqList[selectedMeshId]) {
|
||||||
|
setSelectedMeshObj({
|
||||||
|
equipmentName:eqList[selectedMeshId].equipmentName,
|
||||||
|
run:eqList[selectedMeshId].run ? eqList[selectedMeshId].run : true,
|
||||||
|
error:eqList[selectedMeshId].error ? eqList[selectedMeshId].error : false,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},[selectedMeshId])
|
||||||
|
useEffect(() => {
|
||||||
|
// 确保 canvas 引用存在
|
||||||
|
if (!canvasRef.current) return;
|
||||||
|
const canvas = canvasRef.current;
|
||||||
|
const engine = new BABYLON.Engine(canvas, true, {
|
||||||
|
preserveDrawingBuffer: true,
|
||||||
|
stencil: true,
|
||||||
|
});
|
||||||
|
|
||||||
|
const createScene = async function () {
|
||||||
|
// This creates a basic Babylon Scene object (non-mesh)
|
||||||
|
const scene = new BABYLON.Scene(engine);
|
||||||
|
scene.clearColor = new BABYLON.Color4(0, 0, 0, 0);
|
||||||
|
const baseLight = new HemisphericLight(
|
||||||
|
"hemiLight",
|
||||||
|
new Vector3(-1, 1, 0),
|
||||||
|
scene
|
||||||
|
);
|
||||||
|
baseLight.intensity = 1;
|
||||||
|
baseLight.diffuse = new BABYLON.Color3(1, 1, 1);
|
||||||
|
baseLight.specular = new BABYLON.Color3(0.25, 0.25, 0.25);
|
||||||
|
baseLight.groundColor = new BABYLON.Color3(0.5, 0.5, 0.5);
|
||||||
|
|
||||||
|
//add an arcRotateCamera to the scene
|
||||||
|
const camera = new BABYLON.ArcRotateCamera(
|
||||||
|
"camera",
|
||||||
|
BABYLON.Tools.ToRadians(245),
|
||||||
|
BABYLON.Tools.ToRadians(25),
|
||||||
|
modelPath.slice(-3) === "2-1"
|
||||||
|
? 120
|
||||||
|
: modelPath.slice(-1) === "1"
|
||||||
|
? 110
|
||||||
|
: modelPath.slice(-3) === "5-2"
|
||||||
|
? 100
|
||||||
|
: modelPath.slice(-3) === "1-2"
|
||||||
|
? 90
|
||||||
|
: 65,
|
||||||
|
new BABYLON.Vector3(-13, 0, 0)
|
||||||
|
);
|
||||||
|
camera.lowerRadiusLimit = 10;
|
||||||
|
camera.upperRadiusLimit = 600;
|
||||||
|
|
||||||
|
// This attaches the camera to the canvas
|
||||||
|
camera.attachControl(canvas, true);
|
||||||
|
|
||||||
|
//创建一个材质
|
||||||
|
const newMt = new BABYLON.StandardMaterial("newMt");
|
||||||
|
newMt.diffuseColor = BABYLON.Color3.Blue();
|
||||||
|
|
||||||
|
const ground = BABYLON.MeshBuilder.CreateGround(
|
||||||
|
"ground",
|
||||||
|
{
|
||||||
|
width: 1000,
|
||||||
|
height: 1000,
|
||||||
|
subdivisions: 1,
|
||||||
|
},
|
||||||
|
scene
|
||||||
|
);
|
||||||
|
|
||||||
|
ground.scaling.x = 100;
|
||||||
|
ground.scaling.z = ground.scaling.x;
|
||||||
|
ground.isPickable = false;
|
||||||
|
|
||||||
|
let grid = new GridMaterial("grid", scene);
|
||||||
|
|
||||||
|
grid.majorUnitFrequency = 10;
|
||||||
|
grid.minorUnitVisibility = 0.3;
|
||||||
|
grid.gridRatio = 0.04;
|
||||||
|
grid.backFaceCulling = !1;
|
||||||
|
grid.mainColor = new BABYLON.Color3(1, 1, 1);
|
||||||
|
grid.lineColor = new BABYLON.Color3(1, 1, 1);
|
||||||
|
grid.opacity = 0;
|
||||||
|
grid.zOffset = 1;
|
||||||
|
grid.opacityTexture = new BABYLON.Texture(
|
||||||
|
"/public/png/backgroundGround.png",
|
||||||
|
scene
|
||||||
|
);
|
||||||
|
ground.material = grid;
|
||||||
|
|
||||||
|
let hl = new BABYLON.HighlightLayer("hl1", scene);
|
||||||
|
let hl2 = new BABYLON.HighlightLayer("hl2", scene);
|
||||||
|
|
||||||
|
// 定义一个函数来加载或重新加载模型
|
||||||
|
const loadOrReloadModel = async () => {
|
||||||
|
// 在加载新模型之前卸载已加载的模型
|
||||||
|
currentMeshesRef.current.forEach((mesh) => {
|
||||||
|
if (mesh && mesh.parent) {
|
||||||
|
scene.removeMesh(mesh, true);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
currentMeshesRef.current = []; // 重置模型数组
|
||||||
|
try {
|
||||||
|
// 使用 ImportMeshAsync 加载新模型
|
||||||
|
var LOD0MESH = await BABYLON.SceneLoader.ImportMeshAsync(
|
||||||
|
"",
|
||||||
|
"/Line/",
|
||||||
|
`${modelPath}.babylon`,
|
||||||
|
scene
|
||||||
|
);
|
||||||
|
// 将新加载的模型添加到 currentMeshesRef 中
|
||||||
|
currentMeshesRef.current.push(...LOD0MESH.meshes);
|
||||||
|
|
||||||
|
// ...为新加载的模型设置交互逻辑
|
||||||
|
|
||||||
|
LOD0MESH.meshes.map((mesh) => {
|
||||||
|
mesh.isPickable = true;
|
||||||
|
mesh.actionManager = new BABYLON.ActionManager(scene);
|
||||||
|
if (modelPath.slice(-1) === "1") {
|
||||||
|
if (
|
||||||
|
mesh.name.includes("磨边") ||
|
||||||
|
mesh.name.includes("清洗") ||
|
||||||
|
mesh.name.includes("镀膜") ||
|
||||||
|
mesh.name.includes("固化") ||
|
||||||
|
mesh.name.includes("丝印") ||
|
||||||
|
mesh.name.includes("打孔")
|
||||||
|
) {
|
||||||
|
// @ts-ignore
|
||||||
|
hl.addMesh(mesh, BABYLON.Color3.Green());
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (
|
||||||
|
mesh.name.includes("钢化") ||
|
||||||
|
mesh.name.includes("包装") ||
|
||||||
|
mesh.name.includes("铺纸") ||
|
||||||
|
mesh.name.includes("下片机械手")
|
||||||
|
) {
|
||||||
|
// @ts-ignore
|
||||||
|
hl.addMesh(mesh, BABYLON.Color3.Green());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
mesh._scene.onPointerDown = async (event, _pickResult) => {
|
||||||
|
console.log('_pickResult',_pickResult)
|
||||||
|
const pickInfo = mesh._scene.pick(
|
||||||
|
mesh._scene.pointerX,
|
||||||
|
mesh._scene.pointerY
|
||||||
|
);
|
||||||
|
//判断是否是右键
|
||||||
|
if (!(event.buttons === 1 && pickInfo.pickedMesh)) return;
|
||||||
|
const MeshName = pickInfo.pickedMesh.name;
|
||||||
|
const MeshNameId = pickInfo.pickedMesh.metadata.tags;
|
||||||
|
|
||||||
|
setSelectedMeshName(MeshName);
|
||||||
|
setSelectedMeshId(MeshNameId);
|
||||||
|
};
|
||||||
|
});
|
||||||
|
} catch (error) {
|
||||||
|
console.error("加载模型失败:", error);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// 调用函数以加载或重新加载模型
|
||||||
|
loadOrReloadModel();
|
||||||
|
|
||||||
|
function reset() {
|
||||||
|
camera.target = new BABYLON.Vector3(-13, 0, 0);
|
||||||
|
camera.alpha = BABYLON.Tools.ToRadians(245);
|
||||||
|
camera.beta = BABYLON.Tools.ToRadians(25);
|
||||||
|
camera.radius =
|
||||||
|
modelPath.slice(-3) === "2-1"
|
||||||
|
? 120
|
||||||
|
: modelPath.slice(-1) === "1"
|
||||||
|
? 110
|
||||||
|
: modelPath.slice(-3) === "5-2"
|
||||||
|
? 100
|
||||||
|
: modelPath.slice(-3) === "1-2"
|
||||||
|
? 90
|
||||||
|
: 65
|
||||||
|
setShowInfo(true);
|
||||||
|
setSelectedMeshName(null);
|
||||||
|
}
|
||||||
|
// 外部初始位置按钮
|
||||||
|
resetRef.current = reset;
|
||||||
|
|
||||||
|
let resetCamera = setTimeout(reset, 15000);
|
||||||
|
scene.onPointerObservable.add((pointerInfo) => {
|
||||||
|
switch (pointerInfo.type) {
|
||||||
|
case BABYLON.PointerEventTypes.POINTERMOVE:
|
||||||
|
clearTimeout(resetCamera);
|
||||||
|
resetCamera = setTimeout(reset, 15000);
|
||||||
|
setShowInfo(false);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return scene;
|
||||||
|
};
|
||||||
|
|
||||||
|
// call the createScene function
|
||||||
|
const scene = createScene();
|
||||||
|
|
||||||
|
// run the render loop
|
||||||
|
scene.then(
|
||||||
|
(scene) => {
|
||||||
|
console.log("createScene被调用了=====", scene);
|
||||||
|
engine.runRenderLoop(function () {
|
||||||
|
scene.render();
|
||||||
|
});
|
||||||
|
},
|
||||||
|
(reason) => {
|
||||||
|
console.log("reason=============", reason);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
// Resize
|
||||||
|
window.addEventListener("resize", function () {
|
||||||
|
engine.resize();
|
||||||
|
});
|
||||||
|
// 组件卸载时的清理逻辑
|
||||||
|
return () => {
|
||||||
|
// 清理场景和引擎资源
|
||||||
|
engine.dispose();
|
||||||
|
};
|
||||||
|
}, [modelPath]);
|
||||||
|
const resetModel = () => {
|
||||||
|
//模型初始位置
|
||||||
|
if (resetRef.current) {
|
||||||
|
resetRef.current();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
return (
|
||||||
|
<div style={myStyle}>
|
||||||
|
{/* <h2 className="model_name">当前选择: {selectedMeshName}</h2> */}
|
||||||
|
<div className="model_info">
|
||||||
|
<span className="reset_btn" onClick={resetModel}></span>
|
||||||
|
<span className="title">
|
||||||
|
第{lineNameNo[Number(modelPath.slice(-3,-2))-1]}产线钢化{modelPath.slice(-1) === "1" ? "前段" : "后段"}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
{selectedMeshName && (
|
||||||
|
<div className="eq_detail_info">
|
||||||
|
<div>
|
||||||
|
<span className="left_name">设备名称:</span>
|
||||||
|
<span className="right_value">{selectedMeshObj.equipmentName}</span>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<span className="left_name">报警状态:</span>
|
||||||
|
<span className="right_value">
|
||||||
|
{selectedMeshObj.error ? (
|
||||||
|
<>
|
||||||
|
<img
|
||||||
|
src={AlarmTipRed}
|
||||||
|
alt=""
|
||||||
|
width={17}
|
||||||
|
style={{ position: "relative", top: "2px", marginRight: 5 }}
|
||||||
|
/>
|
||||||
|
<span>报警</span>
|
||||||
|
</>
|
||||||
|
) : (
|
||||||
|
<>
|
||||||
|
<img
|
||||||
|
src={AlarmTipGreen}
|
||||||
|
alt=""
|
||||||
|
width={17}
|
||||||
|
style={{ position: "relative", top: "2px", marginRight: 5 }}
|
||||||
|
/>
|
||||||
|
<span>正常</span>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<span className="left_name">在线状态:</span>
|
||||||
|
<span className="right_value">
|
||||||
|
{selectedMeshObj.run ? (
|
||||||
|
<>
|
||||||
|
<img
|
||||||
|
src={AlarmTipGreen}
|
||||||
|
alt=""
|
||||||
|
width={17}
|
||||||
|
style={{ position: "relative", top: "2px", marginRight: 5 }}
|
||||||
|
/>
|
||||||
|
<span>在线</span>
|
||||||
|
</>
|
||||||
|
) : (
|
||||||
|
<>
|
||||||
|
<img
|
||||||
|
src={AlarmTipYellow}
|
||||||
|
alt=""
|
||||||
|
width={17}
|
||||||
|
style={{ position: "relative", top: "2px", marginRight: 5 }}
|
||||||
|
/>
|
||||||
|
<span>离线</span>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
{showInfo &&
|
||||||
|
EqInfoData[modelPath] &&
|
||||||
|
EqInfoData[modelPath].map((item) => {
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
className="eq_info"
|
||||||
|
key={item.data[0].code+item.data[0].label}
|
||||||
|
style={{ left: item.position[0], top: item.position[1] }}
|
||||||
|
>
|
||||||
|
<div className="eq_info_inner" style={{ color: "#00FFF0" }}>
|
||||||
|
{item.name}
|
||||||
|
</div>
|
||||||
|
{item.data.map((info) => {
|
||||||
|
return (
|
||||||
|
<div className="eq_info_inner" key={info.code+info.label}>
|
||||||
|
{info.name}:{info.value}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
|
||||||
|
<canvas ref={canvasRef} style={myStyle} />
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default MybabylonJS;
|
@ -1,18 +1,20 @@
|
|||||||
import * as echarts from "echarts";
|
import * as echarts from "echarts";
|
||||||
export default function getOptions(dataProps: number[], color: string[]) {
|
export default function getOptions(dataProps: number[],xData:string[], color: string[]) {
|
||||||
if (dataProps.length === 0) return null;
|
if (dataProps.length === 0) return null;
|
||||||
return {
|
return {
|
||||||
grid: { top: 30, right: 12, bottom: 26, left: 48 },
|
grid: { top: 30, right: 10, bottom: 5, left: 10, containLabel: true },
|
||||||
legend: {
|
legend: {
|
||||||
show: false,
|
show: false,
|
||||||
},
|
},
|
||||||
xAxis: {
|
xAxis: {
|
||||||
type: "category",
|
type: "category",
|
||||||
data: ["磨边后", "包装1", "包装2"],
|
data: xData,
|
||||||
axisLabel: {
|
axisLabel: {
|
||||||
color: "#fff",
|
color: "#fff",
|
||||||
fontSize: 14,
|
fontSize: 10,
|
||||||
interval: 0,
|
interval: 0,
|
||||||
|
rotate:20
|
||||||
|
|
||||||
},
|
},
|
||||||
axisTick: { show: false },
|
axisTick: { show: false },
|
||||||
axisLine: {
|
axisLine: {
|
||||||
@ -26,12 +28,12 @@ export default function getOptions(dataProps: number[], color: string[]) {
|
|||||||
name: "单位/片",
|
name: "单位/片",
|
||||||
nameTextStyle: {
|
nameTextStyle: {
|
||||||
color: "#fff",
|
color: "#fff",
|
||||||
fontSize: 14,
|
fontSize: 12,
|
||||||
},
|
},
|
||||||
type: "value",
|
type: "value",
|
||||||
axisLabel: {
|
axisLabel: {
|
||||||
color: "#fff",
|
color: "#fff",
|
||||||
fontSize: 14,
|
fontSize: 12,
|
||||||
formatter: "{value}",
|
formatter: "{value}",
|
||||||
},
|
},
|
||||||
axisLine: {
|
axisLine: {
|
126
src/page/Component/BarLineChart/chart.config.ts
Normal file
126
src/page/Component/BarLineChart/chart.config.ts
Normal file
@ -0,0 +1,126 @@
|
|||||||
|
import * as echarts from "echarts";
|
||||||
|
export default function getOptions(dataProps:any) {
|
||||||
|
if (dataProps.length === 0) return null;
|
||||||
|
return {
|
||||||
|
grid: { top: 40, right: 10, bottom: 5, left: 10, containLabel: true },
|
||||||
|
legend: {
|
||||||
|
show: false,
|
||||||
|
},
|
||||||
|
xAxis: {
|
||||||
|
type: "category",
|
||||||
|
data: dataProps.time,
|
||||||
|
axisLabel: {
|
||||||
|
color: "#fff",
|
||||||
|
fontSize: 12,
|
||||||
|
interval: 0,
|
||||||
|
rotate:20
|
||||||
|
},
|
||||||
|
axisTick: { show: false },
|
||||||
|
axisLine: {
|
||||||
|
lineStyle: {
|
||||||
|
width: 2,
|
||||||
|
color: "#5982B2",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
yAxis: [{
|
||||||
|
name: "单位/片",
|
||||||
|
nameTextStyle: {
|
||||||
|
color: "#fff",
|
||||||
|
fontSize: 12,
|
||||||
|
},
|
||||||
|
type: "value",
|
||||||
|
axisLabel: {
|
||||||
|
color: "#fff",
|
||||||
|
fontSize: 12,
|
||||||
|
formatter: "{value}",
|
||||||
|
},
|
||||||
|
axisLine: {
|
||||||
|
show: true,
|
||||||
|
lineStyle: {
|
||||||
|
width: 2,
|
||||||
|
color: "#5982B2",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
splitLine: {
|
||||||
|
lineStyle: {
|
||||||
|
width: 2,
|
||||||
|
color: "#5982B2",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},{
|
||||||
|
name: "良品率/%",
|
||||||
|
nameTextStyle: {
|
||||||
|
color: "#fff",
|
||||||
|
fontSize: 12,
|
||||||
|
},
|
||||||
|
type: "value",
|
||||||
|
axisLabel: {
|
||||||
|
color: "#fff",
|
||||||
|
fontSize: 12,
|
||||||
|
formatter: "{value}",
|
||||||
|
},
|
||||||
|
axisLine: {
|
||||||
|
show: true,
|
||||||
|
lineStyle: {
|
||||||
|
width: 2,
|
||||||
|
color: "#5982B2",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
splitLine: {
|
||||||
|
lineStyle: {
|
||||||
|
width: 2,
|
||||||
|
color: "#5982B2",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}],
|
||||||
|
tooltip: {
|
||||||
|
trigger: "axis",
|
||||||
|
axisPointer: {
|
||||||
|
type: "shadow",
|
||||||
|
},
|
||||||
|
className: "luoyang-chart-tooltip",
|
||||||
|
show: false,
|
||||||
|
},
|
||||||
|
series: [
|
||||||
|
{
|
||||||
|
data: dataProps.input,
|
||||||
|
type: "bar",
|
||||||
|
barWidth: 10,
|
||||||
|
barGap:0,
|
||||||
|
itemStyle: {
|
||||||
|
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
|
||||||
|
{ offset: 0, color: 'rgba(157, 234, 245, 1)' },
|
||||||
|
{ offset: 1, color: 'rgba(110, 249, 222, 1)' },
|
||||||
|
]),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
data:dataProps.output,
|
||||||
|
type: "bar",
|
||||||
|
barWidth: 10,
|
||||||
|
itemStyle: {
|
||||||
|
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
|
||||||
|
{ offset: 0, color: 'rgba(92, 183, 255, 1)' },
|
||||||
|
{ offset: 1, color: 'rgba(54, 75, 254, 1)' },
|
||||||
|
]),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
data: dataProps.yield,
|
||||||
|
type: "line",
|
||||||
|
yAxisIndex: 1,
|
||||||
|
symbol:'circle',
|
||||||
|
symbolSize: 7,
|
||||||
|
color:'rgba(18, 255, 245, 1)',
|
||||||
|
areaStyle: {
|
||||||
|
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
|
||||||
|
{ offset: 0, color: 'rgba(18, 255, 245, 0.8)' },
|
||||||
|
{ offset: 0.2, color: 'rgba(18, 255, 245, 0.2)' },
|
||||||
|
{ offset: 0.4, color: 'rgba(18, 255, 245, 0)' },
|
||||||
|
]),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
};
|
||||||
|
}
|
@ -1,36 +0,0 @@
|
|||||||
import React, {useState} from "react";
|
|
||||||
import intl from "react-intl-universal";
|
|
||||||
import '../../lanhuapp/common.css';
|
|
||||||
import "../../lanhuapp/index.css";
|
|
||||||
|
|
||||||
function ChangeFullButton() {
|
|
||||||
const [isFull, setIsFull] = useState(false);
|
|
||||||
|
|
||||||
function fullExit() {
|
|
||||||
let element = document.documentElement;
|
|
||||||
|
|
||||||
//HTML5 W3C 提议
|
|
||||||
document.exitFullscreen();
|
|
||||||
|
|
||||||
setIsFull(false)
|
|
||||||
}
|
|
||||||
|
|
||||||
function fullScreen() {
|
|
||||||
let element = document.documentElement;
|
|
||||||
|
|
||||||
//HTML W3C 提议
|
|
||||||
element.requestFullscreen();
|
|
||||||
|
|
||||||
setIsFull(true)
|
|
||||||
}
|
|
||||||
|
|
||||||
const click = () => {
|
|
||||||
isFull ? fullExit() : fullScreen();
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
|
||||||
<button className="section_1 flex-col" onClick={click}/>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
export default ChangeFullButton;
|
|
@ -1,19 +0,0 @@
|
|||||||
import React from "react";
|
|
||||||
import intl from "react-intl-universal";
|
|
||||||
import '../../lanhuapp/common.css';
|
|
||||||
import "../../lanhuapp/index.css";
|
|
||||||
import {useAppDispatch} from "../../store/hooks";
|
|
||||||
import {UpdateChangeLangAndCss} from "../../store/ChangeLangAndCss";
|
|
||||||
|
|
||||||
function ChangeLangButton() {
|
|
||||||
const dispatch = useAppDispatch();
|
|
||||||
const changeTitle = () => {
|
|
||||||
dispatch(UpdateChangeLangAndCss())
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
|
||||||
<button className="box_76 flex-col" onClick={changeTitle}/>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
export default ChangeLangButton;
|
|
@ -2,13 +2,13 @@ export default function getOptions(chartData: any) {
|
|||||||
if (Object.keys(chartData).length === 0) {
|
if (Object.keys(chartData).length === 0) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
const colors = ["#1A99FF", "#FFB70C", "#C69DFF", "#50F4E3", "#E02094"];
|
const colors = ["#2760FF", "#8167F6", "#5B9BFF", "#99D66C", "#FFD160","#D680FF","#FF6860"];
|
||||||
return {
|
return {
|
||||||
color: colors,
|
color: colors,
|
||||||
grid: { top: 38, right: 12, bottom: 26, left: 48 },
|
grid: { top: 50, right: 12, bottom: 5, left: 15, containLabel: true },
|
||||||
legend: {
|
legend: {
|
||||||
show: true,
|
show: true,
|
||||||
top: 10,
|
top: 5,
|
||||||
right: 10,
|
right: 10,
|
||||||
padding: 0,
|
padding: 0,
|
||||||
itemWidth: 14,
|
itemWidth: 14,
|
||||||
@ -17,12 +17,13 @@ export default function getOptions(chartData: any) {
|
|||||||
height: 10,
|
height: 10,
|
||||||
textStyle: {
|
textStyle: {
|
||||||
color: "#DFF1FE",
|
color: "#DFF1FE",
|
||||||
fontSize: 14,
|
fontSize: 12,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
xAxis: {
|
xAxis: {
|
||||||
type: "category",
|
type: "category",
|
||||||
data: ["8/22", "8/23", "8/24", "8/25", "8/26", "8/27", "8/28"],
|
data: chartData.xData,
|
||||||
|
// data: ["8/22", "8/23", "8/24", "8/25", "8/26", "8/27", "8/28"],
|
||||||
// data: Array(7)
|
// data: Array(7)
|
||||||
// .fill(1)
|
// .fill(1)
|
||||||
// .map((_, index) => {
|
// .map((_, index) => {
|
||||||
@ -36,7 +37,7 @@ export default function getOptions(chartData: any) {
|
|||||||
// .reverse(),
|
// .reverse(),
|
||||||
axisLabel: {
|
axisLabel: {
|
||||||
color: "#fff",
|
color: "#fff",
|
||||||
fontSize: 14,
|
fontSize: 12,
|
||||||
},
|
},
|
||||||
axisTick: { show: false },
|
axisTick: { show: false },
|
||||||
axisLine: {
|
axisLine: {
|
||||||
@ -51,12 +52,12 @@ export default function getOptions(chartData: any) {
|
|||||||
min: 50,
|
min: 50,
|
||||||
nameTextStyle: {
|
nameTextStyle: {
|
||||||
color: "#fff",
|
color: "#fff",
|
||||||
fontSize: 14,
|
fontSize: 12,
|
||||||
},
|
},
|
||||||
type: "value",
|
type: "value",
|
||||||
axisLabel: {
|
axisLabel: {
|
||||||
color: "#fff",
|
color: "#fff",
|
||||||
fontSize: 14,
|
fontSize: 12,
|
||||||
formatter: "{value}",
|
formatter: "{value}",
|
||||||
},
|
},
|
||||||
axisLine: {
|
axisLine: {
|
||||||
@ -78,42 +79,43 @@ export default function getOptions(chartData: any) {
|
|||||||
className: "luoyang-chart-tooltip",
|
className: "luoyang-chart-tooltip",
|
||||||
show: false,
|
show: false,
|
||||||
},
|
},
|
||||||
series: [
|
series:chartData.series
|
||||||
{
|
// series: [
|
||||||
name: "产线1",
|
// {
|
||||||
type: "line",
|
// name: "产线1",
|
||||||
symbol: "circle",
|
// type: "line",
|
||||||
symbolSize: 4,
|
// symbol: "circle",
|
||||||
data: chartData.yData1,
|
// symbolSize: 4,
|
||||||
},
|
// data: chartData.yData[0],
|
||||||
{
|
// },
|
||||||
name: "产线2",
|
// {
|
||||||
type: "line",
|
// name: "产线2",
|
||||||
symbol: "circle",
|
// type: "line",
|
||||||
symbolSize: 4,
|
// symbol: "circle",
|
||||||
data: chartData.yData2,
|
// symbolSize: 4,
|
||||||
},
|
// data: chartData.yData[1],
|
||||||
{
|
// },
|
||||||
name: "产线3",
|
// {
|
||||||
type: "line",
|
// name: "产线3",
|
||||||
symbol: "circle",
|
// type: "line",
|
||||||
symbolSize: 4,
|
// symbol: "circle",
|
||||||
data: chartData.yData3,
|
// symbolSize: 4,
|
||||||
},
|
// data: chartData.yData[2],
|
||||||
{
|
// },
|
||||||
name: "产线4",
|
// {
|
||||||
type: "line",
|
// name: "产线4",
|
||||||
symbol: "circle",
|
// type: "line",
|
||||||
symbolSize: 4,
|
// symbol: "circle",
|
||||||
data: chartData.yData4,
|
// symbolSize: 4,
|
||||||
},
|
// data: chartData.yData[3],
|
||||||
{
|
// },
|
||||||
name: "产线5",
|
// {
|
||||||
type: "line",
|
// name: "产线5",
|
||||||
symbol: "circle",
|
// type: "line",
|
||||||
symbolSize: 4,
|
// symbol: "circle",
|
||||||
data: chartData.yData5,
|
// symbolSize: 4,
|
||||||
},
|
// data: chartData.yData[4],
|
||||||
],
|
// },
|
||||||
|
// ],
|
||||||
};
|
};
|
||||||
}
|
}
|
@ -6,20 +6,19 @@ export default function getOptions(tempData: any) {
|
|||||||
const colors = ["#1A99FF", "#50F4E3"];
|
const colors = ["#1A99FF", "#50F4E3"];
|
||||||
return {
|
return {
|
||||||
color: colors,
|
color: colors,
|
||||||
grid: { top: 30, right: 12, bottom: 10, left: 10, containLabel: true },
|
grid: { top: 30, right: 12, bottom: 10, left: 5, containLabel: true },
|
||||||
legend: {
|
legend: {
|
||||||
show: true,
|
show: true,
|
||||||
icon: "roundRect",
|
|
||||||
top: 10,
|
top: 10,
|
||||||
right: 10,
|
right: 10,
|
||||||
padding: 0,
|
padding: 0,
|
||||||
itemWidth: 10,
|
itemWidth: 14,
|
||||||
itemHeight: 10,
|
itemHeight: 10,
|
||||||
itemGap: 3,
|
itemGap: 8,
|
||||||
height: 10,
|
height: 10,
|
||||||
textStyle: {
|
textStyle: {
|
||||||
color: "#DFF1FE",
|
color: "#DFF1FE",
|
||||||
fontSize: 14,
|
fontSize: 12,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
xAxis: {
|
xAxis: {
|
||||||
@ -38,7 +37,7 @@ export default function getOptions(tempData: any) {
|
|||||||
// .reverse(),
|
// .reverse(),
|
||||||
axisLabel: {
|
axisLabel: {
|
||||||
color: "#fff",
|
color: "#fff",
|
||||||
fontSize: 14,
|
fontSize: 12,
|
||||||
},
|
},
|
||||||
axisTick: { show: false },
|
axisTick: { show: false },
|
||||||
axisLine: {
|
axisLine: {
|
||||||
@ -52,12 +51,12 @@ export default function getOptions(tempData: any) {
|
|||||||
name: "单位/千片",
|
name: "单位/千片",
|
||||||
nameTextStyle: {
|
nameTextStyle: {
|
||||||
color: "#fff",
|
color: "#fff",
|
||||||
fontSize: 14,
|
fontSize: 12,
|
||||||
},
|
},
|
||||||
type: "value",
|
type: "value",
|
||||||
axisLabel: {
|
axisLabel: {
|
||||||
color: "#fff",
|
color: "#fff",
|
||||||
fontSize: 14,
|
fontSize: 12,
|
||||||
formatter: "{value}",
|
formatter: "{value}",
|
||||||
},
|
},
|
||||||
axisLine: {
|
axisLine: {
|
@ -1,51 +0,0 @@
|
|||||||
import React from "react";
|
|
||||||
import intl from "react-intl-universal";
|
|
||||||
import '../../lanhuapp/common.css';
|
|
||||||
import "../../lanhuapp/index.css";
|
|
||||||
import {useAppSelector} from "../../store/hooks";
|
|
||||||
import {Quality, selectQualityMonitorEntity} from "../../store/QualityMonitorEntity";
|
|
||||||
import {Table, TableBody, TableHead} from "@mui/material";
|
|
||||||
import {StyledTableCell, StyledTableContainer, StyledTableRow} from "./StyledTable";
|
|
||||||
|
|
||||||
interface param {
|
|
||||||
timeName: "todayQualityLineAll" | "weekQualityLineAll" | "monthQualityLineAll";
|
|
||||||
lineName: "Line_1" | "Line_2" | "Line_3" | "Line_4";
|
|
||||||
}
|
|
||||||
|
|
||||||
function QualityRightTable(props: param) {
|
|
||||||
const AllData = useAppSelector(selectQualityMonitorEntity);
|
|
||||||
const TimeData = AllData[props.timeName];
|
|
||||||
const LineData = TimeData[props.lineName];
|
|
||||||
const SlicedLineData = LineData.slice(0, 6);
|
|
||||||
return (
|
|
||||||
<div className="rightTableAreaQ">
|
|
||||||
<StyledTableContainer>
|
|
||||||
<Table>
|
|
||||||
<TableHead>
|
|
||||||
<StyledTableRow>
|
|
||||||
<StyledTableCell align="center" sx={{width: 100}}>{intl.get('serialNo')}</StyledTableCell>
|
|
||||||
<StyledTableCell align="center" sx={{width: 250}}>{intl.get('DefectType')}</StyledTableCell>
|
|
||||||
<StyledTableCell align="center" sx={{width: 120}}>{intl.get('DefectNumber')}</StyledTableCell>
|
|
||||||
</StyledTableRow>
|
|
||||||
</TableHead>
|
|
||||||
<TableBody>
|
|
||||||
{SlicedLineData.map((item: Quality, index: number) => (
|
|
||||||
<StyledTableRow key={index}>
|
|
||||||
<StyledTableCell align="center">{item.sort}</StyledTableCell>
|
|
||||||
<StyledTableCell align="center" sx={{
|
|
||||||
maxWidth: 250,
|
|
||||||
overflow: 'hidden',
|
|
||||||
whiteSpace: 'nowrap',
|
|
||||||
textOverflow: 'ellipsis'
|
|
||||||
}}>{item.content}</StyledTableCell>
|
|
||||||
<StyledTableCell align="center">{item.num}</StyledTableCell>
|
|
||||||
</StyledTableRow>
|
|
||||||
))}
|
|
||||||
</TableBody>
|
|
||||||
</Table>
|
|
||||||
</StyledTableContainer>
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
export default QualityRightTable;
|
|
@ -1,71 +0,0 @@
|
|||||||
import React from "react";
|
|
||||||
import {styled, TableCell, tableCellClasses, TableContainer, TableRow, ToggleButton} from "@mui/material";
|
|
||||||
|
|
||||||
export const StyledTableCell = styled(TableCell)(({theme}) => ({
|
|
||||||
[`&.${tableCellClasses.head}`]: {
|
|
||||||
backgroundColor: 'rgba(32, 55, 96, 0.7)',
|
|
||||||
color: theme.palette.common.white,
|
|
||||||
fontSize: 14,
|
|
||||||
padding: 0,
|
|
||||||
border: 0,
|
|
||||||
height: 28,
|
|
||||||
},
|
|
||||||
[`&.${tableCellClasses.body}`]: {
|
|
||||||
fontSize: 12,
|
|
||||||
color: theme.palette.common.white,
|
|
||||||
padding: 0,
|
|
||||||
border: 0,
|
|
||||||
height: 26
|
|
||||||
},
|
|
||||||
}));
|
|
||||||
|
|
||||||
export const StyledTableRow = styled(TableRow)(({theme}) => ({
|
|
||||||
'&:nth-of-type(odd)': {
|
|
||||||
backgroundColor: 'rgba(14, 32, 62, 0.7)',
|
|
||||||
},
|
|
||||||
backgroundColor: 'rgba(32, 55, 96, 0.7)',
|
|
||||||
}));
|
|
||||||
|
|
||||||
export const StyledTableContainer = styled(TableContainer)(({theme}) => ({
|
|
||||||
overflow: 'auto hidden',
|
|
||||||
'&::-webkit-scrollbar': {
|
|
||||||
height: 8,
|
|
||||||
WebkitAppearance: 'none'
|
|
||||||
},
|
|
||||||
'&::-webkit-scrollbar-thumb': {
|
|
||||||
borderRadius: 2,
|
|
||||||
backgroundColor: 'rgba(91, 196, 190, 0.5)',
|
|
||||||
},
|
|
||||||
'&::-webkit-scrollbar-button': {
|
|
||||||
width: 8,
|
|
||||||
borderBottomLeftRadius: 2,
|
|
||||||
borderBottomRightRadius: 2,
|
|
||||||
backgroundColor: 'rgba(91, 196, 190, 1)',
|
|
||||||
},
|
|
||||||
'&::-webkit-scrollbar-track': {
|
|
||||||
backgroundColor: 'rgba(12, 32, 67, 1)',
|
|
||||||
}
|
|
||||||
}));
|
|
||||||
|
|
||||||
export const StyledToggleButton = styled(ToggleButton)({
|
|
||||||
width: 120,
|
|
||||||
height: 24,
|
|
||||||
backgroundColor: 'rgba(49, 135, 140, 0.29)',
|
|
||||||
color: "white",
|
|
||||||
'&.Mui-selected': {
|
|
||||||
backgroundColor: 'rgba(86, 244, 231, 0.69)',
|
|
||||||
color: "white",
|
|
||||||
'&:hover': {
|
|
||||||
backgroundColor: 'rgba(86, 244, 231, 0.5)',
|
|
||||||
color: "white",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
'&:hover': {
|
|
||||||
backgroundColor: 'rgba(86, 244, 231, 0.5)',
|
|
||||||
color: "white",
|
|
||||||
},
|
|
||||||
'&:active': {
|
|
||||||
backgroundColor: 'rgba(86, 244, 231, 0.69)',
|
|
||||||
color: "white",
|
|
||||||
},
|
|
||||||
});
|
|
75
src/page/Component/SummaryBarChart/chart.config.ts
Normal file
75
src/page/Component/SummaryBarChart/chart.config.ts
Normal file
@ -0,0 +1,75 @@
|
|||||||
|
export default function getOptions(chartData: any) {
|
||||||
|
if (Object.keys(chartData).length === 0) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
const colors = ["#2760FF", "#8167F6", "#5B9BFF", "#99D66C", "#FFD160","#D680FF","#FF6860"];
|
||||||
|
return {
|
||||||
|
color: colors,
|
||||||
|
grid: { top: 48, right: 20, bottom: 5, left: 10, containLabel: true },
|
||||||
|
legend: {
|
||||||
|
show: true,
|
||||||
|
icon: "roundRect",
|
||||||
|
top: 5,
|
||||||
|
right: 20,
|
||||||
|
padding: 0,
|
||||||
|
itemWidth: 10,
|
||||||
|
itemHeight: 10,
|
||||||
|
itemGap: 15,
|
||||||
|
height: 10,
|
||||||
|
textStyle: {
|
||||||
|
color: "#DFF1FE",
|
||||||
|
fontSize: 12,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
xAxis: {
|
||||||
|
type: "category",
|
||||||
|
data: chartData.xData,
|
||||||
|
axisLabel: {
|
||||||
|
color: "#fff",
|
||||||
|
fontSize: 12,
|
||||||
|
},
|
||||||
|
axisTick: { show: false },
|
||||||
|
axisLine: {
|
||||||
|
lineStyle: {
|
||||||
|
width: 2,
|
||||||
|
color: "#5982B2",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
yAxis: {
|
||||||
|
name: "单位/片",
|
||||||
|
nameTextStyle: {
|
||||||
|
color: "#fff",
|
||||||
|
fontSize: 12,
|
||||||
|
},
|
||||||
|
type: "value",
|
||||||
|
axisLabel: {
|
||||||
|
color: "#fff",
|
||||||
|
fontSize: 12,
|
||||||
|
formatter: "{value}",
|
||||||
|
},
|
||||||
|
axisLine: {
|
||||||
|
show: true,
|
||||||
|
lineStyle: {
|
||||||
|
width: 2,
|
||||||
|
color: "#5982B2",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
splitLine: {
|
||||||
|
lineStyle: {
|
||||||
|
width: 2,
|
||||||
|
color: "#5982B2",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
tooltip: {
|
||||||
|
show: false,
|
||||||
|
trigger: "axis",
|
||||||
|
axisPointer: {
|
||||||
|
type: "shadow",
|
||||||
|
},
|
||||||
|
className: "luoyang-chart-tooltip",
|
||||||
|
},
|
||||||
|
series:chartData.series
|
||||||
|
};
|
||||||
|
}
|
@ -1,26 +0,0 @@
|
|||||||
import React, {useState} from "react";
|
|
||||||
import intl from "react-intl-universal";
|
|
||||||
import '../../lanhuapp/common.css';
|
|
||||||
import "../../lanhuapp/index.css";
|
|
||||||
import {FormControlLabel, Switch} from "@mui/material";
|
|
||||||
import {useAppSelector, useAppDispatch} from "../../store/hooks";
|
|
||||||
import {selectSwitchState,ChangeSwitch} from "../../store/ChangeSwitchState";
|
|
||||||
|
|
||||||
function SwitchOnOff() {
|
|
||||||
const dispatch = useAppDispatch();
|
|
||||||
const [isSwitch, setIsSwitch] = useState(useAppSelector(selectSwitchState));
|
|
||||||
|
|
||||||
const handleChange = (event: React.ChangeEvent<HTMLInputElement>) => {
|
|
||||||
dispatch(ChangeSwitch())
|
|
||||||
setIsSwitch(event.target.checked);
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div className={'switchBtn'}>
|
|
||||||
<FormControlLabel control={<Switch color={'warning'} checked={isSwitch} onChange={handleChange}/>}
|
|
||||||
label={intl.get('AutoSwitch')}/>
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
export default SwitchOnOff;
|
|
@ -1,19 +0,0 @@
|
|||||||
import React from "react";
|
|
||||||
import "../style/standard.css"
|
|
||||||
|
|
||||||
interface TabPanelProps {
|
|
||||||
children?: React.ReactNode;
|
|
||||||
index: number;
|
|
||||||
value: number;
|
|
||||||
}
|
|
||||||
|
|
||||||
function TabPanel(props: TabPanelProps) {
|
|
||||||
const {children, value, index, ...other} = props;
|
|
||||||
return (
|
|
||||||
<div hidden={value !== index}>
|
|
||||||
{children}
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
export default TabPanel;
|
|
73
src/page/LDPage/Center/CenterDown.tsx
Normal file
73
src/page/LDPage/Center/CenterDown.tsx
Normal file
@ -0,0 +1,73 @@
|
|||||||
|
import TitleBox from "../Component/TitleBox";
|
||||||
|
import NumberBox from "../Component/NumberBox";
|
||||||
|
import {useAppSelector} from "./../../../store/hooks"
|
||||||
|
import { selectAllLine } from "./../../../store/LeaderPageSlice";
|
||||||
|
import { formatNumberWithCommas } from './../../../utils/index';
|
||||||
|
function CenterDown() {
|
||||||
|
interface mapInterface {
|
||||||
|
inputRate:string,
|
||||||
|
outputRate:string,
|
||||||
|
input:string,
|
||||||
|
output:string
|
||||||
|
}
|
||||||
|
let monthMap = {
|
||||||
|
inputRate:'',
|
||||||
|
outputRate:'',
|
||||||
|
input:'',
|
||||||
|
output:''
|
||||||
|
}
|
||||||
|
let lastMonthMap = {
|
||||||
|
input:'',
|
||||||
|
output:''
|
||||||
|
}
|
||||||
|
let yearMap = {
|
||||||
|
inputRate:'',
|
||||||
|
outputRate:'',
|
||||||
|
input:'',
|
||||||
|
output:''
|
||||||
|
}
|
||||||
|
const data = useAppSelector(selectAllLine);
|
||||||
|
if (data.monthMap) {
|
||||||
|
monthMap = data.monthMap as mapInterface
|
||||||
|
lastMonthMap = data.lastMonthMap as mapInterface
|
||||||
|
yearMap = data.yearMap as mapInterface
|
||||||
|
}
|
||||||
|
return(
|
||||||
|
<div className="ld_center_down flex-row">
|
||||||
|
<div className="ld_center_down_inner flex-col ld_left-box">
|
||||||
|
<TitleBox title={"center_down_left"} />
|
||||||
|
<div style={{padding:'10px 0px 0px 20px'}}>
|
||||||
|
<div style={{width:'300px',height:'128px',marginBottom:'5px'}}>
|
||||||
|
<NumberBox num={monthMap.inputRate?monthMap.inputRate:'-'} show={true} title={'总投入片数'} bigNum={monthMap.input?formatNumberWithCommas(monthMap.input):'-'}/>
|
||||||
|
</div>
|
||||||
|
<div style={{width:'300px',height:'128px'}}>
|
||||||
|
<NumberBox num={monthMap.outputRate || '-'} show={true} title={'总生产片数'} bigNum={monthMap.output?formatNumberWithCommas(monthMap.output):'-'}/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="ld_center_down_inner flex-col ld_center-box">
|
||||||
|
<TitleBox title={"center_down_center"} />
|
||||||
|
<div style={{padding:'10px 0px 0px 20px'}}>
|
||||||
|
<div style={{width:'300px',height:'128px',marginBottom:'5px'}}>
|
||||||
|
<NumberBox num={''} show={false} title={'总投入片数'} bigNum={lastMonthMap.input?formatNumberWithCommas(lastMonthMap.input):'-'}/>
|
||||||
|
</div>
|
||||||
|
<div style={{width:'300px',height:'128px'}}>
|
||||||
|
<NumberBox num={''} show={false} title={'总生产片数'} bigNum={lastMonthMap.output?formatNumberWithCommas(lastMonthMap.output):'-'}/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="ld_center_down_inner flex-col ld_right-box">
|
||||||
|
<TitleBox title={"center_down_right"} />
|
||||||
|
<div style={{padding:'10px 0px 0px 20px'}}>
|
||||||
|
<div style={{width:'300px',height:'128px',marginBottom:'5px'}}>
|
||||||
|
<NumberBox num={yearMap.inputRate || '_'} show={true} title={'总投入片数/万'} bigNum={monthMap.input?formatNumberWithCommas(monthMap.input):'-'}/>
|
||||||
|
</div>
|
||||||
|
<div style={{width:'300px',height:'128px'}}>
|
||||||
|
<NumberBox num={yearMap.outputRate || '_'} show={true} title={'总生产片数/万'} bigNum={yearMap.output?formatNumberWithCommas(yearMap.output):'-'}/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
export default CenterDown;
|
10
src/page/LDPage/Center/CenterUp.tsx
Normal file
10
src/page/LDPage/Center/CenterUp.tsx
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
import LinePageBabylon from "../../../babylonjs/AllLinePageBabylon";
|
||||||
|
function CenterUp() {
|
||||||
|
const lineID = "1-1"
|
||||||
|
return(
|
||||||
|
<div className="ld_center_up">
|
||||||
|
<LinePageBabylon modelPath={`Line${lineID}`} />
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
export default CenterUp;
|
27
src/page/LDPage/Component/NumberBox/index.css
Normal file
27
src/page/LDPage/Component/NumberBox/index.css
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
.number_box_container {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
background: url(../../../../../public/png/numberBox.png) no-repeat;
|
||||||
|
background-size: 100% 100%;
|
||||||
|
background-position: 0 0;
|
||||||
|
margin:0 auto;
|
||||||
|
padding: 25px 20px 20px;
|
||||||
|
}
|
||||||
|
.number_box_container .big_number {
|
||||||
|
font-size:38px;
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
.number_box_container .big_number_title {
|
||||||
|
margin-bottom: 10px;
|
||||||
|
}
|
||||||
|
.number_box_container .big_number_title_left {
|
||||||
|
font-size: 20px;
|
||||||
|
color: #fff;
|
||||||
|
letter-spacing: 2px;
|
||||||
|
}
|
||||||
|
.number_box_container .big_number_title_right {
|
||||||
|
font-size: 18px;
|
||||||
|
position: relative;
|
||||||
|
top: 6px;
|
||||||
|
left:10px;
|
||||||
|
}
|
35
src/page/LDPage/Component/NumberBox/index.tsx
Normal file
35
src/page/LDPage/Component/NumberBox/index.tsx
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
import './index.css';
|
||||||
|
import a_r from './../../../assets/icon/a_r.png';
|
||||||
|
import a_g from './../../../assets/icon/a_g.png';
|
||||||
|
interface boxProps {
|
||||||
|
num:string | number,
|
||||||
|
show?:boolean,
|
||||||
|
title:string,
|
||||||
|
lastYear?:boolean,
|
||||||
|
bigNum:string | number
|
||||||
|
}
|
||||||
|
function NumberBox(props: boxProps) {
|
||||||
|
return (
|
||||||
|
<div className="number_box_container" style={{paddingLeft:props.lastYear?'45px':'25px'}}>
|
||||||
|
<div className='flex-row big_number_title'>
|
||||||
|
<div className='big_number_title_left'>{props.title}</div>
|
||||||
|
{
|
||||||
|
props.show?(
|
||||||
|
<div className='big_number_title_right' style={{color:Number(props.num)>0?'#FF0000':'#00FF00'}}>
|
||||||
|
{Number(props.num)>0?'+':''}{props.num}%
|
||||||
|
{
|
||||||
|
Number(props.num)>0?(
|
||||||
|
<img src={a_r} alt="" width='5px'/>
|
||||||
|
):(
|
||||||
|
<img src={a_g} alt="" width='5px'/>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
):''
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
<div className='big_number'>{props.bigNum}</div>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
export default NumberBox;
|
56
src/page/LDPage/Component/TitleBox/index.tsx
Normal file
56
src/page/LDPage/Component/TitleBox/index.tsx
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
import Defect from "./../../../assets/icon/defect.png";
|
||||||
|
import NumBar from "./../../../assets/icon/numBar.png";
|
||||||
|
import Defe from "./../../../assets/icon/defe.png";
|
||||||
|
import Record from "./../../../assets/icon/record.png";
|
||||||
|
import "./index.css";
|
||||||
|
interface titleProps {
|
||||||
|
title: string;
|
||||||
|
}
|
||||||
|
function TitleBox(props: titleProps) {
|
||||||
|
const filteredTitles = () => {
|
||||||
|
switch (props.title) {
|
||||||
|
case "left_up":
|
||||||
|
return {
|
||||||
|
img: Record,
|
||||||
|
title: "近期数据对比",
|
||||||
|
};
|
||||||
|
case "left_down":
|
||||||
|
return {
|
||||||
|
img: NumBar,
|
||||||
|
title: "投入产出及良品率",
|
||||||
|
};
|
||||||
|
case "center_down_left":
|
||||||
|
return {
|
||||||
|
img: Defect,
|
||||||
|
title: "本月数据",
|
||||||
|
};
|
||||||
|
case "center_down_center":
|
||||||
|
return {
|
||||||
|
img: Defect,
|
||||||
|
title: "上月数据",
|
||||||
|
};
|
||||||
|
case "center_down_right":
|
||||||
|
return {
|
||||||
|
img: Defect,
|
||||||
|
title: "本年数据",
|
||||||
|
};
|
||||||
|
case "right_up":
|
||||||
|
return {
|
||||||
|
img: Defe,
|
||||||
|
title: "缺陷情况",
|
||||||
|
};
|
||||||
|
default:
|
||||||
|
return {
|
||||||
|
img: Defect,
|
||||||
|
title: "上年数据",
|
||||||
|
};
|
||||||
|
}
|
||||||
|
};
|
||||||
|
return (
|
||||||
|
<div className="title_box">
|
||||||
|
<img src={filteredTitles().img} alt="title" />
|
||||||
|
<span>{filteredTitles().title}</span>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
export default TitleBox;
|
164
src/page/LDPage/Component/pieChart/chart.config.ts
Normal file
164
src/page/LDPage/Component/pieChart/chart.config.ts
Normal file
@ -0,0 +1,164 @@
|
|||||||
|
function getCoordinates(startArc: number, endArc: number) {
|
||||||
|
const posi = [
|
||||||
|
Math.sin(startArc),
|
||||||
|
-Math.cos(startArc),
|
||||||
|
Math.sin(endArc),
|
||||||
|
-Math.cos(endArc),
|
||||||
|
];
|
||||||
|
const dx = posi[2] - posi[0];
|
||||||
|
const dy = posi[3] - posi[1];
|
||||||
|
|
||||||
|
return getLocation(dx, dy);
|
||||||
|
}
|
||||||
|
function getLocation(dx: number, dy: number) {
|
||||||
|
const tanV = dx / dy;
|
||||||
|
const directSign = Math.abs(tanV) < 1;
|
||||||
|
const t = directSign ? tanV : 1 / tanV;
|
||||||
|
|
||||||
|
const sign1 = t > 0 ? 1 : -1;
|
||||||
|
const sign2 = dx > 0 ? 1 : -1;
|
||||||
|
const sign = directSign ? sign1 * sign2 : sign2;
|
||||||
|
|
||||||
|
const group1 = [0.5 - (sign * t) / 2, 0.5 + (sign * t) / 2];
|
||||||
|
const group2 = sign > 0 ? [0, 1] : [1, 0];
|
||||||
|
const group = [...group1, ...group2];
|
||||||
|
const keys = directSign ? ["x", "x2", "y", "y2"] : ["y", "y2", "x", "x2"];
|
||||||
|
|
||||||
|
let res: { [key: string]: any } = {};
|
||||||
|
keys.forEach((k, idx) => {
|
||||||
|
res[k] = group[idx];
|
||||||
|
});
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
// 数据格式
|
||||||
|
// const dataProps = [
|
||||||
|
// {value: 14,name:'缺陷1'},
|
||||||
|
// {value: 20,name:'缺陷2'},
|
||||||
|
// {value: 22,name:'缺陷3'},
|
||||||
|
// {value: 14,name:'缺陷4'},
|
||||||
|
// {value: 30,name:'缺陷5'}
|
||||||
|
// ]
|
||||||
|
let rangArrValue: any[] = [];
|
||||||
|
let dataList: any = [];
|
||||||
|
let totalValue = 0;
|
||||||
|
const colors = [
|
||||||
|
"rgb(39, 96, 255)",
|
||||||
|
"rgb(91, 155, 255)",
|
||||||
|
"rgb(153, 214, 108)",
|
||||||
|
"rgb(18, 255, 245)",
|
||||||
|
"rgb(221, 177, 18)",
|
||||||
|
];
|
||||||
|
const getPersonnelList = async (dataProps: any) => {
|
||||||
|
totalValue = dataProps.reduce(
|
||||||
|
(total: any, value: any) => total + value.value,
|
||||||
|
0
|
||||||
|
);
|
||||||
|
let cacheNum = 0;
|
||||||
|
for (let i = 0; i < dataProps.length; i++) {
|
||||||
|
const endNum = cacheNum + dataProps[i].value;
|
||||||
|
rangArrValue.push([cacheNum, endNum]);
|
||||||
|
cacheNum = endNum;
|
||||||
|
}
|
||||||
|
const angleArr = rangArrValue.map((arr) =>
|
||||||
|
arr.map((num: any) => (num / totalValue) * Math.PI * 2)
|
||||||
|
);
|
||||||
|
dataList = dataProps.map((item: any, index: any) => {
|
||||||
|
const range = getCoordinates(angleArr[index][0], angleArr[index][1]);
|
||||||
|
const startColor = colors[index%5];
|
||||||
|
const color = {
|
||||||
|
type: "linear",
|
||||||
|
x: range.x,
|
||||||
|
x2: range.x2,
|
||||||
|
y: range.y,
|
||||||
|
y2: range.y2,
|
||||||
|
colorStops: [
|
||||||
|
{
|
||||||
|
offset: 0,
|
||||||
|
color: startColor, // 起始颜色
|
||||||
|
},
|
||||||
|
{
|
||||||
|
offset: 1,
|
||||||
|
color: `${startColor.substring(0, startColor.length - 1)}, 0.2)`, // 终点颜色
|
||||||
|
},
|
||||||
|
],
|
||||||
|
global: false,
|
||||||
|
};
|
||||||
|
|
||||||
|
return {
|
||||||
|
name: item.name,
|
||||||
|
value: item.value,
|
||||||
|
itemStyle: {
|
||||||
|
color: color,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
});
|
||||||
|
};
|
||||||
|
export default function getOptions(dataProps: any) {
|
||||||
|
if (dataProps.length === 0) return null;
|
||||||
|
getPersonnelList(dataProps);
|
||||||
|
return {
|
||||||
|
color: colors,
|
||||||
|
graphic: [
|
||||||
|
{
|
||||||
|
type: "text",
|
||||||
|
left: "center",
|
||||||
|
top: "44%",
|
||||||
|
style: {
|
||||||
|
text: totalValue,
|
||||||
|
fill: "#fff",
|
||||||
|
width: 150,
|
||||||
|
height: 44,
|
||||||
|
fontSize: 31,
|
||||||
|
fontWeight: 400,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: "text",
|
||||||
|
left: "center",
|
||||||
|
top: "55%",
|
||||||
|
style: {
|
||||||
|
text: "总数/件",
|
||||||
|
fill: "rgba(255, 255, 255, 0.70)",
|
||||||
|
width: 32,
|
||||||
|
height: 16,
|
||||||
|
fontSize: 16,
|
||||||
|
fontWeight: 400,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
series: [
|
||||||
|
{
|
||||||
|
name: "产线缺陷分类",
|
||||||
|
type: "pie",
|
||||||
|
radius: ["45%", "60%"],
|
||||||
|
center: ["50%", "50%"],
|
||||||
|
// label: {
|
||||||
|
// formatter: "{d}%",
|
||||||
|
// color: "#fff",
|
||||||
|
// },
|
||||||
|
label:{
|
||||||
|
formatter:function(params:any){
|
||||||
|
return `{color${params.dataIndex}|${params.percent}%}\n{style2|${params.name}}`
|
||||||
|
},
|
||||||
|
rich:{
|
||||||
|
color0:{color:'rgb(39, 96, 255)',fontSize:22},
|
||||||
|
color1:{color:'rgb(91, 155, 255)',fontSize:22},
|
||||||
|
color2:{color:'rgb(153, 214, 108)',fontSize:22},
|
||||||
|
color3:{color:'rgb(18, 255, 245)',fontSize:22},
|
||||||
|
color4:{color:'rgb(221, 177, 18)',fontSize:22},
|
||||||
|
color5:{color:'rgb(39, 96, 255)',fontSize:22},
|
||||||
|
color6:{color:'rgb(91, 155, 255)',fontSize:22},
|
||||||
|
color7:{color:'rgb(153, 214, 108)',fontSize:22},
|
||||||
|
color8:{color:'rgb(18, 255, 245)',fontSize:22},
|
||||||
|
color9:{color:'rgb(221, 177, 18)',fontSize:22},
|
||||||
|
style2:{
|
||||||
|
color:'#fff',
|
||||||
|
fontSize:14
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
data: dataList,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
};
|
||||||
|
}
|
73
src/page/LDPage/Left/LeftDown.tsx
Normal file
73
src/page/LDPage/Left/LeftDown.tsx
Normal file
@ -0,0 +1,73 @@
|
|||||||
|
import ReactECharts from "echarts-for-react";
|
||||||
|
import TitleBox from "../Component/TitleBox";
|
||||||
|
import getOptions from "../../Component/BarLineChart/chart.config";
|
||||||
|
import {useAppSelector} from "./../../../store/hooks"
|
||||||
|
import { selectAllLine } from "./../../../store/LeaderPageSlice";
|
||||||
|
import { Fragment } from "react/jsx-runtime";
|
||||||
|
function LeftDown() {
|
||||||
|
const data = useAppSelector(selectAllLine);
|
||||||
|
interface Detail {
|
||||||
|
time: string;
|
||||||
|
input: string;
|
||||||
|
output: string;
|
||||||
|
Yield: string;
|
||||||
|
}
|
||||||
|
interface DataSource {
|
||||||
|
time: string[];
|
||||||
|
input: number[];
|
||||||
|
output: number[];
|
||||||
|
yield: number[];
|
||||||
|
}
|
||||||
|
let dataSource:DataSource = {
|
||||||
|
time:[],
|
||||||
|
input:[],
|
||||||
|
output:[],
|
||||||
|
yield:[]
|
||||||
|
};
|
||||||
|
if (data.numDet && Array.isArray(data.numDet)) {
|
||||||
|
(data.numDet as Detail[]).forEach((item: Detail) => {
|
||||||
|
dataSource.time.push(item.time);
|
||||||
|
dataSource.input.push(Number(item.input));
|
||||||
|
dataSource.output.push(Number(item.output));
|
||||||
|
dataSource.yield.push(Number(item.Yield));
|
||||||
|
})
|
||||||
|
}else{
|
||||||
|
dataSource.time = []
|
||||||
|
dataSource.input = []
|
||||||
|
dataSource.output = []
|
||||||
|
dataSource.yield = []
|
||||||
|
}
|
||||||
|
const options1 = getOptions(dataSource);
|
||||||
|
return(
|
||||||
|
<div className="ld_left_down">
|
||||||
|
<TitleBox title={"left_down"} />
|
||||||
|
{
|
||||||
|
dataSource.time.length>0?(
|
||||||
|
<div>
|
||||||
|
<div className="top_legend">
|
||||||
|
<span className="chart_legend_icon1">投入</span>
|
||||||
|
<span className="chart_legend_icon2">产出</span>
|
||||||
|
<span><span className="chart_legend_icon3"></span>良品率</span>
|
||||||
|
</div>
|
||||||
|
<div style={{ width: "402px", height: "288px" }}>
|
||||||
|
<ReactECharts option={options1} style={{ height: "100%" }} />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
):(<p
|
||||||
|
style={{
|
||||||
|
color: "#cccf",
|
||||||
|
fontSize: "24px",
|
||||||
|
userSelect: "none",
|
||||||
|
textAlign: "center",
|
||||||
|
paddingTop: "50px",
|
||||||
|
margin:0
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
暂无数据
|
||||||
|
</p>)
|
||||||
|
}
|
||||||
|
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
export default LeftDown;
|
85
src/page/LDPage/Left/LeftUp.tsx
Normal file
85
src/page/LDPage/Left/LeftUp.tsx
Normal file
@ -0,0 +1,85 @@
|
|||||||
|
import TitleBox from "../Component/TitleBox";
|
||||||
|
import inputImg from "../../assets/icon/input.png"
|
||||||
|
import prod from '../../assets/icon/prod.png'
|
||||||
|
import {useAppSelector} from "./../../../store/hooks"
|
||||||
|
import { selectAllLine } from "./../../../store/LeaderPageSlice";
|
||||||
|
import { formatNumberWithCommas,parseAndFormatStringToTwoDecimalPlaces } from './../../../utils/index'
|
||||||
|
function LeftUp() {
|
||||||
|
const data = useAppSelector(selectAllLine);
|
||||||
|
console.log(data)
|
||||||
|
interface DataProps {
|
||||||
|
input: string,
|
||||||
|
inputArea: string,
|
||||||
|
output: string,
|
||||||
|
outputArea: string
|
||||||
|
}
|
||||||
|
let todayData:DataProps = {} as DataProps;
|
||||||
|
let yesterdayData:DataProps = {} as DataProps;
|
||||||
|
if (data.todayMap) {
|
||||||
|
todayData = data.todayMap as DataProps;
|
||||||
|
yesterdayData = data.yesterdayMap as DataProps;
|
||||||
|
}
|
||||||
|
|
||||||
|
return(
|
||||||
|
<div className="ld_left_up">
|
||||||
|
<TitleBox title={"left_up"} />
|
||||||
|
<div style={{ padding: "10px", height: "555px" }}>
|
||||||
|
<div className="left_down_title flex-row" style={{marginBottom:"8px"}}>
|
||||||
|
<div className="left_down_box1 flex-col" />
|
||||||
|
<span className="left_down_text">本日</span>
|
||||||
|
<div className="left_down_box2 flex-col" />
|
||||||
|
</div>
|
||||||
|
<div className="ld_left_up_inner">
|
||||||
|
<div className="num_contrast flex-row">
|
||||||
|
<div>
|
||||||
|
<img src={inputImg} alt="" width="54px"/>
|
||||||
|
<p style={{position:"relative",top:"-3px",left:"3px",color:'#9DEAF5'}}>总投入</p>
|
||||||
|
</div>
|
||||||
|
<div className="num_contrast_right">
|
||||||
|
<p style={{height:"45px",paddingTop:'5px'}}><span style={{fontSize:'32px',display:'inline-block',marginRight:'5px'}}>{todayData.input?formatNumberWithCommas(todayData.input):'-'}</span>片数</p>
|
||||||
|
<p style={{height:"40px"}}><span style={{fontSize:'32px',display:'inline-block',marginRight:'5px'}}>{todayData.inputArea?parseAndFormatStringToTwoDecimalPlaces(todayData.inputArea):'-'}</span>面积/㎡</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="num_contrast flex-row">
|
||||||
|
<div>
|
||||||
|
<img src={prod} alt="" width="54px"/>
|
||||||
|
<p style={{position:"relative",top:"-3px",left:"3px",color:'#9DEAF5'}}>总生产</p>
|
||||||
|
</div>
|
||||||
|
<div className="num_contrast_right">
|
||||||
|
<p style={{height:"45px",paddingTop:'5px'}}><span style={{fontSize:'32px',display:'inline-block',marginRight:'5px'}}>{todayData.output?formatNumberWithCommas(todayData.output):'-'}</span>片数</p>
|
||||||
|
<p style={{height:"40px"}}><span style={{fontSize:'32px',display:'inline-block',marginRight:'5px'}}>{todayData.outputArea?parseAndFormatStringToTwoDecimalPlaces(todayData.outputArea):'-'}</span>面积/㎡</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="left_down_title flex-row" style={{margin:"10px 0px 8px 0px"}}>
|
||||||
|
<div className="left_down_box1 flex-col" />
|
||||||
|
<span className="left_down_text">昨日</span>
|
||||||
|
<div className="left_down_box2 flex-col" />
|
||||||
|
</div>
|
||||||
|
<div className="ld_left_up_inner">
|
||||||
|
<div className="num_contrast flex-row">
|
||||||
|
<div>
|
||||||
|
<img src={inputImg} alt="" width="54px"/>
|
||||||
|
<p style={{position:"relative",top:"-3px",left:"3px",color:'#9DEAF5'}}>总投入</p>
|
||||||
|
</div>
|
||||||
|
<div className="num_contrast_right">
|
||||||
|
<p style={{height:"45px",paddingTop:'5px'}}><span style={{fontSize:'32px',display:'inline-block',marginRight:'5px'}}>{yesterdayData.input?formatNumberWithCommas(yesterdayData.input):'-'}</span>片数</p>
|
||||||
|
<p style={{height:"40px"}}><span style={{fontSize:'32px',display:'inline-block',marginRight:'5px'}}>{yesterdayData.inputArea?parseAndFormatStringToTwoDecimalPlaces(yesterdayData.inputArea):'-'}</span>面积/㎡</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="num_contrast flex-row">
|
||||||
|
<div>
|
||||||
|
<img src={prod} alt="" width="54px"/>
|
||||||
|
<p style={{position:"relative",top:"-3px",left:"3px",color:'#9DEAF5'}}>总生产</p>
|
||||||
|
</div>
|
||||||
|
<div className="num_contrast_right">
|
||||||
|
<p style={{height:"45px",paddingTop:'5px'}}><span style={{fontSize:'32px',display:'inline-block',marginRight:'5px'}}>{yesterdayData.output?formatNumberWithCommas(yesterdayData.output):'-'}</span>片数</p>
|
||||||
|
<p style={{height:"40px"}}><span style={{fontSize:'32px',display:'inline-block',marginRight:'5px'}}>{yesterdayData.outputArea?parseAndFormatStringToTwoDecimalPlaces(yesterdayData.outputArea):'-'}</span>面积/㎡</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
export default LeftUp;
|
11
src/page/LDPage/Left/index.tsx
Normal file
11
src/page/LDPage/Left/index.tsx
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
import LeftUp from "./LeftUp";
|
||||||
|
import LeftDown from "./LeftDown";
|
||||||
|
function Left() {
|
||||||
|
return (
|
||||||
|
<div className="group_left flex-col">
|
||||||
|
<LeftUp />
|
||||||
|
<LeftDown />
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
export default Left;
|
33
src/page/LDPage/Right/RightDown.tsx
Normal file
33
src/page/LDPage/Right/RightDown.tsx
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
import TitleBox from "../Component/TitleBox";
|
||||||
|
import NumberBox from "../Component/NumberBox";
|
||||||
|
import {useAppSelector} from "./../../../store/hooks"
|
||||||
|
import { selectAllLine } from "./../../../store/LeaderPageSlice";
|
||||||
|
import { formatNumberWithCommas } from './../../../utils/index';
|
||||||
|
function RightDown() {
|
||||||
|
interface mapInterface {
|
||||||
|
input:string,
|
||||||
|
output:string
|
||||||
|
}
|
||||||
|
let lastYearMap = {
|
||||||
|
input:'',
|
||||||
|
output:''
|
||||||
|
} as mapInterface
|
||||||
|
const data = useAppSelector(selectAllLine);
|
||||||
|
if (data.lastYearMap) {
|
||||||
|
lastYearMap = data.lastYearMap as mapInterface
|
||||||
|
}
|
||||||
|
return(
|
||||||
|
<div className="ld_right_down">
|
||||||
|
<TitleBox title={"right_down"} />
|
||||||
|
<div style={{padding:'10px 0px 0px 20px'}}>
|
||||||
|
<div style={{width:'365px',height:'128px',marginBottom:'5px'}}>
|
||||||
|
<NumberBox num={''} show={false} title={'总投入片数/万'} lastYear={true} bigNum={lastYearMap.input?formatNumberWithCommas(lastYearMap.input):'-'}/>
|
||||||
|
</div>
|
||||||
|
<div style={{width:'365px',height:'128px'}}>
|
||||||
|
<NumberBox num={''} show={false} title={'总生产片数/万'} lastYear={true} bigNum={lastYearMap.output?formatNumberWithCommas(lastYearMap.output):'-'}/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
export default RightDown;
|
86
src/page/LDPage/Right/RightUp.tsx
Normal file
86
src/page/LDPage/Right/RightUp.tsx
Normal file
@ -0,0 +1,86 @@
|
|||||||
|
import TitleBox from "../Component/TitleBox";
|
||||||
|
import a_r from './../../assets/icon/a_r.png';
|
||||||
|
import a_g from './../../assets/icon/a_g.png';
|
||||||
|
import ReactECharts from "echarts-for-react";
|
||||||
|
import getOptions from "../Component/pieChart/chart.config";
|
||||||
|
import dayjs from 'dayjs';
|
||||||
|
function RightUp() {
|
||||||
|
const monthData = (Math.floor(Math.random() * (1100-900+1))+900)*(dayjs().date());
|
||||||
|
const dataProps = [
|
||||||
|
{value: 121,name:'打孔'},
|
||||||
|
{value: 41,name:'丝印'},
|
||||||
|
{value: 194,name:'磨边'},
|
||||||
|
{value: 33,name:'一次镀膜'},
|
||||||
|
{value: 25,name:'二次镀膜'},
|
||||||
|
{value: 51,name:'钢化'},
|
||||||
|
]
|
||||||
|
const options1 = getOptions(dataProps);
|
||||||
|
return(
|
||||||
|
<div className="ld_right_up">
|
||||||
|
<TitleBox title={"right_up"} />
|
||||||
|
<div>
|
||||||
|
<div className="left_down_title flex-row" style={{marginBottom:"8px"}}>
|
||||||
|
<div className="left_down_box1 flex-col" />
|
||||||
|
<span className="left_down_text">总数</span>
|
||||||
|
<div className="left_down_box2 flex-col" />
|
||||||
|
</div>
|
||||||
|
<div className="ld_right_up_box">
|
||||||
|
<div className="ld_right_up_box1 flex-row">
|
||||||
|
<div style={{width:"106px"}}>
|
||||||
|
<p>
|
||||||
|
当日
|
||||||
|
{/* <img src={a_r} alt="" width='5px' className="ld_right_up_img"/> */}
|
||||||
|
<img src={a_g} alt="" width='5px' className="ld_right_up_img"/>
|
||||||
|
</p>
|
||||||
|
<p style={{fontSize:'28px',textShadow: '0px 5px 2px rgba(0,0,0,0.62)'}}>465</p>
|
||||||
|
</div>
|
||||||
|
<div style={{width:"106px"}}>
|
||||||
|
<p>
|
||||||
|
本月
|
||||||
|
<img src={monthData > 29456 ? a_r : a_g} alt="" width='5px' className="ld_right_up_img"/>
|
||||||
|
</p>
|
||||||
|
<p style={{fontSize:'28px',textShadow: '0px 5px 2px rgba(0,0,0,0.62)'}}>{monthData}</p>
|
||||||
|
</div>
|
||||||
|
<div style={{width:"106px"}}>
|
||||||
|
<p>
|
||||||
|
本年
|
||||||
|
<img src={a_r} alt="" width='5px' className="ld_right_up_img"/>
|
||||||
|
</p>
|
||||||
|
<p style={{fontSize:'28px',textShadow: '0px 5px 2px rgba(0,0,0,0.62)'}}>48549</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="ld_right_up_box1 flex-row">
|
||||||
|
<div style={{width:"106px"}}>
|
||||||
|
<p>
|
||||||
|
昨日
|
||||||
|
</p>
|
||||||
|
<p style={{fontSize:'28px',textShadow: '0px 5px 2px rgba(0,0,0,0.62)'}}>968</p>
|
||||||
|
</div>
|
||||||
|
<div style={{width:"106px"}}>
|
||||||
|
<p>
|
||||||
|
上月
|
||||||
|
</p>
|
||||||
|
<p style={{fontSize:'28px',textShadow: '0px 5px 2px rgba(0,0,0,0.62)'}}>29456</p>
|
||||||
|
</div>
|
||||||
|
<div style={{width:"106px"}}>
|
||||||
|
<p>
|
||||||
|
上年
|
||||||
|
</p>
|
||||||
|
<p style={{fontSize:'28px',textShadow: '0px 5px 2px rgba(0,0,0,0.62)'}}>0</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="left_down_title flex-row" style={{marginBottom:"8px"}}>
|
||||||
|
<div className="left_down_box1 flex-col" />
|
||||||
|
<span className="left_down_text">全厂缺陷汇总</span>
|
||||||
|
<div className="left_down_box2 flex-col" />
|
||||||
|
</div>
|
||||||
|
<div style={{ width: "400px", height: "320px" }}>
|
||||||
|
<ReactECharts option={options1} style={{ height: "100%" }} />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
export default RightUp;
|
12
src/page/LDPage/Right/index.tsx
Normal file
12
src/page/LDPage/Right/index.tsx
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
import RightDown from "./RightDown";
|
||||||
|
import RightUp from "./RightUp";
|
||||||
|
|
||||||
|
function Right() {
|
||||||
|
return (
|
||||||
|
<div className="group_right flex-col">
|
||||||
|
<RightUp />
|
||||||
|
<RightDown />
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
export default Right;
|
32
src/page/LDPage/TopP.tsx
Normal file
32
src/page/LDPage/TopP.tsx
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
import '../../lanhuapp/common.css';
|
||||||
|
import "./index.css";
|
||||||
|
import { useState } from "react";
|
||||||
|
import dayjs from 'dayjs';
|
||||||
|
|
||||||
|
import 'dayjs/locale/zh-cn';
|
||||||
|
function TopP() {
|
||||||
|
const [time, setTime] = useState(dayjs().format('HH:mm'));
|
||||||
|
const [date, setDate] = useState(dayjs().format('YY/MM/DD'));
|
||||||
|
const [weekday, setWeekday] = useState(dayjs().locale('zh-cn').format('dddd'));
|
||||||
|
setInterval(() => {
|
||||||
|
setTime(dayjs().format('HH:mm'));
|
||||||
|
setDate(dayjs().format('YY/MM/DD'));
|
||||||
|
setWeekday(dayjs().locale('zh-cn').format('dddd'));
|
||||||
|
})
|
||||||
|
return (
|
||||||
|
<div className="flex-row">
|
||||||
|
<div className="block_top_ld flex-row">
|
||||||
|
<div className='block_top_title'></div>
|
||||||
|
<div className='block_top_time'>
|
||||||
|
<div className='time-title'>{time}</div>
|
||||||
|
<div className='time-content'>
|
||||||
|
<div>{weekday}</div>
|
||||||
|
<div>{date}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default TopP;
|
@ -1,4 +1,346 @@
|
|||||||
.main-box {
|
/* 顶部 */
|
||||||
font-size: 50px;
|
.block_top_ld {
|
||||||
color: #fff;
|
width: 1920px;
|
||||||
|
height: 94px;
|
||||||
|
background: url(/public/svg/topbackLD.svg) 100% no-repeat;
|
||||||
|
background-size: 100% 100%;
|
||||||
|
opacity: 1;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.block_top_title {
|
||||||
|
width: 651px;
|
||||||
|
height: 77px;
|
||||||
|
background: url(/public/png/topTiltle.png) 100% no-repeat;
|
||||||
|
background-size: 100% 100%;
|
||||||
|
margin-top: 18px;
|
||||||
|
}
|
||||||
|
.block_top_time {
|
||||||
|
position:absolute;
|
||||||
|
right:22px;
|
||||||
|
top:54px;
|
||||||
|
color:#fff;
|
||||||
|
letter-spacing: 1px;
|
||||||
|
}
|
||||||
|
.block_top_time .time-title {
|
||||||
|
display:inline-block;
|
||||||
|
width:113px;
|
||||||
|
height: 42px;
|
||||||
|
line-height: 42px;
|
||||||
|
font-size: 42px;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
.block_top_time .time-content {
|
||||||
|
display:inline-block;
|
||||||
|
font-size: 18px;
|
||||||
|
width:95px;
|
||||||
|
height: 42px;
|
||||||
|
padding-left:12px;
|
||||||
|
}
|
||||||
|
/* 中部 */
|
||||||
|
.block_bottom {
|
||||||
|
width: 1920px;
|
||||||
|
height: 966px;
|
||||||
|
padding-top: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.group_left {
|
||||||
|
width: 402px;
|
||||||
|
height: 966px;
|
||||||
|
margin: 0 0 0 24px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.group_center {
|
||||||
|
width: 1041px;
|
||||||
|
height: 966px;
|
||||||
|
margin: 0 0 0 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.group_right {
|
||||||
|
width: 401px;
|
||||||
|
height: 966px;
|
||||||
|
margin-left: 15px;
|
||||||
|
}
|
||||||
|
.ld_left_up {
|
||||||
|
width: 402px;
|
||||||
|
height: 599px;
|
||||||
|
background: url(../../../public/png/rect/lp_left_down.png) no-repeat;
|
||||||
|
background-size: 100% 100%;
|
||||||
|
background-position: 0 0;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
.ld_left_up_inner {
|
||||||
|
width: 360px;
|
||||||
|
height: 236px;
|
||||||
|
background: url(../../../public/png/rect/ld_left_up_innerbox.png) no-repeat;
|
||||||
|
background-size: 100% 100%;
|
||||||
|
background-position: 0 0;
|
||||||
|
margin:0 auto;
|
||||||
|
}
|
||||||
|
.ld_left_up_inner .num_contrast {
|
||||||
|
height:113px;
|
||||||
|
padding:20px 18px 0px 29px;
|
||||||
|
color:#fff;
|
||||||
|
}
|
||||||
|
.ld_left_up_inner .num_contrast p{
|
||||||
|
margin: 0px;
|
||||||
|
text-shadow: 0px 4px 2px rgba(0,0,0,0.62);
|
||||||
|
}
|
||||||
|
.ld_left_up_inner .num_contrast .num_contrast_right {
|
||||||
|
padding-left: 18px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ld_left_down {
|
||||||
|
width: 402px;
|
||||||
|
height: 332px;
|
||||||
|
background: url(../../../public/png/rect/lp_left_up.png) no-repeat;
|
||||||
|
background-size: 100% 100%;
|
||||||
|
background-position: 0 0;
|
||||||
|
margin-top: 14px;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
.ld_left_down .top_legend {
|
||||||
|
color: #fff;
|
||||||
|
font-size: 14px;
|
||||||
|
position: absolute;
|
||||||
|
left:120px;
|
||||||
|
}
|
||||||
|
.ld_left_down .top_legend .chart_legend_icon1{
|
||||||
|
margin-right: 10px;
|
||||||
|
}
|
||||||
|
.ld_left_down .top_legend .chart_legend_icon2{
|
||||||
|
margin-right: 14px;
|
||||||
|
}
|
||||||
|
.ld_left_down .top_legend .chart_legend_icon1:before {
|
||||||
|
display: inline-block;
|
||||||
|
content: "";
|
||||||
|
width: 10px;
|
||||||
|
height: 10px;
|
||||||
|
margin-right: 5px;
|
||||||
|
border-radius: 2px;
|
||||||
|
background: #73F8E0;
|
||||||
|
}
|
||||||
|
.ld_left_down .top_legend .chart_legend_icon2:before {
|
||||||
|
display: inline-block;
|
||||||
|
content: "";
|
||||||
|
width: 10px;
|
||||||
|
height: 10px;
|
||||||
|
margin-right: 5px;
|
||||||
|
border-radius: 2px;
|
||||||
|
background: #497EFF;
|
||||||
|
}
|
||||||
|
.ld_left_down .top_legend .chart_legend_icon3 {
|
||||||
|
display: inline-block;
|
||||||
|
width: 8px;
|
||||||
|
height: 8px;
|
||||||
|
margin-right: 8px;
|
||||||
|
border-radius: 4px;
|
||||||
|
background: #73F8E0;
|
||||||
|
position:relative;
|
||||||
|
}
|
||||||
|
.ld_left_down .top_legend .chart_legend_icon3:before {
|
||||||
|
display: inline-block;
|
||||||
|
content: "";
|
||||||
|
width: 16px;
|
||||||
|
height:2px;
|
||||||
|
background: #73F8E0;
|
||||||
|
position:absolute;
|
||||||
|
top:3px;
|
||||||
|
left:-4px;
|
||||||
|
}
|
||||||
|
.ld_center_up {
|
||||||
|
width: 1041px;
|
||||||
|
height: 599px;
|
||||||
|
background: url(../../../public/png/rect/lp_center_up.png) no-repeat;
|
||||||
|
background-size: 100% 100%;
|
||||||
|
background-position: 0 0;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
.ld_center_down {
|
||||||
|
width: 1041px;
|
||||||
|
height: 332px;
|
||||||
|
margin-top: 17px;
|
||||||
|
}
|
||||||
|
.ld_center_down_inner {
|
||||||
|
width: 337px;
|
||||||
|
height: 329px;
|
||||||
|
background: url(../../../public/png/rect/ld_center_down.png) no-repeat;
|
||||||
|
background-size: 100% 100%;
|
||||||
|
background-position: 0 0;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
.ld_center_down .ld_left-box, .ld_center_down .ld_center-box {
|
||||||
|
margin-right: 15px;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
.ld_right_up {
|
||||||
|
width: 402px;
|
||||||
|
height: 599px;
|
||||||
|
background: url(../../../public/png/rect/lp_left_down.png) no-repeat;
|
||||||
|
background-size: 100% 100%;
|
||||||
|
background-position: 0 0;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
.ld_right_down {
|
||||||
|
width: 402px;
|
||||||
|
height: 332px;
|
||||||
|
background: url(../../../public/png/rect/lp_left_up.png) no-repeat;
|
||||||
|
background-size: 100% 100%;
|
||||||
|
background-position: 0 0;
|
||||||
|
margin-top: 14px;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
.ld_right_up .ld_right_up_box {
|
||||||
|
width: 358px;
|
||||||
|
height:160px;
|
||||||
|
background: url(../../../public/png/rect/ld_left_up_innerbox.png) no-repeat;
|
||||||
|
background-size: 100% 100%;
|
||||||
|
background-position: 0 0;
|
||||||
|
margin:0 auto 20px;
|
||||||
|
}
|
||||||
|
.ld_right_up .ld_right_up_box .ld_right_up_box1 {
|
||||||
|
width:100%;
|
||||||
|
height: 80px;
|
||||||
|
color: #fff;
|
||||||
|
padding:12px 20px;
|
||||||
|
}
|
||||||
|
.ld_right_up .ld_right_up_box .ld_right_up_box1 p {
|
||||||
|
margin:0;
|
||||||
|
letter-spacing:2px;
|
||||||
|
font-size:20px;
|
||||||
|
}
|
||||||
|
.ld_right_up_img {
|
||||||
|
position:relative;
|
||||||
|
left:2px;
|
||||||
|
top:2px;
|
||||||
|
}
|
||||||
|
/* 三维页面部分 */
|
||||||
|
.ld_center_up .model_name {
|
||||||
|
position: absolute;
|
||||||
|
left: 0px;
|
||||||
|
top: 0px;
|
||||||
|
z-index: 1000;
|
||||||
|
}
|
||||||
|
.ld_center_up .model_info {
|
||||||
|
position: absolute;
|
||||||
|
left: 100px;
|
||||||
|
bottom: 0px;
|
||||||
|
z-index: 1000;
|
||||||
|
width: 841px;
|
||||||
|
height: 62px;
|
||||||
|
background: url(/public/png/lp/line_part.png) 100% no-repeat;
|
||||||
|
background-size: 100% 100%;
|
||||||
|
}
|
||||||
|
.ld_center_up .model_info .reset_btn {
|
||||||
|
position: absolute;
|
||||||
|
top: 20px;
|
||||||
|
left: 40px;
|
||||||
|
width: 140px;
|
||||||
|
height: 40px;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
.ld_center_up .model_info .title {
|
||||||
|
display: inline-block;
|
||||||
|
width: 361px;
|
||||||
|
text-align: center;
|
||||||
|
font-size: 32px;
|
||||||
|
color: #fff;
|
||||||
|
letter-spacing: 5px;
|
||||||
|
position: absolute;
|
||||||
|
left: 241px;
|
||||||
|
bottom: 10px;
|
||||||
|
}
|
||||||
|
.ld_center_up .eq_detail_info {
|
||||||
|
position: absolute;
|
||||||
|
right: 0px;
|
||||||
|
bottom: 0px;
|
||||||
|
z-index: 1002;
|
||||||
|
width: 300px;
|
||||||
|
height: 140px;
|
||||||
|
background: url(/public/png/lp/eq_msg_detail.png) 100% no-repeat;
|
||||||
|
background-size: 100% 100%;
|
||||||
|
color: #fff;
|
||||||
|
padding: 15px 0 0 15px;
|
||||||
|
}
|
||||||
|
.ld_center_up .eq_detail_info .left_name {
|
||||||
|
display: inline-block;
|
||||||
|
width: 115px;
|
||||||
|
height: 28px;
|
||||||
|
text-align: right;
|
||||||
|
font-size: 18px;
|
||||||
|
}
|
||||||
|
.ld_center_up .eq_detail_info .right_value {
|
||||||
|
display: inline-block;
|
||||||
|
height: 28px;
|
||||||
|
font-size: 18px;
|
||||||
|
}
|
||||||
|
.ld_center_up .eq_info {
|
||||||
|
position: absolute;
|
||||||
|
z-index: 1002;
|
||||||
|
background: url(/public/png/lp/eq_msg_always.png) 100% no-repeat;
|
||||||
|
background-size: 100% 100%;
|
||||||
|
color: #fff;
|
||||||
|
padding: 10px 15px;
|
||||||
|
}
|
||||||
|
.ld_center_up .eq_info .eq_info_inner {
|
||||||
|
height: 24px;
|
||||||
|
font-size: 17px;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
.ld_center_up .model_top_container {
|
||||||
|
width:936px;
|
||||||
|
height:100px;
|
||||||
|
position: absolute;
|
||||||
|
top: 20px;
|
||||||
|
left: 45px;
|
||||||
|
z-index: 1002;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
.ld_center_up .model_top_container .model_top_style1 {
|
||||||
|
display: inline-block;
|
||||||
|
width:203px;
|
||||||
|
}
|
||||||
|
.model_top_style1 .model_top_num {
|
||||||
|
width:100%;
|
||||||
|
height:65px;
|
||||||
|
line-height: 65px;
|
||||||
|
font-size: 38px;
|
||||||
|
font-weight: 500;
|
||||||
|
color: #FFFFFF;
|
||||||
|
text-shadow: 0px 5px 2px rgba(0,0,0,0.62);
|
||||||
|
background: url(./../assets/blue-box.png) 100% no-repeat;
|
||||||
|
background-size: 100% 100%;
|
||||||
|
margin-bottom: 5px;
|
||||||
|
}
|
||||||
|
.model_top_style2 .model_top_num {
|
||||||
|
width:100%;
|
||||||
|
height:65px;
|
||||||
|
line-height: 65px;
|
||||||
|
font-size: 38px;
|
||||||
|
font-weight: 500;
|
||||||
|
color: #FFFFFF;
|
||||||
|
text-shadow: 0px 5px 2px rgba(0,0,0,0.62);
|
||||||
|
background: url(./../assets/yellow-box.png) 100% no-repeat;
|
||||||
|
background-size: 100% 100%;
|
||||||
|
margin-bottom: 5px;
|
||||||
|
}
|
||||||
|
.model_top_style1 .model_top_text {
|
||||||
|
font-size: 20px;
|
||||||
|
font-weight: 500;
|
||||||
|
color: #00C8F7;
|
||||||
|
letter-spacing: 2px;
|
||||||
|
text-shadow: 0px 5px 2px rgba(0,0,0,0.62);
|
||||||
|
}
|
||||||
|
.model_top_style2 .model_top_text {
|
||||||
|
font-size: 20px;
|
||||||
|
font-weight: 500;
|
||||||
|
color: #FFB625;
|
||||||
|
letter-spacing: 2px;
|
||||||
|
text-shadow: 0px 5px 2px rgba(0,0,0,0.62);
|
||||||
|
}
|
||||||
|
.ld_center_up .model_top_container .model_top_style2 {
|
||||||
|
display: inline-block;
|
||||||
|
width:261px;
|
||||||
}
|
}
|
@ -1,35 +1,45 @@
|
|||||||
import "./index.css"
|
import React from "react";
|
||||||
|
import TopP from "./TopP";
|
||||||
|
import Left from "./Left";
|
||||||
|
import Right from "./Right";
|
||||||
|
import Center from "./Center";
|
||||||
import {useEffect} from 'react';
|
import {useEffect} from 'react';
|
||||||
import {useLocation,useNavigate} from "react-router-dom";
|
import {useLocation,useNavigate} from "react-router-dom";
|
||||||
function LDPage() {
|
function LDPage() {
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
const {state} = useLocation();
|
const location = useLocation();
|
||||||
|
const LineID = location.search.split('=')[1];
|
||||||
|
console.log(location)
|
||||||
console.log("LDPage被加载了")
|
console.log("LDPage被加载了")
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const handleKeyDown = (event:any) => {
|
const handleKeyDown = (event:any) => {
|
||||||
if (event.key === 'ArrowUp') {
|
if (event.key === 'ArrowUp') {
|
||||||
console.log('LDPage向上键被按下');
|
console.log('LDPage向上键被按下');
|
||||||
navigate(`/TP/${state.LineID}`);
|
navigate(`/LP/${LineID}`);
|
||||||
// 执行向上键的逻辑
|
// 执行向上键的逻辑
|
||||||
} else if (event.key === 'ArrowDown') {
|
} else if (event.key === 'ArrowDown') {
|
||||||
console.log('LDPage向下键被按下');
|
console.log('LDPage向下键被按下');
|
||||||
// 执行向下键的逻辑
|
// 执行向下键的逻辑
|
||||||
|
navigate(`/LP/${LineID}`);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
window.addEventListener('keydown', handleKeyDown);
|
window.addEventListener('keydown', handleKeyDown);
|
||||||
|
|
||||||
return () => {
|
return () => {
|
||||||
window.removeEventListener('keydown', handleKeyDown);
|
window.removeEventListener('keydown', handleKeyDown);
|
||||||
};
|
};
|
||||||
}, []);
|
});
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<React.Fragment>
|
||||||
<div className="main-box">LDPage{state.LineID}</div>
|
<TopP />
|
||||||
<div className="main-box" style={{display:'none'}}>3434</div>
|
<div className="block_bottom flex-row">
|
||||||
</>
|
<Left />
|
||||||
);
|
<Center />
|
||||||
|
<Right />
|
||||||
|
</div>
|
||||||
|
</React.Fragment>
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
export default LDPage;
|
export default LDPage;
|
@ -1,248 +0,0 @@
|
|||||||
import ReactECharts from "echarts-for-react";
|
|
||||||
import TitleBox from "../Component/TitleBox";
|
|
||||||
import ScrollBoard from "./../../Component/ScrollBoard";
|
|
||||||
import SwitchButton from "../Component/SwitchButton";
|
|
||||||
import { useState } from "react";
|
|
||||||
import getOptions from "./LineChart/chart.config";
|
|
||||||
import { useParams } from "react-router-dom";
|
|
||||||
function CenterDown() {
|
|
||||||
const { LineID } = useParams();
|
|
||||||
const lineID = LineID?.toString() || "1-1";
|
|
||||||
console.log(lineID.slice(-1));
|
|
||||||
// 假数据
|
|
||||||
const dataSource = {
|
|
||||||
day: {
|
|
||||||
yData1: [76.1, 77.4, 75.2, 74.1, 78.5, 81.3, 79.2],
|
|
||||||
yData2: [77.2, 78.1, 78.2, 77.1, 79.2, 78.3, 79.5],
|
|
||||||
yData3: [75.1, 74.3, 71.3, 79.8, 82.3, 81.4, 80.3],
|
|
||||||
yData4: [82.4, 83.1, 88.4, 85.3, 87.1, 82.5, 84.9],
|
|
||||||
yData5: [82.3, 81.9, 85.8, 81.9, 84.1, 83.5, 82.3],
|
|
||||||
},
|
|
||||||
week: {
|
|
||||||
yData1: [120, 200, 150, 80, 100, 89, 69],
|
|
||||||
yData2: [100, 150, 120, 70, 90, 97, 89],
|
|
||||||
yData3: [80, 120, 90, 60, 80, 79, 98],
|
|
||||||
yData4: [60, 90, 70, 40, 60, 69, 98],
|
|
||||||
yData5: [40, 60, 50, 20, 40, 89, 99],
|
|
||||||
},
|
|
||||||
month: {
|
|
||||||
yData1: [1200, 2000, 1500, 800, 1000, 999, 889],
|
|
||||||
yData2: [1000, 1500, 1200, 700, 900, 987, 897],
|
|
||||||
yData3: [800, 1200, 900, 600, 800, 962, 759],
|
|
||||||
yData4: [600, 900, 700, 400, 600, 896, 987],
|
|
||||||
yData5: [400, 600, 500, 200, 400, 986, 951],
|
|
||||||
},
|
|
||||||
};
|
|
||||||
const nameList = [
|
|
||||||
{ name: "天", ename: "day" },
|
|
||||||
{ name: "周", ename: "week" },
|
|
||||||
{ name: "月", ename: "month" },
|
|
||||||
];
|
|
||||||
const [activeName, setActiveName] = useState<string>(nameList[0].ename);
|
|
||||||
let chartData = (dataSource as { [key: string]: any })[activeName];
|
|
||||||
const handleButtonChange = (activeName: string) => {
|
|
||||||
setActiveName(activeName);
|
|
||||||
};
|
|
||||||
const options = getOptions(chartData);
|
|
||||||
const config = {
|
|
||||||
header: ["序号", "报警时间", "报警编码", "设备状态"],
|
|
||||||
headerHeight: 36,
|
|
||||||
rowNum: 6,
|
|
||||||
align: ["center", "left", "left", "left"],
|
|
||||||
headerBGC: "rgba(79, 114, 136, 0.3)",
|
|
||||||
oddRowBGC: "rgba(79, 114, 136, 0.3)",
|
|
||||||
evenRowBGC: "rgba(76, 97, 123, 0.1)",
|
|
||||||
columnWidth: [80, 137, 137, 137],
|
|
||||||
data: [
|
|
||||||
["1", "行1列1", "行1列2", "<span style='color:#FF1E1E'>行1列3</span>"],
|
|
||||||
["2", "行2列1", "行2列2", "<span style='color:#FF1E1E'>行2列3</span>"],
|
|
||||||
["3", "行3列1", "行3列2", "<span style='color:#FF1E1E'>行3列3</span>"],
|
|
||||||
["4", "行4列1", "行4列2", "<span style='color:#FFB40F'>行4列3</span>"],
|
|
||||||
["5", "行5列1", "行5列2", "<span style='color:#FF1E1E'>行5列3</span>"],
|
|
||||||
["6", "行6列1", "行6列2", "<span style='color:#FFB40F'>行6列3</span>"],
|
|
||||||
["7", "行7列1", "行7列2", "<span style='color:#FF1E1E'>行7列3</span>"],
|
|
||||||
["8", "行8列1", "行8列2", "<span style='color:#FF1E1E'>行8列3</span>"],
|
|
||||||
["9", "行9列1", "行9列2", "<span style='color:#FF1E1E'>行9列3</span>"],
|
|
||||||
[
|
|
||||||
"10",
|
|
||||||
"行10列1",
|
|
||||||
"行10列2",
|
|
||||||
"<span style='color:#FFB40F'>行10列3</span>",
|
|
||||||
],
|
|
||||||
],
|
|
||||||
};
|
|
||||||
const config1 = {
|
|
||||||
header: ["序号", "报警时间", "报警设备", "报警内容"],
|
|
||||||
headerHeight: 36,
|
|
||||||
rowNum: 6,
|
|
||||||
align: ["center", "left", "left", "left"],
|
|
||||||
headerBGC: "rgba(79, 114, 136, 0.3)",
|
|
||||||
oddRowBGC: "rgba(79, 114, 136, 0.3)",
|
|
||||||
evenRowBGC: "rgba(76, 97, 123, 0.1)",
|
|
||||||
columnWidth: [80, 137, 137, 137],
|
|
||||||
data: [
|
|
||||||
[
|
|
||||||
"1",
|
|
||||||
"2024/8/28 08:32",
|
|
||||||
"清洗机5_1",
|
|
||||||
"<span style='color:#FF1E1E'>故障</span>",
|
|
||||||
],
|
|
||||||
[
|
|
||||||
"2",
|
|
||||||
"2024/8/28 06:12",
|
|
||||||
"清洗机5_1",
|
|
||||||
"<span style='color:#FFB40F'>离线</span>",
|
|
||||||
],
|
|
||||||
[
|
|
||||||
"3",
|
|
||||||
"2024/8/28 06:05",
|
|
||||||
"磨边机5_2",
|
|
||||||
"<span style='color:#FFB40F'>离线</span>",
|
|
||||||
],
|
|
||||||
[
|
|
||||||
"4",
|
|
||||||
"2024/8/28 04:43",
|
|
||||||
"二次镀膜机5_1",
|
|
||||||
"<span style='color:#FFB40F'>离线</span>",
|
|
||||||
],
|
|
||||||
[
|
|
||||||
"5",
|
|
||||||
"2024/8/28 02:14",
|
|
||||||
"磨边机5_1",
|
|
||||||
"<span style='color:#FF1E1E'>故障</span>",
|
|
||||||
],
|
|
||||||
[
|
|
||||||
"6",
|
|
||||||
"2024/8/27 22:54",
|
|
||||||
"磨边机5_2",
|
|
||||||
"<span style='color:#FFB40F'>离线</span>",
|
|
||||||
],
|
|
||||||
[
|
|
||||||
"7",
|
|
||||||
"2024/8/27 21:55",
|
|
||||||
"磨边机5_1",
|
|
||||||
"<span style='color:#FFB40F'>离线</span>",
|
|
||||||
],
|
|
||||||
[
|
|
||||||
"8",
|
|
||||||
"2024/8/27 21:42",
|
|
||||||
"一次镀膜机5_2",
|
|
||||||
"<span style='color:#FFB40F'>离线</span>",
|
|
||||||
],
|
|
||||||
[
|
|
||||||
"9",
|
|
||||||
"2024/8/27 21:37",
|
|
||||||
"磨边机5_1",
|
|
||||||
"<span style='color:#FFB40F'>离线</span>",
|
|
||||||
],
|
|
||||||
],
|
|
||||||
};
|
|
||||||
const config2 = {
|
|
||||||
header: ["序号", "报警时间", "报警设备", "报警内容"],
|
|
||||||
headerHeight: 36,
|
|
||||||
rowNum: 6,
|
|
||||||
align: ["center", "left", "left", "left"],
|
|
||||||
headerBGC: "rgba(79, 114, 136, 0.3)",
|
|
||||||
oddRowBGC: "rgba(79, 114, 136, 0.3)",
|
|
||||||
evenRowBGC: "rgba(76, 97, 123, 0.1)",
|
|
||||||
columnWidth: [80, 137, 137, 137],
|
|
||||||
data: [
|
|
||||||
[
|
|
||||||
"1",
|
|
||||||
"2024/8/28 07:44",
|
|
||||||
"下片机械手5_1",
|
|
||||||
"<span style='color:#FF1E1E'>故障</span>",
|
|
||||||
],
|
|
||||||
[
|
|
||||||
"2",
|
|
||||||
"2024/8/28 07:35",
|
|
||||||
"下片机械手5_1",
|
|
||||||
"<span style='color:#FF1E1E'>故障</span>",
|
|
||||||
],
|
|
||||||
[
|
|
||||||
"3",
|
|
||||||
"2024/8/28 03:23",
|
|
||||||
"在线铺纸机5_1",
|
|
||||||
"<span style='color:#FFB40F'>离线</span>",
|
|
||||||
],
|
|
||||||
[
|
|
||||||
"4",
|
|
||||||
"2024/8/28 01:36",
|
|
||||||
"下片机械手5_2",
|
|
||||||
"<span style='color:#FF1E1E'>故障</span>",
|
|
||||||
],
|
|
||||||
[
|
|
||||||
"5",
|
|
||||||
"2024/8/28 00:38",
|
|
||||||
"钢化炉5",
|
|
||||||
"<span style='color:#FFB40F'>离线</span>",
|
|
||||||
],
|
|
||||||
[
|
|
||||||
"6",
|
|
||||||
"2024/8/27 23:58",
|
|
||||||
"下片机械手5_3",
|
|
||||||
"<span style='color:#FFB40F'>离线</span>",
|
|
||||||
],
|
|
||||||
[
|
|
||||||
"7",
|
|
||||||
"2024/8/27 23:45",
|
|
||||||
"下片机械手5_2",
|
|
||||||
"<span style='color:#FFB40F'>离线</span>",
|
|
||||||
],
|
|
||||||
[
|
|
||||||
"8",
|
|
||||||
"2024/8/27 22:34",
|
|
||||||
"钢化炉5",
|
|
||||||
"<span style='color:#FFB40F'>离线</span>",
|
|
||||||
],
|
|
||||||
[
|
|
||||||
"9",
|
|
||||||
"2024/8/27 20:31",
|
|
||||||
"在线铺纸机5_1",
|
|
||||||
"<span style='color:#FF1E1E'>故障</span>",
|
|
||||||
],
|
|
||||||
],
|
|
||||||
};
|
|
||||||
return (
|
|
||||||
<div className="center_down flex-row">
|
|
||||||
<div className="center_down_inner flex-col left-box">
|
|
||||||
<TitleBox title={"center_down_left"} />
|
|
||||||
<span className="alarm_num_title">— 报警总数 —</span>
|
|
||||||
<div className="alarm_num">321,343</div>
|
|
||||||
<div style={{ padding: 10, height: "270px" }}>
|
|
||||||
<ScrollBoard
|
|
||||||
config={lineID.slice(-1) === "1" ? config1 : config2}
|
|
||||||
style={{ width: "492px", height: "250px" }}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{/* 产线成品率 */}
|
|
||||||
<div className="center_down_inner flex-col right_box">
|
|
||||||
<TitleBox title={"center_down_right"} />
|
|
||||||
{/* <div className="left_up_switch">
|
|
||||||
<SwitchButton nameList={nameList} onChange={handleButtonChange} />
|
|
||||||
</div> */}
|
|
||||||
|
|
||||||
{options && (
|
|
||||||
<div className="chart_box">
|
|
||||||
{<ReactECharts option={options} style={{ height: "100%" }} />}
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
{!options && (
|
|
||||||
<p
|
|
||||||
style={{
|
|
||||||
color: "#cccf",
|
|
||||||
fontSize: "24px",
|
|
||||||
userSelect: "none",
|
|
||||||
textAlign: "center",
|
|
||||||
paddingTop: "72px",
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
暂无数据
|
|
||||||
</p>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
export default CenterDown;
|
|
@ -1,12 +0,0 @@
|
|||||||
import LinePageBabylon from "../../../babylonjs/LinePageBabylon";
|
|
||||||
import { useParams } from "react-router-dom";
|
|
||||||
function CenterUp() {
|
|
||||||
const { LineID } = useParams();
|
|
||||||
const lineID = LineID?.toString() || "1-1";
|
|
||||||
return (
|
|
||||||
<div className="center_up">
|
|
||||||
<LinePageBabylon modelPath={`Line${lineID}`} />
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
export default CenterUp;
|
|
@ -1,69 +0,0 @@
|
|||||||
import ReactECharts from "echarts-for-react";
|
|
||||||
import TitleBox from "../Component/TitleBox";
|
|
||||||
import SwitchButton from "../Component/SwitchButton";
|
|
||||||
import getOptions from "./SummaryBarChart/chart.config";
|
|
||||||
import { useState } from "react";
|
|
||||||
function LeftUp() {
|
|
||||||
// 假数据
|
|
||||||
const dataSource = {
|
|
||||||
day: {
|
|
||||||
xData: ["钢1线", "钢2线", "钢3线", "钢4线", "钢5线"],
|
|
||||||
yData1: [236, 214, 196, 239, 224],
|
|
||||||
yData2: [346, 296, 327, 311, 322],
|
|
||||||
yData3: [78, 85, 56, 106, 66],
|
|
||||||
sumData: [660, 595, 579, 656, 612],
|
|
||||||
},
|
|
||||||
week: {
|
|
||||||
xData: ["钢1线", "钢2线", "钢3线", "钢4线", "钢5线"],
|
|
||||||
yData1: [1336, 1223, 1313, 1134, 1119],
|
|
||||||
yData2: [2146, 1996, 2053, 1857, 1798],
|
|
||||||
yData3: [892, 658, 467, 758, 435],
|
|
||||||
sumData: [4374, 3877, 3833, 3749, 3352],
|
|
||||||
},
|
|
||||||
month: {
|
|
||||||
xData: ["钢1线", "钢2线", "钢3线", "钢4线", "钢5线"],
|
|
||||||
yData1: [5789, 6432, 4679, 5456, 5004],
|
|
||||||
yData2: [8762, 9732, 8137, 8820, 9122],
|
|
||||||
yData3: [2468, 3120, 2782, 2395, 1924],
|
|
||||||
sumData: [17019, 19284, 15598, 16671, 16050],
|
|
||||||
},
|
|
||||||
};
|
|
||||||
const nameList = [
|
|
||||||
{ name: "天", ename: "day" },
|
|
||||||
{ name: "周", ename: "week" },
|
|
||||||
{ name: "月", ename: "month" },
|
|
||||||
];
|
|
||||||
const [activeName, setActiveName] = useState<string>(nameList[0].ename);
|
|
||||||
let chartData = (dataSource as { [key: string]: any })[activeName];
|
|
||||||
const handleButtonChange = (activeName: string) => {
|
|
||||||
setActiveName(activeName);
|
|
||||||
};
|
|
||||||
const options = getOptions(chartData);
|
|
||||||
return (
|
|
||||||
<div className="left_up">
|
|
||||||
<TitleBox title={"left_up"} />
|
|
||||||
<div className="left_up_switch">
|
|
||||||
<SwitchButton nameList={nameList} onChange={handleButtonChange} />
|
|
||||||
</div>
|
|
||||||
{options && (
|
|
||||||
<div className="left_up_chart">
|
|
||||||
{<ReactECharts option={options} style={{ height: "100%" }} />}
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
{!options && (
|
|
||||||
<p
|
|
||||||
style={{
|
|
||||||
color: "#cccf",
|
|
||||||
fontSize: "24px",
|
|
||||||
userSelect: "none",
|
|
||||||
textAlign: "center",
|
|
||||||
paddingTop: "72px",
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
暂无数据
|
|
||||||
</p>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
export default LeftUp;
|
|
@ -1,149 +0,0 @@
|
|||||||
export default function getOptions(chartData: any) {
|
|
||||||
if (Object.keys(chartData).length === 0) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
const colors = ["#2760FF", "#8167F6", "#5B9BFF", "#99D66C", "#FFD160"];
|
|
||||||
let sum = chartData.sumData;
|
|
||||||
return {
|
|
||||||
color: colors,
|
|
||||||
grid: { top: 48, right: 20, bottom: 5, left: 15, containLabel: true },
|
|
||||||
legend: {
|
|
||||||
show: true,
|
|
||||||
icon: "roundRect",
|
|
||||||
top: 10,
|
|
||||||
right: 20,
|
|
||||||
padding: 0,
|
|
||||||
itemWidth: 10,
|
|
||||||
itemHeight: 10,
|
|
||||||
itemGap: 15,
|
|
||||||
height: 10,
|
|
||||||
textStyle: {
|
|
||||||
color: "#DFF1FE",
|
|
||||||
fontSize: 14,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
xAxis: {
|
|
||||||
type: "category",
|
|
||||||
data: chartData.xData,
|
|
||||||
axisLabel: {
|
|
||||||
color: "#fff",
|
|
||||||
fontSize: 16,
|
|
||||||
},
|
|
||||||
axisTick: { show: false },
|
|
||||||
axisLine: {
|
|
||||||
lineStyle: {
|
|
||||||
width: 2,
|
|
||||||
color: "#5982B2",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
yAxis: {
|
|
||||||
name: "单位/片",
|
|
||||||
nameTextStyle: {
|
|
||||||
color: "#fff",
|
|
||||||
fontSize: 14,
|
|
||||||
},
|
|
||||||
type: "value",
|
|
||||||
axisLabel: {
|
|
||||||
color: "#fff",
|
|
||||||
fontSize: 16,
|
|
||||||
formatter: "{value}",
|
|
||||||
},
|
|
||||||
axisLine: {
|
|
||||||
show: true,
|
|
||||||
lineStyle: {
|
|
||||||
width: 2,
|
|
||||||
color: "#5982B2",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
splitLine: {
|
|
||||||
lineStyle: {
|
|
||||||
width: 2,
|
|
||||||
color: "#5982B2",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
tooltip: {
|
|
||||||
show: false,
|
|
||||||
trigger: "axis",
|
|
||||||
axisPointer: {
|
|
||||||
type: "shadow",
|
|
||||||
},
|
|
||||||
className: "luoyang-chart-tooltip",
|
|
||||||
},
|
|
||||||
// Declare several bar series, each will be mapped
|
|
||||||
// to a column of dataset.source by default.
|
|
||||||
series: [
|
|
||||||
{
|
|
||||||
data: chartData.yData1,
|
|
||||||
type: "bar",
|
|
||||||
stack: "a",
|
|
||||||
name: "磨边后",
|
|
||||||
barWidth: 14,
|
|
||||||
label: {
|
|
||||||
show: true,
|
|
||||||
position: "right",
|
|
||||||
color: "inherit",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
data: chartData.yData2,
|
|
||||||
type: "bar",
|
|
||||||
stack: "a",
|
|
||||||
name: "包装1",
|
|
||||||
label: {
|
|
||||||
show: true,
|
|
||||||
position: "right",
|
|
||||||
color: "inherit",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
data: chartData.yData3,
|
|
||||||
type: "bar",
|
|
||||||
stack: "a",
|
|
||||||
name: "包装2",
|
|
||||||
label: {
|
|
||||||
show: true,
|
|
||||||
position: "right",
|
|
||||||
color: "inherit",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
// {
|
|
||||||
// data: chartData.yData4,
|
|
||||||
// type: "bar",
|
|
||||||
// stack: "a",
|
|
||||||
// name: "镀膜",
|
|
||||||
// label: {
|
|
||||||
// show: true,
|
|
||||||
// position: "right",
|
|
||||||
// color: "inherit",
|
|
||||||
// },
|
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// data: chartData.yData5,
|
|
||||||
// type: "bar",
|
|
||||||
// stack: "a",
|
|
||||||
// name: "包装",
|
|
||||||
// label: {
|
|
||||||
// show: true,
|
|
||||||
// position: "right",
|
|
||||||
// color: "inherit",
|
|
||||||
// },
|
|
||||||
// },
|
|
||||||
{
|
|
||||||
data: [0, 0, 0, 0, 0],
|
|
||||||
type: "bar",
|
|
||||||
stack: "a",
|
|
||||||
name: "",
|
|
||||||
label: {
|
|
||||||
show: true,
|
|
||||||
position: "top",
|
|
||||||
color: "#fff",
|
|
||||||
formatter: function (params: any) {
|
|
||||||
return sum[params.dataIndex];
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
],
|
|
||||||
};
|
|
||||||
}
|
|
@ -1,4 +0,0 @@
|
|||||||
function Table() {
|
|
||||||
return <div>111</div>;
|
|
||||||
}
|
|
||||||
export default Table;
|
|
@ -1,33 +0,0 @@
|
|||||||
import TitleBox from "../Component/TitleBox";
|
|
||||||
import ScrollBoard from "./../../Component/ScrollBoard";
|
|
||||||
function RightUp() {
|
|
||||||
const config = {
|
|
||||||
header: ["序号", "产线", "上片数据量", "成品下片数量"],
|
|
||||||
headerHeight: 32,
|
|
||||||
rowNum: 5,
|
|
||||||
align: ["center", "left", "left", "left"],
|
|
||||||
headerBGC: "rgba(79, 114, 136, 0.3)",
|
|
||||||
oddRowBGC: "rgba(79, 114, 136, 0.3)",
|
|
||||||
evenRowBGC: "rgba(76, 97, 123, 0.1)",
|
|
||||||
columnWidth: [70, 90, 106, 114],
|
|
||||||
data: [
|
|
||||||
["1", "钢1线", "82315", "64268"],
|
|
||||||
["2", "钢2线", "78246", "61235"],
|
|
||||||
["3", "钢3线", "79092", "63562"],
|
|
||||||
["4", "钢4线", "84125", "66789"],
|
|
||||||
["5", "钢5线", "85223", "68246"],
|
|
||||||
],
|
|
||||||
};
|
|
||||||
return (
|
|
||||||
<div className="right_up">
|
|
||||||
<TitleBox title={"right_up"} />
|
|
||||||
<div style={{ padding: "10px", height: "213px" }}>
|
|
||||||
<ScrollBoard
|
|
||||||
config={config}
|
|
||||||
style={{ width: "380px", height: "193px" }}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
export default RightUp;
|
|
@ -1,18 +0,0 @@
|
|||||||
import React from "react";
|
|
||||||
import TopP from "./TopP";
|
|
||||||
import Left from "./Left";
|
|
||||||
import Right from "./Right";
|
|
||||||
import Center from "./Center";
|
|
||||||
function LinePage() {
|
|
||||||
return (
|
|
||||||
<React.Fragment>
|
|
||||||
<TopP />
|
|
||||||
<div className="block_bottom flex-row">
|
|
||||||
<Left />
|
|
||||||
<Center />
|
|
||||||
<Right />
|
|
||||||
</div>
|
|
||||||
</React.Fragment>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
export default LinePage;
|
|
213
src/page/LinePage1-1/Center/CenterDown.tsx
Normal file
213
src/page/LinePage1-1/Center/CenterDown.tsx
Normal file
@ -0,0 +1,213 @@
|
|||||||
|
import ReactECharts from "echarts-for-react";
|
||||||
|
import TitleBox from "../Component/TitleBox";
|
||||||
|
import ScrollBoard from "./../../Component/ScrollBoard";
|
||||||
|
// import SwitchButton from "../Component/SwitchButton";
|
||||||
|
import { useState } from "react";
|
||||||
|
import getOptions from "../../Component/LineChart/chart.config";
|
||||||
|
import {useAppSelector} from "./../../../store/hooks"
|
||||||
|
import {selectLine1Before} from "./../../../store/LinePageSlice"
|
||||||
|
import dayjs from "dayjs";
|
||||||
|
function CenterDown() {
|
||||||
|
const data = useAppSelector(selectLine1Before);
|
||||||
|
// 假数据
|
||||||
|
const dataSource = {
|
||||||
|
day: {
|
||||||
|
xData:[],
|
||||||
|
series: [] as { name: string; type: string; symbol: string; symbolSize: number; data: never[]; }[],
|
||||||
|
},
|
||||||
|
week: {
|
||||||
|
xData:[],
|
||||||
|
series: [] as { name: string; type: string; symbol: string; symbolSize: number; data: never[]; }[],
|
||||||
|
},
|
||||||
|
month: {
|
||||||
|
xData:[],
|
||||||
|
series: [] as { name: string; type: string; symbol: string; symbolSize: number; data: never[]; }[],
|
||||||
|
},
|
||||||
|
};
|
||||||
|
const nameList = [
|
||||||
|
{ name: "天", ename: "day" },
|
||||||
|
{ name: "周", ename: "week" },
|
||||||
|
{ name: "月", ename: "month" },
|
||||||
|
];
|
||||||
|
const [activeName, setActiveName] = useState<string>(nameList[1].ename);
|
||||||
|
// const handleButtonChange = (activeName: string) => {
|
||||||
|
// setActiveName(activeName);
|
||||||
|
// };
|
||||||
|
const config = {
|
||||||
|
header: ["序号", "报警时间", "报警设备", "报警内容"],
|
||||||
|
headerHeight: 36,
|
||||||
|
rowNum: 6,
|
||||||
|
align: ["center", "left", "left", "left"],
|
||||||
|
headerBGC: "rgba(79, 114, 136, 0.3)",
|
||||||
|
oddRowBGC: "rgba(79, 114, 136, 0.3)",
|
||||||
|
evenRowBGC: "rgba(76, 97, 123, 0.1)",
|
||||||
|
columnWidth: [80, 137, 177, 97],
|
||||||
|
data: []
|
||||||
|
};
|
||||||
|
// 报警数据
|
||||||
|
let arr:any = []
|
||||||
|
let sumAlarm = 0
|
||||||
|
// @ts-ignore
|
||||||
|
if (data.alarms && data.alarms.length > 0) {
|
||||||
|
// @ts-ignore
|
||||||
|
sumAlarm = data.alarms.length
|
||||||
|
// @ts-ignore
|
||||||
|
data.alarms.map((item,index) => {
|
||||||
|
let arrInner = []
|
||||||
|
arrInner.push(
|
||||||
|
index+1,
|
||||||
|
dayjs(item.recTime).format("YYYY/MM/DD HH:mm"),
|
||||||
|
item.name,
|
||||||
|
item.status === '故障'?"<span style='color:#FF1E1E'>故障</span>":"<span style='color:#FFB40F'>离线</span>",
|
||||||
|
);
|
||||||
|
arr.push(arrInner)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
config.data = arr
|
||||||
|
// 工段成品率
|
||||||
|
// @ts-ignore
|
||||||
|
if (data.todayProductionRates && Object.keys(data.todayProductionRates).length > 0) {
|
||||||
|
// @ts-ignore
|
||||||
|
let keys = Object.keys(data.todayProductionRates)
|
||||||
|
// @ts-ignore
|
||||||
|
data.todayProductionRates[keys[0]].map((item,index)=>{
|
||||||
|
// @ts-ignore
|
||||||
|
dataSource.day.xData.push(dayjs(item.recTime).format("HH:mm"))
|
||||||
|
})
|
||||||
|
keys.map((item,index)=>{
|
||||||
|
let obj = {
|
||||||
|
name: "",
|
||||||
|
type: "line",
|
||||||
|
symbol: "circle",
|
||||||
|
symbolSize: 4,
|
||||||
|
data:[]
|
||||||
|
}
|
||||||
|
// @ts-ignore
|
||||||
|
obj.name = data.todayProductionRates[item][0].lineName
|
||||||
|
// @ts-ignore
|
||||||
|
data.todayProductionRates[item].map((subItem,index)=>{
|
||||||
|
// @ts-ignore
|
||||||
|
obj.data.push(subItem.passRate)
|
||||||
|
})
|
||||||
|
dataSource.day.series.push(obj)
|
||||||
|
})
|
||||||
|
}else{
|
||||||
|
dataSource.day.xData = []
|
||||||
|
dataSource.day.series = []
|
||||||
|
}
|
||||||
|
// @ts-ignore
|
||||||
|
if (data.weekProductionRates && Object.keys(data.weekProductionRates).length > 0) {
|
||||||
|
// @ts-ignore
|
||||||
|
let keys = Object.keys(data.weekProductionRates)
|
||||||
|
// @ts-ignore
|
||||||
|
data.weekProductionRates[keys[0]].map((item,index)=>{
|
||||||
|
// @ts-ignore
|
||||||
|
dataSource.week.xData.push(dayjs(item.recTime).format("HH:mm"))
|
||||||
|
})
|
||||||
|
keys.map((item,index)=>{
|
||||||
|
let obj = {
|
||||||
|
name: "",
|
||||||
|
type: "line",
|
||||||
|
symbol: "circle",
|
||||||
|
symbolSize: 4,
|
||||||
|
data:[]
|
||||||
|
}
|
||||||
|
// @ts-ignore
|
||||||
|
obj.name = data.weekProductionRates[item][0].lineName
|
||||||
|
// @ts-ignore
|
||||||
|
data.weekProductionRates[item].map((subItem,index)=>{
|
||||||
|
// @ts-ignore
|
||||||
|
obj.data.push(subItem.passRate)
|
||||||
|
})
|
||||||
|
dataSource.week.series.push(obj)
|
||||||
|
})
|
||||||
|
}else{
|
||||||
|
dataSource.week.xData = []
|
||||||
|
dataSource.week.series = []
|
||||||
|
}
|
||||||
|
// @ts-ignore
|
||||||
|
if (data.monthProductionRates && Object.keys(data.monthProductionRates).length > 0) {
|
||||||
|
// @ts-ignore
|
||||||
|
let keys = Object.keys(data.monthProductionRates)
|
||||||
|
// @ts-ignore
|
||||||
|
data.monthProductionRates[keys[0]].map((item,index)=>{
|
||||||
|
// @ts-ignore
|
||||||
|
dataSource.month.xData.push(dayjs(item.recTime).format("HH:mm"))
|
||||||
|
})
|
||||||
|
keys.map((item,index)=>{
|
||||||
|
let obj = {
|
||||||
|
name: "",
|
||||||
|
type: "line",
|
||||||
|
symbol: "circle",
|
||||||
|
symbolSize: 4,
|
||||||
|
data:[]
|
||||||
|
}
|
||||||
|
// @ts-ignore
|
||||||
|
obj.name = data.monthProductionRates[item][0].lineName
|
||||||
|
// @ts-ignore
|
||||||
|
data.monthProductionRates[item].map((subItem,index)=>{
|
||||||
|
// @ts-ignore
|
||||||
|
obj.data.push(subItem.passRate)
|
||||||
|
})
|
||||||
|
dataSource.month.series.push(obj)
|
||||||
|
})
|
||||||
|
}else{
|
||||||
|
dataSource.month.xData = []
|
||||||
|
dataSource.month.series = []
|
||||||
|
}
|
||||||
|
let chartData = (dataSource as { [key: string]: any })[activeName];
|
||||||
|
const options = getOptions(chartData);
|
||||||
|
return (
|
||||||
|
<div className="center_down flex-row">
|
||||||
|
<div className="center_down_inner flex-col left-box">
|
||||||
|
<TitleBox title={"center_down_left"} />
|
||||||
|
<span className="alarm_num_title">— 报警总数 —</span>
|
||||||
|
<div className="alarm_num">{sumAlarm}</div>
|
||||||
|
<div style={{ padding: 10, height: "270px" }}>
|
||||||
|
{arr.length>0?<ScrollBoard
|
||||||
|
config={config}
|
||||||
|
style={{ width: "492px", height: "250px" }}
|
||||||
|
/>:(<p
|
||||||
|
style={{
|
||||||
|
color: "#cccf",
|
||||||
|
fontSize: "24px",
|
||||||
|
userSelect: "none",
|
||||||
|
textAlign: "center",
|
||||||
|
paddingTop: "50px",
|
||||||
|
margin:0
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
暂无数据
|
||||||
|
</p>)}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{/* 工段成品率 */}
|
||||||
|
<div className="center_down_inner flex-col right_box">
|
||||||
|
<TitleBox title={"center_down_right"} />
|
||||||
|
{/* <div className="left_up_switch">
|
||||||
|
<SwitchButton nameList={nameList} onChange={handleButtonChange} />
|
||||||
|
</div> */}
|
||||||
|
{chartData.xData.length>0 && (
|
||||||
|
<div className="chart_box">
|
||||||
|
{<ReactECharts option={options} style={{ height: "100%" }} />}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
{chartData.xData.length==0 && (
|
||||||
|
<p
|
||||||
|
style={{
|
||||||
|
color: "#cccf",
|
||||||
|
fontSize: "24px",
|
||||||
|
userSelect: "none",
|
||||||
|
textAlign: "center",
|
||||||
|
paddingTop: "120px",
|
||||||
|
margin:0
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
暂无数据
|
||||||
|
</p>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
export default CenterDown;
|
10
src/page/LinePage1-1/Center/CenterUp.tsx
Normal file
10
src/page/LinePage1-1/Center/CenterUp.tsx
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
import LinePageBabylon from "../../../babylonjs/LinePageBabylonNew";
|
||||||
|
function CenterUp() {
|
||||||
|
const lineID = "1-1"
|
||||||
|
return (
|
||||||
|
<div className="center_up">
|
||||||
|
<LinePageBabylon modelPath={`Line${lineID}`} />
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
export default CenterUp;
|
12
src/page/LinePage1-1/Center/index.tsx
Normal file
12
src/page/LinePage1-1/Center/index.tsx
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
import CenterDown from "./CenterDown";
|
||||||
|
import CenterUp from "./CenterUp";
|
||||||
|
|
||||||
|
function Center() {
|
||||||
|
return (
|
||||||
|
<div className="group_center flex-col">
|
||||||
|
<CenterUp />
|
||||||
|
<CenterDown />
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
export default Center;
|
13
src/page/LinePage1-1/Component/TitleBox/index.css
Normal file
13
src/page/LinePage1-1/Component/TitleBox/index.css
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
.title_box {
|
||||||
|
font-size: 24px;
|
||||||
|
color: #52fff1;
|
||||||
|
padding: 10px 0 0 15px;
|
||||||
|
}
|
||||||
|
.title_box img {
|
||||||
|
width: 33px;
|
||||||
|
height: 33px;
|
||||||
|
vertical-align: bottom;
|
||||||
|
margin-right: 3px;
|
||||||
|
position: relative;
|
||||||
|
top: 3px;
|
||||||
|
}
|
@ -1,9 +1,9 @@
|
|||||||
import Defect from "./../../assets/icon/defect.png";
|
import Defect from "./../../../assets/icon/defect.png";
|
||||||
import Alarm from "./../../assets/icon/alarm.png";
|
import Alarm from "./../../../assets/icon/alarm.png";
|
||||||
import Finished from "./../../assets/icon/finished.png";
|
import Finished from "./../../../assets/icon/finished.png";
|
||||||
import InputAndOutput from "./../../assets/icon/inputAndOutput.png";
|
import InputAndOutput from "./../../../assets/icon/inputAndOutput.png";
|
||||||
import Num from "./../../assets/icon/num.png";
|
import Num from "./../../../assets/icon/num.png";
|
||||||
import Record from "./../../assets/icon/record.png";
|
import Record from "./../../../assets/icon/record.png";
|
||||||
import "./index.css";
|
import "./index.css";
|
||||||
interface titleProps {
|
interface titleProps {
|
||||||
title: string;
|
title: string;
|
||||||
@ -14,12 +14,12 @@ function TitleBox(props: titleProps) {
|
|||||||
case "left_up":
|
case "left_up":
|
||||||
return {
|
return {
|
||||||
img: Defect,
|
img: Defect,
|
||||||
title: "产线报废汇总",
|
title: "工段报废汇总",
|
||||||
};
|
};
|
||||||
case "left_down":
|
case "left_down":
|
||||||
return {
|
return {
|
||||||
img: Record,
|
img: Record,
|
||||||
title: "当前产线报废情况",
|
title: "工序报废情况",
|
||||||
};
|
};
|
||||||
case "center_down_left":
|
case "center_down_left":
|
||||||
return {
|
return {
|
||||||
@ -29,12 +29,12 @@ function TitleBox(props: titleProps) {
|
|||||||
case "center_down_right":
|
case "center_down_right":
|
||||||
return {
|
return {
|
||||||
img: Finished,
|
img: Finished,
|
||||||
title: "产线成品率",
|
title: "工段成品率",
|
||||||
};
|
};
|
||||||
case "right_up":
|
case "right_up":
|
||||||
return {
|
return {
|
||||||
img: Num,
|
img: Num,
|
||||||
title: "各产线总投入和产出",
|
title: "各工段总投入和产出",
|
||||||
};
|
};
|
||||||
default:
|
default:
|
||||||
return {
|
return {
|
250
src/page/LinePage1-1/Left/LeftDown.tsx
Normal file
250
src/page/LinePage1-1/Left/LeftDown.tsx
Normal file
@ -0,0 +1,250 @@
|
|||||||
|
import ReactECharts from "echarts-for-react";
|
||||||
|
import TitleBox from "../Component/TitleBox";
|
||||||
|
import SwitchButton from "../Component/SwitchButton";
|
||||||
|
import ScrollBoard from "./../../Component/ScrollBoard";
|
||||||
|
import { useState } from "react";
|
||||||
|
import getOptions from "../../Component/BarChart/chart.config";
|
||||||
|
import {useAppSelector} from "./../../../store/hooks"
|
||||||
|
import {selectLine1Before} from "./../../../store/LinePageSlice"
|
||||||
|
function LeftDown() {
|
||||||
|
const data = useAppSelector(selectLine1Before);
|
||||||
|
// console.log('页面数据:',data)
|
||||||
|
const nameList = [
|
||||||
|
{ name: "表单", ename: "table" },
|
||||||
|
{ name: "柱状", ename: "chart" },
|
||||||
|
];
|
||||||
|
const [activeName, setActiveName] = useState<string>(nameList[0].ename);
|
||||||
|
const handleButtonChange = (activeName: string) => {
|
||||||
|
setActiveName(activeName);
|
||||||
|
};
|
||||||
|
const configDay = {
|
||||||
|
header: ["序号", "工序类型", "报废数量"],
|
||||||
|
headerHeight: 30,
|
||||||
|
rowNum: 4,
|
||||||
|
align: ["center", "left", "left"],
|
||||||
|
headerBGC: "rgba(79, 114, 136, 0.3)",
|
||||||
|
oddRowBGC: "rgba(79, 114, 136, 0.3)",
|
||||||
|
evenRowBGC: "rgba(76, 97, 123, 0.1)",
|
||||||
|
columnWidth: [73, 200, 107],
|
||||||
|
data: [
|
||||||
|
["1", "磨边后", 224],
|
||||||
|
["2", "包装1", 322],
|
||||||
|
["3", "包装2", 66],
|
||||||
|
],
|
||||||
|
};
|
||||||
|
const configWeek = {
|
||||||
|
header: ["序号", "工序类型", "报废数量"],
|
||||||
|
headerHeight: 30,
|
||||||
|
rowNum: 4,
|
||||||
|
align: ["center", "left", "left"],
|
||||||
|
headerBGC: "rgba(79, 114, 136, 0.3)",
|
||||||
|
oddRowBGC: "rgba(79, 114, 136, 0.3)",
|
||||||
|
evenRowBGC: "rgba(76, 97, 123, 0.1)",
|
||||||
|
columnWidth: [73, 200, 107],
|
||||||
|
data: [
|
||||||
|
["1", "磨边后", 1119],
|
||||||
|
["2", "包装1", 1798],
|
||||||
|
["3", "包装2", 435],
|
||||||
|
],
|
||||||
|
};
|
||||||
|
const configMonth = {
|
||||||
|
header: ["序号", "工序类型", "报废数量"],
|
||||||
|
headerHeight: 30,
|
||||||
|
rowNum: 4,
|
||||||
|
align: ["center", "left", "left"],
|
||||||
|
headerBGC: "rgba(79, 114, 136, 0.3)",
|
||||||
|
oddRowBGC: "rgba(79, 114, 136, 0.3)",
|
||||||
|
evenRowBGC: "rgba(76, 97, 123, 0.1)",
|
||||||
|
columnWidth: [73, 200, 107],
|
||||||
|
data: [
|
||||||
|
["1", "磨边后", 5004],
|
||||||
|
["2", "包装1", 9122],
|
||||||
|
["3", "包装2", 1924],
|
||||||
|
],
|
||||||
|
};
|
||||||
|
const color1 = ["#9DD5FF", "#1295FF"];
|
||||||
|
const color2 = ["#85F6E9", "#2EC6B4"];
|
||||||
|
// @ts-ignore
|
||||||
|
let xData1: string[] = [];
|
||||||
|
let xData2: string[] = [];
|
||||||
|
let xData3: string[] = [];
|
||||||
|
let dataProps1: number[] = [];
|
||||||
|
let dataProps2: number[] = [];
|
||||||
|
let dataProps3: number[] = [];
|
||||||
|
let arr1: any = [];
|
||||||
|
let arr2: any = [];
|
||||||
|
let arr3: any = [];
|
||||||
|
// @ts-ignore
|
||||||
|
if (data.todayProductionScraps && data.todayProductionScraps.length > 0) {
|
||||||
|
// @ts-ignore
|
||||||
|
data.todayProductionScraps.map((item,index)=>{
|
||||||
|
let arrInner = [];
|
||||||
|
arrInner.push(index+1,item.sectionName,item.scrapNum || 0);
|
||||||
|
arr1.push(arrInner);
|
||||||
|
xData1.push(item.sectionName);
|
||||||
|
dataProps1.push(item.scrapNum || 0);
|
||||||
|
})
|
||||||
|
}else{
|
||||||
|
dataProps1 = []
|
||||||
|
}
|
||||||
|
// @ts-ignore
|
||||||
|
if (data.weekProductionScraps && data.weekProductionScraps.length > 0) {
|
||||||
|
// @ts-ignore
|
||||||
|
data.weekProductionScraps.map((item,index)=>{
|
||||||
|
let arrInner = [];
|
||||||
|
arrInner.push(index+1,item.sectionName,item.scrapNum || 0);
|
||||||
|
arr2.push(arrInner);
|
||||||
|
xData2.push(item.sectionName);
|
||||||
|
dataProps2.push(item.scrapNum || 0);
|
||||||
|
})
|
||||||
|
}else{
|
||||||
|
dataProps2 = []
|
||||||
|
}
|
||||||
|
// @ts-ignore
|
||||||
|
if (data.monthProductionScraps && data.monthProductionScraps.length > 0) {
|
||||||
|
// @ts-ignore
|
||||||
|
data.monthProductionScraps.map((item,index)=>{
|
||||||
|
let arrInner = [];
|
||||||
|
arrInner.push(index+1,item.sectionName,item.scrapNum || 0);
|
||||||
|
arr3.push(arrInner);
|
||||||
|
xData3.push(item.sectionName);
|
||||||
|
dataProps3.push(item.scrapNum || 0);
|
||||||
|
})
|
||||||
|
}else{
|
||||||
|
dataProps3 = []
|
||||||
|
}
|
||||||
|
configDay.data = arr1;
|
||||||
|
configWeek.data = arr2;
|
||||||
|
configMonth.data = arr3;
|
||||||
|
const options1 = getOptions(dataProps1,xData1, color1);
|
||||||
|
const options2 = getOptions(dataProps2,xData2, color2);
|
||||||
|
const options3 = getOptions(dataProps3,xData3, color1);
|
||||||
|
return (
|
||||||
|
<div className="left_down">
|
||||||
|
<TitleBox title={"left_down"} />
|
||||||
|
<div className="left_up_switch">
|
||||||
|
<SwitchButton nameList={nameList} onChange={handleButtonChange} />
|
||||||
|
</div>
|
||||||
|
<div style={{ padding: "10px", height: "555px" }}>
|
||||||
|
<div className="left_down_title flex-row">
|
||||||
|
<div className="left_down_box1 flex-col" />
|
||||||
|
<span className="left_down_text">当天</span>
|
||||||
|
<div className="left_down_box2 flex-col" />
|
||||||
|
</div>
|
||||||
|
<div className="left_down_content">
|
||||||
|
{activeName === "table" ? (
|
||||||
|
arr1.length > 0 ? <ScrollBoard
|
||||||
|
config={configDay}
|
||||||
|
style={{ width: "380px", height: "150px" }}
|
||||||
|
/>:(<p
|
||||||
|
style={{
|
||||||
|
color: "#cccf",
|
||||||
|
fontSize: "24px",
|
||||||
|
userSelect: "none",
|
||||||
|
textAlign: "center",
|
||||||
|
paddingTop: "50px",
|
||||||
|
margin:0
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
暂无数据
|
||||||
|
</p>)
|
||||||
|
) : dataProps1.length>0 ? (
|
||||||
|
<ReactECharts option={options1} style={{ height: "100%" }} />
|
||||||
|
) : (
|
||||||
|
<p
|
||||||
|
style={{
|
||||||
|
color: "#cccf",
|
||||||
|
fontSize: "24px",
|
||||||
|
userSelect: "none",
|
||||||
|
textAlign: "center",
|
||||||
|
paddingTop: "50px",
|
||||||
|
margin:0
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
暂无数据
|
||||||
|
</p>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
<div className="left_down_title flex-row">
|
||||||
|
<div className="left_down_box1 flex-col" />
|
||||||
|
<span className="left_down_text">本周</span>
|
||||||
|
<div className="left_down_box2 flex-col" />
|
||||||
|
</div>
|
||||||
|
<div className="left_down_content">
|
||||||
|
{activeName === "table" ? (
|
||||||
|
arr2.length > 0 ? <ScrollBoard
|
||||||
|
config={configWeek}
|
||||||
|
style={{ width: "380px", height: "150px" }}
|
||||||
|
/>:(<p
|
||||||
|
style={{
|
||||||
|
color: "#cccf",
|
||||||
|
fontSize: "24px",
|
||||||
|
userSelect: "none",
|
||||||
|
textAlign: "center",
|
||||||
|
paddingTop: "50px",
|
||||||
|
margin:0
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
暂无数据
|
||||||
|
</p>)
|
||||||
|
) : dataProps2.length>0 ? (
|
||||||
|
<ReactECharts option={options2} style={{ height: "100%" }} />
|
||||||
|
) : (
|
||||||
|
<p
|
||||||
|
style={{
|
||||||
|
color: "#cccf",
|
||||||
|
fontSize: "24px",
|
||||||
|
userSelect: "none",
|
||||||
|
textAlign: "center",
|
||||||
|
paddingTop: "50px",
|
||||||
|
margin:0
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
暂无数据
|
||||||
|
</p>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
<div className="left_down_title flex-row">
|
||||||
|
<div className="left_down_box1 flex-col" />
|
||||||
|
<span className="left_down_text">本月</span>
|
||||||
|
<div className="left_down_box2 flex-col" />
|
||||||
|
</div>
|
||||||
|
<div className="left_down_content">
|
||||||
|
{activeName === "table" ? (
|
||||||
|
arr3.length > 0 ? <ScrollBoard
|
||||||
|
config={configMonth}
|
||||||
|
style={{ width: "380px", height: "150px" }}
|
||||||
|
/>:(<p
|
||||||
|
style={{
|
||||||
|
color: "#cccf",
|
||||||
|
fontSize: "24px",
|
||||||
|
userSelect: "none",
|
||||||
|
textAlign: "center",
|
||||||
|
paddingTop: "50px",
|
||||||
|
margin:0
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
暂无数据
|
||||||
|
</p>)
|
||||||
|
) : dataProps3.length>0 ? (
|
||||||
|
<ReactECharts option={options3} style={{ height: "100%" }} />
|
||||||
|
) : (
|
||||||
|
<p
|
||||||
|
style={{
|
||||||
|
color: "#cccf",
|
||||||
|
fontSize: "24px",
|
||||||
|
userSelect: "none",
|
||||||
|
textAlign: "center",
|
||||||
|
paddingTop: "50px",
|
||||||
|
margin:0
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
暂无数据
|
||||||
|
</p>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
export default LeftDown;
|
268
src/page/LinePage1-1/Left/LeftUp.tsx
Normal file
268
src/page/LinePage1-1/Left/LeftUp.tsx
Normal file
@ -0,0 +1,268 @@
|
|||||||
|
import ReactECharts from "echarts-for-react";
|
||||||
|
import TitleBox from "../Component/TitleBox";
|
||||||
|
import SwitchButton from "../Component/SwitchButton";
|
||||||
|
import getOptions from "../../Component/SummaryBarChart/chart.config";
|
||||||
|
import { useState } from "react";
|
||||||
|
import {useAppSelector} from "./../../../store/hooks"
|
||||||
|
import {selectLine1Before} from "./../../../store/LinePageSlice"
|
||||||
|
function LeftUp() {
|
||||||
|
const data = useAppSelector(selectLine1Before);
|
||||||
|
// 假数据
|
||||||
|
const dataSource = {
|
||||||
|
day: {
|
||||||
|
xData: [],
|
||||||
|
series: [] as { data: number[]; type: string; stack: string; name: any; barWidth?: number; label: { show: boolean; position: string; color: string;formatter?:any }; }[],
|
||||||
|
},
|
||||||
|
week: {
|
||||||
|
xData: [],
|
||||||
|
series: [] as { data: number[]; type: string; stack: string; name: any; barWidth?: number; label: { show: boolean; position: string; color: string;formatter?:any }; }[],
|
||||||
|
},
|
||||||
|
month: {
|
||||||
|
xData: [],
|
||||||
|
series: [] as { data: number[]; type: string; stack: string; name: any; barWidth?: number; label: { show: boolean; position: string; color: string;formatter?:any }; }[],
|
||||||
|
},
|
||||||
|
};
|
||||||
|
const nameList = [
|
||||||
|
{ name: "天", ename: "day" },
|
||||||
|
{ name: "周", ename: "week" },
|
||||||
|
{ name: "月", ename: "month" },
|
||||||
|
];
|
||||||
|
const [activeName, setActiveName] = useState<string>(nameList[0].ename);
|
||||||
|
let chartData = (dataSource as { [key: string]: any })[activeName];
|
||||||
|
const handleButtonChange = (activeName: string) => {
|
||||||
|
setActiveName(activeName);
|
||||||
|
};
|
||||||
|
// @ts-ignore
|
||||||
|
if (data.todayAllProductionScraps && Object.keys(data.todayAllProductionScraps).length > 0) {
|
||||||
|
let sum: number[] = [];
|
||||||
|
// 生成obj
|
||||||
|
// @ts-ignore
|
||||||
|
data.scrapBars.map((item,index) => {
|
||||||
|
let obj = {
|
||||||
|
data: [],
|
||||||
|
type: "bar",
|
||||||
|
stack: "a",
|
||||||
|
name: item,
|
||||||
|
barWidth: 14,
|
||||||
|
label: {
|
||||||
|
show: true,
|
||||||
|
position: "right",
|
||||||
|
color: "inherit",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
dataSource.day.series.push(obj)
|
||||||
|
})
|
||||||
|
// @ts-ignore
|
||||||
|
dataSource.day.xData = Object.keys(data.todayAllProductionScraps)
|
||||||
|
dataSource.day.xData.sort((a,b)=>{// 保证横坐标是有序的
|
||||||
|
// @ts-ignore
|
||||||
|
const lastDigitA = parseInt(a[a.length - 1], 10);
|
||||||
|
// @ts-ignore
|
||||||
|
const lastDigitB = parseInt(b[b.length - 1], 10);
|
||||||
|
return lastDigitA - lastDigitB;
|
||||||
|
})
|
||||||
|
for (let k = 0; k < dataSource.day.xData.length; k++) {
|
||||||
|
let item = dataSource.day.xData[k];
|
||||||
|
let sumIner = 0
|
||||||
|
for(let i = 0;i < dataSource.day.series.length;i++){
|
||||||
|
let itemSeries = dataSource.day.series[i]
|
||||||
|
// @ts-ignore
|
||||||
|
data.todayAllProductionScraps[item].map((itemInner,indexInner)=>{
|
||||||
|
// @ts-ignore
|
||||||
|
if (itemInner.sectionName.indexOf(itemSeries.name)!==-1) {
|
||||||
|
// @ts-ignore
|
||||||
|
itemSeries.data.push(itemInner.scrapNum || 0)
|
||||||
|
sumIner += itemInner.scrapNum || 0
|
||||||
|
return
|
||||||
|
}
|
||||||
|
})
|
||||||
|
if (itemSeries.data.length === k) {
|
||||||
|
itemSeries.data.push(0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
sum.push(sumIner)
|
||||||
|
}
|
||||||
|
dataSource.day.series.push({
|
||||||
|
data: sum,
|
||||||
|
type: "bar",
|
||||||
|
stack: "a",
|
||||||
|
name: "",
|
||||||
|
label: {
|
||||||
|
show: true,
|
||||||
|
position: "top",
|
||||||
|
color: "#fff",
|
||||||
|
formatter: function (params: any) {
|
||||||
|
return sum[params.dataIndex];
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}else{
|
||||||
|
dataSource.day.xData = []
|
||||||
|
dataSource.day.series = []
|
||||||
|
}
|
||||||
|
// @ts-ignore
|
||||||
|
if (data.weekAllProductionScraps && Object.keys(data.weekAllProductionScraps).length > 0) {
|
||||||
|
let sum: number[] = [];
|
||||||
|
// 生成obj
|
||||||
|
// @ts-ignore
|
||||||
|
data.scrapBars.map((item,index) => {
|
||||||
|
let obj = {
|
||||||
|
data: [],
|
||||||
|
type: "bar",
|
||||||
|
stack: "a",
|
||||||
|
name: item,
|
||||||
|
barWidth: 14,
|
||||||
|
label: {
|
||||||
|
show: true,
|
||||||
|
position: "right",
|
||||||
|
color: "inherit",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
dataSource.week.series.push(obj)
|
||||||
|
})
|
||||||
|
// @ts-ignore
|
||||||
|
dataSource.week.xData = Object.keys(data.weekAllProductionScraps)
|
||||||
|
dataSource.week.xData.sort((a,b)=>{// 保证横坐标是有序的
|
||||||
|
// @ts-ignore
|
||||||
|
const lastDigitA = parseInt(a[a.length - 1], 10);
|
||||||
|
// @ts-ignore
|
||||||
|
const lastDigitB = parseInt(b[b.length - 1], 10);
|
||||||
|
return lastDigitA - lastDigitB;
|
||||||
|
})
|
||||||
|
for (let k = 0; k < dataSource.week.xData.length; k++) {
|
||||||
|
let item = dataSource.week.xData[k];
|
||||||
|
let sumIner = 0
|
||||||
|
for(let i = 0;i < dataSource.week.series.length;i++){
|
||||||
|
let itemSeries = dataSource.week.series[i]
|
||||||
|
// @ts-ignore
|
||||||
|
data.weekAllProductionScraps[item].map((itemInner,indexInner)=>{
|
||||||
|
// @ts-ignore
|
||||||
|
if (itemInner.sectionName.indexOf(itemSeries.name)!==-1) {
|
||||||
|
// @ts-ignore
|
||||||
|
itemSeries.data.push(itemInner.scrapNum || 0)
|
||||||
|
sumIner += itemInner.scrapNum || 0
|
||||||
|
return
|
||||||
|
}
|
||||||
|
})
|
||||||
|
if (itemSeries.data.length === k) {
|
||||||
|
itemSeries.data.push(0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
sum.push(sumIner)
|
||||||
|
}
|
||||||
|
dataSource.week.series.push({
|
||||||
|
data: sum,
|
||||||
|
type: "bar",
|
||||||
|
stack: "a",
|
||||||
|
name: "",
|
||||||
|
label: {
|
||||||
|
show: true,
|
||||||
|
position: "top",
|
||||||
|
color: "#fff",
|
||||||
|
formatter: function (params: any) {
|
||||||
|
return sum[params.dataIndex];
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}else{
|
||||||
|
dataSource.week.xData = []
|
||||||
|
dataSource.week.series = []
|
||||||
|
}
|
||||||
|
// @ts-ignore
|
||||||
|
if (data.monthAllProductionScraps && Object.keys(data.monthAllProductionScraps).length > 0) {
|
||||||
|
let sum: number[] = [];
|
||||||
|
// 生成obj
|
||||||
|
// @ts-ignore
|
||||||
|
data.scrapBars.map((item,index) => {
|
||||||
|
let obj = {
|
||||||
|
data: [],
|
||||||
|
type: "bar",
|
||||||
|
stack: "a",
|
||||||
|
name: item,
|
||||||
|
barWidth: 14,
|
||||||
|
label: {
|
||||||
|
show: true,
|
||||||
|
position: "right",
|
||||||
|
color: "inherit",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
dataSource.month.series.push(obj)
|
||||||
|
})
|
||||||
|
// @ts-ignore
|
||||||
|
dataSource.month.xData = Object.keys(data.monthAllProductionScraps)
|
||||||
|
dataSource.month.xData.sort((a,b)=>{// 保证横坐标是有序的
|
||||||
|
// @ts-ignore
|
||||||
|
const lastDigitA = parseInt(a[a.length - 1], 10);
|
||||||
|
// @ts-ignore
|
||||||
|
const lastDigitB = parseInt(b[b.length - 1], 10);
|
||||||
|
return lastDigitA - lastDigitB;
|
||||||
|
})
|
||||||
|
for (let k = 0; k < dataSource.month.xData.length; k++) {
|
||||||
|
let item = dataSource.month.xData[k];
|
||||||
|
let sumIner = 0
|
||||||
|
for(let i = 0;i < dataSource.month.series.length;i++){
|
||||||
|
let itemSeries = dataSource.month.series[i]
|
||||||
|
// @ts-ignore
|
||||||
|
data.monthAllProductionScraps[item].map((itemInner,indexInner)=>{
|
||||||
|
// @ts-ignore
|
||||||
|
if (itemInner.sectionName.indexOf(itemSeries.name)!==-1) {
|
||||||
|
// @ts-ignore
|
||||||
|
itemSeries.data.push(itemInner.scrapNum || 0)
|
||||||
|
sumIner += itemInner.scrapNum || 0
|
||||||
|
return
|
||||||
|
}
|
||||||
|
})
|
||||||
|
if (itemSeries.data.length === k) {
|
||||||
|
itemSeries.data.push(0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
sum.push(sumIner)
|
||||||
|
}
|
||||||
|
dataSource.month.series.push({
|
||||||
|
data: sum,
|
||||||
|
type: "bar",
|
||||||
|
stack: "a",
|
||||||
|
name: "",
|
||||||
|
label: {
|
||||||
|
show: true,
|
||||||
|
position: "top",
|
||||||
|
color: "#fff",
|
||||||
|
formatter: function (params: any) {
|
||||||
|
return sum[params.dataIndex];
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}else{
|
||||||
|
dataSource.month.xData = []
|
||||||
|
dataSource.month.series = []
|
||||||
|
}
|
||||||
|
const options = getOptions(chartData);
|
||||||
|
console.log('dataSource',dataSource)
|
||||||
|
return (
|
||||||
|
<div className="left_up">
|
||||||
|
<TitleBox title={"left_up"} />
|
||||||
|
<div className="left_up_switch">
|
||||||
|
<SwitchButton nameList={nameList} onChange={handleButtonChange} />
|
||||||
|
</div>
|
||||||
|
{// @ts-ignore
|
||||||
|
dataSource[activeName].xData.length>0 ? (
|
||||||
|
<div className="left_up_chart">
|
||||||
|
{<ReactECharts option={options} style={{ height: "100%" }} />}
|
||||||
|
</div>
|
||||||
|
):(
|
||||||
|
<p
|
||||||
|
style={{
|
||||||
|
color: "#cccf",
|
||||||
|
fontSize: "24px",
|
||||||
|
userSelect: "none",
|
||||||
|
textAlign: "center",
|
||||||
|
paddingTop: "72px",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
暂无数据
|
||||||
|
</p>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
export default LeftUp;
|
@ -3,109 +3,37 @@ import TitleBox from "../Component/TitleBox";
|
|||||||
import SwitchButton from "../Component/SwitchButton";
|
import SwitchButton from "../Component/SwitchButton";
|
||||||
import ScrollBoard from "./../../Component/ScrollBoard";
|
import ScrollBoard from "./../../Component/ScrollBoard";
|
||||||
import { useState } from "react";
|
import { useState } from "react";
|
||||||
import getOptions from "./LineChart/chart.config";
|
import getOptions from "../../Component/LineChartRight/chart.config";
|
||||||
|
import {useAppSelector} from "./../../../store/hooks"
|
||||||
|
import {selectLine1Before} from "./../../../store/LinePageSlice"
|
||||||
|
import dayjs from "dayjs";
|
||||||
function RightDown() {
|
function RightDown() {
|
||||||
|
const data = useAppSelector(selectLine1Before);
|
||||||
|
// console.log('页面数据:',data)
|
||||||
// 假数据
|
// 假数据
|
||||||
let tempData = [
|
let tempData = [
|
||||||
{
|
{
|
||||||
type: "day",
|
type: "day",
|
||||||
data: {
|
data: {
|
||||||
time: [
|
time: [] as string[],
|
||||||
"0:00",
|
input: [] as number[],
|
||||||
"1:00",
|
output: [] as number[],
|
||||||
"2:00",
|
|
||||||
"3:00",
|
|
||||||
"4:00",
|
|
||||||
"5:00",
|
|
||||||
"6:00",
|
|
||||||
"7:00",
|
|
||||||
"8:00",
|
|
||||||
"9:00",
|
|
||||||
"10:00",
|
|
||||||
"11:00",
|
|
||||||
"12:00",
|
|
||||||
"13:00",
|
|
||||||
"14:00",
|
|
||||||
"15:00",
|
|
||||||
"16:00",
|
|
||||||
"17:00",
|
|
||||||
"18:00",
|
|
||||||
"19:00",
|
|
||||||
"20:00",
|
|
||||||
"21:00",
|
|
||||||
"22:00",
|
|
||||||
"23:00",
|
|
||||||
],
|
|
||||||
input: [
|
|
||||||
456, 425, 246, 424, 453, 466, 412, 434, 425, 418, 0, 0, 0, 0, 0, 0, 0,
|
|
||||||
0, 0, 0, 0, 0, 0, 0,
|
|
||||||
],
|
|
||||||
output: [
|
|
||||||
432, 401, 232, 398, 421, 439, 378, 411, 400, 394, 0, 0, 0, 0, 0, 0, 0,
|
|
||||||
0, 0, 0, 0, 0, 0, 0,
|
|
||||||
],
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
type: "week",
|
type: "week",
|
||||||
data: {
|
data: {
|
||||||
time: [
|
time: [] as string[],
|
||||||
"2024/8/22",
|
input: [] as number[],
|
||||||
"2024/8/23",
|
output: [] as number[],
|
||||||
"2024/8/24",
|
|
||||||
"2024/8/25",
|
|
||||||
"2024/8/26",
|
|
||||||
"2024/8/27",
|
|
||||||
"2024/8/28",
|
|
||||||
],
|
|
||||||
input: [9753, 10357, 11246, 10123, 9872, 9985, 10352],
|
|
||||||
output: [7925, 8216, 9091, 7847, 7589, 8126, 8112],
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
type: "month",
|
type: "month",
|
||||||
data: {
|
data: {
|
||||||
time: [
|
time: [] as string[],
|
||||||
"2024/8/1",
|
input: [] as number[],
|
||||||
"2024/8/2",
|
output: [] as number[],
|
||||||
"2024/8/3",
|
|
||||||
"2024/8/4",
|
|
||||||
"2024/8/5",
|
|
||||||
"2024/8/6",
|
|
||||||
"2024/8/7",
|
|
||||||
"2024/8/8",
|
|
||||||
"2024/8/9",
|
|
||||||
"2024/8/10",
|
|
||||||
"2024/8/11",
|
|
||||||
"2024/8/12",
|
|
||||||
"2024/8/13",
|
|
||||||
"2024/8/14",
|
|
||||||
"2024/8/15",
|
|
||||||
"2024/8/16",
|
|
||||||
"2024/8/17",
|
|
||||||
"2024/8/18",
|
|
||||||
"2024/8/19",
|
|
||||||
"2024/8/20",
|
|
||||||
"2024/8/21",
|
|
||||||
"2024/8/22",
|
|
||||||
"2024/8/23",
|
|
||||||
"2024/8/24",
|
|
||||||
"2024/8/25",
|
|
||||||
"2024/8/26",
|
|
||||||
"2024/8/27",
|
|
||||||
"2024/8/28",
|
|
||||||
"2024/8/29",
|
|
||||||
"2024/8/30",
|
|
||||||
"2024/8/31",
|
|
||||||
],
|
|
||||||
input: [
|
|
||||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9813, 9753,
|
|
||||||
10357, 11246, 10123, 9872, 9985, 10352, 4235, 0, 0, 0,
|
|
||||||
],
|
|
||||||
output: [
|
|
||||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7883, 7925,
|
|
||||||
8216, 9091, 7847, 7589, 8126, 8112, 3962, 0, 0, 0,
|
|
||||||
],
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
@ -117,28 +45,7 @@ function RightDown() {
|
|||||||
const handleButtonChange = (activeName: string) => {
|
const handleButtonChange = (activeName: string) => {
|
||||||
setActiveName(activeName);
|
setActiveName(activeName);
|
||||||
};
|
};
|
||||||
const config = {
|
const configDay = {
|
||||||
header: ["时间", "投入数量", "产出数量"],
|
|
||||||
headerHeight: 30,
|
|
||||||
rowNum: 5,
|
|
||||||
headerBGC: "rgba(79, 114, 136, 0.3)",
|
|
||||||
oddRowBGC: "rgba(79, 114, 136, 0.3)",
|
|
||||||
evenRowBGC: "rgba(76, 97, 123, 0.1)",
|
|
||||||
columnWidth: [120, 130, 130],
|
|
||||||
data: [
|
|
||||||
["行1列1", "行1列2", "行1列3"],
|
|
||||||
["行2列1", "行2列2", "行2列3"],
|
|
||||||
["行3列1", "行3列2", "行3列3"],
|
|
||||||
["行4列1", "行4列2", "行4列3"],
|
|
||||||
["行5列1", "行5列2", "行5列3"],
|
|
||||||
["行6列1", "行6列2", "行6列3"],
|
|
||||||
["行7列1", "行7列2", "行7列3"],
|
|
||||||
["行8列1", "行8列2", "行8列3"],
|
|
||||||
["行9列1", "行9列2", "行9列3"],
|
|
||||||
["行10列1", "行10列2", "行10列3"],
|
|
||||||
],
|
|
||||||
};
|
|
||||||
const config1 = {
|
|
||||||
header: ["时间", "投入数量", "产出数量"],
|
header: ["时间", "投入数量", "产出数量"],
|
||||||
headerHeight: 30,
|
headerHeight: 30,
|
||||||
rowNum: 5,
|
rowNum: 5,
|
||||||
@ -148,7 +55,7 @@ function RightDown() {
|
|||||||
columnWidth: [120, 130, 130],
|
columnWidth: [120, 130, 130],
|
||||||
data: [],
|
data: [],
|
||||||
};
|
};
|
||||||
const config2 = {
|
const configWeek = {
|
||||||
header: ["时间", "投入数量", "产出数量"],
|
header: ["时间", "投入数量", "产出数量"],
|
||||||
headerHeight: 30,
|
headerHeight: 30,
|
||||||
rowNum: 5,
|
rowNum: 5,
|
||||||
@ -158,7 +65,7 @@ function RightDown() {
|
|||||||
columnWidth: [120, 130, 130],
|
columnWidth: [120, 130, 130],
|
||||||
data: [],
|
data: [],
|
||||||
};
|
};
|
||||||
const config3 = {
|
const configMonth = {
|
||||||
header: ["时间", "投入数量", "产出数量"],
|
header: ["时间", "投入数量", "产出数量"],
|
||||||
headerHeight: 30,
|
headerHeight: 30,
|
||||||
rowNum: 5,
|
rowNum: 5,
|
||||||
@ -168,30 +75,60 @@ function RightDown() {
|
|||||||
columnWidth: [120, 130, 130],
|
columnWidth: [120, 130, 130],
|
||||||
data: [],
|
data: [],
|
||||||
};
|
};
|
||||||
let data1Lenght = tempData[0].data.input.length;
|
let arr1: any = [];
|
||||||
for (let i = 0; i < data1Lenght; i++) {
|
let arr2: any = [];
|
||||||
(config1.data as any).push([
|
let arr3: any = [];
|
||||||
tempData[0].data.time ? tempData[0].data.time[i] : "-",
|
// @ts-ignore
|
||||||
tempData[0].data.input ? tempData[0].data.input[i] : "-",
|
if (data.todayProductionDets && data.todayProductionDets.length > 0) {
|
||||||
tempData[0].data.output ? tempData[0].data.output[i] : "-",
|
// @ts-ignore
|
||||||
]);
|
data.todayProductionDets.map((item,index)=>{
|
||||||
|
let arrInner = [];
|
||||||
|
arrInner.push(dayjs(item.recTime).format("HH:mm"),item.inputNum,item.outputNum);
|
||||||
|
arr1.push(arrInner);
|
||||||
|
tempData[0].data.time.push(dayjs(item.recTime).format("HH:mm"));
|
||||||
|
tempData[0].data.input.push(item.inputNum);
|
||||||
|
tempData[0].data.output.push(item.outputNum);
|
||||||
|
})
|
||||||
|
}else{
|
||||||
|
tempData[0].data.time = []
|
||||||
|
tempData[0].data.input = []
|
||||||
|
tempData[0].data.output = []
|
||||||
}
|
}
|
||||||
let data2Lenght = tempData[1].data.input.length;
|
// @ts-ignore
|
||||||
for (let i = 0; i < data2Lenght; i++) {
|
if (data.weekProductionDets && data.weekProductionDets.length > 0) {
|
||||||
(config2.data as any).push([
|
// @ts-ignore
|
||||||
tempData[1].data.time ? tempData[1].data.time[i] : "-",
|
data.weekProductionDets.map((item,index)=>{
|
||||||
tempData[1].data.input ? tempData[1].data.input[i] : "-",
|
let arrInner = [];
|
||||||
tempData[1].data.output ? tempData[1].data.output[i] : "-",
|
arrInner.push(dayjs(item.recTime).format("YYYY/MM/DD"),item.inputNum,item.outputNum);
|
||||||
]);
|
arr2.push(arrInner);
|
||||||
|
tempData[1].data.time.push(dayjs(item.recTime).format("MM.DD"));
|
||||||
|
tempData[1].data.input.push(item.inputNum);
|
||||||
|
tempData[1].data.output.push(item.outputNum);
|
||||||
|
})
|
||||||
|
}else{
|
||||||
|
tempData[1].data.time = []
|
||||||
|
tempData[1].data.input = []
|
||||||
|
tempData[1].data.output = []
|
||||||
}
|
}
|
||||||
let data3Lenght = tempData[0].data.input.length;
|
// @ts-ignore
|
||||||
for (let i = 0; i < data3Lenght; i++) {
|
if (data.monthProductionDets && data.monthProductionDets.length > 0) {
|
||||||
(config3.data as any).push([
|
// @ts-ignore
|
||||||
tempData[2].data.time ? tempData[2].data.time[i] : "-",
|
data.monthProductionDets.map((item,index)=>{
|
||||||
tempData[2].data.input ? tempData[2].data.input[i] : "-",
|
let arrInner = [];
|
||||||
tempData[2].data.output ? tempData[2].data.output[i] : "-",
|
arrInner.push(dayjs(item.recTime).format("YYYY/MM/DD"),item.inputNum,item.outputNum);
|
||||||
]);
|
arr3.push(arrInner);
|
||||||
|
tempData[2].data.time.push(dayjs(item.recTime).format("MM.DD"));
|
||||||
|
tempData[2].data.input.push(item.inputNum);
|
||||||
|
tempData[2].data.output.push(item.outputNum);
|
||||||
|
})
|
||||||
|
}else{
|
||||||
|
tempData[2].data.time = []
|
||||||
|
tempData[2].data.input = []
|
||||||
|
tempData[2].data.output = []
|
||||||
}
|
}
|
||||||
|
configDay.data = arr1;
|
||||||
|
configWeek.data = arr2;
|
||||||
|
configMonth.data = arr3;
|
||||||
|
|
||||||
const chartData1 = tempData[0].data;
|
const chartData1 = tempData[0].data;
|
||||||
const chartData2 = tempData[1].data;
|
const chartData2 = tempData[1].data;
|
||||||
@ -213,11 +150,24 @@ function RightDown() {
|
|||||||
</div>
|
</div>
|
||||||
<div className="right_down_content">
|
<div className="right_down_content">
|
||||||
{activeName === "table" ? (
|
{activeName === "table" ? (
|
||||||
<ScrollBoard
|
arr1.length>0?<ScrollBoard
|
||||||
config={config1}
|
config={configDay}
|
||||||
style={{ width: "380px", height: "180px" }}
|
style={{ width: "380px", height: "180px" }}
|
||||||
/>
|
/>:(
|
||||||
) : options1 ? (
|
<p
|
||||||
|
style={{
|
||||||
|
color: "#cccf",
|
||||||
|
fontSize: "24px",
|
||||||
|
userSelect: "none",
|
||||||
|
textAlign: "center",
|
||||||
|
paddingTop: "50px",
|
||||||
|
margin:0
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
暂无数据
|
||||||
|
</p>
|
||||||
|
)
|
||||||
|
) : tempData[0].data.time.length>0 ? (
|
||||||
<ReactECharts option={options1} style={{ height: "100%" }} />
|
<ReactECharts option={options1} style={{ height: "100%" }} />
|
||||||
) : (
|
) : (
|
||||||
<p
|
<p
|
||||||
@ -226,7 +176,8 @@ function RightDown() {
|
|||||||
fontSize: "24px",
|
fontSize: "24px",
|
||||||
userSelect: "none",
|
userSelect: "none",
|
||||||
textAlign: "center",
|
textAlign: "center",
|
||||||
paddingTop: "72px",
|
paddingTop: "50px",
|
||||||
|
margin:0
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
暂无数据
|
暂无数据
|
||||||
@ -240,11 +191,24 @@ function RightDown() {
|
|||||||
</div>
|
</div>
|
||||||
<div className="right_down_content">
|
<div className="right_down_content">
|
||||||
{activeName === "table" ? (
|
{activeName === "table" ? (
|
||||||
<ScrollBoard
|
arr2.length>0?<ScrollBoard
|
||||||
config={config2}
|
config={configWeek}
|
||||||
style={{ width: "380px", height: "180px" }}
|
style={{ width: "380px", height: "180px" }}
|
||||||
/>
|
/>:(
|
||||||
) : options2 ? (
|
<p
|
||||||
|
style={{
|
||||||
|
color: "#cccf",
|
||||||
|
fontSize: "24px",
|
||||||
|
userSelect: "none",
|
||||||
|
textAlign: "center",
|
||||||
|
paddingTop: "50px",
|
||||||
|
margin:0
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
暂无数据
|
||||||
|
</p>
|
||||||
|
)
|
||||||
|
) : tempData[1].data.time.length>0 ? (
|
||||||
<ReactECharts option={options2} style={{ height: "100%" }} />
|
<ReactECharts option={options2} style={{ height: "100%" }} />
|
||||||
) : (
|
) : (
|
||||||
<p
|
<p
|
||||||
@ -253,7 +217,8 @@ function RightDown() {
|
|||||||
fontSize: "24px",
|
fontSize: "24px",
|
||||||
userSelect: "none",
|
userSelect: "none",
|
||||||
textAlign: "center",
|
textAlign: "center",
|
||||||
paddingTop: "72px",
|
paddingTop: "50px",
|
||||||
|
margin:0
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
暂无数据
|
暂无数据
|
||||||
@ -267,11 +232,24 @@ function RightDown() {
|
|||||||
</div>
|
</div>
|
||||||
<div className="right_down_content">
|
<div className="right_down_content">
|
||||||
{activeName === "table" ? (
|
{activeName === "table" ? (
|
||||||
<ScrollBoard
|
arr3.length>0?<ScrollBoard
|
||||||
config={config3}
|
config={configMonth}
|
||||||
style={{ width: "380px", height: "180px" }}
|
style={{ width: "380px", height: "180px" }}
|
||||||
/>
|
/>:(
|
||||||
) : options3 ? (
|
<p
|
||||||
|
style={{
|
||||||
|
color: "#cccf",
|
||||||
|
fontSize: "24px",
|
||||||
|
userSelect: "none",
|
||||||
|
textAlign: "center",
|
||||||
|
paddingTop: "50px",
|
||||||
|
margin:0
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
暂无数据
|
||||||
|
</p>
|
||||||
|
)
|
||||||
|
) : tempData[2].data.time.length>0 ? (
|
||||||
<ReactECharts option={options3} style={{ height: "100%" }} />
|
<ReactECharts option={options3} style={{ height: "100%" }} />
|
||||||
) : (
|
) : (
|
||||||
<p
|
<p
|
||||||
@ -280,7 +258,8 @@ function RightDown() {
|
|||||||
fontSize: "24px",
|
fontSize: "24px",
|
||||||
userSelect: "none",
|
userSelect: "none",
|
||||||
textAlign: "center",
|
textAlign: "center",
|
||||||
paddingTop: "72px",
|
paddingTop: "50px",
|
||||||
|
margin:0
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
暂无数据
|
暂无数据
|
52
src/page/LinePage1-1/Right/RightUp.tsx
Normal file
52
src/page/LinePage1-1/Right/RightUp.tsx
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
import TitleBox from "../Component/TitleBox";
|
||||||
|
import ScrollBoard from "./../../Component/ScrollBoard";
|
||||||
|
import {useAppSelector} from "./../../../store/hooks"
|
||||||
|
import {selectLine1Before} from "./../../../store/LinePageSlice"
|
||||||
|
function RightUp() {
|
||||||
|
const data = useAppSelector(selectLine1Before);
|
||||||
|
const config = {
|
||||||
|
header: ["序号", "工段名", "上片数据量", "成品下片数量"],
|
||||||
|
headerHeight: 32,
|
||||||
|
rowNum: 5,
|
||||||
|
align: ["center", "left", "left", "left"],
|
||||||
|
headerBGC: "rgba(79, 114, 136, 0.3)",
|
||||||
|
oddRowBGC: "rgba(79, 114, 136, 0.3)",
|
||||||
|
evenRowBGC: "rgba(76, 97, 123, 0.1)",
|
||||||
|
columnWidth: [55, 115, 100, 110],
|
||||||
|
data: [],
|
||||||
|
};
|
||||||
|
let arr:any = []
|
||||||
|
// @ts-ignore
|
||||||
|
if (data.sectionDet && data.sectionDet.length > 0) {
|
||||||
|
// @ts-ignore
|
||||||
|
data.sectionDet.map((item, index) => {
|
||||||
|
let arrInner = []
|
||||||
|
arrInner.push(index + 1, item.lineName, item.inputNum, item.outputNum)
|
||||||
|
arr.push(arrInner)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
config.data = arr
|
||||||
|
return (
|
||||||
|
<div className="right_up">
|
||||||
|
<TitleBox title={"right_up"} />
|
||||||
|
<div style={{ padding: "10px", height: "213px" }}>
|
||||||
|
{arr.length>0?<ScrollBoard
|
||||||
|
config={config}
|
||||||
|
style={{ width: "380px", height: "193px" }}
|
||||||
|
/>:(<p
|
||||||
|
style={{
|
||||||
|
color: "#cccf",
|
||||||
|
fontSize: "24px",
|
||||||
|
userSelect: "none",
|
||||||
|
textAlign: "center",
|
||||||
|
paddingTop: "50px",
|
||||||
|
margin:0
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
暂无数据
|
||||||
|
</p>)}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
export default RightUp;
|
@ -100,7 +100,7 @@
|
|||||||
.center_down .right_box .chart_box {
|
.center_down .right_box .chart_box {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 310px;
|
height: 310px;
|
||||||
margin-top: 10px;
|
margin-top: 5px;
|
||||||
}
|
}
|
||||||
.right_up {
|
.right_up {
|
||||||
width: 401px;
|
width: 401px;
|
||||||
@ -230,7 +230,7 @@
|
|||||||
right: 0px;
|
right: 0px;
|
||||||
bottom: 0px;
|
bottom: 0px;
|
||||||
z-index: 1002;
|
z-index: 1002;
|
||||||
width: 240px;
|
width: 270px;
|
||||||
height: 110px;
|
height: 110px;
|
||||||
background: url(/public/png/lp/eq_msg_detail.png) 100% no-repeat;
|
background: url(/public/png/lp/eq_msg_detail.png) 100% no-repeat;
|
||||||
background-size: 100% 100%;
|
background-size: 100% 100%;
|
38
src/page/LinePage1-1/index.tsx
Normal file
38
src/page/LinePage1-1/index.tsx
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
import React from "react";
|
||||||
|
import TopP from "./TopP";
|
||||||
|
import Left from "./Left";
|
||||||
|
import Right from "./Right";
|
||||||
|
import Center from "./Center";
|
||||||
|
import {useEffect} from 'react';
|
||||||
|
import {useNavigate} from "react-router-dom";
|
||||||
|
function LinePage() {
|
||||||
|
const navigate = useNavigate();
|
||||||
|
useEffect(() => {
|
||||||
|
const handleKeyDown = (event:any) => {
|
||||||
|
if (event.key === 'ArrowUp') {
|
||||||
|
console.log('LDPage向上键被按下');
|
||||||
|
navigate('/LD?lineId=1-1');
|
||||||
|
// 执行向上键的逻辑
|
||||||
|
} else if (event.key === 'ArrowDown') {
|
||||||
|
console.log('LDPage向下键被按下');
|
||||||
|
// 执行向下键的逻辑
|
||||||
|
navigate('/LD?lineId=1-1');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
window.addEventListener('keydown', handleKeyDown);
|
||||||
|
return () => {
|
||||||
|
window.removeEventListener('keydown', handleKeyDown);
|
||||||
|
};
|
||||||
|
});
|
||||||
|
return (
|
||||||
|
<React.Fragment>
|
||||||
|
<TopP />
|
||||||
|
<div className="block_bottom flex-row">
|
||||||
|
<Left />
|
||||||
|
<Center />
|
||||||
|
<Right />
|
||||||
|
</div>
|
||||||
|
</React.Fragment>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
export default LinePage;
|
213
src/page/LinePage1-2/Center/CenterDown.tsx
Normal file
213
src/page/LinePage1-2/Center/CenterDown.tsx
Normal file
@ -0,0 +1,213 @@
|
|||||||
|
import ReactECharts from "echarts-for-react";
|
||||||
|
import TitleBox from "../Component/TitleBox";
|
||||||
|
import ScrollBoard from "./../../Component/ScrollBoard";
|
||||||
|
// import SwitchButton from "../Component/SwitchButton";
|
||||||
|
import { useState } from "react";
|
||||||
|
import getOptions from "../../Component/LineChart/chart.config";
|
||||||
|
import {useAppSelector} from "./../../../store/hooks"
|
||||||
|
import {selectLine1After} from "./../../../store/LinePageSlice"
|
||||||
|
import dayjs from "dayjs";
|
||||||
|
function CenterDown() {
|
||||||
|
const data = useAppSelector(selectLine1After);
|
||||||
|
// 假数据
|
||||||
|
const dataSource = {
|
||||||
|
day: {
|
||||||
|
xData:[],
|
||||||
|
series: [] as { name: string; type: string; symbol: string; symbolSize: number; data: never[]; }[],
|
||||||
|
},
|
||||||
|
week: {
|
||||||
|
xData:[],
|
||||||
|
series: [] as { name: string; type: string; symbol: string; symbolSize: number; data: never[]; }[],
|
||||||
|
},
|
||||||
|
month: {
|
||||||
|
xData:[],
|
||||||
|
series: [] as { name: string; type: string; symbol: string; symbolSize: number; data: never[]; }[],
|
||||||
|
},
|
||||||
|
};
|
||||||
|
const nameList = [
|
||||||
|
{ name: "天", ename: "day" },
|
||||||
|
{ name: "周", ename: "week" },
|
||||||
|
{ name: "月", ename: "month" },
|
||||||
|
];
|
||||||
|
const [activeName, setActiveName] = useState<string>(nameList[1].ename);
|
||||||
|
// const handleButtonChange = (activeName: string) => {
|
||||||
|
// setActiveName(activeName);
|
||||||
|
// };
|
||||||
|
const config = {
|
||||||
|
header: ["序号", "报警时间", "报警设备", "报警内容"],
|
||||||
|
headerHeight: 36,
|
||||||
|
rowNum: 6,
|
||||||
|
align: ["center", "left", "left", "left"],
|
||||||
|
headerBGC: "rgba(79, 114, 136, 0.3)",
|
||||||
|
oddRowBGC: "rgba(79, 114, 136, 0.3)",
|
||||||
|
evenRowBGC: "rgba(76, 97, 123, 0.1)",
|
||||||
|
columnWidth: [80, 137, 177, 97],
|
||||||
|
data: []
|
||||||
|
};
|
||||||
|
// 报警数据
|
||||||
|
let arr:any = []
|
||||||
|
let sumAlarm = 0
|
||||||
|
// @ts-ignore
|
||||||
|
if (data.alarms && data.alarms.length > 0) {
|
||||||
|
// @ts-ignore
|
||||||
|
sumAlarm = data.alarms.length
|
||||||
|
// @ts-ignore
|
||||||
|
data.alarms.map((item,index) => {
|
||||||
|
let arrInner = []
|
||||||
|
arrInner.push(
|
||||||
|
index+1,
|
||||||
|
dayjs(item.recTime).format("YYYY/MM/DD HH:mm"),
|
||||||
|
item.name,
|
||||||
|
item.status === '故障'?"<span style='color:#FF1E1E'>故障</span>":"<span style='color:#FFB40F'>离线</span>",
|
||||||
|
);
|
||||||
|
arr.push(arrInner)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
config.data = arr
|
||||||
|
// 工段成品率
|
||||||
|
// @ts-ignore
|
||||||
|
if (data.todayProductionRates && Object.keys(data.todayProductionRates).length > 0) {
|
||||||
|
// @ts-ignore
|
||||||
|
let keys = Object.keys(data.todayProductionRates)
|
||||||
|
// @ts-ignore
|
||||||
|
data.todayProductionRates[keys[0]].map((item,index)=>{
|
||||||
|
// @ts-ignore
|
||||||
|
dataSource.day.xData.push(dayjs(item.recTime).format("HH:mm"))
|
||||||
|
})
|
||||||
|
keys.map((item,index)=>{
|
||||||
|
let obj = {
|
||||||
|
name: "",
|
||||||
|
type: "line",
|
||||||
|
symbol: "circle",
|
||||||
|
symbolSize: 4,
|
||||||
|
data:[]
|
||||||
|
}
|
||||||
|
// @ts-ignore
|
||||||
|
obj.name = data.todayProductionRates[item][0].lineName
|
||||||
|
// @ts-ignore
|
||||||
|
data.todayProductionRates[item].map((subItem,index)=>{
|
||||||
|
// @ts-ignore
|
||||||
|
obj.data.push(subItem.passRate)
|
||||||
|
})
|
||||||
|
dataSource.day.series.push(obj)
|
||||||
|
})
|
||||||
|
}else{
|
||||||
|
dataSource.day.xData = []
|
||||||
|
dataSource.day.series = []
|
||||||
|
}
|
||||||
|
// @ts-ignore
|
||||||
|
if (data.weekProductionRates && Object.keys(data.weekProductionRates).length > 0) {
|
||||||
|
// @ts-ignore
|
||||||
|
let keys = Object.keys(data.weekProductionRates)
|
||||||
|
// @ts-ignore
|
||||||
|
data.weekProductionRates[keys[0]].map((item,index)=>{
|
||||||
|
// @ts-ignore
|
||||||
|
dataSource.week.xData.push(dayjs(item.recTime).format("HH:mm"))
|
||||||
|
})
|
||||||
|
keys.map((item,index)=>{
|
||||||
|
let obj = {
|
||||||
|
name: "",
|
||||||
|
type: "line",
|
||||||
|
symbol: "circle",
|
||||||
|
symbolSize: 4,
|
||||||
|
data:[]
|
||||||
|
}
|
||||||
|
// @ts-ignore
|
||||||
|
obj.name = data.weekProductionRates[item][0].lineName
|
||||||
|
// @ts-ignore
|
||||||
|
data.weekProductionRates[item].map((subItem,index)=>{
|
||||||
|
// @ts-ignore
|
||||||
|
obj.data.push(subItem.passRate)
|
||||||
|
})
|
||||||
|
dataSource.week.series.push(obj)
|
||||||
|
})
|
||||||
|
}else{
|
||||||
|
dataSource.week.xData = []
|
||||||
|
dataSource.week.series = []
|
||||||
|
}
|
||||||
|
// @ts-ignore
|
||||||
|
if (data.monthProductionRates && Object.keys(data.monthProductionRates).length > 0) {
|
||||||
|
// @ts-ignore
|
||||||
|
let keys = Object.keys(data.monthProductionRates)
|
||||||
|
// @ts-ignore
|
||||||
|
data.monthProductionRates[keys[0]].map((item,index)=>{
|
||||||
|
// @ts-ignore
|
||||||
|
dataSource.month.xData.push(dayjs(item.recTime).format("HH:mm"))
|
||||||
|
})
|
||||||
|
keys.map((item,index)=>{
|
||||||
|
let obj = {
|
||||||
|
name: "",
|
||||||
|
type: "line",
|
||||||
|
symbol: "circle",
|
||||||
|
symbolSize: 4,
|
||||||
|
data:[]
|
||||||
|
}
|
||||||
|
// @ts-ignore
|
||||||
|
obj.name = data.monthProductionRates[item][0].lineName
|
||||||
|
// @ts-ignore
|
||||||
|
data.monthProductionRates[item].map((subItem,index)=>{
|
||||||
|
// @ts-ignore
|
||||||
|
obj.data.push(subItem.passRate)
|
||||||
|
})
|
||||||
|
dataSource.month.series.push(obj)
|
||||||
|
})
|
||||||
|
}else{
|
||||||
|
dataSource.month.xData = []
|
||||||
|
dataSource.month.series = []
|
||||||
|
}
|
||||||
|
let chartData = (dataSource as { [key: string]: any })[activeName];
|
||||||
|
const options = getOptions(chartData);
|
||||||
|
return (
|
||||||
|
<div className="center_down flex-row">
|
||||||
|
<div className="center_down_inner flex-col left-box">
|
||||||
|
<TitleBox title={"center_down_left"} />
|
||||||
|
<span className="alarm_num_title">— 报警总数 —</span>
|
||||||
|
<div className="alarm_num">{sumAlarm}</div>
|
||||||
|
<div style={{ padding: 10, height: "270px" }}>
|
||||||
|
{arr.length>0?<ScrollBoard
|
||||||
|
config={config}
|
||||||
|
style={{ width: "492px", height: "250px" }}
|
||||||
|
/>:(<p
|
||||||
|
style={{
|
||||||
|
color: "#cccf",
|
||||||
|
fontSize: "24px",
|
||||||
|
userSelect: "none",
|
||||||
|
textAlign: "center",
|
||||||
|
paddingTop: "50px",
|
||||||
|
margin:0
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
暂无数据
|
||||||
|
</p>)}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{/* 工段成品率 */}
|
||||||
|
<div className="center_down_inner flex-col right_box">
|
||||||
|
<TitleBox title={"center_down_right"} />
|
||||||
|
{/* <div className="left_up_switch">
|
||||||
|
<SwitchButton nameList={nameList} onChange={handleButtonChange} />
|
||||||
|
</div> */}
|
||||||
|
{chartData.xData.length>0 && (
|
||||||
|
<div className="chart_box">
|
||||||
|
{<ReactECharts option={options} style={{ height: "100%" }} />}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
{chartData.xData.length==0 && (
|
||||||
|
<p
|
||||||
|
style={{
|
||||||
|
color: "#cccf",
|
||||||
|
fontSize: "24px",
|
||||||
|
userSelect: "none",
|
||||||
|
textAlign: "center",
|
||||||
|
paddingTop: "120px",
|
||||||
|
margin:0
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
暂无数据
|
||||||
|
</p>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
export default CenterDown;
|
10
src/page/LinePage1-2/Center/CenterUp.tsx
Normal file
10
src/page/LinePage1-2/Center/CenterUp.tsx
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
import LinePageBabylon from "../../../babylonjs/LinePageBabylonNew";
|
||||||
|
function CenterUp() {
|
||||||
|
const lineID = "1-2";
|
||||||
|
return (
|
||||||
|
<div className="center_up">
|
||||||
|
<LinePageBabylon modelPath={`Line${lineID}`} />
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
export default CenterUp;
|
12
src/page/LinePage1-2/Center/index.tsx
Normal file
12
src/page/LinePage1-2/Center/index.tsx
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
import CenterDown from "./CenterDown";
|
||||||
|
import CenterUp from "./CenterUp";
|
||||||
|
|
||||||
|
function Center() {
|
||||||
|
return (
|
||||||
|
<div className="group_center flex-col">
|
||||||
|
<CenterUp />
|
||||||
|
<CenterDown />
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
export default Center;
|
19
src/page/LinePage1-2/Component/SwitchButton/index.css
Normal file
19
src/page/LinePage1-2/Component/SwitchButton/index.css
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
.switch-button {
|
||||||
|
height: 33px;
|
||||||
|
}
|
||||||
|
.switch-button button {
|
||||||
|
color: #fff;
|
||||||
|
font-size: 18px;
|
||||||
|
padding: 4px 10px;
|
||||||
|
background-color: rgba(49, 135, 140, 0.3);
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
.switch-button button:first-child {
|
||||||
|
border-radius: 5px 0 0 5px;
|
||||||
|
}
|
||||||
|
.switch-button button:last-child {
|
||||||
|
border-radius: 0 5px 5px 0;
|
||||||
|
}
|
||||||
|
.switch-button button.active {
|
||||||
|
background-color: rgba(86, 244, 231, 0.7);
|
||||||
|
}
|
65
src/page/LinePage1-2/Component/SwitchButton/index.tsx
Normal file
65
src/page/LinePage1-2/Component/SwitchButton/index.tsx
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
import { useEffect, useState } from "react";
|
||||||
|
import "./index.css";
|
||||||
|
interface Name {
|
||||||
|
name: string;
|
||||||
|
ename: string;
|
||||||
|
}
|
||||||
|
interface nameListProps {
|
||||||
|
nameList: Name[];
|
||||||
|
onChange: (value: string) => void;
|
||||||
|
}
|
||||||
|
function createActiveNameUpdater(nameList: any, activeName: string) {
|
||||||
|
let activeIndex = nameList.findIndex((obj: any) => obj.name === activeName);
|
||||||
|
|
||||||
|
return function updateActiveName() {
|
||||||
|
activeIndex = (activeIndex + 1) % nameList.length;
|
||||||
|
return nameList[activeIndex].ename;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
function SwitchButton(props: nameListProps) {
|
||||||
|
const [activeName, setActiveName] = useState(props.nameList[0].ename);
|
||||||
|
const [timerId, setTimerId] = useState<any>(null);
|
||||||
|
let updateActiveName = createActiveNameUpdater(props.nameList, activeName);
|
||||||
|
useEffect(() => {
|
||||||
|
const timer = setInterval(() => {
|
||||||
|
let active = updateActiveName();
|
||||||
|
setActiveName(active);
|
||||||
|
props.onChange(active);
|
||||||
|
}, 60000);
|
||||||
|
setTimerId(timer);
|
||||||
|
return () => {
|
||||||
|
if (timerId !== null) {
|
||||||
|
clearInterval(timerId);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}, [props.nameList.length]);
|
||||||
|
const btnClick = (ename: string) => {
|
||||||
|
if (timerId !== null) {
|
||||||
|
clearInterval(timerId);
|
||||||
|
}
|
||||||
|
setActiveName(ename);
|
||||||
|
props.onChange(ename); // 通知父组件
|
||||||
|
const newTimer = setInterval(() => {
|
||||||
|
let active = updateActiveName();
|
||||||
|
setActiveName(active);
|
||||||
|
props.onChange(active);
|
||||||
|
}, 60000);
|
||||||
|
setTimerId(newTimer);
|
||||||
|
};
|
||||||
|
return (
|
||||||
|
<div className="switch-button">
|
||||||
|
{props.nameList.map((item, index) => {
|
||||||
|
return (
|
||||||
|
<button
|
||||||
|
key={item.ename}
|
||||||
|
className={activeName === item.ename ? "active" : ""}
|
||||||
|
onClick={() => btnClick(item.ename)}
|
||||||
|
>
|
||||||
|
{item.name}
|
||||||
|
</button>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
export default SwitchButton;
|
13
src/page/LinePage1-2/Component/TitleBox/index.css
Normal file
13
src/page/LinePage1-2/Component/TitleBox/index.css
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
.title_box {
|
||||||
|
font-size: 24px;
|
||||||
|
color: #52fff1;
|
||||||
|
padding: 10px 0 0 15px;
|
||||||
|
}
|
||||||
|
.title_box img {
|
||||||
|
width: 33px;
|
||||||
|
height: 33px;
|
||||||
|
vertical-align: bottom;
|
||||||
|
margin-right: 3px;
|
||||||
|
position: relative;
|
||||||
|
top: 3px;
|
||||||
|
}
|
53
src/page/LinePage1-2/Component/TitleBox/index.tsx
Normal file
53
src/page/LinePage1-2/Component/TitleBox/index.tsx
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
import Defect from "./../../../assets/icon/defect.png";
|
||||||
|
import Alarm from "./../../../assets/icon/alarm.png";
|
||||||
|
import Finished from "./../../../assets/icon/finished.png";
|
||||||
|
import InputAndOutput from "./../../../assets/icon/inputAndOutput.png";
|
||||||
|
import Num from "./../../../assets/icon/num.png";
|
||||||
|
import Record from "./../../../assets/icon/record.png";
|
||||||
|
import "./index.css";
|
||||||
|
interface titleProps {
|
||||||
|
title: string;
|
||||||
|
}
|
||||||
|
function TitleBox(props: titleProps) {
|
||||||
|
const filteredTitles = () => {
|
||||||
|
switch (props.title) {
|
||||||
|
case "left_up":
|
||||||
|
return {
|
||||||
|
img: Defect,
|
||||||
|
title: "工段报废汇总",
|
||||||
|
};
|
||||||
|
case "left_down":
|
||||||
|
return {
|
||||||
|
img: Record,
|
||||||
|
title: "工序报废情况",
|
||||||
|
};
|
||||||
|
case "center_down_left":
|
||||||
|
return {
|
||||||
|
img: Alarm,
|
||||||
|
title: "异常报警",
|
||||||
|
};
|
||||||
|
case "center_down_right":
|
||||||
|
return {
|
||||||
|
img: Finished,
|
||||||
|
title: "工段成品率",
|
||||||
|
};
|
||||||
|
case "right_up":
|
||||||
|
return {
|
||||||
|
img: Num,
|
||||||
|
title: "各工段总投入和产出",
|
||||||
|
};
|
||||||
|
default:
|
||||||
|
return {
|
||||||
|
img: InputAndOutput,
|
||||||
|
title: "当前产线投入和产出",
|
||||||
|
};
|
||||||
|
}
|
||||||
|
};
|
||||||
|
return (
|
||||||
|
<div className="title_box">
|
||||||
|
<img src={filteredTitles().img} alt="title" />
|
||||||
|
<span>{filteredTitles().title}</span>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
export default TitleBox;
|
@ -3,8 +3,12 @@ import TitleBox from "../Component/TitleBox";
|
|||||||
import SwitchButton from "../Component/SwitchButton";
|
import SwitchButton from "../Component/SwitchButton";
|
||||||
import ScrollBoard from "./../../Component/ScrollBoard";
|
import ScrollBoard from "./../../Component/ScrollBoard";
|
||||||
import { useState } from "react";
|
import { useState } from "react";
|
||||||
import getOptions from "./BarChart/chart.config";
|
import getOptions from "../../Component/BarChart/chart.config";
|
||||||
|
import {useAppSelector} from "./../../../store/hooks"
|
||||||
|
import {selectLine1After} from "./../../../store/LinePageSlice"
|
||||||
function LeftDown() {
|
function LeftDown() {
|
||||||
|
const data = useAppSelector(selectLine1After);
|
||||||
|
// console.log('页面数据:',data)
|
||||||
const nameList = [
|
const nameList = [
|
||||||
{ name: "表单", ename: "table" },
|
{ name: "表单", ename: "table" },
|
||||||
{ name: "柱状", ename: "chart" },
|
{ name: "柱状", ename: "chart" },
|
||||||
@ -13,7 +17,7 @@ function LeftDown() {
|
|||||||
const handleButtonChange = (activeName: string) => {
|
const handleButtonChange = (activeName: string) => {
|
||||||
setActiveName(activeName);
|
setActiveName(activeName);
|
||||||
};
|
};
|
||||||
const config = {
|
const configDay = {
|
||||||
header: ["序号", "工序类型", "报废数量"],
|
header: ["序号", "工序类型", "报废数量"],
|
||||||
headerHeight: 30,
|
headerHeight: 30,
|
||||||
rowNum: 4,
|
rowNum: 4,
|
||||||
@ -21,36 +25,14 @@ function LeftDown() {
|
|||||||
headerBGC: "rgba(79, 114, 136, 0.3)",
|
headerBGC: "rgba(79, 114, 136, 0.3)",
|
||||||
oddRowBGC: "rgba(79, 114, 136, 0.3)",
|
oddRowBGC: "rgba(79, 114, 136, 0.3)",
|
||||||
evenRowBGC: "rgba(76, 97, 123, 0.1)",
|
evenRowBGC: "rgba(76, 97, 123, 0.1)",
|
||||||
columnWidth: [73, 117, 190],
|
columnWidth: [73, 200, 107],
|
||||||
data: [
|
|
||||||
["行1列1", "行1列2", "行1列3"],
|
|
||||||
["行2列1", "行2列2", "行2列3"],
|
|
||||||
["行3列1", "行3列2", "行3列3"],
|
|
||||||
["行4列1", "行4列2", "行4列3"],
|
|
||||||
["行5列1", "行5列2", "行5列3"],
|
|
||||||
["行6列1", "行6列2", "行6列3"],
|
|
||||||
["行7列1", "行7列2", "行7列3"],
|
|
||||||
["行8列1", "行8列2", "行8列3"],
|
|
||||||
["行9列1", "行9列2", "行9列3"],
|
|
||||||
["行10列1", "行10列2", "行10列3"],
|
|
||||||
],
|
|
||||||
};
|
|
||||||
const config1 = {
|
|
||||||
header: ["序号", "工序类型", "报废数量"],
|
|
||||||
headerHeight: 30,
|
|
||||||
rowNum: 4,
|
|
||||||
align: ["center", "left", "left"],
|
|
||||||
headerBGC: "rgba(79, 114, 136, 0.3)",
|
|
||||||
oddRowBGC: "rgba(79, 114, 136, 0.3)",
|
|
||||||
evenRowBGC: "rgba(76, 97, 123, 0.1)",
|
|
||||||
columnWidth: [73, 117, 190],
|
|
||||||
data: [
|
data: [
|
||||||
["1", "磨边后", 224],
|
["1", "磨边后", 224],
|
||||||
["2", "包装1", 322],
|
["2", "包装1", 322],
|
||||||
["3", "包装2", 66],
|
["3", "包装2", 66],
|
||||||
],
|
],
|
||||||
};
|
};
|
||||||
const config2 = {
|
const configWeek = {
|
||||||
header: ["序号", "工序类型", "报废数量"],
|
header: ["序号", "工序类型", "报废数量"],
|
||||||
headerHeight: 30,
|
headerHeight: 30,
|
||||||
rowNum: 4,
|
rowNum: 4,
|
||||||
@ -58,14 +40,14 @@ function LeftDown() {
|
|||||||
headerBGC: "rgba(79, 114, 136, 0.3)",
|
headerBGC: "rgba(79, 114, 136, 0.3)",
|
||||||
oddRowBGC: "rgba(79, 114, 136, 0.3)",
|
oddRowBGC: "rgba(79, 114, 136, 0.3)",
|
||||||
evenRowBGC: "rgba(76, 97, 123, 0.1)",
|
evenRowBGC: "rgba(76, 97, 123, 0.1)",
|
||||||
columnWidth: [73, 117, 190],
|
columnWidth: [73, 200, 107],
|
||||||
data: [
|
data: [
|
||||||
["1", "磨边后", 1119],
|
["1", "磨边后", 1119],
|
||||||
["2", "包装1", 1798],
|
["2", "包装1", 1798],
|
||||||
["3", "包装2", 435],
|
["3", "包装2", 435],
|
||||||
],
|
],
|
||||||
};
|
};
|
||||||
const config3 = {
|
const configMonth = {
|
||||||
header: ["序号", "工序类型", "报废数量"],
|
header: ["序号", "工序类型", "报废数量"],
|
||||||
headerHeight: 30,
|
headerHeight: 30,
|
||||||
rowNum: 4,
|
rowNum: 4,
|
||||||
@ -73,7 +55,7 @@ function LeftDown() {
|
|||||||
headerBGC: "rgba(79, 114, 136, 0.3)",
|
headerBGC: "rgba(79, 114, 136, 0.3)",
|
||||||
oddRowBGC: "rgba(79, 114, 136, 0.3)",
|
oddRowBGC: "rgba(79, 114, 136, 0.3)",
|
||||||
evenRowBGC: "rgba(76, 97, 123, 0.1)",
|
evenRowBGC: "rgba(76, 97, 123, 0.1)",
|
||||||
columnWidth: [73, 117, 190],
|
columnWidth: [73, 200, 107],
|
||||||
data: [
|
data: [
|
||||||
["1", "磨边后", 5004],
|
["1", "磨边后", 5004],
|
||||||
["2", "包装1", 9122],
|
["2", "包装1", 9122],
|
||||||
@ -82,12 +64,61 @@ function LeftDown() {
|
|||||||
};
|
};
|
||||||
const color1 = ["#9DD5FF", "#1295FF"];
|
const color1 = ["#9DD5FF", "#1295FF"];
|
||||||
const color2 = ["#85F6E9", "#2EC6B4"];
|
const color2 = ["#85F6E9", "#2EC6B4"];
|
||||||
const dataProps1 = [224, 322, 66];
|
// @ts-ignore
|
||||||
const dataProps2 = [1119, 1798, 435];
|
let xData1: string[] = [];
|
||||||
const dataProps3 = [5004, 9122, 1924];
|
let xData2: string[] = [];
|
||||||
const options1 = getOptions(dataProps1, color1);
|
let xData3: string[] = [];
|
||||||
const options2 = getOptions(dataProps2, color2);
|
let dataProps1: number[] = [];
|
||||||
const options3 = getOptions(dataProps3, color1);
|
let dataProps2: number[] = [];
|
||||||
|
let dataProps3: number[] = [];
|
||||||
|
let arr1: any = [];
|
||||||
|
let arr2: any = [];
|
||||||
|
let arr3: any = [];
|
||||||
|
// @ts-ignore
|
||||||
|
if (data.todayProductionScraps && data.todayProductionScraps.length > 0) {
|
||||||
|
// @ts-ignore
|
||||||
|
data.todayProductionScraps.map((item,index)=>{
|
||||||
|
let arrInner = [];
|
||||||
|
arrInner.push(index+1,item.sectionName,item.scrapNum || 0);
|
||||||
|
arr1.push(arrInner);
|
||||||
|
xData1.push(item.sectionName);
|
||||||
|
dataProps1.push(item.scrapNum || 0);
|
||||||
|
})
|
||||||
|
}else{
|
||||||
|
dataProps1 = []
|
||||||
|
}
|
||||||
|
// @ts-ignore
|
||||||
|
if (data.weekProductionScraps && data.weekProductionScraps.length > 0) {
|
||||||
|
// @ts-ignore
|
||||||
|
data.weekProductionScraps.map((item,index)=>{
|
||||||
|
let arrInner = [];
|
||||||
|
arrInner.push(index+1,item.sectionName,item.scrapNum || 0);
|
||||||
|
arr2.push(arrInner);
|
||||||
|
xData2.push(item.sectionName);
|
||||||
|
dataProps2.push(item.scrapNum || 0);
|
||||||
|
})
|
||||||
|
}else{
|
||||||
|
dataProps2 = []
|
||||||
|
}
|
||||||
|
// @ts-ignore
|
||||||
|
if (data.monthProductionScraps && data.monthProductionScraps.length > 0) {
|
||||||
|
// @ts-ignore
|
||||||
|
data.monthProductionScraps.map((item,index)=>{
|
||||||
|
let arrInner = [];
|
||||||
|
arrInner.push(index+1,item.sectionName,item.scrapNum || 0);
|
||||||
|
arr3.push(arrInner);
|
||||||
|
xData3.push(item.sectionName);
|
||||||
|
dataProps3.push(item.scrapNum || 0);
|
||||||
|
})
|
||||||
|
}else{
|
||||||
|
dataProps3 = []
|
||||||
|
}
|
||||||
|
configDay.data = arr1;
|
||||||
|
configWeek.data = arr2;
|
||||||
|
configMonth.data = arr3;
|
||||||
|
const options1 = getOptions(dataProps1,xData1, color1);
|
||||||
|
const options2 = getOptions(dataProps2,xData2, color2);
|
||||||
|
const options3 = getOptions(dataProps3,xData3, color1);
|
||||||
return (
|
return (
|
||||||
<div className="left_down">
|
<div className="left_down">
|
||||||
<TitleBox title={"left_down"} />
|
<TitleBox title={"left_down"} />
|
||||||
@ -102,11 +133,22 @@ function LeftDown() {
|
|||||||
</div>
|
</div>
|
||||||
<div className="left_down_content">
|
<div className="left_down_content">
|
||||||
{activeName === "table" ? (
|
{activeName === "table" ? (
|
||||||
<ScrollBoard
|
arr1.length > 0 ? <ScrollBoard
|
||||||
config={config1}
|
config={configDay}
|
||||||
style={{ width: "380px", height: "150px" }}
|
style={{ width: "380px", height: "150px" }}
|
||||||
/>
|
/>:(<p
|
||||||
) : options1 ? (
|
style={{
|
||||||
|
color: "#cccf",
|
||||||
|
fontSize: "24px",
|
||||||
|
userSelect: "none",
|
||||||
|
textAlign: "center",
|
||||||
|
paddingTop: "50px",
|
||||||
|
margin:0
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
暂无数据
|
||||||
|
</p>)
|
||||||
|
) : dataProps1.length>0 ? (
|
||||||
<ReactECharts option={options1} style={{ height: "100%" }} />
|
<ReactECharts option={options1} style={{ height: "100%" }} />
|
||||||
) : (
|
) : (
|
||||||
<p
|
<p
|
||||||
@ -115,7 +157,8 @@ function LeftDown() {
|
|||||||
fontSize: "24px",
|
fontSize: "24px",
|
||||||
userSelect: "none",
|
userSelect: "none",
|
||||||
textAlign: "center",
|
textAlign: "center",
|
||||||
paddingTop: "72px",
|
paddingTop: "50px",
|
||||||
|
margin:0
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
暂无数据
|
暂无数据
|
||||||
@ -129,11 +172,22 @@ function LeftDown() {
|
|||||||
</div>
|
</div>
|
||||||
<div className="left_down_content">
|
<div className="left_down_content">
|
||||||
{activeName === "table" ? (
|
{activeName === "table" ? (
|
||||||
<ScrollBoard
|
arr2.length > 0 ? <ScrollBoard
|
||||||
config={config2}
|
config={configWeek}
|
||||||
style={{ width: "380px", height: "150px" }}
|
style={{ width: "380px", height: "150px" }}
|
||||||
/>
|
/>:(<p
|
||||||
) : options2 ? (
|
style={{
|
||||||
|
color: "#cccf",
|
||||||
|
fontSize: "24px",
|
||||||
|
userSelect: "none",
|
||||||
|
textAlign: "center",
|
||||||
|
paddingTop: "50px",
|
||||||
|
margin:0
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
暂无数据
|
||||||
|
</p>)
|
||||||
|
) : dataProps2.length>0 ? (
|
||||||
<ReactECharts option={options2} style={{ height: "100%" }} />
|
<ReactECharts option={options2} style={{ height: "100%" }} />
|
||||||
) : (
|
) : (
|
||||||
<p
|
<p
|
||||||
@ -142,7 +196,8 @@ function LeftDown() {
|
|||||||
fontSize: "24px",
|
fontSize: "24px",
|
||||||
userSelect: "none",
|
userSelect: "none",
|
||||||
textAlign: "center",
|
textAlign: "center",
|
||||||
paddingTop: "72px",
|
paddingTop: "50px",
|
||||||
|
margin:0
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
暂无数据
|
暂无数据
|
||||||
@ -156,11 +211,22 @@ function LeftDown() {
|
|||||||
</div>
|
</div>
|
||||||
<div className="left_down_content">
|
<div className="left_down_content">
|
||||||
{activeName === "table" ? (
|
{activeName === "table" ? (
|
||||||
<ScrollBoard
|
arr3.length > 0 ? <ScrollBoard
|
||||||
config={config3}
|
config={configMonth}
|
||||||
style={{ width: "380px", height: "150px" }}
|
style={{ width: "380px", height: "150px" }}
|
||||||
/>
|
/>:(<p
|
||||||
) : options3 ? (
|
style={{
|
||||||
|
color: "#cccf",
|
||||||
|
fontSize: "24px",
|
||||||
|
userSelect: "none",
|
||||||
|
textAlign: "center",
|
||||||
|
paddingTop: "50px",
|
||||||
|
margin:0
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
暂无数据
|
||||||
|
</p>)
|
||||||
|
) : dataProps3.length>0 ? (
|
||||||
<ReactECharts option={options3} style={{ height: "100%" }} />
|
<ReactECharts option={options3} style={{ height: "100%" }} />
|
||||||
) : (
|
) : (
|
||||||
<p
|
<p
|
||||||
@ -169,7 +235,8 @@ function LeftDown() {
|
|||||||
fontSize: "24px",
|
fontSize: "24px",
|
||||||
userSelect: "none",
|
userSelect: "none",
|
||||||
textAlign: "center",
|
textAlign: "center",
|
||||||
paddingTop: "72px",
|
paddingTop: "50px",
|
||||||
|
margin:0
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
暂无数据
|
暂无数据
|
268
src/page/LinePage1-2/Left/LeftUp.tsx
Normal file
268
src/page/LinePage1-2/Left/LeftUp.tsx
Normal file
@ -0,0 +1,268 @@
|
|||||||
|
import ReactECharts from "echarts-for-react";
|
||||||
|
import TitleBox from "../Component/TitleBox";
|
||||||
|
import SwitchButton from "../Component/SwitchButton";
|
||||||
|
import getOptions from "../../Component/SummaryBarChart/chart.config";
|
||||||
|
import { useState } from "react";
|
||||||
|
import {useAppSelector} from "./../../../store/hooks"
|
||||||
|
import {selectLine1After} from "./../../../store/LinePageSlice"
|
||||||
|
function LeftUp() {
|
||||||
|
const data = useAppSelector(selectLine1After);
|
||||||
|
// 假数据
|
||||||
|
const dataSource = {
|
||||||
|
day: {
|
||||||
|
xData: [],
|
||||||
|
series: [] as { data: number[]; type: string; stack: string; name: any; barWidth?: number; label: { show: boolean; position: string; color: string;formatter?:any }; }[],
|
||||||
|
},
|
||||||
|
week: {
|
||||||
|
xData: [],
|
||||||
|
series: [] as { data: number[]; type: string; stack: string; name: any; barWidth?: number; label: { show: boolean; position: string; color: string;formatter?:any }; }[],
|
||||||
|
},
|
||||||
|
month: {
|
||||||
|
xData: [],
|
||||||
|
series: [] as { data: number[]; type: string; stack: string; name: any; barWidth?: number; label: { show: boolean; position: string; color: string;formatter?:any }; }[],
|
||||||
|
},
|
||||||
|
};
|
||||||
|
const nameList = [
|
||||||
|
{ name: "天", ename: "day" },
|
||||||
|
{ name: "周", ename: "week" },
|
||||||
|
{ name: "月", ename: "month" },
|
||||||
|
];
|
||||||
|
const [activeName, setActiveName] = useState<string>(nameList[0].ename);
|
||||||
|
let chartData = (dataSource as { [key: string]: any })[activeName];
|
||||||
|
const handleButtonChange = (activeName: string) => {
|
||||||
|
setActiveName(activeName);
|
||||||
|
};
|
||||||
|
// @ts-ignore
|
||||||
|
if (data.todayAllProductionScraps && Object.keys(data.todayAllProductionScraps).length > 0) {
|
||||||
|
let sum: number[] = [];
|
||||||
|
// 生成obj
|
||||||
|
// @ts-ignore
|
||||||
|
data.scrapBars.map((item,index) => {
|
||||||
|
let obj = {
|
||||||
|
data: [],
|
||||||
|
type: "bar",
|
||||||
|
stack: "a",
|
||||||
|
name: item,
|
||||||
|
barWidth: 14,
|
||||||
|
label: {
|
||||||
|
show: true,
|
||||||
|
position: "right",
|
||||||
|
color: "inherit",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
dataSource.day.series.push(obj)
|
||||||
|
})
|
||||||
|
// @ts-ignore
|
||||||
|
dataSource.day.xData = Object.keys(data.todayAllProductionScraps)
|
||||||
|
dataSource.day.xData.sort((a,b)=>{// 保证横坐标是有序的
|
||||||
|
// @ts-ignore
|
||||||
|
const lastDigitA = parseInt(a[a.length - 1], 10);
|
||||||
|
// @ts-ignore
|
||||||
|
const lastDigitB = parseInt(b[b.length - 1], 10);
|
||||||
|
return lastDigitA - lastDigitB;
|
||||||
|
})
|
||||||
|
for (let k = 0; k < dataSource.day.xData.length; k++) {
|
||||||
|
let item = dataSource.day.xData[k];
|
||||||
|
let sumIner = 0
|
||||||
|
for(let i = 0;i < dataSource.day.series.length;i++){
|
||||||
|
let itemSeries = dataSource.day.series[i]
|
||||||
|
// @ts-ignore
|
||||||
|
data.todayAllProductionScraps[item].map((itemInner,indexInner)=>{
|
||||||
|
// @ts-ignore
|
||||||
|
if (itemInner.sectionName.indexOf(itemSeries.name)!==-1) {
|
||||||
|
// @ts-ignore
|
||||||
|
itemSeries.data.push(itemInner.scrapNum || 0)
|
||||||
|
sumIner += itemInner.scrapNum || 0
|
||||||
|
return
|
||||||
|
}
|
||||||
|
})
|
||||||
|
if (itemSeries.data.length === k) {
|
||||||
|
itemSeries.data.push(0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
sum.push(sumIner)
|
||||||
|
}
|
||||||
|
dataSource.day.series.push({
|
||||||
|
data: sum,
|
||||||
|
type: "bar",
|
||||||
|
stack: "a",
|
||||||
|
name: "",
|
||||||
|
label: {
|
||||||
|
show: true,
|
||||||
|
position: "top",
|
||||||
|
color: "#fff",
|
||||||
|
formatter: function (params: any) {
|
||||||
|
return sum[params.dataIndex];
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}else{
|
||||||
|
dataSource.day.xData = []
|
||||||
|
dataSource.day.series = []
|
||||||
|
}
|
||||||
|
// @ts-ignore
|
||||||
|
if (data.weekAllProductionScraps && Object.keys(data.weekAllProductionScraps).length > 0) {
|
||||||
|
let sum: number[] = [];
|
||||||
|
// 生成obj
|
||||||
|
// @ts-ignore
|
||||||
|
data.scrapBars.map((item,index) => {
|
||||||
|
let obj = {
|
||||||
|
data: [],
|
||||||
|
type: "bar",
|
||||||
|
stack: "a",
|
||||||
|
name: item,
|
||||||
|
barWidth: 14,
|
||||||
|
label: {
|
||||||
|
show: true,
|
||||||
|
position: "right",
|
||||||
|
color: "inherit",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
dataSource.week.series.push(obj)
|
||||||
|
})
|
||||||
|
// @ts-ignore
|
||||||
|
dataSource.week.xData = Object.keys(data.weekAllProductionScraps)
|
||||||
|
dataSource.week.xData.sort((a,b)=>{// 保证横坐标是有序的
|
||||||
|
// @ts-ignore
|
||||||
|
const lastDigitA = parseInt(a[a.length - 1], 10);
|
||||||
|
// @ts-ignore
|
||||||
|
const lastDigitB = parseInt(b[b.length - 1], 10);
|
||||||
|
return lastDigitA - lastDigitB;
|
||||||
|
})
|
||||||
|
for (let k = 0; k < dataSource.week.xData.length; k++) {
|
||||||
|
let item = dataSource.week.xData[k];
|
||||||
|
let sumIner = 0
|
||||||
|
for(let i = 0;i < dataSource.week.series.length;i++){
|
||||||
|
let itemSeries = dataSource.week.series[i]
|
||||||
|
// @ts-ignore
|
||||||
|
data.weekAllProductionScraps[item].map((itemInner,indexInner)=>{
|
||||||
|
// @ts-ignore
|
||||||
|
if (itemInner.sectionName.indexOf(itemSeries.name)!==-1) {
|
||||||
|
// @ts-ignore
|
||||||
|
itemSeries.data.push(itemInner.scrapNum || 0)
|
||||||
|
sumIner += itemInner.scrapNum || 0
|
||||||
|
return
|
||||||
|
}
|
||||||
|
})
|
||||||
|
if (itemSeries.data.length === k) {
|
||||||
|
itemSeries.data.push(0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
sum.push(sumIner)
|
||||||
|
}
|
||||||
|
dataSource.week.series.push({
|
||||||
|
data: sum,
|
||||||
|
type: "bar",
|
||||||
|
stack: "a",
|
||||||
|
name: "",
|
||||||
|
label: {
|
||||||
|
show: true,
|
||||||
|
position: "top",
|
||||||
|
color: "#fff",
|
||||||
|
formatter: function (params: any) {
|
||||||
|
return sum[params.dataIndex];
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}else{
|
||||||
|
dataSource.week.xData = []
|
||||||
|
dataSource.week.series = []
|
||||||
|
}
|
||||||
|
// @ts-ignore
|
||||||
|
if (data.monthAllProductionScraps && Object.keys(data.monthAllProductionScraps).length > 0) {
|
||||||
|
let sum: number[] = [];
|
||||||
|
// 生成obj
|
||||||
|
// @ts-ignore
|
||||||
|
data.scrapBars.map((item,index) => {
|
||||||
|
let obj = {
|
||||||
|
data: [],
|
||||||
|
type: "bar",
|
||||||
|
stack: "a",
|
||||||
|
name: item,
|
||||||
|
barWidth: 14,
|
||||||
|
label: {
|
||||||
|
show: true,
|
||||||
|
position: "right",
|
||||||
|
color: "inherit",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
dataSource.month.series.push(obj)
|
||||||
|
})
|
||||||
|
// @ts-ignore
|
||||||
|
dataSource.month.xData = Object.keys(data.monthAllProductionScraps)
|
||||||
|
dataSource.month.xData.sort((a,b)=>{// 保证横坐标是有序的
|
||||||
|
// @ts-ignore
|
||||||
|
const lastDigitA = parseInt(a[a.length - 1], 10);
|
||||||
|
// @ts-ignore
|
||||||
|
const lastDigitB = parseInt(b[b.length - 1], 10);
|
||||||
|
return lastDigitA - lastDigitB;
|
||||||
|
})
|
||||||
|
for (let k = 0; k < dataSource.month.xData.length; k++) {
|
||||||
|
let item = dataSource.month.xData[k];
|
||||||
|
let sumIner = 0
|
||||||
|
for(let i = 0;i < dataSource.month.series.length;i++){
|
||||||
|
let itemSeries = dataSource.month.series[i]
|
||||||
|
// @ts-ignore
|
||||||
|
data.monthAllProductionScraps[item].map((itemInner,indexInner)=>{
|
||||||
|
// @ts-ignore
|
||||||
|
if (itemInner.sectionName.indexOf(itemSeries.name)!==-1) {
|
||||||
|
// @ts-ignore
|
||||||
|
itemSeries.data.push(itemInner.scrapNum || 0)
|
||||||
|
sumIner += itemInner.scrapNum || 0
|
||||||
|
return
|
||||||
|
}
|
||||||
|
})
|
||||||
|
if (itemSeries.data.length === k) {
|
||||||
|
itemSeries.data.push(0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
sum.push(sumIner)
|
||||||
|
}
|
||||||
|
dataSource.month.series.push({
|
||||||
|
data: sum,
|
||||||
|
type: "bar",
|
||||||
|
stack: "a",
|
||||||
|
name: "",
|
||||||
|
label: {
|
||||||
|
show: true,
|
||||||
|
position: "top",
|
||||||
|
color: "#fff",
|
||||||
|
formatter: function (params: any) {
|
||||||
|
return sum[params.dataIndex];
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}else{
|
||||||
|
dataSource.month.xData = []
|
||||||
|
dataSource.month.series = []
|
||||||
|
}
|
||||||
|
const options = getOptions(chartData);
|
||||||
|
console.log('dataSource',dataSource)
|
||||||
|
return (
|
||||||
|
<div className="left_up">
|
||||||
|
<TitleBox title={"left_up"} />
|
||||||
|
<div className="left_up_switch">
|
||||||
|
<SwitchButton nameList={nameList} onChange={handleButtonChange} />
|
||||||
|
</div>
|
||||||
|
{// @ts-ignore
|
||||||
|
dataSource[activeName].xData.length>0 ? (
|
||||||
|
<div className="left_up_chart">
|
||||||
|
{<ReactECharts option={options} style={{ height: "100%" }} />}
|
||||||
|
</div>
|
||||||
|
):(
|
||||||
|
<p
|
||||||
|
style={{
|
||||||
|
color: "#cccf",
|
||||||
|
fontSize: "24px",
|
||||||
|
userSelect: "none",
|
||||||
|
textAlign: "center",
|
||||||
|
paddingTop: "72px",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
暂无数据
|
||||||
|
</p>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
export default LeftUp;
|
11
src/page/LinePage1-2/Left/index.tsx
Normal file
11
src/page/LinePage1-2/Left/index.tsx
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
import LeftUp from "./LeftUp";
|
||||||
|
import LeftDown from "./LeftDown";
|
||||||
|
function Left() {
|
||||||
|
return (
|
||||||
|
<div className="group_left flex-col">
|
||||||
|
<LeftUp />
|
||||||
|
<LeftDown />
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
export default Left;
|
273
src/page/LinePage1-2/Right/RightDown.tsx
Normal file
273
src/page/LinePage1-2/Right/RightDown.tsx
Normal file
@ -0,0 +1,273 @@
|
|||||||
|
import ReactECharts from "echarts-for-react";
|
||||||
|
import TitleBox from "../Component/TitleBox";
|
||||||
|
import SwitchButton from "../Component/SwitchButton";
|
||||||
|
import ScrollBoard from "./../../Component/ScrollBoard";
|
||||||
|
import { useState } from "react";
|
||||||
|
import getOptions from "../../Component/LineChartRight/chart.config";
|
||||||
|
import {useAppSelector} from "./../../../store/hooks"
|
||||||
|
import {selectLine1After} from "./../../../store/LinePageSlice"
|
||||||
|
import dayjs from "dayjs";
|
||||||
|
function RightDown() {
|
||||||
|
const data = useAppSelector(selectLine1After);
|
||||||
|
// console.log('页面数据:',data)
|
||||||
|
// 假数据
|
||||||
|
let tempData = [
|
||||||
|
{
|
||||||
|
type: "day",
|
||||||
|
data: {
|
||||||
|
time: [] as string[],
|
||||||
|
input: [] as number[],
|
||||||
|
output: [] as number[],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: "week",
|
||||||
|
data: {
|
||||||
|
time: [] as string[],
|
||||||
|
input: [] as number[],
|
||||||
|
output: [] as number[],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: "month",
|
||||||
|
data: {
|
||||||
|
time: [] as string[],
|
||||||
|
input: [] as number[],
|
||||||
|
output: [] as number[],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
];
|
||||||
|
const nameList = [
|
||||||
|
{ name: "表单", ename: "table" },
|
||||||
|
{ name: "折线", ename: "chart" },
|
||||||
|
];
|
||||||
|
const [activeName, setActiveName] = useState<string>(nameList[0].ename);
|
||||||
|
const handleButtonChange = (activeName: string) => {
|
||||||
|
setActiveName(activeName);
|
||||||
|
};
|
||||||
|
const configDay = {
|
||||||
|
header: ["时间", "投入数量", "产出数量"],
|
||||||
|
headerHeight: 30,
|
||||||
|
rowNum: 5,
|
||||||
|
headerBGC: "rgba(79, 114, 136, 0.3)",
|
||||||
|
oddRowBGC: "rgba(79, 114, 136, 0.3)",
|
||||||
|
evenRowBGC: "rgba(76, 97, 123, 0.1)",
|
||||||
|
columnWidth: [120, 130, 130],
|
||||||
|
data: [],
|
||||||
|
};
|
||||||
|
const configWeek = {
|
||||||
|
header: ["时间", "投入数量", "产出数量"],
|
||||||
|
headerHeight: 30,
|
||||||
|
rowNum: 5,
|
||||||
|
headerBGC: "rgba(79, 114, 136, 0.3)",
|
||||||
|
oddRowBGC: "rgba(79, 114, 136, 0.3)",
|
||||||
|
evenRowBGC: "rgba(76, 97, 123, 0.1)",
|
||||||
|
columnWidth: [120, 130, 130],
|
||||||
|
data: [],
|
||||||
|
};
|
||||||
|
const configMonth = {
|
||||||
|
header: ["时间", "投入数量", "产出数量"],
|
||||||
|
headerHeight: 30,
|
||||||
|
rowNum: 5,
|
||||||
|
headerBGC: "rgba(79, 114, 136, 0.3)",
|
||||||
|
oddRowBGC: "rgba(79, 114, 136, 0.3)",
|
||||||
|
evenRowBGC: "rgba(76, 97, 123, 0.1)",
|
||||||
|
columnWidth: [120, 130, 130],
|
||||||
|
data: [],
|
||||||
|
};
|
||||||
|
let arr1: any = [];
|
||||||
|
let arr2: any = [];
|
||||||
|
let arr3: any = [];
|
||||||
|
// @ts-ignore
|
||||||
|
if (data.todayProductionDets && data.todayProductionDets.length > 0) {
|
||||||
|
// @ts-ignore
|
||||||
|
data.todayProductionDets.map((item,index)=>{
|
||||||
|
let arrInner = [];
|
||||||
|
arrInner.push(dayjs(item.recTime).format("HH:mm"),item.inputNum,item.outputNum);
|
||||||
|
arr1.push(arrInner);
|
||||||
|
tempData[0].data.time.push(dayjs(item.recTime).format("HH:mm"));
|
||||||
|
tempData[0].data.input.push(item.inputNum);
|
||||||
|
tempData[0].data.output.push(item.outputNum);
|
||||||
|
})
|
||||||
|
}else{
|
||||||
|
tempData[0].data.time = []
|
||||||
|
tempData[0].data.input = []
|
||||||
|
tempData[0].data.output = []
|
||||||
|
}
|
||||||
|
// @ts-ignore
|
||||||
|
if (data.weekProductionDets && data.weekProductionDets.length > 0) {
|
||||||
|
// @ts-ignore
|
||||||
|
data.weekProductionDets.map((item,index)=>{
|
||||||
|
let arrInner = [];
|
||||||
|
arrInner.push(dayjs(item.recTime).format("YYYY/MM/DD"),item.inputNum,item.outputNum);
|
||||||
|
arr2.push(arrInner);
|
||||||
|
tempData[1].data.time.push(dayjs(item.recTime).format("MM.DD"));
|
||||||
|
tempData[1].data.input.push(item.inputNum);
|
||||||
|
tempData[1].data.output.push(item.outputNum);
|
||||||
|
})
|
||||||
|
}else{
|
||||||
|
tempData[1].data.time = []
|
||||||
|
tempData[1].data.input = []
|
||||||
|
tempData[1].data.output = []
|
||||||
|
}
|
||||||
|
// @ts-ignore
|
||||||
|
if (data.monthProductionDets && data.monthProductionDets.length > 0) {
|
||||||
|
// @ts-ignore
|
||||||
|
data.monthProductionDets.map((item,index)=>{
|
||||||
|
let arrInner = [];
|
||||||
|
arrInner.push(dayjs(item.recTime).format("YYYY/MM/DD"),item.inputNum,item.outputNum);
|
||||||
|
arr3.push(arrInner);
|
||||||
|
tempData[2].data.time.push(dayjs(item.recTime).format("MM.DD"));
|
||||||
|
tempData[2].data.input.push(item.inputNum);
|
||||||
|
tempData[2].data.output.push(item.outputNum);
|
||||||
|
})
|
||||||
|
}else{
|
||||||
|
tempData[2].data.time = []
|
||||||
|
tempData[2].data.input = []
|
||||||
|
tempData[2].data.output = []
|
||||||
|
}
|
||||||
|
configDay.data = arr1;
|
||||||
|
configWeek.data = arr2;
|
||||||
|
configMonth.data = arr3;
|
||||||
|
|
||||||
|
const chartData1 = tempData[0].data;
|
||||||
|
const chartData2 = tempData[1].data;
|
||||||
|
const chartData3 = tempData[2].data;
|
||||||
|
const options1 = getOptions(chartData1);
|
||||||
|
const options2 = getOptions(chartData2);
|
||||||
|
const options3 = getOptions(chartData3);
|
||||||
|
return (
|
||||||
|
<div className="right_down">
|
||||||
|
<TitleBox title={"right_down"} />
|
||||||
|
<div className="left_up_switch">
|
||||||
|
<SwitchButton nameList={nameList} onChange={handleButtonChange} />
|
||||||
|
</div>
|
||||||
|
<div style={{ padding: "10px", height: "628px" }}>
|
||||||
|
<div className="left_down_title flex-row">
|
||||||
|
<div className="left_down_box1 flex-col" />
|
||||||
|
<span className="left_down_text">当天</span>
|
||||||
|
<div className="left_down_box2 flex-col" />
|
||||||
|
</div>
|
||||||
|
<div className="right_down_content">
|
||||||
|
{activeName === "table" ? (
|
||||||
|
arr1.length>0?<ScrollBoard
|
||||||
|
config={configDay}
|
||||||
|
style={{ width: "380px", height: "180px" }}
|
||||||
|
/>:(
|
||||||
|
<p
|
||||||
|
style={{
|
||||||
|
color: "#cccf",
|
||||||
|
fontSize: "24px",
|
||||||
|
userSelect: "none",
|
||||||
|
textAlign: "center",
|
||||||
|
paddingTop: "50px",
|
||||||
|
margin:0
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
暂无数据
|
||||||
|
</p>
|
||||||
|
)
|
||||||
|
) : tempData[0].data.time.length>0 ? (
|
||||||
|
<ReactECharts option={options1} style={{ height: "100%" }} />
|
||||||
|
) : (
|
||||||
|
<p
|
||||||
|
style={{
|
||||||
|
color: "#cccf",
|
||||||
|
fontSize: "24px",
|
||||||
|
userSelect: "none",
|
||||||
|
textAlign: "center",
|
||||||
|
paddingTop: "50px",
|
||||||
|
margin:0
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
暂无数据
|
||||||
|
</p>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
<div className="left_down_title flex-row">
|
||||||
|
<div className="left_down_box1 flex-col" />
|
||||||
|
<span className="left_down_text">本周</span>
|
||||||
|
<div className="left_down_box2 flex-col" />
|
||||||
|
</div>
|
||||||
|
<div className="right_down_content">
|
||||||
|
{activeName === "table" ? (
|
||||||
|
arr2.length>0?<ScrollBoard
|
||||||
|
config={configWeek}
|
||||||
|
style={{ width: "380px", height: "180px" }}
|
||||||
|
/>:(
|
||||||
|
<p
|
||||||
|
style={{
|
||||||
|
color: "#cccf",
|
||||||
|
fontSize: "24px",
|
||||||
|
userSelect: "none",
|
||||||
|
textAlign: "center",
|
||||||
|
paddingTop: "50px",
|
||||||
|
margin:0
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
暂无数据
|
||||||
|
</p>
|
||||||
|
)
|
||||||
|
) : tempData[1].data.time.length>0 ? (
|
||||||
|
<ReactECharts option={options2} style={{ height: "100%" }} />
|
||||||
|
) : (
|
||||||
|
<p
|
||||||
|
style={{
|
||||||
|
color: "#cccf",
|
||||||
|
fontSize: "24px",
|
||||||
|
userSelect: "none",
|
||||||
|
textAlign: "center",
|
||||||
|
paddingTop: "50px",
|
||||||
|
margin:0
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
暂无数据
|
||||||
|
</p>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
<div className="left_down_title flex-row">
|
||||||
|
<div className="left_down_box1 flex-col" />
|
||||||
|
<span className="left_down_text">本月</span>
|
||||||
|
<div className="left_down_box2 flex-col" />
|
||||||
|
</div>
|
||||||
|
<div className="right_down_content">
|
||||||
|
{activeName === "table" ? (
|
||||||
|
arr3.length>0?<ScrollBoard
|
||||||
|
config={configMonth}
|
||||||
|
style={{ width: "380px", height: "180px" }}
|
||||||
|
/>:(
|
||||||
|
<p
|
||||||
|
style={{
|
||||||
|
color: "#cccf",
|
||||||
|
fontSize: "24px",
|
||||||
|
userSelect: "none",
|
||||||
|
textAlign: "center",
|
||||||
|
paddingTop: "50px",
|
||||||
|
margin:0
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
暂无数据
|
||||||
|
</p>
|
||||||
|
)
|
||||||
|
) : tempData[2].data.time.length>0 ? (
|
||||||
|
<ReactECharts option={options3} style={{ height: "100%" }} />
|
||||||
|
) : (
|
||||||
|
<p
|
||||||
|
style={{
|
||||||
|
color: "#cccf",
|
||||||
|
fontSize: "24px",
|
||||||
|
userSelect: "none",
|
||||||
|
textAlign: "center",
|
||||||
|
paddingTop: "50px",
|
||||||
|
margin:0
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
暂无数据
|
||||||
|
</p>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
export default RightDown;
|
52
src/page/LinePage1-2/Right/RightUp.tsx
Normal file
52
src/page/LinePage1-2/Right/RightUp.tsx
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
import TitleBox from "../Component/TitleBox";
|
||||||
|
import ScrollBoard from "./../../Component/ScrollBoard";
|
||||||
|
import {useAppSelector} from "./../../../store/hooks"
|
||||||
|
import {selectLine1After} from "./../../../store/LinePageSlice"
|
||||||
|
function RightUp() {
|
||||||
|
const data = useAppSelector(selectLine1After);
|
||||||
|
const config = {
|
||||||
|
header: ["序号", "工段名", "上片数据量", "成品下片数量"],
|
||||||
|
headerHeight: 32,
|
||||||
|
rowNum: 5,
|
||||||
|
align: ["center", "left", "left", "left"],
|
||||||
|
headerBGC: "rgba(79, 114, 136, 0.3)",
|
||||||
|
oddRowBGC: "rgba(79, 114, 136, 0.3)",
|
||||||
|
evenRowBGC: "rgba(76, 97, 123, 0.1)",
|
||||||
|
columnWidth: [55, 115, 100, 110],
|
||||||
|
data: [],
|
||||||
|
};
|
||||||
|
let arr:any = []
|
||||||
|
// @ts-ignore
|
||||||
|
if (data.sectionDet && data.sectionDet.length > 0) {
|
||||||
|
// @ts-ignore
|
||||||
|
data.sectionDet.map((item, index) => {
|
||||||
|
let arrInner = []
|
||||||
|
arrInner.push(index + 1, item.lineName, item.inputNum, item.outputNum)
|
||||||
|
arr.push(arrInner)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
config.data = arr
|
||||||
|
return (
|
||||||
|
<div className="right_up">
|
||||||
|
<TitleBox title={"right_up"} />
|
||||||
|
<div style={{ padding: "10px", height: "213px" }}>
|
||||||
|
{arr.length>0?<ScrollBoard
|
||||||
|
config={config}
|
||||||
|
style={{ width: "380px", height: "193px" }}
|
||||||
|
/>:(<p
|
||||||
|
style={{
|
||||||
|
color: "#cccf",
|
||||||
|
fontSize: "24px",
|
||||||
|
userSelect: "none",
|
||||||
|
textAlign: "center",
|
||||||
|
paddingTop: "50px",
|
||||||
|
margin:0
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
暂无数据
|
||||||
|
</p>)}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
export default RightUp;
|
12
src/page/LinePage1-2/Right/index.tsx
Normal file
12
src/page/LinePage1-2/Right/index.tsx
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
import RightDown from "./RightDown";
|
||||||
|
import RightUp from "./RightUp";
|
||||||
|
|
||||||
|
function Right() {
|
||||||
|
return (
|
||||||
|
<div className="group_right flex-col">
|
||||||
|
<RightUp />
|
||||||
|
<RightDown />
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
export default Right;
|
14
src/page/LinePage1-2/TopP.tsx
Normal file
14
src/page/LinePage1-2/TopP.tsx
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
import '../../lanhuapp/common.css';
|
||||||
|
import "./../style/linePage.css";
|
||||||
|
|
||||||
|
function TopP() {
|
||||||
|
return (
|
||||||
|
<div className="flex-row">
|
||||||
|
<div className="block_top flex-row">
|
||||||
|
<div className='block_top_title'></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default TopP;
|
38
src/page/LinePage1-2/index.tsx
Normal file
38
src/page/LinePage1-2/index.tsx
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
import React from "react";
|
||||||
|
import TopP from "./TopP";
|
||||||
|
import Left from "./Left";
|
||||||
|
import Right from "./Right";
|
||||||
|
import Center from "./Center";
|
||||||
|
import {useEffect} from 'react';
|
||||||
|
import {useNavigate} from "react-router-dom";
|
||||||
|
function LinePage() {
|
||||||
|
const navigate = useNavigate();
|
||||||
|
useEffect(() => {
|
||||||
|
const handleKeyDown = (event:any) => {
|
||||||
|
if (event.key === 'ArrowUp') {
|
||||||
|
console.log('LDPage向上键被按下');
|
||||||
|
navigate('/LD?lineId=1-2');
|
||||||
|
// 执行向上键的逻辑
|
||||||
|
} else if (event.key === 'ArrowDown') {
|
||||||
|
console.log('LDPage向下键被按下');
|
||||||
|
// 执行向下键的逻辑
|
||||||
|
navigate('/LD?lineId=1-2');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
window.addEventListener('keydown', handleKeyDown);
|
||||||
|
return () => {
|
||||||
|
window.removeEventListener('keydown', handleKeyDown);
|
||||||
|
};
|
||||||
|
});
|
||||||
|
return (
|
||||||
|
<React.Fragment>
|
||||||
|
<TopP />
|
||||||
|
<div className="block_bottom flex-row">
|
||||||
|
<Left />
|
||||||
|
<Center />
|
||||||
|
<Right />
|
||||||
|
</div>
|
||||||
|
</React.Fragment>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
export default LinePage;
|
213
src/page/LinePage2-1/Center/CenterDown.tsx
Normal file
213
src/page/LinePage2-1/Center/CenterDown.tsx
Normal file
@ -0,0 +1,213 @@
|
|||||||
|
import ReactECharts from "echarts-for-react";
|
||||||
|
import TitleBox from "../Component/TitleBox";
|
||||||
|
import ScrollBoard from "./../../Component/ScrollBoard";
|
||||||
|
// import SwitchButton from "../Component/SwitchButton";
|
||||||
|
import { useState } from "react";
|
||||||
|
import getOptions from "../../Component/LineChart/chart.config";
|
||||||
|
import {useAppSelector} from "./../../../store/hooks"
|
||||||
|
import {selectLine2Before} from "./../../../store/LinePageSlice"
|
||||||
|
import dayjs from "dayjs";
|
||||||
|
function CenterDown() {
|
||||||
|
const data = useAppSelector(selectLine2Before);
|
||||||
|
// 假数据
|
||||||
|
const dataSource = {
|
||||||
|
day: {
|
||||||
|
xData:[],
|
||||||
|
series: [] as { name: string; type: string; symbol: string; symbolSize: number; data: never[]; }[],
|
||||||
|
},
|
||||||
|
week: {
|
||||||
|
xData:[],
|
||||||
|
series: [] as { name: string; type: string; symbol: string; symbolSize: number; data: never[]; }[],
|
||||||
|
},
|
||||||
|
month: {
|
||||||
|
xData:[],
|
||||||
|
series: [] as { name: string; type: string; symbol: string; symbolSize: number; data: never[]; }[],
|
||||||
|
},
|
||||||
|
};
|
||||||
|
const nameList = [
|
||||||
|
{ name: "天", ename: "day" },
|
||||||
|
{ name: "周", ename: "week" },
|
||||||
|
{ name: "月", ename: "month" },
|
||||||
|
];
|
||||||
|
const [activeName, setActiveName] = useState<string>(nameList[1].ename);
|
||||||
|
// const handleButtonChange = (activeName: string) => {
|
||||||
|
// setActiveName(activeName);
|
||||||
|
// };
|
||||||
|
const config = {
|
||||||
|
header: ["序号", "报警时间", "报警设备", "报警内容"],
|
||||||
|
headerHeight: 36,
|
||||||
|
rowNum: 6,
|
||||||
|
align: ["center", "left", "left", "left"],
|
||||||
|
headerBGC: "rgba(79, 114, 136, 0.3)",
|
||||||
|
oddRowBGC: "rgba(79, 114, 136, 0.3)",
|
||||||
|
evenRowBGC: "rgba(76, 97, 123, 0.1)",
|
||||||
|
columnWidth: [80, 137, 177, 97],
|
||||||
|
data: []
|
||||||
|
};
|
||||||
|
// 报警数据
|
||||||
|
let arr:any = []
|
||||||
|
let sumAlarm = 0
|
||||||
|
// @ts-ignore
|
||||||
|
if (data.alarms && data.alarms.length > 0) {
|
||||||
|
// @ts-ignore
|
||||||
|
sumAlarm = data.alarms.length
|
||||||
|
// @ts-ignore
|
||||||
|
data.alarms.map((item,index) => {
|
||||||
|
let arrInner = []
|
||||||
|
arrInner.push(
|
||||||
|
index+1,
|
||||||
|
dayjs(item.recTime).format("YYYY/MM/DD HH:mm"),
|
||||||
|
item.name,
|
||||||
|
item.status === '故障'?"<span style='color:#FF1E1E'>故障</span>":"<span style='color:#FFB40F'>离线</span>",
|
||||||
|
);
|
||||||
|
arr.push(arrInner)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
config.data = arr
|
||||||
|
// 工段成品率
|
||||||
|
// @ts-ignore
|
||||||
|
if (data.todayProductionRates && Object.keys(data.todayProductionRates).length > 0) {
|
||||||
|
// @ts-ignore
|
||||||
|
let keys = Object.keys(data.todayProductionRates)
|
||||||
|
// @ts-ignore
|
||||||
|
data.todayProductionRates[keys[0]].map((item,index)=>{
|
||||||
|
// @ts-ignore
|
||||||
|
dataSource.day.xData.push(dayjs(item.recTime).format("HH:mm"))
|
||||||
|
})
|
||||||
|
keys.map((item,index)=>{
|
||||||
|
let obj = {
|
||||||
|
name: "",
|
||||||
|
type: "line",
|
||||||
|
symbol: "circle",
|
||||||
|
symbolSize: 4,
|
||||||
|
data:[]
|
||||||
|
}
|
||||||
|
// @ts-ignore
|
||||||
|
obj.name = data.todayProductionRates[item][0].lineName
|
||||||
|
// @ts-ignore
|
||||||
|
data.todayProductionRates[item].map((subItem,index)=>{
|
||||||
|
// @ts-ignore
|
||||||
|
obj.data.push(subItem.passRate)
|
||||||
|
})
|
||||||
|
dataSource.day.series.push(obj)
|
||||||
|
})
|
||||||
|
}else{
|
||||||
|
dataSource.day.xData = []
|
||||||
|
dataSource.day.series = []
|
||||||
|
}
|
||||||
|
// @ts-ignore
|
||||||
|
if (data.weekProductionRates && Object.keys(data.weekProductionRates).length > 0) {
|
||||||
|
// @ts-ignore
|
||||||
|
let keys = Object.keys(data.weekProductionRates)
|
||||||
|
// @ts-ignore
|
||||||
|
data.weekProductionRates[keys[0]].map((item,index)=>{
|
||||||
|
// @ts-ignore
|
||||||
|
dataSource.week.xData.push(dayjs(item.recTime).format("HH:mm"))
|
||||||
|
})
|
||||||
|
keys.map((item,index)=>{
|
||||||
|
let obj = {
|
||||||
|
name: "",
|
||||||
|
type: "line",
|
||||||
|
symbol: "circle",
|
||||||
|
symbolSize: 4,
|
||||||
|
data:[]
|
||||||
|
}
|
||||||
|
// @ts-ignore
|
||||||
|
obj.name = data.weekProductionRates[item][0].lineName
|
||||||
|
// @ts-ignore
|
||||||
|
data.weekProductionRates[item].map((subItem,index)=>{
|
||||||
|
// @ts-ignore
|
||||||
|
obj.data.push(subItem.passRate)
|
||||||
|
})
|
||||||
|
dataSource.week.series.push(obj)
|
||||||
|
})
|
||||||
|
}else{
|
||||||
|
dataSource.week.xData = []
|
||||||
|
dataSource.week.series = []
|
||||||
|
}
|
||||||
|
// @ts-ignore
|
||||||
|
if (data.monthProductionRates && Object.keys(data.monthProductionRates).length > 0) {
|
||||||
|
// @ts-ignore
|
||||||
|
let keys = Object.keys(data.monthProductionRates)
|
||||||
|
// @ts-ignore
|
||||||
|
data.monthProductionRates[keys[0]].map((item,index)=>{
|
||||||
|
// @ts-ignore
|
||||||
|
dataSource.month.xData.push(dayjs(item.recTime).format("HH:mm"))
|
||||||
|
})
|
||||||
|
keys.map((item,index)=>{
|
||||||
|
let obj = {
|
||||||
|
name: "",
|
||||||
|
type: "line",
|
||||||
|
symbol: "circle",
|
||||||
|
symbolSize: 4,
|
||||||
|
data:[]
|
||||||
|
}
|
||||||
|
// @ts-ignore
|
||||||
|
obj.name = data.monthProductionRates[item][0].lineName
|
||||||
|
// @ts-ignore
|
||||||
|
data.monthProductionRates[item].map((subItem,index)=>{
|
||||||
|
// @ts-ignore
|
||||||
|
obj.data.push(subItem.passRate)
|
||||||
|
})
|
||||||
|
dataSource.month.series.push(obj)
|
||||||
|
})
|
||||||
|
}else{
|
||||||
|
dataSource.month.xData = []
|
||||||
|
dataSource.month.series = []
|
||||||
|
}
|
||||||
|
let chartData = (dataSource as { [key: string]: any })[activeName];
|
||||||
|
const options = getOptions(chartData);
|
||||||
|
return (
|
||||||
|
<div className="center_down flex-row">
|
||||||
|
<div className="center_down_inner flex-col left-box">
|
||||||
|
<TitleBox title={"center_down_left"} />
|
||||||
|
<span className="alarm_num_title">— 报警总数 —</span>
|
||||||
|
<div className="alarm_num">{sumAlarm}</div>
|
||||||
|
<div style={{ padding: 10, height: "270px" }}>
|
||||||
|
{arr.length>0?<ScrollBoard
|
||||||
|
config={config}
|
||||||
|
style={{ width: "492px", height: "250px" }}
|
||||||
|
/>:(<p
|
||||||
|
style={{
|
||||||
|
color: "#cccf",
|
||||||
|
fontSize: "24px",
|
||||||
|
userSelect: "none",
|
||||||
|
textAlign: "center",
|
||||||
|
paddingTop: "50px",
|
||||||
|
margin:0
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
暂无数据
|
||||||
|
</p>)}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{/* 工段成品率 */}
|
||||||
|
<div className="center_down_inner flex-col right_box">
|
||||||
|
<TitleBox title={"center_down_right"} />
|
||||||
|
{/* <div className="left_up_switch">
|
||||||
|
<SwitchButton nameList={nameList} onChange={handleButtonChange} />
|
||||||
|
</div> */}
|
||||||
|
{chartData.xData.length>0 && (
|
||||||
|
<div className="chart_box">
|
||||||
|
{<ReactECharts option={options} style={{ height: "100%" }} />}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
{chartData.xData.length==0 && (
|
||||||
|
<p
|
||||||
|
style={{
|
||||||
|
color: "#cccf",
|
||||||
|
fontSize: "24px",
|
||||||
|
userSelect: "none",
|
||||||
|
textAlign: "center",
|
||||||
|
paddingTop: "120px",
|
||||||
|
margin:0
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
暂无数据
|
||||||
|
</p>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
export default CenterDown;
|
10
src/page/LinePage2-1/Center/CenterUp.tsx
Normal file
10
src/page/LinePage2-1/Center/CenterUp.tsx
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
import LinePageBabylon from "../../../babylonjs/LinePageBabylonNew";
|
||||||
|
function CenterUp() {
|
||||||
|
const lineID = "2-1"
|
||||||
|
return (
|
||||||
|
<div className="center_up">
|
||||||
|
<LinePageBabylon modelPath={`Line${lineID}`} />
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
export default CenterUp;
|
12
src/page/LinePage2-1/Center/index.tsx
Normal file
12
src/page/LinePage2-1/Center/index.tsx
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
import CenterDown from "./CenterDown";
|
||||||
|
import CenterUp from "./CenterUp";
|
||||||
|
|
||||||
|
function Center() {
|
||||||
|
return (
|
||||||
|
<div className="group_center flex-col">
|
||||||
|
<CenterUp />
|
||||||
|
<CenterDown />
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
export default Center;
|
19
src/page/LinePage2-1/Component/SwitchButton/index.css
Normal file
19
src/page/LinePage2-1/Component/SwitchButton/index.css
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
.switch-button {
|
||||||
|
height: 33px;
|
||||||
|
}
|
||||||
|
.switch-button button {
|
||||||
|
color: #fff;
|
||||||
|
font-size: 18px;
|
||||||
|
padding: 4px 10px;
|
||||||
|
background-color: rgba(49, 135, 140, 0.3);
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
.switch-button button:first-child {
|
||||||
|
border-radius: 5px 0 0 5px;
|
||||||
|
}
|
||||||
|
.switch-button button:last-child {
|
||||||
|
border-radius: 0 5px 5px 0;
|
||||||
|
}
|
||||||
|
.switch-button button.active {
|
||||||
|
background-color: rgba(86, 244, 231, 0.7);
|
||||||
|
}
|
65
src/page/LinePage2-1/Component/SwitchButton/index.tsx
Normal file
65
src/page/LinePage2-1/Component/SwitchButton/index.tsx
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
import { useEffect, useState } from "react";
|
||||||
|
import "./index.css";
|
||||||
|
interface Name {
|
||||||
|
name: string;
|
||||||
|
ename: string;
|
||||||
|
}
|
||||||
|
interface nameListProps {
|
||||||
|
nameList: Name[];
|
||||||
|
onChange: (value: string) => void;
|
||||||
|
}
|
||||||
|
function createActiveNameUpdater(nameList: any, activeName: string) {
|
||||||
|
let activeIndex = nameList.findIndex((obj: any) => obj.name === activeName);
|
||||||
|
|
||||||
|
return function updateActiveName() {
|
||||||
|
activeIndex = (activeIndex + 1) % nameList.length;
|
||||||
|
return nameList[activeIndex].ename;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
function SwitchButton(props: nameListProps) {
|
||||||
|
const [activeName, setActiveName] = useState(props.nameList[0].ename);
|
||||||
|
const [timerId, setTimerId] = useState<any>(null);
|
||||||
|
let updateActiveName = createActiveNameUpdater(props.nameList, activeName);
|
||||||
|
useEffect(() => {
|
||||||
|
const timer = setInterval(() => {
|
||||||
|
let active = updateActiveName();
|
||||||
|
setActiveName(active);
|
||||||
|
props.onChange(active);
|
||||||
|
}, 60000);
|
||||||
|
setTimerId(timer);
|
||||||
|
return () => {
|
||||||
|
if (timerId !== null) {
|
||||||
|
clearInterval(timerId);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}, [props.nameList.length]);
|
||||||
|
const btnClick = (ename: string) => {
|
||||||
|
if (timerId !== null) {
|
||||||
|
clearInterval(timerId);
|
||||||
|
}
|
||||||
|
setActiveName(ename);
|
||||||
|
props.onChange(ename); // 通知父组件
|
||||||
|
const newTimer = setInterval(() => {
|
||||||
|
let active = updateActiveName();
|
||||||
|
setActiveName(active);
|
||||||
|
props.onChange(active);
|
||||||
|
}, 60000);
|
||||||
|
setTimerId(newTimer);
|
||||||
|
};
|
||||||
|
return (
|
||||||
|
<div className="switch-button">
|
||||||
|
{props.nameList.map((item, index) => {
|
||||||
|
return (
|
||||||
|
<button
|
||||||
|
key={item.ename}
|
||||||
|
className={activeName === item.ename ? "active" : ""}
|
||||||
|
onClick={() => btnClick(item.ename)}
|
||||||
|
>
|
||||||
|
{item.name}
|
||||||
|
</button>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
export default SwitchButton;
|
13
src/page/LinePage2-1/Component/TitleBox/index.css
Normal file
13
src/page/LinePage2-1/Component/TitleBox/index.css
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
.title_box {
|
||||||
|
font-size: 24px;
|
||||||
|
color: #52fff1;
|
||||||
|
padding: 10px 0 0 15px;
|
||||||
|
}
|
||||||
|
.title_box img {
|
||||||
|
width: 33px;
|
||||||
|
height: 33px;
|
||||||
|
vertical-align: bottom;
|
||||||
|
margin-right: 3px;
|
||||||
|
position: relative;
|
||||||
|
top: 3px;
|
||||||
|
}
|
53
src/page/LinePage2-1/Component/TitleBox/index.tsx
Normal file
53
src/page/LinePage2-1/Component/TitleBox/index.tsx
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
import Defect from "./../../../assets/icon/defect.png";
|
||||||
|
import Alarm from "./../../../assets/icon/alarm.png";
|
||||||
|
import Finished from "./../../../assets/icon/finished.png";
|
||||||
|
import InputAndOutput from "./../../../assets/icon/inputAndOutput.png";
|
||||||
|
import Num from "./../../../assets/icon/num.png";
|
||||||
|
import Record from "./../../../assets/icon/record.png";
|
||||||
|
import "./index.css";
|
||||||
|
interface titleProps {
|
||||||
|
title: string;
|
||||||
|
}
|
||||||
|
function TitleBox(props: titleProps) {
|
||||||
|
const filteredTitles = () => {
|
||||||
|
switch (props.title) {
|
||||||
|
case "left_up":
|
||||||
|
return {
|
||||||
|
img: Defect,
|
||||||
|
title: "工段报废汇总",
|
||||||
|
};
|
||||||
|
case "left_down":
|
||||||
|
return {
|
||||||
|
img: Record,
|
||||||
|
title: "工序报废情况",
|
||||||
|
};
|
||||||
|
case "center_down_left":
|
||||||
|
return {
|
||||||
|
img: Alarm,
|
||||||
|
title: "异常报警",
|
||||||
|
};
|
||||||
|
case "center_down_right":
|
||||||
|
return {
|
||||||
|
img: Finished,
|
||||||
|
title: "工段成品率",
|
||||||
|
};
|
||||||
|
case "right_up":
|
||||||
|
return {
|
||||||
|
img: Num,
|
||||||
|
title: "各工段总投入和产出",
|
||||||
|
};
|
||||||
|
default:
|
||||||
|
return {
|
||||||
|
img: InputAndOutput,
|
||||||
|
title: "当前产线投入和产出",
|
||||||
|
};
|
||||||
|
}
|
||||||
|
};
|
||||||
|
return (
|
||||||
|
<div className="title_box">
|
||||||
|
<img src={filteredTitles().img} alt="title" />
|
||||||
|
<span>{filteredTitles().title}</span>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
export default TitleBox;
|
250
src/page/LinePage2-1/Left/LeftDown.tsx
Normal file
250
src/page/LinePage2-1/Left/LeftDown.tsx
Normal file
@ -0,0 +1,250 @@
|
|||||||
|
import ReactECharts from "echarts-for-react";
|
||||||
|
import TitleBox from "../Component/TitleBox";
|
||||||
|
import SwitchButton from "../Component/SwitchButton";
|
||||||
|
import ScrollBoard from "./../../Component/ScrollBoard";
|
||||||
|
import { useState } from "react";
|
||||||
|
import getOptions from "../../Component/BarChart/chart.config";
|
||||||
|
import {useAppSelector} from "./../../../store/hooks"
|
||||||
|
import {selectLine2Before} from "./../../../store/LinePageSlice"
|
||||||
|
function LeftDown() {
|
||||||
|
const data = useAppSelector(selectLine2Before);
|
||||||
|
// console.log('页面数据:',data)
|
||||||
|
const nameList = [
|
||||||
|
{ name: "表单", ename: "table" },
|
||||||
|
{ name: "柱状", ename: "chart" },
|
||||||
|
];
|
||||||
|
const [activeName, setActiveName] = useState<string>(nameList[0].ename);
|
||||||
|
const handleButtonChange = (activeName: string) => {
|
||||||
|
setActiveName(activeName);
|
||||||
|
};
|
||||||
|
const configDay = {
|
||||||
|
header: ["序号", "工序类型", "报废数量"],
|
||||||
|
headerHeight: 30,
|
||||||
|
rowNum: 4,
|
||||||
|
align: ["center", "left", "left"],
|
||||||
|
headerBGC: "rgba(79, 114, 136, 0.3)",
|
||||||
|
oddRowBGC: "rgba(79, 114, 136, 0.3)",
|
||||||
|
evenRowBGC: "rgba(76, 97, 123, 0.1)",
|
||||||
|
columnWidth: [73, 200, 107],
|
||||||
|
data: [
|
||||||
|
["1", "磨边后", 224],
|
||||||
|
["2", "包装1", 322],
|
||||||
|
["3", "包装2", 66],
|
||||||
|
],
|
||||||
|
};
|
||||||
|
const configWeek = {
|
||||||
|
header: ["序号", "工序类型", "报废数量"],
|
||||||
|
headerHeight: 30,
|
||||||
|
rowNum: 4,
|
||||||
|
align: ["center", "left", "left"],
|
||||||
|
headerBGC: "rgba(79, 114, 136, 0.3)",
|
||||||
|
oddRowBGC: "rgba(79, 114, 136, 0.3)",
|
||||||
|
evenRowBGC: "rgba(76, 97, 123, 0.1)",
|
||||||
|
columnWidth: [73, 200, 107],
|
||||||
|
data: [
|
||||||
|
["1", "磨边后", 1119],
|
||||||
|
["2", "包装1", 1798],
|
||||||
|
["3", "包装2", 435],
|
||||||
|
],
|
||||||
|
};
|
||||||
|
const configMonth = {
|
||||||
|
header: ["序号", "工序类型", "报废数量"],
|
||||||
|
headerHeight: 30,
|
||||||
|
rowNum: 4,
|
||||||
|
align: ["center", "left", "left"],
|
||||||
|
headerBGC: "rgba(79, 114, 136, 0.3)",
|
||||||
|
oddRowBGC: "rgba(79, 114, 136, 0.3)",
|
||||||
|
evenRowBGC: "rgba(76, 97, 123, 0.1)",
|
||||||
|
columnWidth: [73, 200, 107],
|
||||||
|
data: [
|
||||||
|
["1", "磨边后", 5004],
|
||||||
|
["2", "包装1", 9122],
|
||||||
|
["3", "包装2", 1924],
|
||||||
|
],
|
||||||
|
};
|
||||||
|
const color1 = ["#9DD5FF", "#1295FF"];
|
||||||
|
const color2 = ["#85F6E9", "#2EC6B4"];
|
||||||
|
// @ts-ignore
|
||||||
|
let xData1: string[] = [];
|
||||||
|
let xData2: string[] = [];
|
||||||
|
let xData3: string[] = [];
|
||||||
|
let dataProps1: number[] = [];
|
||||||
|
let dataProps2: number[] = [];
|
||||||
|
let dataProps3: number[] = [];
|
||||||
|
let arr1: any = [];
|
||||||
|
let arr2: any = [];
|
||||||
|
let arr3: any = [];
|
||||||
|
// @ts-ignore
|
||||||
|
if (data.todayProductionScraps && data.todayProductionScraps.length > 0) {
|
||||||
|
// @ts-ignore
|
||||||
|
data.todayProductionScraps.map((item,index)=>{
|
||||||
|
let arrInner = [];
|
||||||
|
arrInner.push(index+1,item.sectionName,item.scrapNum || 0);
|
||||||
|
arr1.push(arrInner);
|
||||||
|
xData1.push(item.sectionName);
|
||||||
|
dataProps1.push(item.scrapNum || 0);
|
||||||
|
})
|
||||||
|
}else{
|
||||||
|
dataProps1 = []
|
||||||
|
}
|
||||||
|
// @ts-ignore
|
||||||
|
if (data.weekProductionScraps && data.weekProductionScraps.length > 0) {
|
||||||
|
// @ts-ignore
|
||||||
|
data.weekProductionScraps.map((item,index)=>{
|
||||||
|
let arrInner = [];
|
||||||
|
arrInner.push(index+1,item.sectionName,item.scrapNum || 0);
|
||||||
|
arr2.push(arrInner);
|
||||||
|
xData2.push(item.sectionName);
|
||||||
|
dataProps2.push(item.scrapNum || 0);
|
||||||
|
})
|
||||||
|
}else{
|
||||||
|
dataProps2 = []
|
||||||
|
}
|
||||||
|
// @ts-ignore
|
||||||
|
if (data.monthProductionScraps && data.monthProductionScraps.length > 0) {
|
||||||
|
// @ts-ignore
|
||||||
|
data.monthProductionScraps.map((item,index)=>{
|
||||||
|
let arrInner = [];
|
||||||
|
arrInner.push(index+1,item.sectionName,item.scrapNum || 0);
|
||||||
|
arr3.push(arrInner);
|
||||||
|
xData3.push(item.sectionName);
|
||||||
|
dataProps3.push(item.scrapNum || 0);
|
||||||
|
})
|
||||||
|
}else{
|
||||||
|
dataProps3 = []
|
||||||
|
}
|
||||||
|
configDay.data = arr1;
|
||||||
|
configWeek.data = arr2;
|
||||||
|
configMonth.data = arr3;
|
||||||
|
const options1 = getOptions(dataProps1,xData1, color1);
|
||||||
|
const options2 = getOptions(dataProps2,xData2, color2);
|
||||||
|
const options3 = getOptions(dataProps3,xData3, color1);
|
||||||
|
return (
|
||||||
|
<div className="left_down">
|
||||||
|
<TitleBox title={"left_down"} />
|
||||||
|
<div className="left_up_switch">
|
||||||
|
<SwitchButton nameList={nameList} onChange={handleButtonChange} />
|
||||||
|
</div>
|
||||||
|
<div style={{ padding: "10px", height: "555px" }}>
|
||||||
|
<div className="left_down_title flex-row">
|
||||||
|
<div className="left_down_box1 flex-col" />
|
||||||
|
<span className="left_down_text">当天</span>
|
||||||
|
<div className="left_down_box2 flex-col" />
|
||||||
|
</div>
|
||||||
|
<div className="left_down_content">
|
||||||
|
{activeName === "table" ? (
|
||||||
|
arr1.length > 0 ? <ScrollBoard
|
||||||
|
config={configDay}
|
||||||
|
style={{ width: "380px", height: "150px" }}
|
||||||
|
/>:(<p
|
||||||
|
style={{
|
||||||
|
color: "#cccf",
|
||||||
|
fontSize: "24px",
|
||||||
|
userSelect: "none",
|
||||||
|
textAlign: "center",
|
||||||
|
paddingTop: "50px",
|
||||||
|
margin:0
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
暂无数据
|
||||||
|
</p>)
|
||||||
|
) : dataProps1.length>0 ? (
|
||||||
|
<ReactECharts option={options1} style={{ height: "100%" }} />
|
||||||
|
) : (
|
||||||
|
<p
|
||||||
|
style={{
|
||||||
|
color: "#cccf",
|
||||||
|
fontSize: "24px",
|
||||||
|
userSelect: "none",
|
||||||
|
textAlign: "center",
|
||||||
|
paddingTop: "50px",
|
||||||
|
margin:0
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
暂无数据
|
||||||
|
</p>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
<div className="left_down_title flex-row">
|
||||||
|
<div className="left_down_box1 flex-col" />
|
||||||
|
<span className="left_down_text">本周</span>
|
||||||
|
<div className="left_down_box2 flex-col" />
|
||||||
|
</div>
|
||||||
|
<div className="left_down_content">
|
||||||
|
{activeName === "table" ? (
|
||||||
|
arr2.length > 0 ? <ScrollBoard
|
||||||
|
config={configWeek}
|
||||||
|
style={{ width: "380px", height: "150px" }}
|
||||||
|
/>:(<p
|
||||||
|
style={{
|
||||||
|
color: "#cccf",
|
||||||
|
fontSize: "24px",
|
||||||
|
userSelect: "none",
|
||||||
|
textAlign: "center",
|
||||||
|
paddingTop: "50px",
|
||||||
|
margin:0
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
暂无数据
|
||||||
|
</p>)
|
||||||
|
) : dataProps2.length>0 ? (
|
||||||
|
<ReactECharts option={options2} style={{ height: "100%" }} />
|
||||||
|
) : (
|
||||||
|
<p
|
||||||
|
style={{
|
||||||
|
color: "#cccf",
|
||||||
|
fontSize: "24px",
|
||||||
|
userSelect: "none",
|
||||||
|
textAlign: "center",
|
||||||
|
paddingTop: "50px",
|
||||||
|
margin:0
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
暂无数据
|
||||||
|
</p>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
<div className="left_down_title flex-row">
|
||||||
|
<div className="left_down_box1 flex-col" />
|
||||||
|
<span className="left_down_text">本月</span>
|
||||||
|
<div className="left_down_box2 flex-col" />
|
||||||
|
</div>
|
||||||
|
<div className="left_down_content">
|
||||||
|
{activeName === "table" ? (
|
||||||
|
arr3.length > 0 ? <ScrollBoard
|
||||||
|
config={configMonth}
|
||||||
|
style={{ width: "380px", height: "150px" }}
|
||||||
|
/>:(<p
|
||||||
|
style={{
|
||||||
|
color: "#cccf",
|
||||||
|
fontSize: "24px",
|
||||||
|
userSelect: "none",
|
||||||
|
textAlign: "center",
|
||||||
|
paddingTop: "50px",
|
||||||
|
margin:0
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
暂无数据
|
||||||
|
</p>)
|
||||||
|
) : dataProps3.length>0 ? (
|
||||||
|
<ReactECharts option={options3} style={{ height: "100%" }} />
|
||||||
|
) : (
|
||||||
|
<p
|
||||||
|
style={{
|
||||||
|
color: "#cccf",
|
||||||
|
fontSize: "24px",
|
||||||
|
userSelect: "none",
|
||||||
|
textAlign: "center",
|
||||||
|
paddingTop: "50px",
|
||||||
|
margin:0
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
暂无数据
|
||||||
|
</p>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
export default LeftDown;
|
268
src/page/LinePage2-1/Left/LeftUp.tsx
Normal file
268
src/page/LinePage2-1/Left/LeftUp.tsx
Normal file
@ -0,0 +1,268 @@
|
|||||||
|
import ReactECharts from "echarts-for-react";
|
||||||
|
import TitleBox from "../Component/TitleBox";
|
||||||
|
import SwitchButton from "../Component/SwitchButton";
|
||||||
|
import getOptions from "../../Component/SummaryBarChart/chart.config";
|
||||||
|
import { useState } from "react";
|
||||||
|
import {useAppSelector} from "./../../../store/hooks"
|
||||||
|
import {selectLine2Before} from "./../../../store/LinePageSlice"
|
||||||
|
function LeftUp() {
|
||||||
|
const data = useAppSelector(selectLine2Before);
|
||||||
|
// 假数据
|
||||||
|
const dataSource = {
|
||||||
|
day: {
|
||||||
|
xData: [],
|
||||||
|
series: [] as { data: number[]; type: string; stack: string; name: any; barWidth?: number; label: { show: boolean; position: string; color: string;formatter?:any }; }[],
|
||||||
|
},
|
||||||
|
week: {
|
||||||
|
xData: [],
|
||||||
|
series: [] as { data: number[]; type: string; stack: string; name: any; barWidth?: number; label: { show: boolean; position: string; color: string;formatter?:any }; }[],
|
||||||
|
},
|
||||||
|
month: {
|
||||||
|
xData: [],
|
||||||
|
series: [] as { data: number[]; type: string; stack: string; name: any; barWidth?: number; label: { show: boolean; position: string; color: string;formatter?:any }; }[],
|
||||||
|
},
|
||||||
|
};
|
||||||
|
const nameList = [
|
||||||
|
{ name: "天", ename: "day" },
|
||||||
|
{ name: "周", ename: "week" },
|
||||||
|
{ name: "月", ename: "month" },
|
||||||
|
];
|
||||||
|
const [activeName, setActiveName] = useState<string>(nameList[0].ename);
|
||||||
|
let chartData = (dataSource as { [key: string]: any })[activeName];
|
||||||
|
const handleButtonChange = (activeName: string) => {
|
||||||
|
setActiveName(activeName);
|
||||||
|
};
|
||||||
|
// @ts-ignore
|
||||||
|
if (data.todayAllProductionScraps && Object.keys(data.todayAllProductionScraps).length > 0) {
|
||||||
|
let sum: number[] = [];
|
||||||
|
// 生成obj
|
||||||
|
// @ts-ignore
|
||||||
|
data.scrapBars.map((item,index) => {
|
||||||
|
let obj = {
|
||||||
|
data: [],
|
||||||
|
type: "bar",
|
||||||
|
stack: "a",
|
||||||
|
name: item,
|
||||||
|
barWidth: 14,
|
||||||
|
label: {
|
||||||
|
show: true,
|
||||||
|
position: "right",
|
||||||
|
color: "inherit",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
dataSource.day.series.push(obj)
|
||||||
|
})
|
||||||
|
// @ts-ignore
|
||||||
|
dataSource.day.xData = Object.keys(data.todayAllProductionScraps)
|
||||||
|
dataSource.day.xData.sort((a,b)=>{// 保证横坐标是有序的
|
||||||
|
// @ts-ignore
|
||||||
|
const lastDigitA = parseInt(a[a.length - 1], 10);
|
||||||
|
// @ts-ignore
|
||||||
|
const lastDigitB = parseInt(b[b.length - 1], 10);
|
||||||
|
return lastDigitA - lastDigitB;
|
||||||
|
})
|
||||||
|
for (let k = 0; k < dataSource.day.xData.length; k++) {
|
||||||
|
let item = dataSource.day.xData[k];
|
||||||
|
let sumIner = 0
|
||||||
|
for(let i = 0;i < dataSource.day.series.length;i++){
|
||||||
|
let itemSeries = dataSource.day.series[i]
|
||||||
|
// @ts-ignore
|
||||||
|
data.todayAllProductionScraps[item].map((itemInner,indexInner)=>{
|
||||||
|
// @ts-ignore
|
||||||
|
if (itemInner.sectionName.indexOf(itemSeries.name)!==-1) {
|
||||||
|
// @ts-ignore
|
||||||
|
itemSeries.data.push(itemInner.scrapNum || 0)
|
||||||
|
sumIner += itemInner.scrapNum || 0
|
||||||
|
return
|
||||||
|
}
|
||||||
|
})
|
||||||
|
if (itemSeries.data.length === k) {
|
||||||
|
itemSeries.data.push(0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
sum.push(sumIner)
|
||||||
|
}
|
||||||
|
dataSource.day.series.push({
|
||||||
|
data: sum,
|
||||||
|
type: "bar",
|
||||||
|
stack: "a",
|
||||||
|
name: "",
|
||||||
|
label: {
|
||||||
|
show: true,
|
||||||
|
position: "top",
|
||||||
|
color: "#fff",
|
||||||
|
formatter: function (params: any) {
|
||||||
|
return sum[params.dataIndex];
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}else{
|
||||||
|
dataSource.day.xData = []
|
||||||
|
dataSource.day.series = []
|
||||||
|
}
|
||||||
|
// @ts-ignore
|
||||||
|
if (data.weekAllProductionScraps && Object.keys(data.weekAllProductionScraps).length > 0) {
|
||||||
|
let sum: number[] = [];
|
||||||
|
// 生成obj
|
||||||
|
// @ts-ignore
|
||||||
|
data.scrapBars.map((item,index) => {
|
||||||
|
let obj = {
|
||||||
|
data: [],
|
||||||
|
type: "bar",
|
||||||
|
stack: "a",
|
||||||
|
name: item,
|
||||||
|
barWidth: 14,
|
||||||
|
label: {
|
||||||
|
show: true,
|
||||||
|
position: "right",
|
||||||
|
color: "inherit",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
dataSource.week.series.push(obj)
|
||||||
|
})
|
||||||
|
// @ts-ignore
|
||||||
|
dataSource.week.xData = Object.keys(data.weekAllProductionScraps)
|
||||||
|
dataSource.week.xData.sort((a,b)=>{// 保证横坐标是有序的
|
||||||
|
// @ts-ignore
|
||||||
|
const lastDigitA = parseInt(a[a.length - 1], 10);
|
||||||
|
// @ts-ignore
|
||||||
|
const lastDigitB = parseInt(b[b.length - 1], 10);
|
||||||
|
return lastDigitA - lastDigitB;
|
||||||
|
})
|
||||||
|
for (let k = 0; k < dataSource.week.xData.length; k++) {
|
||||||
|
let item = dataSource.week.xData[k];
|
||||||
|
let sumIner = 0
|
||||||
|
for(let i = 0;i < dataSource.week.series.length;i++){
|
||||||
|
let itemSeries = dataSource.week.series[i]
|
||||||
|
// @ts-ignore
|
||||||
|
data.weekAllProductionScraps[item].map((itemInner,indexInner)=>{
|
||||||
|
// @ts-ignore
|
||||||
|
if (itemInner.sectionName.indexOf(itemSeries.name)!==-1) {
|
||||||
|
// @ts-ignore
|
||||||
|
itemSeries.data.push(itemInner.scrapNum || 0)
|
||||||
|
sumIner += itemInner.scrapNum || 0
|
||||||
|
return
|
||||||
|
}
|
||||||
|
})
|
||||||
|
if (itemSeries.data.length === k) {
|
||||||
|
itemSeries.data.push(0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
sum.push(sumIner)
|
||||||
|
}
|
||||||
|
dataSource.week.series.push({
|
||||||
|
data: sum,
|
||||||
|
type: "bar",
|
||||||
|
stack: "a",
|
||||||
|
name: "",
|
||||||
|
label: {
|
||||||
|
show: true,
|
||||||
|
position: "top",
|
||||||
|
color: "#fff",
|
||||||
|
formatter: function (params: any) {
|
||||||
|
return sum[params.dataIndex];
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}else{
|
||||||
|
dataSource.week.xData = []
|
||||||
|
dataSource.week.series = []
|
||||||
|
}
|
||||||
|
// @ts-ignore
|
||||||
|
if (data.monthAllProductionScraps && Object.keys(data.monthAllProductionScraps).length > 0) {
|
||||||
|
let sum: number[] = [];
|
||||||
|
// 生成obj
|
||||||
|
// @ts-ignore
|
||||||
|
data.scrapBars.map((item,index) => {
|
||||||
|
let obj = {
|
||||||
|
data: [],
|
||||||
|
type: "bar",
|
||||||
|
stack: "a",
|
||||||
|
name: item,
|
||||||
|
barWidth: 14,
|
||||||
|
label: {
|
||||||
|
show: true,
|
||||||
|
position: "right",
|
||||||
|
color: "inherit",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
dataSource.month.series.push(obj)
|
||||||
|
})
|
||||||
|
// @ts-ignore
|
||||||
|
dataSource.month.xData = Object.keys(data.monthAllProductionScraps)
|
||||||
|
dataSource.month.xData.sort((a,b)=>{// 保证横坐标是有序的
|
||||||
|
// @ts-ignore
|
||||||
|
const lastDigitA = parseInt(a[a.length - 1], 10);
|
||||||
|
// @ts-ignore
|
||||||
|
const lastDigitB = parseInt(b[b.length - 1], 10);
|
||||||
|
return lastDigitA - lastDigitB;
|
||||||
|
})
|
||||||
|
for (let k = 0; k < dataSource.month.xData.length; k++) {
|
||||||
|
let item = dataSource.month.xData[k];
|
||||||
|
let sumIner = 0
|
||||||
|
for(let i = 0;i < dataSource.month.series.length;i++){
|
||||||
|
let itemSeries = dataSource.month.series[i]
|
||||||
|
// @ts-ignore
|
||||||
|
data.monthAllProductionScraps[item].map((itemInner,indexInner)=>{
|
||||||
|
// @ts-ignore
|
||||||
|
if (itemInner.sectionName.indexOf(itemSeries.name)!==-1) {
|
||||||
|
// @ts-ignore
|
||||||
|
itemSeries.data.push(itemInner.scrapNum || 0)
|
||||||
|
sumIner += itemInner.scrapNum || 0
|
||||||
|
return
|
||||||
|
}
|
||||||
|
})
|
||||||
|
if (itemSeries.data.length === k) {
|
||||||
|
itemSeries.data.push(0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
sum.push(sumIner)
|
||||||
|
}
|
||||||
|
dataSource.month.series.push({
|
||||||
|
data: sum,
|
||||||
|
type: "bar",
|
||||||
|
stack: "a",
|
||||||
|
name: "",
|
||||||
|
label: {
|
||||||
|
show: true,
|
||||||
|
position: "top",
|
||||||
|
color: "#fff",
|
||||||
|
formatter: function (params: any) {
|
||||||
|
return sum[params.dataIndex];
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}else{
|
||||||
|
dataSource.month.xData = []
|
||||||
|
dataSource.month.series = []
|
||||||
|
}
|
||||||
|
const options = getOptions(chartData);
|
||||||
|
console.log('dataSource',dataSource)
|
||||||
|
return (
|
||||||
|
<div className="left_up">
|
||||||
|
<TitleBox title={"left_up"} />
|
||||||
|
<div className="left_up_switch">
|
||||||
|
<SwitchButton nameList={nameList} onChange={handleButtonChange} />
|
||||||
|
</div>
|
||||||
|
{// @ts-ignore
|
||||||
|
dataSource[activeName].xData.length>0 ? (
|
||||||
|
<div className="left_up_chart">
|
||||||
|
{<ReactECharts option={options} style={{ height: "100%" }} />}
|
||||||
|
</div>
|
||||||
|
):(
|
||||||
|
<p
|
||||||
|
style={{
|
||||||
|
color: "#cccf",
|
||||||
|
fontSize: "24px",
|
||||||
|
userSelect: "none",
|
||||||
|
textAlign: "center",
|
||||||
|
paddingTop: "72px",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
暂无数据
|
||||||
|
</p>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
export default LeftUp;
|
11
src/page/LinePage2-1/Left/index.tsx
Normal file
11
src/page/LinePage2-1/Left/index.tsx
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
import LeftUp from "./LeftUp";
|
||||||
|
import LeftDown from "./LeftDown";
|
||||||
|
function Left() {
|
||||||
|
return (
|
||||||
|
<div className="group_left flex-col">
|
||||||
|
<LeftUp />
|
||||||
|
<LeftDown />
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
export default Left;
|
273
src/page/LinePage2-1/Right/RightDown.tsx
Normal file
273
src/page/LinePage2-1/Right/RightDown.tsx
Normal file
@ -0,0 +1,273 @@
|
|||||||
|
import ReactECharts from "echarts-for-react";
|
||||||
|
import TitleBox from "../Component/TitleBox";
|
||||||
|
import SwitchButton from "../Component/SwitchButton";
|
||||||
|
import ScrollBoard from "./../../Component/ScrollBoard";
|
||||||
|
import { useState } from "react";
|
||||||
|
import getOptions from "../../Component/LineChartRight/chart.config";
|
||||||
|
import {useAppSelector} from "./../../../store/hooks"
|
||||||
|
import {selectLine2Before} from "./../../../store/LinePageSlice"
|
||||||
|
import dayjs from "dayjs";
|
||||||
|
function RightDown() {
|
||||||
|
const data = useAppSelector(selectLine2Before);
|
||||||
|
// console.log('页面数据:',data)
|
||||||
|
// 假数据
|
||||||
|
let tempData = [
|
||||||
|
{
|
||||||
|
type: "day",
|
||||||
|
data: {
|
||||||
|
time: [] as string[],
|
||||||
|
input: [] as number[],
|
||||||
|
output: [] as number[],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: "week",
|
||||||
|
data: {
|
||||||
|
time: [] as string[],
|
||||||
|
input: [] as number[],
|
||||||
|
output: [] as number[],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: "month",
|
||||||
|
data: {
|
||||||
|
time: [] as string[],
|
||||||
|
input: [] as number[],
|
||||||
|
output: [] as number[],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
];
|
||||||
|
const nameList = [
|
||||||
|
{ name: "表单", ename: "table" },
|
||||||
|
{ name: "折线", ename: "chart" },
|
||||||
|
];
|
||||||
|
const [activeName, setActiveName] = useState<string>(nameList[0].ename);
|
||||||
|
const handleButtonChange = (activeName: string) => {
|
||||||
|
setActiveName(activeName);
|
||||||
|
};
|
||||||
|
const configDay = {
|
||||||
|
header: ["时间", "投入数量", "产出数量"],
|
||||||
|
headerHeight: 30,
|
||||||
|
rowNum: 5,
|
||||||
|
headerBGC: "rgba(79, 114, 136, 0.3)",
|
||||||
|
oddRowBGC: "rgba(79, 114, 136, 0.3)",
|
||||||
|
evenRowBGC: "rgba(76, 97, 123, 0.1)",
|
||||||
|
columnWidth: [120, 130, 130],
|
||||||
|
data: [],
|
||||||
|
};
|
||||||
|
const configWeek = {
|
||||||
|
header: ["时间", "投入数量", "产出数量"],
|
||||||
|
headerHeight: 30,
|
||||||
|
rowNum: 5,
|
||||||
|
headerBGC: "rgba(79, 114, 136, 0.3)",
|
||||||
|
oddRowBGC: "rgba(79, 114, 136, 0.3)",
|
||||||
|
evenRowBGC: "rgba(76, 97, 123, 0.1)",
|
||||||
|
columnWidth: [120, 130, 130],
|
||||||
|
data: [],
|
||||||
|
};
|
||||||
|
const configMonth = {
|
||||||
|
header: ["时间", "投入数量", "产出数量"],
|
||||||
|
headerHeight: 30,
|
||||||
|
rowNum: 5,
|
||||||
|
headerBGC: "rgba(79, 114, 136, 0.3)",
|
||||||
|
oddRowBGC: "rgba(79, 114, 136, 0.3)",
|
||||||
|
evenRowBGC: "rgba(76, 97, 123, 0.1)",
|
||||||
|
columnWidth: [120, 130, 130],
|
||||||
|
data: [],
|
||||||
|
};
|
||||||
|
let arr1: any = [];
|
||||||
|
let arr2: any = [];
|
||||||
|
let arr3: any = [];
|
||||||
|
// @ts-ignore
|
||||||
|
if (data.todayProductionDets && data.todayProductionDets.length > 0) {
|
||||||
|
// @ts-ignore
|
||||||
|
data.todayProductionDets.map((item,index)=>{
|
||||||
|
let arrInner = [];
|
||||||
|
arrInner.push(dayjs(item.recTime).format("HH:mm"),item.inputNum,item.outputNum);
|
||||||
|
arr1.push(arrInner);
|
||||||
|
tempData[0].data.time.push(dayjs(item.recTime).format("HH:mm"));
|
||||||
|
tempData[0].data.input.push(item.inputNum);
|
||||||
|
tempData[0].data.output.push(item.outputNum);
|
||||||
|
})
|
||||||
|
}else{
|
||||||
|
tempData[0].data.time = []
|
||||||
|
tempData[0].data.input = []
|
||||||
|
tempData[0].data.output = []
|
||||||
|
}
|
||||||
|
// @ts-ignore
|
||||||
|
if (data.weekProductionDets && data.weekProductionDets.length > 0) {
|
||||||
|
// @ts-ignore
|
||||||
|
data.weekProductionDets.map((item,index)=>{
|
||||||
|
let arrInner = [];
|
||||||
|
arrInner.push(dayjs(item.recTime).format("YYYY/MM/DD"),item.inputNum,item.outputNum);
|
||||||
|
arr2.push(arrInner);
|
||||||
|
tempData[1].data.time.push(dayjs(item.recTime).format("MM.DD"));
|
||||||
|
tempData[1].data.input.push(item.inputNum);
|
||||||
|
tempData[1].data.output.push(item.outputNum);
|
||||||
|
})
|
||||||
|
}else{
|
||||||
|
tempData[1].data.time = []
|
||||||
|
tempData[1].data.input = []
|
||||||
|
tempData[1].data.output = []
|
||||||
|
}
|
||||||
|
// @ts-ignore
|
||||||
|
if (data.monthProductionDets && data.monthProductionDets.length > 0) {
|
||||||
|
// @ts-ignore
|
||||||
|
data.monthProductionDets.map((item,index)=>{
|
||||||
|
let arrInner = [];
|
||||||
|
arrInner.push(dayjs(item.recTime).format("YYYY/MM/DD"),item.inputNum,item.outputNum);
|
||||||
|
arr3.push(arrInner);
|
||||||
|
tempData[2].data.time.push(dayjs(item.recTime).format("MM.DD"));
|
||||||
|
tempData[2].data.input.push(item.inputNum);
|
||||||
|
tempData[2].data.output.push(item.outputNum);
|
||||||
|
})
|
||||||
|
}else{
|
||||||
|
tempData[2].data.time = []
|
||||||
|
tempData[2].data.input = []
|
||||||
|
tempData[2].data.output = []
|
||||||
|
}
|
||||||
|
configDay.data = arr1;
|
||||||
|
configWeek.data = arr2;
|
||||||
|
configMonth.data = arr3;
|
||||||
|
|
||||||
|
const chartData1 = tempData[0].data;
|
||||||
|
const chartData2 = tempData[1].data;
|
||||||
|
const chartData3 = tempData[2].data;
|
||||||
|
const options1 = getOptions(chartData1);
|
||||||
|
const options2 = getOptions(chartData2);
|
||||||
|
const options3 = getOptions(chartData3);
|
||||||
|
return (
|
||||||
|
<div className="right_down">
|
||||||
|
<TitleBox title={"right_down"} />
|
||||||
|
<div className="left_up_switch">
|
||||||
|
<SwitchButton nameList={nameList} onChange={handleButtonChange} />
|
||||||
|
</div>
|
||||||
|
<div style={{ padding: "10px", height: "628px" }}>
|
||||||
|
<div className="left_down_title flex-row">
|
||||||
|
<div className="left_down_box1 flex-col" />
|
||||||
|
<span className="left_down_text">当天</span>
|
||||||
|
<div className="left_down_box2 flex-col" />
|
||||||
|
</div>
|
||||||
|
<div className="right_down_content">
|
||||||
|
{activeName === "table" ? (
|
||||||
|
arr1.length>0?<ScrollBoard
|
||||||
|
config={configDay}
|
||||||
|
style={{ width: "380px", height: "180px" }}
|
||||||
|
/>:(
|
||||||
|
<p
|
||||||
|
style={{
|
||||||
|
color: "#cccf",
|
||||||
|
fontSize: "24px",
|
||||||
|
userSelect: "none",
|
||||||
|
textAlign: "center",
|
||||||
|
paddingTop: "50px",
|
||||||
|
margin:0
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
暂无数据
|
||||||
|
</p>
|
||||||
|
)
|
||||||
|
) : tempData[0].data.time.length>0 ? (
|
||||||
|
<ReactECharts option={options1} style={{ height: "100%" }} />
|
||||||
|
) : (
|
||||||
|
<p
|
||||||
|
style={{
|
||||||
|
color: "#cccf",
|
||||||
|
fontSize: "24px",
|
||||||
|
userSelect: "none",
|
||||||
|
textAlign: "center",
|
||||||
|
paddingTop: "50px",
|
||||||
|
margin:0
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
暂无数据
|
||||||
|
</p>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
<div className="left_down_title flex-row">
|
||||||
|
<div className="left_down_box1 flex-col" />
|
||||||
|
<span className="left_down_text">本周</span>
|
||||||
|
<div className="left_down_box2 flex-col" />
|
||||||
|
</div>
|
||||||
|
<div className="right_down_content">
|
||||||
|
{activeName === "table" ? (
|
||||||
|
arr2.length>0?<ScrollBoard
|
||||||
|
config={configWeek}
|
||||||
|
style={{ width: "380px", height: "180px" }}
|
||||||
|
/>:(
|
||||||
|
<p
|
||||||
|
style={{
|
||||||
|
color: "#cccf",
|
||||||
|
fontSize: "24px",
|
||||||
|
userSelect: "none",
|
||||||
|
textAlign: "center",
|
||||||
|
paddingTop: "50px",
|
||||||
|
margin:0
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
暂无数据
|
||||||
|
</p>
|
||||||
|
)
|
||||||
|
) : tempData[1].data.time.length>0 ? (
|
||||||
|
<ReactECharts option={options2} style={{ height: "100%" }} />
|
||||||
|
) : (
|
||||||
|
<p
|
||||||
|
style={{
|
||||||
|
color: "#cccf",
|
||||||
|
fontSize: "24px",
|
||||||
|
userSelect: "none",
|
||||||
|
textAlign: "center",
|
||||||
|
paddingTop: "50px",
|
||||||
|
margin:0
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
暂无数据
|
||||||
|
</p>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
<div className="left_down_title flex-row">
|
||||||
|
<div className="left_down_box1 flex-col" />
|
||||||
|
<span className="left_down_text">本月</span>
|
||||||
|
<div className="left_down_box2 flex-col" />
|
||||||
|
</div>
|
||||||
|
<div className="right_down_content">
|
||||||
|
{activeName === "table" ? (
|
||||||
|
arr3.length>0?<ScrollBoard
|
||||||
|
config={configMonth}
|
||||||
|
style={{ width: "380px", height: "180px" }}
|
||||||
|
/>:(
|
||||||
|
<p
|
||||||
|
style={{
|
||||||
|
color: "#cccf",
|
||||||
|
fontSize: "24px",
|
||||||
|
userSelect: "none",
|
||||||
|
textAlign: "center",
|
||||||
|
paddingTop: "50px",
|
||||||
|
margin:0
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
暂无数据
|
||||||
|
</p>
|
||||||
|
)
|
||||||
|
) : tempData[2].data.time.length>0 ? (
|
||||||
|
<ReactECharts option={options3} style={{ height: "100%" }} />
|
||||||
|
) : (
|
||||||
|
<p
|
||||||
|
style={{
|
||||||
|
color: "#cccf",
|
||||||
|
fontSize: "24px",
|
||||||
|
userSelect: "none",
|
||||||
|
textAlign: "center",
|
||||||
|
paddingTop: "50px",
|
||||||
|
margin:0
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
暂无数据
|
||||||
|
</p>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
export default RightDown;
|
52
src/page/LinePage2-1/Right/RightUp.tsx
Normal file
52
src/page/LinePage2-1/Right/RightUp.tsx
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
import TitleBox from "../Component/TitleBox";
|
||||||
|
import ScrollBoard from "./../../Component/ScrollBoard";
|
||||||
|
import {useAppSelector} from "./../../../store/hooks"
|
||||||
|
import {selectLine2Before} from "./../../../store/LinePageSlice"
|
||||||
|
function RightUp() {
|
||||||
|
const data = useAppSelector(selectLine2Before);
|
||||||
|
const config = {
|
||||||
|
header: ["序号", "工段名", "上片数据量", "成品下片数量"],
|
||||||
|
headerHeight: 32,
|
||||||
|
rowNum: 5,
|
||||||
|
align: ["center", "left", "left", "left"],
|
||||||
|
headerBGC: "rgba(79, 114, 136, 0.3)",
|
||||||
|
oddRowBGC: "rgba(79, 114, 136, 0.3)",
|
||||||
|
evenRowBGC: "rgba(76, 97, 123, 0.1)",
|
||||||
|
columnWidth: [55, 115, 100, 110],
|
||||||
|
data: [],
|
||||||
|
};
|
||||||
|
let arr:any = []
|
||||||
|
// @ts-ignore
|
||||||
|
if (data.sectionDet && data.sectionDet.length > 0) {
|
||||||
|
// @ts-ignore
|
||||||
|
data.sectionDet.map((item, index) => {
|
||||||
|
let arrInner = []
|
||||||
|
arrInner.push(index + 1, item.lineName, item.inputNum, item.outputNum)
|
||||||
|
arr.push(arrInner)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
config.data = arr
|
||||||
|
return (
|
||||||
|
<div className="right_up">
|
||||||
|
<TitleBox title={"right_up"} />
|
||||||
|
<div style={{ padding: "10px", height: "213px" }}>
|
||||||
|
{arr.length>0?<ScrollBoard
|
||||||
|
config={config}
|
||||||
|
style={{ width: "380px", height: "193px" }}
|
||||||
|
/>:(<p
|
||||||
|
style={{
|
||||||
|
color: "#cccf",
|
||||||
|
fontSize: "24px",
|
||||||
|
userSelect: "none",
|
||||||
|
textAlign: "center",
|
||||||
|
paddingTop: "50px",
|
||||||
|
margin:0
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
暂无数据
|
||||||
|
</p>)}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
export default RightUp;
|
12
src/page/LinePage2-1/Right/index.tsx
Normal file
12
src/page/LinePage2-1/Right/index.tsx
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
import RightDown from "./RightDown";
|
||||||
|
import RightUp from "./RightUp";
|
||||||
|
|
||||||
|
function Right() {
|
||||||
|
return (
|
||||||
|
<div className="group_right flex-col">
|
||||||
|
<RightUp />
|
||||||
|
<RightDown />
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
export default Right;
|
14
src/page/LinePage2-1/TopP.tsx
Normal file
14
src/page/LinePage2-1/TopP.tsx
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
import '../../lanhuapp/common.css';
|
||||||
|
import "./index.css";
|
||||||
|
|
||||||
|
function TopP() {
|
||||||
|
return (
|
||||||
|
<div className="flex-row">
|
||||||
|
<div className="block_top flex-row">
|
||||||
|
<div className='block_top_title'></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default TopP;
|
264
src/page/LinePage2-1/index.css
Normal file
264
src/page/LinePage2-1/index.css
Normal file
@ -0,0 +1,264 @@
|
|||||||
|
/* 顶部 */
|
||||||
|
.block_top {
|
||||||
|
width: 1920px;
|
||||||
|
height: 94px;
|
||||||
|
background: url(/public/svg/topback.svg) 100% no-repeat;
|
||||||
|
background-size: 100% 100%;
|
||||||
|
opacity: 1;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.block_top_title {
|
||||||
|
width: 651px;
|
||||||
|
height: 77px;
|
||||||
|
background: url(/public/png/topTiltle.png) 100% no-repeat;
|
||||||
|
background-size: 100% 100%;
|
||||||
|
margin-top: 18px;
|
||||||
|
}
|
||||||
|
/* 中部 */
|
||||||
|
.block_bottom {
|
||||||
|
width: 1920px;
|
||||||
|
height: 966px;
|
||||||
|
padding-top: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.group_left {
|
||||||
|
width: 402px;
|
||||||
|
height: 966px;
|
||||||
|
margin: 0 0 0 24px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.group_center {
|
||||||
|
width: 1041px;
|
||||||
|
height: 966px;
|
||||||
|
margin: 0 0 0 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.group_right {
|
||||||
|
width: 401px;
|
||||||
|
height: 966px;
|
||||||
|
margin-left: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.left_up {
|
||||||
|
width: 402px;
|
||||||
|
height: 332px;
|
||||||
|
background: url(../../../public/png/rect/lp_left_up.png) no-repeat;
|
||||||
|
background-size: 100% 100%;
|
||||||
|
background-position: 0 0;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
.left_down {
|
||||||
|
width: 402px;
|
||||||
|
height: 599px;
|
||||||
|
background: url(../../../public/png/rect/lp_left_down.png) no-repeat;
|
||||||
|
background-size: 100% 100%;
|
||||||
|
background-position: 0 0;
|
||||||
|
margin-top: 14px;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
.center_up {
|
||||||
|
width: 1041px;
|
||||||
|
height: 562px;
|
||||||
|
background: url(../../../public/png/rect/lp_center_up.png) no-repeat;
|
||||||
|
background-size: 100% 100%;
|
||||||
|
background-position: 0 0;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
.center_down {
|
||||||
|
width: 1041px;
|
||||||
|
height: 368px;
|
||||||
|
margin-top: 17px;
|
||||||
|
}
|
||||||
|
.center_down_inner {
|
||||||
|
width: 513px;
|
||||||
|
height: 366px;
|
||||||
|
background: url(../../../public/png/rect/lp_center_down.png) no-repeat;
|
||||||
|
background-size: 100% 100%;
|
||||||
|
background-position: 0 0;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
.center_down .left-box {
|
||||||
|
margin-right: 15px;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
.center_down .left-box .alarm_num_title {
|
||||||
|
position: absolute;
|
||||||
|
left: 220px;
|
||||||
|
top: 22px;
|
||||||
|
font-size: 13px;
|
||||||
|
letter-spacing: 3px;
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
.center_down .left-box .alarm_num {
|
||||||
|
color: #52fff1;
|
||||||
|
font-size: 40px;
|
||||||
|
text-align: center;
|
||||||
|
font-family: PingFangSC, PingFang SC;
|
||||||
|
}
|
||||||
|
.center_down .right_box .chart_box {
|
||||||
|
width: 100%;
|
||||||
|
height: 310px;
|
||||||
|
margin-top: 5px;
|
||||||
|
}
|
||||||
|
.right_up {
|
||||||
|
width: 401px;
|
||||||
|
height: 257px;
|
||||||
|
background: url(../../../public/png/rect/lp_right_up.png) no-repeat;
|
||||||
|
background-size: 100% 100%;
|
||||||
|
background-position: 0 0;
|
||||||
|
}
|
||||||
|
.right_down {
|
||||||
|
width: 401px;
|
||||||
|
height: 673px;
|
||||||
|
background: url(../../../public/png/rect/lp_right_down.png) no-repeat;
|
||||||
|
background-size: 100% 100%;
|
||||||
|
background-position: 0 0;
|
||||||
|
margin-top: 14px;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
.left_up_switch {
|
||||||
|
position: absolute;
|
||||||
|
right: 10px;
|
||||||
|
top: 12px;
|
||||||
|
}
|
||||||
|
.left_up_chart {
|
||||||
|
height: 275px;
|
||||||
|
margin-top: 10px;
|
||||||
|
}
|
||||||
|
/* 左侧 */
|
||||||
|
.left_down_title {
|
||||||
|
height: 18px;
|
||||||
|
justify-content: center;
|
||||||
|
margin-bottom: 4px;
|
||||||
|
}
|
||||||
|
.left_down_box1 {
|
||||||
|
width: 56px;
|
||||||
|
height: 13px;
|
||||||
|
background: url(/public/png/leftbar.png) 100% no-repeat;
|
||||||
|
background-size: 100% 100%;
|
||||||
|
margin-top: 2px;
|
||||||
|
}
|
||||||
|
.left_down_box2 {
|
||||||
|
width: 56px;
|
||||||
|
height: 13px;
|
||||||
|
background: url(/public/png/rightbar.png) 100% no-repeat;
|
||||||
|
background-size: 100% 100%;
|
||||||
|
margin: 2px 0 0 0px;
|
||||||
|
}
|
||||||
|
.left_down_text {
|
||||||
|
/*width: 40px;*/
|
||||||
|
height: 18px;
|
||||||
|
overflow-wrap: break-word;
|
||||||
|
color: rgba(1, 207, 204, 1);
|
||||||
|
font-size: 18px;
|
||||||
|
letter-spacing: 5px;
|
||||||
|
font-family: PingFangSC-Regular;
|
||||||
|
white-space: nowrap;
|
||||||
|
line-height: 18px;
|
||||||
|
margin-left: 18px;
|
||||||
|
margin-right: 16px;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
.left_down_content {
|
||||||
|
height: 160px;
|
||||||
|
/* padding-bottom: 5px; */
|
||||||
|
}
|
||||||
|
.right_down_content {
|
||||||
|
height: 185px;
|
||||||
|
/* padding-bottom: 5px; */
|
||||||
|
}
|
||||||
|
/* 滚动表格部分 */
|
||||||
|
.dv-scroll-board .header .header-item,
|
||||||
|
.dv-scroll-board .rows .ceil {
|
||||||
|
border-right: 1px solid #0d1728;
|
||||||
|
}
|
||||||
|
.dv-scroll-board .header .header-item:last-child,
|
||||||
|
.dv-scroll-board .rows .ceil:last-child {
|
||||||
|
border-right: none;
|
||||||
|
border: none;
|
||||||
|
}
|
||||||
|
/* chart图部分 */
|
||||||
|
.luoyang-chart-tooltip {
|
||||||
|
background: #0a2b4f77 !important;
|
||||||
|
border: none !important;
|
||||||
|
backdrop-filter: blur(12px);
|
||||||
|
}
|
||||||
|
|
||||||
|
.luoyang-chart-tooltip * {
|
||||||
|
color: #fff !important;
|
||||||
|
}
|
||||||
|
/* 三维页面部分 */
|
||||||
|
.center_up .model_name {
|
||||||
|
position: absolute;
|
||||||
|
left: 0px;
|
||||||
|
top: 0px;
|
||||||
|
z-index: 1000;
|
||||||
|
}
|
||||||
|
.center_up .model_info {
|
||||||
|
position: absolute;
|
||||||
|
left: 100px;
|
||||||
|
bottom: 0px;
|
||||||
|
z-index: 1000;
|
||||||
|
width: 841px;
|
||||||
|
height: 62px;
|
||||||
|
background: url(/public/png/lp/line_part.png) 100% no-repeat;
|
||||||
|
background-size: 100% 100%;
|
||||||
|
}
|
||||||
|
.center_up .model_info .reset_btn {
|
||||||
|
position: absolute;
|
||||||
|
top: 20px;
|
||||||
|
left: 40px;
|
||||||
|
width: 140px;
|
||||||
|
height: 40px;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
.center_up .model_info .title {
|
||||||
|
display: inline-block;
|
||||||
|
width: 361px;
|
||||||
|
text-align: center;
|
||||||
|
font-size: 32px;
|
||||||
|
color: #fff;
|
||||||
|
letter-spacing: 5px;
|
||||||
|
position: absolute;
|
||||||
|
left: 241px;
|
||||||
|
bottom: 10px;
|
||||||
|
}
|
||||||
|
.center_up .eq_detail_info {
|
||||||
|
position: absolute;
|
||||||
|
right: 0px;
|
||||||
|
bottom: 0px;
|
||||||
|
z-index: 1002;
|
||||||
|
width: 270px;
|
||||||
|
height: 110px;
|
||||||
|
background: url(/public/png/lp/eq_msg_detail.png) 100% no-repeat;
|
||||||
|
background-size: 100% 100%;
|
||||||
|
color: #fff;
|
||||||
|
padding: 15px 0 0 15px;
|
||||||
|
}
|
||||||
|
.center_up .eq_detail_info .left_name {
|
||||||
|
display: inline-block;
|
||||||
|
width: 95px;
|
||||||
|
height: 28px;
|
||||||
|
text-align: right;
|
||||||
|
font-size: 18px;
|
||||||
|
}
|
||||||
|
.center_up .eq_detail_info .right_value {
|
||||||
|
display: inline-block;
|
||||||
|
height: 28px;
|
||||||
|
font-size: 18px;
|
||||||
|
}
|
||||||
|
.center_up .eq_info {
|
||||||
|
position: absolute;
|
||||||
|
z-index: 1002;
|
||||||
|
background: url(/public/png/lp/eq_msg_always.png) 100% no-repeat;
|
||||||
|
background-size: 100% 100%;
|
||||||
|
color: #fff;
|
||||||
|
padding: 10px 15px;
|
||||||
|
}
|
||||||
|
.center_up .eq_info .eq_info_inner {
|
||||||
|
height: 24px;
|
||||||
|
font-size: 17px;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
38
src/page/LinePage2-1/index.tsx
Normal file
38
src/page/LinePage2-1/index.tsx
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
import React from "react";
|
||||||
|
import TopP from "./TopP";
|
||||||
|
import Left from "./Left";
|
||||||
|
import Right from "./Right";
|
||||||
|
import Center from "./Center";
|
||||||
|
import {useEffect} from 'react';
|
||||||
|
import {useNavigate} from "react-router-dom";
|
||||||
|
function LinePage() {
|
||||||
|
const navigate = useNavigate();
|
||||||
|
useEffect(() => {
|
||||||
|
const handleKeyDown = (event:any) => {
|
||||||
|
if (event.key === 'ArrowUp') {
|
||||||
|
console.log('LDPage向上键被按下');
|
||||||
|
navigate('/LD?lineId=2-1');
|
||||||
|
// 执行向上键的逻辑
|
||||||
|
} else if (event.key === 'ArrowDown') {
|
||||||
|
console.log('LDPage向下键被按下');
|
||||||
|
// 执行向下键的逻辑
|
||||||
|
navigate('/LD?lineId=2-1');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
window.addEventListener('keydown', handleKeyDown);
|
||||||
|
return () => {
|
||||||
|
window.removeEventListener('keydown', handleKeyDown);
|
||||||
|
};
|
||||||
|
});
|
||||||
|
return (
|
||||||
|
<React.Fragment>
|
||||||
|
<TopP />
|
||||||
|
<div className="block_bottom flex-row">
|
||||||
|
<Left />
|
||||||
|
<Center />
|
||||||
|
<Right />
|
||||||
|
</div>
|
||||||
|
</React.Fragment>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
export default LinePage;
|
213
src/page/LinePage2-2/Center/CenterDown.tsx
Normal file
213
src/page/LinePage2-2/Center/CenterDown.tsx
Normal file
@ -0,0 +1,213 @@
|
|||||||
|
import ReactECharts from "echarts-for-react";
|
||||||
|
import TitleBox from "../Component/TitleBox";
|
||||||
|
import ScrollBoard from "./../../Component/ScrollBoard";
|
||||||
|
// import SwitchButton from "../Component/SwitchButton";
|
||||||
|
import { useState } from "react";
|
||||||
|
import getOptions from "../../Component/LineChart/chart.config";
|
||||||
|
import {useAppSelector} from "./../../../store/hooks"
|
||||||
|
import {selectLine2After} from "./../../../store/LinePageSlice"
|
||||||
|
import dayjs from "dayjs";
|
||||||
|
function CenterDown() {
|
||||||
|
const data = useAppSelector(selectLine2After);
|
||||||
|
// 假数据
|
||||||
|
const dataSource = {
|
||||||
|
day: {
|
||||||
|
xData:[],
|
||||||
|
series: [] as { name: string; type: string; symbol: string; symbolSize: number; data: never[]; }[],
|
||||||
|
},
|
||||||
|
week: {
|
||||||
|
xData:[],
|
||||||
|
series: [] as { name: string; type: string; symbol: string; symbolSize: number; data: never[]; }[],
|
||||||
|
},
|
||||||
|
month: {
|
||||||
|
xData:[],
|
||||||
|
series: [] as { name: string; type: string; symbol: string; symbolSize: number; data: never[]; }[],
|
||||||
|
},
|
||||||
|
};
|
||||||
|
const nameList = [
|
||||||
|
{ name: "天", ename: "day" },
|
||||||
|
{ name: "周", ename: "week" },
|
||||||
|
{ name: "月", ename: "month" },
|
||||||
|
];
|
||||||
|
const [activeName, setActiveName] = useState<string>(nameList[1].ename);
|
||||||
|
// const handleButtonChange = (activeName: string) => {
|
||||||
|
// setActiveName(activeName);
|
||||||
|
// };
|
||||||
|
const config = {
|
||||||
|
header: ["序号", "报警时间", "报警设备", "报警内容"],
|
||||||
|
headerHeight: 36,
|
||||||
|
rowNum: 6,
|
||||||
|
align: ["center", "left", "left", "left"],
|
||||||
|
headerBGC: "rgba(79, 114, 136, 0.3)",
|
||||||
|
oddRowBGC: "rgba(79, 114, 136, 0.3)",
|
||||||
|
evenRowBGC: "rgba(76, 97, 123, 0.1)",
|
||||||
|
columnWidth: [80, 137, 177, 97],
|
||||||
|
data: []
|
||||||
|
};
|
||||||
|
// 报警数据
|
||||||
|
let arr:any = []
|
||||||
|
let sumAlarm = 0
|
||||||
|
// @ts-ignore
|
||||||
|
if (data.alarms && data.alarms.length > 0) {
|
||||||
|
// @ts-ignore
|
||||||
|
sumAlarm = data.alarms.length
|
||||||
|
// @ts-ignore
|
||||||
|
data.alarms.map((item,index) => {
|
||||||
|
let arrInner = []
|
||||||
|
arrInner.push(
|
||||||
|
index+1,
|
||||||
|
dayjs(item.recTime).format("YYYY/MM/DD HH:mm"),
|
||||||
|
item.name,
|
||||||
|
item.status === '故障'?"<span style='color:#FF1E1E'>故障</span>":"<span style='color:#FFB40F'>离线</span>",
|
||||||
|
);
|
||||||
|
arr.push(arrInner)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
config.data = arr
|
||||||
|
// 工段成品率
|
||||||
|
// @ts-ignore
|
||||||
|
if (data.todayProductionRates && Object.keys(data.todayProductionRates).length > 0) {
|
||||||
|
// @ts-ignore
|
||||||
|
let keys = Object.keys(data.todayProductionRates)
|
||||||
|
// @ts-ignore
|
||||||
|
data.todayProductionRates[keys[0]].map((item,index)=>{
|
||||||
|
// @ts-ignore
|
||||||
|
dataSource.day.xData.push(dayjs(item.recTime).format("HH:mm"))
|
||||||
|
})
|
||||||
|
keys.map((item,index)=>{
|
||||||
|
let obj = {
|
||||||
|
name: "",
|
||||||
|
type: "line",
|
||||||
|
symbol: "circle",
|
||||||
|
symbolSize: 4,
|
||||||
|
data:[]
|
||||||
|
}
|
||||||
|
// @ts-ignore
|
||||||
|
obj.name = data.todayProductionRates[item][0].lineName
|
||||||
|
// @ts-ignore
|
||||||
|
data.todayProductionRates[item].map((subItem,index)=>{
|
||||||
|
// @ts-ignore
|
||||||
|
obj.data.push(subItem.passRate)
|
||||||
|
})
|
||||||
|
dataSource.day.series.push(obj)
|
||||||
|
})
|
||||||
|
}else{
|
||||||
|
dataSource.day.xData = []
|
||||||
|
dataSource.day.series = []
|
||||||
|
}
|
||||||
|
// @ts-ignore
|
||||||
|
if (data.weekProductionRates && Object.keys(data.weekProductionRates).length > 0) {
|
||||||
|
// @ts-ignore
|
||||||
|
let keys = Object.keys(data.weekProductionRates)
|
||||||
|
// @ts-ignore
|
||||||
|
data.weekProductionRates[keys[0]].map((item,index)=>{
|
||||||
|
// @ts-ignore
|
||||||
|
dataSource.week.xData.push(dayjs(item.recTime).format("HH:mm"))
|
||||||
|
})
|
||||||
|
keys.map((item,index)=>{
|
||||||
|
let obj = {
|
||||||
|
name: "",
|
||||||
|
type: "line",
|
||||||
|
symbol: "circle",
|
||||||
|
symbolSize: 4,
|
||||||
|
data:[]
|
||||||
|
}
|
||||||
|
// @ts-ignore
|
||||||
|
obj.name = data.weekProductionRates[item][0].lineName
|
||||||
|
// @ts-ignore
|
||||||
|
data.weekProductionRates[item].map((subItem,index)=>{
|
||||||
|
// @ts-ignore
|
||||||
|
obj.data.push(subItem.passRate)
|
||||||
|
})
|
||||||
|
dataSource.week.series.push(obj)
|
||||||
|
})
|
||||||
|
}else{
|
||||||
|
dataSource.week.xData = []
|
||||||
|
dataSource.week.series = []
|
||||||
|
}
|
||||||
|
// @ts-ignore
|
||||||
|
if (data.monthProductionRates && Object.keys(data.monthProductionRates).length > 0) {
|
||||||
|
// @ts-ignore
|
||||||
|
let keys = Object.keys(data.monthProductionRates)
|
||||||
|
// @ts-ignore
|
||||||
|
data.monthProductionRates[keys[0]].map((item,index)=>{
|
||||||
|
// @ts-ignore
|
||||||
|
dataSource.month.xData.push(dayjs(item.recTime).format("HH:mm"))
|
||||||
|
})
|
||||||
|
keys.map((item,index)=>{
|
||||||
|
let obj = {
|
||||||
|
name: "",
|
||||||
|
type: "line",
|
||||||
|
symbol: "circle",
|
||||||
|
symbolSize: 4,
|
||||||
|
data:[]
|
||||||
|
}
|
||||||
|
// @ts-ignore
|
||||||
|
obj.name = data.monthProductionRates[item][0].lineName
|
||||||
|
// @ts-ignore
|
||||||
|
data.monthProductionRates[item].map((subItem,index)=>{
|
||||||
|
// @ts-ignore
|
||||||
|
obj.data.push(subItem.passRate)
|
||||||
|
})
|
||||||
|
dataSource.month.series.push(obj)
|
||||||
|
})
|
||||||
|
}else{
|
||||||
|
dataSource.month.xData = []
|
||||||
|
dataSource.month.series = []
|
||||||
|
}
|
||||||
|
let chartData = (dataSource as { [key: string]: any })[activeName];
|
||||||
|
const options = getOptions(chartData);
|
||||||
|
return (
|
||||||
|
<div className="center_down flex-row">
|
||||||
|
<div className="center_down_inner flex-col left-box">
|
||||||
|
<TitleBox title={"center_down_left"} />
|
||||||
|
<span className="alarm_num_title">— 报警总数 —</span>
|
||||||
|
<div className="alarm_num">{sumAlarm}</div>
|
||||||
|
<div style={{ padding: 10, height: "270px" }}>
|
||||||
|
{arr.length>0?<ScrollBoard
|
||||||
|
config={config}
|
||||||
|
style={{ width: "492px", height: "250px" }}
|
||||||
|
/>:(<p
|
||||||
|
style={{
|
||||||
|
color: "#cccf",
|
||||||
|
fontSize: "24px",
|
||||||
|
userSelect: "none",
|
||||||
|
textAlign: "center",
|
||||||
|
paddingTop: "50px",
|
||||||
|
margin:0
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
暂无数据
|
||||||
|
</p>)}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{/* 工段成品率 */}
|
||||||
|
<div className="center_down_inner flex-col right_box">
|
||||||
|
<TitleBox title={"center_down_right"} />
|
||||||
|
{/* <div className="left_up_switch">
|
||||||
|
<SwitchButton nameList={nameList} onChange={handleButtonChange} />
|
||||||
|
</div> */}
|
||||||
|
{chartData.xData.length>0 && (
|
||||||
|
<div className="chart_box">
|
||||||
|
{<ReactECharts option={options} style={{ height: "100%" }} />}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
{chartData.xData.length==0 && (
|
||||||
|
<p
|
||||||
|
style={{
|
||||||
|
color: "#cccf",
|
||||||
|
fontSize: "24px",
|
||||||
|
userSelect: "none",
|
||||||
|
textAlign: "center",
|
||||||
|
paddingTop: "120px",
|
||||||
|
margin:0
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
暂无数据
|
||||||
|
</p>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
export default CenterDown;
|
10
src/page/LinePage2-2/Center/CenterUp.tsx
Normal file
10
src/page/LinePage2-2/Center/CenterUp.tsx
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
import LinePageBabylon from "../../../babylonjs/LinePageBabylonNew";
|
||||||
|
function CenterUp() {
|
||||||
|
const lineID = "2-2";
|
||||||
|
return (
|
||||||
|
<div className="center_up">
|
||||||
|
<LinePageBabylon modelPath={`Line${lineID}`} />
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
export default CenterUp;
|
12
src/page/LinePage2-2/Center/index.tsx
Normal file
12
src/page/LinePage2-2/Center/index.tsx
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
import CenterDown from "./CenterDown";
|
||||||
|
import CenterUp from "./CenterUp";
|
||||||
|
|
||||||
|
function Center() {
|
||||||
|
return (
|
||||||
|
<div className="group_center flex-col">
|
||||||
|
<CenterUp />
|
||||||
|
<CenterDown />
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
export default Center;
|
19
src/page/LinePage2-2/Component/SwitchButton/index.css
Normal file
19
src/page/LinePage2-2/Component/SwitchButton/index.css
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
.switch-button {
|
||||||
|
height: 33px;
|
||||||
|
}
|
||||||
|
.switch-button button {
|
||||||
|
color: #fff;
|
||||||
|
font-size: 18px;
|
||||||
|
padding: 4px 10px;
|
||||||
|
background-color: rgba(49, 135, 140, 0.3);
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
.switch-button button:first-child {
|
||||||
|
border-radius: 5px 0 0 5px;
|
||||||
|
}
|
||||||
|
.switch-button button:last-child {
|
||||||
|
border-radius: 0 5px 5px 0;
|
||||||
|
}
|
||||||
|
.switch-button button.active {
|
||||||
|
background-color: rgba(86, 244, 231, 0.7);
|
||||||
|
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user