yangys
2025-08-22 016f6009aef19985e5e50be497651cb77795c868
偏离单审批完成文件内容未更新问题修复
已添加2个文件
已重命名1个文件
已修改7个文件
474 ■■■■ 文件已修改
blade-service/blade-mdm/src/main/java/org/springblade/mdm/flow/excution/StartDispatcher.java 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
blade-service/blade-mdm/src/main/java/org/springblade/mdm/flow/excution/cure/CureFinishOperateTask.java 96 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
blade-service/blade-mdm/src/main/java/org/springblade/mdm/flow/excution/cure/DeviationCureFinishDataHandler.java 132 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
blade-service/blade-mdm/src/main/java/org/springblade/mdm/flow/excution/cure/NormalCureFinishDataHandler.java 155 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
blade-service/blade-mdm/src/main/java/org/springblade/mdm/flow/service/CureFlowService.java 4 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
blade-service/blade-mdm/src/main/java/org/springblade/mdm/flow/vo/TaskAssignVO.java 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
blade-service/blade-mdm/src/main/java/org/springblade/mdm/program/mapper/NcNodeMapper.xml 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
blade-service/blade-mdm/src/main/java/org/springblade/mdm/program/service/NcNodeService.java 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
blade-service/blade-mdm/src/main/java/org/springblade/mdm/program/service/NcProgramExportDNCService.java 14 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
blade-service/blade-mdm/src/main/java/org/springblade/mdm/program/service/ProgramAnnotationService.java 40 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
blade-service/blade-mdm/src/main/java/org/springblade/mdm/flow/excution/StartDispatcher.java
@@ -59,8 +59,6 @@
        vars.put(FlowContants.ASSIGNEE,div.getTeamLeaderId());//第一个用户组长
        vars.put(FlowContants.TITLE,startVO.getTitle());
        //临时流程标志,明确指定Y,属于临时流程
        //机床编号
        vars.put(FlowContants.MACHINE_CODE,startVO.getMachineCode());
        String workshop = nodeDeptQueryService.getWorkshopNameByMachineCode(startVO.getMachineCode());
