Commit 0b649fd3e1c7f178bf5c0cbdadc584628a6b7ffc

Authored by YunaiV
1 parent 38268463

bpm:简化获得可回退节点的实现

yudao-framework/yudao-spring-boot-starter-flowable/src/main/java/cn/iocoder/yudao/framework/flowable/core/util/ModelUtils.java
1 1 package cn.iocoder.yudao.framework.flowable.core.util;
2 2  
3   -import cn.hutool.core.util.ObjectUtil;
4   -import cn.hutool.core.util.StrUtil;
5   -import org.flowable.bpmn.converter.BpmnXMLConverter;
6 3 import org.flowable.bpmn.model.Process;
7 4 import org.flowable.bpmn.model.*;
8   -import org.flowable.common.engine.impl.util.io.StringStreamSource;
9 5  
10   -import java.util.*;
  6 +import java.util.ArrayList;
  7 +import java.util.HashSet;
  8 +import java.util.List;
  9 +import java.util.Set;
11 10  
12 11 /**
13 12 * 流程模型转操作工具类
... ... @@ -56,7 +55,6 @@ public class ModelUtils {
56 55 return process.getFlowElement(flowElementId);
57 56 }
58 57  
59   -
60 58 /**
61 59 * 找到 source 节点之前的所有用户任务节点
62 60 *
... ...
yudao-module-bpm/yudao-module-bpm-api/src/main/java/cn/iocoder/yudao/module/bpm/enums/ErrorCodeConstants.java
... ... @@ -47,9 +47,10 @@ public interface ErrorCodeConstants {
47 47 ErrorCode TASK_COMPLETE_FAIL_ASSIGN_NOT_SELF = new ErrorCode(1_009_005_001, "审批任务失败,原因:该任务的审批人不是你");
48 48 ErrorCode TASK_NOT_EXISTS = new ErrorCode(1_009_005_002, "流程任务不存在");
49 49 ErrorCode TASK_IS_PENDING = new ErrorCode(1_009_005_003, "当前任务处于挂起状态,不能操作");
50   - ErrorCode TASK_SOURCE_TARGET_ERROR = new ErrorCode(1_009_005_004, "目标节点是在并行网关上或非同一路线上,不可跳转");
51   - ErrorCode TASK_TARGET_NODE_NOT_EXISTS = new ErrorCode(1_009_005_005, " 目标节点不存在");
52   - ErrorCode TASK_RETURN_FAIL = new ErrorCode(1_009_005_006, "回退任务失败,选择回退的节点没有需要回滚的任务!请重新选择其他任务节点");
  50 + ErrorCode TASK_TARGET_NODE_NOT_EXISTS = new ErrorCode(1_009_005_004, " 目标节点不存在");
  51 + ErrorCode TASK_RETURN_FAIL_NO_RETURN_TASK = new ErrorCode(1_009_005_005, "回退任务失败,选择回退的节点没有需要回滚的任务!请重新选择其他任务节点");
  52 + ErrorCode TASK_RETURN_FAIL_SOURCE_TARGET_ERROR = new ErrorCode(1_009_005_006, "回退任务失败,目标节点是在并行网关上或非同一路线上,不可跳转");
  53 +
53 54 // ========== 流程任务分配规则 1-009-006-000 ==========
54 55 ErrorCode TASK_ASSIGN_RULE_EXISTS = new ErrorCode(1_009_006_000, "流程({}) 的任务({}) 已经存在分配规则");
55 56 ErrorCode TASK_ASSIGN_RULE_NOT_EXISTS = new ErrorCode(1_009_006_001, "流程任务分配规则不存在");
... ...
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/task/BpmTaskReturnReqVO.java
... ... @@ -14,10 +14,10 @@ public class BpmTaskReturnReqVO {
14 14 private String id;
15 15  
16 16 @Schema(description = "回退到的任务 Key", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
17   - @NotEmpty(message = "回退到的任务Key不能为空")
  17 + @NotEmpty(message = "回退到的任务 Key 不能为空")
18 18 private String targetDefinitionKey;
19 19  
20   - @Schema(description = "回退意见", example = "")
  20 + @Schema(description = "回退意见", example = "我就是想驳回")
21 21 private String reason;
22 22  
23 23 }
... ...
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/task/BpmTaskSimpleRespVO.java
... ... @@ -3,10 +3,7 @@ package cn.iocoder.yudao.module.bpm.controller.admin.task.vo.task;
3 3 import io.swagger.v3.oas.annotations.media.Schema;
4 4 import lombok.Data;
5 5  
6   -/**
7   - *
8   - */
9   -@Schema(description = "管理后台 - 流程任务的 可回退的节点 Response VO")
  6 +@Schema(description = "管理后台 - 流程任务的精简 Response VO")
