import React, { useRef, useEffect, useCallback } from 'react'; import _ from 'lodash'; import { withRouter } from 'next/router'; 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; // 返回结果是个字符串,需要转一下 let testData = { "code": "0000", "data": { //今日生产总数 "productCount": { "planQty": 3162.000000, //计划总数 "productQty": 199.000000, //生产总数 "unFinishedQty": 2963.000000 //未完成数量 }, //今日生产统计 "productDayCountList": [ { "productQty": 0.000000, //生产数量 "qualityQty": 0.000000, //合格数量 "time": "00:00" }, { "productQty": 0.000000, "qualityQty": 0.000000, "time": "01:00" }, { "productQty": 0.000000, "qualityQty": 0.000000, "time": "02:00" }, { "productQty": 0.000000, "qualityQty": 0.000000, "time": "03:00" }, { "productQty": 0.000000, "qualityQty": 0.000000, "time": "04:00" }, { "productQty": 0.000000, "qualityQty": 0.000000, "time": "05:00" }, { "productQty": 0.000000, "qualityQty": 0.000000, "time": "06:00" }, { "productQty": 0.000000, "qualityQty": 0.000000, "time": "07:00" }, { "productQty": 0.000000, "qualityQty": 0.000000, "time": "08:00" }, { "productQty": 0.000000, "qualityQty": 0.000000, "time": "09:00" }, { "productQty": 69.000000, "qualityQty": 17.000000, "time": "10:00" }, { "productQty": 12.000000, "qualityQty": 12.000000, "time": "11:00" }, { "productQty": 0.000000, "qualityQty": 0.000000, "time": "12:00" }, { "productQty": 15.000000, "qualityQty": 15.000000, "time": "13:00" }, { "productQty": 25.000000, "qualityQty": 25.000000, "time": "14:00" }, { "productQty": 26.000000, "qualityQty": 26.000000, "time": "15:00" }, { "productQty": 52.000000, "qualityQty": 51.000000, "time": "16:00" }, { "productQty": 0.000000, "qualityQty": 0.000000, "time": "17:00" }, { "productQty": 0.000000, "qualityQty": 0.000000, "time": "18:00" }, { "productQty": 0.000000, "qualityQty": 0.000000, "time": "19:00" }, { "productQty": 0.000000, "qualityQty": 0.000000, "time": "20:00" }, { "productQty": 0.000000, "qualityQty": 0.000000, "time": "21:00" }, { "productQty": 0.000000, "qualityQty": 0.000000, "time": "22:00" }, { "productQty": 0.000000, "qualityQty": 0.000000, "time": "23:00" } ], //日产能概况 "productDayRecordList": [ { "code": "WO202203300001", //工单号 "materialCode": "L5CP", //产品编码 "materialName": "L5车间成品", //产品名称 "planQty": 1000.000000, //计划数量 "productQty": 10.000000, //生产数量 "productRate": 0.010, //生产进度 "productStatus": "已完工", //生产状态 "unQualityQty": 0.000000, //不合格数量 "unQualityRate": 0.000, //不合格率 "workCenterCode": "L5", //产线编码 "workCenterName": "L5车间" //产线名称 }, { "code": "WO202204010001", "materialCode": "L5CP", "materialName": "L5车间成品", "planQty": 100.000000, "productQty": 15.000000, "productRate": 0.150, "productStatus": "已创建", "unQualityQty": 0.000000, "unQualityRate": 0.000, "workCenterCode": "L5", "workCenterName": "L5车间" }, { "code": "WO202204010002", "materialCode": "L5CP", "materialName": "L5车间成品", "planQty": 10.000000, "productQty": 15.000000, "productRate": 1.500, "productStatus": "生产中", "unQualityQty": 0.000000, "unQualityRate": 0.000, "workCenterCode": "L5", "workCenterName": "L5车间" }, { "code": "WO202204010003", "materialCode": "L5CP", "materialName": "L5车间成品", "planQty": 10.000000, "productQty": 12.000000, "productRate": 1.200, "productStatus": "生产中", "unQualityQty": 0.000000, "unQualityRate": 0.000, "workCenterCode": "L5", "workCenterName": "L5车间" }, { "code": "WO202204060001", "materialCode": "L5CP", "materialName": "L5车间成品", "planQty": 1000.000000, "productQty": 14.000000, "productRate": 0.014, "productStatus": "生产中", "unQualityQty": 0.000000, "unQualityRate": 0.000, "workCenterCode": "L5", "workCenterName": "L5车间" }, { "code": "WO202204060002", "materialCode": "L5CP", "materialName": "L5车间成品", "planQty": 10.000000, "productQty": 12.000000, "productRate": 1.200, "productStatus": "生产中", "unQualityQty": 0.000000, "unQualityRate": 0.000, "workCenterCode": "L5", "workCenterName": "L5车间" }, { "code": "WO202204060003", "materialCode": "L5CP", "materialName": "L5车间成品", "planQty": 10.000000, "productQty": 14.000000, "productRate": 1.400, "productStatus": "生产中", "unQualityQty": 0.000000, "unQualityRate": 0.000, "workCenterCode": "L5", "workCenterName": "L5车间" }, { "code": "WO202204070001", "materialCode": "L5CP", "materialName": "L5车间成品", "planQty": 10.000000, "productQty": 52.000000, "productRate": 5.200, "productStatus": "生产中", "unQualityQty": 1.000000, "unQualityRate": 0.019, "workCenterCode": "L5", "workCenterName": "L5车间" }, { "code": "WO202204080001", "materialCode": "L5CP", "materialName": "L5车间成品", "planQty": 12.000000, "productQty": 55.000000, "productRate": 4.583, "productStatus": "生产中", "unQualityQty": 52.000000, "unQualityRate": 0.945, "workCenterCode": "L5", "workCenterName": "L5车间" }, { "code": "RcQuickWearStr", "materialCode": "L5CP", "materialName": "L5车间成品", "planQty": 1000.000000, "productQty": 0.000000, "productRate": 0.000, "productStatus": "待生产", "unQualityQty": 0.000000, "unQualityRate": 0.000, "workCenterCode": "L5", "workCenterName": "L5车间" } ], // 今日生产合格数 "qualityDayCount": { "qualityQty": 146.000000, //合格数量 "qualityRate": 0.734, //合格率 "unQualityQty": 53.000000 //不合格数量 } }, "success": true }; 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 = _.cloneDeep(polarBarOpt); if(title) res.title.text = `${title}:${total}`; let percent = (100 * done / total).toFixed(2); res.series.data[0].name = "生产总数"; res.series.data[0].value = percent; res.series.detail.formatter = () => done; return res; } const setOkNumOpt = (total, done, title) => { let res = _.cloneDeep(polarBarOpt); let percent = (100 * done / (total === 0 ? 1 : total)).toFixed(2); if(isNaN(percent)) percent = 0; 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 = (data) => { let res = _.cloneDeep(barOpt); data.forEach(({productQty, qualityQty, time}, index) => { res.xAxis.data.push(time); res.series[0].data[index] = productQty; res.series[1].data[index] = qualityQty; }) return res; }; const productTableColumns = [ {title: "机台", code: "workCenterName"}, {title: "生产状态", code: "productStatus", color: val => { if(val === '待生产') return "#d5542d"; if(val === '已创建') return "#1a7cc6"; if(val === '生产中') return "#0aac61"; if(val === '已完工') return "#0db5a4"; if(val === '已关闭') return "#c1c1c1"; if(val === '已取消') return "#c1c1c1"; }, render: (text, config, rowData) => { const {color} = config; let resColor = color(text); return (
{text}
) }, }, {title: "产品编码", code: "materialCode"}, {title: "产品名称", code: "materialName"}, {title: "工单编号", code: "code"}, {title: "生产数量", code: "productQty"}, {title: "计划数量", code: "planQty"}, {title: "生产进度", code: "productRate", width: 200, render: (value, config, rowData) => { return }, }, {title: "不良品数量", code: "unQualityQty"}, {title: "不良品率", code: "unQualityRate", render: (value, config, rowData) => { return {value * 100}% }, }, ] function PlanBoard(props) { const {config : {ioSocketUrl, planBoard = {}} = {}} = global; const tableToNextPage = planBoard.productTableNext; const {router} = props; const planNumRef = useRef(); const okNumRef = useRef(); const productNumRef = useRef(); const productTableRef = useRef(); const socket = useRef(); const workCenterCodeRef = useRef(); const tableTimeoutRef = useRef(); 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); } const getData = () => { let workCenterCode = workCenterCodeRef.current let date = getQueryVariable('date'); console.log("fetch", workCenterCode) if(!workCenterCode) return; let query = { workCenterCode, screenType: "ProductPlanType", } if (date) query.date = date; else{ query.date = new Date().toJSON().split('T').join(' ').substr(0,10) } socket.current.emit('timePerformanceGoodProduct', 'channel', {query}) setTimeGetData() }; const setTimeGetData = () => { setTimeout(() => { getData() }, 300000) } const pageFinished = useCallback(() => { console.log("finished") clearInterval(tableTimeoutRef.current); getData(); }) const setTableNextPage = useCallback(() => { tableTimeoutRef.current = setInterval(() => { productTableRef.current.nextPage(); }, tableToNextPage); }, []) const update = (data) => { try{ data = JSON.parse(data) }catch(e){console.log(e)} // if(!data) data = testData; const {productCount, productDayCountList, qualityDayCount, productDayRecordList} = data.data; console.log("data", data.data) planNumRef.current.setOption(setNumOpt( productCount.planQty, productCount.productQty, "计划总数" )); okNumRef.current.setOption(setOkNumOpt( qualityDayCount.qualityQty, qualityDayCount.qualityQty - qualityDayCount.unQualityQty, "合格率" )); productNumRef.current.setOption(setBarOpt(productDayCountList)); productTableRef.current.setData(productDayRecordList); setTableNextPage(); }; useEffect(() => { const {workCenterCode} = router.query; if(!workCenterCode) return; workCenterCodeRef.current = workCenterCode; }, [router]) useEffect(() => { socket.current = io.connect(ioSocketUrl, {transports:['websocket']}); socket.current.on('connect', function() { console.log("msg页面连接成功!"); getData(); }); socket.current.on('timePerformanceGoodProduct', function(data) { update(data) }); // update(); }, []) return (
); } export default withRouter(PlanBoard)