From ffe7921a138331185186fd100846fe50dcaf841c Mon Sep 17 00:00:00 2001
From: 云 <2163098428@qq.com>
Date: 星期四, 16 七月 2026 10:08:02 +0800
Subject: [PATCH] 1.采购管理-采购申请恢复

---
 yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/util/BpmnModelUtils.java |  127 +++++++++++++++++++++++++++++++++++++++++
 1 files changed, 125 insertions(+), 2 deletions(-)

diff --git a/yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/util/BpmnModelUtils.java b/yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/util/BpmnModelUtils.java
index b624c53..726e0dc 100644
--- a/yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/util/BpmnModelUtils.java
+++ b/yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/util/BpmnModelUtils.java
@@ -457,6 +457,54 @@
     }
 
     /**
+     * 鏍规嵁鑺傜偣锛岄�掑綊鑾峰彇涓婃父 source 涓� UserTask 鐨勫叆鍙h繛绾�
+     *
+     * 1. 濡傛灉褰撳墠鑺傜偣鐨勭洿鎺ュ叆鍙h繛绾� source 灏辨槸 UserTask锛屽垯鐩存帴杩斿洖璇ヨ繛绾�
+     * 2. 濡傛灉褰撳墠鑺傜偣鐨勭洿鎺ュ叆鍙h繛绾� source 涓嶆槸 UserTask锛屽垯缁х画鍚戜笂閫掑綊鏌ユ壘
+     * 3. 濡傛灉閫掑綊杩囩▼涓亣鍒� StartEvent 鎴� SubProcess锛屽垯鍋滄璇ュ垎鏀户缁悜涓婃煡鎵�
+     *
+     * @param source 璧峰鑺傜偣
+     * @return 涓婃父杩炴帴 UserTask 鐨勫叆鍙h繛绾垮垪琛�
+     */
+    public static List<SequenceFlow> getElementIncomingUserTaskFlows(FlowElement source) {
+        List<SequenceFlow> result = new ArrayList<>();
+        collectElementIncomingUserTaskFlows(source, new HashSet<>(), new HashSet<>(), result);
+        return result;
+    }
+
+    private static void collectElementIncomingUserTaskFlows(FlowElement source, Set<String> visitedSequenceFlowIds,
+                                                            Set<String> resultSequenceFlowIds, List<SequenceFlow> result) {
+        // 濡傛灉鏄紑濮嬭妭鐐规垨瀛愭祦绋嬶紝鍒欏仠姝㈣鍒嗘敮鍚戜笂鏌ユ壘
+        if (source == null || source instanceof StartEvent || source instanceof SubProcess) {
+            return;
+        }
+        // 鑾峰彇鍏ュ彛杩炵嚎
+        List<SequenceFlow> incomingFlows = getElementIncomingFlows(source);
+        if (CollUtil.isEmpty(incomingFlows)) {
+            return;
+        }
+
+        // 寰幆鎵惧埌鐩爣鍏冪礌
+        for (SequenceFlow incomingFlow : incomingFlows) {
+            // 濡傛灉鍙戠幇杩炵嚎閲嶅锛岃鏄庤繛绾垮凡缁忚蛋杩囥�傝烦杩�
+            if (incomingFlow == null || !visitedSequenceFlowIds.add(incomingFlow.getId())) {
+                continue;
+            }
+            // 濡傛灉 source 鏄� UserTask锛屽垯娣诲姞鍒扮粨鏋滀腑
+            FlowElement sourceFlowElement = incomingFlow.getSourceFlowElement();
+            if (sourceFlowElement instanceof UserTask) {
+                if (resultSequenceFlowIds.add(incomingFlow.getId())) {
+                    result.add(incomingFlow);
+                }
+                continue;
+            }
+            // 閫掑綊鍚戜笂鏌ユ壘 UserTask
+            collectElementIncomingUserTaskFlows(sourceFlowElement, visitedSequenceFlowIds,
+                    resultSequenceFlowIds, result);
+        }
+    }
+
+    /**
      * 鏍规嵁鑺傜偣锛岃幏鍙栧嚭鍙h繛绾�
      *
      * @param source 璧峰鑺傜偣
@@ -910,13 +958,88 @@
     }
 
     /**
-     * 鏌ユ壘璧峰鑺傜偣涓嬩竴涓敤鎴蜂换鍔″垪琛ㄥ垪琛�
+     * 鏌ユ壘璧峰鑺傜偣涓嬩竴涓敤鎴蜂换鍔″垪琛�, 璇ユ柟娉曚細閫掑綊鍚戜笅鏌ユ壘锛氳烦杩囬潪 UserTask 鑺傜偣, 鏀寔缃戝叧鏉′欢鍒ゆ柇
+     *
+     * <ul>
+     *     <li>鎺掍粬缃戝叧锛氳蛋婊¤冻鏉′欢鐨勫敮涓�涓�鏉¤矾寰勶紙鍚粯璁よ矾寰勫厹搴曪級</li>
+     *     <li>鍖呭缃戝叧锛氳蛋鎵�鏈夋弧瓒虫潯浠剁殑璺緞</li>
+     *     <li>骞惰缃戝叧锛氳蛋鎵�鏈夊嚭鍙h矾寰�</li>
+     * </ul>
+     *
+     * @param currentElement 褰撳墠鑺傜偣
+     * @param bpmnModel      BPMN 妯″瀷
+     * @param variables      娴佺▼鍙橀噺锛堢敤浜庣綉鍏虫潯浠跺垽鏂級
+     * @return 涓嬩竴涓敤鎴蜂换鍔¤妭鐐瑰垪琛�
+     */
+    public static List<UserTask> getNextUserTasks(FlowElement currentElement, BpmnModel bpmnModel,
+                                                      Map<String, Object> variables) {
+        return getNextUserTasks(currentElement, bpmnModel, variables, new HashSet<>(), new ArrayList<>());
+    }
+
+    private static List<UserTask> getNextUserTasks(FlowElement currentElement, BpmnModel bpmnModel,
+                                                       Map<String, Object> variables,
+                                                       Set<String> hasSequenceFlow, List<UserTask> userTaskList) {
+        // 1. 鏍规嵁鑺傜偣绫诲瀷鍐冲畾瑕侀亶鍘嗙殑鍑哄彛杩炵嚎
+        //    缃戝叧闇�瑕佹牴鎹潯浠惰〃杈惧紡绛涢�夛紱鍏跺畠鑺傜偣鐩存帴鍙栨墍鏈� outgoing flows
+        List<SequenceFlow> outgoingFlows;
+        if (currentElement instanceof Gateway) {
+            outgoingFlows = getGatewayOutgoingFlows((Gateway) currentElement, variables);
+        } else {
+            outgoingFlows = getElementOutgoingFlows(currentElement);
+        }
+        if (CollUtil.isEmpty(outgoingFlows)) {
+            return userTaskList;
+        }
+        // 2. 閬嶅巻鍑哄彛杩炵嚎锛岄�掑綊鏌ユ壘鐢ㄦ埛浠诲姟
+        for (SequenceFlow outgoingFlow : outgoingFlows) {
+            // 闃叉杩炵嚎鎴愮幆瀵艰嚧姝诲惊鐜�
+            if (hasSequenceFlow.contains(outgoingFlow.getId())) {
+                continue;
+            }
+            hasSequenceFlow.add(outgoingFlow.getId());
+            // 鑾峰彇鐩爣鑺傜偣
+            FlowElement targetElement = bpmnModel.getFlowElement(outgoingFlow.getTargetRef());
+            if (targetElement == null || targetElement instanceof EndEvent) {
+                continue;
+            }
+            if (targetElement instanceof UserTask) {
+                // 鎵惧埌鐢ㄦ埛浠诲姟锛氬姞鍏ョ粨鏋�
+                userTaskList.add((UserTask) targetElement);
+            } else {
+                // 闈炵敤鎴蜂换鍔★紙缃戝叧銆佹湇鍔′换鍔°�佷腑闂翠簨浠剁瓑锛夛細缁х画閫掑綊鍚戜笅鏌ユ壘
+                getNextUserTasks(targetElement, bpmnModel, variables, hasSequenceFlow, userTaskList);
+            }
+        }
+        return userTaskList;
+    }
+
+    /**
+     * 鏍规嵁缃戝叧绫诲瀷涓庢祦绋嬪彉閲忥紝绛涢�夌綉鍏崇殑鍑哄彛杩炵嚎
+     *
+     * @param gateway   缃戝叧鑺傜偣
+     * @param variables 娴佺▼鍙橀噺
+     * @return 鍛戒腑鐨勫嚭鍙h繛绾垮垪琛�
+     */
+    private static List<SequenceFlow> getGatewayOutgoingFlows(Gateway gateway, Map<String, Object> variables) {
+        if (gateway instanceof ExclusiveGateway) {
+            SequenceFlow matchFlow = findMatchSequenceFlowByExclusiveGateway(gateway, variables);
+            return matchFlow == null ? Collections.emptyList() : Collections.singletonList(matchFlow);
+        }
+        if (gateway instanceof InclusiveGateway) {
+            return new ArrayList<>(findMatchSequenceFlowsByInclusiveGateway(gateway, variables));
+        }
+        // 榛樿锛堝苟琛岀綉鍏崇瓑锛夛細璧版墍鏈夊嚭鍙�
+        return gateway.getOutgoingFlows();
+    }
+
+    /**
+     * 鏌ユ壘璧峰鑺傜偣涓嬩竴涓敤鎴蜂换鍔″垪琛ㄥ垪琛�, 涓嶅垽鏂綉鍏虫潯浠�
      *
      * @param source 璧峰鑺傜偣
      * @return 缁撴灉
      */
     public static List<UserTask> getNextUserTasks(FlowElement source) {
-        return getNextUserTasks(source, null, null);
+        return getNextUserTasks(source, new HashSet<>(), new ArrayList<>());
     }
 
     /**

--
Gitblit v1.9.3