Commit 1c78cdc26e714e636354f3ec2403f7c12717ee07

Authored by YunaiV
1 parent 23b011b6

【代码优化】工作流:进一步完善 SimpleModelUtils、BpmnModelUtils 的注释,提升可读性!

yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/listener/BpmTaskEventListener.java
@@ -87,6 +87,7 @@ public class BpmTaskEventListener extends AbstractFlowableEngineEventListener { @@ -87,6 +87,7 @@ public class BpmTaskEventListener extends AbstractFlowableEngineEventListener {
87 } 87 }
88 88
89 @Override 89 @Override
  90 + @SuppressWarnings("PatternVariableCanBeUsed")
90 protected void timerFired(FlowableEngineEntityEvent event) { 91 protected void timerFired(FlowableEngineEntityEvent event) {
91 // 1.1 只处理 BoundaryEvent 边界计时时间 92 // 1.1 只处理 BoundaryEvent 边界计时时间
92 String processDefinitionId = event.getProcessDefinitionId(); 93 String processDefinitionId = event.getProcessDefinitionId();
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/util/BpmnModelUtils.java
@@ -9,6 +9,9 @@ import cn.iocoder.yudao.framework.common.util.number.NumberUtils; @@ -9,6 +9,9 @@ import cn.iocoder.yudao.framework.common.util.number.NumberUtils;
9 import cn.iocoder.yudao.framework.common.util.string.StrUtils; 9 import cn.iocoder.yudao.framework.common.util.string.StrUtils;
10 import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.model.simple.BpmSimpleModelNodeVO; 10 import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.model.simple.BpmSimpleModelNodeVO;
11 import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.task.BpmTaskRespVO; 11 import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.task.BpmTaskRespVO;
  12 +import cn.iocoder.yudao.module.bpm.enums.definition.BpmUserTaskApproveTypeEnum;
  13 +import cn.iocoder.yudao.module.bpm.enums.definition.BpmUserTaskAssignEmptyHandlerTypeEnum;
  14 +import cn.iocoder.yudao.module.bpm.enums.definition.BpmUserTaskAssignStartUserHandlerTypeEnum;
12 import cn.iocoder.yudao.module.bpm.enums.definition.BpmUserTaskRejectHandlerType; 15 import cn.iocoder.yudao.module.bpm.enums.definition.BpmUserTaskRejectHandlerType;
13 import cn.iocoder.yudao.module.bpm.framework.flowable.core.enums.BpmnModelConstants; 16 import cn.iocoder.yudao.module.bpm.framework.flowable.core.enums.BpmnModelConstants;
14 import com.google.common.collect.Maps; 17 import com.google.common.collect.Maps;
@@ -24,10 +27,18 @@ import static org.flowable.bpmn.constants.BpmnXMLConstants.FLOWABLE_EXTENSIONS_N @@ -24,10 +27,18 @@ import static org.flowable.bpmn.constants.BpmnXMLConstants.FLOWABLE_EXTENSIONS_N
24 import static org.flowable.bpmn.constants.BpmnXMLConstants.FLOWABLE_EXTENSIONS_PREFIX; 27 import static org.flowable.bpmn.constants.BpmnXMLConstants.FLOWABLE_EXTENSIONS_PREFIX;
25 28
26 /** 29 /**
27 - * 流程模型转操作工具类 30 + * BPMN Model 操作工具类。目前分成三部分:
  31 + *
  32 + * 1. BPMN 修改 + 解析元素相关的方法
  33 + * 2. BPM 简单查找相关的方法
  34 + * 3. BPM 复杂遍历相关的方法
  35 + *
  36 + * @author 芋道源码
28 */ 37 */
29 public class BpmnModelUtils { 38 public class BpmnModelUtils {
30 39
  40 + // ========== BPMN 修改 + 解析元素相关的方法 ==========
  41 +
31 public static void addExtensionElement(FlowElement element, String name, String value) { 42 public static void addExtensionElement(FlowElement element, String name, String value) {
32 if (value == null) { 43 if (value == null) {
33 return; 44 return;
@@ -64,6 +75,21 @@ public class BpmnModelUtils { @@ -64,6 +75,21 @@ public class BpmnModelUtils {
64 } 75 }
65 76
66 /** 77 /**
  78 + * 解析扩展元素
  79 + *
  80 + * @param flowElement 节点
  81 + * @param elementName 元素名称
  82 + * @return 扩展元素
  83 + */
  84 + public static String parseExtensionElement(FlowElement flowElement, String elementName) {
  85 + if (flowElement == null) {
  86 + return null;
  87 + }
  88 + ExtensionElement element = CollUtil.getFirst(flowElement.getExtensionElements().get(elementName));
  89 + return element != null ? element.getElementText() : null;
  90 + }
  91 +
  92 + /**
67 * 给节点添加候选人元素 93 * 给节点添加候选人元素
68 * 94 *
69 * @param candidateStrategy 候选人策略 95 * @param candidateStrategy 候选人策略
@@ -79,7 +105,7 @@ public class BpmnModelUtils { @@ -79,7 +105,7 @@ public class BpmnModelUtils {
79 /** 105 /**
80 * 解析候选人策略 106 * 解析候选人策略
81 * 107 *
82 - * @param userTask 节点 108 + * @param userTask 任务节点
83 * @return 候选人策略 109 * @return 候选人策略
84 */ 110 */
85 public static Integer parseCandidateStrategy(FlowElement userTask) { 111 public static Integer parseCandidateStrategy(FlowElement userTask) {
@@ -93,6 +119,12 @@ public class BpmnModelUtils { @@ -93,6 +119,12 @@ public class BpmnModelUtils {
93 return candidateStrategy; 119 return candidateStrategy;
94 } 120 }
95 121
  122 + /**
  123 + * 解析候选人参数
  124 + *
  125 + * @param userTask 任务节点
  126 + * @return 候选人参数
  127 + */
96 public static String parseCandidateParam(FlowElement userTask) { 128 public static String parseCandidateParam(FlowElement userTask) {
97 String candidateParam = userTask.getAttributeValue( 129 String candidateParam = userTask.getAttributeValue(
98 BpmnModelConstants.NAMESPACE, BpmnModelConstants.USER_TASK_CANDIDATE_PARAM); 130 BpmnModelConstants.NAMESPACE, BpmnModelConstants.USER_TASK_CANDIDATE_PARAM);
@@ -103,10 +135,23 @@ public class BpmnModelUtils { @@ -103,10 +135,23 @@ public class BpmnModelUtils {
103 return candidateParam; 135 return candidateParam;
104 } 136 }
105 137
  138 + /**
  139 + * 解析审批类型
  140 + *
  141 + * @see BpmUserTaskApproveTypeEnum
  142 + * @param userTask 任务节点
  143 + * @return 审批类型
  144 + */
106 public static Integer parseApproveType(FlowElement userTask) { 145 public static Integer parseApproveType(FlowElement userTask) {
107 return NumberUtils.parseInt(parseExtensionElement(userTask, BpmnModelConstants.USER_TASK_APPROVE_TYPE)); 146 return NumberUtils.parseInt(parseExtensionElement(userTask, BpmnModelConstants.USER_TASK_APPROVE_TYPE));
108 } 147 }
109 148
  149 + /**
  150 + * 添加任务拒绝处理元素
  151 + *
  152 + * @param rejectHandler 任务拒绝处理
  153 + * @param userTask 任务节点
  154 + */
110 public static void addTaskRejectElements(BpmSimpleModelNodeVO.RejectHandler rejectHandler, UserTask userTask) { 155 public static void addTaskRejectElements(BpmSimpleModelNodeVO.RejectHandler rejectHandler, UserTask userTask) {
111 if (rejectHandler == null) { 156 if (rejectHandler == null) {
112 return; 157 return;
@@ -115,15 +160,34 @@ public class BpmnModelUtils { @@ -115,15 +160,34 @@ public class BpmnModelUtils {
115 addExtensionElement(userTask, USER_TASK_REJECT_RETURN_TASK_ID, rejectHandler.getReturnNodeId()); 160 addExtensionElement(userTask, USER_TASK_REJECT_RETURN_TASK_ID, rejectHandler.getReturnNodeId());
116 } 161 }
117 162
  163 + /**
  164 + * 解析任务拒绝处理类型
  165 + *
  166 + * @param userTask 任务节点
  167 + * @return 任务拒绝处理类型
  168 + */
118 public static BpmUserTaskRejectHandlerType parseRejectHandlerType(FlowElement userTask) { 169 public static BpmUserTaskRejectHandlerType parseRejectHandlerType(FlowElement userTask) {
119 Integer rejectHandlerType = NumberUtils.parseInt(parseExtensionElement(userTask, USER_TASK_REJECT_HANDLER_TYPE)); 170 Integer rejectHandlerType = NumberUtils.parseInt(parseExtensionElement(userTask, USER_TASK_REJECT_HANDLER_TYPE));
120 return BpmUserTaskRejectHandlerType.typeOf(rejectHandlerType); 171 return BpmUserTaskRejectHandlerType.typeOf(rejectHandlerType);
121 } 172 }
122 173
  174 + /**
  175 + * 解析任务拒绝返回任务节点 ID
  176 + *
  177 + * @param flowElement 任务节点
  178 + * @return 任务拒绝返回任务节点 ID
  179 + */
123 public static String parseReturnTaskId(FlowElement flowElement) { 180 public static String parseReturnTaskId(FlowElement flowElement) {
124 return parseExtensionElement(flowElement, USER_TASK_REJECT_RETURN_TASK_ID); 181 return parseExtensionElement(flowElement, USER_TASK_REJECT_RETURN_TASK_ID);
125 } 182 }
126 183
  184 + /**
  185 + * 给节点添加用户任务的审批人与发起人相同时,处理类型枚举
  186 + *
  187 + * @see BpmUserTaskAssignStartUserHandlerTypeEnum
  188 + * @param assignStartUserHandlerType 发起人处理类型
  189 + * @param userTask 任务节点
  190 + */
127 public static void addAssignStartUserHandlerType(Integer assignStartUserHandlerType, UserTask userTask) { 191 public static void addAssignStartUserHandlerType(Integer assignStartUserHandlerType, UserTask userTask) {
128 if (assignStartUserHandlerType == null) { 192 if (assignStartUserHandlerType == null) {
129 return; 193 return;
@@ -131,6 +195,13 @@ public class BpmnModelUtils { @@ -131,6 +195,13 @@ public class BpmnModelUtils {
131 addExtensionElement(userTask, USER_TASK_ASSIGN_START_USER_HANDLER_TYPE, assignStartUserHandlerType.toString()); 195 addExtensionElement(userTask, USER_TASK_ASSIGN_START_USER_HANDLER_TYPE, assignStartUserHandlerType.toString());
132 } 196 }
133 197
  198 + /**
  199 + * 给节点添加用户任务的审批人为空时,处理类型枚举
  200 + *
  201 + * @see BpmUserTaskAssignEmptyHandlerTypeEnum
  202 + * @param emptyHandler 空处理
  203 + * @param userTask 任务节点
  204 + */
134 public static void addAssignEmptyHandlerType(BpmSimpleModelNodeVO.AssignEmptyHandler emptyHandler, UserTask userTask) { 205 public static void addAssignEmptyHandlerType(BpmSimpleModelNodeVO.AssignEmptyHandler emptyHandler, UserTask userTask) {
135 if (emptyHandler == null) { 206 if (emptyHandler == null) {
136 return; 207 return;
@@ -139,26 +210,36 @@ public class BpmnModelUtils { @@ -139,26 +210,36 @@ public class BpmnModelUtils {
139 addExtensionElement(userTask, USER_TASK_ASSIGN_USER_IDS, StrUtil.join(",", emptyHandler.getUserIds())); 210 addExtensionElement(userTask, USER_TASK_ASSIGN_USER_IDS, StrUtil.join(",", emptyHandler.getUserIds()));
140 } 211 }
141 212
  213 + /**
  214 + * 解析用户任务的审批人与发起人相同时,处理类型枚举
  215 + *
  216 + * @param userTask 任务节点
  217 + * @return 处理类型枚举
  218 + */
142 public static Integer parseAssignStartUserHandlerType(FlowElement userTask) { 219 public static Integer parseAssignStartUserHandlerType(FlowElement userTask) {
143 return NumberUtils.parseInt(parseExtensionElement(userTask, USER_TASK_ASSIGN_START_USER_HANDLER_TYPE)); 220 return NumberUtils.parseInt(parseExtensionElement(userTask, USER_TASK_ASSIGN_START_USER_HANDLER_TYPE));
144 } 221 }
145 222
  223 + /**
  224 + * 解析用户任务的审批人为空时,处理类型枚举
  225 + *
  226 + * @param userTask 任务节点
  227 + * @return 处理类型枚举
  228 + */
146 public static Integer parseAssignEmptyHandlerType(FlowElement userTask) { 229 public static Integer parseAssignEmptyHandlerType(FlowElement userTask) {
147 return NumberUtils.parseInt(parseExtensionElement(userTask, USER_TASK_ASSIGN_EMPTY_HANDLER_TYPE)); 230 return NumberUtils.parseInt(parseExtensionElement(userTask, USER_TASK_ASSIGN_EMPTY_HANDLER_TYPE));
148 } 231 }
149 232
  233 + /**
  234 + * 解析用户任务的审批人为空时,处理用户 ID 数组
  235 + *
  236 + * @param userTask 任务节点
  237 + * @return 处理用户 ID 数组
  238 + */
150 public static List<Long> parseAssignEmptyHandlerUserIds(FlowElement userTask) { 239 public static List<Long> parseAssignEmptyHandlerUserIds(FlowElement userTask) {
151 return StrUtils.splitToLong(parseExtensionElement(userTask, USER_TASK_ASSIGN_USER_IDS), ","); 240 return StrUtils.splitToLong(parseExtensionElement(userTask, USER_TASK_ASSIGN_USER_IDS), ",");
152 } 241 }
153 242
154 - public static String parseExtensionElement(FlowElement flowElement, String elementName) {  
155 - if (flowElement == null) {  
156 - return null;  
157 - }  
158 - ExtensionElement element = CollUtil.getFirst(flowElement.getExtensionElements().get(elementName));  
159 - return element != null ? element.getElementText() : null;  
160 - }  
161 -  
162 /** 243 /**
163 * 给节点添加表单字段权限元素 244 * 给节点添加表单字段权限元素
164 * 245 *
@@ -217,6 +298,13 @@ public class BpmnModelUtils { @@ -217,6 +298,13 @@ public class BpmnModelUtils {
217 } 298 }
218 } 299 }
219 300
  301 + /**
  302 + * 解析操作按钮设置
  303 + *
  304 + * @param bpmnModel bpmnModel 对象
  305 + * @param flowElementId 元素 ID
  306 + * @return 操作按钮设置
  307 + */
220 public static Map<Integer, BpmTaskRespVO.OperationButtonSetting> parseButtonsSetting(BpmnModel bpmnModel, String flowElementId) { 308 public static Map<Integer, BpmTaskRespVO.OperationButtonSetting> parseButtonsSetting(BpmnModel bpmnModel, String flowElementId) {
221 FlowElement flowElement = getFlowElementById(bpmnModel, flowElementId); 309 FlowElement flowElement = getFlowElementById(bpmnModel, flowElementId);
222 if (flowElement == null) { 310 if (flowElement == null) {
@@ -226,7 +314,7 @@ public class BpmnModelUtils { @@ -226,7 +314,7 @@ public class BpmnModelUtils {
226 if (CollUtil.isEmpty(extensionElements)) { 314 if (CollUtil.isEmpty(extensionElements)) {
227 return null; 315 return null;
228 } 316 }
229 - Map<Integer, BpmTaskRespVO.OperationButtonSetting> buttonSettings = MapUtil.newHashMap(16); 317 + Map<Integer, BpmTaskRespVO.OperationButtonSetting> buttonSettings = Maps.newHashMapWithExpectedSize(extensionElements.size());
230 extensionElements.forEach(element -> { 318 extensionElements.forEach(element -> {
231 String id = element.getAttributeValue(FLOWABLE_EXTENSIONS_NAMESPACE, BUTTON_SETTING_ELEMENT_ID_ATTRIBUTE); 319 String id = element.getAttributeValue(FLOWABLE_EXTENSIONS_NAMESPACE, BUTTON_SETTING_ELEMENT_ID_ATTRIBUTE);
232 String displayName = element.getAttributeValue(FLOWABLE_EXTENSIONS_NAMESPACE, BUTTON_SETTING_ELEMENT_DISPLAY_NAME_ATTRIBUTE); 320 String displayName = element.getAttributeValue(FLOWABLE_EXTENSIONS_NAMESPACE, BUTTON_SETTING_ELEMENT_DISPLAY_NAME_ATTRIBUTE);
@@ -240,6 +328,23 @@ public class BpmnModelUtils { @@ -240,6 +328,23 @@ public class BpmnModelUtils {
240 } 328 }
241 329
242 /** 330 /**
  331 + * 解析边界事件扩展元素
  332 + *
  333 + * @param boundaryEvent 边界事件
  334 + * @param customElement 元素
  335 + * @return 扩展元素
  336 + */
  337 + public static String parseBoundaryEventExtensionElement(BoundaryEvent boundaryEvent, String customElement) {
  338 + if (boundaryEvent == null) {
  339 + return null;
  340 + }
  341 + ExtensionElement extensionElement = CollUtil.getFirst(boundaryEvent.getExtensionElements().get(customElement));
  342 + return Optional.ofNullable(extensionElement).map(ExtensionElement::getElementText).orElse(null);
  343 + }
  344 +
  345 + // ========== BPM 简单查找相关的方法 ==========
  346 +
  347 + /**
243 * 根据节点,获取入口连线 348 * 根据节点,获取入口连线
244 * 349 *
245 * @param source 起始节点 350 * @param source 起始节点
@@ -284,15 +389,14 @@ public class BpmnModelUtils { @@ -284,15 +389,14 @@ public class BpmnModelUtils {
284 * @param clazz 指定元素。例如说,{@link UserTask}、{@link Gateway} 等等 389 * @param clazz 指定元素。例如说,{@link UserTask}、{@link Gateway} 等等
285 * @return 元素们 390 * @return 元素们
286 */ 391 */
  392 + @SuppressWarnings("unchecked")
287 public static <T extends FlowElement> List<T> getBpmnModelElements(BpmnModel model, Class<T> clazz) { 393 public static <T extends FlowElement> List<T> getBpmnModelElements(BpmnModel model, Class<T> clazz) {
288 List<T> result = new ArrayList<>(); 394 List<T> result = new ArrayList<>();
289 - model.getProcesses().forEach(process -> {  
290 - process.getFlowElements().forEach(flowElement -> {  
291 - if (flowElement.getClass().isAssignableFrom(clazz)) {  
292 - result.add((T) flowElement);  
293 - }  
294 - });  
295 - }); 395 + model.getProcesses().forEach(process -> process.getFlowElements().forEach(flowElement -> {
  396 + if (flowElement.getClass().isAssignableFrom(clazz)) {
  397 + result.add((T) flowElement);
  398 + }
  399 + }));
296 return result; 400 return result;
297 } 401 }
298 402
@@ -337,7 +441,7 @@ public class BpmnModelUtils { @@ -337,7 +441,7 @@ public class BpmnModelUtils {
337 return StrUtil.utf8Str(bpmnBytes); 441 return StrUtil.utf8Str(bpmnBytes);
338 } 442 }
339 443
340 - // ========== 遍历相关的方法 ========== 444 + // ========== BPMN 复杂遍历相关的方法 ==========
341 445
342 /** 446 /**
343 * 找到 source 节点之前的所有用户任务节点 447 * 找到 source 节点之前的所有用户任务节点
@@ -441,6 +545,7 @@ public class BpmnModelUtils { @@ -441,6 +545,7 @@ public class BpmnModelUtils {
441 * @param visitedElements 已经经过的连线的 ID,用于判断线路是否重复 545 * @param visitedElements 已经经过的连线的 ID,用于判断线路是否重复
442 * @return 结果 546 * @return 结果
443 */ 547 */
  548 + @SuppressWarnings("BooleanMethodIsAlwaysInverted")
444 public static boolean isSequentialReachable(FlowElement source, FlowElement target, Set<String> visitedElements) { 549 public static boolean isSequentialReachable(FlowElement source, FlowElement target, Set<String> visitedElements) {
445 visitedElements = visitedElements == null ? new HashSet<>() : visitedElements; 550 visitedElements = visitedElements == null ? new HashSet<>() : visitedElements;
446 // 不能是开始事件和子流程 551 // 不能是开始事件和子流程
@@ -551,11 +656,4 @@ public class BpmnModelUtils { @@ -551,11 +656,4 @@ public class BpmnModelUtils {
551 return userTaskList; 656 return userTaskList;
552 } 657 }
553 658
554 - public static String parseBoundaryEventExtensionElement(BoundaryEvent boundaryEvent, String customElement) {  
555 - if (boundaryEvent == null) {  
556 - return null;  
557 - }  
558 - ExtensionElement extensionElement = CollUtil.getFirst(boundaryEvent.getExtensionElements().get(customElement));  
559 - return Optional.ofNullable(extensionElement).map(ExtensionElement::getElementText).orElse(null);  
560 - }  
561 } 659 }
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/util/SimpleModelUtils.java
@@ -25,6 +25,9 @@ import static java.util.Arrays.asList; @@ -25,6 +25,9 @@ import static java.util.Arrays.asList;
25 /** 25 /**
26 * 仿钉钉/飞书的模型相关的工具方法 26 * 仿钉钉/飞书的模型相关的工具方法
27 * 27 *
  28 + * 1. 核心的逻辑实现,可见 {@link #buildBpmnModel(String, String, BpmSimpleModelNodeVO)} 方法
  29 + * 2. 所有的 BpmSimpleModelNodeVO 转换成 BPMN FlowNode 元素,可见 {@link NodeConvert} 实现类
  30 + *
28 * @author jason 31 * @author jason
29 */ 32 */
30 public class SimpleModelUtils { 33 public class SimpleModelUtils {
@@ -41,6 +44,11 @@ public class SimpleModelUtils { @@ -41,6 +44,11 @@ public class SimpleModelUtils {
41 /** 44 /**
42 * 仿钉钉流程设计模型数据结构(json)转换成 Bpmn Model 45 * 仿钉钉流程设计模型数据结构(json)转换成 Bpmn Model
43 * 46 *
  47 + * 整体逻辑如下:
  48 + * 1. 创建:BpmnModel、Process 对象
  49 + * 2. 转换:将 BpmSimpleModelNodeVO 转换成 BPMN FlowNode 元素
  50 + * 3. 连接:构建并添加节点之间的连线 Sequence Flow
  51 + *
44 * @param processId 流程标识 52 * @param processId 流程标识
45 * @param processName 流程名称 53 * @param processName 流程名称
46 * @param simpleModelNode 仿钉钉流程设计模型数据结构 54 * @param simpleModelNode 仿钉钉流程设计模型数据结构