yangys
2025-08-17 0ef4cc755bddd87799b8bfdd65c8123df6e149d0
锁定流程完成
已修改17个文件
359 ■■■■ 文件已修改
blade-service/blade-mdm/pom.xml 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
blade-service/blade-mdm/src/main/java/org/springblade/mdm/flow/constants/FlowContants.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
blade-service/blade-mdm/src/main/java/org/springblade/mdm/flow/controller/DispatchController.java 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
blade-service/blade-mdm/src/main/java/org/springblade/mdm/flow/controller/LockFlowController.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
blade-service/blade-mdm/src/main/java/org/springblade/mdm/flow/excution/DispatchFinishListener.java 14 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
blade-service/blade-mdm/src/main/java/org/springblade/mdm/flow/excution/replace/ReplaceFinishListener.java 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
blade-service/blade-mdm/src/main/java/org/springblade/mdm/flow/service/CureFlowService.java 155 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
blade-service/blade-mdm/src/main/java/org/springblade/mdm/flow/service/FlowCommonService.java 36 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
blade-service/blade-mdm/src/main/java/org/springblade/mdm/flow/service/FlowProgramProperties.java 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
blade-service/blade-mdm/src/main/java/org/springblade/mdm/flow/service/LockFlowService.java 49 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
blade-service/blade-mdm/src/main/java/org/springblade/mdm/flow/service/ReplaceFlowService.java 26 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
blade-service/blade-mdm/src/main/java/org/springblade/mdm/flow/task/cure/CureFinishOperateTask.java 21 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
blade-service/blade-mdm/src/main/java/org/springblade/mdm/program/entity/NcNode.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
blade-service/blade-mdm/src/main/java/org/springblade/mdm/program/entity/NcProgramApproved.java 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
blade-service/blade-mdm/src/main/java/org/springblade/mdm/program/service/DNCSendBackService.java 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
blade-service/blade-mdm/src/main/java/org/springblade/mdm/program/service/NcNodeService.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
blade-service/blade-mdm/src/main/resources/processesbpmn/program-unlock.bpmn20.xml 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
blade-service/blade-mdm/pom.xml
@@ -104,6 +104,11 @@
            <artifactId>juniversalchardet</artifactId>
            <version>1.0.3</version>
        </dependency>
        <dependency>
            <groupId>org.apache.groovy</groupId>
            <artifactId>groovy-jsr223</artifactId>
            <version>4.0.28</version>
        </dependency>
        <!--<dependency>
            <groupId>org.springblade</groupId>
            <artifactId>blade-starter-transaction</artifactId>
blade-service/blade-mdm/src/main/java/org/springblade/mdm/flow/constants/FlowContants.java
@@ -19,6 +19,10 @@
     */
    public static final String REPLACE_PROCESS_KEY = "program-replace";
    /**
     * 程序解锁流程key
     */
    public static final String UNLOCK_PROCESS_KEY = "program-unlock";
    public static final String TEAM_LEADER = "teamLeader";
