package org.springblade.mdm.flow.excution.cure; import lombok.extern.slf4j.Slf4j; import org.apache.commons.io.IOUtils; import org.springblade.core.log.exception.ServiceException; import org.springblade.core.oss.OssTemplate; import org.springblade.core.oss.model.BladeFile; import org.springblade.core.tool.api.R; import org.springblade.core.tool.utils.DateUtil; import org.springblade.mdm.basesetting.machine.service.MachineService; import org.springblade.mdm.basesetting.machine.entity.Machine; import org.springblade.mdm.commons.contants.ParamConstants; import org.springblade.mdm.flow.entity.FlowProgramFile; import org.springblade.mdm.flow.excution.dispatch.FinishDataHandler; 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.program.service.NcNodeAutoCreateService; import org.springblade.mdm.program.service.NcNodeHisService; import org.springblade.mdm.program.service.NcNodeService; import org.springblade.mdm.program.service.ProgramAnnotationService; import org.springblade.mdm.program.service.programannotation.AnnotationProperties; import org.springblade.mdm.program.service.programannotation.AnnotationUtil; import org.springblade.mdm.program.service.programannotation.MachineAnnotationConfig; import org.springblade.mdm.utils.EntityUtil; import org.springblade.system.feign.ISysClient; import org.springblade.system.pojo.entity.DictBiz; import org.springframework.beans.BeanUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStream; import java.time.LocalDate; import java.time.LocalDateTime; import java.util.Arrays; import java.util.Date; import java.util.List; import java.util.Optional; /** * 普通派工完成数据处理器,功能:插入审批表数据,DispatchFinishListener调用 */ @Slf4j @Component("normalCureFinishDataHandler") public class NormalCureFinishDataHandler implements FinishDataHandler { @Autowired private MachineAnnotationConfig config; @Autowired private FlowProgramFileService flowProgramFileService; @Autowired private NcNodeService nodeService; @Autowired private NcNodeAutoCreateService ncNodeAutoCreateService; @Autowired private MachineService machineService; @Autowired private OssTemplate ossTemplate; @Autowired private ISysClient sysClient; @Autowired private ProgramAnnotationService programAnnotationService; /** * 默认有效期间(月数),2年 */ private static final int DEFAULT_VALID_MONTH = 24; /** * DispatchFinishListener中调用 * @param flowProps 流程属性 */ public void handleData(FlowProgramProperties flowProps) { //需要固化的节点 NcNode pkgNode = nodeService.lambdaQuery().eq(NcNode::getProcessInstanceId, flowProps.getProcessInstanceId()).one(); //原节点保留不动,置为老版本 pkgNode.setIsLastEdition(0); pkgNode.setIsLocked(1); nodeService.updateById(pkgNode); nodeService.getBaseMapper().deleteById(pkgNode.getParentId());//删除机床组节点 //List historyProgramPackageNodes = nodeService.getTryNodeHistory(pkgNode); try { moveNodeToCuredTree(pkgNode, flowProps);//, historyProgramPackageNodes //固化不锁定,后续还可能使用该固化程序 //nodeService.lockSameNameOtherMachineGroupProgramPackage(pkgNode); /* nodeService.lambdaUpdate().eq(NcNode::getDrawingNo,pkgNode.getDrawingNo()) .eq(NcNode::getProcessNo,pkgNode.getProcessNo()) .eq(NcNode::getName,pkgNode.getName()) .ne(NcNode::getMachineGroupCode,pkgNode.getMachineGroupCode()) .eq(NcNode::getIsCured,1) .set(NcNode::getIsLocked,NcNode.LOCKED) .set(NcNode::getRemark,"回传固化同名程序锁定") .update(); */ }catch(Exception e) { log.error("固化流程完成异常",e); throw new ServiceException("普通固化执行异常"+e.getMessage()); } } /** * 将节点和历史节点挪动到固化的同级节点下 * @param pkgNode1 要固化的节点 * @param programProperties 流程属性 */ void moveNodeToCuredTree(NcNode pkgNode1, FlowProgramProperties programProperties) throws IOException { //创建节点到机床级别.(固化树) NcNode machineGroupNode = ncNodeAutoCreateService.createNodeTreeToMachineGroup(programProperties); //新建一个节点,作为固化节点, this.nodeService.lambdaUpdate().likeRight(NcNode::getParentIds, machineGroupNode.subNodeParentIds()) .in(NcNode::getNodeType, Arrays.asList(NcNode.TYPE_PROGRAM_PACKAGE,NcNode.TYPE_PROGRAM_FILE)) .set(NcNode::getIsLastEdition,0).set(NcNode::getIsLocked,1).update(); List programNodes = nodeService.getProgramFilesByPackageId(pkgNode1.getId()); boolean tryPkgNodeHasChild = !programNodes.isEmpty(); //新建固化节点 NcNode cureNode = createNewCureNodeByTargetNode(pkgNode1,tryPkgNodeHasChild); cureNode.setParentId(machineGroupNode.getId()); cureNode.setParentIds(machineGroupNode.subNodeParentIds()); nodeService.save(cureNode); this.copyNonProgramNodes(pkgNode1,cureNode); /* List oriProgramNodes = nodeService.lambdaQuery().eq(NcNode::getParentId,pkgNode1.getId()).list(); FlowProgramFile pfile; for(NcNode oldProgramNode : oriProgramNodes){ oldProgramNode.setParentIds(pkgNode1.subNodeParentIds()); oldProgramNode.setIsLastEdition(0); //当前固化程序包名下的“其他文件”非程序文件。不设置为老版本,直接挪到固化树下,两个网络之间只交换程序文件,其他文件只能保留 //其他文件,需要复制到新建的固化节点下(程序文件不复制) pfile = flowProgramFileService.getById(oldProgramNode.getFlowProgramFileId()); if(!pfile.isProgram()) { NcNode newFileNode = new NcNode(); BeanUtils.copyProperties(oldProgramNode, newFileNode); EntityUtil.clearBaseProperties(newFileNode); newFileNode.setParentId(cureNode.getId()); newFileNode.setParentIds(cureNode.subNodeParentIds()); newFileNode.setIsLastEdition(1); nodeService.save(newFileNode); } } nodeService.updateBatchById(oriProgramNodes); */ this.addNewProgramNode(cureNode,pkgNode1.getProcessInstanceId()); } /** * 从待固化节点复制非程序文件节点到固化节点下 * @param oriPkgNode 待固化节点 * @param cureNode 固化节点 */ void copyNonProgramNodes(NcNode oriPkgNode,NcNode cureNode){ List oriProgramNodes = nodeService.lambdaQuery().eq(NcNode::getParentId,oriPkgNode.getId()).list(); FlowProgramFile pfile; for(NcNode oldProgramNode : oriProgramNodes){ oldProgramNode.setParentIds(oriPkgNode.subNodeParentIds()); oldProgramNode.setIsLastEdition(0); //当前固化程序包名下的“其他文件”非程序文件。不设置为老版本,直接挪到固化树下,两个网络之间只交换程序文件,其他文件只能保留 //其他文件,需要复制到新建的固化节点下(程序文件不复制) /* pfile = flowProgramFileService.getById(oldProgramNode.getFlowProgramFileId()); if(!pfile.isProgram()) { NcNode newFileNode = new NcNode(); BeanUtils.copyProperties(oldProgramNode, newFileNode); EntityUtil.clearBaseProperties(newFileNode); newFileNode.setParentId(cureNode.getId()); newFileNode.setParentIds(cureNode.subNodeParentIds()); newFileNode.setIsLastEdition(1); nodeService.save(newFileNode); } */ } nodeService.updateBatchById(oriProgramNodes); } /** * 加入新的程序节点 * @param cureNode 固化节点 * @param processInstanceId 流程实例id * @throws IOException */ void addNewProgramNode(NcNode cureNode,String processInstanceId) throws IOException { Machine machine = machineService.getByCode(cureNode.getMachineCode()); List annoDicts = programAnnotationService.getAnnotionDictList(); //新的流程文件,需要在包节点下新建,不能用老的包节点 List files = flowProgramFileService.lambdaQuery().eq(FlowProgramFile::getProcessInstanceId,processInstanceId).list(); for(FlowProgramFile flowProgramFile : files){ NcNode newProgNode = new NcNode(); BeanUtils.copyProperties(cureNode,newProgNode); EntityUtil.clearBaseProperties(newProgNode); newProgNode.setName(flowProgramFile.getName()); newProgNode.setNodeType(NcNode.TYPE_PROGRAM_FILE); newProgNode.setParentId(cureNode.getId()); newProgNode.setParentIds(cureNode.subNodeParentIds()); newProgNode.setIsLastEdition(1); newProgNode.setFlowProgramFileId(flowProgramFile.getId()); newProgNode.setIsCured(1); setGhAnnotation(flowProgramFile,machine.getControlSystem(),annoDicts); nodeService.save(newProgNode); } } /** * 复制待固化节点数据,创建一个新的固化节点 * @param waitingCureNode 待固化节点 * @param tryPkgNodeHasProgramFiles 是否有程序文件 * @return 固化节点 */ NcNode createNewCureNodeByTargetNode(NcNode waitingCureNode,boolean tryPkgNodeHasProgramFiles){ //新建一个节点,作为固化节点,老节点保留不动 NcNode cureNode = new NcNode(); BeanUtils.copyProperties(waitingCureNode, cureNode); EntityUtil.clearBaseProperties(cureNode); cureNode.setIsCured(1); cureNode.setIsLocked(NcNode.UNLOCK); cureNode.setIsLastEdition(1); cureNode.setExpireDate(calculateExpireDate());//设置过期日期 cureNode.setHisSerial(nodeService.calculateHistorySerial(cureNode)); Optional optOldCuredPackageNode = nodeService.lambdaQuery().eq(NcNode::getName,waitingCureNode.getName()) .eq(NcNode::getProcessNo,waitingCureNode.getProcessNo()) .eq(NcNode::getProcessEdition,waitingCureNode.getProcessEdition()) .eq(NcNode::getIsLastEdition,1).eq(NcNode::getIsCured,1).oneOpt(); if(optOldCuredPackageNode.isEmpty() && tryPkgNodeHasProgramFiles){ //之前 没有已固化的程序包名,则直接更新版本号,如果有,那就使用node现在的版本号,因为不可用转为试切,审批完成已经升级version //tryPkdNodeHasProgramFiles 试切程序包下有程序文件才需要升级版本(没有文件的是车床,无文件,直接等待回传) cureNode.upgradeVersionNumber(); } return cureNode; } /** * 设置固化注释,实现方式,获取文件字节下,修改后替换文件 * @param flowProgramFile oss 文件 * */ void setGhAnnotation(FlowProgramFile flowProgramFile,String controlSystem,List annoDicts) throws IOException { String ossName = flowProgramFile.getOssName(); // try(InputStream ins = ossTemplate.statFileStream(ossName);){ byte[] bytes = IOUtils.toByteArray(ins); ByteArrayInputStream byteInputStream = new ByteArrayInputStream(bytes); List annoDictList = programAnnotationService.getAnnotionDictList(); AnnotationProperties annoProps = config.getConfigMap().get(controlSystem); if(annoProps == null){ annoProps = AnnotationProperties.getDefault(); } InputStream finishedStream =AnnotationUtil.setAnnotationAndGetInputStream(byteInputStream, AnnotationUtil.GH, annoProps.getStatusLineIndex(), controlSystem, annoDictList); try(finishedStream) { finishedStream.reset(); BladeFile bfile = ossTemplate.putFile(flowProgramFile.getName(), finishedStream); //替换原有的文件地址 flowProgramFile.setOssName(bfile.getName()); flowProgramFileService.updateById(flowProgramFile); } } } /** * 计算有效期 * @return 过期日 */ private Date calculateExpireDate() { R validMonResult = sysClient.getParamValue(ParamConstants.CURE_VALID_MONTH_KEY); int month = DEFAULT_VALID_MONTH; if(validMonResult.isSuccess() && validMonResult.getData()!=null){ month = Integer.parseInt(validMonResult.getData()); } LocalDate now = LocalDate.now(); return DateUtil.toDate(now.plusMonths(month)); } }