原理: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; } } } } }