blade-service/blade-mdm/src/main/java/org/springblade/mdm/flow/controller/DispatchController.java
@@ -83,7 +83,8 @@
    AbstractFlowCompleteService getActualService(String processInstanceId){
        ProcessInstance inst = runtimeService.createProcessInstanceQuery().processInstanceId(processInstanceId).singleResult();
        if(inst.getProcessDefinitionKey().equals(FlowContants.TRY_PROCESS_KEY) || inst.getProcessDefinitionKey().equals(FlowContants.CURE_PROCESS_KEY) || inst.getProcessDefinitionKey().equals(FlowContants.REPLACE_PROCESS_KEY)){
        if(inst.getProcessDefinitionKey().equals(FlowContants.TRY_PROCESS_KEY) || inst.getProcessDefinitionKey().equals(FlowContants.CURE_PROCESS_KEY)
            || inst.getProcessDefinitionKey().equals(FlowContants.REPLACE_PROCESS_KEY)|| inst.getProcessDefinitionKey().equals(FlowContants.UNLOCK_PROCESS_KEY)){
            return tryFlowCompleteService;
        }else{
            return defaultFlowCompleteService;
blade-service/blade-mdm/src/main/java/org/springblade/mdm/flow/controller/LockFlowController.java
@@ -29,7 +29,7 @@
     */
    @PostMapping("/start-unlock")
    @Operation(summary = "发起解锁流程", description = "发起解锁流程")
    public R<Boolean> start(@Parameter(description = "程序包名 节点的id") Long nodeId) {//,@Parameter(description = "处理人id")String assingee
    public R<Boolean> startUnlock(@Parameter(description = "程序包名 节点的id") Long nodeId) {//,@Parameter(description = "处理人id")String assingee
        try {
            replaceFlowService.startUnlock(nodeId);
            return R.data(true);
blade-service/blade-mdm/src/main/java/org/springblade/mdm/flow/excution/DispatchFinishListener.java
@@ -60,7 +60,7 @@
        String programName = NcNodeService.genProgramName(props.getDrawingNo(),props.getProcessNo());
        NcNode packageNode = ncNodeService.getProgramPackageByName(programName);
        addApproveTable(packageNode,props.getTitle());
        addApproveTable(packageNode,props);
        updateApproveRecordNodeId(instId,packageNode.getId());
@@ -112,12 +112,18 @@
        }
    }
    void addApproveTable(NcNode packageNode,String title){
    /**
     * 保存审批完成的记录
     * @param packageNode
     * @param props
     */
    void addApproveTable(NcNode packageNode,FlowProgramProperties props){
        NcProgramApproved approved = new NcProgramApproved();
        //approved.setProgramName(pf.getProgramName());
        approved.setProgramName(packageNode.getName());
        approved.setNcNodeId(packageNode.getId());//程序包节点id
        approved.setTitle(title);
        approved.setTitle(props.getTitle());
        approved.setProgrammerId(props.getProgrammerId());
        approvedService.save(approved);
    }
blade-service/blade-mdm/src/main/java/org/springblade/mdm/flow/excution/replace/ReplaceFinishListener.java
@@ -7,9 +7,7 @@
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.ApproveRecordService;
import org.springblade.mdm.flow.service.FlowProgramFileService;
import org.springblade.mdm.flow.service.ReplaceFlowService;
import org.springblade.mdm.flow.service.*;
import org.springblade.mdm.program.entity.NcNode;
import org.springblade.mdm.program.entity.NcProgramApproved;
import org.springblade.mdm.program.service.NcNodeService;
@@ -37,6 +35,8 @@
    private NcProgramApprovedService ncProgramApprovedService;
    @Autowired
    private NcNodeService ncNodeService;
    @Autowired
    private FlowCommonService flowCommonService;
    /**
     * 在流程结束时自动调用,(配置在审批结束事件的executelistener中了)
     * @param execution 执行对象
@@ -44,26 +44,29 @@
    public void handle(DelegateExecution execution) {
        // 执行业务逻辑
        String instId = execution.getProcessInstanceId();
        FlowProgramProperties props = flowCommonService.getProgramProperties(instId);
        Long nodeId = runtimeService.getVariable(execution.getId(),FlowContants.NODE_ID,Long.class);
        log.info("事件名称{},instid={}" , execution.getEventName(),instId);
        List<FlowProgramFile> programFiles =  flowProgramFileService.lambdaQuery().eq(FlowProgramFile::getProcessInstanceId, instId).list();
        //List<FlowProgramFile> programFiles =  flowProgramFileService.lambdaQuery().eq(FlowProgramFile::getProcessInstanceId, instId).list();
        List<FlowProgramFile> programFiles = flowProgramFileService.listByProcessInstanceId(instId);
        NcNode newProgramPackage = replaceProgram(nodeId,instId,programFiles);
        addToApproved(newProgramPackage,Func.toStr(execution.getVariables().get(FlowContants.TITLE)));
        addToApproved(newProgramPackage,props);
        log.info("流程已完成 in replaceFinishListener");
    }
    /**
     * 增加审批通过记录,供用户导出到工控网
     * @param newProgramPackage 新的程序包节点
     * @param title 标题
     * @param props 流程属性集合
     */
    void addToApproved(NcNode newProgramPackage,String title){
    void addToApproved(NcNode newProgramPackage,FlowProgramProperties props){
        NcProgramApproved approve = new NcProgramApproved();
        approve.setProgramName(newProgramPackage.getName());
        approve.setNcNodeId(newProgramPackage.getId());
        approve.setTitle(title);
        approve.setTitle(props.getTitle());
        approve.setProgrammerId(props.getProgrammerId());
        ncProgramApprovedService.save(approve);
    }
blade-service/blade-mdm/src/main/java/org/springblade/mdm/flow/service/CureFlowService.java
@@ -6,10 +6,7 @@
import org.flowable.engine.IdentityService;
import org.flowable.engine.RuntimeService;
import org.flowable.engine.TaskService;
import org.flowable.engine.history.HistoricProcessInstance;
import org.flowable.engine.runtime.ProcessInstance;
import org.flowable.task.api.Task;
import org.flowable.task.api.history.HistoricTaskInstance;
import org.springblade.core.secure.utils.AuthUtil;
import org.springblade.mdm.basesetting.machine.MachineService;
import org.springblade.mdm.basesetting.machine.entity.Machine;
@@ -26,7 +23,6 @@
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
/**
 * 固化流程服务
@@ -46,127 +42,22 @@
    private final FlowProgramFileService flowProgramFileService;
    private final ProduceDivisionService produceDivisionService;
    private final MachineService machineService;
    /**
     * 启动固化流程
     */
    @Transactional
    public void startCure(List<NcNode> programPackageList, Map<Long,List<NcNode>> allFlowProgramFilesMap) {
        //根据分组启动流程,并插入关联表
        programPackageList.forEach(pkg -> {
            this.startOne(pkg,allFlowProgramFilesMap.get(pkg.getId()));
        });
    }
    /**
     * 启动一个数控程序的固化流程
     * @param programPackage 程序包名 节点实体
     */
    public void startOne(NcNode programPackage,List<NcNode> programNodes) {
        Map<String, Object> vars = new HashMap<>();
        //该程序在计划任务时 获取编制,校对,审批的人员,作为默认用户,其中编制时第一个固定的用户
        if(programPackage.getProcessInstanceId() != null) {
            //获取审批用户
            HistoricProcessInstance instance = historyService.createHistoricProcessInstanceQuery()
                .processInstanceId(programPackage.getProcessInstanceId()).includeProcessVariables()
                .singleResult();
            if(instance != null) {//使用任务派工流程的变量
                Map<String, Object> oldVars = instance.getProcessVariables();
                //机床编号
                vars.put(FlowContants.MACHINE_CODE,oldVars.get(FlowContants.MACHINE_CODE));
                //机床型号
                vars.put(FlowContants.MACHINE_MODE,oldVars.get(FlowContants.MACHINE_MODE));
                String workshop = nodeDeptQueryService.getWorkshopNameByMachineCode(programPackage.getMachineCode());
                vars.put(FlowContants.WORKSHOP,workshop);
                vars.put(FlowContants.PROCESS_NO,oldVars.get(FlowContants.PROCESS_NO));
                vars.put(FlowContants.PROCESS_NAME,oldVars.get(FlowContants.PROCESS_NAME));
                vars.put(FlowContants.PROCESS_EDITION,oldVars.get(FlowContants.PROCESS_EDITION));
                vars.put(FlowContants.CRAFT_EDITION, oldVars.get(FlowContants.CRAFT_EDITION));
                vars.put(FlowContants.DRAWING_NO,oldVars.get(FlowContants.DRAWING_NO));
                vars.put(FlowContants.DRAWING_NO_EDITION,oldVars.get(FlowContants.DRAWING_NO_EDITION));
                vars.put(FlowContants.PRODUCT_MODEL,oldVars.get(FlowContants.PRODUCT_MODEL));
            }
        }
        //查找历史实际的审批人
        List<HistoricTaskInstance> historicTasks = historyService.createHistoricTaskInstanceQuery()
            .orderByTaskCreateTime().desc().processInstanceId(programPackage.getProcessInstanceId())
            .list();
        fillHistoryAssignees(vars, historicTasks);
        String businessKey = "0";//业务表key
        identityService.setAuthenticatedUserId(String.valueOf(AuthUtil.getUserId()));//设置流程发起人
        vars.put(FlowContants.LAST_STEP_USER_NICKNAME, AuthUtil.getNickName());
        vars.put(FlowContants.TITLE,programPackage.getName()+"-固化");//自动增加标题
        ProcessInstance inst = runtimeService.startProcessInstanceByKey(FlowContants.CURE_PROCESS_KEY,businessKey,vars);
        //更新程序包名节点的流程实例id
        programPackage.setProcessInstanceId(inst.getProcessInstanceId());
        ncNodeService.updateById(programPackage);
        //更新文件的流程实例id,和 程序节点的流程文件id 并入库
        programNodes.forEach(programNode -> {
            FlowProgramFile flowProgramFile = programNode.getFlowProgramFile();
            flowProgramFile.setProcessInstanceId(inst.getProcessInstanceId());
            this.flowProgramFileService.save(flowProgramFile);
            programNode.setFlowProgramFileId(flowProgramFile.getId());
            this.ncNodeService.save(programNode);
        });
        log.info("启动固化流程完成,实例id={}", inst.getId());
    }
    /**
     * 填充历史审批人,从试切流程中查找
     * @param vars 找到审批人后填充的map
     * @param historicTasks 历史任务集合
     */
    @Deprecated
    void fillHistoryAssignees(Map<String, Object> vars,List<HistoricTaskInstance> historicTasks){
        String programmer = null;
        String checker = null;
        String senior = null;
        //找不到工艺员,那么查询最后一个审批的工艺员
        for (HistoricTaskInstance task : historicTasks) {
            // 获取任务的办理人
            if (task.getTaskDefinitionKey().equals("programmingTask")) {
                //编制
                if (programmer == null) {
                    programmer = task.getAssignee();
                }
            } else if (task.getTaskDefinitionKey().equals("check")) {
                //校对
                if (checker == null) {
                    checker = task.getAssignee();
                }
            } else if (task.getTaskDefinitionKey().equals("approveTask")) {
                //审核
                if (senior == null) {
                    senior = task.getAssignee();
                }
            }
        }
        vars.put(FlowContants.PROGRAMMER,programmer);
        vars.put(FlowContants.CHECKER,checker);
        vars.put(FlowContants.SENIOR,senior);
        vars.put(FlowContants.ASSIGNEE,programmer);
    }
    public void startCureNew(Map<Long, List<FlowProgramFile>> pkgIdFileMap) {
        pkgIdFileMap.forEach((nodeId, fileList) -> {
            this.startOneNew(nodeId,fileList);
        });
        pkgIdFileMap.forEach(this::startOneNew);
    }
    /**
     * 启动一调程序的固化流程
     * @param nodeId
     * @param fileList
     */
    private void startOneNew(Long nodeId, List<FlowProgramFile> fileList) {
        Map<String, Object> vars = new HashMap<>();
        NcNode programPackage = this.ncNodeService.getById(nodeId);
@@ -174,6 +65,15 @@
        vars.put(FlowContants.MACHINE_CODE,programPackage.getMachineCode());
        //机床型号
        //vars.put(FlowContants.MACHINE_MODE,programPackage.getm);
        //机床型号
        Machine machine = machineService.getByCode(programPackage.getMachineCode());
        if(machine != null) {
            vars.put(FlowContants.MACHINE_MODE,machine.getName());
        }
        String workshop = nodeDeptQueryService.getWorkshopNameByMachineCode(programPackage.getMachineCode());
        vars.put(FlowContants.WORKSHOP,workshop);
        vars.put(FlowContants.PROCESS_NO,programPackage.getProcessNo());
        vars.put(FlowContants.PROCESS_NAME,programPackage.getProcessName());
        vars.put(FlowContants.PROCESS_EDITION,programPackage.getProcessEdition());
@@ -186,14 +86,13 @@
        vars.put(FlowContants.PROGRAM_PACKAGE_NAME,programPackage.getName());
        ProduceDivision div = produceDivisionService.getByDrawingNoWithQinzhe(programPackage.getDrawingNo());
        if(div != null) {
            vars.put(FlowContants.PROGRAMMER,div.getProgrammerId());
            vars.put(FlowContants.CHECKER,div.getCheckerId());
            vars.put(FlowContants.SENIOR,div.getSeniorId());
            vars.put(FlowContants.TEAM_LEADER,div.getTeamLeaderId());
        vars.put(FlowContants.PROGRAMMER,div.getProgrammerId());
        vars.put(FlowContants.CHECKER,div.getCheckerId());
        vars.put(FlowContants.SENIOR,div.getSeniorId());
        vars.put(FlowContants.TEAM_LEADER,div.getTeamLeaderId());
            vars.put(FlowContants.ASSIGNEE,div.getProgrammerId());
        }
        vars.put(FlowContants.ASSIGNEE,div.getProgrammerId());
        identityService.setAuthenticatedUserId(String.valueOf(AuthUtil.getUserId()));//设置流程发起人
blade-service/blade-mdm/src/main/java/org/springblade/mdm/flow/service/FlowCommonService.java
@@ -12,9 +12,13 @@
import org.springblade.core.tool.api.R;
import org.springblade.core.tool.utils.Func;
import org.springblade.core.tool.utils.StringUtil;
import org.springblade.mdm.basesetting.machine.MachineService;
import org.springblade.mdm.basesetting.machine.entity.Machine;
import org.springblade.mdm.basesetting.producedivision.entity.ProduceDivision;
import org.springblade.mdm.basesetting.producedivision.service.ProduceDivisionService;
import org.springblade.mdm.flow.constants.FlowContants;
import org.springblade.mdm.program.entity.NcNode;
import org.springblade.mdm.program.service.NodeDeptQueryService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.RequestBody;
@@ -28,6 +32,8 @@
    private final RuntimeService runtimeService;
    private final HistoryService historyService;
    private final ProduceDivisionService produceDivisionService;
    private final NodeDeptQueryService nodeDeptQueryService;
    private final MachineService machineService;
    /**
     * 根据流程实例id获取definitionKey
     * @param processInstanceId
@@ -76,6 +82,7 @@
        }
        programProperties.setCureProgramUseable(String.valueOf(vars.get(FlowContants.CURE_PROGRAM_USEABLE)));
        programProperties.setProgrammerId(Func.toLong(vars.get(FlowContants.PROGRAMMER)));
        ProcessInstance processInstance = runtimeService.createProcessInstanceQuery()
            .processInstanceId(processInstanceId)
@@ -147,6 +154,35 @@
        return div;
    }
    /**
     * 根据程序包名节点,填充变量map
     * @param vars
     * @param programPackageNode
     */
    public void putFlowVariablesByNode(Map<String, Object> vars, NcNode programPackageNode){
        //机床编号
        vars.put(FlowContants.MACHINE_CODE,programPackageNode.getMachineCode());
        Machine machine = machineService.getByCode(programPackageNode.getMachineCode());
        //机床型号
        if(machine != null) {
            vars.put(FlowContants.MACHINE_MODE, machine.getName());
        }
        vars.put(FlowContants.PROCESS_NO,programPackageNode.getProcessNo());
        vars.put(FlowContants.PROCESS_NAME,programPackageNode.getProcessName());
        vars.put(FlowContants.PROCESS_EDITION,programPackageNode.getProcessEdition());
        vars.put(FlowContants.CRAFT_EDITION,programPackageNode.getCraftEdition());
        vars.put(FlowContants.DRAWING_NO,programPackageNode.getDrawingNo());
        vars.put(FlowContants.DRAWING_NO_EDITION,programPackageNode.getDrawingNoEdition());
        vars.put(FlowContants.PROGRAM_PACKAGE_NAME,programPackageNode.getName());
        vars.put(FlowContants.PRODUCT_MODEL,programPackageNode.getProductModel());
        vars.put(FlowContants.NODE_ID, programPackageNode.getId());
        vars.put(FlowContants.WORKSHOP,nodeDeptQueryService.getWorkshopNameByMachineCode(programPackageNode.getMachineCode()));
    }
}
blade-service/blade-mdm/src/main/java/org/springblade/mdm/flow/service/FlowProgramProperties.java
@@ -59,4 +59,7 @@
    @Schema(description = "程序是否可用判定:Y/N")
    private String cureProgramUseable;
    @Schema(description = "编程员id")
    private Long programmerId;
}
blade-service/blade-mdm/src/main/java/org/springblade/mdm/flow/service/LockFlowService.java
@@ -10,12 +10,16 @@
import org.springblade.mdm.basesetting.producedivision.entity.ProduceDivision;
import org.springblade.mdm.basesetting.producedivision.service.ProduceDivisionService;
import org.springblade.mdm.flow.constants.FlowContants;
import org.springblade.mdm.flow.entity.FlowProgramFile;
import org.springblade.mdm.program.entity.NcNode;
import org.springblade.mdm.program.service.NcNodeService;
import org.springblade.mdm.program.service.NodeDeptQueryService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@AllArgsConstructor
@@ -26,8 +30,9 @@
    private final IdentityService identityService;
    private final MachineService machineService;
    private final ProduceDivisionService produceDivisionService;
    private final NodeDeptQueryService nodeDeptQueryService;
    private final FlowCommonService flowCommonService;
    private final FlowProgramFileService flowProgramFileService;
    /**
     * 启动解锁流程
     */
@@ -35,40 +40,40 @@
    public void startUnlock(Long nodeId){
        NcNode programPackage = nodeService.getById(nodeId);
        Map<String, Object> vars = new HashMap<>();
        flowCommonService.putFlowVariablesByNode(vars,programPackage);
        ProduceDivision div = produceDivisionService.getByDrawingNoWithQinzhe(programPackage.getDrawingNo());
        vars.put(FlowContants.PROGRAMMER,div.getProgrammerId());
        vars.put(FlowContants.SENIOR,div.getSeniorId());
        vars.put(FlowContants.ASSIGNEE,div.getSeniorId());//审批用户:高师
        vars.put(FlowContants.TITLE,programPackage.getName()+"程序解锁");
        //机床编号
        vars.put(FlowContants.MACHINE_CODE,programPackage.getMachineCode());
        Machine machine = machineService.getByCode(programPackage.getMachineCode());
        //机床型号
        if(machine != null) {
            vars.put(FlowContants.MACHINE_MODE, machine.getName());
        }
        vars.put(FlowContants.PROCESS_NO,programPackage.getProcessNo());
        vars.put(FlowContants.PROCESS_NAME,programPackage.getProcessName());
        vars.put(FlowContants.PROCESS_EDITION,programPackage.getProcessEdition());
        vars.put(FlowContants.CRAFT_EDITION,programPackage.getCraftEdition());
        vars.put(FlowContants.DRAWING_NO,programPackage.getDrawingNo());
        vars.put(FlowContants.DRAWING_NO_EDITION,programPackage.getDrawingNoEdition());
        vars.put(FlowContants.PROGRAM_PACKAGE_NAME,programPackage.getName());
        vars.put(FlowContants.PRODUCT_MODEL,programPackage.getProductModel());
        vars.put(FlowContants.NODE_ID, nodeId);
        vars.put(FlowContants.MY_PROCESS_NAME,"解锁流程");
        vars.put("comment", "解锁程序"+programPackage.getName());
        identityService.setAuthenticatedUserId(String.valueOf(AuthUtil.getUserId()));//设置流程发起人
        ProcessInstance inst = runtimeService.startProcessInstanceByKey(FlowContants.REPLACE_PROCESS_KEY,nodeId+"",vars);
        ProcessInstance inst = runtimeService.startProcessInstanceByKey(FlowContants.UNLOCK_PROCESS_KEY,nodeId+"",vars);
        programPackage.setProcessInstanceId(inst.getId());
        this.nodeService.updateById(programPackage);
        //更新节点文件的流程实例id
        updateFlowProgramFilesProcessInstance(programPackage);
    }
    /**
     * 更新所属流程文件的流程实例id
     * @param programPackage 要解锁的程序报名节点
     */
    void updateFlowProgramFilesProcessInstance(NcNode programPackage){
        List<NcNode> fileNodes = nodeService.getProgramFilesByPackageId(programPackage.getId());
        List<Long> fileIds = fileNodes.stream().map(NcNode::getFlowProgramFileId).toList();
        if(!fileIds.isEmpty()){
            flowProgramFileService.lambdaUpdate().in(FlowProgramFile::getId, fileIds)
                .set(FlowProgramFile::getProcessInstanceId, programPackage.getProcessInstanceId()).update();
        }
    }
}
blade-service/blade-mdm/src/main/java/org/springblade/mdm/flow/service/ReplaceFlowService.java
@@ -53,7 +53,7 @@
    private final NodeDeptQueryService nodeDeptQueryService;
    private final FlowCommonService flowCommonService;
    private final OssTemplate ossTemplate;
    private final MachineService machineService;
    /**
     * 准备替换流程需要的数据
@@ -109,22 +109,23 @@
     */
    @Transactional
    public void start(ReplaceFlowStartVO startVO){
        NcNode programPackage = nodeService.getById(startVO.getNodeId());
        Map<String, Object> vars = new HashMap<>();
        flowCommonService.putFlowVariablesByNode(vars,programPackage);
        flowCommonService.putDefaultAssignees(vars,programPackage.getDrawingNo(),startVO.getAssignee()+"");
        vars.put(FlowContants.TITLE,startVO.getTitle());
        //以下被flowCommonService.putFlowVariablesByNode(vars,programPackage);代替了
        /*
        //机床编号
        vars.put(FlowContants.MACHINE_CODE,programPackage.getMachineCode());
        //Machine machine = machineService.getByCode(programPackge.getMachineCode());
        Machine machine = machineService.getByCode(programPackage.getMachineCode());
        //机床型号
        //if(machine != null) {
            //vars.put(FlowContants.MACHINE_MODE, programPackge.getMachineMode());
        //}
        if(machine != null) {
            vars.put(FlowContants.MACHINE_MODE, machine.getName());
        }
        vars.put(FlowContants.PROCESS_NO,programPackage.getProcessNo());
        vars.put(FlowContants.PROCESS_NAME,programPackage.getProcessName());
        vars.put(FlowContants.PROCESS_EDITION,programPackage.getProcessEdition());
@@ -137,12 +138,15 @@
        vars.put(FlowContants.PRODUCT_MODEL,programPackage.getProductModel());
        vars.put(FlowContants.NODE_ID, startVO.getNodeId());
        vars.put(FlowContants.WORKSHOP,nodeDeptQueryService.getWorkshopNameByMachineCode(programPackage.getMachineCode()));
        */
        vars.put("comment", startVO.getComment());
        vars.put(FlowContants.MY_PROCESS_NAME,"替换流程");
        identityService.setAuthenticatedUserId(String.valueOf(AuthUtil.getUserId()));//设置流程发起人
        ProcessInstance inst = runtimeService.startProcessInstanceByKey(FlowContants.REPLACE_PROCESS_KEY,startVO.getNodeId()+"",vars);
        //replaceProgramFileService.lambdaUpdate().eq(ReplaceProgramFile::getTempId,startVO.getTempId()).set(ReplaceProgramFile::getProcessInstanceId,inst.getProcessInstanceId());
        //更新节点的流程id,避免重复发起流程
        programPackage.setProcessInstanceId(inst.getId());
        this.nodeService.updateById(programPackage);
        /*
        Task startTask = taskService.createTaskQuery()
            .processInstanceId(inst.getId())
blade-service/blade-mdm/src/main/java/org/springblade/mdm/flow/task/cure/CureFinishOperateTask.java
@@ -3,7 +3,6 @@
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.IOUtils;
import org.checkerframework.checker.units.qual.N;
import org.flowable.engine.delegate.DelegateExecution;
import org.springblade.core.oss.OssTemplate;
import org.springblade.core.oss.model.BladeFile;
@@ -47,8 +46,6 @@
    private final ProgramAnnotationService programAnnotationService;
    private final MachineService machineService;
    public static final String GH = "GH";
    /**
     * 默认有效期间(月数),2年
@@ -77,13 +74,15 @@
        NcNode pkgNode =  nodeService.lambdaQuery().eq(NcNode::getProcessInstanceId, processInstanceId).one();
        if(pkgNode.isDeviationProgram()){
            //偏离的程序直接锁定
            pkgNode.setIsLocked(1);
            //pkgNode.setIsLocked(1);
            pkgNode.lock();
            nodeService.updateById(pkgNode);
        }else {
            //试切的
            pkgNode.setIsCured(1);
            pkgNode.setIsLocked(NcNode.UNLOCK);
            //设置过期日期
            pkgNode.upgradeVersionNUmber();
            pkgNode.upgradeVersionNumber();
            pkgNode.setExpireDate(calculateExpireDate());
            nodeService.updateById(pkgNode);
@@ -101,9 +100,13 @@
        //创建节点到机床级别.(固化树)
        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){
@@ -113,7 +116,7 @@
            hisPackageNode.setParentId(machineNode.getParentId());
            hisPackageNode.setParentIds(machineNode.getParentIds());//程序包与机床节点同级
            //处理程序包下层的程序节点
            //处理程序包下层的程序节点111
            List<NcNode> programNodes = nodeService.lambdaQuery().eq(NcNode::getParentId,hisPackageNode.getId()).list();
            for(NcNode programNode : programNodes){
                programNode.setIsLastEdition(0);
@@ -132,6 +135,12 @@
            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());
blade-service/blade-mdm/src/main/java/org/springblade/mdm/program/entity/NcNode.java
@@ -211,7 +211,7 @@
        return this.isCured != null && this.isCured == 1;
    }
    public void upgradeVersionNUmber() {
    public void upgradeVersionNumber() {
        this.versionNumber = genNewVersionNumber();
    }
blade-service/blade-mdm/src/main/java/org/springblade/mdm/program/entity/NcProgramApproved.java
@@ -36,4 +36,9 @@
     */
    private String title;
    /**
     * 变成员id
     */
    private Long programmerId;
}
blade-service/blade-mdm/src/main/java/org/springblade/mdm/program/service/DNCSendBackService.java
@@ -58,6 +58,7 @@
    private final BladeRedis bladeRedis;
    private final FlowCommonService flowCommonService;
    private final DncBackFileService dncBackFileService;
    private final ProgramFlowStatusQueryService programFlowStatusQueryService;
    private String getFileKey(){
        return "dncimpfile-"+ AuthUtil.getUserId();
    }
@@ -254,7 +255,7 @@
                //根据节点信息查询流程
                boolean active = flowCommonService.isProcessInstanceActive(packageNode.getProcessInstanceId());
                if(active){
                    throw new ServiceException(programPackageName+"正在审批中,请勿重复入库。");
                    throw new ServiceException(programPackageName+"正在审批中,请勿等待审批完成。");
                }
                //验证都过了,保存dncbackFile
blade-service/blade-mdm/src/main/java/org/springblade/mdm/program/service/NcNodeService.java
@@ -224,7 +224,7 @@
     */
    public List<NcNode> getNodeHistory(NcNode pkgNode) {
        return this.lambdaQuery().eq(NcNode::getParentId,pkgNode.getParentId())
            .eq(NcNode::getName,pkgNode.getName()).list();
            .eq(NcNode::getName,pkgNode.getName()).list();//.ne(NcNode::getId,pkgNode.getId())
    }
    /**
@@ -306,7 +306,7 @@
    @Transactional
    public void upgradeVersionNumber(Long nodeId) {
        NcNode node = this.getById(nodeId);
        node.upgradeVersionNUmber();
        node.upgradeVersionNumber();
        this.updateById(node);
    }
blade-service/blade-mdm/src/main/resources/processesbpmn/program-unlock.bpmn20.xml
@@ -12,10 +12,10 @@
    <sequenceFlow id="sid-030b6e4b-640a-41aa-a536-ddf9fb485ac1" sourceRef="unlockStart" targetRef="unlockApproveTask"/>
    <userTask id="unlockProgramConfirm" name="编制复核" flowable:assignee="${assignee}"/>
    <sequenceFlow id="sid-eef79355-70bc-4610-aece-b1aed2f9876a" sourceRef="unlockApproveTask" targetRef="unlockApproveEnd">
      <conditionExpression>{approve=='Y'}</conditionExpression>
      <conditionExpression>${approve=='Y'}</conditionExpression>
    </sequenceFlow>
    <sequenceFlow id="sid-be770b3a-d711-45df-8477-fdd73b84d85b" sourceRef="unlockApproveTask" targetRef="unlockProgramConfirm">
      <conditionExpression>{approve=='N'}</conditionExpression>
      <conditionExpression>${approve=='N'}</conditionExpression>
    </sequenceFlow>
    <sequenceFlow id="sid-5a3d8229-b648-424a-a0f4-f356082d5375" sourceRef="unlockProgramConfirm" targetRef="exceptionHandleScriptTask">
      <conditionExpression>${approve=='N'}</conditionExpression>
@@ -23,7 +23,7 @@
    <sequenceFlow id="sid-185054ce-c200-475e-8128-2369554b05cf" sourceRef="unlockProgramConfirm" targetRef="unlockApproveTask">
      <conditionExpression>${approve=='Y'}</conditionExpression>
    </sequenceFlow>
    <scriptTask id="exceptionHandleScriptTask" scriptFormat="JavaScript">
    <scriptTask id="exceptionHandleScriptTask" scriptFormat="groovy">
      <script><![CDATA[
          execution.setVariable("exception", "1");//设置异常标志
        ]]></script>