From 51e5294a3e5cc2a1af47abab60b8f11035a84c6c Mon Sep 17 00:00:00 2001 From: YunaiV Date: Sat, 2 Aug 2025 15:44:19 +0800 Subject: [PATCH] =?UTF-8?q?review=EF=BC=9A=E3=80=90bpm=20=E5=B7=A5?= =?UTF-8?q?=E4=BD=9C=E6=B5=81=E3=80=91=E6=92=A4=E5=9B=9E=E9=80=BB=E8=BE=91?= =?UTF-8?q?=EF=BC=88=E6=B2=A1=E9=97=AE=E9=A2=98=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../vo/model/BpmModelMetaInfoVO.java | 6 +- .../BpmProcessDefinitionInfoDO.java | 10 ++-- .../flowable/core/util/BpmnModelUtils.java | 3 +- .../bpm/service/task/BpmTaskServiceImpl.java | 59 ++++++++----------- 4 files changed, 36 insertions(+), 42 deletions(-) diff --git a/yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/model/BpmModelMetaInfoVO.java b/yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/model/BpmModelMetaInfoVO.java index dca75851e9..943a82d546 100644 --- a/yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/model/BpmModelMetaInfoVO.java +++ b/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 { @Schema(description = "允许撤销审批中的申请", example = "true") private Boolean allowCancelRunningProcess; + @Schema(description = "允许允许审批人撤回任务", example = "false") + private Boolean allowWithdrawTask; + @Schema(description = "流程 ID 规则", example = "{}") private ProcessIdRule processIdRule; @@ -97,9 +100,6 @@ public class BpmModelMetaInfoVO { @Schema(description = "任务后置通知设置", example = "{}") private HttpRequestSetting taskAfterTriggerSetting; - @Schema(description = "允许允许审批人撤回任务", example = "false") - private Boolean allowWithdrawTask; - @Schema(description = "流程 ID 规则") @Data @Valid diff --git a/yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/dal/dataobject/definition/BpmProcessDefinitionInfoDO.java b/yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/dal/dataobject/definition/BpmProcessDefinitionInfoDO.java index 7f10bda388..37e2c4462d 100644 --- a/yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/dal/dataobject/definition/BpmProcessDefinitionInfoDO.java +++ b/yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/dal/dataobject/definition/BpmProcessDefinitionInfoDO.java @@ -172,6 +172,11 @@ public class BpmProcessDefinitionInfoDO extends BaseDO { */ private Boolean allowCancelRunningProcess; + /** + * 是否允许审批人撤回任务 + */ + private Boolean allowWithdrawTask; + /** * 流程 ID 规则 */ @@ -219,9 +224,4 @@ public class BpmProcessDefinitionInfoDO extends BaseDO { @TableField(typeHandler = JacksonTypeHandler.class) private BpmModelMetaInfoVO.HttpRequestSetting taskAfterTriggerSetting; - /** - * 是否允许审批人撤回任务 - */ - private Boolean allowWithdrawTask; - } diff --git a/yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/util/BpmnModelUtils.java b/yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/util/BpmnModelUtils.java index 978693c0c8..a3414cedb4 100644 --- a/yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/util/BpmnModelUtils.java +++ b/yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/util/BpmnModelUtils.java @@ -852,7 +852,7 @@ public class BpmnModelUtils { } else if (flowNode instanceof ScriptTask) { skipExpression = ((ScriptTask) flowNode).getSkipExpression(); } - + if (StrUtil.isEmpty(skipExpression)) { return false; } @@ -910,6 +910,7 @@ public class BpmnModelUtils { /** * 查找起始节点下一个用户任务列表列表 + * * @param source 起始节点 * @return 结果 */ diff --git a/yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmTaskServiceImpl.java b/yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmTaskServiceImpl.java index d75a91c12b..133f05c76b 100644 --- a/yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmTaskServiceImpl.java +++ b/yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmTaskServiceImpl.java @@ -40,9 +40,10 @@ import jakarta.annotation.Resource; import jakarta.validation.Valid; import lombok.extern.slf4j.Slf4j; import org.flowable.bpmn.model.*; -import org.flowable.common.engine.api.FlowableException; -import org.flowable.common.engine.api.FlowableObjectNotFoundException; -import org.flowable.engine.*; +import org.flowable.engine.HistoryService; +import org.flowable.engine.ManagementService; +import org.flowable.engine.RuntimeService; +import org.flowable.engine.TaskService; import org.flowable.engine.history.HistoricActivityInstance; import org.flowable.engine.runtime.ActivityInstance; import org.flowable.engine.runtime.Execution; @@ -61,7 +62,6 @@ import org.springframework.transaction.support.TransactionSynchronization; import org.springframework.transaction.support.TransactionSynchronizationManager; import java.util.*; -import java.util.stream.Collectors; import java.util.stream.Stream; import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; @@ -1180,61 +1180,54 @@ public class BpmTaskServiceImpl implements BpmTaskService { @Override @Transactional(rollbackFor = Exception.class) public void withdrawTask(Long userId, String taskId) { - // 1.查询本人已办任务 + // 1.1 查询本人已办任务 HistoricTaskInstance taskInstance = historyService.createHistoricTaskInstanceQuery() .taskId(taskId).taskAssignee(userId.toString()).finished().singleResult(); - if (ObjectUtil.isNull(taskInstance)) { + if (ObjUtil.isNull(taskInstance)) { throw exception(TASK_WITHDRAW_FAIL_TASK_NOT_EXISTS); } - // 2.校验流程是否结束 - ProcessInstance processInstance = runtimeService.createProcessInstanceQuery() - .processInstanceId(taskInstance.getProcessInstanceId()) - .active() - .singleResult(); - if (ObjectUtil.isNull(processInstance)) { + // 1.2 校验流程是否结束 + ProcessInstance processInstance = processInstanceService.getProcessInstance(taskInstance.getProcessInstanceId()); + if (ObjUtil.isNull(processInstance)) { throw exception(TASK_WITHDRAW_FAIL_PROCESS_NOT_RUNNING); } - // 3.判断此流程是否允许撤回 - BpmProcessDefinitionInfoDO processDefinitionInfo = bpmProcessDefinitionService - .getProcessDefinitionInfo(processInstance.getProcessDefinitionId()); - if (ObjectUtil.isNull(processDefinitionInfo) || !Boolean.TRUE.equals(processDefinitionInfo.getAllowWithdrawTask())) { + // 1.3 判断此流程是否允许撤回 + BpmProcessDefinitionInfoDO processDefinitionInfo = bpmProcessDefinitionService.getProcessDefinitionInfo( + processInstance.getProcessDefinitionId()); + if (ObjUtil.isNull(processDefinitionInfo) || !Boolean.TRUE.equals(processDefinitionInfo.getAllowWithdrawTask())) { throw exception(TASK_WITHDRAW_FAIL_NOT_ALLOW); } - // 4.判断此任务下一节点是否满足撤回 + // 1.4 判断下一个节点是否被审批过,如果是则无法撤回 BpmnModel bpmnModel = modelService.getBpmnModelByDefinitionId(taskInstance.getProcessDefinitionId()); UserTask userTask = (UserTask) BpmnModelUtils.getFlowElementById(bpmnModel, taskInstance.getTaskDefinitionKey()); - List nextUserTaskList = BpmnModelUtils.getNextUserTasks(userTask); - List nextUserTaskKeys = nextUserTaskList.stream().map(UserTask::getId).toList(); + List nextUserTaskKeys = convertList(BpmnModelUtils.getNextUserTasks(userTask), UserTask::getId); if (CollUtil.isEmpty(nextUserTaskKeys)) { throw exception(TASK_WITHDRAW_FAIL_NEXT_TASK_NOT_ALLOW); } + // TODO @芋艿:是否选择升级flowable版本解决taskCreatedAfter、taskCreatedBefore问题,升级7.1.0可以;包括 todo 和 done 那边的查询哇??? long nextUserTaskFinishedCount = historyService.createHistoricTaskInstanceQuery() - .processInstanceId(processInstance.getProcessInstanceId()) - .taskDefinitionKeys(nextUserTaskKeys) - .taskCreatedAfter(taskInstance.getEndTime()) // TODO @芋艿:是否选择升级flowable版本解决taskCreatedAfter、taskCreatedBefore问题,升级7.1.0可以 - .finished() - .count(); + .processInstanceId(processInstance.getProcessInstanceId()).taskDefinitionKeys(nextUserTaskKeys) + .taskCreatedAfter(taskInstance.getEndTime()).finished().count(); if (nextUserTaskFinishedCount > 0) { throw exception(TASK_WITHDRAW_FAIL_NEXT_TASK_NOT_ALLOW); } - // 5.获取需要撤回的运行任务 - List runningTaskList = taskService.createTaskQuery() - .processInstanceId(processInstance.getProcessInstanceId()) - .taskDefinitionKeys(nextUserTaskKeys) - .active().list(); - if (CollUtil.isEmpty(runningTaskList)) { + // 1.5 获取需要撤回的运行任务 + List runningTasks = taskService.createTaskQuery().processInstanceId(processInstance.getProcessInstanceId()) + .taskDefinitionKeys(nextUserTaskKeys).active().list(); + if (CollUtil.isEmpty(runningTasks)) { throw exception(TASK_WITHDRAW_FAIL_NEXT_TASK_NOT_ALLOW); } + + // 2.1 取消当前任务 List withdrawExecutionIds = new ArrayList<>(); - for (Task task : runningTaskList) { + for (Task task : runningTasks) { // 标记撤回任务为取消 - // TODO @芋艿:是否需要添加被撤回状态? taskService.addComment(task.getId(), taskInstance.getProcessInstanceId(), BpmCommentTypeEnum.CANCEL.getType(), BpmCommentTypeEnum.CANCEL.formatComment("前一节点撤回")); updateTaskStatusAndReason(task.getId(), BpmTaskStatusEnum.CANCEL.getStatus(), BpmReasonEnum.CANCEL_BY_WITHDRAW.getReason()); withdrawExecutionIds.add(task.getExecutionId()); } - // 6.执行撤回操作 + // 2.2 执行撤回操作 runtimeService.createChangeActivityStateBuilder() .processInstanceId(processInstance.getProcessInstanceId()) .moveExecutionsToSingleActivityId(withdrawExecutionIds, taskInstance.getTaskDefinitionKey())