Parcourir la source

仿钉钉流程设计- 模型节点结构调整

jason il y a 1 an
Parent
commit
9e41576dc4

+ 11 - 1
yudao-module-bpm/yudao-module-bpm-api/src/main/java/cn/iocoder/yudao/module/bpm/enums/definition/BpmApproveMethodEnum.java

@@ -1,9 +1,12 @@
 package cn.iocoder.yudao.module.bpm.enums.definition;
 
 import cn.hutool.core.util.ArrayUtil;
+import cn.iocoder.yudao.framework.common.core.IntArrayValuable;
 import lombok.AllArgsConstructor;
 import lombok.Getter;
 
+import java.util.Arrays;
+
 /**
  * BPM 多人审批方式的枚举
  *
@@ -11,7 +14,7 @@ import lombok.Getter;
  */
 @Getter
 @AllArgsConstructor
-public enum BpmApproveMethodEnum {
+public enum BpmApproveMethodEnum implements IntArrayValuable {
 
     RANDOM_SELECT_ONE_APPROVE(1, "随机挑选一人审批"),
     APPROVE_BY_RATIO(2, "多人会签(按通过比例)"), // 会签(按通过比例)
@@ -22,13 +25,20 @@ public enum BpmApproveMethodEnum {
      * 审批方式
      */
     private final Integer method;
+
     /**
      * 名字
      */
     private final String name;
 
+    public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(BpmApproveMethodEnum::getMethod).toArray();
+
     public static BpmApproveMethodEnum valueOf(Integer method) {
         return ArrayUtil.firstMatch(item -> item.getMethod().equals(method), values());
     }
 
+    @Override
+    public int[] array() {
+        return ARRAYS;
+    }
 }

+ 10 - 1
yudao-module-bpm/yudao-module-bpm-api/src/main/java/cn/iocoder/yudao/module/bpm/enums/definition/BpmUserTaskRejectHandlerType.java

@@ -1,9 +1,12 @@
 package cn.iocoder.yudao.module.bpm.enums.definition;
 
 import cn.hutool.core.util.ArrayUtil;
+import cn.iocoder.yudao.framework.common.core.IntArrayValuable;
 import lombok.AllArgsConstructor;
 import lombok.Getter;
 
+import java.util.Arrays;
+
 /**
  * BPM 用户任务拒绝处理类型枚举
  *
@@ -11,7 +14,7 @@ import lombok.Getter;
  */
 @Getter
 @AllArgsConstructor
-public enum BpmUserTaskRejectHandlerType {
+public enum BpmUserTaskRejectHandlerType implements IntArrayValuable {
 
     FINISH_PROCESS(1, "终止流程"),
     RETURN_USER_TASK(2, "驳回到指定任务节点");
@@ -19,8 +22,14 @@ public enum BpmUserTaskRejectHandlerType {
     private final Integer type;
     private final String name;
 
+    public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(BpmUserTaskRejectHandlerType::getType).toArray();
+
     public static BpmUserTaskRejectHandlerType typeOf(Integer type) {
         return ArrayUtil.firstMatch(item -> item.getType().equals(type), values());
     }
 
+    @Override
+    public int[] array() {
+        return ARRAYS;
+    }
 }

+ 11 - 1
yudao-module-bpm/yudao-module-bpm-api/src/main/java/cn/iocoder/yudao/module/bpm/enums/definition/BpmUserTaskTimeoutActionEnum.java

@@ -1,9 +1,12 @@
 package cn.iocoder.yudao.module.bpm.enums.definition;
 
 import cn.hutool.core.util.ArrayUtil;
+import cn.iocoder.yudao.framework.common.core.IntArrayValuable;
 import lombok.AllArgsConstructor;
 import lombok.Getter;
 
+import java.util.Arrays;
+
 /**
  * 用户任务超时处理执行动作枚举
  *
@@ -11,7 +14,7 @@ import lombok.Getter;
  */
 @Getter
 @AllArgsConstructor
-public enum BpmUserTaskTimeoutActionEnum {
+public enum BpmUserTaskTimeoutActionEnum implements IntArrayValuable {
 
     AUTO_REMINDER(1,"自动提醒"),
     AUTO_APPROVE(2, "自动同意"),
@@ -20,7 +23,14 @@ public enum BpmUserTaskTimeoutActionEnum {
     private final Integer action;
     private final String name;
 
+    public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(BpmUserTaskTimeoutActionEnum::getAction).toArray();
+
     public static BpmUserTaskTimeoutActionEnum actionOf(Integer action) {
         return ArrayUtil.firstMatch(item -> item.getAction().equals(action), values());
     }
+
+    @Override
+    public int[] array() {
+        return ARRAYS;
+    }
 }

+ 63 - 0
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/model/simple/BpmSimpleModelNodeVO.java

@@ -1,7 +1,11 @@
 package cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.model.simple;
 
 import cn.iocoder.yudao.framework.common.validation.InEnum;
+import cn.iocoder.yudao.module.bpm.enums.definition.BpmApproveMethodEnum;
 import cn.iocoder.yudao.module.bpm.enums.definition.BpmSimpleModelNodeType;
+import cn.iocoder.yudao.module.bpm.enums.definition.BpmUserTaskRejectHandlerType;
+import cn.iocoder.yudao.module.bpm.enums.definition.BpmUserTaskTimeoutActionEnum;
+import cn.iocoder.yudao.module.bpm.framework.flowable.core.enums.BpmTaskCandidateStrategyEnum;
 import com.fasterxml.jackson.annotation.JsonIgnore;
 import com.fasterxml.jackson.annotation.JsonInclude;
 import io.swagger.v3.oas.annotations.media.Schema;
@@ -50,6 +54,64 @@ public class BpmSimpleModelNodeVO {
     @JsonIgnore
     private String attachNodeId;
 
+    @Schema(description = "候选人策略", example = "30")
+    @InEnum(BpmTaskCandidateStrategyEnum.class)
+    private Integer candidateStrategy;  // 用于审批,抄送节点
+
+    @Schema(description = "候选人参数")
+    private String candidateParam;    // 用于审批,抄送节点
+
+    @Schema(description = "多人审批方式", example = "1")
+    @InEnum(BpmApproveMethodEnum.class)  // 用于审批节点
+    private Integer approveMethod;
+
+    @Schema(description = "表单权限", example = "[]")
+    private List<Map<String, String>> fieldsPermission;
+
+    @Schema(description = "通过比例", example = "100")
+    private Integer approveRatio;  // 通过比例  当多人审批方式为:多人会签(按通过比例) 需要设置
+
+    /**
+     * 审批节点拒绝处理
+     */
+    private RejectHandler rejectHandler;
+
+    /**
+     * 审批节点超时处理
+     */
+    private TimeoutHandler timeoutHandler;
+
+    @Data
+    @Schema(description = "审批节点拒绝处理策略")
+    public static class RejectHandler {
+
+        @Schema(description = "拒绝处理类型", example = "1")
+        @InEnum(BpmUserTaskRejectHandlerType.class)
+        private Integer type;
+
+        @Schema(description = "任务拒绝后驳回的节点 Id", example = "Activity_1")
+        private String returnNodeId;
+    }
+
+    @Data
+    @Schema(description = "审批节点超时处理策略")
+    public static class TimeoutHandler {
+
+        @Schema(description = "是否开启超时处理", example = "false")
+        private Boolean enable;
+
+        @Schema(description = "任务超时未处理的行为", example = "1")
+        @InEnum(BpmUserTaskTimeoutActionEnum.class)
+        private Integer action;
+
+        @Schema(description = "超时时间", example = "PT6H")
+        private String timeDuration;
+
+        @Schema(description = "最大提醒次数", example = "1")
+        private Integer maxRemindCount;
+    }
+
+
     // Map<String, Integer> formPermissions; 表单权限;仅发起、审批、抄送节点会使用
     // Integer approveMethod; 审批方式;仅审批节点会使用
     // TODO @jason 后面和前端一起调整一下;下面的 ①、②、③ 是优先级
@@ -61,4 +123,5 @@ public class BpmSimpleModelNodeVO {
     // TODO @芋艿:⑨ 超时配置;要支持指定时间点、指定时间间隔;
     // TODO @芋艿:条件;建议可以固化的一些选项;然后有个表达式兜底;要支持
 
+
 }

+ 11 - 1
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/enums/BpmTaskCandidateStrategyEnum.java

@@ -1,9 +1,12 @@
 package cn.iocoder.yudao.module.bpm.framework.flowable.core.enums;
 
 import cn.hutool.core.util.ArrayUtil;
+import cn.iocoder.yudao.framework.common.core.IntArrayValuable;
 import lombok.AllArgsConstructor;
 import lombok.Getter;
 
+import java.util.Arrays;
+
 /**
  * BPM 任务的候选人策略枚举
  *
@@ -13,7 +16,7 @@ import lombok.Getter;
  */
 @Getter
 @AllArgsConstructor
-public enum BpmTaskCandidateStrategyEnum {
+public enum BpmTaskCandidateStrategyEnum implements IntArrayValuable {
 
     ROLE(10, "角色"),
     DEPT_MEMBER(20, "部门的成员"), // 包括负责人
@@ -26,6 +29,8 @@ public enum BpmTaskCandidateStrategyEnum {
     EXPRESSION(60, "流程表达式"), // 表达式 ExpressionManager
     ;
 
+    public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(BpmTaskCandidateStrategyEnum::getStrategy).toArray();
+
     /**
      * 类型
      */
@@ -39,4 +44,9 @@ public enum BpmTaskCandidateStrategyEnum {
         return ArrayUtil.firstMatch(o -> o.getStrategy().equals(strategy), values());
     }
 
+    @Override
+    public int[] array() {
+        return ARRAYS;
+    }
+
 }

+ 13 - 14
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/util/SimpleModelUtils.java

@@ -8,13 +8,12 @@ import cn.hutool.core.map.MapUtil;
 import cn.hutool.core.util.*;
 import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
 import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.model.simple.BpmSimpleModelNodeVO;
+import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.model.simple.BpmSimpleModelNodeVO.RejectHandler;
 import cn.iocoder.yudao.module.bpm.enums.definition.BpmApproveMethodEnum;
 import cn.iocoder.yudao.module.bpm.enums.definition.BpmSimpleModeConditionType;
 import cn.iocoder.yudao.module.bpm.enums.definition.BpmSimpleModelNodeType;
 import cn.iocoder.yudao.module.bpm.framework.flowable.core.enums.BpmnModelConstants;
 import cn.iocoder.yudao.module.bpm.framework.flowable.core.simplemodel.SimpleModelConditionGroups;
-import cn.iocoder.yudao.module.bpm.framework.flowable.core.simplemodel.SimpleModelUserTaskConfig;
-import cn.iocoder.yudao.module.bpm.framework.flowable.core.simplemodel.SimpleModelUserTaskConfig.RejectHandler;
 import org.flowable.bpmn.BpmnAutoLayout;
 import org.flowable.bpmn.model.Process;
 import org.flowable.bpmn.model.*;
@@ -24,6 +23,7 @@ import java.util.List;
 import java.util.Map;
 import java.util.Objects;
 
+import static cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.model.simple.BpmSimpleModelNodeVO.TimeoutHandler;
 import static cn.iocoder.yudao.module.bpm.enums.definition.BpmBoundaryEventType.USER_TASK_TIMEOUT;
 import static cn.iocoder.yudao.module.bpm.enums.definition.BpmSimpleModelNodeType.*;
 import static cn.iocoder.yudao.module.bpm.enums.definition.BpmUserTaskTimeoutActionEnum.AUTO_REMINDER;
@@ -336,18 +336,17 @@ public class SimpleModelUtils {
 
     private static List<FlowElement> convertApproveNode(BpmSimpleModelNodeVO node) {
         List<FlowElement> flowElements = new ArrayList<>();
-        SimpleModelUserTaskConfig userTaskConfig = BeanUtil.toBean(node.getAttributes(), SimpleModelUserTaskConfig.class);
-        UserTask userTask = buildBpmnUserTask(node, userTaskConfig);
+        UserTask userTask = buildBpmnUserTask(node);
         flowElements.add(userTask);
-        if (userTaskConfig.getTimeoutHandler() != null && userTaskConfig.getTimeoutHandler().getEnable()) {
+        if (node.getTimeoutHandler() != null && node.getTimeoutHandler().getEnable()) {
             // 添加用户任务的 Timer Boundary Event, 用于任务的超时处理
-            BoundaryEvent boundaryEvent = buildUserTaskTimerBoundaryEvent(userTask, userTaskConfig.getTimeoutHandler());
+            BoundaryEvent boundaryEvent = buildUserTaskTimerBoundaryEvent(userTask, node.getTimeoutHandler());
             flowElements.add(boundaryEvent);
         }
         return flowElements;
     }
 
-    private static BoundaryEvent buildUserTaskTimerBoundaryEvent(UserTask userTask, SimpleModelUserTaskConfig.TimeoutHandler timeoutHandler) {
+    private static BoundaryEvent buildUserTaskTimerBoundaryEvent(UserTask userTask, TimeoutHandler timeoutHandler) {
         // 定时器边界事件
         BoundaryEvent boundaryEvent = new BoundaryEvent();
         boundaryEvent.setId("Event-" + IdUtil.fastUUID());
@@ -444,26 +443,26 @@ public class SimpleModelUtils {
         return inclusiveGateway;
     }
 
-    private static UserTask buildBpmnUserTask(BpmSimpleModelNodeVO node, SimpleModelUserTaskConfig userTaskConfig) {
+    private static UserTask buildBpmnUserTask(BpmSimpleModelNodeVO node) {
         UserTask userTask = new UserTask();
         userTask.setId(node.getId());
         userTask.setName(node.getName());
         //  设置审批任务的截止时间
-        if (userTaskConfig.getTimeoutHandler() != null && userTaskConfig.getTimeoutHandler().getEnable()) {
-            userTask.setDueDate(userTaskConfig.getTimeoutHandler().getTimeDuration());
+        if (node.getTimeoutHandler() != null && node.getTimeoutHandler().getEnable()) {
+            userTask.setDueDate(node.getTimeoutHandler().getTimeDuration());
         }
 
         // TODO 芋艿 + jason:要不要基于服务任务,实现或签下的审批不通过?或者说,按比例审批
 
         // TODO @jason:addCandidateElements、processMultiInstanceLoopCharacteristics 建议一起搞哈?
         // 添加候选人元素
-        addCandidateElements(userTaskConfig.getCandidateStrategy(), userTaskConfig.getCandidateParam(), userTask);
+        addCandidateElements(node.getCandidateStrategy(), node.getCandidateParam(), userTask);
         // 添加表单字段权限属性元素
-        addFormFieldsPermission(userTaskConfig.getFieldsPermission(), userTask);
+        addFormFieldsPermission(node.getFieldsPermission(), userTask);
         // 处理多实例
-        processMultiInstanceLoopCharacteristics(userTaskConfig.getApproveMethod(), userTaskConfig.getApproveRatio(), userTask);
+        processMultiInstanceLoopCharacteristics(node.getApproveMethod(), node.getApproveRatio(), userTask);
         // 添加任务被拒绝的处理元素
-        addTaskRejectElements(userTaskConfig.getRejectHandler(), userTask);
+        addTaskRejectElements(node.getRejectHandler(), userTask);
         return userTask;
     }
 

+ 3 - 3
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmTaskServiceImpl.java

@@ -350,7 +350,7 @@ public class BpmTaskServiceImpl implements BpmTaskService {
             }
             // 3.2.2 添加评论
             taskService.addComment(task.getParentTaskId(), task.getProcessInstanceId(),
-                    BpmCommentTypeEnum.REJECT.getType(), BpmCommentTypeEnum.REJECT.formatComment(REJECT_BY_ADD_SIGN_TASK_REJECT));
+                    BpmCommentTypeEnum.REJECT.getType(), REJECT_BY_ADD_SIGN_TASK_REJECT.getComment());
             // 3.2.3 更新还在进行中的加签任务状态为取消
             List<Task> addSignTaskList = getTaskListByParentTaskId(task.getParentTaskId());
             updateTaskStatusWhenCanceled(CollectionUtils.filterList(addSignTaskList, item -> !item.getId().equals(task.getId())),
@@ -375,10 +375,10 @@ public class BpmTaskServiceImpl implements BpmTaskService {
         updateTaskStatusWhenCanceled(CollectionUtils.filterList(taskList, item -> !item.getId().equals(task.getId()) && !item.getId().equals(task.getParentTaskId())),
                 reqVO.getReason());
         // 4.2.2 终止流程
-        List<String> activityIds = convertList(taskList, Task::getTaskDefinitionKey);
+        Set<String> activityIds = convertSet(taskList, Task::getTaskDefinitionKey);
         EndEvent endEvent = BpmnModelUtils.getEndEvent(bpmnModel);
         Assert.notNull(endEvent, "结束节点不能未空");
-        processInstanceService.updateProcessInstanceReject(instance, activityIds, endEvent.getId(), reqVO.getReason());
+        processInstanceService.updateProcessInstanceReject(instance, CollUtil.newArrayList(activityIds), endEvent.getId(), reqVO.getReason());
     }
 
     private void updateTaskStatusWhenCanceled(List<Task> taskList, String reason) {