liu
昨天 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;
@@ -74,7 +75,7 @@
/**
 * 流程任务实例 Service 实现类
 *
 * @author 芋道源码
 * @author 超级管理员
 * @author jason
 */
@Slf4j
@@ -102,6 +103,8 @@
    private BpmMessageService messageService;
    @Resource
    private BpmFormService formService;
    @Resource
    private BpmProcessAutoApproveService processAutoApproveService;
    @Resource
    private AdminUserApi adminUserApi;
@@ -987,7 +990,7 @@
        //  改成 moveExecutionsToSingleActivityId 好像并没有遇到 ② 提到的超时提醒失效的问题。暂时先改回 moveExecutionsToSingleActivityId
        // ④ moveExecutionsToSingleActivityId 回退多实例的时候不会去删除多实例根, 应改成 moveActivityIdsToSingleActivityId
        // flowable 8.0.0  修复上面相关问题, 还修复了并行分支回退的问题 https://t.zsxq.com/z4d9i。
        // ⑤ 使用 moveExecutionsToSingleActivityId 方法进行回退操作时,如果是多实例的用户任务【芋道用户任务默认为多实例】,不会删除多实例任务的根数据 ACT_RU_EXECUTION
        // ⑤ 使用 moveExecutionsToSingleActivityId 方法进行回退操作时,如果是多实例的用户任务【超级管理员用户任务默认为多实例】,不会删除多实例任务的根数据 ACT_RU_EXECUTION
        // 会导致有一些问题,所以使用 moveActivityIdsToSingleActivityId。 但是该方法在 flowable 6.8.1 ~ 7.1.0 的版本会有 bug 阻塞回退功能
        // 相关 issue: https://github.com/flowable/flowable-engine/issues/3944
        runtimeService.createChangeActivityStateBuilder()
@@ -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())) {
                    // 如果有审批人、或者拥有人,则说明不满足情况一,不自动通过、不自动拒绝