原理:java
- 在流程表单数据正式提交审核前,将流程表单数据 formData 及流程执行实例 ExecutionEntity 传递给接口
- 接口在流程定义取得当前节点信息并循环查找出线 SequenceFlow 还须要注意遇到网关时应该怎样处理
- 使用变量执行出线 SequenceFlow 条件(相似完成提交任务操做)
- 找出第一个用户任务UserTask 根据这个UserTask中信息,咱们就能拿到流程审核人了
- 最重要的一点,在第三点中使用变量去执行条件的时候,变量会被持久化至数据库中,因此咱们必定要在事务中进行操做,操做完成后回滚清空当前事务,避免数据紊乱
项目完整源码连接
如下是所有代码,此逻辑仅供参考git
package com.nutzfw.core.plugin.flowable.cmd; import org.apache.commons.collections.CollectionUtils; import org.flowable.bpmn.model.*; import org.flowable.common.engine.impl.interceptor.Command; import org.flowable.common.engine.impl.interceptor.CommandContext; import org.flowable.engine.impl.persistence.entity.ExecutionEntity; import org.flowable.engine.impl.util.condition.ConditionUtil; import java.util.List; import java.util.Map; /** * @author huchuc@vip.qq.com * @date: 2019/7/9 * 使用示例,必定要放到事务中,不然变量会入库,致使数据紊乱 * try { * Trans.begin(); * UserTask userTask = managementService.executeCommand(new FindNextUserTaskNodeCmd(execution, bpmnModel, vars)); * System.out.println(userTask.getId()); * } finally { * Trans.clear(true); * } */ public class FindNextUserTaskNodeCmd implements Command<UserTask> { private final ExecutionEntity execution; private final BpmnModel bpmnModel; private Map<String, Object> vars; /** * 返回下一用户节点 */ private UserTask nextUserTask; /** * @param execution 当前执行实例 * @param bpmnModel 当前执行实例的模型 * @param vars 参与计算流程条件的变量 */ public FindNextUserTaskNodeCmd(ExecutionEntity execution, BpmnModel bpmnModel, Map<String, Object> vars) { this.execution = execution; this.bpmnModel = bpmnModel; this.vars = vars; } /** * @param execution 当前执行实例 * @param bpmnModel 当前执行实例的模型 */ public FindNextUserTaskNodeCmd(ExecutionEntity execution, BpmnModel bpmnModel) { this.execution = execution; this.bpmnModel = bpmnModel; } @Override public UserTask execute(CommandContext commandContext) { execution.setVariables(vars); FlowElement currentNode = bpmnModel.getFlowElement(execution.getActivityId()); List<SequenceFlow> outgoingFlows = ((FlowNode) currentNode).getOutgoingFlows(); if (CollectionUtils.isNotEmpty(outgoingFlows)) { this.findNextUserTaskNode(outgoingFlows, execution); } return nextUserTask; } void findNextUserTaskNode(List<SequenceFlow> outgoingFlows, ExecutionEntity execution) { sw: for (SequenceFlow outgoingFlow : outgoingFlows) { if (ConditionUtil.hasTrueCondition(outgoingFlow, execution)) { if (outgoingFlow.getTargetFlowElement() instanceof ExclusiveGateway) { //只有排他网关才继续 ExclusiveGateway exclusiveGateway = (ExclusiveGateway) outgoingFlow.getTargetFlowElement(); findNextUserTaskNode(exclusiveGateway.getOutgoingFlows(), execution); } else if (outgoingFlow.getTargetFlowElement() instanceof UserTask) { nextUserTask = (UserTask) outgoingFlow.getTargetFlowElement(); //找到第一个符合条件的userTask就跳出循环 break sw; } } } } }