import React, { useRef, useEffect, useState, useCallback, useMemo, } from "react"; import moment from "moment"; import _ from "lodash"; 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 io from "../../../utils/socket.io.js"; import { getDailyBoard } from "../../../reportUtils/getQueryData"; import { parse } from "postcss"; const gutter = 20; const bottom = 20; const socketEmit = "timePerformanceGoodProduct"; const socketScreenType = "DailyPlanType"; // 调试方式: local 本地完整数据调试, server 接口调试, dev 开发期调试 const dataType = "server"; function PlanDailyBoard(props) { const { config: { ioSocketUrl, planDailyConfig = {} } = {} } = global; const { reloadTime = 5000, isSocket = true } = planDailyConfig; // 月份 const [titlePrev, setTitlePrev] = useState(""); // 页面数据 const [pageData, setPageData] = useState(dataType === "dev" ? devData : {}); const socket = useRef(); // 当前时间 const curDateOpt = useMemo(() => { const { curDate } = pageData; if (curDate) { setTitlePrev(`${moment(curDate).format("M")}月`); return moment(curDate).format("YYYY-MM-DD"); } else return ""; }, [pageData.curDate]); const materialInventoryAvailableDaysOpt = useMemo(() => { const { materialInventoryAvailableDays } = pageData; return materialInventoryAvailableDays; }, [pageData.materialInventoryAvailableDays]); // 当前时间 const goalAchievementRateDateOpt = useMemo(() => { const { goalAchievementRateDate } = pageData; if (!goalAchievementRateDate) return curDateOpt; return goalAchievementRateDate; }, [pageData.goalAchievementRateDate]); // 上个月 const lastYearMonthOpt = useMemo(() => { const { lastYearMonth } = pageData; if (lastYearMonth) { return lastYearMonth; } else return ""; }, [pageData.lastYearMonth]); // 月总产出 const mouthProdChart = useRef(); const mouthProdOpt = useMemo( () => chartConfig("mouthProd").init(pageData.mouthProd), [pageData] ); // 月生产目标达成 const mouthAchieveChart = useRef(); const mouthAchieveOpt = useMemo( () => chartConfig("mouthAchieve").init(pageData.mouthAchieve), [pageData] ); // 出货当月 const mouthOutputMemo = useMemo( () => pageData.mouthOutput || { total: 0, totalRate: 0, data: [], names: [], rates: [], }, [pageData] ); // 出货汇总 const totalOutputChart = useRef(); const totalOutputOpt = useMemo( () => chartConfig("totalOutput").init(pageData.totalOutput), [pageData] ); // 生产目标达成 const prodPlanAchieveChart = useRef(); const prodPlanAchieveOpt = useMemo( () => chartConfig("prodPlanAchieve").init(pageData.prodPlanAchieve), [pageData] ); // 原材料库存 const rawMaterialInventoryChart = useRef(); const rawMaterialInventoryOpt = useMemo( () => chartConfig("rawMaterialInventory").init(pageData.rawMaterialInventory), [pageData] ); // 产品库存 const prodInventory = useRef(); const prodInventoryOpt = useMemo(() => { let option = chartConfig("prodInventory").init(pageData.prodInventory); option && (option.getRes = () => pageData.prodInventory); return option; }, [pageData]); const prodInventoryTableOpt = useMemo(() => { let { category = [], data = {} } = prodInventoryOpt?.getRes() || {}; let res = { cloumns: [...category, "合计"], data: [] }; let rowData = []; let total = 0; // Object.keys(data).forEach((key) => { // data[key].forEach((val, index) => { // if (rowData[index] === undefined || isNaN(rowData[index])) // rowData[index] = 0; // rowData[index] += val === undefined ? 0 : val; // let ccval = parseFloat(parseFloat(rowData[index]).toFixed(0)); // rowData[index] = isNaN(ccval) ? 0 : ccval; // total += val === undefined ? 0 : val; // let tptalccval = parseFloat(parseFloat(total).toFixed(0)); // total = isNaN(tptalccval) ? 0 : tptalccval; // }); // }); pageData.productInventoryTable?.forEach((item, index) => { if (rowData[index] === undefined || isNaN(rowData[index])) { rowData[index] = 0; } rowData[index] = parseFloat(parseFloat(item.inventoryQty).toFixed(0)); total += item.inventoryQty; }); total = parseFloat(parseFloat(total).toFixed(0)); rowData.push({total}); res.data[0] = rowData; return res; }, [prodInventoryOpt]); // 历史库存 const historyInventory = useRef(); const historyInventoryOpt = useMemo( () => chartConfig("historyInventory").init(pageData.historyInventory), [pageData] ); // 数据更新 useEffect(() => { // 月总产出 mouthProdOpt && mouthProdChart.current.setOption(mouthProdOpt); // 月目标达成 mouthAchieveOpt && mouthAchieveChart.current.setOption(mouthAchieveOpt); // 出货汇总 totalOutputOpt && totalOutputChart.current.setOption(totalOutputOpt); // 生产目标达成 prodPlanAchieveOpt && prodPlanAchieveChart.current.setOption(prodPlanAchieveOpt); // 原材料库存 rawMaterialInventoryOpt && rawMaterialInventoryChart.current.setOption(rawMaterialInventoryOpt); // 产品库存 prodInventoryOpt && prodInventory.current.setOption(prodInventoryOpt); // 历史库存 historyInventoryOpt && historyInventory.current.setOption(historyInventoryOpt); }, [ mouthProdOpt, mouthAchieveOpt, totalOutputOpt, prodPlanAchieveOpt, rawMaterialInventoryOpt, prodInventoryOpt, historyInventoryOpt, ]); // 收到数据 const update = useCallback((data) => { if (dataType === "local") data = localDataParse; console.log("data", data); let consoleError = (e, name, key) => { console.log("--------------", name, " error", e); console.log("localData: --------------", localDataParse[key]); console.log("requestData: --------------", data[key]); }; // 月总产出 let mouthProd; try { let res = { category: [], data: { prod: [], pect: [] }, }; let { goalAchievementDiagram = [] } = data; goalAchievementDiagram .sort((a, b) => b.productName.localeCompare(a.productName)) .forEach(({ productName, achievingRate, actualQty }) => { res.category.push(productName); res.data.prod.push(actualQty); res.data.pect.push(achievingRate); }); mouthProd = res; } catch (e) { consoleError(e, "月总产出", "goalAchievementDiagram"); } // 月生产目标达成 let mouthAchieve; try { let res = { category: [], data: { plan: [], infect: [], achievement: [] }, }; let { goalAchievementHistogram = [] } = data; var goalAchievementHistogramtmp = goalAchievementHistogram; var llist = goalAchievementHistogramtmp.filter( (x) => x.workLineName.substring(0, 1) === "L" ); var otherlist = goalAchievementHistogramtmp.filter( (x) => x.workLineName.substring(0, 1) !== "L" ); llist.push(...otherlist); var finallist = llist; finallist.forEach( ({ workLineName, goalQty, actualQty, monthGoalQty }) => { res.category.push(workLineName); res.data.infect.push(actualQty); res.data.plan.push(monthGoalQty); res.data.achievement.push(goalQty === 0 ? 0 : actualQty / goalQty); } ); mouthAchieve = res; } catch (e) { consoleError(e, "月生产目标达成", "goalAchievementHistogram"); } // 出货当月 let mouthOutput; try { let res = { total: 0, totalRate: 0, data: [], names: [], rates: [], }; let { shipmentDashBoard = {} } = data; let { summary = {} } = shipmentDashBoard; let { totalShipmentQty = 0, dtl = [], totalAchievingRate } = summary; res.total = totalShipmentQty.toFixed(0); res.totalRate = totalAchievingRate; dtl .sort((a, b) => b.customerName.localeCompare(a.customerName)) .forEach(({ customerName, shipmentQty, achievingRate, goalQty }) => { res.names.push(customerName); res.data.push(shipmentQty.toFixed(0)); res.rates.push(achievingRate); }); mouthOutput = res; // console.log("mouthOutput", mouthOutput, summary); } catch (e) { consoleError(e, "出货当月", "shipmentDashBoard"); } // 出货汇总 let totalOutput; try { let { shipmentDashBoard = {} } = data; let { shipmentPie = [] } = shipmentDashBoard; totalOutput = shipmentPie.map(({ customerName: name, rate: value }) => ({ name, value, })); //演示代码,后面要删除 // totalOutput.forEach((item) => { // if (item.name === "C客户") { // item.value = 0.78; // } else if (item.name === "非C客户") { // item.value = 0.9; // } // }); console.log("-----------totalOutput", totalOutput); } catch (e) { consoleError(e, "出货汇总", "shipmentPie"); } // 生产目标达成 let prodPlanAchieve; try { let res = { category: [], data: { reach: [] }, }; let { goalAchievementRate = [] } = data; goalAchievementRate.forEach(({ workCenterName, achievingRate }) => { res.category.push(workCenterName); res.data.reach.push(achievingRate); }); prodPlanAchieve = res; } catch (e) { consoleError(e, "生产目标达成", "goalAchievementRate"); } // 原材料库存 let rawMaterialInventory; try { let res = { category: [], names: [], data: [], }; let { materialInventoryDiagram = [] } = data; let [data0, data1] = materialInventoryDiagram; let dates = _.cloneDeep(data0.inventoryDate); res.category = dates || []; materialInventoryDiagram.forEach((item) => { res.names.push(item.materialName); res.data.push(item.inventoryQty); }); rawMaterialInventory = res; // } } catch (e) { consoleError(e, "原材料库存", "materialInventoryDiagram"); } // 产品库存 let prodInventory; try { let res = { category: [], data: { qualified: [], review: [], inspecting: [], inspected: [] }, }; let { productInventoryHistogram = [] } = data; productInventoryHistogram.forEach( ({ productName, okQty, reviewQty, pendingInspectionQty, inspectionQty, }) => { res.category.push(productName); res.data.qualified.push(okQty); res.data.review.push(reviewQty); res.data.inspecting.push(pendingInspectionQty); res.data.inspected.push(inspectionQty); } ); prodInventory = res; } catch (e) { consoleError(e, "产品库存", "productInventoryHistogram"); } // 历史库存 let historyInventory; try { let res = { category: [], data: [], }; let { historyInventory: history = [] } = data; history.forEach(({ inventoryDate, inventoryQty },index) => { //只保留8天的数据 //只保留8天所以计算下 let ca=history.length- 8 ; if (index { // let workCenterCode = getQueryVariable("workCenterCode"); let date = getQueryVariable("date"); // if (!workCenterCode) return; let query = { // workCenterCode, screenType: socketScreenType, }; if (date) query.date = date; console.log("fetch", socketEmit, { query }); if (dataType === "server") { if (isSocket) { socket.current.emit(socketEmit, "channel", { query }); } else { getDailyBoard(date) .then((res) => { update(JSON.stringify(res)); }) .catch((err) => console.log(err)); } } else if (dataType === "local") { update(); } clearTimeout(timeoutRef.current); timeoutRef.current = setTimeout(getData, reloadTime); }, []); // 初始化加载 useEffect(() => { if (dataType === "server") { socket.current = io.connect(ioSocketUrl, {transports:['websocket']}); socket.current.on("connect", function () { console.log("msg页面连接成功!"); getData(); }); if (isSocket) socket.current.on(socketEmit, function (data) { try { data = JSON.parse(data); } catch (e) { console.log(e); } update(data.data); }); } else if (dataType === "local") { setTimeout(getData, 1000); } }, [isSocket]); useEffect(() => { return () => { clearTimeout(timeoutRef.current); }; }, []); return (
当月总交付情况
进度达成: {parseFloat( (mouthOutputMemo.totalRate * 100).toFixed(1) )} %
{mouthOutputMemo.names[0]}交货 {mouthOutputMemo.data[0]}
进度达成 {parseFloat( (mouthOutputMemo.rates[0] * 100).toFixed(1) )} %
{mouthOutputMemo.names[1]}交货 {mouthOutputMemo.data[1]}
进度达成 {parseFloat( (mouthOutputMemo.rates[1] * 100).toFixed(1) )} %
1-{lastYearMonthOpt}月汇总
{materialInventoryAvailableDaysOpt !== undefined ? ( Object.keys(materialInventoryAvailableDaysOpt).map( (item, index) => { console.log(item); return ( {item}可用 {materialInventoryAvailableDaysOpt[item]} 天{index === 0 ? "," : ""} ); } ) ) : ( <> )}
{/*
*/}
); } function NumCard(props) { let { data = 0 } = props; const dataArr = useMemo(() => { let res = data + ""; res = res.split(""); while (res.length < 4) res.unshift(""); return res; }, [data]); return (
{dataArr.map((num, index) => (
{num}
))}
); } function SimpleTable(props) { let { cloumns = [], data = [] } = props; return (
{cloumns.map((text) => { return (
{text}
); })}
{data.map((rowData, index) => { return (
{rowData.map((text) => { return (
{text}
); })}
); })}
); } 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 PlanDailyBoard; // 月总产出 let mouthProd = { grid: { bottom: 30, top: 60, left: 60, right: 70, }, legend: { top: 15, right: 10, textStyle: { fontSize: 14, }, }, xAxis: { type: "category", data: [], axisLine: { lineStyle: { color: "rgba(255,255,255,0.65)", }, }, axisTick: { show: true, alignWithLabel: true, }, axisLabel: { color: "rgba(255,255,255,0.85)", }, }, yAxis: [ { type: "value", min: 0, axisLine: { show: false, }, axisTick: { show: false, }, axisLabel: { color: "rgba(255,255,255,0.85)", }, }, { type: "value", min: 0, axisLine: { show: false, }, axisTick: { show: false, }, axisLabel: { color: "rgba(255,255,255,0.85)", formatter: (value) => `${100 * value}%`, }, }, ], series: [ { data: [], type: "bar", barWidth: 28, name: "实际", itemStyle: { color: "#2D99FF", }, label: { show: true, align: "center", width: 200, position: ["50%", "50%"], textBorderColor: "transparent", color: "#fff", }, }, { data: [], yAxisIndex: 1, type: "line", name: "达成率", itemStyle: { color: "#F5A623", }, label: { show: true, position: "top", textBorderColor: "transparent", color: "#F5A623", formatter: (data) => `${parseInt(100 * data.value)}%`, }, }, ], }; mouthProd.init = (res) => { if (!res) return; let opt = _.cloneDeep(mouthProd); let { category, data } = res; let { pect, prod } = data; prod = prod.map((i) => parseInt(i)); pect = pect.map((i) => i); // 分类 opt.xAxis.data = category; // 实际生产数据 opt.series[0].data = prod; // 达成率 opt.series[1].data = pect; return opt; }; // 月生产目标达成 let mouthAchieve = { legend: { top: 15, right: 10, textStyle: { fontSize: 14, }, }, barWidth: 10, barGap: "40%", grid: { bottom: 40, top: 60, left: 60, right: 70, }, xAxis: { type: "value", axisLine: { lineStyle: { color: "rgba(255,255,255,0.65)", }, }, axisLabel: { color: "rgba(255,255,255,0.85)", }, }, yAxis: { type: "category", inverse: true, axisTick: { show: true, alignWithLabel: true, }, axisLine: { lineStyle: { color: "rgba(255,255,255,0.65)", }, }, axisLabel: { color: "rgba(255,255,255,0.85)", }, data: [], }, series: [ { name: "目标", type: "bar", data: [], label: { show: true, position: "right", textBorderColor: "transparent", color: "#fff", }, itemStyle: { color: "#2D99FF", }, }, { name: "实际", type: "bar", data: [], label: { show: true, position: "right", textBorderColor: "transparent", color: "#fff", }, itemStyle: { color: "#6FE621", }, }, { name: "达成率", type: "line", data: [], symbolSize: 0, lineStyle: { width: 0, }, label: { show: true, position: "right", textBorderColor: "transparent", offset: [30, 0], color: "#F6BD16", }, itemStyle: { color: "#F6BD16", }, }, ], }; mouthAchieve.init = (res) => { if (!res) return; let opt = _.cloneDeep(mouthAchieve); let { category, data } = res; let { achievement, infect, plan } = data; // 分类 opt.yAxis.data = category; // 目标 数据 opt.series[0].data = plan.map((i) => parseFloat(i)); // 实际 数据 opt.series[1].data = infect.map((i) => parseFloat(i)); // 达成率 数据 opt.series[2].data = plan .map((planVal, index) => Math.max(planVal, infect[index])) .map((i) => parseFloat(i)); opt.series[2].label.formatter = ({ dataIndex }) => ` ${(100 * achievement[dataIndex]).toFixed(0)}%`; return opt; }; // 出货汇总 let totalOutputBase = { type: "gauge", startAngle: 90, radius: "70%", max: 1, endAngle: -270, pointer: { show: false, }, axisLine: { lineStyle: { width: 16, color: [[1, "#28A3FF"]], opacity: 0.15, }, }, splitLine: { show: false, }, axisTick: { show: false, }, axisLabel: { show: false, }, progress: { show: true, overlap: false, clip: true, itemStyle: { color: "#2D99FF", }, }, title: { fontSize: 14, offsetCenter: [0, -14], color: "#fff", }, detail: { width: 50, height: 14, fontSize: 20, formatter: (val) => `${parseInt(100 * val)}%`, valueAnimation: true, offsetCenter: [0, 10], color: "#fff", }, }; let totalOutput = { series: [ Object.assign({ center: ["30%", "36%"] }, totalOutputBase), Object.assign({ center: ["75%", "36%"] }, totalOutputBase), ], }; totalOutput.init = (res) => { if (!res) return; let opt = _.cloneDeep(totalOutput); let [res0, res1] = res; opt.series[0].data = [res0]; opt.series[1].data = [res1]; return opt; }; // 生产目标达成 let prodPlanAchieve = { grid: { bottom: 40, top: 30, left: 70, right: 40, }, xAxis: { type: "category", data: [], axisLine: { lineStyle: { color: "rgba(255,255,255,0.65)", }, }, axisTick: { show: true, alignWithLabel: true, }, axisLabel: { color: "rgba(255,255,255,0.85)", }, }, yAxis: { type: "value", max: 1, axisLabel: { color: "rgba(255,255,255,0.85)", formatter: (value) => `${parseInt(100 * value)}%`, }, axisLine: { lineStyle: { color: "rgba(255,255,255,0.65)", }, }, }, series: { data: [], type: "bar", barWidth: 28, showBackground: true, itemStyle: { color: "#6FE621", }, label: { show: true, position: "top", textBorderColor: "transparent", color: "#fff", formatter: (data) => `${parseInt(100 * data.value)}%`, }, backgroundStyle: { color: "rgba(45, 153, 255, 0.3)", }, }, }; prodPlanAchieve.init = (res) => { if (!res) return; let opt = _.cloneDeep(prodPlanAchieve); let { category, data } = res; let { reach } = data; opt.xAxis.data = category; opt.series.data = reach.map((i) => parseFloat(i.toFixed(2))); return opt; }; // 原材料库存 let rawMaterialInventory = { grid: { bottom: 40, top: 80, left: 70, right: 70, }, legend: { top: 15, right: 10, textStyle: { fontSize: 14, }, }, xAxis: { type: "category", data: [], axisTick: { show: true, alignWithLabel: true, }, axisLine: { lineStyle: { color: "rgba(255,255,255,0.65)", }, }, axisLabel: { color: "rgba(255,255,255,0.85)", interval: 0, // rotate:45, formatter: function (value) { //x轴的文字改为竖版显示 // var str = value.split(""); return value.replace("-", "/"); }, }, }, yAxis: [ { type: "value", // splitNumber: 3, axisTick: { show: false, }, axisLine: { show: false, }, axisLabel: { color: "rgba(255,255,255,0.85)", formatter: (value) => parseFloat(value.toFixed(1)), }, }, { type: "value", // splitNumber: 3, axisTick: { show: false, }, axisLine: { show: false, }, axisLabel: { color: "rgba(255,255,255,0.85)", formatter: (value) => parseFloat(value.toFixed(1)), }, }, ], series: [ { name: "", type: "line", symbol: "rect", symbolSize: 0, smooth: 0.5, lineStyle: { width: 0, }, areaStyle: { opacity: 0.6, color: "#2D99FF", }, data: [], label: { show: true, position: "insideTop", textBorderColor: "transparent", color: "#fff", // padding:[100,0,0,0], //调整上的位置 }, }, { name: "", type: "line", yAxisIndex: 1, label: { show: true, position: "top", textBorderColor: "transparent", color: "#F5A623", }, data: [], }, ], }; rawMaterialInventory.init = (res) => { if (!res) return; let opt = _.cloneDeep(rawMaterialInventory); let { category, names, data } = res; opt.xAxis.data = category.map((date) => moment(date).format("M-D")); opt.series[0].data = data[0].map((i) => { if (i === null) return i; return parseFloat(i.toFixed(1)); }); opt.series[0].name = names[0] + " 库存量"; data[1] && (opt.series[1].data = data[1].map((i) => { if (i === null) return i; return parseFloat(i.toFixed(1)); })); names[1] && (opt.series[1].name = names[1] + " 库存量"); return opt; }; // 产品库存 let prodInventory = { grid: { bottom: 40, top: 60, left: 70, right: 30, }, barWidth: 32, legend: { top: 15, right: 10, textStyle: { fontSize: 14, }, }, xAxis: { type: "category", data: [], axisTick: { show: true, alignWithLabel: true, }, axisLine: { lineStyle: { color: "rgba(255,255,255,0.65)", }, }, axisLabel: { color: "rgba(255,255,255,0.85)", }, }, yAxis: { type: "value", axisTick: { show: true, alignWithLabel: true, }, axisLine: { lineStyle: { color: "rgba(255,255,255,0.65)", }, }, axisLabel: { color: "rgba(255,255,255,0.85)", }, }, series: [ { name: "合格数量", type: "bar", stack: "Ad", data: [], itemStyle: { color: "#6FE621", }, label: { show: true, position: "inside", textBorderColor: "transparent", color: "#fff", }, }, { name: "待评审数量", type: "bar", stack: "Ad", data: [], itemStyle: { color: "#2D99FF", }, label: { show: true, position: "inside", textBorderColor: "transparent", color: "#fff", }, }, { name: "在检未出数据", type: "bar", stack: "Ad", data: [], itemStyle: { color: "#F6BD16", }, label: { show: true, position: "inside", textBorderColor: "transparent", color: "#fff", }, }, { name: "已评审待处理", type: "bar", stack: "Ad", data: [], itemStyle: { color: "#95D8B9", }, label: { show: true, position: "inside", textBorderColor: "transparent", color: "#fff", }, }, ], }; prodInventory.init = (res) => { if (!res) return; let opt = _.cloneDeep(prodInventory); let { category, data } = res; let { qualified, review, inspecting, inspected } = data; opt.xAxis.data = category; opt.series[0].data = qualified; opt.series[1].data = review; opt.series[2].data = inspecting; opt.series[3].data = inspected; return opt; }; // 历史库存 let historyInventory = { grid: { bottom: 40, top: 30, left: 70, right: 30, }, barWidth: 16, xAxis: { type: "category", data: [], axisTick: { show: true, alignWithLabel: true, }, axisLine: { lineStyle: { color: "rgba(255,255,255,0.65)", }, }, axisLabel: { color: "rgba(255,255,255,0.85)", }, }, yAxis: { type: "value", axisLine: { lineStyle: { color: "rgba(255,255,255,0.65)", }, }, axisLabel: { color: "rgba(255,255,255,0.85)", }, }, series: [ { name: "碳酸铁 库存量", type: "bar", data: [], itemStyle: { color: "#F6BD16", }, label: { show: true, position: "top", textBorderColor: "transparent", color: "#fff", }, }, ], }; historyInventory.init = (res) => { if (!res) return; let opt = _.cloneDeep(historyInventory); let { category, data } = res; opt.xAxis.data = category.map((date) => moment(date).format("M/D")); opt.series[0].data = data.map((i) => parseFloat(i.toFixed(0))); return opt; }; let chartConfig = (() => { let chartOpt = { mouthProd, mouthAchieve, totalOutput, prodPlanAchieve, rawMaterialInventory, prodInventory, historyInventory, }; let getOpt = (type) => chartOpt[type]; return getOpt; })(); // dev 数据 let dates1 = []; for (let i = 0; i < 20; i++) dates1.push(`7-${i + 1}`); let dates2 = []; for (let i = 0; i < 10; i++) dates2.push(`7-${i + 1}`); const devData = { curDate: "2022-08-03", mouthProd: { category: ["磷酸锂铁", "磷酸铁", "高镍三元"], data: { prod: [1269, 452, 852], pect: [0.89, 0.56, 0.763], }, }, mouthAchieve: { category: [ "L1-A", "L1-B", "L2-A", "L2-B", "L3-B", "L3-B", "L4-A", "L4-B", "L5-A", "L5-B", "L6-B", "L6-B", "F1", "F2", "F3", "N1", ], data: { plan: [ 890, 600, 580, 720, 580, 580, 580, 890, 600, 580, 720, 580, 580, 890, 600, 580, ], infect: [ 600, 200, 600, 384, 799, 600, 600, 600, 200, 600, 384, 799, 600, 600, 200, 600, ], achievement: [ 0.6123, 0.6356, 0.6, 0.6, 0.6, 0.6, 0.6, 0.6, 0.6, 0.6, 0.6, 0.6, 0.6, 0.6, 0.6, 0.6, ], }, }, mouthOutput: { total: 319 + 271, totalRate: 0.12, data: [319, 271], names: ["C公司", "非C公司"], rates: [0.12, 0.12], }, totalOutput: [ { value: 0.234, name: "C公司" }, { value: 0.234, name: "非C公司" }, ], prodPlanAchieve: { category: ["L1", "L2", "L3", "L4", "L5", "L6", "F1", "F2", "F3", "N1"], data: { reach: [0.79, 0.4, 1.09, 0.33, 0.4, 0.56, 0.4, 0.86, 0.49, 0.79], }, }, rawMaterialInventory: { category: dates1, names: ["碳酸铁", "碳酸锂"], data: [ [ 3900, 4900, null, 4900, 4300, 3900, null, 5100, null, 4300, 3900, 4900, 5100, 4900, 4300, 4900, 5100, null, 4300, 4300, ], [ 5100, 6200, 6400, 5500, null, 6200, 6400, 5500, 5100, null, 6400, null, 5100, 6200, 6400, 5500, 5100, null, 6400, 6200, ], ], }, prodInventory: { category: ["E80", "E80A", "E70", "E90", "W80S"], data: { qualified: [3900, 4900, 5100, 4900, 4300], review: [5100, 6200, 6400, 5500, 5100], inspecting: [5100, 6200, 6400, 5500, 5100], inspected: [5100, 6200, 6400, 5500, 5100], }, }, historyInventory: { category: dates2, data: [3900, 4900, 5100, 4900, 4300, 5100, 4900, 4300, 4900, 4300], }, }; // local 数据 const localDataParse = { // #当前日期 curDate: "2022-06-03", // #8月产出 goalAchievementDiagram: [ { productName: "磷酸铁锂", achievingRate: 0.57, actualQty: 1268, }, ], // #8月份生产目标达成 goalAchievementHistogram: [ { workLineName: "L1-A", goalQty: 890, actualQty: 600, }, ], // #生产目标达成 goalAchievementRate: [ { workCenterName: "L1", achievingRate: 0.57, }, ], // #产品库存情况 productInventoryTable: [ { productName: "E80", inventoryQty: 1000, }, ], // #产品库存柱状图 productInventoryHistogram: [ { productName: "E80", okQty: 600, reviewQty: 300, pendingInspectionQty: 100, }, ], // #原材料库存情况 materialInventoryDiagram: [ { inventoryDate: ["2022-08-02"], materialName: "磷酸铁锂", inventoryQty: [3532.45], }, { inventoryDate: ["2022-08-02"], materialName: "碳酸锂", inventoryQty: [3932.45], }, ], // #8月份出货 shipmentDashBoard: { // #1-7月汇总 shipmentPie: [ { customerName: "C公司", rate: 0.76, }, { customerName: "非C公司", rate: 1.76, }, ], // #当月情况 summary: { totalShipmentQty: 7339, totalAchievingRate: 1.11, //进度达成 dtl: [ { achievingRate: 1.11, //进度达成 customerName: "C公司", shipmentQty: 4132, goalQty: 4500.0, }, { achievingRate: 1.01, //进度达成 customerName: "非C公司", shipmentQty: 4132, goalQty: 4400.0, }, ], }, }, // #历史库存情况 historyInventory: [ { inventoryDate: "5/31", inventoryQty: 200, }, ], }; const localData = JSON.stringify(localDataParse);