mirror of
				https://github.com/YunaiV/ruoyi-vue-pro.git
				synced 2025-11-04 08:06:12 +08:00 
			
		
		
		
	【功能修复】工作流:自动审批通过时,不能使用 TransactionSynchronizationManager 的 afterCommit 的情况
This commit is contained in:
		@ -1,17 +1,8 @@
 | 
				
			|||||||
package cn.iocoder.yudao.module.bpm.framework.flowable.core.behavior;
 | 
					package cn.iocoder.yudao.module.bpm.framework.flowable.core.behavior;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import cn.hutool.core.collection.CollUtil;
 | 
					import cn.hutool.core.collection.CollUtil;
 | 
				
			||||||
import cn.hutool.core.util.ObjectUtil;
 | 
					 | 
				
			||||||
import cn.hutool.core.util.RandomUtil;
 | 
					import cn.hutool.core.util.RandomUtil;
 | 
				
			||||||
import cn.hutool.extra.spring.SpringUtil;
 | 
					 | 
				
			||||||
import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.task.BpmTaskApproveReqVO;
 | 
					 | 
				
			||||||
import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.task.BpmTaskRejectReqVO;
 | 
					 | 
				
			||||||
import cn.iocoder.yudao.module.bpm.enums.definition.BpmUserTaskApproveTypeEnum;
 | 
					 | 
				
			||||||
import cn.iocoder.yudao.module.bpm.enums.definition.BpmUserTaskAssignEmptyHandlerTypeEnum;
 | 
					 | 
				
			||||||
import cn.iocoder.yudao.module.bpm.enums.task.BpmReasonEnum;
 | 
					 | 
				
			||||||
import cn.iocoder.yudao.module.bpm.framework.flowable.core.candidate.BpmTaskCandidateInvoker;
 | 
					import cn.iocoder.yudao.module.bpm.framework.flowable.core.candidate.BpmTaskCandidateInvoker;
 | 
				
			||||||
import cn.iocoder.yudao.module.bpm.framework.flowable.core.util.BpmnModelUtils;
 | 
					 | 
				
			||||||
import cn.iocoder.yudao.module.bpm.service.task.BpmTaskService;
 | 
					 | 
				
			||||||
import lombok.Setter;
 | 
					import lombok.Setter;
 | 
				
			||||||
import lombok.extern.slf4j.Slf4j;
 | 
					import lombok.extern.slf4j.Slf4j;
 | 
				
			||||||
import org.flowable.bpmn.model.UserTask;
 | 
					import org.flowable.bpmn.model.UserTask;
 | 
				
			||||||
@ -22,8 +13,7 @@ import org.flowable.engine.impl.cfg.ProcessEngineConfigurationImpl;
 | 
				
			|||||||
import org.flowable.engine.impl.util.TaskHelper;
 | 
					import org.flowable.engine.impl.util.TaskHelper;
 | 
				
			||||||
import org.flowable.task.service.TaskService;
 | 
					import org.flowable.task.service.TaskService;
 | 
				
			||||||
import org.flowable.task.service.impl.persistence.entity.TaskEntity;
 | 
					import org.flowable.task.service.impl.persistence.entity.TaskEntity;
 | 
				
			||||||
import org.springframework.transaction.support.TransactionSynchronization;
 | 
					import org.springframework.transaction.annotation.Transactional;
 | 
				
			||||||
import org.springframework.transaction.support.TransactionSynchronizationManager;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
import java.util.List;
 | 
					import java.util.List;
 | 
				
			||||||
import java.util.Set;
 | 
					import java.util.Set;
 | 
				
			||||||
