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 87 }
88 88  
89 89 @Override
  90 + @SuppressWarnings("PatternVariableCanBeUsed")
90 91 protected void timerFired(FlowableEngineEntityEvent event) {
91 92 // 1.1 只处理 BoundaryEvent 边界计时时间
92 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 9 import cn.iocoder.yudao.framework.common.util.string.StrUtils;
10 10 import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.model.simple.BpmSimpleModelNodeVO;
11 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 15 import cn.iocoder.yudao.module.bpm.enums.definition.BpmUserTaskRejectHandlerType;
13 16 import cn.iocoder.yudao.module.bpm.framework.flowable.core.enums.BpmnModelConstants;
14 17 import com.google.common.collect.Maps;
... ... @@ -24,10 +27,18 @@ import static org.flowable.bpmn.constants.BpmnXMLConstants.FLOWABLE_EXTENSIONS_N
24 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 38 public class BpmnModelUtils {
30 39  
  40 + // ========== BPMN 修改 + 解析元素相关的方法 ==========
  41 +
31 42 public static void addExtensionElement(FlowElement element, String name, String value) {
32 43 if (value == null) {
33 44 return;
... ... @@ -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 95 * @param candidateStrategy 候选人策略
... ... @@ -79,7 +105,7 @@ public class BpmnModelUtils {
79 105 /**
80 106 * 解析候选人策略
81 107 *
82   - * @param userTask 节点
  108 + * @param userTask 任务节点
83 109 * @return 候选人策略
84 110 */
85 111 public static Integer parseCandidateStrategy(FlowElement userTask) {
... ... @@ -93,6 +119,12 @@ public class BpmnModelUtils {
93 119 return candidateStrategy;
94 120 }
95 121  
  122 + /**
  123 + * 解析候选人参数
  124 + *
  125 + * @param userTask 任务节点
  126 + * @return 候选人参数
  127 + */
96 128 public static String parseCandidateParam(FlowElement userTask) {
97 129 String candidateParam = userTask.getAttributeValue(
98 130 BpmnModelConstants.NAMESPACE, BpmnModelConstants.USER_TASK_CANDIDATE_PARAM);
... ... @@ -103,10 +135,23 @@ public class BpmnModelUtils {
103 135 return candidateParam;
104 136 }
105 137  
  138 + /**
  139 + * 解析审批类型
  140 + *
  141 + * @see BpmUserTaskApproveTypeEnum
  142 + * @param userTask 任务节点
  143 + * @return 审批类型
  144 + */
106 145 public static Integer parseApproveType(FlowElement userTask) {
107 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 155 public static void addTaskRejectElements(BpmSimpleModelNodeVO.RejectHandler rejectHandler, UserTask userTask) {
111 156 if (rejectHandler == null) {
112 157 return;
... ... @@ -115,15 +160,34 @@ public class BpmnModelUtils {
115 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 169 public static BpmUserTaskRejectHandlerType parseRejectHandlerType(FlowElement userTask) {
119 170 Integer rejectHandlerType = NumberUtils.parseInt(parseExtensionElement(userTask, USER_TASK_REJECT_HANDLER_TYPE));
120 171 return BpmUserTaskRejectHandlerType.typeOf(rejectHandlerType);
121 172 }
122 173  
  174 + /**
  175 + * 解析任务拒绝返回任务节点 ID
  176 + *
  177 + * @param flowElement 任务节点
  178 + * @return 任务拒绝返回任务节点 ID
  179 + */
123 180 public static String parseReturnTaskId(FlowElement flowElement) {
124 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 191 public static void addAssignStartUserHandlerType(Integer assignStartUserHandlerType, UserTask userTask) {
128 192 if (assignStartUserHandlerType == null) {
129 193 return;
... ... @@ -131,6 +195,13 @@ public class BpmnModelUtils {
131 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 205 public static void addAssignEmptyHandlerType(BpmSimpleModelNodeVO.AssignEmptyHandler emptyHandler, UserTask userTask) {
135 206 if (emptyHandler == null) {
136 207 return;
... ... @@ -139,26 +210,36 @@ public class BpmnModelUtils {
139 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 219 public static Integer parseAssignStartUserHandlerType(FlowElement userTask) {
143 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 229 public static Integer parseAssignEmptyHandlerType(FlowElement userTask) {
147 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 239 public static List<Long> parseAssignEmptyHandlerUserIds(FlowElement userTask) {
151 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 298 }
218 299 }
219 300  
  301 + /**
  302 + * 解析操作按钮设置
  303 + *
  304 + * @param bpmnModel bpmnModel 对象
  305 + * @param flowElementId 元素 ID
  306 + * @return 操作按钮设置
  307 + */
220 308 public static Map<Integer, BpmTaskRespVO.OperationButtonSetting> parseButtonsSetting(BpmnModel bpmnModel, String flowElementId) {
221 309 FlowElement flowElement = getFlowElementById(bpmnModel, flowElementId);
222 310 if (flowElement == null) {
... ... @@ -226,7 +314,7 @@ public class BpmnModelUtils {
226 314 if (CollUtil.isEmpty(extensionElements)) {
227 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 318 extensionElements.forEach(element -> {
231 319 String id = element.getAttributeValue(FLOWABLE_EXTENSIONS_NAMESPACE, BUTTON_SETTING_ELEMENT_ID_ATTRIBUTE);
232 320 String displayName = element.getAttributeValue(FLOWABLE_EXTENSIONS_NAMESPACE, BUTTON_SETTING_ELEMENT_DISPLAY_NAME_ATTRIBUTE);
... ... @@ -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 350 * @param source 起始节点
... ... @@ -284,15 +389,14 @@ public class BpmnModelUtils {
284 389 * @param clazz 指定元素。例如说,{@link UserTask}、{@link Gateway} 等等
285 390 * @return 元素们
286 391 */
  392 + @SuppressWarnings("unchecked")
287 393 public static <T extends FlowElement> List<T> getBpmnModelElements(BpmnModel model, Class<T> clazz) {
288 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 400 return result;
297 401 }
298 402  
... ... @@ -337,7 +441,7 @@ public class BpmnModelUtils {
337 441 return StrUtil.utf8Str(bpmnBytes);
338 442 }
339 443  
340   - // ========== 遍历相关的方法 ==========
  444 + // ========== BPMN 复杂遍历相关的方法 ==========
341 445  
342 446 /**
343 447 * 找到 source 节点之前的所有用户任务节点
... ... @@ -441,6 +545,7 @@ public class BpmnModelUtils {
441 545 * @param visitedElements 已经经过的连线的 ID,用于判断线路是否重复
442 546 * @return 结果
443 547 */
  548 + @SuppressWarnings("BooleanMethodIsAlwaysInverted")
444 549 public static boolean isSequentialReachable(FlowElement source, FlowElement target, Set<String> visitedElements) {
445 550 visitedElements = visitedElements == null ? new HashSet<>() : visitedElements;
446 551 // 不能是开始事件和子流程
... ... @@ -551,11 +656,4 @@ public class BpmnModelUtils {
551 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 25 /**
26 26 * 仿钉钉/飞书的模型相关的工具方法
27 27 *
  28 + * 1. 核心的逻辑实现,可见 {@link #buildBpmnModel(String, String, BpmSimpleModelNodeVO)} 方法
  29 + * 2. 所有的 BpmSimpleModelNodeVO 转换成 BPMN FlowNode 元素,可见 {@link NodeConvert} 实现类
  30 + *
28 31 * @author jason
29 32 */
30 33 public class SimpleModelUtils {
... ... @@ -41,6 +44,11 @@ public class SimpleModelUtils {
41 44 /**
42 45 * 仿钉钉流程设计模型数据结构(json)转换成 Bpmn Model
43 46 *
  47 + * 整体逻辑如下:
  48 + * 1. 创建:BpmnModel、Process 对象
  49 + * 2. 转换:将 BpmSimpleModelNodeVO 转换成 BPMN FlowNode 元素
  50 + * 3. 连接:构建并添加节点之间的连线 Sequence Flow
  51 + *
44 52 * @param processId 流程标识
45 53 * @param processName 流程名称
46 54 * @param simpleModelNode 仿钉钉流程设计模型数据结构
... ...