Commit 28aeb8a666f82715f1af61755370fe36a01e7398

Authored by 芋道源码
Committed by Gitee
2 parents 93dadc14 1d463f4f

!1554 fix: 修复回退报错问题, moveExecutionsToSingleActivityId 替换为 moveActivityIdsToS…

Merge pull request !1554 from 芋道源码/master-jdk17-bpm-bug-fix
yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/listener/BpmTaskEventListener.java
... ... @@ -66,8 +66,7 @@ public class BpmTaskEventListener extends AbstractFlowableEngineEventListener {
66 66  
67 67 @Override
68 68 protected void taskAssigned(FlowableEngineEntityEvent event) {
69   - Task entity = (Task) event.getEntity();
70   - FlowableUtils.execute(entity.getTenantId(), () -> taskService.processTaskAssigned(entity));
  69 + taskService.processTaskAssigned((Task) event.getEntity());
71 70 }
72 71  
73 72 @Override
... ...
yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/util/BpmnModelUtils.java
... ... @@ -457,6 +457,52 @@ public class BpmnModelUtils {
457 457 }
458 458  
459 459 /**
  460 + * 根据节点,递归获取上游 source 为 UserTask 的入口连线
  461 + *
  462 + * 1. 如果当前节点的直接入口连线 source 就是 UserTask,则直接返回该连线
  463 + * 2. 如果当前节点的直接入口连线 source 不是 UserTask,则继续向上递归查找
  464 + * 3. 如果递归过程中遇到 StartEvent 或 SubProcess,则停止该分支继续向上查找
  465 + *
  466 + * @param source 起始节点
  467 + * @return 上游连接 UserTask 的入口连线列表
  468 + */
  469 + public static List<SequenceFlow> getElementIncomingUserTaskFlows(FlowElement source) {
  470 + List<SequenceFlow> result = new ArrayList<>();
  471 + collectElementIncomingUserTaskFlows(source, new HashSet<>(), new HashSet<>(), result);
  472 + return result;
  473 + }
  474 +
  475 + private static void collectElementIncomingUserTaskFlows(FlowElement source, Set<String> visitedSequenceFlowIds,
  476 + Set<String> resultSequenceFlowIds, List<SequenceFlow> result) {
  477 + // 如果是开始节点或子流程,则停止该分支向上查找
  478 + if (source == null || source instanceof StartEvent || source instanceof SubProcess) {
  479 + return;
  480 + }
  481 +
  482 + List<SequenceFlow> incomingFlows = getElementIncomingFlows(source);
  483 + if (CollUtil.isEmpty(incomingFlows)) {
  484 + return;
  485 + }
  486 +
  487 + for (SequenceFlow incomingFlow : incomingFlows) {
  488 + // 如果发现连线重复,说明连线已经走过。跳过
  489 + if (incomingFlow == null || !visitedSequenceFlowIds.add(incomingFlow.getId())) {
  490 + continue;
  491 + }
  492 + FlowElement sourceFlowElement = incomingFlow.getSourceFlowElement();
  493 + if (sourceFlowElement instanceof UserTask) {
  494 + if (resultSequenceFlowIds.add(incomingFlow.getId())) {
  495 + result.add(incomingFlow);
  496 + }
  497 + continue;
  498 + }
  499 + // 递归向上查找 UserTask
  500 + collectElementIncomingUserTaskFlows(sourceFlowElement, visitedSequenceFlowIds,
  501 + resultSequenceFlowIds, result);
  502 + }
  503 + }
  504 +
  505 + /**
460 506 * 根据节点,获取出口连线
461 507 *
462 508 * @param source 起始节点
... ...
yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmTaskServiceImpl.java
... ... @@ -618,7 +618,10 @@ public class BpmTaskServiceImpl implements BpmTaskService {
618 618 runtimeService.setVariable(task.getProcessInstanceId(), BpmnVariableConstants.PROCESS_INSTANCE_VARIABLE_NEED_SIMULATE_TASK_IDS, needSimulateTaskIdsByReturn);
619 619 }
620 620  
621   - // 6. 调用 BPM complete 去完成任务
  621 + // 6. 清理退回设置的不自动通过的变量。
  622 + runtimeService.removeVariable(task.getProcessInstanceId(), String.format(BpmnVariableConstants.PROCESS_INSTANCE_VARIABLE_RETURN_FLAG, task.getTaskDefinitionKey()));
  623 +
  624 + // 7. 调用 BPM complete 去完成任务
622 625 taskService.complete(task.getId(), variables, true);
623 626  
624 627 // 【加签专属】处理加签任务
... ... @@ -914,7 +917,7 @@ public class BpmTaskServiceImpl implements BpmTaskService {
914 917 * @param reqVO 前端参数封装
915 918 */
916 919 public void returnTask(Long userId, BpmnModel bpmnModel, Task currentTask, FlowElement targetElement, BpmTaskReturnReqVO reqVO) {
917   - // 1. 获得所有需要回撤的任务 taskDefinitionKey,用于稍后的 moveActivityIdsToSingleActivityId 回撤
  920 + // 1. 获得所有需要回撤的任务 taskDefinitionKey,用于稍后的 moveExecutionsToSingleActivityId 回撤
918 921 // 1.1 获取所有正常进行的任务节点 Key
919 922 List<Task> taskList = taskService.createTaskQuery().processInstanceId(currentTask.getProcessInstanceId()).list();
920 923 List<String> runTaskKeyList = convertList(taskList, Task::getTaskDefinitionKey);
... ... @@ -922,14 +925,16 @@ public class BpmTaskServiceImpl implements BpmTaskService {
922 925 // 为什么不直接使用 runTaskKeyList 呢?因为可能存在多个审批分支,例如说:A -> B -> C 和 D -> F,而只要 C 撤回到 A,需要排除掉 F
923 926 List<UserTask> returnUserTaskList = BpmnModelUtils.iteratorFindChildUserTasks(targetElement, runTaskKeyList, null, null);
924 927 List<String> returnTaskKeyList = convertList(returnUserTaskList, UserTask::getId);
925   -
  928 + List<String> runExecutionIds = new ArrayList<>();
926 929 // 2. 给当前要被退回的 task 数组,设置退回意见
927 930 taskList.forEach(task -> {
928 931 // 需要排除掉,不需要设置退回意见的任务
929 932 if (!returnTaskKeyList.contains(task.getTaskDefinitionKey())) {
930 933 return;
931 934 }
932   -
  935 + if (task.getExecutionId() != null) {
  936 + runExecutionIds.add(task.getExecutionId());
  937 + }
933 938 // 判断是否分配给自己任务,因为会签任务,一个节点会有多个任务
934 939 if (isAssignUserTask(userId, task)) { // 情况一:自己的任务,进行 RETURN 标记
935 940 // 2.1.1 添加评论
... ... @@ -950,14 +955,16 @@ public class BpmTaskServiceImpl implements BpmTaskService {
950 955 // 相关 issue: https://github.com/flowable/flowable-engine/issues/3944
951 956 // ② flowable 7.2.0 版本后,继续使用 moveActivityIdsToSingleActivityId 方法。原因:flowable 7.2.0 版本修复了该问题。
952 957 // 相关 issue:https://github.com/YunaiV/ruoyi-vue-pro/issues/1018
  958 + // ③ moveActivityIdsToSingleActivityId 使用遇到问题, 相关 issue https://gitee.com/zhijiantianya/yudao-cloud/issues/IJM8MS
  959 + // 改成 moveExecutionsToSingleActivityId 好像并没有遇到 ② 提到的超时提醒失效的问题。暂时先改回 moveExecutionsToSingleActivityId
  960 + // 目前还有的相关问题 https://t.zsxq.com/z4d9i。 估计需要升级 flowable 8 版本试试
953 961 runtimeService.createChangeActivityStateBuilder()
954 962 .processInstanceId(currentTask.getProcessInstanceId())
955   - .moveActivityIdsToSingleActivityId(returnTaskKeyList, reqVO.getTargetTaskDefinitionKey())
  963 + .moveExecutionsToSingleActivityId(runExecutionIds, reqVO.getTargetTaskDefinitionKey())
956 964 // 设置需要预测的任务 ids 的流程变量,用于辅助预测
957 965 .processVariable(BpmnVariableConstants.PROCESS_INSTANCE_VARIABLE_NEED_SIMULATE_TASK_IDS, needSimulateTaskDefinitionKeys)
958   - // 设置流程变量(local)节点退回标记, 用于退回到节点,不执行 BpmUserTaskAssignStartUserHandlerTypeEnum 策略,导致自动通过
959   - .localVariable(reqVO.getTargetTaskDefinitionKey(),
960   - String.format(BpmnVariableConstants.PROCESS_INSTANCE_VARIABLE_RETURN_FLAG, reqVO.getTargetTaskDefinitionKey()), Boolean.TRUE)
  966 + // 设置流程变量节点退回标记, 用于退回到节点,不执行 BpmUserTaskAssignStartUserHandlerTypeEnum 策略,导致自动通过
  967 + .processVariable(String.format(BpmnVariableConstants.PROCESS_INSTANCE_VARIABLE_RETURN_FLAG, reqVO.getTargetTaskDefinitionKey()), Boolean.TRUE)
961 968 .changeState();
962 969 }
963 970  
... ... @@ -1463,102 +1470,107 @@ public class BpmTaskServiceImpl implements BpmTaskService {
1463 1470 log.error("[processTaskAssigned][taskId({}) 没有找到流程实例]", task.getId());
1464 1471 return;
1465 1472 }
1466   -
1467   - // 自动去重,通过自动审批的方式
1468   - BpmProcessDefinitionInfoDO processDefinitionInfo = bpmProcessDefinitionService.getProcessDefinitionInfo(task.getProcessDefinitionId());
1469   - if (processDefinitionInfo == null) {
1470   - log.error("[processTaskAssigned][taskId({}) 没有找到流程定义({})]", task.getId(), task.getProcessDefinitionId());
1471   - return;
1472   - }
1473   - if (processDefinitionInfo.getAutoApprovalType() != null) {
1474   - HistoricTaskInstanceQuery sameAssigneeQuery = historyService.createHistoricTaskInstanceQuery()
1475   - .processInstanceId(task.getProcessInstanceId())
1476   - .taskAssignee(task.getAssignee()) // 相同审批人
1477   - .taskVariableValueEquals(BpmnVariableConstants.TASK_VARIABLE_STATUS, BpmTaskStatusEnum.APPROVE.getStatus())
1478   - .finished();
1479   - if (BpmAutoApproveTypeEnum.APPROVE_ALL.getType().equals(processDefinitionInfo.getAutoApprovalType())
1480   - && sameAssigneeQuery.count() > 0) {
1481   - getSelf().approveTask(Long.valueOf(task.getAssignee()), new BpmTaskApproveReqVO().setId(task.getId())
1482   - .setReason(BpmAutoApproveTypeEnum.APPROVE_ALL.getName()));
  1473 + // 需要基于 instance 设置租户编号,避免 Flowable 内部异步执行时【例如:超时自动通过】 丢失租户编号
  1474 + FlowableUtils.execute(processInstance.getTenantId(), () -> {
  1475 + // 自动去重,通过自动审批的方式
  1476 + BpmProcessDefinitionInfoDO processDefinitionInfo = bpmProcessDefinitionService.getProcessDefinitionInfo(task.getProcessDefinitionId());
  1477 + if (processDefinitionInfo == null) {
  1478 + log.error("[processTaskAssigned][taskId({}) 没有找到流程定义({})]", task.getId(), task.getProcessDefinitionId());
1483 1479 return;
1484 1480 }
1485   - if (BpmAutoApproveTypeEnum.APPROVE_SEQUENT.getType().equals(processDefinitionInfo.getAutoApprovalType())) {
1486   - BpmnModel bpmnModel = modelService.getBpmnModelByDefinitionId(processInstance.getProcessDefinitionId());
1487   - if (bpmnModel == null) {
1488   - log.error("[processTaskAssigned][taskId({}) 没有找到流程模型({})]", task.getId(), task.getProcessDefinitionId());
1489   - return;
1490   - }
1491   - List<String> sourceTaskIds = convertList(BpmnModelUtils.getElementIncomingFlows( // 获取所有上一个节点
1492   - BpmnModelUtils.getFlowElementById(bpmnModel, task.getTaskDefinitionKey())),
1493   - SequenceFlow::getSourceRef);
1494   - if (sameAssigneeQuery.taskDefinitionKeys(sourceTaskIds).count() > 0) {
  1481 + if (processDefinitionInfo.getAutoApprovalType() != null) {
  1482 + HistoricTaskInstanceQuery sameAssigneeQuery = historyService.createHistoricTaskInstanceQuery()
  1483 + .processInstanceId(task.getProcessInstanceId())
  1484 + .taskVariableValueEquals(BpmnVariableConstants.TASK_VARIABLE_STATUS, BpmTaskStatusEnum.APPROVE.getStatus())
  1485 + .finished();
  1486 + if (BpmAutoApproveTypeEnum.APPROVE_ALL.getType().equals(processDefinitionInfo.getAutoApprovalType())
  1487 + && sameAssigneeQuery.taskAssignee(task.getAssignee()).count() > 0) {
1495 1488 getSelf().approveTask(Long.valueOf(task.getAssignee()), new BpmTaskApproveReqVO().setId(task.getId())
1496   - .setReason(BpmAutoApproveTypeEnum.APPROVE_SEQUENT.getName()));
  1489 + .setReason(BpmAutoApproveTypeEnum.APPROVE_ALL.getName()));
1497 1490 return;
1498 1491 }
  1492 + // 连续审批的节点自动通过
  1493 + if (BpmAutoApproveTypeEnum.APPROVE_SEQUENT.getType().equals(processDefinitionInfo.getAutoApprovalType())) {
  1494 + BpmnModel bpmnModel = modelService.getBpmnModelByDefinitionId(processInstance.getProcessDefinitionId());
  1495 + if (bpmnModel == null) {
  1496 + log.error("[processTaskAssigned][taskId({}) 没有找到流程模型({})]", task.getId(), task.getProcessDefinitionId());
  1497 + return;
  1498 + }
  1499 + List<String> sourceTaskIds = convertList(BpmnModelUtils.getElementIncomingUserTaskFlows( // 获取所有的上一个 UserTask 节点连线
  1500 + BpmnModelUtils.getFlowElementById(bpmnModel, task.getTaskDefinitionKey())),
  1501 + SequenceFlow::getSourceRef);
  1502 + // 设置 taskIds, 并按创建时间倒序排序
  1503 + sameAssigneeQuery.taskDefinitionKeys(sourceTaskIds)
  1504 + .orderByTaskCreateTime()
  1505 + .desc();
  1506 + HistoricTaskInstance firstHisTask = CollUtil.getFirst(sameAssigneeQuery.list());
  1507 + if (firstHisTask != null && StrUtil.equals(firstHisTask.getAssignee(), task.getAssignee())) {
  1508 + getSelf().approveTask(Long.valueOf(task.getAssignee()), new BpmTaskApproveReqVO().setId(task.getId())
  1509 + .setReason(BpmAutoApproveTypeEnum.APPROVE_SEQUENT.getName()));
  1510 + return;
  1511 + }
  1512 + }
1499 1513 }
1500   - }
1501 1514  
1502   - // 获取发起人节点
1503   - BpmnModel bpmnModel = modelService.getBpmnModelByDefinitionId(processInstance.getProcessDefinitionId());
1504   - if (bpmnModel == null) {
1505   - log.error("[processTaskAssigned][taskId({}) 没有找到流程模型]", task.getId());
1506   - return;
1507   - }
1508   - FlowElement userTaskElement = BpmnModelUtils.getFlowElementById(bpmnModel, task.getTaskDefinitionKey());
1509   - // 判断是否为退回或者驳回:如果是退回或者驳回不走这个策略(使用 local variable)
1510   - Boolean returnTaskFlag = runtimeService.getVariableLocal(task.getExecutionId(),
1511   - String.format(BpmnVariableConstants.PROCESS_INSTANCE_VARIABLE_RETURN_FLAG, task.getTaskDefinitionKey()), Boolean.class);
1512   - Boolean skipStartUserNodeFlag = Convert.toBool(runtimeService.getVariable(processInstance.getProcessInstanceId(),
1513   - BpmnVariableConstants.PROCESS_INSTANCE_VARIABLE_SKIP_START_USER_NODE, String.class));
1514   - if (userTaskElement.getId().equals(START_USER_NODE_ID)
1515   - && (skipStartUserNodeFlag == null // 目的:一般是“主流程”,发起人节点,自动通过审核
1516   - || BooleanUtil.isTrue(skipStartUserNodeFlag)) // 目的:一般是“子流程”,发起人节点,按配置自动通过审核
1517   - && ObjUtil.notEqual(returnTaskFlag, Boolean.TRUE)) {
1518   - getSelf().approveTask(Long.valueOf(task.getAssignee()), new BpmTaskApproveReqVO().setId(task.getId())
1519   - .setReason(BpmReasonEnum.ASSIGN_START_USER_APPROVE_WHEN_SKIP_START_USER_NODE.getReason()));
1520   - return;
1521   - }
1522   - // 当不为发起人节点时,审批人与提交人为同一人时,根据 BpmUserTaskAssignStartUserHandlerTypeEnum 策略进行处理
1523   - if (ObjectUtil.notEqual(userTaskElement.getId(), START_USER_NODE_ID)
1524   - && StrUtil.equals(task.getAssignee(), processInstance.getStartUserId())) {
1525   - if (ObjUtil.notEqual(returnTaskFlag, Boolean.TRUE)) {
1526   - Integer assignStartUserHandlerType = BpmnModelUtils.parseAssignStartUserHandlerType(userTaskElement);
1527   -
1528   - // 情况一:自动跳过
1529   - if (ObjectUtils.equalsAny(assignStartUserHandlerType,
1530   - BpmUserTaskAssignStartUserHandlerTypeEnum.SKIP.getType())) {
1531   - getSelf().approveTask(Long.valueOf(task.getAssignee()), new BpmTaskApproveReqVO().setId(task.getId())
1532   - .setReason(BpmReasonEnum.ASSIGN_START_USER_APPROVE_WHEN_SKIP.getReason()));
1533   - return;
1534   - }
1535   - // 情况二:转交给部门负责人审批
1536   - if (ObjectUtils.equalsAny(assignStartUserHandlerType,
1537   - BpmUserTaskAssignStartUserHandlerTypeEnum.TRANSFER_DEPT_LEADER.getType())) {
1538   - AdminUserRespDTO startUser = adminUserApi.getUser(Long.valueOf(processInstance.getStartUserId()));
1539   - Assert.notNull(startUser, "提交人({})信息为空", processInstance.getStartUserId());
1540   - DeptRespDTO dept = startUser.getDeptId() != null ? deptApi.getDept(startUser.getDeptId()) : null;
1541   - Assert.notNull(dept, "提交人({})部门({})信息为空", processInstance.getStartUserId(), startUser.getDeptId());
1542   - // 找不到部门负责人的情况下,自动审批通过
1543   - // noinspection DataFlowIssue
1544   - if (dept.getLeaderUserId() == null) {
  1515 + // 获取发起人节点
  1516 + BpmnModel bpmnModel = modelService.getBpmnModelByDefinitionId(processInstance.getProcessDefinitionId());
  1517 + if (bpmnModel == null) {
  1518 + log.error("[processTaskAssigned][taskId({}) 没有找到流程模型]", task.getId());
  1519 + return;
  1520 + }
  1521 + FlowElement userTaskElement = BpmnModelUtils.getFlowElementById(bpmnModel, task.getTaskDefinitionKey());
  1522 + // 判断是否为退回或者驳回:如果是退回或者驳回不走这个策略
  1523 + Boolean returnTaskFlag = runtimeService.getVariable(processInstance.getProcessInstanceId(),
  1524 + String.format(BpmnVariableConstants.PROCESS_INSTANCE_VARIABLE_RETURN_FLAG, task.getTaskDefinitionKey()), Boolean.class);
  1525 + Boolean skipStartUserNodeFlag = Convert.toBool(runtimeService.getVariable(processInstance.getProcessInstanceId(),
  1526 + BpmnVariableConstants.PROCESS_INSTANCE_VARIABLE_SKIP_START_USER_NODE, String.class));
  1527 + if (userTaskElement.getId().equals(START_USER_NODE_ID)
  1528 + && (skipStartUserNodeFlag == null // 目的:一般是“主流程”,发起人节点,自动通过审核
  1529 + || BooleanUtil.isTrue(skipStartUserNodeFlag)) // 目的:一般是“子流程”,发起人节点,按配置自动通过审核
  1530 + && ObjUtil.notEqual(returnTaskFlag, Boolean.TRUE)) {
  1531 + getSelf().approveTask(Long.valueOf(task.getAssignee()), new BpmTaskApproveReqVO().setId(task.getId())
  1532 + .setReason(BpmReasonEnum.ASSIGN_START_USER_APPROVE_WHEN_SKIP_START_USER_NODE.getReason()));
  1533 + return;
  1534 + }
  1535 + // 当不为发起人节点时,审批人与提交人为同一人时,根据 BpmUserTaskAssignStartUserHandlerTypeEnum 策略进行处理
  1536 + if (ObjectUtil.notEqual(userTaskElement.getId(), START_USER_NODE_ID)
  1537 + && StrUtil.equals(task.getAssignee(), processInstance.getStartUserId())) {
  1538 + if (ObjUtil.notEqual(returnTaskFlag, Boolean.TRUE)) {
  1539 + Integer assignStartUserHandlerType = BpmnModelUtils.parseAssignStartUserHandlerType(userTaskElement);
  1540 +
  1541 + // 情况一:自动跳过
  1542 + if (ObjectUtils.equalsAny(assignStartUserHandlerType,
  1543 + BpmUserTaskAssignStartUserHandlerTypeEnum.SKIP.getType())) {
1545 1544 getSelf().approveTask(Long.valueOf(task.getAssignee()), new BpmTaskApproveReqVO().setId(task.getId())
1546   - .setReason(BpmReasonEnum.ASSIGN_START_USER_APPROVE_WHEN_DEPT_LEADER_NOT_FOUND.getReason()));
  1545 + .setReason(BpmReasonEnum.ASSIGN_START_USER_APPROVE_WHEN_SKIP.getReason()));
1547 1546 return;
1548 1547 }
1549   - // 找得到部门负责人的情况下,修改负责人
1550   - if (ObjectUtil.notEqual(dept.getLeaderUserId(), startUser.getId())) {
1551   - getSelf().transferTask(Long.valueOf(task.getAssignee()), new BpmTaskTransferReqVO()
1552   - .setId(task.getId()).setAssigneeUserId(dept.getLeaderUserId())
1553   - .setReason(BpmReasonEnum.ASSIGN_START_USER_TRANSFER_DEPT_LEADER.getReason()));
1554   - return;
  1548 + // 情况二:转交给部门负责人审批
  1549 + if (ObjectUtils.equalsAny(assignStartUserHandlerType,
  1550 + BpmUserTaskAssignStartUserHandlerTypeEnum.TRANSFER_DEPT_LEADER.getType())) {
  1551 + AdminUserRespDTO startUser = adminUserApi.getUser(Long.valueOf(processInstance.getStartUserId()));
  1552 + Assert.notNull(startUser, "提交人({})信息为空", processInstance.getStartUserId());
  1553 + DeptRespDTO dept = startUser.getDeptId() != null ? deptApi.getDept(startUser.getDeptId()) : null;
  1554 + Assert.notNull(dept, "提交人({})部门({})信息为空", processInstance.getStartUserId(), startUser.getDeptId());
  1555 + // 找不到部门负责人的情况下,自动审批通过
  1556 + // noinspection DataFlowIssue
  1557 + if (dept.getLeaderUserId() == null) {
  1558 + getSelf().approveTask(Long.valueOf(task.getAssignee()), new BpmTaskApproveReqVO().setId(task.getId())
  1559 + .setReason(BpmReasonEnum.ASSIGN_START_USER_APPROVE_WHEN_DEPT_LEADER_NOT_FOUND.getReason()));
  1560 + return;
  1561 + }
  1562 + // 找得到部门负责人的情况下,修改负责人
  1563 + if (ObjectUtil.notEqual(dept.getLeaderUserId(), startUser.getId())) {
  1564 + getSelf().transferTask(Long.valueOf(task.getAssignee()), new BpmTaskTransferReqVO()
  1565 + .setId(task.getId()).setAssigneeUserId(dept.getLeaderUserId())
  1566 + .setReason(BpmReasonEnum.ASSIGN_START_USER_TRANSFER_DEPT_LEADER.getReason()));
  1567 + return;
  1568 + }
  1569 + // 如果部门负责人是自己,还是自己审批吧~
1555 1570 }
1556   - // 如果部门负责人是自己,还是自己审批吧~
1557 1571 }
1558 1572 }
1559   - }
1560   - // 注意:需要基于 instance 设置租户编号,避免 Flowable 内部异步时,丢失租户编号
1561   - FlowableUtils.execute(processInstance.getTenantId(), () -> {
  1573 +
1562 1574 AdminUserRespDTO startUser = adminUserApi.getUser(Long.valueOf(processInstance.getStartUserId()));
1563 1575 messageService.sendMessageWhenTaskAssigned(BpmTaskConvert.INSTANCE.convert(processInstance, startUser, task));
1564 1576 });
... ...