@@ -86,8 +84,9 @@
        vars.put(FlowContants.IS_TEMP_FLOW,FlowContants.Y.equals(startVO.getIsTempFlow())?FlowContants.Y:FlowContants.N);
        NcNode curedProgramPackage = null;
        if(!FlowContants.Y.equals(startVO.getIsTempFlow())) {
            curedProgramPackage = ncNodeService.getCuredProgramPackage(programPkgName, startVO.getMachineCode());
        if(!startVO.isTemporaryFlow() && !startVO.isDeviationFlow()) {
            //正常流程(非临时流程) ä¸”不是 åç¦»å•,才匹配固化程序
            curedProgramPackage = ncNodeService.getCuredProgramPackage(programPkgName,startVO.getProcessEdition(), startVO.getMachineCode());
            //设置是否有固化程序标记
            vars.put(FlowContants.HAS_CURED_PROGRAM, curedProgramPackage != null ? FlowContants.Y : FlowContants.N);
            //工序版次是否一致,是否在有效期内
blade-service/blade-mdm/src/main/java/org/springblade/mdm/flow/excution/cure/CureFinishOperateTask.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,96 @@
package org.springblade.mdm.flow.excution.cure;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.IOUtils;
import org.flowable.engine.delegate.DelegateExecution;
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.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.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.program.service.NcNodeAutoCreateService;
import org.springblade.mdm.program.service.NcNodeService;
import org.springblade.mdm.program.service.ProgramAnnotationService;
import org.springblade.system.feign.ISysClient;
import org.springblade.system.pojo.entity.DictBiz;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
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;
@Slf4j
@Component("cureFinishOperateTask")
@AllArgsConstructor
public class CureFinishOperateTask {
    private final NcNodeService nodeService;
    private final NcNodeAutoCreateService ncNodeAutoCreateService;
    private final FlowCommonService flowCommonService;
    private final FlowProgramFileService flowProgramFileService;
    private final ISysClient sysClient;
    private final OssTemplate ossTemplate;
    private final NormalCureFinishDataHandler normalCureFinishDataHandler;
    private final DeviationCureFinishDataHandler deviationCureFinishDataHandler;
    private final NcNodeService ncNodeService;
    /**
     * å›ºåŒ–审批通过处理任务,
     *
     * @param execution æµç¨‹execution
     */
    @Transactional
    public void execute(DelegateExecution execution) throws IOException {
        log.info("执行固化程序任务服务,流程实例id={}", execution.getProcessInstanceId());
        //固化程序检查有效期,
        dealWithNode(execution.getProcessInstanceId());
    }
    /**
     * å¤„理node状态。
     *
     * @param processInstanceId æµç¨‹å®žä¾‹id
     */
    void dealWithNode(String processInstanceId) throws IOException {
        //程序包节点和下属程序节点(包括历史节点非最新版本的)从试切挪到固化下面
        //程序包节点 è®¾ç½®æœªå·²å›ºåŒ–
        NcNode pkgNode = nodeService.lambdaQuery().eq(NcNode::getProcessInstanceId,  processInstanceId).one();
        FlowProgramProperties flowProps = flowCommonService.getProgramProperties(processInstanceId);
        getDataHandler(pkgNode).handleData(flowProps);
    }
    /**
     * èŽ·å–æ•°æ®å¤„ç†å…¶
     * @param pkgNode
     * @return
     */
    FinishDataHandler getDataHandler(NcNode pkgNode) {
        if (pkgNode.isDeviationProgram()) {
            return deviationCureFinishDataHandler;
        }else{
            return normalCureFinishDataHandler;
        }
    }
}
blade-service/blade-mdm/src/main/java/org/springblade/mdm/flow/excution/cure/DeviationCureFinishDataHandler.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,132 @@
package org.springblade.mdm.flow.excution.cure;
import lombok.extern.slf4j.Slf4j;
import org.springblade.core.tool.utils.Func;
import org.springblade.mdm.basesetting.machine.MachineService;
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.utils.EntityUtil;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.List;
/**
 * åç¦»å•固化完成数据处理器,功能:梳理树节点
 */
@Slf4j
@Component("deviationCureFinishDataHandler")
public class DeviationCureFinishDataHandler 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;
    /**
     * cureFinishOperateTask调用
     * @param props å±žæ€§
     */
    public void handleData(FlowProgramProperties props) {
        // æ‰§è¡Œä¸šåŠ¡é€»è¾‘
        String instId = props.getProcessInstanceId();
        NcNode pkgNode = nodeService.lambdaQuery().eq(NcNode::getProcessInstanceId,  props.getProcessInstanceId()).one();
        pkgNode.lock();
        pkgNode.setIsLastEdition(0);
        nodeService.updateById(pkgNode);
        NcNode newPkgNode = new NcNode();
        BeanUtils.copyProperties(pkgNode, newPkgNode);
        EntityUtil.clearBaseProperties(newPkgNode);
        newPkgNode.setIsLastEdition(1);
        newPkgNode.upgradeVersionNumber();
        nodeService.save(newPkgNode);
        //处理程序包下层的程序节点111
        List<NcNode> oriProgramNodes = nodeService.lambdaQuery().eq(NcNode::getParentId,pkgNode.getId()).list();
        FlowProgramFile pfile;
        for(NcNode programNode : oriProgramNodes){
            programNode.setIsLastEdition(0);
            programNode.setVersionNumber(newPkgNode.getVersionNumber());
            pfile = flowProgramFileService.getById(programNode.getFlowProgramFileId());
            if(!pfile.isProgram()){
                //当前固化程序包名下的“其他文件”非程序文件。不设置为老版本,直接挪到固化树下,两个网络之间只交换程序文件,其他文件只能保留
                programNode.setIsLastEdition(1);
            }
        }
        nodeService.updateBatchById(oriProgramNodes);
        //新的文件作为最新版本
        List<FlowProgramFile> files = flowProgramFileService.lambdaQuery().eq(FlowProgramFile::getProcessInstanceId,pkgNode.getProcessInstanceId()).list();
        for(FlowProgramFile flowProgramFile : files){
            NcNode newProgNode = new NcNode();
            BeanUtils.copyProperties(newPkgNode, newProgNode);
            EntityUtil.clearBaseProperties(newProgNode);
            newProgNode.setName(flowProgramFile.getName());
            newProgNode.setNodeType(NcNode.TYPE_PROGRAM_FILE);
            newProgNode.setParentId(newPkgNode.getId());
            newProgNode.setParentIds(newPkgNode.getParentIds()+","+newPkgNode.getId());
            newProgNode.setIsLastEdition(1);
            newProgNode.setVersionNumber(newPkgNode.getVersionNumber());
            newProgNode.setFlowProgramFileId(flowProgramFile.getId());
            newProgNode.setIsCured(0);
            nodeService.save(newProgNode);
            //修改文件内容更新注释,并更新文件数据的地址
            //setGhAnnotation(flowProgramFile,machine.getMachineGroupCode(),annoDicts);
            //flowProgramFileService.updateById(flowProgramFile);
        }
        addApproveTable(pkgNode,props);
        updateApproveRecordNodeId(instId, pkgNode.getId());
        log.info("偏离回传Listener完成");
    }
    /**
     * ä¿å­˜å®¡æ‰¹å®Œæˆçš„记录
     * @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();
    }
}
blade-service/blade-mdm/src/main/java/org/springblade/mdm/flow/excution/cure/NormalCureFinishDataHandler.java
ÎļþÃû´Ó blade-service/blade-mdm/src/main/java/org/springblade/mdm/flow/task/cure/CureFinishOperateTask.java ÐÞ¸Ä
@@ -1,30 +1,35 @@
package org.springblade.mdm.flow.task.cure;
package org.springblade.mdm.flow.excution.cure;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.IOUtils;
import org.flowable.engine.delegate.DelegateExecution;
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.service.FlowCommonService;
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.FileContentUtil;
import org.springblade.mdm.utils.EntityUtil;
import org.springblade.system.feign.ISysClient;
import org.springblade.system.pojo.entity.Dict;
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 org.springframework.transaction.annotation.Transactional;
import java.io.ByteArrayInputStream;
import java.io.IOException;
@@ -34,62 +39,61 @@
import java.util.Date;
import java.util.List;
/**
 * æ™®é€šæ´¾å·¥å®Œæˆæ•°æ®å¤„理器,功能:插入审批表数据,DispatchFinishListener调用
 */
@Slf4j
@Component("cureFinishOperateTask")
@AllArgsConstructor
public class CureFinishOperateTask {
    private final NcNodeService nodeService;
    private final NcNodeAutoCreateService ncNodeAutoCreateService;
    private final FlowCommonService flowCommonService;
    private final FlowProgramFileService flowProgramFileService;
    private final ISysClient sysClient;
    private final OssTemplate ossTemplate;
    private final ProgramAnnotationService programAnnotationService;
    private final MachineService machineService;
@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;
    private final NcNodeService ncNodeService;
    /**
     * å›ºåŒ–审批通过处理任务,
     * @param execution æµç¨‹execution
     * DispatchFinishListener中调用
     * @param flowProps æµç¨‹å±žæ€§
     */
    @Transactional
    public void execute(DelegateExecution execution) throws IOException {
        log.info("执行固化程序任务服务,流程实例id={}", execution.getProcessInstanceId());
        //固化程序检查有效期,
        dealWithNode(execution.getProcessInstanceId());
    }
    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);
    /**
     * å¤„理node状态。
     * @param processInstanceId æµç¨‹å®žä¾‹id
     */
    void dealWithNode(String processInstanceId) throws IOException {
        //程序包节点和下属程序节点(包括历史节点非最新版本的)从试切挪到固化下面
        //程序包节点 è®¾ç½®æœªå·²å›ºåŒ–
        NcNode pkgNode =  nodeService.lambdaQuery().eq(NcNode::getProcessInstanceId, processInstanceId).one();
        if(pkgNode.isDeviationProgram()){
            //偏离的程序直接锁定
            //pkgNode.setIsLocked(1);
            pkgNode.lock();
            nodeService.updateById(pkgNode);
        }else {
            //试切的
            pkgNode.setIsCured(1);
            pkgNode.setIsLocked(NcNode.UNLOCK);
            //设置过期日期
            pkgNode.upgradeVersionNumber();
            pkgNode.setExpireDate(calculateExpireDate());
            nodeService.updateById(pkgNode);
            List<NcNode> historyProgramPackageNodes = nodeService.getNodeHistory(pkgNode);
            moveNodeToCuredTree(pkgNode, historyProgramPackageNodes, flowCommonService.getProgramProperties(processInstanceId));
        List<NcNode> 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());
    }
    /**
     * å°†èŠ‚ç‚¹å’ŒåŽ†å²èŠ‚ç‚¹æŒªåŠ¨åˆ°å›ºåŒ–çš„åŒçº§èŠ‚ç‚¹ä¸‹
@@ -140,27 +144,21 @@
        List<FlowProgramFile> 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.setDrawingNo(pkgNode.getDrawingNo());
            newProgNode.setDrawingNoEdition(pkgNode.getDrawingNoEdition());
            newProgNode.setMachineCode(pkgNode.getMachineCode());
            newProgNode.setProcessEdition(pkgNode.getProcessEdition());
            newProgNode.setProcessName(pkgNode.getProcessName());
            newProgNode.setProcessNo(pkgNode.getProcessNo());
            newProgNode.setParentIds(pkgNode.getParentIds()+","+pkgNode.getId());
            newProgNode.setIsLastEdition(1);
            newProgNode.setVersionNumber(pkgNode.getVersionNumber());
            newProgNode.setFlowProgramFileId(flowProgramFile.getId());
            newProgNode.setIsCured(1);
            ncNodeService.save(newProgNode);
            nodeService.save(newProgNode);
            //修改文件内容更新注释,并更新文件数据的地址
            ///替换注释后总是不行啊
            setGhAnnotation(flowProgramFile,machine.getMachineGroupCode(),annoDicts);
            flowProgramFileService.updateById(flowProgramFile);
            //flowProgramFileService.updateById(flowProgramFile);
        }
    }
@@ -178,17 +176,7 @@
            ByteArrayInputStream byteInputStream =  new ByteArrayInputStream(bytes);
            InputStream finishedStream = programAnnotationService.setGHAnnotation(byteInputStream,machineGroup,annoDicts);
            /*
            String annoTxt = programAnnotationService.generateAnnotation("GH",machineGroup,annoDicts);
            //int statusLineIndex = 2;
            String line2 = FileContentUtil.readLineAt(byteInputStream,ProgramAnnotationService.STATUS_LINE_INDEX);//第三行应该是状态注释
            byteInputStream.reset();
            InputStream finishedStream;
            if(programAnnotationService.isAnnotation(line2,machineGroup,annoDicts)){
                finishedStream = FileContentUtil.replaceAtLine(byteInputStream,ProgramAnnotationService.STATUS_LINE_INDEX,annoTxt);
            }else{
                finishedStream = FileContentUtil.insertLine(byteInputStream,ProgramAnnotationService.STATUS_LINE_INDEX,annoTxt);
            }*/
            try(finishedStream) {
                finishedStream.reset();
                BladeFile bfile = ossTemplate.putFile(flowProgramFile.getName(), finishedStream);
@@ -214,4 +202,27 @@
        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();
    }
}
blade-service/blade-mdm/src/main/java/org/springblade/mdm/flow/service/CureFlowService.java
@@ -90,12 +90,14 @@
        identityService.setAuthenticatedUserId(String.valueOf(AuthUtil.getUserId()));//设置流程发起人
        vars.put(FlowContants.LAST_STEP_USER_NICKNAME, AuthUtil.getNickName());
        vars.put(FlowContants.TITLE,programPackage.getName()+"-固化");//自动增加标题
        if(programPackage.getDeviation() != null) {
            vars.put(FlowContants.MY_PROCESS_NAME, "偏离回传");
            vars.put(FlowContants.TITLE,programPackage.getName()+"-偏离回传");//自动增加标题
        }else {
            vars.put(FlowContants.MY_PROCESS_NAME, "固化流程");
            vars.put(FlowContants.TITLE,programPackage.getName()+"-固化");//自动增加标题
        }
        ProcessInstance inst = runtimeService.startProcessInstanceByKey(FlowContants.CURE_PROCESS_KEY,"0",vars);
blade-service/blade-mdm/src/main/java/org/springblade/mdm/flow/vo/TaskAssignVO.java
@@ -2,6 +2,8 @@
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import org.apache.commons.lang3.StringUtils;
import org.springblade.mdm.flow.constants.FlowContants;
import java.time.LocalDate;
import java.time.LocalDateTime;
@@ -43,4 +45,20 @@
    private String deviation;
    @Schema(description = "是否临时流程,值:Y/N")
    private String isTempFlow;
    /**
     * æ˜¯å¦ æœª ç¨‹åºè¡¥å……流程(临时流程)
     * @return æ˜¯å¦
     */
    public boolean isTemporaryFlow(){
        return FlowContants.Y.equals(isTempFlow);
    }
    /**
     * æ˜¯å¦åç¦»å•
     * @return æ˜¯å¦
     */
    public boolean isDeviationFlow(){
        return StringUtils.isNotBlank(deviation);
    }
}
blade-service/blade-mdm/src/main/java/org/springblade/mdm/program/mapper/NcNodeMapper.xml
@@ -126,7 +126,7 @@
                <if test='status.contains("2")'>
                    or n.parent_ids LIKE '0,2,%'
                </if>
                <if test='status.contains("2")'>
                <if test='status.contains("3")'>
                    or n.parent_ids LIKE '0,3,%'
                </if>
                )
