Commit e4fbc11dc453e86097270a2131bd1314186f3cb0

Authored by jason
1 parent cb5cfd31

仿钉钉流程设计- 前端重构调整, 新增多人审批方式

yudao-module-bpm/yudao-module-bpm-api/src/main/java/cn/iocoder/yudao/module/bpm/enums/definition/BpmApproveMethodEnum.java 0 → 100644
  1 +package cn.iocoder.yudao.module.bpm.enums.definition;
  2 +
  3 +import cn.hutool.core.util.ArrayUtil;
  4 +import lombok.AllArgsConstructor;
  5 +import lombok.Getter;
  6 +
  7 +/**
  8 + * BPM 审批方式的枚举
  9 + *
  10 + * @author jason
  11 + */
  12 +@Getter
  13 +@AllArgsConstructor
  14 +public enum BpmApproveMethodEnum {
  15 +
  16 + SINGLE_PERSON_APPROVE(1, "单人审批"),
  17 + ALL_APPROVE(2, "多人会签(需所有审批人同意)"),
  18 + ANY_OF_APPROVE(3, "多人或签(一名审批人同意即可)"),
  19 + SEQUENTIAL_APPROVE(4, "依次审批");
  20 +
  21 + /**
  22 + * 审批方式
  23 + */
  24 + private final Integer method;
  25 + /**
  26 + * 名字
  27 + */
  28 + private final String name;
  29 +
  30 + public static BpmApproveMethodEnum valueOf(Integer method) {
  31 + return ArrayUtil.firstMatch(item -> item.getMethod().equals(method), values());
  32 + }
  33 +}
