Commit 83a133b344664889571cbe839b8b73dd56d1ae67

Authored by YunaiV
1 parent ffdaf3a8

bpm:优化 BpmnModelUtils

yudao-framework/yudao-spring-boot-starter-flowable/src/main/java/cn/iocoder/yudao/framework/flowable/core/util/ModelUtils.java renamed to yudao-framework/yudao-spring-boot-starter-flowable/src/main/java/cn/iocoder/yudao/framework/flowable/core/util/BpmnModelUtils.java
1 1 package cn.iocoder.yudao.framework.flowable.core.util;
2 2  
  3 +import cn.hutool.core.collection.CollUtil;
  4 +import org.flowable.bpmn.converter.BpmnXMLConverter;
3 5 import org.flowable.bpmn.model.Process;
4 6 import org.flowable.bpmn.model.*;
5 7  
6   -import java.util.ArrayList;
7   -import java.util.HashSet;
8   -import java.util.List;
9   -import java.util.Set;
  8 +import java.util.*;
10 9  
11 10 /**
12 11 * 流程模型转操作工具类
13 12 */
14   -public class ModelUtils {
  13 +public class BpmnModelUtils {
15 14  
16 15 /**
17 16 * 根据节点,获取入口连线
... ... @@ -20,14 +19,12 @@ public class ModelUtils {
20 19 * @return 入口连线列表
21 20 */
22 21 public static List<SequenceFlow> getElementIncomingFlows(FlowElement source) {
23   - List<SequenceFlow> sequenceFlows = new ArrayList<>();
24 22 if (source instanceof FlowNode) {
25   - sequenceFlows = ((FlowNode) source).getIncomingFlows();
  23 + return ((FlowNode) source).getIncomingFlows();
26 24 }
27   - return sequenceFlows;
  25 + return new ArrayList<>();
28 26 }
29 27  
30   -
31 28 /**
32 29 * 根据节点,获取出口连线
33 30 *
... ... @@ -35,19 +32,17 @@ public class ModelUtils {
35 32 * @return 出口连线列表
36 33 */
37 34 public static List<SequenceFlow> getElementOutgoingFlows(FlowElement source) {
38   - List<SequenceFlow> sequenceFlows = new ArrayList<>();
39 35 if (source instanceof FlowNode) {
40   - sequenceFlows = ((FlowNode) source).getOutgoingFlows();
  36 + return ((FlowNode) source).getOutgoingFlows();
41 37 }
42   - return sequenceFlows;
  38 + return new ArrayList<>();
43 39 }
44 40  
45   -
46 41 /**
47 42 * 获取流程元素信息
48 43 *
49   - * @param model bpmnModel对象
50   - * @param flowElementId 元素ID
  44 + * @param model bpmnModel 对象
  45 + * @param flowElementId 元素 ID
51 46 * @return 元素信息
52 47 */
53 48 public static FlowElement getFlowElementById(BpmnModel model, String flowElementId) {
... ... @@ -56,50 +51,92 @@ public class ModelUtils {
56 51 }
57 52  
58 53 /**
  54 + * 获得 BPMN 流程中,指定的元素们
  55 + *
  56 + * @param model
  57 + * @param clazz 指定元素。例如说,{@link UserTask}、{@link Gateway} 等等
  58 + * @return 元素们
  59 + */
  60 + public static <T extends FlowElement> List<T> getBpmnModelElements(BpmnModel model, Class<T> clazz) {
  61 + List<T> result = new ArrayList<>();
  62 + model.getProcesses().forEach(process -> {
  63 + process.getFlowElements().forEach(flowElement -> {
  64 + if (flowElement.getClass().isAssignableFrom(clazz)) {
  65 + result.add((T) flowElement);
  66 + }
  67 + });
  68 + });
  69 + return result;
  70 + }
  71 +
  72 + /**
  73 + * 比较 两个bpmnModel 是否相同
  74 + * @param oldModel 老的bpmn model
  75 + * @param newModel 新的bpmn model
  76 + */
  77 + public static boolean equals(BpmnModel oldModel, BpmnModel newModel) {
  78 + // 由于 BpmnModel 未提供 equals 方法,所以只能转成字节数组,进行比较
  79 + return Arrays.equals(getBpmnBytes(oldModel), getBpmnBytes(newModel));
  80 + }
  81 +
  82 + /**
  83 + * 把 bpmnModel 转换成 byte[]
  84 + * @param model bpmnModel
  85 + */
  86 + public static byte[] getBpmnBytes(BpmnModel model) {
  87 + if (model == null) {
  88 + return new byte[0];
  89 + }
  90 + BpmnXMLConverter converter = new BpmnXMLConverter();
  91 + return converter.convertToXML(model);
  92 + }
  93 +
  94 + // ========== 遍历相关的方法 ==========
  95 +
  96 + /**
59 97 * 找到 source 节点之前的所有用户任务节点
60 98 *
61 99 * @param source 起始节点
62 100 * @param hasSequenceFlow 已经经过的连线的 ID,用于判断线路是否重复
63 101 * @param userTaskList 已找到的用户任务节点
64   - * @return
  102 + * @return 用户任务节点 数组
65 103 */
66   - public static List<UserTask> getPreUserTaskList(FlowElement source, Set<String> hasSequenceFlow, List<UserTask> userTaskList) {
  104 + public static List<UserTask> getPreviousUserTaskList(FlowElement source, Set<String> hasSequenceFlow, List<UserTask> userTaskList) {
67 105 userTaskList = userTaskList == null ? new ArrayList<>() : userTaskList;
68 106 hasSequenceFlow = hasSequenceFlow == null ? new HashSet<>() : hasSequenceFlow;
69   -
70 107 // 如果该节点为开始节点,且存在上级子节点,则顺着上级子节点继续迭代
71 108 if (source instanceof StartEvent && source.getSubProcess() != null) {
72   - userTaskList = getPreUserTaskList(source.getSubProcess(), hasSequenceFlow, userTaskList);
  109 + userTaskList = getPreviousUserTaskList(source.getSubProcess(), hasSequenceFlow, userTaskList);
73 110 }
74 111  
75 112 // 根据类型,获取入口连线
76 113 List<SequenceFlow> sequenceFlows = getElementIncomingFlows(source);
77   -
78   - if (sequenceFlows != null) {
79   - // 循环找到目标元素
80   - for (SequenceFlow sequenceFlow : sequenceFlows) {
81   - // 如果发现连线重复,说明循环了,跳过这个循环
82   - if (hasSequenceFlow.contains(sequenceFlow.getId())) {
83   - continue;
84   - }
85   - // 添加已经走过的连线
86   - hasSequenceFlow.add(sequenceFlow.getId());
87   - // 类型为用户节点,则新增父级节点
88   - if (sequenceFlow.getSourceFlowElement() instanceof UserTask) {
89   - userTaskList.add((UserTask) sequenceFlow.getSourceFlowElement());
90   - }
91   - // 类型为子流程,则添加子流程开始节点出口处相连的节点
92   - if (sequenceFlow.getSourceFlowElement() instanceof SubProcess) {
93   - // 获取子流程用户任务节点
94   - List<UserTask> childUserTaskList = findChildProcessUserTasks((StartEvent) ((SubProcess) sequenceFlow.getSourceFlowElement()).getFlowElements().toArray()[0], null, null);
95   - // 如果找到节点,则说明该线路找到节点,不继续向下找,反之继续
96   - if (childUserTaskList != null && childUserTaskList.size() > 0) {
97   - userTaskList.addAll(childUserTaskList);
98   - }
  114 + if (sequenceFlows == null) {
  115 + return userTaskList;
  116 + }
  117 + // 循环找到目标元素
  118 + for (SequenceFlow sequenceFlow : sequenceFlows) {
  119 + // 如果发现连线重复,说明循环了,跳过这个循环
  120 + if (hasSequenceFlow.contains(sequenceFlow.getId())) {
  121 + continue;
  122 + }
  123 + // 添加已经走过的连线
  124 + hasSequenceFlow.add(sequenceFlow.getId());
  125 + // 类型为用户节点,则新增父级节点
  126 + if (sequenceFlow.getSourceFlowElement() instanceof UserTask) {
  127 + userTaskList.add((UserTask) sequenceFlow.getSourceFlowElement());
  128 + }
  129 + // 类型为子流程,则添加子流程开始节点出口处相连的节点
  130 + if (sequenceFlow.getSourceFlowElement() instanceof SubProcess) {
  131 + // 获取子流程用户任务节点
  132 + List<UserTask> childUserTaskList = findChildProcessUserTaskList((StartEvent) ((SubProcess) sequenceFlow.getSourceFlowElement()).getFlowElements().toArray()[0], null, null);
  133 + // 如果找到节点,则说明该线路找到节点,不继续向下找,反之继续
  134 + if (CollUtil.isNotEmpty(childUserTaskList)) {
  135 + userTaskList.addAll(childUserTaskList);
99 136 }
100   - // 继续迭代
101   - userTaskList = getPreUserTaskList(sequenceFlow.getSourceFlowElement(), hasSequenceFlow, userTaskList);
102 137 }
  138 + // 继续迭代
  139 + userTaskList = getPreviousUserTaskList(sequenceFlow.getSourceFlowElement(), hasSequenceFlow, userTaskList);
103 140 }
104 141 return userTaskList;
105 142 }
... ... @@ -110,41 +147,41 @@ public class ModelUtils {
110 147 * @param source 起始节点
111 148 * @param hasSequenceFlow 已经经过的连线的 ID,用于判断线路是否重复
112 149 * @param userTaskList 需要撤回的用户任务列表
113   - * @return
  150 + * @return 用户任务节点
114 151 */
115   - public static List<UserTask> findChildProcessUserTasks(FlowElement source, Set<String> hasSequenceFlow, List<UserTask> userTaskList) {
  152 + public static List<UserTask> findChildProcessUserTaskList(FlowElement source, Set<String> hasSequenceFlow, List<UserTask> userTaskList) {
116 153 hasSequenceFlow = hasSequenceFlow == null ? new HashSet<>() : hasSequenceFlow;
117 154 userTaskList = userTaskList == null ? new ArrayList<>() : userTaskList;
118 155  
119 156 // 根据类型,获取出口连线
120 157 List<SequenceFlow> sequenceFlows = getElementOutgoingFlows(source);
121   -
122   - if (sequenceFlows != null) {
123   - // 循环找到目标元素
124   - for (SequenceFlow sequenceFlow : sequenceFlows) {
125   - // 如果发现连线重复,说明循环了,跳过这个循环
126   - if (hasSequenceFlow.contains(sequenceFlow.getId())) {
127   - continue;
128   - }
129   - // 添加已经走过的连线
130   - hasSequenceFlow.add(sequenceFlow.getId());
131   - // 如果为用户任务类型,且任务节点的 Key 正在运行的任务中存在,添加
132   - if (sequenceFlow.getTargetFlowElement() instanceof UserTask) {
133   - userTaskList.add((UserTask) sequenceFlow.getTargetFlowElement());
  158 + if (sequenceFlows == null) {
  159 + return userTaskList;
  160 + }
  161 + // 循环找到目标元素
  162 + for (SequenceFlow sequenceFlow : sequenceFlows) {
  163 + // 如果发现连线重复,说明循环了,跳过这个循环
  164 + if (hasSequenceFlow.contains(sequenceFlow.getId())) {
  165 + continue;
  166 + }
  167 + // 添加已经走过的连线
  168 + hasSequenceFlow.add(sequenceFlow.getId());
  169 + // 如果为用户任务类型,且任务节点的 Key 正在运行的任务中存在,添加
  170 + if (sequenceFlow.getTargetFlowElement() instanceof UserTask) {
  171 + userTaskList.add((UserTask) sequenceFlow.getTargetFlowElement());
  172 + continue;
  173 + }
  174 + // 如果节点为子流程节点情况,则从节点中的第一个节点开始获取
  175 + if (sequenceFlow.getTargetFlowElement() instanceof SubProcess) {
  176 + List<UserTask> childUserTaskList = findChildProcessUserTaskList((FlowElement) (((SubProcess) sequenceFlow.getTargetFlowElement()).getFlowElements().toArray()[0]), hasSequenceFlow, null);
  177 + // 如果找到节点,则说明该线路找到节点,不继续向下找,反之继续
  178 + if (CollUtil.isNotEmpty(childUserTaskList)) {
  179 + userTaskList.addAll(childUserTaskList);
134 180 continue;
135 181 }
136   - // 如果节点为子流程节点情况,则从节点中的第一个节点开始获取
137   - if (sequenceFlow.getTargetFlowElement() instanceof SubProcess) {
138   - List<UserTask> childUserTaskList = findChildProcessUserTasks((FlowElement) (((SubProcess) sequenceFlow.getTargetFlowElement()).getFlowElements().toArray()[0]), hasSequenceFlow, null);
139   - // 如果找到节点,则说明该线路找到节点,不继续向下找,反之继续
140   - if (childUserTaskList != null && childUserTaskList.size() > 0) {
141   - userTaskList.addAll(childUserTaskList);
142   - continue;
143   - }
144   - }
145   - // 继续迭代
146   - userTaskList = findChildProcessUserTasks(sequenceFlow.getTargetFlowElement(), hasSequenceFlow, userTaskList);
147 182 }
  183 + // 继续迭代
  184 + userTaskList = findChildProcessUserTaskList(sequenceFlow.getTargetFlowElement(), hasSequenceFlow, userTaskList);
148 185 }
149 186 return userTaskList;
150 187 }
... ... @@ -161,36 +198,36 @@ public class ModelUtils {
161 198 */
162 199 public static boolean isSequentialReachable(FlowElement source, FlowElement target, Set<String> visitedElements) {
163 200 visitedElements = visitedElements == null ? new HashSet<>() : visitedElements;
164   - //不能是开始事件和子流程
  201 + // 不能是开始事件和子流程
165 202 if (source instanceof StartEvent && isInEventSubprocess(source)) {
166 203 return false;
167 204 }
168 205  
169 206 // 根据类型,获取入口连线
170 207 List<SequenceFlow> sequenceFlows = getElementIncomingFlows(source);
171   - if (sequenceFlows != null && sequenceFlows.size() > 0) {
172   - // 循环找到目标元素
173   - for (SequenceFlow sequenceFlow : sequenceFlows) {
174   - // 如果发现连线重复,说明循环了,跳过这个循环
175   - if (visitedElements.contains(sequenceFlow.getId())) {
176   - continue;
177   - }
178   - // 添加已经走过的连线
179   - visitedElements.add(sequenceFlow.getId());
180   - FlowElement sourceFlowElement = sequenceFlow.getSourceFlowElement();
181   - // 这条线路存在目标节点,这条线路完成,进入下个线路
182   - if (target.getId().equals(sourceFlowElement.getId())) {
183   - continue;
184   - }
185   - // 如果目标节点为并行网关,则不继续
186   - if (sourceFlowElement instanceof ParallelGateway) {
187   - return false;
188   - }
189   - // 否则就继续迭代
190   - boolean isSequential = isSequentialReachable(sourceFlowElement, target, visitedElements);
191   - if (!isSequential) {
192   - return false;
193   - }
  208 + if (CollUtil.isEmpty(sequenceFlows)) {
  209 + return true;
  210 + }
  211 + // 循环找到目标元素
  212 + for (SequenceFlow sequenceFlow : sequenceFlows) {
  213 + // 如果发现连线重复,说明循环了,跳过这个循环
  214 + if (visitedElements.contains(sequenceFlow.getId())) {
  215 + continue;
  216 + }
  217 + // 添加已经走过的连线
  218 + visitedElements.add(sequenceFlow.getId());
  219 + // 这条线路存在目标节点,这条线路完成,进入下个线路
  220 + FlowElement sourceFlowElement = sequenceFlow.getSourceFlowElement();
  221 + if (target.getId().equals(sourceFlowElement.getId())) {
  222 + continue;
  223 + }
  224 + // 如果目标节点为并行网关,则不继续
  225 + if (sourceFlowElement instanceof ParallelGateway) {
  226 + return false;
  227 + }
  228 + // 否则就继续迭代
  229 + if (!isSequentialReachable(sourceFlowElement, target, visitedElements)) {
  230 + return false;
194 231 }
195 232 }
196 233 return true;
... ... @@ -200,9 +237,9 @@ public class ModelUtils {
200 237 * 判断当前节点是否属于不同的子流程
201 238 *
202 239 * @param flowElement 被判断的节点
203   - * @return true表示属于子流程
  240 + * @return true 表示属于子流程
204 241 */
205   - protected static boolean isInEventSubprocess(FlowElement flowElement) {
  242 + private static boolean isInEventSubprocess(FlowElement flowElement) {
206 243 FlowElementsContainer flowElementsContainer = flowElement.getParentContainer();
207 244 while (flowElementsContainer != null) {
208 245 if (flowElementsContainer instanceof EventSubProcess) {
... ... @@ -218,7 +255,6 @@ public class ModelUtils {
218 255 return false;
219 256 }
220 257  
221   -
222 258 /**
223 259 * 根据正在运行的任务节点,迭代获取子级任务节点列表,向后找
224 260 *
... ... @@ -226,12 +262,12 @@ public class ModelUtils {
226 262 * @param runTaskKeyList 正在运行的任务 Key,用于校验任务节点是否是正在运行的节点
227 263 * @param hasSequenceFlow 已经经过的连线的 ID,用于判断线路是否重复
228 264 * @param userTaskList 需要撤回的用户任务列表
229   - * @return
  265 + * @return 子级任务节点列表
230 266 */
231   - public static List<UserTask> iteratorFindChildUserTasks(FlowElement source, List<String> runTaskKeyList, Set<String> hasSequenceFlow, List<UserTask> userTaskList) {
  267 + public static List<UserTask> iteratorFindChildUserTasks(FlowElement source, List<String> runTaskKeyList,
  268 + Set<String> hasSequenceFlow, List<UserTask> userTaskList) {
232 269 hasSequenceFlow = hasSequenceFlow == null ? new HashSet<>() : hasSequenceFlow;
233 270 userTaskList = userTaskList == null ? new ArrayList<>() : userTaskList;
234   -
235 271 // 如果该节点为开始节点,且存在上级子节点,则顺着上级子节点继续迭代
236 272 if (source instanceof StartEvent && source.getSubProcess() != null) {
237 273 userTaskList = iteratorFindChildUserTasks(source.getSubProcess(), runTaskKeyList, hasSequenceFlow, userTaskList);
... ... @@ -239,34 +275,35 @@ public class ModelUtils {
239 275  
240 276 // 根据类型,获取出口连线
241 277 List<SequenceFlow> sequenceFlows = getElementOutgoingFlows(source);
242   -
243   - if (sequenceFlows != null) {
244   - // 循环找到目标元素
245   - for (SequenceFlow sequenceFlow : sequenceFlows) {
246   - // 如果发现连线重复,说明循环了,跳过这个循环
247   - if (hasSequenceFlow.contains(sequenceFlow.getId())) {
248   - continue;
249   - }
250   - // 添加已经走过的连线
251   - hasSequenceFlow.add(sequenceFlow.getId());
252   - // 如果为用户任务类型,且任务节点的 Key 正在运行的任务中存在,添加
253   - if (sequenceFlow.getTargetFlowElement() instanceof UserTask && runTaskKeyList.contains((sequenceFlow.getTargetFlowElement()).getId())) {
254   - userTaskList.add((UserTask) sequenceFlow.getTargetFlowElement());
  278 + if (sequenceFlows == null) {
  279 + return userTaskList;
  280 + }
  281 + // 循环找到目标元素
  282 + for (SequenceFlow sequenceFlow : sequenceFlows) {
  283 + // 如果发现连线重复,说明循环了,跳过这个循环
  284 + if (hasSequenceFlow.contains(sequenceFlow.getId())) {
  285 + continue;
  286 + }
  287 + // 添加已经走过的连线
  288 + hasSequenceFlow.add(sequenceFlow.getId());
  289 + // 如果为用户任务类型,且任务节点的 Key 正在运行的任务中存在,添加
  290 + if (sequenceFlow.getTargetFlowElement() instanceof UserTask && runTaskKeyList.contains((sequenceFlow.getTargetFlowElement()).getId())) {
  291 + userTaskList.add((UserTask) sequenceFlow.getTargetFlowElement());
  292 + continue;
  293 + }
  294 + // 如果节点为子流程节点情况,则从节点中的第一个节点开始获取
  295 + if (sequenceFlow.getTargetFlowElement() instanceof SubProcess) {
  296 + List<UserTask> childUserTaskList = iteratorFindChildUserTasks((FlowElement) (((SubProcess) sequenceFlow.getTargetFlowElement()).getFlowElements().toArray()[0]), runTaskKeyList, hasSequenceFlow, null);
  297 + // 如果找到节点,则说明该线路找到节点,不继续向下找,反之继续
  298 + if (CollUtil.isNotEmpty(childUserTaskList)) {
  299 + userTaskList.addAll(childUserTaskList);
255 300 continue;
256 301 }
257   - // 如果节点为子流程节点情况,则从节点中的第一个节点开始获取
258   - if (sequenceFlow.getTargetFlowElement() instanceof SubProcess) {
259   - List<UserTask> childUserTaskList = iteratorFindChildUserTasks((FlowElement) (((SubProcess) sequenceFlow.getTargetFlowElement()).getFlowElements().toArray()[0]), runTaskKeyList, hasSequenceFlow, null);
260   - // 如果找到节点,则说明该线路找到节点,不继续向下找,反之继续
261   - if (childUserTaskList != null && childUserTaskList.size() > 0) {
262   - userTaskList.addAll(childUserTaskList);
263   - continue;
264   - }
265   - }
266   - // 继续迭代
267   - userTaskList = iteratorFindChildUserTasks(sequenceFlow.getTargetFlowElement(), runTaskKeyList, hasSequenceFlow, userTaskList);
268 302 }
  303 + // 继续迭代
  304 + userTaskList = iteratorFindChildUserTasks(sequenceFlow.getTargetFlowElement(), runTaskKeyList, hasSequenceFlow, userTaskList);
269 305 }
270 306 return userTaskList;
271 307 }
  308 +
272 309 }
... ...
yudao-framework/yudao-spring-boot-starter-flowable/src/main/java/cn/iocoder/yudao/framework/flowable/core/util/FlowableUtils.java
1 1 package cn.iocoder.yudao.framework.flowable.core.util;
2 2  
3   -import org.flowable.bpmn.converter.BpmnXMLConverter;
4   -import org.flowable.bpmn.model.BpmnModel;
5   -import org.flowable.bpmn.model.FlowElement;
6 3 import org.flowable.common.engine.impl.identity.Authentication;
7 4  
8   -import java.util.ArrayList;
9   -import java.util.Arrays;
10   -import java.util.List;
11   -
12 5 /**
13 6 * Flowable 相关的工具方法
14 7 *
... ... @@ -26,49 +19,6 @@ public class FlowableUtils {
26 19 Authentication.setAuthenticatedUserId(null);
27 20 }
28 21  
29   - // ========== BPMN 相关的工具方法 ==========
30   -
31   - /**
32   - * 获得 BPMN 流程中,指定的元素们
33   - *
34   - * @param model
35   - * @param clazz 指定元素。例如说,{@link org.flowable.bpmn.model.UserTask}、{@link org.flowable.bpmn.model.Gateway} 等等
36   - * @return 元素们
37   - */
38   - public static <T extends FlowElement> List<T> getBpmnModelElements(BpmnModel model, Class<T> clazz) {
39   - List<T> result = new ArrayList<>();
40   - model.getProcesses().forEach(process -> {
41   - process.getFlowElements().forEach(flowElement -> {
42   - if (flowElement.getClass().isAssignableFrom(clazz)) {
43   - result.add((T) flowElement);
44   - }
45   - });
46   - });
47   - return result;
48   - }
49   -
50   - /**
51   - * 比较 两个bpmnModel 是否相同
52   - * @param oldModel 老的bpmn model
53   - * @param newModel 新的bpmn model
54   - */
55   - public static boolean equals(BpmnModel oldModel, BpmnModel newModel) {
56   - // 由于 BpmnModel 未提供 equals 方法,所以只能转成字节数组,进行比较
57   - return Arrays.equals(getBpmnBytes(oldModel), getBpmnBytes(newModel));
58   - }
59   -
60   - /**
61   - * 把 bpmnModel 转换成 byte[]
62   - * @param model bpmnModel
63   - */
64   - public static byte[] getBpmnBytes(BpmnModel model) {
65   - if (model == null) {
66   - return new byte[0];
67   - }
68   - BpmnXMLConverter converter = new BpmnXMLConverter();
69   - return converter.convertToXML(model);
70   - }
71   -
72 22 // ========== Execution 相关的工具方法 ==========
73 23  
74 24 public static String formatCollectionVariable(String activityId) {
... ...
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmProcessDefinitionServiceImpl.java
... ... @@ -5,7 +5,7 @@ import cn.hutool.core.util.ObjectUtil;
5 5 import cn.hutool.core.util.StrUtil;
6 6 import cn.iocoder.yudao.framework.common.pojo.PageResult;
7 7 import cn.iocoder.yudao.framework.common.util.object.PageUtils;
8   -import cn.iocoder.yudao.framework.flowable.core.util.FlowableUtils;
  8 +import cn.iocoder.yudao.framework.flowable.core.util.BpmnModelUtils;
9 9 import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.process.BpmProcessDefinitionListReqVO;
10 10 import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.process.BpmProcessDefinitionPageItemRespVO;
11 11 import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.process.BpmProcessDefinitionPageReqVO;
... ... @@ -200,7 +200,7 @@ public class BpmProcessDefinitionServiceImpl implements BpmProcessDefinitionServ
200 200 BpmnModel newModel = buildBpmnModel(createReqDTO.getBpmnBytes());
201 201 BpmnModel oldModel = getBpmnModel(oldProcessDefinition.getId());
202 202 // 对比字节变化
203   - if (!FlowableUtils.equals(oldModel, newModel)) {
  203 + if (!BpmnModelUtils.equals(oldModel, newModel)) {
204 204 return false;
205 205 }
206 206 // 最终发现都一致,则返回 true
... ...
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmTaskAssignRuleServiceImpl.java
... ... @@ -7,7 +7,7 @@ import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
7 7 import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
8 8 import cn.iocoder.yudao.framework.common.util.object.ObjectUtils;
9 9 import cn.iocoder.yudao.framework.datapermission.core.annotation.DataPermission;
10   -import cn.iocoder.yudao.framework.flowable.core.util.FlowableUtils;
  10 +import cn.iocoder.yudao.framework.flowable.core.util.BpmnModelUtils;
11 11 import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.rule.BpmTaskAssignRuleCreateReqVO;
12 12 import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.rule.BpmTaskAssignRuleRespVO;
13 13 import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.rule.BpmTaskAssignRuleUpdateReqVO;
... ... @@ -114,7 +114,7 @@ public class BpmTaskAssignRuleServiceImpl implements BpmTaskAssignRuleService {
114 114 return Collections.emptyList();
115 115 }
116 116 // 获得用户任务,只有用户任务才可以设置分配规则
117   - List<UserTask> userTasks = FlowableUtils.getBpmnModelElements(model, UserTask.class);
  117 + List<UserTask> userTasks = BpmnModelUtils.getBpmnModelElements(model, UserTask.class);
118 118 if (CollUtil.isEmpty(userTasks)) {
119 119 return Collections.emptyList();
120 120 }
... ...
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmTaskServiceImpl.java
... ... @@ -7,7 +7,7 @@ import cn.iocoder.yudao.framework.common.pojo.PageResult;
7 7 import cn.iocoder.yudao.framework.common.util.date.DateUtils;
8 8 import cn.iocoder.yudao.framework.common.util.number.NumberUtils;
9 9 import cn.iocoder.yudao.framework.common.util.object.PageUtils;
10   -import cn.iocoder.yudao.framework.flowable.core.util.ModelUtils;
  10 +import cn.iocoder.yudao.framework.flowable.core.util.BpmnModelUtils;
11 11 import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.task.*;
12 12 import cn.iocoder.yudao.module.bpm.convert.task.BpmTaskConvert;
13 13 import cn.iocoder.yudao.module.bpm.dal.dataobject.task.BpmTaskExtDO;
... ... @@ -61,22 +61,23 @@ public class BpmTaskServiceImpl implements BpmTaskService {
61 61 private TaskService taskService;
62 62 @Resource
63 63 private HistoryService historyService;
  64 + @Resource
  65 + private RuntimeService runtimeService;
64 66  
65 67 @Resource
66 68 private BpmProcessInstanceService processInstanceService;
67 69 @Resource
68   - private AdminUserApi adminUserApi;
69   - @Resource
70   - private DeptApi deptApi;
71   - @Resource
72   - private BpmTaskExtMapper taskExtMapper;
  70 + private BpmModelService bpmModelService;
73 71 @Resource
74 72 private BpmMessageService messageService;
  73 +
75 74 @Resource
76   - private BpmModelService bpmModelService;
  75 + private AdminUserApi adminUserApi;
77 76 @Resource
78   - private RuntimeService runtimeService;
  77 + private DeptApi deptApi;
79 78  
  79 + @Resource
  80 + private BpmTaskExtMapper taskExtMapper;
80 81  
81 82 @Override
82 83 public PageResult<BpmTaskTodoPageItemRespVO> getTodoTaskPage(Long userId, BpmTaskTodoPageReqVO pageVO) {
... ... @@ -351,18 +352,18 @@ public class BpmTaskServiceImpl implements BpmTaskService {
351 352 throw exception(TASK_NOT_EXISTS);
352 353 }
353 354 BpmnModel bpmnModel = bpmModelService.getBpmnModelByDefinitionId(task.getProcessDefinitionId());
354   - FlowElement source = ModelUtils.getFlowElementById(bpmnModel, task.getTaskDefinitionKey());
  355 + FlowElement source = BpmnModelUtils.getFlowElementById(bpmnModel, task.getTaskDefinitionKey());
355 356 if (source == null) {
356 357 throw exception(TASK_NOT_EXISTS);
357 358 }
358 359  
359 360 // 2.1 查询该任务的前置任务节点的 key 集合
360   - List<UserTask> previousUserList = ModelUtils.getPreUserTaskList(source, null, null);
  361 + List<UserTask> previousUserList = BpmnModelUtils.getPreviousUserTaskList(source, null, null);
361 362 if (CollUtil.isEmpty(previousUserList)) {
362 363 return Collections.emptyList();
363 364 }
364 365 // 2.2 过滤:只有串行可到达的节点,才可以回退。类似非串行、子流程无法退回
365   - previousUserList.removeIf(userTask -> !ModelUtils.isSequentialReachable(source, userTask, null));
  366 + previousUserList.removeIf(userTask -> !BpmnModelUtils.isSequentialReachable(source, userTask, null));
366 367 return BpmTaskConvert.INSTANCE.convertList(previousUserList);
367 368 }
368 369  
... ... @@ -395,15 +396,15 @@ public class BpmTaskServiceImpl implements BpmTaskService {
395 396 // 1.1 获取流程模型信息
396 397 BpmnModel bpmnModel = bpmModelService.getBpmnModelByDefinitionId(processDefinitionId);
397 398 // 1.3 获取当前任务节点元素
398   - FlowElement source = ModelUtils.getFlowElementById(bpmnModel, sourceKey);
  399 + FlowElement source = BpmnModelUtils.getFlowElementById(bpmnModel, sourceKey);
399 400 // 1.3 获取跳转的节点元素
400   - FlowElement target = ModelUtils.getFlowElementById(bpmnModel, targetKey);
  401 + FlowElement target = BpmnModelUtils.getFlowElementById(bpmnModel, targetKey);
401 402 if (target == null) {
402 403 throw exception(TASK_TARGET_NODE_NOT_EXISTS);
403 404 }
404 405  
405 406 // 2.2 只有串行可到达的节点,才可以回退。类似非串行、子流程无法退回
406   - if (!ModelUtils.isSequentialReachable(source, target, null)) {
  407 + if (!BpmnModelUtils.isSequentialReachable(source, target, null)) {
407 408 throw exception(TASK_RETURN_FAIL_SOURCE_TARGET_ERROR);
408 409 }
409 410 return target;
... ... @@ -423,7 +424,7 @@ public class BpmTaskServiceImpl implements BpmTaskService {
423 424 List<String> runTaskKeyList = convertList(taskList, Task::getTaskDefinitionKey);
424 425 // 1.2 通过 targetElement 的出口连线,计算在 runTaskKeyList 有哪些 key 需要被撤回
425 426 // 为什么不直接使用 runTaskKeyList 呢?因为可能存在多个审批分支,例如说:A -> B -> C 和 D -> F,而只要 C 撤回到 A,需要排除掉 F
426   - List<UserTask> returnUserTaskList = ModelUtils.iteratorFindChildUserTasks(targetElement, runTaskKeyList, null, null);
  427 + List<UserTask> returnUserTaskList = BpmnModelUtils.iteratorFindChildUserTasks(targetElement, runTaskKeyList, null, null);
427 428 List<String> returnTaskKeyList = convertList(returnUserTaskList, UserTask::getId);
428 429  
429 430 // 2. 给当前要被回退的 task 数组,设置回退意见
... ...