blade-service/blade-mdm/src/main/java/org/springblade/mdm/program/service/NcNodeService.java
@@ -318,12 +318,14 @@
     * @param machineCode æœºåºŠç¼–号
     * @return
     */
    public NcNode getCuredProgramPackage(String programPkgName,String machineCode) {
    public NcNode getCuredProgramPackage(String programPkgName,String processEdition,String machineCode) {
        Machine machine = machineService.getByCode(machineCode);
        List<Machine> sameGroupMachines = machineService.lambdaQuery().eq(Machine::getMachineGroupCode,machine.getMachineGroupCode()).list();
        List<String> machineCodesInGroup = sameGroupMachines.stream().map(Machine::getCode).toList();
        List<NcNode> nodes = lambdaQuery().eq(NcNode::getNodeType,NcNode.TYPE_PROGRAM_PACKAGE)
            .eq(NcNode::getName, programPkgName).likeRight(NcNode::getParentIds,"0,2,").eq(NcNode::getIsCured,1)
            .eq(NcNode::getName, programPkgName)
            .eq(NcNode::getProcessEdition,processEdition)
            .likeRight(NcNode::getParentIds,"0,2,").eq(NcNode::getIsCured,1)
            .in(!machineCodesInGroup.isEmpty(),NcNode::getMachineCode,machineCodesInGroup)
            .eq(NcNode::getIsLastEdition,1).list();
blade-service/blade-mdm/src/main/java/org/springblade/mdm/program/service/NcProgramExportDNCService.java
@@ -5,6 +5,7 @@
import com.baomidou.mybatisplus.core.metadata.IPage;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springblade.core.log.exception.ServiceException;
import org.springblade.core.mp.base.BizServiceImpl;
import org.springblade.core.mp.support.Condition;
@@ -23,6 +24,7 @@
import org.springblade.mdm.program.mapper.NcProgramExchangeMapper;
import org.springblade.mdm.program.vo.DncSendBackData;
import org.springblade.system.feign.IDictClient;
import org.springblade.system.pojo.entity.DictBiz;
import org.springframework.stereotype.Service;
import java.io.*;
@@ -40,7 +42,6 @@
@AllArgsConstructor
public class NcProgramExportDNCService extends BizServiceImpl<NcProgramExchangeMapper, NcProgramExchange> {
    //private final NcProgramService progService;
    private final IDictClient dictClient;
    private final MachineService machineService;
    private final NcProgramApprovedService approvedService;
@@ -95,7 +96,6 @@
        zipOut.putNextEntry(zipEntry);
        zipOut.closeEntry();
        Machine machine = machineService.getByCode(packageNode.getMachineCode());//程序包节点,获取注释用
        List<NcNode> programNodes = ncNodeService.lambdaQuery().eq(NcNode::getIsLastEdition,1).eq(NcNode::getParentId, approved.getNcNodeId()).list();
@@ -109,14 +109,22 @@
            status = "GH";
        }
        List<DictBiz> annotationDictList= programAnnotationService.getAnnotionList();
        for (NcNode node : programNodes) {
            String filePathInZip = packageFolder + node.getName();
            programFile = this.flowProgramFileService.getById(node.getFlowProgramFileId());
            if(programFile.isProgram()) {//程序文件,才会加入压缩包
                InputStream inputStream = ossTemplate.statFileStream(programFile.getOssName());
                String sendDir = machine.getProgSendDir()==null? StringUtil.EMPTY:machine.getProgSendDir();
                InputStream addedInsFinal;
                InputStream addedIns2 = programAnnotationService.setSendDirAndStatusAnnotation(sendDir,status,inputStream,machine.getMachineGroupCode());
                this.addInputStreamToZip(zipOut, addedIns2, filePathInZip);
                if(StringUtils.isNotBlank(programPackageNode.getDeviation())) {
                    //偏离单,增加偏离单号
                    addedInsFinal = programAnnotationService.setPldAnnotation(programPackageNode.getDeviation(),addedIns2, machine.getMachineGroupCode(), annotationDictList);;
                }else{
                    addedInsFinal = addedIns2;
                }
                this.addInputStreamToZip(zipOut, addedInsFinal, filePathInZip);
            }
        }
blade-service/blade-mdm/src/main/java/org/springblade/mdm/program/service/ProgramAnnotationService.java
@@ -4,6 +4,7 @@
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
import org.jetbrains.annotations.NotNull;
import org.springblade.core.tool.api.R;
import org.springblade.mdm.utils.FileContentUtil;
import org.springblade.system.feign.IDictBizClient;
@@ -41,6 +42,11 @@
     * çŠ¶æ€è¡Œç´¢å¼•ï¼ˆç¬¬ä¸‰è¡Œï¼‰ 0 based
     */
    public static final int STATUS_LINE_INDEX = 2;
    /**
     * åç¦»å•注释行索引号 0 based
     */
    public static final int STATUS_DEVIATION_INDEX = 3;
    public static final String SQ = "SQ";
    public static final String GH = "GH";
@@ -152,33 +158,51 @@
     * è®¾ç½®å›ºåŒ–注释行
     * @param inputStream
     * @param machineGroup
     * @param annoDicts
     * @param annoDictList
     * @return
     * @throws IOException
     */
    public InputStream setGHAnnotation(InputStream inputStream, String machineGroup,List<DictBiz> annoDicts) throws IOException {
    public InputStream setGHAnnotation(InputStream inputStream, String machineGroup,List<DictBiz> annoDictList) throws IOException {
        return setAnnotationAndGetInputStream(inputStream, machineGroup, annoDictList, GH, STATUS_LINE_INDEX);
    }
    /**
     * è®¾ç½®åç¦»å•注释
     * @param inputStream
     * @param machineGroup
     * @param annoDictList
     * @return
     * @throws IOException
     */
    public InputStream setPldAnnotation(String deviation,InputStream inputStream,String machineGroup,List<DictBiz> annoDictList) throws IOException {
        //
        return setAnnotationAndGetInputStream(inputStream, machineGroup, annoDictList, deviation, STATUS_DEVIATION_INDEX);
    }
    @NotNull
    private InputStream setAnnotationAndGetInputStream(InputStream inputStream, String machineGroup, List<DictBiz> annoDictList, String text, int lineIndex) throws IOException {
        InputStream finishedStream;
        try(inputStream){
            ByteArrayInputStream byteInputStream =  new ByteArrayInputStream(IOUtils.toByteArray(inputStream));
            String annoTxt = generateAnnotation(GH,machineGroup,annoDicts);//加了注释之后的文本
            String annoTxt = generateAnnotation(text,machineGroup,annoDictList);//加了注释之后的文本
            String lineText = FileContentUtil.readLineAt(byteInputStream,STATUS_LINE_INDEX);//第三行应该是状态注释
            String lineText = FileContentUtil.readLineAt(byteInputStream, lineIndex);
            byteInputStream.reset();
            if(isAnnotation(lineText,machineGroup,annoDicts)){
                finishedStream = FileContentUtil.replaceAtLine(byteInputStream,STATUS_LINE_INDEX,annoTxt);
            if(isAnnotation(lineText,machineGroup,annoDictList)){
                finishedStream = FileContentUtil.replaceAtLine(byteInputStream, lineIndex,annoTxt);
            }else{
                finishedStream = FileContentUtil.insertLine(byteInputStream,STATUS_LINE_INDEX,annoTxt);
                finishedStream = FileContentUtil.insertLine(byteInputStream, lineIndex,annoTxt);
            }
            finishedStream.reset();
        }
        return finishedStream;
    }
    /**
     * ä¸ºè¾“入流设置发送目录(第二行)和状态(第三行)
     * @param sendPath å‘送路径