... ...
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/simple/BpmSimpleModelNodeVO.java
... ... @@ -28,6 +28,9 @@ public class BpmSimpleModelNodeVO {
28 28 @Schema(description = "模型节点名称", example = "领导审批")
29 29 private String name;
30 30  
  31 + @Schema(description = "节点展示内容", example = "指定成员: 芋道源码")
  32 + private String showText;
  33 +
31 34 @Schema(description = "孩子节点")
32 35 private BpmSimpleModelNodeVO childNode;
33 36  
... ...
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/enums/SimpleModelConstants.java
... ... @@ -7,4 +7,8 @@ package cn.iocoder.yudao.module.bpm.framework.flowable.core.enums;
7 7 */
8 8 public interface SimpleModelConstants {
9 9  
  10 + /**
  11 + * 审批方式属性
  12 + */
  13 + String APPROVE_METHOD_ATTRIBUTE = "approveMethod";
10 14 }
... ...
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/util/SimpleModelUtils.java
... ... @@ -7,8 +7,10 @@ import cn.hutool.core.map.MapUtil;
7 7 import cn.hutool.core.util.ArrayUtil;
8 8 import cn.hutool.core.util.StrUtil;
9 9 import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.simple.BpmSimpleModelNodeVO;
  10 +import cn.iocoder.yudao.module.bpm.enums.definition.BpmApproveMethodEnum;
10 11 import cn.iocoder.yudao.module.bpm.enums.definition.BpmSimpleModelNodeType;
11 12 import cn.iocoder.yudao.module.bpm.framework.flowable.core.enums.BpmnModelConstants;
  13 +import cn.iocoder.yudao.module.bpm.framework.flowable.core.enums.SimpleModelConstants;
12 14 import org.flowable.bpmn.BpmnAutoLayout;
13 15 import org.flowable.bpmn.model.Process;
14 16 import org.flowable.bpmn.model.*;
... ... @@ -16,6 +18,7 @@ import org.flowable.bpmn.model.*;
16 18 import java.util.List;
17 19 import java.util.Map;
18 20  
  21 +import static cn.iocoder.yudao.module.bpm.enums.definition.BpmSimpleModelNodeType.END_EVENT;
19 22 import static cn.iocoder.yudao.module.bpm.framework.flowable.core.enums.BpmnModelConstants.FORM_FIELD_PERMISSION_ELEMENT;
20 23 import static org.flowable.bpmn.constants.BpmnXMLConstants.FLOWABLE_EXTENSIONS_NAMESPACE;
21 24 import static org.flowable.bpmn.constants.BpmnXMLConstants.FLOWABLE_EXTENSIONS_PREFIX;
... ... @@ -30,6 +33,16 @@ public class SimpleModelUtils {
30 33 public static final String BPMN_SIMPLE_COPY_EXECUTION_SCRIPT = "#{bpmSimpleNodeService.copy(execution)}";
31 34  
32 35 /**
  36 + * 所有审批人同意的表达式
  37 + */
  38 + public static final String ALL_APPROVE_COMPLETE_EXPRESSION = "${ nrOfCompletedInstances >= 0 }";
  39 +
  40 + /**
  41 + * 任一一名审批人同意的表达式
  42 + */
  43 + public static final String ANY_OF_APPROVE_COMPLETE_EXPRESSION = "${ nrOfCompletedInstances >= nrOfInstances }";
  44 +
  45 + /**
33 46 * 仿钉钉流程设计模型数据结构(json) 转换成 Bpmn Model (待完善)
34 47 *
35 48 * @param processId 流程标识
... ... @@ -47,10 +60,15 @@ public class SimpleModelUtils {
47 60 // 前端模型数据结构。 有 start event 节点. 没有 end event 节点。
48 61 // 从 SimpleModel 构建 FlowNode 并添加到 Main Process
49 62 buildAndAddBpmnFlowNode(simpleModelNode, mainProcess);
50   - // 单独构建 end event 节点
51   - buildAndAddBpmnEndEvent(mainProcess);
  63 + // 找到 end event
  64 + EndEvent endEvent = (EndEvent) CollUtil.findOne(mainProcess.getFlowElements(), item -> item instanceof EndEvent);
  65 + if (endEvent == null) {
  66 + // 暂时为了兼容 单独构建 end event 节点
  67 + endEvent = buildAndAddBpmnEndEvent(mainProcess);
  68 + }
  69 +
52 70 // 构建并添加节点之间的连线 Sequence Flow
53   - buildAndAddBpmnSequenceFlow(mainProcess, simpleModelNode, BpmnModelConstants.END_EVENT_ID);
  71 + buildAndAddBpmnSequenceFlow(mainProcess, simpleModelNode, endEvent.getId());
54 72 // 自动布局
55 73 new BpmnAutoLayout(bpmnModel).execute();
56 74 return bpmnModel;
... ... @@ -58,7 +76,7 @@ public class SimpleModelUtils {
58 76  
59 77 private static void buildAndAddBpmnSequenceFlow(Process mainProcess, BpmSimpleModelNodeVO node, String targetId) {
60 78 // 节点为 null 退出
61   - if (node == null || node.getId() == null) {
  79 + if (node == null || node.getId() == null || END_EVENT.getType().equals(node.getType())) {
62 80 return;
63 81 }
64 82 BpmSimpleModelNodeVO childNode = node.getChildNode();
... ... @@ -169,6 +187,11 @@ public class SimpleModelUtils {
169 187 mainProcess.addFlowElement(inclusiveGateway);
170 188 break;
171 189 }
  190 + case END_EVENT: {
  191 + EndEvent endEvent = buildBpmnEndEvent(simpleModelNode);
  192 + mainProcess.addFlowElement(endEvent);
  193 + break;
  194 + }
172 195 default: {
173 196 // TODO 其它节点类型的实现
174 197 }
... ... @@ -242,32 +265,59 @@ public class SimpleModelUtils {
242 265 return inclusiveGateway;
243 266 }
244 267  
245   - private static void buildAndAddBpmnEndEvent(Process mainProcess) {
  268 + private static EndEvent buildAndAddBpmnEndEvent(Process mainProcess) {
246 269 EndEvent endEvent = new EndEvent();
247 270 endEvent.setId(BpmnModelConstants.END_EVENT_ID);
248 271 endEvent.setName("结束");
249 272 mainProcess.addFlowElement(endEvent);
  273 + return endEvent;
250 274 }
251 275  
252 276 private static UserTask buildBpmnUserTask(BpmSimpleModelNodeVO node) {
253 277 UserTask userTask = new UserTask();
254 278 userTask.setId(node.getId());
255 279 userTask.setName(node.getName());
256   - // TODO 暂时测试,后面去掉
257   - userTask.setFormKey("24");
258 280 // 添加候选人元素
259 281 addCandidateElements(node, userTask);
260 282 // 添加表单字段权限属性元素
261 283 addFormFieldsPermission(node, userTask);
  284 + // 处理多实例
  285 + processMultiInstanceLoopCharacteristics(node, userTask);
262 286 return userTask;
263 287 }
264 288  
  289 + private static void processMultiInstanceLoopCharacteristics(BpmSimpleModelNodeVO node, UserTask userTask) {
  290 + Integer approveMethod = MapUtil.getInt(node.getAttributes(), SimpleModelConstants.APPROVE_METHOD_ATTRIBUTE);
  291 + BpmApproveMethodEnum bpmApproveMethodEnum = BpmApproveMethodEnum.valueOf(approveMethod);
  292 + if (bpmApproveMethodEnum == null || bpmApproveMethodEnum == BpmApproveMethodEnum.SINGLE_PERSON_APPROVE) {
  293 + return;
  294 + }
  295 + MultiInstanceLoopCharacteristics multiInstanceCharacteristics = new MultiInstanceLoopCharacteristics();
  296 + // 设置 collectionVariable。本系统用不到。会在 仅仅为了校验。
  297 + multiInstanceCharacteristics.setInputDataItem("${coll_userList}");
  298 + if (bpmApproveMethodEnum == BpmApproveMethodEnum.ALL_APPROVE) {
  299 + multiInstanceCharacteristics.setCompletionCondition(ALL_APPROVE_COMPLETE_EXPRESSION);
  300 + multiInstanceCharacteristics.setSequential(false);
  301 + } else if (bpmApproveMethodEnum == BpmApproveMethodEnum.ANY_OF_APPROVE) {
  302 + multiInstanceCharacteristics.setCompletionCondition(ANY_OF_APPROVE_COMPLETE_EXPRESSION);
  303 + multiInstanceCharacteristics.setSequential(false);
  304 + userTask.setLoopCharacteristics(multiInstanceCharacteristics);
  305 + } else if (bpmApproveMethodEnum == BpmApproveMethodEnum.SEQUENTIAL_APPROVE) {
  306 + multiInstanceCharacteristics.setCompletionCondition(ALL_APPROVE_COMPLETE_EXPRESSION);
  307 + multiInstanceCharacteristics.setSequential(true);
  308 + multiInstanceCharacteristics.setLoopCardinality("1");
  309 + userTask.setLoopCharacteristics(multiInstanceCharacteristics);
  310 + }
  311 + userTask.setLoopCharacteristics(multiInstanceCharacteristics);
  312 + }
  313 +
265 314 /**
266 315 * 给节点添加表单字段权限元素
267 316 */
268 317 private static void addFormFieldsPermission(BpmSimpleModelNodeVO node, FlowElement flowElement) {
269 318 List<Map<String, String>> fieldsPermissions = MapUtil.get(node.getAttributes(),
270   - FORM_FIELD_PERMISSION_ELEMENT, new TypeReference<>() {});
  319 + FORM_FIELD_PERMISSION_ELEMENT, new TypeReference<>() {
  320 + });
271 321 if (CollUtil.isNotEmpty(fieldsPermissions)) {
272 322 fieldsPermissions.forEach(item -> addExtensionElement(flowElement, FORM_FIELD_PERMISSION_ELEMENT, item));
273 323 }
... ... @@ -307,4 +357,11 @@ public class SimpleModelUtils {
307 357 startEvent.setName(node.getName());
308 358 return startEvent;
309 359 }
  360 +
  361 + private static EndEvent buildBpmnEndEvent(BpmSimpleModelNodeVO node) {
  362 + EndEvent endEvent = new EndEvent();
  363 + endEvent.setId(node.getId());
  364 + endEvent.setName(node.getName());
  365 + return endEvent;
  366 + }
310 367 }
... ...