content: package com.ruoyi.flowable.flow;
  
  import com.googlecode.aviator.AviatorEvaluator;
  import com.googlecode.aviator.Expression;
  import org.flowable.bpmn.model.Process;
  import org.flowable.bpmn.model.*;
  import org.flowable.engine.RepositoryService;
  import org.flowable.engine.repository.ProcessDefinition;
  
  import java.util.ArrayList;
  import java.util.Collection;
  import java.util.List;
  import java.util.Map;
  
  /**
   * @author Xuan xuan
   * @date 2021/4/19 20:51
   */
  public class FindNextNodeUtil {
  
      /**
       * 获取下一步骤的用户任务
       *
       * @param repositoryService
       * @param map
       * @return
       */
      public static List<UserTask> getNextUserTasks(RepositoryService repositoryService, org.flowable.task.api.Task task, Map<String, Object> map) {
          List<UserTask> data = new ArrayList<>();
          ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery().processDefinitionId(task.getProcessDefinitionId()).singleResult();
          BpmnModel bpmnModel = repositoryService.getBpmnModel(processDefinition.getId());
          Process mainProcess = bpmnModel.getMainProcess();
          Collection<FlowElement> flowElements = mainProcess.getFlowElements();
          String key = task.getTaskDefinitionKey();
          FlowElement flowElement = bpmnModel.getFlowElement(key);
          next(flowElements, flowElement, map, data);
          return data;
      }
  
      public static void next(Collection<FlowElement> flowElements, FlowElement flowElement, Map<String, Object> map, List<UserTask> nextUser) {
          //如果是结束节点
          if (flowElement instanceof EndEvent) {
              //如果是子任务的结束节点
              if (getSubProcess(flowElements, flowElement) != null) {
                  flowElement = getSubProcess(flowElements, flowElement);
              }
          }
          //获取Task的出线信息--可以拥有多个
          List<SequenceFlow> outGoingFlows = null;
          if (flowElement instanceof Task) {
              outGoingFlows = ((Task) flowElement).getOutgoingFlows();
          } else if (flowElement instanceof Gateway) {
              outGoingFlows = ((Gateway) flowElement).getOutgoingFlows();
          } else if (flowElement instanceof StartEvent) {
              outGoingFlows = ((StartEvent) flowElement).getOutgoingFlows();
          } else if (flowElement instanceof SubProcess) {
              outGoingFlows = ((SubProcess) flowElement).getOutgoingFlows();
          } else if (flowElement instanceof CallActivity) {
              outGoingFlows = ((CallActivity) flowElement).getOutgoingFlows();
          }
          if (outGoingFlows != null && outGoingFlows.size() > 0) {
              //遍历所有的出线--找到可以正确执行的那一条
              for (SequenceFlow sequenceFlow : outGoingFlows) {
                  //1.有表达式，且为true
                  //2.无表达式
                  String expression = sequenceFlow.getConditionExpression();
                  if (expression == null || expressionResult(map, expression.substring(expression.lastIndexOf("{") + 1, expression.lastIndexOf("}")))) {
                      //出线的下一节点
                      String nextFlowElementID = sequenceFlow.getTargetRef();
                      if (checkSubProcess(nextFlowElementID, flowElements, nextUser)) {
                          continue;
                      }
  
                      //查询下一节点的信息
                      FlowElement nextFlowElement = getFlowElementById(nextFlowElementID, flowElements);
                      //调用流程
                      if (nextFlowElement instanceof CallActivity) {
                          CallActivity ca = (CallActivity) nextFlowElement;
                          if (ca.getLoopCharacteristics() != null) {
                              UserTask userTask = new UserTask();
                              userTask.setId(ca.getId());
  
                              userTask.setId(ca.getId());
                              userTask.setLoopCharacteristics(ca.getLoopCharacteristics());
                              userTask.setName(ca.getName());
                              nextUser.add(userTask);
                          }
                          next(flowElements, nextFlowElement, map, nextUser);
                      }
                      //用户任务
                      if (nextFlowElement instanceof UserTask) {
                          nextUser.add((UserTask) nextFlowElement);
                      }
                      //排他网关
                      else if (nextFlowElement instanceof ExclusiveGateway) {
                          next(flowElements, nextFlowElement, map, nextUser);
                      }
                      //并行网关
                      else if (nextFlowElement instanceof ParallelGateway) {
                          next(flowElements, nextFlowElement, map, nextUser);
                      }
                      //接收任务
                      else if (nextFlowElement instanceof ReceiveTask) {
                          next(flowElements, nextFlowElement, map, nextUser);
                      }
                      //服务任务
                      else if (nextFlowElement instanceof ServiceTask) {
                          next(flowElements, nextFlowElement, map, nextUser);
                      }
                      //子任务的起点
                      else if (nextFlowElement instanceof StartEvent) {
                          next(flowElements, nextFlowElement, map, nextUser);
                      }
                      //结束节点
                      else if (nextFlowElement instanceof EndEvent) {
                          next(flowElements, nextFlowElement, map, nextUser);
                      }
                  }
              }
          }
      }
  
      /**
       * 判断是否是多实例子流程并且需要设置集合类型变量
       */
      public static boolean checkSubProcess(String Id, Collection<FlowElement> flowElements, List<UserTask> nextUser) {
          for (FlowElement flowElement1 : flowElements) {
              if (flowElement1 instanceof SubProcess && flowElement1.getId().equals(Id)) {
  
                  SubProcess sp = (SubProcess) flowElement1;
                  if (sp.getLoopCharacteristics() != null) {
                      String inputDataItem = sp.getLoopCharacteristics().getInputDataItem();
                      UserTask userTask = new UserTask();
                      userTask.setId(sp.getId());
                      userTask.setLoopCharacteristics(sp.getLoopCharacteristics());
                      userTask.setName(sp.getName());
                      nextUser.add(userTask);
                      return true;
                  }
              }
          }
  
          return false;
  
      }
  
      /**
       * 查询一个节点的是否子任务中的节点，如果是，返回子任务
       *
       * @param flowElements 全流程的节点集合
       * @param flowElement  当前节点
       * @return
       */
      public static FlowElement getSubProcess(Collection<FlowElement> flowElements, FlowElement flowElement) {
          for (FlowElement flowElement1 : flowElements) {
              if (flowElement1 instanceof SubProcess) {
                  for (FlowElement flowElement2 : ((SubProcess) flowElement1).getFlowElements()) {
                      if (flowElement.equals(flowElement2)) {
                          return flowElement1;
                      }
                  }
              }
          }
          return null;
      }
  
  
      /**
       * 根据ID查询流程节点对象, 如果是子任务，则返回子任务的开始节点
       *
       * @param Id           节点ID
       * @param flowElements 流程节点集合
       * @return
       */
      public static FlowElement getFlowElementById(String Id, Collection<FlowElement> flowElements) {
          for (FlowElement flowElement : flowElements) {
              if (flowElement.getId().equals(Id)) {
                  //如果是子任务，则查询出子任务的开始节点
                  if (flowElement instanceof SubProcess) {
                      return getStartFlowElement(((SubProcess) flowElement).getFlowElements());
                  }
                  return flowElement;
              }
              if (flowElement instanceof SubProcess) {
                  FlowElement flowElement1 = getFlowElementById(Id, ((SubProcess) flowElement).getFlowElements());
                  if (flowElement1 != null) {
                      return flowElement1;
                  }
              }
          }
          return null;
      }
  
      /**
       * 返回流程的开始节点
       *
       * @param flowElements 节点集合
       * @description:
       */
      public static FlowElement getStartFlowElement(Collection<FlowElement> flowElements) {
          for (FlowElement flowElement : flowElements) {
              if (flowElement instanceof StartEvent) {
                  return flowElement;
              }
          }
          return null;
      }
  
      /**
       * 校验el表达式
       *
       * @param map
       * @param expression
       * @return
       */
      public static boolean expressionResult(Map<String, Object> map, String expression) {
          Expression exp = AviatorEvaluator.compile(expression);
          final Object execute = exp.execute(map);
          return Boolean.parseBoolean(String.valueOf(execute));
      }
  }
  