撤回任务:主流程 > 主流程
处室主管【送科长审核】
处室主管【撤回科长审核】
流程日志
撤回任务:子流程 > 子流程
会办接收岗【送处室主管】
会办接收岗【撤回处室主管】
会办接收岗【同意】
撤回任务:子流程 > 主流程
处室主管【送会办】
处室主管【撤回送会办】
处室主管【再次送会办】【接收员同意】
撤回任务:主流程 > 子流程
会办主管【送经办人】
会办主管【撤回经办人】
会办主管【同意】
撤回任务:主流程 > 并行子流程
同时送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;
}