@ -46,6 +36,7 @@ public class BpmUserTaskActivityBehavior extends UserTaskActivityBehavior {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @Override
 | 
					    @Override
 | 
				
			||||||
 | 
					    @Transactional(rollbackFor = Exception.class)
 | 
				
			||||||
    protected void handleAssignments(TaskService taskService, String assignee, String owner,
 | 
					    protected void handleAssignments(TaskService taskService, String assignee, String owner,
 | 
				
			||||||
        List<String> candidateUsers, List<String> candidateGroups, TaskEntity task, ExpressionManager expressionManager,
 | 
					        List<String> candidateUsers, List<String> candidateGroups, TaskEntity task, ExpressionManager expressionManager,
 | 
				
			||||||
        DelegateExecution execution, ProcessEngineConfigurationImpl processEngineConfiguration) {
 | 
					        DelegateExecution execution, ProcessEngineConfigurationImpl processEngineConfiguration) {
 | 
				
			||||||
@ -54,39 +45,7 @@ public class BpmUserTaskActivityBehavior extends UserTaskActivityBehavior {
 | 
				
			|||||||
        // 第二步,设置作为负责人
 | 
					        // 第二步,设置作为负责人
 | 
				
			||||||
        if (assigneeUserId != null) {
 | 
					        if (assigneeUserId != null) {
 | 
				
			||||||
            TaskHelper.changeTaskAssignee(task, String.valueOf(assigneeUserId));
 | 
					            TaskHelper.changeTaskAssignee(task, String.valueOf(assigneeUserId));
 | 
				
			||||||
            return;
 | 
					 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					 | 
				
			||||||
        // 特殊:处理需要自动通过、不通过的情况
 | 
					 | 
				
			||||||
        Integer approveType = BpmnModelUtils.parseApproveType(userTask);
 | 
					 | 
				
			||||||
        Integer assignEmptyHandlerType = BpmnModelUtils.parseAssignEmptyHandlerType(userTask);
 | 
					 | 
				
			||||||
        TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronization() {
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            @Override
 | 
					 | 
				
			||||||
            public void afterCommit() {
 | 
					 | 
				
			||||||
                // 特殊情况一:【人工审核】审批人为空,根据配置是否要自动通过、自动拒绝
 | 
					 | 
				
			||||||
                if (ObjectUtil.equal(approveType, BpmUserTaskApproveTypeEnum.USER.getType())) {
 | 
					 | 
				
			||||||
                    if (ObjectUtil.equal(assignEmptyHandlerType, BpmUserTaskAssignEmptyHandlerTypeEnum.APPROVE.getType())) {
 | 
					 | 
				
			||||||
                        SpringUtil.getBean(BpmTaskService.class).approveTask(null, new BpmTaskApproveReqVO()
 | 
					 | 
				
			||||||
                                .setId(task.getId()).setReason(BpmReasonEnum.ASSIGN_EMPTY_APPROVE.getReason()));
 | 
					 | 
				
			||||||
                    } else if (ObjectUtil.equal(assignEmptyHandlerType, BpmUserTaskAssignEmptyHandlerTypeEnum.REJECT.getType())) {
 | 
					 | 
				
			||||||
                        SpringUtil.getBean(BpmTaskService.class).rejectTask(null, new BpmTaskRejectReqVO()
 | 
					 | 
				
			||||||
                                .setId(task.getId()).setReason(BpmReasonEnum.ASSIGN_EMPTY_REJECT.getReason()));
 | 
					 | 
				
			||||||
                    }
 | 
					 | 
				
			||||||
                // 特殊情况二:【自动审核】审批类型为自动通过、不通过
 | 
					 | 
				
			||||||
                } else {
 | 
					 | 
				
			||||||
                    if (ObjectUtil.equal(approveType, BpmUserTaskApproveTypeEnum.AUTO_APPROVE.getType())) {
 | 
					 | 
				
			||||||
                        SpringUtil.getBean(BpmTaskService.class).approveTask(null, new BpmTaskApproveReqVO()
 | 
					 | 
				
			||||||
                                .setId(task.getId()).setReason(BpmReasonEnum.APPROVE_TYPE_AUTO_APPROVE.getReason()));
 | 
					 | 
				
			||||||
                    } else if (ObjectUtil.equal(approveType, BpmUserTaskApproveTypeEnum.AUTO_REJECT.getType())) {
 | 
					 | 
				
			||||||
                        SpringUtil.getBean(BpmTaskService.class).rejectTask(null, new BpmTaskRejectReqVO()
 | 
					 | 
				
			||||||
                                .setId(task.getId()).setReason(BpmReasonEnum.APPROVE_TYPE_AUTO_REJECT.getReason()));
 | 
					 | 
				
			||||||
                    }
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    private Long calculateTaskCandidateUsers(DelegateExecution execution) {
 | 
					    private Long calculateTaskCandidateUsers(DelegateExecution execution) {
 | 
				
			||||||
 | 
				
			|||||||
@ -188,7 +188,12 @@ public interface BpmTaskService {
 | 
				
			|||||||
    // ========== Event 事件相关方法 ==========
 | 
					    // ========== Event 事件相关方法 ==========
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
     * 处理 Task 创建事件,目前是更新它的状态为审批中
 | 
					     * 处理 Task 创建事件,目前是
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * 1. 更新它的状态为审批中
 | 
				
			||||||
 | 
					     * 2. 处理自动通过的情况,例如说:1)无审批人时,是否自动通过、不通过;2)非【人工审核】时,是否自动通过、不通过
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * 注意:它的触发时机,晚于 {@link #processTaskAssigned(Task)} 之后
 | 
				
			||||||
     *
 | 
					     *
 | 
				
			||||||
     * @param task 任务实体
 | 
					     * @param task 任务实体
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
 | 
				
			|||||||
@ -12,9 +12,7 @@ import cn.iocoder.yudao.framework.common.util.object.PageUtils;
 | 
				
			|||||||
import cn.iocoder.yudao.framework.web.core.util.WebFrameworkUtils;
 | 
					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.controller.admin.task.vo.task.*;
 | 
				
			||||||
import cn.iocoder.yudao.module.bpm.convert.task.BpmTaskConvert;
 | 
					import cn.iocoder.yudao.module.bpm.convert.task.BpmTaskConvert;
 | 
				
			||||||
import cn.iocoder.yudao.module.bpm.enums.definition.BpmUserTaskAssignStartUserHandlerTypeEnum;
 | 
					import cn.iocoder.yudao.module.bpm.enums.definition.*;
 | 
				
			||||||
import cn.iocoder.yudao.module.bpm.enums.definition.BpmUserTaskRejectHandlerType;
 | 
					 | 
				
			||||||
import cn.iocoder.yudao.module.bpm.enums.definition.BpmUserTaskTimeoutHandlerTypeEnum;
 | 
					 | 
				
			||||||
import cn.iocoder.yudao.module.bpm.enums.task.BpmCommentTypeEnum;
 | 
					import cn.iocoder.yudao.module.bpm.enums.task.BpmCommentTypeEnum;
 | 
				
			||||||
import cn.iocoder.yudao.module.bpm.enums.task.BpmReasonEnum;
 | 
					import cn.iocoder.yudao.module.bpm.enums.task.BpmReasonEnum;
 | 
				
			||||||
import cn.iocoder.yudao.module.bpm.enums.task.BpmTaskSignTypeEnum;
 | 
					import cn.iocoder.yudao.module.bpm.enums.task.BpmTaskSignTypeEnum;
 | 
				
			||||||
@ -888,12 +886,55 @@ public class BpmTaskServiceImpl implements BpmTaskService {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    @Override
 | 
					    @Override
 | 
				
			||||||
    public void processTaskCreated(Task task) {
 | 
					    public void processTaskCreated(Task task) {
 | 
				
			||||||
 | 
					        // 1. 设置为待办中
 | 
				
			||||||
        Integer status = (Integer) task.getTaskLocalVariables().get(BpmnVariableConstants.TASK_VARIABLE_STATUS);
 | 
					        Integer status = (Integer) task.getTaskLocalVariables().get(BpmnVariableConstants.TASK_VARIABLE_STATUS);
 | 
				
			||||||
        if (status != null) {
 | 
					        if (status != null) {
 | 
				
			||||||
            log.error("[updateTaskStatusWhenCreated][taskId({}) 已经有状态({})]", task.getId(), status);
 | 
					            log.error("[updateTaskStatusWhenCreated][taskId({}) 已经有状态({})]", task.getId(), status);
 | 
				
			||||||
            return;
 | 
					            return;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        updateTaskStatus(task.getId(), BpmTaskStatusEnum.RUNNING.getStatus());
 | 
					        updateTaskStatus(task.getId(), BpmTaskStatusEnum.RUNNING.getStatus());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // 2. 处理自动通过的情况,例如说:1)无审批人时,是否自动通过、不通过;2)非【人工审核】时,是否自动通过、不通过
 | 
				
			||||||
 | 
					        ProcessInstance processInstance = processInstanceService.getProcessInstance(task.getProcessInstanceId());
 | 
				
			||||||
 | 
					        if (processInstance == null) {
 | 
				
			||||||
 | 
					            log.error("[processTaskCreated][taskId({}) 没有找到流程实例]", task.getId());
 | 
				
			||||||
 | 
					            return;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        BpmnModel bpmnModel = modelService.getBpmnModelByDefinitionId(processInstance.getProcessDefinitionId());
 | 
				
			||||||
 | 
					        FlowElement userTaskElement = BpmnModelUtils.getFlowElementById(bpmnModel, task.getTaskDefinitionKey());
 | 
				
			||||||
 | 
					        Integer approveType = BpmnModelUtils.parseApproveType(userTaskElement);
 | 
				
			||||||
 | 
					        Integer assignEmptyHandlerType = BpmnModelUtils.parseAssignEmptyHandlerType(userTaskElement);
 | 
				
			||||||
 | 
					        TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronization() {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            @Override
 | 
				
			||||||
 | 
					            public void afterCompletion(int transactionStatus) {
 | 
				
			||||||
 | 
					                // 特殊情况:部分情况下,TransactionSynchronizationManager 注册 afterCommit 监听时,不会被调用,但是 afterCompletion 可以
 | 
				
			||||||
 | 
					                // 例如说:第一个 task 就是配置【自动通过】或者【自动拒绝】时
 | 
				
			||||||
 | 
					                if (ObjectUtil.notEqual(transactionStatus, TransactionSynchronization.STATUS_COMMITTED)) {
 | 
				
			||||||
 | 
					                    return;
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                // 特殊情况一:【人工审核】审批人为空,根据配置是否要自动通过、自动拒绝
 | 
				
			||||||
 | 
					                if (ObjectUtil.equal(approveType, BpmUserTaskApproveTypeEnum.USER.getType())) {
 | 
				
			||||||
 | 
					                    if (ObjectUtil.equal(assignEmptyHandlerType, BpmUserTaskAssignEmptyHandlerTypeEnum.APPROVE.getType())) {
 | 
				
			||||||
 | 
					                        SpringUtil.getBean(BpmTaskService.class).approveTask(null, new BpmTaskApproveReqVO()
 | 
				
			||||||
 | 
					                                .setId(task.getId()).setReason(BpmReasonEnum.ASSIGN_EMPTY_APPROVE.getReason()));
 | 
				
			||||||
 | 
					                    } else if (ObjectUtil.equal(assignEmptyHandlerType, BpmUserTaskAssignEmptyHandlerTypeEnum.REJECT.getType())) {
 | 
				
			||||||
 | 
					                        SpringUtil.getBean(BpmTaskService.class).rejectTask(null, new BpmTaskRejectReqVO()
 | 
				
			||||||
 | 
					                                .setId(task.getId()).setReason(BpmReasonEnum.ASSIGN_EMPTY_REJECT.getReason()));
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                    // 特殊情况二:【自动审核】审批类型为自动通过、不通过
 | 
				
			||||||
 | 
					                } else {
 | 
				
			||||||
 | 
					                    if (ObjectUtil.equal(approveType, BpmUserTaskApproveTypeEnum.AUTO_APPROVE.getType())) {
 | 
				
			||||||
 | 
					                        SpringUtil.getBean(BpmTaskService.class).approveTask(null, new BpmTaskApproveReqVO()
 | 
				
			||||||
 | 
					                                .setId(task.getId()).setReason(BpmReasonEnum.APPROVE_TYPE_AUTO_APPROVE.getReason()));
 | 
				
			||||||
 | 
					                    } else if (ObjectUtil.equal(approveType, BpmUserTaskApproveTypeEnum.AUTO_REJECT.getType())) {
 | 
				
			||||||
 | 
					                        SpringUtil.getBean(BpmTaskService.class).rejectTask(null, new BpmTaskRejectReqVO()
 | 
				
			||||||
 | 
					                                .setId(task.getId()).setReason(BpmReasonEnum.APPROVE_TYPE_AUTO_REJECT.getReason()));
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user