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 package cn.iocoder.yudao.framework.flowable.core.util; 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 import org.flowable.bpmn.model.Process; 3 import org.flowable.bpmn.model.Process;
7 import org.flowable.bpmn.model.*; 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,7 +55,6 @@ public class ModelUtils {
56 return process.getFlowElement(flowElementId); 55 return process.getFlowElement(flowElementId);
57 } 56 }
58 57
59 -  
60 /** 58 /**
61 * 找到 source 节点之前的所有用户任务节点 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,9 +47,10 @@ public interface ErrorCodeConstants {
47 ErrorCode TASK_COMPLETE_FAIL_ASSIGN_NOT_SELF = new ErrorCode(1_009_005_001, "审批任务失败,原因:该任务的审批人不是你"); 47 ErrorCode TASK_COMPLETE_FAIL_ASSIGN_NOT_SELF = new ErrorCode(1_009_005_001, "审批任务失败,原因:该任务的审批人不是你");
48 ErrorCode TASK_NOT_EXISTS = new ErrorCode(1_009_005_002, "流程任务不存在"); 48 ErrorCode TASK_NOT_EXISTS = new ErrorCode(1_009_005_002, "流程任务不存在");
49 ErrorCode TASK_IS_PENDING = new ErrorCode(1_009_005_003, "当前任务处于挂起状态,不能操作"); 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 // ========== 流程任务分配规则 1-009-006-000 ========== 54 // ========== 流程任务分配规则 1-009-006-000 ==========
54 ErrorCode TASK_ASSIGN_RULE_EXISTS = new ErrorCode(1_009_006_000, "流程({}) 的任务({}) 已经存在分配规则"); 55 ErrorCode TASK_ASSIGN_RULE_EXISTS = new ErrorCode(1_009_006_000, "流程({}) 的任务({}) 已经存在分配规则");
55 ErrorCode TASK_ASSIGN_RULE_NOT_EXISTS = new ErrorCode(1_009_006_001, "流程任务分配规则不存在"); 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,10 +14,10 @@ public class BpmTaskReturnReqVO {
14 private String id; 14 private String id;
15 15
16 @Schema(description = "回退到的任务 Key", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") 16 @Schema(description = "回退到的任务 Key", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
17 - @NotEmpty(message = "回退到的任务Key不能为空") 17 + @NotEmpty(message = "回退到的任务 Key 不能为空")
18 private String targetDefinitionKey; 18 private String targetDefinitionKey;
19 19
20 - @Schema(description = "回退意见", example = "") 20 + @Schema(description = "回退意见", example = "我就是想驳回")
21 private String reason; 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,10 +3,7 @@ package cn.iocoder.yudao.module.bpm.controller.admin.task.vo.task;
3 import io.swagger.v3.oas.annotations.media.Schema; 3 import io.swagger.v3.oas.annotations.media.Schema;
4 import lombok.Data; 4 import lombok.Data;
5 5
6 -/**  
7 - *  
8 - */  
9 -@Schema(description = "管理后台 - 流程任务的 可回退的节点 Response VO") 6 +@Schema(description = "管理后台 - 流程任务的精简 Response VO")
10 @Data 7 @Data
11 public class BpmTaskSimpleRespVO { 8 public class BpmTaskSimpleRespVO {
12 9
@@ -15,4 +12,5 @@ public class BpmTaskSimpleRespVO { @@ -15,4 +12,5 @@ public class BpmTaskSimpleRespVO {
15 12
16 @Schema(description = "任务名词", requiredMode = Schema.RequiredMode.REQUIRED, example = "经理审批") 13 @Schema(description = "任务名词", requiredMode = Schema.RequiredMode.REQUIRED, example = "经理审批")
17 private String name; 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,8 +140,7 @@ public interface BpmTaskConvert {
140 return reqDTO; 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 return CollectionUtils.convertList(elementList, element -> new BpmTaskSimpleRespVO() 144 return CollectionUtils.convertList(elementList, element -> new BpmTaskSimpleRespVO()
146 .setName(element.getName()) 145 .setName(element.getName())
147 .setDefinitionKey(element.getId())); 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,7 +125,7 @@ public interface BpmTaskService {
125 /** 125 /**
126 * 获取当前任务的可回退的流程集合 126 * 获取当前任务的可回退的流程集合
127 * 127 *
128 - * @param taskId 当前的任务ID 128 + * @param taskId 当前的任务 ID
129 * @return 可以回退的节点列表 129 * @return 可以回退的节点列表
130 */ 130 */
131 List<BpmTaskSimpleRespVO> getReturnTaskList(String taskId); 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,49 +327,25 @@ public class BpmTaskServiceImpl implements BpmTaskService {
327 327
328 @Override 328 @Override
329 public List<BpmTaskSimpleRespVO> getReturnTaskList(String taskId) { 329 public List<BpmTaskSimpleRespVO> getReturnTaskList(String taskId) {
330 - // 当前任务 task 330 + // 1. 校验当前任务 task 存在
331 Task task = getTask(taskId); 331 Task task = getTask(taskId);
332 - if (null == task) { 332 + if (task == null) {
333 throw exception(TASK_NOT_EXISTS); 333 throw exception(TASK_NOT_EXISTS);
334 } 334 }
335 - // 根据流程定义获取流程模型信息  
336 BpmnModel bpmnModel = bpmModelService.getBpmnModelByDefinitionId(task.getProcessDefinitionId()); 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 FlowElement source = ModelUtils.getFlowElementById(bpmnModel, task.getTaskDefinitionKey()); 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 @Transactional(rollbackFor = Exception.class) 351 @Transactional(rollbackFor = Exception.class)
@@ -426,7 +402,7 @@ public class BpmTaskServiceImpl implements BpmTaskService { @@ -426,7 +402,7 @@ public class BpmTaskServiceImpl implements BpmTaskService {
426 // 从当前节点向前扫描,判断当前节点与目标节点是否属于串行,若目标节点是在并行网关上或非同一路线上,不可跳转 402 // 从当前节点向前扫描,判断当前节点与目标节点是否属于串行,若目标节点是在并行网关上或非同一路线上,不可跳转
427 boolean isSequential = ModelUtils.isSequentialReachable(source, target, new HashSet<>()); 403 boolean isSequential = ModelUtils.isSequentialReachable(source, target, new HashSet<>());
428 if (!isSequential) { 404 if (!isSequential) {
429 - throw exception(TASK_SOURCE_TARGET_ERROR); 405 + throw exception(TASK_RETURN_FAIL_SOURCE_TARGET_ERROR);
430 } 406 }
431 return target; 407 return target;
432 } 408 }
@@ -455,7 +431,7 @@ public class BpmTaskServiceImpl implements BpmTaskService { @@ -455,7 +431,7 @@ public class BpmTaskServiceImpl implements BpmTaskService {
455 } 431 }
456 })); 432 }));
457 if (CollUtil.isEmpty(currentTaskIds)) { 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 for (String currentTaskId : currentTaskIds) { 437 for (String currentTaskId : currentTaskIds) {