package org.springblade.mdm.program.service; import lombok.AllArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springblade.core.log.exception.ServiceException; import org.springblade.core.tool.utils.Func; import org.springblade.mdm.flow.constants.FlowConstant; import org.springblade.mdm.flow.entity.FlowProgramFile; import org.springblade.mdm.flow.service.FlowCommonService; import org.springblade.mdm.flow.service.FlowProgramFileService; import org.springblade.mdm.flow.service.FlowProgramProperties; import org.springblade.mdm.program.entity.NcNode; import org.springblade.mdm.utils.EntityUtil; import org.springframework.beans.BeanUtils; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import java.util.List; import java.util.Optional; /** * 程序节点自动创建服务,在 试切流程 程序编制 节点 审核通过后调用 * * @author yangys */ @Slf4j @Service @AllArgsConstructor public class NcNodeAutoCreateService { private final NcNodeService ncNodeService; private final FlowCommonService flowCommonService; private final FlowProgramFileService flowProgramFileService; public static final String TRY_NAME = "试切"; public static final String CURE_NAME = "固化"; public static final String DEVIATION_NAME = "偏离"; /** * 创建树到机床级别 * @param programProperties 程序属性 */ @Transactional public NcNode createNodeTreeToMachineGroup(FlowProgramProperties programProperties) { NcNode root; if(programProperties.getProcessDefinitionKey().equals(FlowConstant.TRY_PROCESS_KEY)){ if(Func.isEmpty(programProperties.getDeviation()) || (FlowConstant.Y.equals(programProperties.getHasCuredProgram()) && FlowConstant.N.equals(programProperties.getCureProgramUseable()))){ //普通试切,或者有固化不可用,建立试切节点 //试切根节点 root = rootNodeByName(TRY_NAME); if (root == null) { root = createTryNode(); } }else{ //有偏离 root = rootNodeByName(DEVIATION_NAME); if(root == null){ root = createDeviationNode(); } } }else if(programProperties.getProcessDefinitionKey().equals(FlowConstant.CURE_PROCESS_KEY)){ root = rootNodeByName(CURE_NAME); if(root == null){ root = createCureNode(); } }else{ throw new ServiceException("流程定义不在范围内"); } //创建产品型号节点 NcNode productModelNode = createNodeIfNotExists(programProperties.getProductModel(),NcNode.TYPE_PRODUCT_MODEL, root,programProperties,null); //零组件号节点 NcNode drawingNoNode = createNodeIfNotExists(programProperties.getDrawingNo(),NcNode.TYPE_DRAWING_NO, productModelNode,programProperties,null); //工艺版次节点 //NcNode craftEditionNode = createNodeIfNotExists(programProperties.getCraftEdition(),NcNode.TYPE_CRAFT_EDITION, drawingNoNode,programProperties); //工序号节 NcNode processNoNode = createNodeIfNotExists(programProperties.getProcessNo(),NcNode.TYPE_PROCESS_NO, drawingNoNode,programProperties,null); //工序版次节点 NcNode processEditionNode = createNodeIfNotExists(programProperties.getProcessEdition(),NcNode.TYPE_PROCESS_EDITION, processNoNode,programProperties,null); //加工机床节点 return createNodeIfNotExists(programProperties.getMachineGroupCode(),NcNode.TYPE_MACHINE_GROUP, processEditionNode,programProperties,null); } /* @Transactional public NcNode createNodeTreeToProcessEdition(FlowProgramProperties programProperties) { NcNode root; if(programProperties.getProcessDefinitionKey().equals(FlowContants.TRY_PROCESS_KEY)){ if(Func.isEmpty(programProperties.getDeviation()) || (FlowContants.Y.equals(programProperties.getHasCuredProgram()) && FlowContants.N.equals(programProperties.getCureProgramUseable()))){ //普通试切,或者有固化不可用,建立试切节点 //试切根节点 root = rootNodeByName(TRY_NAME); if (root == null) { root = createTryNode(); } }else{ //有偏离 root = rootNodeByName(DEVIATION_NAME); if(root == null){ root = createDeviationNode(); } } }else if(programProperties.getProcessDefinitionKey().equals(FlowContants.CURE_PROCESS_KEY)){ root = rootNodeByName(CURE_NAME); if(root == null){ root = createCureNode(); } }else{ throw new ServiceException("流程定义不在范围内"); } //创建产品型号节点 NcNode productModelNode = createNodeIfNotExists(programProperties.getProductModel(),NcNode.TYPE_PRODUCT_MODEL, root,programProperties,null); //零组件号节点 NcNode drawingNoNode = createNodeIfNotExists(programProperties.getDrawingNo(),NcNode.TYPE_DRAWING_NO, productModelNode,programProperties,null); //工艺版次节点 //NcNode craftEditionNode = createNodeIfNotExists(programProperties.getCraftEdition(),NcNode.TYPE_CRAFT_EDITION, drawingNoNode,programProperties); //工序号节 NcNode processNoNode = createNodeIfNotExists(programProperties.getProcessNo(),NcNode.TYPE_PROCESS_NO, drawingNoNode,programProperties,null); //工序版次节点 NcNode processEditionNode = createNodeIfNotExists(programProperties.getProcessEdition(),NcNode.TYPE_PROCESS_EDITION, processNoNode,programProperties,null); //加工机床节点 return createNodeIfNotExists(programProperties.getMachineCode(),NcNode.TYPE_MACHINE_CODE, processEditionNode,programProperties,null); } */ /** * 根据流程信息,自动创建各个节点,包括程序节点 * @param programProperties 程序属性 * @return 程序包节点实例 */ @Transactional public NcNode createNodeTreeWithProgram(FlowProgramProperties programProperties,Integer versionNumber) { //,int rootNodeCatgory = 1:试切,2固化,3偏离 NcNode programPkdNode = createTreeToPackage(programProperties,versionNumber); //删除之前创建过的程序文件节点(因为重复在编制节点审批),避免重复数据 ncNodeService.deleteSubNodes(programPkdNode.getId()); List programFiles = flowProgramFileService.lambdaQuery().eq(FlowProgramFile::getProcessInstanceId, programProperties.getProcessInstanceId()).list(); for (FlowProgramFile programFile : programFiles) { createProgramFileNode(programFile, programPkdNode,versionNumber);//所有文件包括程序和其他,都需要建立节点 } return programPkdNode; } /** * 建立程序文件节点 * @param programFile 流程文件 * @param programPkdNode 程序包名 节点,程序节点的 上级 * @param versionNumber 版本号 */ private void createProgramFileNode(FlowProgramFile programFile, NcNode programPkdNode, Integer versionNumber) { //此处应避免重复创建 NcNode node = new NcNode(); BeanUtils.copyProperties(programPkdNode, node); EntityUtil.clearBaseProperties(node); node.setNodeType(NcNode.TYPE_PROGRAM_FILE); node.setName(programFile.getName());//文件名, node.setIsLastEdition(1); node.setFlowProgramFileId(programFile.getId()); if(versionNumber == null){ node.setVersionNumber(1); }else { node.setVersionNumber(versionNumber); } node.setParentId(programPkdNode.getId()); node.setParentIds(programPkdNode.getParentIds()+","+programPkdNode.getId()); ncNodeService.save(node); } /** * 创建节点到程序包级别 * @param programProperties 程序属性 * @return 程序包名节点(最末级) */ @Transactional public NcNode createTreeToPackage(FlowProgramProperties programProperties,Integer versionNumber) { NcNode machineGroupNode = createNodeTreeToMachineGroup(programProperties); //NcNode processEditionNode = this.ncNodeService.getById(machineCodeNode.getParentId()); //获取工序版次下其他机床名,存在则删除 /* ncNodeService.lambdaUpdate().eq(NcNode::getNodeType,NcNode.TYPE_MACHINE_GROUP) .eq(NcNode::getParentId,processEditionNode.getId()).eq(NcNode::getIsLastEdition,1) .ne(NcNode::getName,machineCodeNode.getName()).remove(); */ //保持加工机床是最新下发任务的机床,不是新建一个机床节点,插叙工序版次下是否有其他的机床(零件号一致,工序号,工序版次一致) //获取 //程序包名在机床组下级 20250913 String programPkgName = NcNodeService.genProgramName(programProperties.getDrawingNo(),programProperties.getProcessNo(),programProperties.getProcessEdition()); return createNodeIfNotExists(programPkgName ,NcNode.TYPE_PROGRAM_PACKAGE, machineGroupNode,programProperties,versionNumber); } /** * 不存在则创建节点 * @param name 节点名称 * @param nodeType 节点类型 * @param parentNode 父节点 * @param programProperties 流程程序属性 * @return 创建或已存在的节点或 */ NcNode createNodeIfNotExists(String name,String nodeType,NcNode parentNode,FlowProgramProperties programProperties,Integer versionNumber) { Optional nodeOpt = this.ncNodeService.lambdaQuery().eq(NcNode::getName,name).eq(NcNode::getNodeType,nodeType) .eq(NcNode::getParentId,parentNode.getId()).eq(NcNode::getIsLastEdition,1).oneOpt(); if(nodeOpt.isPresent()){ return nodeOpt.get(); }else { NcNode ncNode = new NcNode(); ncNode.setName(name); ncNode.setParentId(parentNode.getId()); ncNode.setParentIds(parentNode.getParentIds() + "," + parentNode.getId()); ncNode.setNodeType(nodeType); if(versionNumber == null){ ncNode.setVersionNumber(1); }else{ ncNode.setVersionNumber(versionNumber); } //程序包节点和程序文件节点数据 if(NcNode.TYPE_PROGRAM_PACKAGE.equals(nodeType) || NcNode.TYPE_PROGRAM_FILE.equals(nodeType)){ ncNode.setProcessInstanceId(programProperties.getProcessInstanceId()); ncNode.setDrawingNo(programProperties.getDrawingNo()); ncNode.setDrawingNoEdition(programProperties.getDrawingNoEdition()); ncNode.setCraftEdition(programProperties.getCraftEdition()); ncNode.setProcessNo(programProperties.getProcessNo()); ncNode.setProcessEdition(programProperties.getProcessEdition()); ncNode.setProcessName(programProperties.getProcessName()); ncNode.setMachineCode(programProperties.getMachineCode()); ncNode.setMachineGroupCode(programProperties.getMachineGroupCode()); ncNode.setProductModel(programProperties.getProductModel()); ncNode.setDeviation(programProperties.getDeviation()); if(NcNode.TYPE_PROGRAM_PACKAGE.equals(nodeType)) {//程序包节点,分配程序编号 ncNode.setProgramNo(programProperties.getProgramNo()); } } ncNode.setIsLastEdition(1); ncNodeService.save(ncNode); return ncNode; } } NcNode rootNodeByName(String name){ Optional rootOpt = ncNodeService.lambdaQuery().eq(NcNode::getName, name).eq(NcNode::getParentId, 0).oneOpt(); return rootOpt.orElse(null); } /** * 创建试切节点(根) */ NcNode createTryNode() { NcNode ncNode = new NcNode(); ncNode.setId(1L); ncNode.setName(TRY_NAME); ncNode.setParentId(0L); ncNode.setParentIds("0"); ncNode.setNodeType("10"); ncNode.setVersionNumber(1); ncNodeService.save(ncNode); return ncNode; } /** * 创建固化节点(根) */ NcNode createCureNode() { NcNode ncNode = new NcNode(); ncNode.setId(2L); ncNode.setName(CURE_NAME); ncNode.setParentId(0L); ncNode.setParentIds("0"); ncNode.setNodeType("10"); ncNode.setVersionNumber(1); ncNodeService.save(ncNode); return ncNode; } NcNode createDeviationNode() { NcNode ncNode = new NcNode(); ncNode.setId(3L); ncNode.setName(DEVIATION_NAME); ncNode.setParentId(0L); ncNode.setParentIds("0"); ncNode.setNodeType("10"); ncNode.setVersionNumber(1); ncNodeService.save(ncNode); return ncNode; } }