Explorar el Código

feat: BPM-更多设置-自动去重

Lesan hace 6 meses
padre
commit
d8bc3a46e5

+ 32 - 0
yudao-module-bpm/yudao-module-bpm-api/src/main/java/cn/iocoder/yudao/module/bpm/enums/definition/BpmAutoApproveType.java

@@ -0,0 +1,32 @@
+package cn.iocoder.yudao.module.bpm.enums.definition;
+
+import cn.iocoder.yudao.framework.common.core.IntArrayValuable;
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+import java.util.Arrays;
+
+/**
+ * BPM 自动去重的类型的枚举
+ *
+ * @author Lesan
+ */
+@Getter
+@AllArgsConstructor
+public enum BpmAutoApproveType implements IntArrayValuable {
+
+    NONE(1, "不自动通过"),
+    APPROVE_ALL(2, "仅审批一次,后续重复的审批节点均自动通过"),
+    APPROVE_SEQUENT(3, "仅针对连续审批的节点自动通过");
+
+    public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(BpmAutoApproveType::getType).toArray();
+
+    private final Integer type;
+    private final String name;
+
+    @Override
+    public int[] array() {
+        return ARRAYS;
+    }
+
+}

+ 5 - 0
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/model/BpmModelMetaInfoVO.java

@@ -1,6 +1,7 @@
 package cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.model;
 
 import cn.iocoder.yudao.framework.common.validation.InEnum;
+import cn.iocoder.yudao.module.bpm.enums.definition.BpmAutoApproveType;
 import cn.iocoder.yudao.module.bpm.enums.definition.BpmModelFormTypeEnum;
 import cn.iocoder.yudao.module.bpm.enums.definition.BpmModelTypeEnum;
 import io.swagger.v3.oas.annotations.media.Schema;
@@ -69,6 +70,10 @@ public class BpmModelMetaInfoVO {
     @Schema(description = "流程 ID 规则", example = "{}")
     private ProcessIdRule processIdRule;
 
+    @Schema(description = "自动去重类型", example = "1")
+    @InEnum(BpmAutoApproveType.class)
+    private Integer autoApprovalType;
+
     @Schema(description = "流程 ID 规则")
     @Data
     @Valid

+ 5 - 0
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/dal/dataobject/definition/BpmProcessDefinitionInfoDO.java

@@ -162,4 +162,9 @@ public class BpmProcessDefinitionInfoDO extends BaseDO {
     @TableField(typeHandler = JacksonTypeHandler.class)
     private BpmModelMetaInfoVO.ProcessIdRule processIdRule;
 
+    /**
+     * 自动去重类型
+     */
+    private Integer autoApprovalType;
+
 }

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

@@ -13,6 +13,7 @@ import cn.iocoder.yudao.framework.web.core.util.WebFrameworkUtils;
 import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.task.*;
 import cn.iocoder.yudao.module.bpm.convert.task.BpmTaskConvert;
 import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmFormDO;
+import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmProcessDefinitionInfoDO;
 import cn.iocoder.yudao.module.bpm.enums.definition.*;
 import cn.iocoder.yudao.module.bpm.enums.task.BpmCommentTypeEnum;
 import cn.iocoder.yudao.module.bpm.enums.task.BpmReasonEnum;
@@ -33,10 +34,7 @@ import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
 import jakarta.annotation.Resource;
 import jakarta.validation.Valid;
 import lombok.extern.slf4j.Slf4j;
-import org.flowable.bpmn.model.BpmnModel;
-import org.flowable.bpmn.model.EndEvent;
-import org.flowable.bpmn.model.FlowElement;
-import org.flowable.bpmn.model.UserTask;
+import org.flowable.bpmn.model.*;
 import org.flowable.engine.HistoryService;
 import org.flowable.engine.ManagementService;
 import org.flowable.engine.RuntimeService;
@@ -1174,6 +1172,51 @@ public class BpmTaskServiceImpl implements BpmTaskService {
                     log.error("[processTaskAssigned][taskId({}) 没有找到流程实例]", task.getId());
                     return;
                 }
+                // 自动去重 TODO @芋艿 驳回的情况得考虑一下
+                BpmProcessDefinitionInfoDO processDefinitionInfo = bpmProcessDefinitionService.getProcessDefinitionInfo(task.getProcessDefinitionId());
+                if (processDefinitionInfo == null) {
+                    log.error("[processTaskAssigned][taskId({}) 没有找到流程定义]", task.getId());
+                    return;
+                }
+                if (processDefinitionInfo.getAutoApprovalType() != null) {
+                    HistoricTaskInstanceQuery query = historyService.createHistoricTaskInstanceQuery()
+                            .processInstanceId(task.getProcessInstanceId())
+                            .taskAssignee(task.getAssignee())
+                            .taskVariableValueEquals(BpmnVariableConstants.TASK_VARIABLE_STATUS,
+                                    BpmTaskStatusEnum.APPROVE.getStatus())
+                            .finished();
+                    if (BpmAutoApproveType.APPROVE_ALL.getType().equals(processDefinitionInfo.getAutoApprovalType())){
+                        long count = query.count();
+                        if (count > 0) {
+                            // 自动通过
+                            getSelf().approveTask(Long.valueOf(task.getAssignee()), new BpmTaskApproveReqVO().setId(task.getId())
+                                    .setReason(BpmReasonEnum.APPROVE_TYPE_AUTO_APPROVE.getReason()));
+                            return;
+                        }
+                    }
+                    if (BpmAutoApproveType.APPROVE_SEQUENT.getType().equals(processDefinitionInfo.getAutoApprovalType())) {
+                        BpmnModel bpmnModel = modelService.getBpmnModelByDefinitionId(processInstance.getProcessDefinitionId());
+                        if (bpmnModel == null) {
+                            log.error("[processTaskAssigned][taskId({}) 没有找到流程模型]", task.getId());
+                            return;
+                        }
+                        FlowNode taskElement = (FlowNode) BpmnModelUtils.getFlowElementById(bpmnModel, task.getTaskDefinitionKey());
+                        List<SequenceFlow> incomingFlows = taskElement.getIncomingFlows();
+                        List<String> sourceTaskIds = new ArrayList<>();
+                        if (incomingFlows != null && !incomingFlows.isEmpty()) {
+                            incomingFlows.forEach(flow -> {
+                                sourceTaskIds.add(flow.getSourceRef());
+                            });
+                        }
+                        long count = query.taskDefinitionKeys(sourceTaskIds).count();
+                        if (count > 0) {
+                            // 自动通过
+                            getSelf().approveTask(Long.valueOf(task.getAssignee()), new BpmTaskApproveReqVO().setId(task.getId())
+                                    .setReason(BpmReasonEnum.APPROVE_TYPE_AUTO_APPROVE.getReason()));
+                            return;
+                        }
+                    }
+                }
                 // 审批人与提交人为同一人时,根据 BpmUserTaskAssignStartUserHandlerTypeEnum 策略进行处理
                 if (StrUtil.equals(task.getAssignee(), processInstance.getStartUserId())) {
                     // 判断是否为退回或者驳回:如果是退回或者驳回不走这个策略