ソースを参照

【功能修复】工作流:延迟器 trigger 时,租户 id 丢失的问题

YunaiV 7 ヶ月 前
コミット
e380bc34f3

+ 32 - 27
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/candidate/BpmTaskCandidateInvoker.java

@@ -12,6 +12,7 @@ import cn.iocoder.yudao.module.bpm.enums.definition.BpmUserTaskApproveTypeEnum;
 import cn.iocoder.yudao.module.bpm.enums.definition.BpmUserTaskAssignStartUserHandlerTypeEnum;
 import cn.iocoder.yudao.module.bpm.framework.flowable.core.enums.BpmTaskCandidateStrategyEnum;
 import cn.iocoder.yudao.module.bpm.framework.flowable.core.util.BpmnModelUtils;
+import cn.iocoder.yudao.module.bpm.framework.flowable.core.util.FlowableUtils;
 import cn.iocoder.yudao.module.bpm.service.task.BpmProcessInstanceService;
 import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
 import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
@@ -91,35 +92,39 @@ public class BpmTaskCandidateInvoker {
      */
     @DataPermission(enable = false) // 忽略数据权限,避免因为过滤,导致找不到候选人
     public Set<Long> calculateUsersByTask(DelegateExecution execution) {
-        // 审批类型非人工审核时,不进行计算候选人。原因是:后续会自动通过、不通过
-        FlowElement flowElement = execution.getCurrentFlowElement();
-        Integer approveType = BpmnModelUtils.parseApproveType(flowElement);
-        if (ObjectUtils.equalsAny(approveType,
-                BpmUserTaskApproveTypeEnum.AUTO_APPROVE.getType(),
-                BpmUserTaskApproveTypeEnum.AUTO_REJECT.getType())) {
-            return new HashSet<>();
-        }
-
-        // 1.1 计算任务的候选人
-        Integer strategy = BpmnModelUtils.parseCandidateStrategy(flowElement);
-        String param = BpmnModelUtils.parseCandidateParam(flowElement);
-        Set<Long> userIds = getCandidateStrategy(strategy).calculateUsersByTask(execution, param);
-        // 1.2 移除被禁用的用户
-        removeDisableUsers(userIds);
+        // 注意:解决极端情况下,Flowable 异步调用,导致租户 id 丢失的情况
+        // 例如说,SIMPLE 延迟器在 trigger 的时候!!!
+        return FlowableUtils.execute(execution.getTenantId(), () -> {
+            // 审批类型非人工审核时,不进行计算候选人。原因是:后续会自动通过、不通过
+            FlowElement flowElement = execution.getCurrentFlowElement();
+            Integer approveType = BpmnModelUtils.parseApproveType(flowElement);
+            if (ObjectUtils.equalsAny(approveType,
+                    BpmUserTaskApproveTypeEnum.AUTO_APPROVE.getType(),
+                    BpmUserTaskApproveTypeEnum.AUTO_REJECT.getType())) {
+                return new HashSet<>();
+            }
 
-        // 2. 候选人为空时,根据“审批人为空”的配置补充
-        if (CollUtil.isEmpty(userIds)) {
-            userIds = getCandidateStrategy(BpmTaskCandidateStrategyEnum.ASSIGN_EMPTY.getStrategy())
-                    .calculateUsersByTask(execution, param);
-            // ASSIGN_EMPTY 策略,不需要移除被禁用的用户。原因是,再移除,可能会出现更没审批人了!!!
-        }
+            // 1.1 计算任务的候选人
+            Integer strategy = BpmnModelUtils.parseCandidateStrategy(flowElement);
+            String param = BpmnModelUtils.parseCandidateParam(flowElement);
+            Set<Long> userIds = getCandidateStrategy(strategy).calculateUsersByTask(execution, param);
+            // 1.2 移除被禁用的用户
+            removeDisableUsers(userIds);
+
+            // 2. 候选人为空时,根据“审批人为空”的配置补充
+            if (CollUtil.isEmpty(userIds)) {
+                userIds = getCandidateStrategy(BpmTaskCandidateStrategyEnum.ASSIGN_EMPTY.getStrategy())
+                        .calculateUsersByTask(execution, param);
+                // ASSIGN_EMPTY 策略,不需要移除被禁用的用户。原因是,再移除,可能会出现更没审批人了!!!
+            }
 
-        // 3. 移除发起人的用户
-        ProcessInstance processInstance = SpringUtil.getBean(BpmProcessInstanceService.class)
-                .getProcessInstance(execution.getProcessInstanceId());
-        Assert.notNull(processInstance, "流程实例({}) 不存在", execution.getProcessInstanceId());
-        removeStartUserIfSkip(userIds, flowElement, Long.valueOf(processInstance.getStartUserId()));
-        return userIds;
+            // 3. 移除发起人的用户
+            ProcessInstance processInstance = SpringUtil.getBean(BpmProcessInstanceService.class)
+                    .getProcessInstance(execution.getProcessInstanceId());
+            Assert.notNull(processInstance, "流程实例({}) 不存在", execution.getProcessInstanceId());
+            removeStartUserIfSkip(userIds, flowElement, Long.valueOf(processInstance.getStartUserId()));
+            return userIds;
+        });
     }
 
     public Set<Long> calculateUsersByActivity(BpmnModel bpmnModel, String activityId,

+ 1 - 2
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/util/SimpleModelUtils.java

@@ -628,8 +628,7 @@ public class SimpleModelUtils {
                 TimerEventDefinition eventDefinition = new TimerEventDefinition();
                 if (node.getDelaySetting().getDelayType().equals(BpmDelayTimerType.FIXED_DATE_TIME.getType())){
                     eventDefinition.setTimeDuration(node.getDelaySetting().getDelayTime());
-                }
-                if (node.getDelaySetting().getDelayType().equals(BpmDelayTimerType.FIXED_TIME_DURATION.getType())){
+                } else if (node.getDelaySetting().getDelayType().equals(BpmDelayTimerType.FIXED_TIME_DURATION.getType())){
                     eventDefinition.setTimeDate(node.getDelaySetting().getDelayTime());
                 }
                 boundaryEvent.addEventDefinition(eventDefinition);

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

@@ -1246,15 +1246,14 @@ public class BpmTaskServiceImpl implements BpmTaskService {
                 .activityId(taskDefineKey)
                 .singleResult();
         if (execution == null) {
-            log.error("[processDelayTimerTimeout][processInstanceId({})activityId({}) 没有找到执行活动]",
+            log.error("[processDelayTimerTimeout][processInstanceId({}) activityId({}) 没有找到执行活动]",
                     processInstanceId, taskDefineKey);
             return;
         }
+
         // 若存在直接触发接收任务,执行后续节点
-        // TODO @芋艿 这里需要帮助看一下,我不懂为啥开启了租户后就一直报错:不存在租户编号
-        FlowableUtils.execute(execution.getTenantId(), () -> {
-            runtimeService.trigger(execution.getId());
-        });
+        FlowableUtils.execute(execution.getTenantId(),
+                () -> runtimeService.trigger(execution.getId()));
     }
 
     /**