liu
2 天以前 dd69dd49c98e2d8fdd9b1c77e97923bde0d57b57
yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmTaskServiceImpl.java
@@ -29,6 +29,7 @@
import cn.iocoder.yudao.module.bpm.framework.flowable.core.util.FlowableUtils;
import cn.iocoder.yudao.module.bpm.service.definition.BpmFormService;
import cn.iocoder.yudao.module.bpm.service.definition.BpmModelService;
import cn.iocoder.yudao.module.bpm.service.definition.BpmProcessAutoApproveService;
import cn.iocoder.yudao.module.bpm.service.definition.BpmProcessDefinitionService;
import cn.iocoder.yudao.module.bpm.service.message.BpmMessageService;
import cn.iocoder.yudao.module.bpm.service.message.dto.BpmMessageSendWhenTaskTimeoutReqDTO;
@@ -102,6 +103,8 @@
    private BpmMessageService messageService;
    @Resource
    private BpmFormService formService;
    @Resource
    private BpmProcessAutoApproveService processAutoApproveService;
    @Resource
    private AdminUserApi adminUserApi;
@@ -1400,6 +1403,10 @@
        FlowElement userTaskElement = BpmnModelUtils.getFlowElementById(bpmnModel, task.getTaskDefinitionKey());
        Integer approveType = BpmnModelUtils.parseApproveType(userTaskElement);
        Integer assignEmptyHandlerType = BpmnModelUtils.parseAssignEmptyHandlerType(userTaskElement);
        // 流程级【免审批】开关:仅对【人工审核】节点生效。
        // 非人工审核的节点(AUTO_APPROVE / AUTO_REJECT)有其自身的设计器配置,不受本开关影响,避免两处配置互相干扰。
        boolean autoApproveEnabled = ObjectUtil.equal(approveType, BpmUserTaskApproveTypeEnum.USER.getType())
                && processAutoApproveService.isAutoApprove(processInstance.getProcessDefinitionKey());
        TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronization() {
            /**
@@ -1418,6 +1425,26 @@
                        && getTask(task.getId()) == null) {
                    return;
                }
                // 特殊情况零:流程开启了【免审批】开关,人工审核节点直接自动通过
                //   说明:不改动业务侧任何逻辑——业务照常把单据置为「审批中」,随后走与正常审批通过
                //        完全相同的 approveTask 流程,因此业务监听器、审批留痕、以及下游动作
                //        (生成采购订单 / MPS / 供应商档案 / 报工产出等)全部照常执行。
                if (autoApproveEnabled) {
                    // 幂等保护:任务可能已被推进(例如「发起人节点」由引擎自带的策略先行自动通过),
                    // 此时任务已不存在,直接跳过,避免重复审批报错
                    Task autoApproveTask = getTask(task.getId());
                    if (autoApproveTask == null) {
                        return;
                    }
                    // 必须传入任务的实际审批人:approveTask 会校验「操作人必须是该任务的审批人」,
                    // 传 null 仅对「审批人为空」的任务放行,否则会抛「该任务的审批人不是你」
                    Long assigneeUserId = StrUtil.isNotBlank(autoApproveTask.getAssignee())
                            ? NumberUtils.parseLong(autoApproveTask.getAssignee()) : null;
                    getSelf().approveTask(assigneeUserId, new BpmTaskApproveReqVO()
                            .setId(autoApproveTask.getId())
                            .setReason(BpmReasonEnum.PROCESS_AUTO_APPROVE.getReason()));
                    return;
                }
                // 特殊情况一:【人工审核】审批人为空,根据配置是否要自动通过、自动拒绝
                if (ObjectUtil.equal(approveType, BpmUserTaskApproveTypeEnum.USER.getType())) {
                    // 如果有审批人、或者拥有人,则说明不满足情况一,不自动通过、不自动拒绝