Commit 91f356fc741a1e17928b326069eda646e61ffc1c

Authored by jason
1 parent 45399687

fix: 自动去重,连续审批自动通过问题修复。https://gitee.com/zhijiantianya/yudao-cloud/issues/IE8CQN

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
... ... @@ -1475,25 +1475,30 @@ public class BpmTaskServiceImpl implements BpmTaskService {
1475 1475 if (processDefinitionInfo.getAutoApprovalType() != null) {
1476 1476 HistoricTaskInstanceQuery sameAssigneeQuery = historyService.createHistoricTaskInstanceQuery()
1477 1477 .processInstanceId(task.getProcessInstanceId())
1478   - .taskAssignee(task.getAssignee()) // 相同审批人
1479 1478 .taskVariableValueEquals(BpmnVariableConstants.TASK_VARIABLE_STATUS, BpmTaskStatusEnum.APPROVE.getStatus())
1480 1479 .finished();
1481 1480 if (BpmAutoApproveTypeEnum.APPROVE_ALL.getType().equals(processDefinitionInfo.getAutoApprovalType())
1482   - && sameAssigneeQuery.count() > 0) {
  1481 + && sameAssigneeQuery.taskAssignee(task.getAssignee()).count() > 0) {
1483 1482 getSelf().approveTask(Long.valueOf(task.getAssignee()), new BpmTaskApproveReqVO().setId(task.getId())
1484 1483 .setReason(BpmAutoApproveTypeEnum.APPROVE_ALL.getName()));
1485 1484 return;
1486 1485 }
  1486 + // 连续审批的节点自动通过
1487 1487 if (BpmAutoApproveTypeEnum.APPROVE_SEQUENT.getType().equals(processDefinitionInfo.getAutoApprovalType())) {
1488 1488 BpmnModel bpmnModel = modelService.getBpmnModelByDefinitionId(processInstance.getProcessDefinitionId());
1489 1489 if (bpmnModel == null) {
1490 1490 log.error("[processTaskAssigned][taskId({}) 没有找到流程模型({})]", task.getId(), task.getProcessDefinitionId());
1491 1491 return;
1492 1492 }
1493   - List<String> sourceTaskIds = convertList(BpmnModelUtils.getElementIncomingFlows( // 获取所有上一个节点
  1493 + List<String> sourceTaskIds = convertList(BpmnModelUtils.getElementIncomingUserTaskFlows( // 获取所有的上一个 UserTask 节点连线
1494 1494 BpmnModelUtils.getFlowElementById(bpmnModel, task.getTaskDefinitionKey())),
1495 1495 SequenceFlow::getSourceRef);
1496   - if (sameAssigneeQuery.taskDefinitionKeys(sourceTaskIds).count() > 0) {
  1496 + // 设置 taskIds, 并按创建时间倒序排序
  1497 + sameAssigneeQuery.taskDefinitionKeys(sourceTaskIds)
  1498 + .orderByTaskCreateTime()
  1499 + .desc();
  1500 + HistoricTaskInstance firstHisTask = CollUtil.getFirst(sameAssigneeQuery.list());
  1501 + if (firstHisTask != null && StrUtil.equals(firstHisTask.getAssignee(), task.getAssignee())) {
1497 1502 getSelf().approveTask(Long.valueOf(task.getAssignee()), new BpmTaskApproveReqVO().setId(task.getId())
1498 1503 .setReason(BpmAutoApproveTypeEnum.APPROVE_SEQUENT.getName()));
1499 1504 return;
... ...