import React, { useCallback, useRef, useReducer, useEffect, useState, useMemo, } from "react"; import { message } from "antd"; import moment from "moment"; import Decimal from "decimal.js" import Row from "../../../components/screen/Row"; import { FormItem } from "../FormItem"; import { Button } from "../Button"; import { ModelSetting, ModelBreak, ModelOverproductionBatch, ModelFinish, ModelOverPrint, } from "./ModalClient"; import { logo } from "./logo"; import { request } from "../utils"; import { useEquipKey, useSetting, useMetaInfo, useWsInfo, useUser, isDev, } from "./hooks"; const headerHeight = 56; /** * url获取token * 获取用户信息 * 获取权限信息 * * url获取ip * ip - 设置信息 * 设置信息 - 产品信息 * 设置信息 - socket 重量信息 * * 任务状态: * 无任务 待包装 包装中 中断 包装完成 */ function formReducer(state, action) { let { type, value } = action; // console.log("action", action); if (type === "FROM_INIT") return value; if (type === "FROM_CHANGE") return Object.assign({}, state, value); return state; } function PackagingOperation(props) { const ModelSettingRef = useRef(); const ModelBreakRef = useRef(); const ModelOverproductionBatchRef = useRef(); const ModelFinishRef = useRef(); const [isEdit, setIsEdit] = useState(false); const { equipKey, getEquipKey } = useEquipKey(); const { settingData, getSettingData } = useSetting(equipKey); const [metaInfo, getMetaInfo] = useMetaInfo(settingData?.equipCode); const [wsData] = useWsInfo(settingData?.equipCode, isEdit); const [user, getUser] = useUser(); // 页面表单变化 const [form, dispatch] = useReducer(formReducer, {}); const onFormChange = useCallback((type, value) => { dispatch({ type: "FROM_CHANGE", value: { [type]: value } }); }, []); // 更新当前登录用户 useEffect(() => { dispatch({ type: "FROM_CHANGE", value: { userName: user?.userName } }); }, [user]); // 初始化表单 useEffect(() => { dispatch({ type: "FROM_INIT", value: metaInfo }); getUser(); }, [metaInfo, getUser]); // ws更新表单 useEffect(() => { let { czzl, fczl } = wsData || {}; dispatch({ type: "FROM_CHANGE", value: { czzl, fczl } }); }, [wsData]); // 更新净重 const netWeight = useMemo(() => { let { bagWeight } = settingData; let { fczl } = form; if (isNaN(parseFloat(fczl))) return ""; if (isNaN(parseFloat(bagWeight))) return ""; let res = Decimal(fczl).sub(Decimal(bagWeight)).toNumber(); if (isNaN(res)) return ""; return res; }, [form, settingData]); // 更新持续时长 const [durationTime, setDurationTime] = useState(0); useEffect(() => { let getTime = () => { let { startTime, status, recoverDate, interruptDate, intrptDuration = 0, } = metaInfo; // console.log("metaInfo", metaInfo, {startTime, status, recoverDate, interruptDate, intrptDuration }) /** * 无任务 “” * 待包装 “” * 包装中 currentDate - startTime - intrptDuration * 中断 interruptDate - startTime - intrptDuration * 包装完成 endTime - startTime - intrptDuration */ if (["no_job", "TO_BE_PACKAGED"].includes(status)) return ""; let dif = new Date(startTime).getTime() + intrptDuration * 1000; if (status === "IN_PACKAGING") return new Date().getTime() - dif; if (status === "INTERRUPT") return new Date(interruptDate).getTime() - dif; if (status === "PACKAGING_COMPLETED") return new Date(endTime).getTime() - dif; }; let timmer; let run = () => { setDurationTime(getTime()); timmer = setTimeout(() => { run(); }, 1000); }; run(); return () => { clearTimeout(timmer); }; }, [metaInfo]); const durationTimeStr = useMemo(() => { let time = moment.duration(durationTime); let res = ""; let sec = time.seconds(); let min = time.minutes(); let hor = time.hours(); let day = time.days(); let m = time.months(); let y = time.years(); let flag = false; let arr = [y, m, day, hor, min, sec]; let unt = ["年", "月", "日", "时", "分", "秒"]; arr.forEach((val, index) => { if (val) { flag = true; res += val + unt[index]; } else if (flag) { res += 0 + unt[index]; } }); return res; }, [durationTime]); // 包装袋数 const [realBagNo, setRealBagNo] = useState(1); useEffect(() => { let { bagNo, outBagNo, outBatch } = form; let res = 0; if (outBatch) { res = parseFloat(outBagNo) + 1; } else { res = parseFloat(bagNo) + 1; } setRealBagNo(isNaN(res) ? 0 : res); }, [form.bagNo, form.outBagNo, form.outBatch]); // 设备状态 const equipStatus = useMemo(() => { if (form.status === "no_job") return "无任务"; if (form.status === "INTERRUPT") return "中断"; if (form.status === "TO_BE_PACKAGED") return "待包装"; if (form.status === "IN_PACKAGING") return "包装中"; if (form.status === "PACKAGING_COMPLETED") return "包装完成"; return "-"; }, [form.status]); // 按钮启用禁用 const btnEnable = useMemo(() => { /** * 超产批号 ? * 设置 - 权限 * 历史记录 - 非无任务 * 开始 - 待包装 * 打印 - 包装中 * 结束 - 包装中 中断 * 中断 - 包装中 * 编辑 - 权限 包装中 * 编辑完成 - 权限 包装中 */ return { overPro: true, setting: true, history: ["中断", "待包装", "包装中", "包装完成"].includes(equipStatus), start: ["待包装"].includes(equipStatus), print: ["包装中"].includes(equipStatus), finish: ["包装中", "中断"].includes(equipStatus), break: ["包装中"].includes(equipStatus), edit: ["包装中"].includes(equipStatus), }; }, [equipStatus]); // 退出 const handleCancel = useCallback(() => { window.parent.postMessage({ type: "logOut" }, window.config.mesHost); }, []); // 设置 const handleSetting = useCallback(() => { if (equipKey) { let settingRes = Object.assign({}, settingData || {}, { equipKey }); ModelSettingRef.current.show(settingRes, getSettingData); } }, [equipKey, getSettingData, settingData]); // 超产批号 const handleOverproduct = useCallback(() => { ModelOverproductionBatchRef.current.show( metaInfo.workOrderCode, (outBatch) => { onFormChange("outBatch", outBatch); } ); }, [metaInfo.workOrderCode, onFormChange]); // 历史记录 const handleHistory = useCallback(() => { window.parent.postMessage( { type: "history", data: metaInfo }, window.config.mesHost ); }, [metaInfo]); // 开始 const handleStart = useCallback(() => { if (metaInfo.gid) return new Promise((resolve, reject) => { request({ url: `${window.config.mesUrl}/prodexec/prodexec/packageEquipment/startPack`, bodys: { gid: metaInfo.gid }, }) .then((res) => { if (res.success) { message.success("开始成功!"); getMetaInfo(); } }) .finally(() => { resolve(); }); }); }, [metaInfo.gid, getMetaInfo]); // 打印 const ModelOverPrintRef = useRef(); const [isGT, setIsGT] = useState(false) const handlePrint = useCallback((GT, callback) => { if (GT === undefined) GT = isGT; let { gid: recordGid } = metaInfo; let { gid: setInfoGid, bagWeight } = settingData; let { fczl, czzl, outBatch, materialCode, productLevel, startTime, materialName, workOrderCode, } = form; // collectValue 页面可见数据 除自定义字段外的 对象json 字符串 let collectValue = { materialCode, productLevel, startTime, materialName, workOrderCode, czzl, fczl, bagWeight, yetWeight: netWeight, bagNo: realBagNo, }; let data = { recordGid, mark: GT? "GT": undefined, fczl, bagNo: realBagNo, setInfoGid, yetWeight: netWeight, outBatch, collectValue: JSON.stringify(collectValue), }; if (recordGid) return new Promise((resolve, reject) => { request({ url: `${window.config.mesUrl}/prodexec/prodexec/packageEquipment/print`, bodys: data, }) .then((res) => { // if (isDev) { // if (res.message.indexOf('打印命令发送失败') > -1) { // res = { // success: false, // data: "GT", // message: "message text" // } // } // } if (res && res.success) { message.success("打印成功!"); setRealBagNo(parseFloat(realBagNo) + 1); } else { if (res?.data === "GT") { ModelOverPrintRef.current.show(res.message, (close) => { setIsGT(true); return handlePrint(true, close); }) }else message.error(res?.message); } }) .finally(() => { resolve(); callback && callback(); }); }); }, [metaInfo, settingData, form, netWeight, realBagNo, isGT]); // 结束 const handleFinish = useCallback(() => { ModelFinishRef.current.show({ gid: metaInfo.gid }, getMetaInfo); }, [metaInfo.gid, getMetaInfo]); // 中断 const handleBreak = useCallback(() => { ModelBreakRef.current.show({ gid: metaInfo.gid }, getMetaInfo); }, [metaInfo.gid, getMetaInfo]); // 编辑 const handleEdit = useCallback(() => { // console.log("handleEdit"); if (isEdit) { setIsEdit(false); } else { setIsEdit(true); } }, [isEdit]); return (