Просмотр исходного кода

【功能优化】工作流:增加 SimpleModelUtils 遍历逻辑

YunaiV 7 месяцев назад
Родитель
Сommit
c93d7eb9c0

+ 2 - 2
yudao-module-bpm/yudao-module-bpm-api/src/main/java/cn/iocoder/yudao/module/bpm/enums/definition/BpmSimpleModelNodeType.java

@@ -28,8 +28,8 @@ public enum BpmSimpleModelNodeType implements IntArrayValuable {
 
     // 50 ~ 条件分支
     CONDITION_NODE(50, "sequenceFlow", "条件节点"), // 用于构建流转条件的表达式
-    CONDITION_BRANCH_NODE(51, "parallelGateway", "条件分支节点"),
-    PARALLEL_BRANCH_NODE(52, "exclusiveGateway", "并行分支节点"),
+    CONDITION_BRANCH_NODE(51, "exclusiveGateway", "条件分支节点"),
+    PARALLEL_BRANCH_NODE(52, "parallelGateway", "并行分支节点"),
     INCLUSIVE_BRANCH_NODE(53, "inclusiveGateway", "包容分支节点"),
     ;
 

+ 5 - 4
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/util/BpmnModelUtils.java

@@ -705,10 +705,10 @@ public class BpmnModelUtils {
             || currentElement instanceof UserTask
             || currentElement instanceof ServiceTask) {
             // 添加元素
-            FlowNode startEvent = (FlowNode) currentElement;
-            resultElements.add(startEvent);
+            FlowNode flowNode = (FlowNode) currentElement;
+            resultElements.add(flowNode);
             // 遍历子节点
-            startEvent.getOutgoingFlows().forEach(
+            flowNode.getOutgoingFlows().forEach(
                     nextElement -> simulateNextFlowElements(nextElement.getTargetFlowElement(), variables, resultElements, visitElements));
             return;
         }
@@ -755,6 +755,7 @@ public class BpmnModelUtils {
                     flow -> simulateNextFlowElements(flow.getTargetFlowElement(), variables, resultElements, visitElements));
         }
 
+        // 情况:ParallelGateway 并行,都满足,都走
         if (currentElement instanceof ParallelGateway) {
             Gateway gateway = (Gateway) currentElement;
             // 遍历子节点
@@ -771,7 +772,7 @@ public class BpmnModelUtils {
      * @param express 条件表达式
      * @return 是否满足条件
      */
-    private static boolean evalConditionExpress(Map<String, Object> variables, String express) {
+    public static boolean evalConditionExpress(Map<String, Object> variables, String express) {
         ManagementService managementService = SpringUtil.getBean(ManagementService.class);
         if (express == null) {
             return Boolean.FALSE;

+ 74 - 0
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/util/SimpleModelUtils.java

@@ -608,4 +608,78 @@ public class SimpleModelUtils {
         return id + "_join";
     }
 
+    // ========== SIMPLE 流程预测相关的方法 ==========
+
+    public static List<BpmSimpleModelNodeVO> simulateProcess(BpmSimpleModelNodeVO rootNode, Map<String, Object> variables) {
+        List<BpmSimpleModelNodeVO> resultNodes = new ArrayList<>();
+
+        // 从头开始遍历
+        simulateNextNode(rootNode, variables, resultNodes);
+        return resultNodes;
+    }
+
+    private static void simulateNextNode(BpmSimpleModelNodeVO currentNode, Map<String, Object> variables,
+                                  List<BpmSimpleModelNodeVO> resultNodes) {
+        // 如果不合法(包括为空),则直接结束
+        if (!isValidNode(currentNode)) {
+            return;
+        }
+        BpmSimpleModelNodeType nodeType = BpmSimpleModelNodeType.valueOf(currentNode.getType());
+        Assert.notNull(nodeType, "模型节点类型不支持");
+
+        // 情况:START_NODE/START_USER_NODE/APPROVE_NODE/END_NODE
+        if (nodeType == BpmSimpleModelNodeType.START_NODE
+            || nodeType == BpmSimpleModelNodeType.START_USER_NODE
+            || nodeType == BpmSimpleModelNodeType.APPROVE_NODE
+            || nodeType == BpmSimpleModelNodeType.END_NODE) {
+            // 添加元素
+            resultNodes.add(currentNode);
+        }
+
+        // 情况:CONDITION_BRANCH_NODE 排它,只有一个满足条件的。如果没有,就走默认的
+        if (nodeType == BpmSimpleModelNodeType.CONDITION_BRANCH_NODE) {
+            // 查找满足条件的 BpmSimpleModelNodeVO 节点
+            BpmSimpleModelNodeVO matchConditionNode = CollUtil.findOne(currentNode.getConditionNodes(),
+                    conditionNode -> BooleanUtil.isFalse(currentNode.getDefaultFlow())
+                        && evalConditionExpress(variables, conditionNode));
+            if (matchConditionNode == null) {
+                matchConditionNode = CollUtil.findOne(currentNode.getConditionNodes(),
+                        conditionNode -> BooleanUtil.isTrue(conditionNode.getDefaultFlow()));
+            }
+            Assert.notNull(matchConditionNode, "找不到条件节点({})", currentNode);
+            // 遍历满足条件的 BpmSimpleModelNodeVO 节点
+            simulateNextNode(matchConditionNode.getChildNode(), variables, resultNodes);
+        }
+
+        // 情况:INCLUSIVE_BRANCH_NODE 包容,多个满足条件的。如果没有,就走默认的
+        if (nodeType == BpmSimpleModelNodeType.INCLUSIVE_BRANCH_NODE) {
+            // 查找满足条件的 BpmSimpleModelNodeVO 节点
+            Collection<BpmSimpleModelNodeVO> matchConditionNodes = CollUtil.filterNew(currentNode.getConditionNodes(),
+                    conditionNode -> BooleanUtil.isFalse(currentNode.getDefaultFlow())
+                            && evalConditionExpress(variables, conditionNode));
+            if (CollUtil.isEmpty(matchConditionNodes)) {
+                matchConditionNodes = CollUtil.filterNew(currentNode.getConditionNodes(),
+                        conditionNode -> BooleanUtil.isTrue(conditionNode.getDefaultFlow()));
+            }
+            Assert.isTrue(!matchConditionNodes.isEmpty(), "找不到条件节点({})", currentNode);
+            // 遍历满足条件的 BpmSimpleModelNodeVO 节点
+            matchConditionNodes.forEach(matchConditionNode ->
+                    simulateNextNode(matchConditionNode.getChildNode(), variables, resultNodes));
+        }
+
+        // 情况:PARALLEL_BRANCH_NODE 并行,都满足,都走
+        if (nodeType == BpmSimpleModelNodeType.PARALLEL_BRANCH_NODE) {
+            // 遍历所有 BpmSimpleModelNodeVO 节点
+            currentNode.getConditionNodes().forEach(matchConditionNode ->
+                    simulateNextNode(matchConditionNode.getChildNode(), variables, resultNodes));
+        }
+
+        // 遍历子节点
+        simulateNextNode(currentNode.getChildNode(), variables, resultNodes);
+    }
+
+    public static boolean evalConditionExpress(Map<String, Object> variables, BpmSimpleModelNodeVO conditionNode) {
+        return BpmnModelUtils.evalConditionExpress(variables, ConditionNodeConvert.buildConditionExpression(conditionNode));
+    }
+
 }