/* * @Author: Sakura * @LastEditors: Sakura * @Date: 2024-02-28 9:55:04 * @Description: 设备状态组件 */ import React, { useRef, useEffect, useState } from "react"; import { Button, message } from "antd"; import * as commonFunc from "@/components/Common/commonFunc"; import * as commonUtils from "@/utils/utils"; import useCommonBase from "@/components/Common/CommonHooks/useCommonBase"; import * as commonBusiness from "@/components/Common/commonBusiness"; import CommonViewTable from "@/components/Common/CommonViewTable"; import ShowType from "@/components/Common/CommonComponent"; import ReportInfo from "@/mes/productionExec/noticeModal/reportInfoButton"; import styles from "./index.less"; import { cloneDeep } from "lodash"; const sTypeJson = { sType1: ["行车状态", "green", "greenTd"], sType2: ["正常待机", "cyan", "cyanTd"], sType3: ["不正常待机(材料异常)", "red", "redTd"], sType4: ["不正常待机(工艺异常)", "red", "redTd"], sType5: ["不正常待机(制程异常)", "red", "redTd"], sType6: ["不正常待机(其它类型)(协助类)", "red", "redTd"], sType7: ["不正常待机", "red", "redTd"], sType8: ["设备保养(协助类)", "blue", "blueTd"], sType9: ["设备维修", "blue", "blueTd"], sType10: ["设备保养", "red", "blueTd"], sType11: ["材料异常", "red", "redTd"], sType12: ["工艺异常", "red", "redTd"], sType13: ["其他异常", "red", "redTd"], sType14: ["设备异常", "red", "redTd"], sType15: ["其他类型", "blue", "blueTd"], sType16: ["制程异常", "red", "red"], "": ["其它", "blue", "blueTd"] }; // 业务层 const businessTier = props => { const { formData = [], copyTo = {} } = props; useEffect( async () => { if (commonUtils.isNotEmptyArr(formData)) { const colunmData = handleGetColumnData(formData, true); const result = await handleGetData(formData, true); const addState = { ...colunmData, ...result }; Object.keys(copyTo).forEach(key => { addState[`${key}Data`] = copyTo[key]; }); props.onSaveState(addState); } }, [formData.length] ); // 获取表头数据 const handleGetColumnData = (formData = [], isWait) => { let addState = {}; for (let i = 0; i < formData.length; i++) { const config = formData[i]; const column = commonFunc.getHeaderConfig(config); if (i === 1) { addState.slave2Data = [{ sId: commonUtils.createSid() }]; } addState = { ...addState, [`slave${i > 0 ? i + 1 : i}Column`]: column, [`slave${i > 0 ? i + 1 : i}Config`]: config }; } if (isWait) { return addState; } else { props.onSaveState(addState); } }; // 获取数据集 const handleGetData = async (formData = [], isWait) => { let addState = {}; for (let i = 0; i < formData.length; i++) { const config = formData[i]; const conditonValues = props.onGetSqlConditionValues(config); const iSort = props.app?.userinfo?.sWorkshopId === "20240511102738235320239993832437" ? 1 : 0; const result = (await props.onGetDataSet({ name: `slave${i}`, configData: config, condition: { sSqlCondition: { ...conditonValues, iSort } }, isWait: true })) || {}; props.setTempRef(result); addState = { ...addState, ...result }; } props.setTempRef({}, true); if (isWait) { return addState; } else { props.onSaveState(addState); } }; return { ...props // 其他对象 }; }; // 弹窗 const RunningStatusModal = _props => { const { bNotModal } = _props; // 如果不是弹窗(异常事件提报用) if (bNotModal) return RunningStatus(_props); const props = businessTier(useCommonBase({ ..._props })); const tableName = "slave0"; const { [`${tableName}Data`]: tableData = [], [`${tableName}SelectedRowKeys`]: selectedRowKeys = [], [`${tableName}Config`]: config = {} } = props; // 按sClassifyName分组 const list = []; tableData.forEach(rowData => { const { sClassifyName } = rowData; const iIndex = list.findIndex(item => item.sClassifyName === sClassifyName); if (iIndex === -1) { list.push({ sClassifyName, group: [rowData] }); } else { list[iIndex].group.push(rowData); } }); // 把sClassifyName为空的放到最后 const iIndex = list.findIndex(item => item.sClassifyName === ""); if (iIndex !== -1) { const element = list.splice(iIndex, 1)[0]; list.push(element); } const contentProps = { ...props, bModal: true, dataList: list, selectedRowKeys, onTdClick: data => { if (!data) return; const { sId } = data; const addState = { [`${tableName}SelectedRowKeys`]: [sId], table1SelectedRowKeys: [sId], table1Data: [data], slave1SelectedRowKeys: [sId], slave1Data: [data], slave2Data: [{ sId: commonUtils.createSid() }] }; props.onSaveState(addState, (nextProps) => { // 如果配置了指令集,调用指令集 const btnConfig = props[ `${tableName}Config` ]?.gdsconfigformslave?.find(item => item.sControlName === "clickOpr"); if (btnConfig) { props.onExecInstructSet({ btnConfig, tableLineParams: { name: tableName, record: data }, nextProps }); } }); } }; const [record, setRecord] = useState({}); const [loading, setLoading] = useState(false); const bXingchejiluClick = () => { const { table1Data = [], slave2Data = [] } = props; const { tableS1Data = [], tableS1SelectedRowKeys = [] } = props.parentProps; const rowData1 = { ...table1Data[0], ...slave2Data[0], ...record }; const rowData2 = tableS1Data.find( item => item.sId === tableS1SelectedRowKeys[0] ); props.onExecInstructSet({ nextProps: { ...props.parentProps, temp0Data: [ { sId: rowData2.sId, tStartDate: rowData1.tStartDate, tEndDate: rowData1.tEndDate, sAbnormalEventId: rowData1.sId } ] }, btnConfig: { showName: "保存", sInstruct: JSON.stringify([ { opr: "procedure", config: { sproName: "sp_mes_SetMachineDateStatusCode", inMap: "temp0.sId,temp0.tStartDate,temp0.tEndDate,temp0.sAbnormalEventId" } } ]) }, callback: () => { props.parentProps.onSaveState({ refreshTableList: ["tableS5"] }); props.app.globalFun.onCloseCommonModal({ type: "commonModal" }); } }); }; const deviceTargetInfoClick = () => { const config = props.parentProps?.deviceTargetInfoConfig?.gdsconfigformslave?.find( item => item.sName === "sStatusNameSetting" ); if (config) { const { table1Data = [], slave2Data = [] } = props; setLoading(true); setTimeout(() => { props.onTableBtnClick({ name: "table1", record: { ...table1Data[0], ...slave2Data[0] }, config, onSuccess: () => { props.parentProps.onSaveState({ refreshDeviceTargetInfo: true }); props.app.globalFun.onCloseCommonModal({ type: "commonModal" }); } }); }, 100); } else { message.info("请先配置sStatusNameSetting!"); } }; const btnProps = { className: styles.settingBtn, type: "primary", size: "large", disabled: loading, onClick: () => { if (commonUtils.isEmptyArr(selectedRowKeys)) { message.warning("请先选择一个状态!"); return; } if (!commonBusiness.validateTable(props.slave2Config, props.slave2Data, props)) { return; } if (window.bXingchejiluModal) { bXingchejiluClick(); return; } if (window.deviceTargetInfoModal) { deviceTargetInfoClick(); return; } const bNotCheck = props.parentProps.table0Data === undefined; const parentTable0Data = cloneDeep( !bNotCheck ? props.parentProps.table0Data : props.parentProps.slaveData ); const iIndex = parentTable0Data.findIndex( item => item.sId === props.table0Data[0].sId ); if (iIndex === -1) { message.error("操作失败"); props.modalCallback({ closeModal: true }); return; } const { table1Data } = props; const { sId: sAbnormalEventId, sClassifyName, sName: sCode, sStatusName } = table1Data[0]; if (!bNotCheck) { if ( (parentTable0Data[iIndex].sPlcMachineStatusName === "运行" && sClassifyName !== "sType1") || (parentTable0Data[iIndex].sPlcMachineStatusName !== "运行" && sClassifyName === "sType1") ) { message.error("行车状态与当前选择不匹配,请重新选择!"); return; } } parentTable0Data[iIndex].sAbnormalEventId = sAbnormalEventId; parentTable0Data[iIndex].sClassifyName = sClassifyName; parentTable0Data[iIndex].sCode = sCode; parentTable0Data[iIndex].sStatusName = sStatusName; parentTable0Data[iIndex].handleType = parentTable0Data[iIndex].handleType || "update"; if (parentTable0Data[iIndex].bUnChanged) { } if (!bNotCheck) { props.parentProps.onSaveState( { table0Data: parentTable0Data }, nextProps => { if (parentTable0Data[iIndex].bUnChanged) { props.modalCallback({ closeModal: true }); } else { props.onExecInstructSet({ nextProps: nextProps, btnConfig: { showName: "保存", sInstruct: JSON.stringify([ { opr: "save", doNotRefresh: true, data: [ { tablename: "mftproductionreportslave", srcDataset: "table0" } ] } ]) }, callback: () => { props.modalCallback({ closeModal: true }); } }); } } ); } else { props.onExecInstructSet({ nextProps: { ...props.parentProps, slaveData: parentTable0Data }, btnConfig: { showName: "保存", sInstruct: JSON.stringify([ { opr: "save", data: [ { tablename: "mftAbnormalEventReportMaster", srcDataset: "slave" } ] } ]) }, callback: () => { props.modalCallback({ closeModal: true }); } }); } // const btnConfig = config?.gdsconfigformslave?.find( // item => item.sControlName === "BtnSetting" // ); // props.onExecInstructSet({ // btnConfig, // callback: () => { // props.modalCallback({ refreshTable: true, closeModal: true }); // } // }); } }; let TimeComponent = ""; if (window.bXingchejiluModal) { const showTypeProps = { app: props.app, getFloatNum: props.getFloatNum, getDateFormat: props.getDateFormat, iColValue: 12, name: tableName, showConfig: { showName: "开始时间", sName: "tStartDate", costomStyle: styles.noBorderRight, sDateFormat: "YYYY-MM-DD HH:mm" }, record, sId: commonUtils.createSid(), textArea: true, enabled: true, dataValue: record.tStartDate, bTable: true, bViewTable: true, onChange: (...args) => { setRecord(pre => ({ ...pre, ...args[2] })); // if (table1Data.length) { // props.onSaveState({ table1Data: [{ sMemo: args[2].dataValue }] }); // } } }; const showTypeProps1 = { app: props.app, getFloatNum: props.getFloatNum, getDateFormat: props.getDateFormat, iColValue: 12, name: tableName, showConfig: { showName: "结束时间", sName: "tEndDate", sDateFormat: "YYYY-MM-DD HH:mm" }, record, sId: commonUtils.createSid(), textArea: true, enabled: true, dataValue: record.tEndDate, bTable: true, bViewTable: true, onChange: (...args) => { setRecord(pre => ({ ...pre, ...args[2] })); // if (table1Data.length) { // props.onSaveState({ table1Data: [{ sMemo: args[2].dataValue }] }); // } } }; TimeComponent = (
); } const [reportInfoVisible, setReportInfoVisible] = useState(false); const reportRef = useRef(null); const handleReportInfo = (config = null) => { reportRef.current = config; setReportInfoVisible(!reportInfoVisible); }; const { slave2Config: slave2ConfigOld, slave2Data = [] } = props; const slave2Config = props.onMergeTableConfig(slave2ConfigOld); const viewConfigsOld = slave2Config?.gdsconfigformslave?.filter( item => item.sName && item.bControl && item.sControlName.indexOf("Btn") === -1 && item.sControlName.indexOf("_") === -1 ); const viewConfigs = cloneDeep(viewConfigsOld); // const iIndex1 = // viewConfigs?.findIndex(item => item.sName === "bRepairRequest") || -1; // if (iIndex1 !== -1 && !slave2Data[0]?.sAbnormalStatusName?.startsWith("W")) { // viewConfigs[iIndex1].iTag = 1; // } const viewProps = { ...props, viewConfigs, tableConfig: slave2Config, iColValueView: 24, viewRow: slave2Data[0], tableName: 'slave2', enabled: true, handleReportInfo }; return (
{TimeComponent}
); }; // 非弹窗 const RunningStatus = props => { const { tableName, viewRow = {} } = props; const { [`${tableName}Data`]: tableData = [], [`${tableName}SelectedRowKeys`]: selectedRowKeys = [] } = props; // 按sClassifyName分组 const list = []; tableData.forEach(rowData => { const { sClassifyName } = rowData; const iIndex = list.findIndex(item => item.sClassifyName === sClassifyName); if (iIndex === -1) { list.push({ sClassifyName, group: [rowData] }); } else { list[iIndex].group.push(rowData); } }); // 把sClassifyName为空的放到最后 const iIndex = list.findIndex(item => item.sClassifyName === ""); if (iIndex !== -1) { const element = list.splice(iIndex, 1)[0]; list.push(element); } const { sAbClassifycode, sAbsStatusName } = viewRow; // 根据sAbClassifycode、sAbsStatusName设置选中数据 useEffect( () => { const selectData = tableData.find( item => item.sClassifyName === sAbClassifycode && item.sStatusName === sAbsStatusName ); if (selectData) { props.onSaveState({ [`${tableName}SelectedRowKeys`]: [selectData.sId] }); } else { props.onSaveState({ [`${tableName}SelectedRowKeys`]: [] }); } }, [sAbClassifycode, sAbsStatusName, tableData.length] ); const contentProps = { ...props, dataList: list, selectedRowKeys, onTdClick: data => { if (!data) return; const { sPlcMachineStatusName, bUnChanged } = viewRow; if (commonUtils.isEmptyObject(viewRow)) { message.info("请先选择一条行车记录!", 3); return; } if (viewRow.bSaveAbnormal) { return; } if (bUnChanged) { message.info("请先填写新增行车记录的结束时间!", 3); return; } // if (sPlcMachineStatusName === "运行" && data.sClassifyName !== "sType1") { // message.info("设备状态为【运行】时只能选择【行车状态行】!", 3); // return; // } // if (sPlcMachineStatusName !== "运行" && data.sClassifyName === "sType1") { // message.info("设备状态非【运行】时不能选择【行车状态行】!", 3); // return; // } const { sId } = data; props.onSaveState( { [`${tableName}SelectedRowKeys`]: [sId] }, nextProps => { props.onChange(data, nextProps); } ); } }; return ; }; // 内容区域 const RunningContent = props => { const [data, setData] = useState([]); // 根据dataList拼接数据 const { dataList = [], selectedRowKeys = [] } = props; useEffect( () => { if (!dataList.length) return; const tempData = []; dataList.filter(item => item.sClassifyName).forEach(item => { const { sClassifyName, group } = item; const rowspan = Math.ceil(group.length / 6); for (let i = 0; i < rowspan; i++) { const [title, className, classNameTd] = sTypeJson[sClassifyName]; const temp = { title, rowspan, type: i === 0 ? 1 : 2, className, status: [ ...group.filter((_, index) => index >= i * 6 && index < i * 6 + 6) ].map(rowData => { const { sStatusName, sId, sResponsibilityType, sResponsibilityColor } = rowData; const [name, status] = sStatusName.split(" "); return { name, status, className: selectedRowKeys.includes(sId) ? classNameTd : "", rowData: { ...rowData, sClassifyName1: title }, // 添加停机原因字段 responsibilityType: sResponsibilityType || "", responsibilityColor: sResponsibilityColor || "" }; }) }; const statusSize = temp.status.length; new Array(6 - statusSize).fill("").forEach(() => { temp.status.push({}); }); tempData.push(temp); } }); setData(tempData); }, [JSON.stringify(dataList), JSON.stringify(selectedRowKeys)] ); // 计算停机原因的rowspan const calculateResponsibilityRowspan = (data) => { const rowspans = []; const colors = []; // 存储每行的颜色 let currentValue = null; let currentColor = null; let currentCount = 0; let startIndex = 0; // 遍历所有行,计算连续的相同responsibilityType的行数 for (let i = 0; i < data.length; i++) { const trData = data[i]; const responsibilityType = trData.status[0]?.responsibilityType || ""; const responsibilityColor = trData.status[0]?.responsibilityColor || ""; if (responsibilityType === currentValue) { currentCount++; } else { // 处理前一段相同值 if (currentValue !== null) { for (let j = startIndex; j < startIndex + currentCount; j++) { rowspans[j] = j === startIndex ? currentCount : 0; colors[j] = currentColor; // 设置颜色 } } // 开始新的计数 currentValue = responsibilityType; currentColor = responsibilityColor; currentCount = 1; startIndex = i; } } // 处理最后一段 if (currentValue !== null) { for (let j = startIndex; j < startIndex + currentCount; j++) { rowspans[j] = j === startIndex ? currentCount : 0; colors[j] = currentColor; // 设置颜色 } } return { rowspans, colors }; }; const pattern = title => { const regex = /(.+?)\((.+)\)/; const result = title.match(regex); if (result) { return (

{result[1]}

({result[2]})

); } else { return title; } }; // 计算停机原因的rowspan数组和颜色数组 const { rowspans: responsibilityRowspans, colors: responsibilityColors } = calculateResponsibilityRowspan(data); return (
{data.map((trData, trIndex) => ( {/* 第一列:停机原因列 */} {responsibilityRowspans[trIndex] > 0 && ( )} {trData.type === 1 && ( )} {trData.status.map(tdData => ( ))} ))}

{trData.status[0]?.responsibilityType || ""}

{pattern(trData.title)}

{tdData.name}

{tdData.status}

); }; export default RunningStatusModal;