10 7 @Data
11 8 public class BpmTaskSimpleRespVO {
12 9  
... ... @@ -15,4 +12,5 @@ public class BpmTaskSimpleRespVO {
15 12  
16 13 @Schema(description = "任务名词", requiredMode = Schema.RequiredMode.REQUIRED, example = "经理审批")
17 14 private String name;
  15 +
18 16 }
... ...
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/convert/task/BpmTaskConvert.java
... ... @@ -140,8 +140,7 @@ public interface BpmTaskConvert {
140 140 return reqDTO;
141 141 }
142 142  
143   - @Mapping(source = "taskDefinitionKey", target = "id")
144   - default List<BpmTaskSimpleRespVO> convertList(List<FlowElement> elementList) {
  143 + default List<BpmTaskSimpleRespVO> convertList(List<? extends FlowElement> elementList) {
145 144 return CollectionUtils.convertList(elementList, element -> new BpmTaskSimpleRespVO()
146 145 .setName(element.getName())
147 146 .setDefinitionKey(element.getId()));
... ...
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmTaskService.java
... ... @@ -125,7 +125,7 @@ public interface BpmTaskService {
125 125 /**
126 126 * 获取当前任务的可回退的流程集合
127 127 *
128   - * @param taskId 当前的任务ID
  128 + * @param taskId 当前的任务 ID
129 129 * @return 可以回退的节点列表
130 130 */
131 131 List<BpmTaskSimpleRespVO> getReturnTaskList(String taskId);
... ...
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmTaskServiceImpl.java
... ... @@ -327,49 +327,25 @@ public class BpmTaskServiceImpl implements BpmTaskService {
327 327  
328 328 @Override
329 329 public List<BpmTaskSimpleRespVO> getReturnTaskList(String taskId) {
330   - // 当前任务 task
  330 + // 1. 校验当前任务 task 存在
331 331 Task task = getTask(taskId);
332   - if (null == task) {
  332 + if (task == null) {
333 333 throw exception(TASK_NOT_EXISTS);
334 334 }
335   - // 根据流程定义获取流程模型信息
336 335 BpmnModel bpmnModel = bpmModelService.getBpmnModelByDefinitionId(task.getProcessDefinitionId());
337   - // 查询该任务的前置任务节点的key集合
338   - Set<String> historyTaksDefinitionKeySet = getPreTaskByCurrentTask(task, bpmnModel);
339   - if (CollUtil.isEmpty(historyTaksDefinitionKeySet)) {
340   - return Collections.emptyList();
341   - }
342   - // 获取当前任务节点元素
343 336 FlowElement source = ModelUtils.getFlowElementById(bpmnModel, task.getTaskDefinitionKey());
344   - List<FlowElement> elementList = new ArrayList<>();
345   - for (String activityId : historyTaksDefinitionKeySet) {
346   - FlowElement target = ModelUtils.getFlowElementById(bpmnModel, activityId);
347   - //非 串行和子流程则加入返回节点 elementList
348   - boolean isSequential = ModelUtils.isSequentialReachable(source, target, new HashSet<>());
349   - if (isSequential) {
350   - elementList.add(target);
351   - }
  337 + if (source == null) {
  338 + throw exception(TASK_NOT_EXISTS);
352 339 }
353   - return BpmTaskConvert.INSTANCE.convertList(elementList);
354   - }
355 340  
356   - /**
357   - * 查询当前流程实例符合条件可回退的 taskDefinitionKey 集合
358   - *
359   - * @param task 当前任务
360   - * @param bpmnModel 当前流程定义对应的流程模型
361   - * @return 符合条件的已去重的 taskDefinitionKey集合
362   - */
363   - private Set<String> getPreTaskByCurrentTask(Task task, BpmnModel bpmnModel) {
364   - // 获取当前任务节点元素
365   - FlowElement source = ModelUtils.getFlowElementById(bpmnModel, task.getTaskDefinitionKey());
366   - //拿到当前任务节点的前置节点集合
367   - List<UserTask> preUserTaskList = ModelUtils.getPreUserTaskList(source, null, null);
368   - //需要保证这些节点都是在该source节点之前的
369   - if (CollUtil.isNotEmpty(preUserTaskList)) {
370   - return convertSet(preUserTaskList, UserTask::getId);
  341 + // 2.1 查询该任务的前置任务节点的 key 集合
  342 + List<UserTask> previousUserList = ModelUtils.getPreUserTaskList(source, null, null);
  343 + if (CollUtil.isEmpty(previousUserList)) {
  344 + return Collections.emptyList();
371 345 }
372   - return Collections.emptySet();
  346 + // 2.2 过滤:只有串行可到达的节点,才可以回退。类似非串行、子流程无法退回
  347 + previousUserList.removeIf(userTask -> ModelUtils.isSequentialReachable(source, userTask, null));
  348 + return BpmTaskConvert.INSTANCE.convertList(previousUserList);
373 349 }
374 350  
375 351 @Transactional(rollbackFor = Exception.class)
... ... @@ -426,7 +402,7 @@ public class BpmTaskServiceImpl implements BpmTaskService {
426 402 // 从当前节点向前扫描,判断当前节点与目标节点是否属于串行,若目标节点是在并行网关上或非同一路线上,不可跳转
427 403 boolean isSequential = ModelUtils.isSequentialReachable(source, target, new HashSet<>());
428 404 if (!isSequential) {
429   - throw exception(TASK_SOURCE_TARGET_ERROR);
  405 + throw exception(TASK_RETURN_FAIL_SOURCE_TARGET_ERROR);
430 406 }
431 407 return target;
432 408 }
... ... @@ -455,7 +431,7 @@ public class BpmTaskServiceImpl implements BpmTaskService {
455 431 }
456 432 }));
457 433 if (CollUtil.isEmpty(currentTaskIds)) {
458   - throw exception(TASK_RETURN_FAIL);
  434 + throw exception(TASK_RETURN_FAIL_NO_RETURN_TASK);
459 435 }
460 436 // 设置回退意见
461 437 for (String currentTaskId : currentTaskIds) {
... ...