Commit 51e5294a3e5cc2a1af47abab60b8f11035a84c6c

Authored by YunaiV
1 parent 937fd731

review:【bpm 工作流】撤回逻辑(没问题)

yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/model/BpmModelMetaInfoVO.java
@@ -72,6 +72,9 @@ public class BpmModelMetaInfoVO { @@ -72,6 +72,9 @@ public class BpmModelMetaInfoVO {
72 @Schema(description = "允许撤销审批中的申请", example = "true") 72 @Schema(description = "允许撤销审批中的申请", example = "true")
73 private Boolean allowCancelRunningProcess; 73 private Boolean allowCancelRunningProcess;
74 74
  75 + @Schema(description = "允许允许审批人撤回任务", example = "false")
  76 + private Boolean allowWithdrawTask;
  77 +
75 @Schema(description = "流程 ID 规则", example = "{}") 78 @Schema(description = "流程 ID 规则", example = "{}")
76 private ProcessIdRule processIdRule; 79 private ProcessIdRule processIdRule;
77 80
@@ -97,9 +100,6 @@ public class BpmModelMetaInfoVO { @@ -97,9 +100,6 @@ public class BpmModelMetaInfoVO {
97 @Schema(description = "任务后置通知设置", example = "{}") 100 @Schema(description = "任务后置通知设置", example = "{}")
98 private HttpRequestSetting taskAfterTriggerSetting; 101 private HttpRequestSetting taskAfterTriggerSetting;
99 102
100 - @Schema(description = "允许允许审批人撤回任务", example = "false")  
101 - private Boolean allowWithdrawTask;  
102 -  
103 @Schema(description = "流程 ID 规则") 103 @Schema(description = "流程 ID 规则")
104 @Data 104 @Data
105 @Valid 105 @Valid
yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/dal/dataobject/definition/BpmProcessDefinitionInfoDO.java
@@ -173,6 +173,11 @@ public class BpmProcessDefinitionInfoDO extends BaseDO { @@ -173,6 +173,11 @@ public class BpmProcessDefinitionInfoDO extends BaseDO {
173 private Boolean allowCancelRunningProcess; 173 private Boolean allowCancelRunningProcess;
174 174
175 /** 175 /**
  176 + * 是否允许审批人撤回任务
  177 + */
  178 + private Boolean allowWithdrawTask;
  179 +
  180 + /**
176 * 流程 ID 规则 181 * 流程 ID 规则
177 */ 182 */
178 @TableField(typeHandler = JacksonTypeHandler.class) 183 @TableField(typeHandler = JacksonTypeHandler.class)
@@ -219,9 +224,4 @@ public class BpmProcessDefinitionInfoDO extends BaseDO { @@ -219,9 +224,4 @@ public class BpmProcessDefinitionInfoDO extends BaseDO {
219 @TableField(typeHandler = JacksonTypeHandler.class) 224 @TableField(typeHandler = JacksonTypeHandler.class)
220 private BpmModelMetaInfoVO.HttpRequestSetting taskAfterTriggerSetting; 225 private BpmModelMetaInfoVO.HttpRequestSetting taskAfterTriggerSetting;
221 226
222 - /**  
223 - * 是否允许审批人撤回任务  
224 - */  
225 - private Boolean allowWithdrawTask;  
226 -  
227 } 227 }
yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/util/BpmnModelUtils.java
@@ -852,7 +852,7 @@ public class BpmnModelUtils { @@ -852,7 +852,7 @@ public class BpmnModelUtils {
852 } else if (flowNode instanceof ScriptTask) { 852 } else if (flowNode instanceof ScriptTask) {
853 skipExpression = ((ScriptTask) flowNode).getSkipExpression(); 853 skipExpression = ((ScriptTask) flowNode).getSkipExpression();
854 } 854 }
855 - 855 +
856 if (StrUtil.isEmpty(skipExpression)) { 856 if (StrUtil.isEmpty(skipExpression)) {
857 return false; 857 return false;
858 } 858 }
@@ -910,6 +910,7 @@ public class BpmnModelUtils { @@ -910,6 +910,7 @@ public class BpmnModelUtils {
910 910
911 /** 911 /**
912 * 查找起始节点下一个用户任务列表列表 912 * 查找起始节点下一个用户任务列表列表
  913 + *
913 * @param source 起始节点 914 * @param source 起始节点
914 * @return 结果 915 * @return 结果
915 */ 916 */
yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmTaskServiceImpl.java
@@ -40,9 +40,10 @@ import jakarta.annotation.Resource; @@ -40,9 +40,10 @@ import jakarta.annotation.Resource;
40 import jakarta.validation.Valid; 40 import jakarta.validation.Valid;
41 import lombok.extern.slf4j.Slf4j; 41 import lombok.extern.slf4j.Slf4j;
42 import org.flowable.bpmn.model.*; 42 import org.flowable.bpmn.model.*;
43 -import org.flowable.common.engine.api.FlowableException;  
44 -import org.flowable.common.engine.api.FlowableObjectNotFoundException;  
45 -import org.flowable.engine.*; 43 +import org.flowable.engine.HistoryService;
  44 +import org.flowable.engine.ManagementService;
  45 +import org.flowable.engine.RuntimeService;
  46 +import org.flowable.engine.TaskService;
46 import org.flowable.engine.history.HistoricActivityInstance; 47 import org.flowable.engine.history.HistoricActivityInstance;
47 import org.flowable.engine.runtime.ActivityInstance; 48 import org.flowable.engine.runtime.ActivityInstance;
48 import org.flowable.engine.runtime.Execution; 49 import org.flowable.engine.runtime.Execution;
@@ -61,7 +62,6 @@ import org.springframework.transaction.support.TransactionSynchronization; @@ -61,7 +62,6 @@ import org.springframework.transaction.support.TransactionSynchronization;
61 import org.springframework.transaction.support.TransactionSynchronizationManager; 62 import org.springframework.transaction.support.TransactionSynchronizationManager;
62 63
63 import java.util.*; 64 import java.util.*;
64 -import java.util.stream.Collectors;  
65 import java.util.stream.Stream; 65 import java.util.stream.Stream;
66 66
67 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; 67 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
@@ -1180,61 +1180,54 @@ public class BpmTaskServiceImpl implements BpmTaskService { @@ -1180,61 +1180,54 @@ public class BpmTaskServiceImpl implements BpmTaskService {
1180 @Override 1180 @Override
1181 @Transactional(rollbackFor = Exception.class) 1181 @Transactional(rollbackFor = Exception.class)
1182 public void withdrawTask(Long userId, String taskId) { 1182 public void withdrawTask(Long userId, String taskId) {
1183 - // 1.查询本人已办任务 1183 + // 1.1 查询本人已办任务
1184 HistoricTaskInstance taskInstance = historyService.createHistoricTaskInstanceQuery() 1184 HistoricTaskInstance taskInstance = historyService.createHistoricTaskInstanceQuery()
1185 .taskId(taskId).taskAssignee(userId.toString()).finished().singleResult(); 1185 .taskId(taskId).taskAssignee(userId.toString()).finished().singleResult();
1186 - if (ObjectUtil.isNull(taskInstance)) { 1186 + if (ObjUtil.isNull(taskInstance)) {
1187 throw exception(TASK_WITHDRAW_FAIL_TASK_NOT_EXISTS); 1187 throw exception(TASK_WITHDRAW_FAIL_TASK_NOT_EXISTS);
1188 } 1188 }
1189 - // 2.校验流程是否结束  
1190 - ProcessInstance processInstance = runtimeService.createProcessInstanceQuery()  
1191 - .processInstanceId(taskInstance.getProcessInstanceId())  
1192 - .active()  
1193 - .singleResult();  
1194 - if (ObjectUtil.isNull(processInstance)) { 1189 + // 1.2 校验流程是否结束
  1190 + ProcessInstance processInstance = processInstanceService.getProcessInstance(taskInstance.getProcessInstanceId());
  1191 + if (ObjUtil.isNull(processInstance)) {
1195 throw exception(TASK_WITHDRAW_FAIL_PROCESS_NOT_RUNNING); 1192 throw exception(TASK_WITHDRAW_FAIL_PROCESS_NOT_RUNNING);
1196 } 1193 }
1197 - // 3.判断此流程是否允许撤回  
1198 - BpmProcessDefinitionInfoDO processDefinitionInfo = bpmProcessDefinitionService  
1199 - .getProcessDefinitionInfo(processInstance.getProcessDefinitionId());  
1200 - if (ObjectUtil.isNull(processDefinitionInfo) || !Boolean.TRUE.equals(processDefinitionInfo.getAllowWithdrawTask())) { 1194 + // 1.3 判断此流程是否允许撤回
  1195 + BpmProcessDefinitionInfoDO processDefinitionInfo = bpmProcessDefinitionService.getProcessDefinitionInfo(
  1196 + processInstance.getProcessDefinitionId());
  1197 + if (ObjUtil.isNull(processDefinitionInfo) || !Boolean.TRUE.equals(processDefinitionInfo.getAllowWithdrawTask())) {
1201 throw exception(TASK_WITHDRAW_FAIL_NOT_ALLOW); 1198 throw exception(TASK_WITHDRAW_FAIL_NOT_ALLOW);
1202 } 1199 }
1203 - // 4.判断此任务下一节点是否满足撤回 1200 + // 1.4 判断下一个节点是否被审批过,如果是则无法撤回
1204 BpmnModel bpmnModel = modelService.getBpmnModelByDefinitionId(taskInstance.getProcessDefinitionId()); 1201 BpmnModel bpmnModel = modelService.getBpmnModelByDefinitionId(taskInstance.getProcessDefinitionId());
1205 UserTask userTask = (UserTask) BpmnModelUtils.getFlowElementById(bpmnModel, taskInstance.getTaskDefinitionKey()); 1202 UserTask userTask = (UserTask) BpmnModelUtils.getFlowElementById(bpmnModel, taskInstance.getTaskDefinitionKey());
1206 - List<UserTask> nextUserTaskList = BpmnModelUtils.getNextUserTasks(userTask);  
1207 - List<String> nextUserTaskKeys = nextUserTaskList.stream().map(UserTask::getId).toList(); 1203 + List<String> nextUserTaskKeys = convertList(BpmnModelUtils.getNextUserTasks(userTask), UserTask::getId);
1208 if (CollUtil.isEmpty(nextUserTaskKeys)) { 1204 if (CollUtil.isEmpty(nextUserTaskKeys)) {
1209 throw exception(TASK_WITHDRAW_FAIL_NEXT_TASK_NOT_ALLOW); 1205 throw exception(TASK_WITHDRAW_FAIL_NEXT_TASK_NOT_ALLOW);
1210 } 1206 }
  1207 + // TODO @芋艿:是否选择升级flowable版本解决taskCreatedAfter、taskCreatedBefore问题,升级7.1.0可以;包括 todo 和 done 那边的查询哇???
1211 long nextUserTaskFinishedCount = historyService.createHistoricTaskInstanceQuery() 1208 long nextUserTaskFinishedCount = historyService.createHistoricTaskInstanceQuery()
1212 - .processInstanceId(processInstance.getProcessInstanceId())  
1213 - .taskDefinitionKeys(nextUserTaskKeys)  
1214 - .taskCreatedAfter(taskInstance.getEndTime()) // TODO @芋艿:是否选择升级flowable版本解决taskCreatedAfter、taskCreatedBefore问题,升级7.1.0可以  
1215 - .finished()  
1216 - .count(); 1209 + .processInstanceId(processInstance.getProcessInstanceId()).taskDefinitionKeys(nextUserTaskKeys)
  1210 + .taskCreatedAfter(taskInstance.getEndTime()).finished().count();
1217 if (nextUserTaskFinishedCount > 0) { 1211 if (nextUserTaskFinishedCount > 0) {
1218 throw exception(TASK_WITHDRAW_FAIL_NEXT_TASK_NOT_ALLOW); 1212 throw exception(TASK_WITHDRAW_FAIL_NEXT_TASK_NOT_ALLOW);
1219 } 1213 }
1220 - // 5.获取需要撤回的运行任务  
1221 - List<Task> runningTaskList = taskService.createTaskQuery()  
1222 - .processInstanceId(processInstance.getProcessInstanceId())  
1223 - .taskDefinitionKeys(nextUserTaskKeys)  
1224 - .active().list();  
1225 - if (CollUtil.isEmpty(runningTaskList)) { 1214 + // 1.5 获取需要撤回的运行任务
  1215 + List<Task> runningTasks = taskService.createTaskQuery().processInstanceId(processInstance.getProcessInstanceId())
  1216 + .taskDefinitionKeys(nextUserTaskKeys).active().list();
  1217 + if (CollUtil.isEmpty(runningTasks)) {
1226 throw exception(TASK_WITHDRAW_FAIL_NEXT_TASK_NOT_ALLOW); 1218 throw exception(TASK_WITHDRAW_FAIL_NEXT_TASK_NOT_ALLOW);
1227 } 1219 }
  1220 +
  1221 + // 2.1 取消当前任务
1228 List<String> withdrawExecutionIds = new ArrayList<>(); 1222 List<String> withdrawExecutionIds = new ArrayList<>();
1229 - for (Task task : runningTaskList) { 1223 + for (Task task : runningTasks) {
1230 // 标记撤回任务为取消 1224 // 标记撤回任务为取消
1231 - // TODO @芋艿:是否需要添加被撤回状态?  
1232 taskService.addComment(task.getId(), taskInstance.getProcessInstanceId(), BpmCommentTypeEnum.CANCEL.getType(), 1225 taskService.addComment(task.getId(), taskInstance.getProcessInstanceId(), BpmCommentTypeEnum.CANCEL.getType(),
1233 BpmCommentTypeEnum.CANCEL.formatComment("前一节点撤回")); 1226 BpmCommentTypeEnum.CANCEL.formatComment("前一节点撤回"));
1234 updateTaskStatusAndReason(task.getId(), BpmTaskStatusEnum.CANCEL.getStatus(), BpmReasonEnum.CANCEL_BY_WITHDRAW.getReason()); 1227 updateTaskStatusAndReason(task.getId(), BpmTaskStatusEnum.CANCEL.getStatus(), BpmReasonEnum.CANCEL_BY_WITHDRAW.getReason());
1235 withdrawExecutionIds.add(task.getExecutionId()); 1228 withdrawExecutionIds.add(task.getExecutionId());
1236 } 1229 }
1237 - // 6.执行撤回操作 1230 + // 2.2 执行撤回操作
1238 runtimeService.createChangeActivityStateBuilder() 1231 runtimeService.createChangeActivityStateBuilder()
1239 .processInstanceId(processInstance.getProcessInstanceId()) 1232 .processInstanceId(processInstance.getProcessInstanceId())
1240 .moveExecutionsToSingleActivityId(withdrawExecutionIds, taskInstance.getTaskDefinitionKey()) 1233 .moveExecutionsToSingleActivityId(withdrawExecutionIds, taskInstance.getTaskDefinitionKey())