diff --git a/yudao-module-bpm/yudao-module-bpm-api/src/main/java/cn/iocoder/yudao/module/bpm/enums/definition/BpmAutoApproveType.java b/yudao-module-bpm/yudao-module-bpm-api/src/main/java/cn/iocoder/yudao/module/bpm/enums/definition/BpmAutoApproveType.java new file mode 100644 index 0000000000..7e6444fb2a --- /dev/null +++ b/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; + } + +} \ No newline at end of file diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/model/BpmModelMetaInfoVO.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/model/BpmModelMetaInfoVO.java index dfd62cfc2e..ee14536d58 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/model/BpmModelMetaInfoVO.java +++ b/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 diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/dal/dataobject/definition/BpmProcessDefinitionInfoDO.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/dal/dataobject/definition/BpmProcessDefinitionInfoDO.java index 3edbb9fd51..6416e30cd1 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/dal/dataobject/definition/BpmProcessDefinitionInfoDO.java +++ b/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; + } diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmTaskServiceImpl.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmTaskServiceImpl.java index 03a65f2a58..f9f0340917 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmTaskServiceImpl.java +++ b/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 incomingFlows = taskElement.getIncomingFlows(); + List 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())) { // 判断是否为退回或者驳回:如果是退回或者驳回不走这个策略