Flowable之任务撤回(支持主流程、子流程相互撤回)

撤回任务:主流程 > 主流程

处室主管【送科长审核】

处室主管【撤回科长审核】

流程日志

撤回任务:子流程 > 子流程

会办接收岗【送处室主管】

会办接收岗【撤回处室主管】

会办接收岗【同意】

撤回任务:子流程 > 主流程

处室主管【送会办】

处室主管【撤回送会办】

处室主管【再次送会办】【接收员同意】

撤回任务:主流程 > 子流程

会办主管【送经办人】

会办主管【撤回经办人】

会办主管【同意】

撤回任务:主流程 > 并行子流程

同时送2个会办,A接收员同意,B主管送经办人

B主管【撤回送经办人】

B主管【同意】

核心代码实现


        List<FlowNode> doingNodes = findFlowNodesInMainProcess(taskItem.getProcDefId(), doingTaskKey);
        List<FlowNode> targetNodes = findFlowNodesInMainProcess(taskItem.getProcDefId(), taskKey);

        //撤回到子流程内部: 恢复子流程数据AddChildExecutionCmd
        if(doingNodes.size()>0 && targetNodes.size()==0){
            log.info(">>>> 主流程撤回到子流程 {} > {}", doingTaskKey, taskKey);
            revokeExecutions(bo.getProcInstId(), taskKey);
            //还原子流程subProcess边界
            ExecutionEntityImpl root = (ExecutionEntityImpl)runtimeService.createExecutionQuery().executionId(bo.getProcInstId()).singleResult();
            ExecutionEntityImpl child = (ExecutionEntityImpl)runtimeService.createExecutionQuery().parentId(bo.getProcInstId()).singleResult();
            Map<String, Object> varMap = this.getInstancesVariables(bo.getProcInstId());
            managementService.executeCommand(new AddChildExecutionCmd(root, child, varMap));
        }else if(doingNodes.size()==0 && targetNodes.size()==0){
            log.info(">>>> 子流程内任务撤回 {} > {}", doingTaskKey, taskKey);
            revokeActivityIds(bo.getProcInstId(), taskKey, doingTaskKeys);
        }else if(doingNodes.size()>0 && targetNodes.size()>0){
            log.info(">>>> 主流程内任务撤回 {} > {}", doingTaskKey, taskKey);
            revokeExecutions(bo.getProcInstId(), taskKey);
        }else if(doingNodes.size()==0 && targetNodes.size()>0){
            log.info(">>>> 子流程撤回到主流程 {} > {}", doingTaskKey, taskKey);
            revokeActivityIds(bo.getProcInstId(), taskKey, doingTaskKeys);
        }else {
            log.error(">>>> 未知撤回流程 {} > {}", doingTaskKey, taskKey);
        }

        //6.退回到指定节点(撤销所有子流程)
        Date endTime = taskItem.getEndTime();
        //撤回当前用户上一次已办理任务
        Integer taskNum = processCmdMapper.updateRevokeTask(procInstIdsStr, endTime);
        Integer actNum = processCmdMapper.updateRevokeAct(procInstIdsStr, endTime);
        log.info("success revokeTask  = {}, revokeAct = {}", taskNum, actNum);

        //更新待办任务并发通知
        handleDoingTask(taskItem.getBusinessKey(), false);
    }

    //撤回已经办理的任务
    private void revokeActivityIds(String procInstId, String taskKey, List<String> doingTaskKeys){
        if(doingTaskKeys.size()>0){
            runtimeService.createChangeActivityStateBuilder().processInstanceId(procInstId)
                    .moveActivityIdsToSingleActivityId(doingTaskKeys, taskKey).changeState();
        }
    }

    //撤回已经办理的任务
    private void revokeExecutions(String procInstId, String taskKey){
        List<String> executionIds = new ArrayList<>();
        List<Execution> executions = runtimeService.createExecutionQuery().parentId(procInstId).list();
        executions.forEach(execution -> executionIds.add(execution.getId()));
        if(executionIds.size()>0){
            runtimeService.createChangeActivityStateBuilder().moveExecutionsToSingleActivityId(executionIds, taskKey).changeState();
        }
    }


    //在主流程中查询节点
    private List<FlowNode> findFlowNodesInMainProcess(String processDefId, String activityId) {
        List<FlowNode> activities = new ArrayList<>();
        BpmnModel bpmnModel = repositoryService.getBpmnModel(processDefId);
        List<Process> processes = bpmnModel.getProcesses();
        for (Process process : processes) {
            FlowElement flowElement = process.getFlowElement(activityId);
            if (flowElement != null) {
                FlowNode flowNode = (FlowNode) flowElement;
                activities.add(flowNode);
            }
        }
        return activities;
    }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

星梦天河

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值