439 lines
11 KiB
JavaScript
439 lines
11 KiB
JavaScript
import React, { useRef, useEffect, useState, useCallback } from "react";
|
||
import Footer from "../../../components/screen/Footer";
|
||
import Header from "../../../components/screen/Header";
|
||
import Row from "../../../components/screen/Row";
|
||
import Card from "../../../components/screen/Card";
|
||
import Chart from "../../../components/screen/Chart";
|
||
import Table from "../../../components/screen/Table";
|
||
import TableProgress from "../../../components/screen/TableProgress";
|
||
import io from "../../../utils/socket.io.js";
|
||
const gutter = 20;
|
||
const bottom = 20;
|
||
const tableToNextPage = 6000;
|
||
|
||
const polarBarOpt = {
|
||
title: {
|
||
text: "计划总数",
|
||
left: "center",
|
||
bottom: 24,
|
||
textStyle: {
|
||
fontSize: 20,
|
||
},
|
||
},
|
||
legend: {
|
||
show: false,
|
||
},
|
||
radiusAxis: {
|
||
show: false,
|
||
type: "category",
|
||
data: ["%"],
|
||
},
|
||
tooltip: {
|
||
show: false,
|
||
},
|
||
series: {
|
||
type: "gauge",
|
||
center: ["50%", "40%"],
|
||
radius: "70%",
|
||
startAngle: 90,
|
||
endAngle: -270,
|
||
pointer: {
|
||
show: false,
|
||
},
|
||
progress: {
|
||
show: true,
|
||
overlap: false,
|
||
roundCap: false,
|
||
clip: false,
|
||
itemStyle: {
|
||
borderWidth: 0,
|
||
},
|
||
},
|
||
axisLine: {
|
||
lineStyle: {
|
||
width: 20,
|
||
color: [[1, "rgba(40, 163, 255, 0.2)"]],
|
||
},
|
||
},
|
||
splitLine: {
|
||
show: false,
|
||
},
|
||
axisTick: {
|
||
show: false,
|
||
},
|
||
axisLabel: {
|
||
show: false,
|
||
},
|
||
data: [
|
||
{
|
||
value: 0,
|
||
name: "生产总数",
|
||
},
|
||
],
|
||
title: {
|
||
offsetCenter: ["0%", "20"],
|
||
color: "#fff",
|
||
fontSize: 20,
|
||
},
|
||
detail: {
|
||
show: true,
|
||
offsetCenter: ["0%", "-20"],
|
||
width: "auto",
|
||
height: 32,
|
||
fontSize: 32,
|
||
color: "#00E1FA",
|
||
borderColor: "auto",
|
||
borderWidth: 0,
|
||
formatter: "{value}",
|
||
},
|
||
},
|
||
};
|
||
const setNumOpt = (total, done, title) => {
|
||
let res = Object.assign({}, polarBarOpt);
|
||
if (title) res.title.text = `${title}:${total}`;
|
||
let percent = ((100 * done) / (total || 1)).toFixed(2);
|
||
res.series.data[0].value = percent;
|
||
res.series.detail.formatter = () => done;
|
||
return res;
|
||
};
|
||
const setOkNumOpt = (total, done, title) => {
|
||
let res = Object.assign({}, polarBarOpt);
|
||
let percent = ((100 * done) / (total || 1)).toFixed(2);
|
||
if (title) res.title.text = `${title}:${percent}%`;
|
||
res.series.data[0].value = percent;
|
||
res.series.data[0].name = "实际总量";
|
||
res.series.detail.formatter = () => done;
|
||
res.series.detail.color = "#6FE621";
|
||
res.series.progress.itemStyle.color = "#6FE621";
|
||
return res;
|
||
};
|
||
|
||
const barOpt = {
|
||
legend: {
|
||
show: true,
|
||
data: ["生产数量", "合格数量"],
|
||
top: 10,
|
||
right: 10,
|
||
textStyle: {
|
||
fontSize: 14,
|
||
},
|
||
},
|
||
tooltip: {
|
||
trigger: "axis",
|
||
axisPointer: {
|
||
type: "shadow",
|
||
},
|
||
},
|
||
xAxis: {
|
||
type: "category",
|
||
axisTick: {
|
||
lineStyle: { opacity: 0.3 },
|
||
alignWithLabel: true,
|
||
},
|
||
axisLine: {
|
||
lineStyle: { opacity: 0.3 },
|
||
},
|
||
axisLabel: {
|
||
color: "rgba(255, 255, 255, 0.8)",
|
||
},
|
||
data: [],
|
||
},
|
||
yAxis: {
|
||
type: "value",
|
||
axisTick: {
|
||
lineStyle: { opacity: 0.3 },
|
||
},
|
||
axisLine: {
|
||
lineStyle: { opacity: 0.3 },
|
||
},
|
||
axisLabel: {
|
||
color: "rgba(255, 255, 255, 0.8)",
|
||
},
|
||
},
|
||
grid: {
|
||
bottom: 40,
|
||
top: 60,
|
||
left: 50,
|
||
},
|
||
barWidth: 20,
|
||
series: [
|
||
{
|
||
name: "生产数量",
|
||
type: "bar",
|
||
barGap: -1,
|
||
data: [],
|
||
},
|
||
{
|
||
name: "合格数量",
|
||
itemStyle: {
|
||
color: "#6FE621",
|
||
},
|
||
type: "bar",
|
||
data: [],
|
||
},
|
||
],
|
||
};
|
||
const setBarOpt = ({ product = {}, qualify = {} }) => {
|
||
let res = Object.assign({}, barOpt);
|
||
for (let n = 0; n < 24; n++) {
|
||
res.xAxis.data.push(`${n}:00`.padStart(5, "0"));
|
||
}
|
||
for (let index in product) {
|
||
res.series[0].data[parseInt(index)] = product[index];
|
||
}
|
||
for (let index in qualify) {
|
||
res.series[1].data[parseInt(index)] = qualify[index];
|
||
}
|
||
return res;
|
||
};
|
||
|
||
const productTableColumns = [
|
||
{ title: "客户编码", code: "vendorCode" },
|
||
{ title: "客户名称", code: "vendorName" },
|
||
{ title: "销售名称", code: "userName" },
|
||
{ title: "客户分类", code: "customType" },
|
||
{ title: "产品型号", code: "productMode" },
|
||
{ title: "计划发货日期", code: "planDeliveryTime" },
|
||
{ title: "计划发货数量", code: "planDeliveryQty" },
|
||
{ title: "实际发货数量", code: "deliveryQty" },
|
||
{
|
||
title: "发货率",
|
||
code: "deliveryRateNew",
|
||
render: (value, config, rowData) => {
|
||
console.log(config, rowData);
|
||
return <TableProgress percent={value} />;
|
||
},
|
||
},
|
||
|
||
// {title: "生产状态", code: "code",
|
||
// value: val => {
|
||
// if(val === '1') return "生产中";
|
||
// if(val === '2') return "中断";
|
||
// if(val === '3') return "转产";
|
||
// },
|
||
// color: val => {
|
||
// if(val === '1') return "#6FE621";
|
||
// if(val === '2') return "#28A3FF";
|
||
// if(val === '3') return "#F82D22";
|
||
// },
|
||
// render: (text, config, rowData) => {
|
||
// const {value, color} = config;
|
||
// let resColor = color(text);
|
||
// let resText = value(text);
|
||
// return (
|
||
// <div style={{color: resColor}}>
|
||
// <span style={{
|
||
// background: resColor,
|
||
// width: '8px',
|
||
// height: '8px',
|
||
// display: 'inline-block',
|
||
// borderRadius: '50%',
|
||
// verticalAlign: 'middle',
|
||
// }}></span>
|
||
// <span style={{
|
||
// verticalAlign: 'middle',
|
||
// marginLeft: '6px',
|
||
// }}>{resText}</span>
|
||
// </div>
|
||
// )
|
||
// },
|
||
// },
|
||
// {title: "产品编码", code: "code"},
|
||
// {title: "产品名称", code: "code"},
|
||
// {title: "工单编号", code: "code"},
|
||
// {title: "生产数量", code: "code"},
|
||
// {title: "计划数量", code: "code"},
|
||
// {title: "生产进度", code: "code",
|
||
// render: (value, config, rowData) => {
|
||
// console.log(config, rowData)
|
||
// return <TableProgress percent={0.31}/>
|
||
// },
|
||
// },
|
||
// {title: "不良品数量", code: "code"},
|
||
// {title: "不良品率", code: "code"},
|
||
];
|
||
|
||
const productTableColumnNew = [
|
||
{ title: "产品类型", code: "materialTypeName" },
|
||
{ title: "产品型号", code: "productLevel" },
|
||
{ title: "产线信息", code: "workCenterName" },
|
||
{ title: "计划产出日期", code: "planOutputDate" },
|
||
{ title: "计划产量", code: "planNum" },
|
||
{ title: "实际产量", code: "actualNum" },
|
||
{
|
||
title: "达成率",
|
||
code: "fulfillRateNew",
|
||
render: (value, config, rowData) => {
|
||
console.log(config, rowData);
|
||
return <TableProgress percent={value} />;
|
||
},
|
||
},
|
||
];
|
||
|
||
function Comprehensive(props) {
|
||
const { config: { ioSocketUrl, comprehensiveConfig = {} } = {} } = global;
|
||
const okNumRefNew = useRef();
|
||
const okNumRef = useRef();
|
||
const productTableRefNew = useRef();
|
||
const productTableRef = useRef();
|
||
const socket = useRef();
|
||
let date = "";
|
||
let query = {
|
||
screenType: "ComprehensiveType",
|
||
};
|
||
if (date) query.date = date;
|
||
else {
|
||
query.date = new Date().toJSON().split("T").join(" ").substr(0, 10);
|
||
}
|
||
|
||
const getData = () =>
|
||
socket.current.emit("timePerformanceGoodProduct", "channel", { query });
|
||
|
||
setTimeout(() => {
|
||
getData();
|
||
}, 300000);
|
||
const setTableNextPage = useCallback(() => {
|
||
setTimeout(() => {
|
||
productTableRef.current.nextPage();
|
||
setTableNextPage();
|
||
}, tableToNextPage);
|
||
}, []);
|
||
|
||
const setTableNextPageNew = useCallback(() => {
|
||
setTimeout(() => {
|
||
productTableRefNew.current.nextPage();
|
||
setTableNextPageNew();
|
||
}, tableToNextPage);
|
||
}, []);
|
||
|
||
useEffect(() => {
|
||
socket.current = io.connect(ioSocketUrl, {transports:['websocket']});
|
||
|
||
socket.current.on("connect", function () {
|
||
console.log("msg页面连接成功!");
|
||
getData();
|
||
});
|
||
|
||
socket.current.on("timePerformanceGoodProduct", function (data) {
|
||
data = JSON.parse(data);
|
||
console.log(data, "data");
|
||
okNumRef.current.setOption(
|
||
setOkNumOpt(
|
||
data.data.deliveryRates.planQty,
|
||
data.data.deliveryRates.qty,
|
||
"发货总体达成率"
|
||
)
|
||
);
|
||
okNumRefNew.current.setOption(
|
||
setOkNumOpt(
|
||
data.data.planRates.planOutQty,
|
||
data.data.planRates.OutQty,
|
||
"计划总体达成率"
|
||
)
|
||
);
|
||
productTableRefNew.current.addData(data.data.planOutputList);
|
||
productTableRef.current.addData(data.data.deliveryPlanList);
|
||
});
|
||
|
||
//planNumRef.current.setOption(setNumOpt(500000, 212923, "计划总数"));
|
||
|
||
// productNumRef.current.setOption(setBarOpt({
|
||
// product: {
|
||
// "0": 10,
|
||
// "1": 40,
|
||
// "5": 30,
|
||
// "6": 40,
|
||
// },
|
||
// qualify: {
|
||
// "0": 5,
|
||
// "1": 4,
|
||
// "5": 3,
|
||
// },
|
||
// }));
|
||
|
||
setTableNextPageNew();
|
||
setTableNextPage();
|
||
}, []);
|
||
|
||
return (
|
||
<div className="screen-container">
|
||
<Header title={"综合看板"} />
|
||
<div className="screen-container-content">
|
||
<Row className="height-50" gutter={gutter} bottom={bottom}>
|
||
<Row.Col span={18}>
|
||
<Card
|
||
title="发货达成率"
|
||
titleSpace={true}
|
||
padding={`15px ${gutter}px`}
|
||
>
|
||
<Table
|
||
ref={productTableRef}
|
||
mainKey="code"
|
||
columns={productTableColumns}
|
||
/>
|
||
</Card>
|
||
</Row.Col>
|
||
{/*<Row.Col span={14}>*/}
|
||
{/* <Card title="今日生产统计" overVisible={true}>*/}
|
||
{/* <Chart ref={productNumRef} />*/}
|
||
{/* </Card>*/}
|
||
{/*</Row.Col>*/}
|
||
<Row.Col span={6}>
|
||
<Card title="发货总体达成率" titleSpace={true} overVisible={true}>
|
||
<Chart ref={okNumRef} />
|
||
</Card>
|
||
</Row.Col>
|
||
</Row>
|
||
|
||
<Row className="height-50" gutter={gutter} bottom={bottom}>
|
||
<Row.Col span={18}>
|
||
<Card
|
||
title="计划达成率"
|
||
titleSpace={true}
|
||
padding={`15px ${gutter}px`}
|
||
>
|
||
<Table
|
||
ref={productTableRefNew}
|
||
mainKey="code"
|
||
columns={productTableColumnNew}
|
||
/>
|
||
</Card>
|
||
</Row.Col>
|
||
<Row.Col span={6}>
|
||
<Card title="计划总体达成率" titleSpace={true} overVisible={true}>
|
||
<Chart ref={okNumRefNew} />
|
||
</Card>
|
||
</Row.Col>
|
||
</Row>
|
||
</div>
|
||
<Footer />
|
||
<style jsx>{`
|
||
.screen-container {
|
||
height: 100vh;
|
||
overflow: auto;
|
||
background: url("/img/bg.png") center center;
|
||
position: relative;
|
||
padding-top: 96px;
|
||
padding-bottom: 82px;
|
||
}
|
||
.screen-container-content {
|
||
height: 100%;
|
||
padding: 0 ${gutter}px;
|
||
}
|
||
`}</style>
|
||
</div>
|
||
);
|
||
}
|
||
const getQueryVariable = (variable) => {
|
||
let query = window.location.search.substring(1);
|
||
let vars = query.split("&");
|
||
for (let i = 0; i < vars.length; i++) {
|
||
let pair = vars[i].split("=");
|
||
if (pair[0] == variable) {
|
||
return pair[1];
|
||
}
|
||
}
|
||
return false;
|
||
};
|
||
export default Comprehensive;
|