Commit d9ca52a478a4c56344b042914d3dfa548fdd29d3

Authored by YunaiV
1 parent 4bd399cd

【代码评审】BPM:review simple 字段、seq 连线

yudao-module-bpm/yudao-module-bpm-api/src/main/java/cn/iocoder/yudao/module/bpm/enums/definition/BpmSimpleModelNodeType.java
@@ -30,6 +30,7 @@ public enum BpmSimpleModelNodeType implements IntArrayValuable { @@ -30,6 +30,7 @@ public enum BpmSimpleModelNodeType implements IntArrayValuable {
30 PARALLEL_BRANCH_JOIN_NODE(6, "并行分支聚合节点"), 30 PARALLEL_BRANCH_JOIN_NODE(6, "并行分支聚合节点"),
31 INCLUSIVE_BRANCH_FORK_NODE(7, "包容网关分叉节点"), 31 INCLUSIVE_BRANCH_FORK_NODE(7, "包容网关分叉节点"),
32 INCLUSIVE_BRANCH_JOIN_NODE(8, "包容网关聚合节点"), 32 INCLUSIVE_BRANCH_JOIN_NODE(8, "包容网关聚合节点"),
  33 + // TODO @jason:建议整合 join,最终只有 条件分支、并行分支、包容分支,三种~
33 ; 34 ;
34 35
35 public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(BpmSimpleModelNodeType::getType).toArray(); 36 public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(BpmSimpleModelNodeType::getType).toArray();
@@ -43,7 +44,8 @@ public enum BpmSimpleModelNodeType implements IntArrayValuable { @@ -43,7 +44,8 @@ public enum BpmSimpleModelNodeType implements IntArrayValuable {
43 * @param type 节点类型 44 * @param type 节点类型
44 */ 45 */
45 public static boolean isBranchNode(Integer type) { 46 public static boolean isBranchNode(Integer type) {
46 - return Objects.equals(CONDITION_BRANCH_NODE.getType(), type) || Objects.equals(PARALLEL_BRANCH_FORK_NODE.getType(), type) 47 + return Objects.equals(CONDITION_BRANCH_NODE.getType(), type)
  48 + || Objects.equals(PARALLEL_BRANCH_FORK_NODE.getType(), type)
47 || Objects.equals(INCLUSIVE_BRANCH_FORK_NODE.getType(), type) ; 49 || Objects.equals(INCLUSIVE_BRANCH_FORK_NODE.getType(), type) ;
48 } 50 }
49 51
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/model/simple/BpmSimpleModelNodeVO.java
@@ -28,16 +28,25 @@ public class BpmSimpleModelNodeVO { @@ -28,16 +28,25 @@ public class BpmSimpleModelNodeVO {
28 @Schema(description = "模型节点名称", example = "领导审批") 28 @Schema(description = "模型节点名称", example = "领导审批")
29 private String name; 29 private String name;
30 30
  31 + // TODO @jason:要不改成 placeholder 和一般 Element-Plus 组件一致。占位符,用于展示。
31 @Schema(description = "节点展示内容", example = "指定成员: 芋道源码") 32 @Schema(description = "节点展示内容", example = "指定成员: 芋道源码")
32 private String showText; 33 private String showText;
33 34
34 - @Schema(description = "孩子节点")  
35 - private BpmSimpleModelNodeVO childNode; 35 + @Schema(description = "子节点")
  36 + private BpmSimpleModelNodeVO childNode; // 补充说明:在该模型下,子节点有且仅有一个,不会有多个
36 37
37 - @Schema(description = "网关节点的条件节点")  
38 - private List<BpmSimpleModelNodeVO> conditionNodes; 38 + @Schema(description = "条件节点")
  39 + private List<BpmSimpleModelNodeVO> conditionNodes; // 补充说明:有且仅有条件、并行、包容等分支会使用
39 40
40 @Schema(description = "节点的属性") 41 @Schema(description = "节点的属性")
41 - private Map<String, Object> attributes; 42 + private Map<String, Object> attributes; // TODO @jason:建议是字段分拆下;类似说:
  43 + // Map<String, Integer> formPermissions; 表单权限;仅发起、审批、抄送节点会使用
  44 + // Integer approveMethod; 审批方式;仅审批节点会使用
  45 + // TODO @芋艿:审批人的选择;
  46 + // TODO @芋艿:没有人的策略?
  47 + // TODO @芋艿:审批拒绝的策略?
  48 + // TODO @芋艿:配置的可操作列表?
  49 + // TODO @芋艿:超时配置;要支持指定时间点、指定时间间隔;
  50 + // TODO @芋艿:条件;建议可以固化的一些选项;然后有个表达式兜底;要支持
42 51
43 } 52 }
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/model/simple/BpmSimpleModelUpdateReqVO.java
@@ -6,6 +6,7 @@ import jakarta.validation.constraints.NotEmpty; @@ -6,6 +6,7 @@ import jakarta.validation.constraints.NotEmpty;
6 import jakarta.validation.constraints.NotNull; 6 import jakarta.validation.constraints.NotNull;
7 import lombok.Data; 7 import lombok.Data;
8 8
  9 +// TODO @jason:需要考虑,如果某个节点的配置不正确,需要有提示;具体怎么实现,可以讨论下;
9 @Schema(description = "管理后台 - 仿钉钉流程设计模型的新增/修改 Request VO") 10 @Schema(description = "管理后台 - 仿钉钉流程设计模型的新增/修改 Request VO")
10 @Data 11 @Data
11 public class BpmSimpleModelUpdateReqVO { 12 public class BpmSimpleModelUpdateReqVO {
@@ -14,6 +15,7 @@ public class BpmSimpleModelUpdateReqVO { @@ -14,6 +15,7 @@ public class BpmSimpleModelUpdateReqVO {
14 @NotEmpty(message = "流程模型编号不能为空") 15 @NotEmpty(message = "流程模型编号不能为空")
15 private String modelId; // 对应 Flowable act_re_model 表 ID_ 字段 16 private String modelId; // 对应 Flowable act_re_model 表 ID_ 字段
16 17
  18 + // TODO @jason:simpleModel 要不?
17 @Schema(description = "仿钉钉流程设计模型对象", requiredMode = Schema.RequiredMode.REQUIRED) 19 @Schema(description = "仿钉钉流程设计模型对象", requiredMode = Schema.RequiredMode.REQUIRED)
18 @NotNull(message = "仿钉钉流程设计模型对象不能为空") 20 @NotNull(message = "仿钉钉流程设计模型对象不能为空")
19 @Valid 21 @Valid
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/util/SimpleModelUtils.java
@@ -92,11 +92,13 @@ public class SimpleModelUtils { @@ -92,11 +92,13 @@ public class SimpleModelUtils {
92 92
93 private static void buildAndAddBpmnSequenceFlow(Process mainProcess, BpmSimpleModelNodeVO node, String targetId) { 93 private static void buildAndAddBpmnSequenceFlow(Process mainProcess, BpmSimpleModelNodeVO node, String targetId) {
94 // 节点为 null 或者 为END_EVENT 退出 94 // 节点为 null 或者 为END_EVENT 退出
  95 + // TODO @jason:isValidNode;然后把 END_NODE 是不是拿到 switch (nodeType) { 那 return 哈?这样出口更统一一点?
95 if (node == null || node.getId() == null || END_NODE.getType().equals(node.getType())) { 96 if (node == null || node.getId() == null || END_NODE.getType().equals(node.getType())) {
96 return; 97 return;
97 } 98 }
98 BpmSimpleModelNodeVO childNode = node.getChildNode(); 99 BpmSimpleModelNodeVO childNode = node.getChildNode();
99 // 如果是网关分支节点. 后续节点可能为 null。但不是 END_EVENT 节点 100 // 如果是网关分支节点. 后续节点可能为 null。但不是 END_EVENT 节点
  101 + // TODO @芋艿:这个要不要挪到 START_NODE - INCLUSIVE_BRANCH_JOIN_NODE 待定;感觉 switch 那最终是分三个情况;branch、子节点、结束了;(每种情况的注释,需要写的更完整)
100 if (!BpmSimpleModelNodeType.isBranchNode(node.getType()) && (childNode == null || childNode.getId() == null)) { 102 if (!BpmSimpleModelNodeType.isBranchNode(node.getType()) && (childNode == null || childNode.getId() == null)) {
101 SequenceFlow sequenceFlow = buildBpmnSequenceFlow(node.getId(), targetId, null, null, null); 103 SequenceFlow sequenceFlow = buildBpmnSequenceFlow(node.getId(), targetId, null, null, null);
102 mainProcess.addFlowElement(sequenceFlow); 104 mainProcess.addFlowElement(sequenceFlow);
@@ -104,6 +106,7 @@ public class SimpleModelUtils { @@ -104,6 +106,7 @@ public class SimpleModelUtils {
104 } 106 }
105 BpmSimpleModelNodeType nodeType = BpmSimpleModelNodeType.valueOf(node.getType()); 107 BpmSimpleModelNodeType nodeType = BpmSimpleModelNodeType.valueOf(node.getType());
106 Assert.notNull(nodeType, "模型节点类型不支持"); 108 Assert.notNull(nodeType, "模型节点类型不支持");
  109 + // TODO @jason:下面的 PARALLEL_BRANCH_FORK_NODE、CONDITION_BRANCH_NODE、INCLUSIVE_BRANCH_FORK_NODE 是不是就是 isBranchNode?如果是的话,貌似不用 swtich,而是 if else 分类处理呢。
107 switch (nodeType) { 110 switch (nodeType) {
108 case START_NODE: 111 case START_NODE:
109 case APPROVE_NODE: 112 case APPROVE_NODE:
@@ -119,17 +122,24 @@ public class SimpleModelUtils { @@ -119,17 +122,24 @@ public class SimpleModelUtils {
119 case PARALLEL_BRANCH_FORK_NODE: 122 case PARALLEL_BRANCH_FORK_NODE:
120 case CONDITION_BRANCH_NODE: 123 case CONDITION_BRANCH_NODE:
121 case INCLUSIVE_BRANCH_FORK_NODE: { 124 case INCLUSIVE_BRANCH_FORK_NODE: {
  125 + // TODO @jason:这里 sequenceFlowTargetId 不建议做这样的 default。万一可能有 bug 哈;直接弄到对应的 136- 146 会更安全一点。
122 String sequenceFlowTargetId = (childNode == null || childNode.getId() == null) ? targetId : childNode.getId(); 126 String sequenceFlowTargetId = (childNode == null || childNode.getId() == null) ? targetId : childNode.getId();
123 List<BpmSimpleModelNodeVO> conditionNodes = node.getConditionNodes(); 127 List<BpmSimpleModelNodeVO> conditionNodes = node.getConditionNodes();
124 Assert.notEmpty(conditionNodes, "网关节点的条件节点不能为空"); 128 Assert.notEmpty(conditionNodes, "网关节点的条件节点不能为空");
125 for (BpmSimpleModelNodeVO item : conditionNodes) { 129 for (BpmSimpleModelNodeVO item : conditionNodes) {
  130 + // 构建表达式
  131 + // TODO @jason:条件分支的情况下,需要分 item 搞的条件,和 conditionNodes 搞的条件
126 String conditionExpression = buildConditionExpression(item); 132 String conditionExpression = buildConditionExpression(item);
  133 +
127 BpmSimpleModelNodeVO nextNodeOnCondition = item.getChildNode(); 134 BpmSimpleModelNodeVO nextNodeOnCondition = item.getChildNode();
  135 + // TODO @jason:isValidNode
128 if (nextNodeOnCondition != null && nextNodeOnCondition.getId() != null) { 136 if (nextNodeOnCondition != null && nextNodeOnCondition.getId() != null) {
  137 + // TODO @jason:会存在 item.name 未空的情况么?这个时候,要不要兜底处理拼接
129 SequenceFlow sequenceFlow = buildBpmnSequenceFlow(node.getId(), nextNodeOnCondition.getId(), 138 SequenceFlow sequenceFlow = buildBpmnSequenceFlow(node.getId(), nextNodeOnCondition.getId(),
130 item.getId(), item.getName(), conditionExpression); 139 item.getId(), item.getName(), conditionExpression);
131 mainProcess.addFlowElement(sequenceFlow); 140 mainProcess.addFlowElement(sequenceFlow);
132 // 递归调用后续节点 141 // 递归调用后续节点
  142 + // TODO @jason:最好也有个例子,嘿嘿;S4
133 buildAndAddBpmnSequenceFlow(mainProcess, nextNodeOnCondition, sequenceFlowTargetId); 143 buildAndAddBpmnSequenceFlow(mainProcess, nextNodeOnCondition, sequenceFlowTargetId);
134 } else { 144 } else {
135 SequenceFlow sequenceFlow = buildBpmnSequenceFlow(node.getId(), sequenceFlowTargetId, 145 SequenceFlow sequenceFlow = buildBpmnSequenceFlow(node.getId(), sequenceFlowTargetId,
@@ -137,7 +147,7 @@ public class SimpleModelUtils { @@ -137,7 +147,7 @@ public class SimpleModelUtils {
137 mainProcess.addFlowElement(sequenceFlow); 147 mainProcess.addFlowElement(sequenceFlow);
138 } 148 }
139 } 149 }
140 - // 递归调用后续节点 150 + // 递归调用后续节点 TODO @jason:最好有个例子哈
141 buildAndAddBpmnSequenceFlow(mainProcess, childNode, targetId); 151 buildAndAddBpmnSequenceFlow(mainProcess, childNode, targetId);
142 break; 152 break;
143 } 153 }
@@ -188,6 +198,9 @@ public class SimpleModelUtils { @@ -188,6 +198,9 @@ public class SimpleModelUtils {
188 } 198 }
189 199
190 private static SequenceFlow buildBpmnSequenceFlow(String sourceId, String targetId, String seqFlowId, String seqName, String conditionExpression) { 200 private static SequenceFlow buildBpmnSequenceFlow(String sourceId, String targetId, String seqFlowId, String seqName, String conditionExpression) {
  201 + // TODO @jason:最好断言下,sourceId、targetId 必须存在!
  202 + // TODO @jason:如果 seqFlowId 不存在的时候,是不是要生成一个默认的 seqFlowId?
  203 + // TODO @jason:如果 name 不存在的时候,是不是要生成一个默认的 name?
191 SequenceFlow sequenceFlow = new SequenceFlow(sourceId, targetId); 204 SequenceFlow sequenceFlow = new SequenceFlow(sourceId, targetId);
192 if (StrUtil.isNotEmpty(conditionExpression)) { 205 if (StrUtil.isNotEmpty(conditionExpression)) {
193 sequenceFlow.setConditionExpression(conditionExpression); 206 sequenceFlow.setConditionExpression(conditionExpression);