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.core.tool.utils.Func; import org.springblade.mdm.basesetting.machine.MachineService; import org.springblade.mdm.basesetting.machine.entity.Machine; import org.springblade.mdm.commons.contants.ParamConstants; import org.springblade.mdm.flow.constants.FlowContants; import org.springblade.mdm.flow.entity.ApproveRecord; import org.springblade.mdm.flow.entity.FlowProgramFile; import org.springblade.mdm.flow.excution.dispatch.FinishDataHandler; import org.springblade.mdm.flow.service.ApproveRecordService; 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.entity.NcProgramApproved; import org.springblade.mdm.program.service.NcNodeAutoCreateService; import org.springblade.mdm.program.service.NcNodeService; import org.springblade.mdm.program.service.NcProgramApprovedService; import org.springblade.mdm.program.service.ProgramAnnotationService; 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.util.Arrays; import java.util.Date; import java.util.List; /** * 普通派工完成数据处理器,功能:插入审批表数据,DispatchFinishListener调用 */ @Slf4j @Component("normalCureFinishDataHandler") public class NormalCureFinishDataHandler implements FinishDataHandler { @Autowired private NcProgramApprovedService approvedService; @Autowired private ApproveRecordService approveRecordService; @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.setIsCured(1); pkgNode.setIsLocked(NcNode.UNLOCK); //设置过期日期 pkgNode.upgradeVersionNumber(); pkgNode.setExpireDate(calculateExpireDate()); nodeService.updateById(pkgNode); List historyProgramPackageNodes = nodeService.getNodeHistory(pkgNode); try { moveNodeToCuredTree(pkgNode, historyProgramPackageNodes, flowProps); }catch(Exception e) { log.error("固化流程完成异常",e); throw new ServiceException("普通固化执行异常"+e.getMessage()); } addApproveTable(pkgNode,flowProps); updateApproveRecordNodeId(flowProps.getProcessInstanceId(), pkgNode.getId()); } /** * 将节点和历史节点挪动到固化的同级节点下 * @param pkgNode 要挪动的节点 * @param historyProgramPackageNodes 程序包名 历史节点 */ void moveNodeToCuredTree(NcNode pkgNode,List historyProgramPackageNodes, FlowProgramProperties programProperties) throws IOException { //创建节点到机床级别.(固化树) NcNode machineNode = ncNodeAutoCreateService.createNodeTreeToMachine(programProperties); pkgNode.setParentId(machineNode.getParentId()); pkgNode.setParentIds(machineNode.getParentIds());//更新上级节点,下面还要用应为在historyProgramPackageNodes中的和这个不是一个实例 //机床下现在没有文件了,程序包名升级与机床同级了,改为找到机床同级程序包名更新了 //TODO 这个parentIds是不是不够?,不够,一个机床下多个程序包的情况不行吧,但是按照树,多个程序包不太现实 this.nodeService.lambdaUpdate().likeRight(NcNode::getParentIds, machineNode.getParentIds()) .in(NcNode::getNodeType, Arrays.asList(NcNode.TYPE_PROGRAM_PACKAGE,NcNode.TYPE_PROGRAM_FILE)) .ne(NcNode::getId,pkgNode.getId())//不要更新新固化的节点new .set(NcNode::getIsLastEdition,0).set(NcNode::getIsLocked,1).update(); for(NcNode hisPackageNode : historyProgramPackageNodes){ if(!hisPackageNode.getId().equals(pkgNode.getId())){ hisPackageNode.setIsLastEdition(0); } hisPackageNode.setParentId(machineNode.getParentId()); hisPackageNode.setParentIds(machineNode.getParentIds());//程序包与机床节点同级 //处理程序包下层的程序节点111 List programNodes = nodeService.lambdaQuery().eq(NcNode::getParentId,hisPackageNode.getId()).list(); FlowProgramFile pfile; for(NcNode programNode : programNodes){ programNode.setParentIds(hisPackageNode.getParentIds()+","+hisPackageNode.getId()); programNode.setIsLastEdition(0); pfile = flowProgramFileService.getById(programNode.getFlowProgramFileId()); if(programNode.getParentId().equals(pkgNode.getId()) && !pfile.isProgram()){ //当前固化程序包名下的“其他文件”非程序文件。不设置为老版本,直接挪到固化树下,两个网络之间只交换程序文件,其他文件只能保留 programNode.setIsLastEdition(1); } } nodeService.updateBatchById(programNodes); } nodeService.updateBatchById(historyProgramPackageNodes); Machine machine = machineService.getByCode(pkgNode.getMachineCode()); List annoDicts = programAnnotationService.getAnnotionList(); //新的流程文件,需要在包节点下新建,不能用老的 List files = flowProgramFileService.lambdaQuery().eq(FlowProgramFile::getProcessInstanceId,pkgNode.getProcessInstanceId()).list(); for(FlowProgramFile flowProgramFile : files){ NcNode newProgNode = new NcNode(); BeanUtils.copyProperties(pkgNode,newProgNode); newProgNode.setName(flowProgramFile.getName()); newProgNode.setNodeType(NcNode.TYPE_PROGRAM_FILE); newProgNode.setParentId(pkgNode.getId()); newProgNode.setParentIds(pkgNode.getParentIds()+","+pkgNode.getId()); newProgNode.setIsLastEdition(1); newProgNode.setFlowProgramFileId(flowProgramFile.getId()); newProgNode.setIsCured(1); nodeService.save(newProgNode); //修改文件内容更新注释,并更新文件数据的地址 ///替换注释后总是不行啊 setGhAnnotation(flowProgramFile,machine.getMachineGroupCode(),annoDicts); //flowProgramFileService.updateById(flowProgramFile); } } /** * 设置固化注释,实现方式,获取文件字节下,修改后替换文件 * @param flowProgramFile oss 文件 * */ void setGhAnnotation(FlowProgramFile flowProgramFile,String machineGroup,List annoDicts) throws IOException { String ossName = flowProgramFile.getOssName(); // try(InputStream ins = ossTemplate.statFileStream(ossName);){ byte[] bytes = IOUtils.toByteArray(ins); ByteArrayInputStream byteInputStream = new ByteArrayInputStream(bytes); InputStream finishedStream = programAnnotationService.setGHAnnotation(byteInputStream,machineGroup,annoDicts); try(finishedStream) { finishedStream.reset(); BladeFile bfile = ossTemplate.putFile(flowProgramFile.getName(), finishedStream); //替换原有的文件地址 flowProgramFile.setOssName(bfile.getName()); } } } /** * 计算有效期 * @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)); } /** * 保存审批完成的记录 * @param packageNode * @param props */ void addApproveTable(NcNode packageNode,FlowProgramProperties props){ NcProgramApproved approved = new NcProgramApproved(); approved.setProgramName(packageNode.getName()); approved.setNcNodeId(packageNode.getId());//程序包节点id approved.setTitle(props.getTitle()); approved.setProgrammerId(props.getProgrammerId()); approvedService.save(approved); } void updateApproveRecordNodeId(String processInstanceId,Long nodeId){ //更新审批记录的ncNodeId approveRecordService.lambdaUpdate() .eq(ApproveRecord::getProcessInstanceId, processInstanceId) .set(ApproveRecord::getNcNodeId,nodeId).update(); } }