原理:
- 在流程表单数据正式提交审核前,将流程表单数据 formData 及流程执行实例 ExecutionEntity 传递给接口
- 接口在流程定义取得当前节点信息并循环查找出线 SequenceFlow 还需要注意遇到网关时应该怎样处理
- 使用变量执行出线 SequenceFlow 条件(类似完成提交任务操作)
- 找出第一个用户任务UserTask 根据这个UserTask中信息,我们就能拿到流程审核人了
- 最重要的一点,在第三点中使用变量去执行条件的时候,变量会被持久化至数据库中,所以我们一定要在事务中进行操作,操作完成后回滚清空当前事务,避免数据紊乱
项目完整源码链接
以下是全部代码,此逻辑仅供参考
1package com.nutzfw.core.plugin.flowable.cmd; 2 3import org.apache.commons.collections.CollectionUtils; 4import org.flowable.bpmn.model.*; 5import org.flowable.common.engine.impl.interceptor.Command; 6import org.flowable.common.engine.impl.interceptor.CommandContext; 7import org.flowable.engine.impl.persistence.entity.ExecutionEntity; 8import org.flowable.engine.impl.util.condition.ConditionUtil; 9 10import java.util.List; 11import java.util.Map; 12 13/** 14 * @author huchuc@vip.qq.com 15 * @date: 2019/7/9 16 * 使用示例,一定要放到事务中,否则变量会入库,导致数据紊乱 17 * try { 18 * Trans.begin(); 19 * UserTask userTask = managementService.executeCommand(new FindNextUserTaskNodeCmd(execution, bpmnModel, vars)); 20 * System.out.println(userTask.getId()); 21 * } finally { 22 * Trans.clear(true); 23 * } 24 */ 25public class FindNextUserTaskNodeCmd implements Command<UserTask> { 26 27 private final ExecutionEntity execution; 28 private final BpmnModel bpmnModel; 29 private Map<String, Object> vars; 30 /** 31 * 返回下一用户节点 32 */ 33 private UserTask nextUserTask; 34 35 /** 36 * @param execution 当前执行实例 37 * @param bpmnModel 当前执行实例的模型 38 * @param vars 参与计算流程条件的变量 39 */ 40 public FindNextUserTaskNodeCmd(ExecutionEntity execution, BpmnModel bpmnModel, Map<String, Object> vars) { 41 this.execution = execution; 42 this.bpmnModel = bpmnModel; 43 this.vars = vars; 44 } 45 46 /** 47 * @param execution 当前执行实例 48 * @param bpmnModel 当前执行实例的模型 49 */ 50 public FindNextUserTaskNodeCmd(ExecutionEntity execution, BpmnModel bpmnModel) { 51 this.execution = execution; 52 this.bpmnModel = bpmnModel; 53 } 54 55 @Override 56 public UserTask execute(CommandContext commandContext) { 57 execution.setVariables(vars); 58 FlowElement currentNode = bpmnModel.getFlowElement(execution.getActivityId()); 59 List<SequenceFlow> outgoingFlows = ((FlowNode) currentNode).getOutgoingFlows(); 60 if (CollectionUtils.isNotEmpty(outgoingFlows)) { 61 this.findNextUserTaskNode(outgoingFlows, execution); 62 } 63 return nextUserTask; 64 } 65 66 67 void findNextUserTaskNode(List<SequenceFlow> outgoingFlows, ExecutionEntity execution) { 68 sw: 69 for (SequenceFlow outgoingFlow : outgoingFlows) { 70 if (ConditionUtil.hasTrueCondition(outgoingFlow, execution)) { 71 if (outgoingFlow.getTargetFlowElement() instanceof ExclusiveGateway) { 72 //只有排他网关才继续 73 ExclusiveGateway exclusiveGateway = (ExclusiveGateway) outgoingFlow.getTargetFlowElement(); 74 findNextUserTaskNode(exclusiveGateway.getOutgoingFlows(), execution); 75 } else if (outgoingFlow.getTargetFlowElement() instanceof UserTask) { 76 nextUserTask = (UserTask) outgoingFlow.getTargetFlowElement(); 77 //找到第一个符合条件的userTask就跳出循环 78 break sw; 79 } 80 } 81 } 82 } 83}