diff --git a/yudao-module-bpm/yudao-module-bpm-api/src/main/java/cn/iocoder/yudao/module/bpm/enums/ErrorCodeConstants.java b/yudao-module-bpm/yudao-module-bpm-api/src/main/java/cn/iocoder/yudao/module/bpm/enums/ErrorCodeConstants.java index 63f374822..b84781ed6 100644 --- a/yudao-module-bpm/yudao-module-bpm-api/src/main/java/cn/iocoder/yudao/module/bpm/enums/ErrorCodeConstants.java +++ b/yudao-module-bpm/yudao-module-bpm-api/src/main/java/cn/iocoder/yudao/module/bpm/enums/ErrorCodeConstants.java @@ -43,15 +43,13 @@ public interface ErrorCodeConstants { ErrorCode PROCESS_INSTANCE_CANCEL_FAIL_NOT_SELF = new ErrorCode(1_009_004_002, "流程取消失败,该流程不是你发起的"); // ========== 流程任务 1-009-005-000 ========== - ErrorCode TASK_COMPLETE_FAIL_NOT_EXISTS = new ErrorCode(1_009_005_000, "审批任务失败,原因:该任务不处于未审批"); - ErrorCode TASK_COMPLETE_FAIL_ASSIGN_NOT_SELF = new ErrorCode(1_009_005_001, "审批任务失败,原因:该任务的审批人不是你"); + ErrorCode TASK_OPERATE_FAIL_ASSIGN_NOT_SELF = new ErrorCode(1_009_005_001, "操作失败,原因:该任务的审批人不是你"); ErrorCode TASK_NOT_EXISTS = new ErrorCode(1_009_005_002, "流程任务不存在"); ErrorCode TASK_IS_PENDING = new ErrorCode(1_009_005_003, "当前任务处于挂起状态,不能操作"); ErrorCode TASK_TARGET_NODE_NOT_EXISTS = new ErrorCode(1_009_005_004, " 目标节点不存在"); - ErrorCode TASK_RETURN_FAIL_NO_RETURN_TASK = new ErrorCode(1_009_005_005, "回退任务失败,选择回退的节点没有需要回滚的任务!请重新选择其他任务节点"); ErrorCode TASK_RETURN_FAIL_SOURCE_TARGET_ERROR = new ErrorCode(1_009_005_006, "回退任务失败,目标节点是在并行网关上或非同一路线上,不可跳转"); - ErrorCode TASK_DELEGATE_USER_REPEAT = new ErrorCode(1_009_005_007, "任务委派失败,委派人和当前审批人为同一人"); - ErrorCode TASK_DELEGATE_USER_NULL = new ErrorCode(1_009_005_008, "任务委派失败,被委派人不存在"); + ErrorCode TASK_DELEGATE_FAIL_USER_REPEAT = new ErrorCode(1_009_005_007, "任务委派失败,委派人和当前审批人为同一人"); + ErrorCode TASK_DELEGATE_FAIL_USER_NOT_EXISTS = new ErrorCode(1_009_005_008, "任务委派失败,被委派人不存在"); // ========== 流程任务分配规则 1-009-006-000 ========== ErrorCode TASK_ASSIGN_RULE_EXISTS = new ErrorCode(1_009_006_000, "流程({}) 的任务({}) 已经存在分配规则"); diff --git a/yudao-module-bpm/yudao-module-bpm-api/src/main/java/cn/iocoder/yudao/module/bpm/enums/task/BpmProcessInstanceResultEnum.java b/yudao-module-bpm/yudao-module-bpm-api/src/main/java/cn/iocoder/yudao/module/bpm/enums/task/BpmProcessInstanceResultEnum.java index 519c7bc4e..a19c68ba8 100644 --- a/yudao-module-bpm/yudao-module-bpm-api/src/main/java/cn/iocoder/yudao/module/bpm/enums/task/BpmProcessInstanceResultEnum.java +++ b/yudao-module-bpm/yudao-module-bpm-api/src/main/java/cn/iocoder/yudao/module/bpm/enums/task/BpmProcessInstanceResultEnum.java @@ -20,8 +20,7 @@ public enum BpmProcessInstanceResultEnum { // ========== 流程任务独有的状态 ========== - BACK(5, "退回/驳回"), - + BACK(5, "驳回"), // 退回 DELEGATE(6, "委派"); /** diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/BpmTaskController.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/BpmTaskController.java index bf849df0a..e980fddcf 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/BpmTaskController.java +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/BpmTaskController.java @@ -87,14 +87,15 @@ public class BpmTaskController { @Operation(summary = "回退任务", description = "用于【流程详情】的【回退】按钮") @PreAuthorize("@ss.hasPermission('bpm:task:update')") public CommonResult returnTask(@Valid @RequestBody BpmTaskReturnReqVO reqVO) { - taskService.returnTask(reqVO); + taskService.returnTask(getLoginUserId(), reqVO); return success(true); } @PutMapping("/delegate") - @Operation(summary = "委派任务", description = "用于【流程详情】的【委派】按钮,和向前加签有点像,和向前加签的唯一的区别是没有单独创立任务") - @PreAuthorize("@ss.hasPermission('bpm:task:delegate')") + @Operation(summary = "委派任务", description = "用于【流程详情】的【委派】按钮。和向前【加签】有点像,唯一区别是【委托】没有单独创立任务") + @PreAuthorize("@ss.hasPermission('bpm:task:update')") public CommonResult delegateTask(@Valid @RequestBody BpmTaskDelegateReqVO reqVO) { + // TODO @海:, 后面要有空格 taskService.delegateTask(reqVO,getLoginUserId()); return success(true); } diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/task/BpmTaskDelegateReqVO.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/task/BpmTaskDelegateReqVO.java index 295980345..96c42deb8 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/task/BpmTaskDelegateReqVO.java +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/task/BpmTaskDelegateReqVO.java @@ -14,11 +14,12 @@ public class BpmTaskDelegateReqVO { @NotEmpty(message = "任务编号不能为空") private String id; - @Schema(description = "被委派人ID", requiredMode = Schema.RequiredMode.REQUIRED,example = "1") - @NotNull(message = "被委派人ID不能为空") + @Schema(description = "被委派人 ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") + @NotNull(message = "被委派人 ID 不能为空") private Long delegateUserId; - @Schema(description = "委派原因", requiredMode = Schema.RequiredMode.REQUIRED,example = "做不了决定,需要你先帮忙瞅瞅") + @Schema(description = "委派原因", requiredMode = Schema.RequiredMode.REQUIRED, example = "做不了决定,需要你先帮忙瞅瞅") @NotEmpty(message = "委派原因不能为空") private String reason; + } diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmTaskService.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmTaskService.java index 65645e9ea..99699d791 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmTaskService.java +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmTaskService.java @@ -133,15 +133,18 @@ public interface BpmTaskService { /** * 将任务回退到指定的 targetDefinitionKey 位置 * + * @param userId 用户编号 * @param reqVO 回退的任务key和当前所在的任务ID */ - void returnTask(BpmTaskReturnReqVO reqVO); + void returnTask(Long userId, BpmTaskReturnReqVO reqVO); + // TODO @海:userId 放前面 /** * 将指定任务委派给其他人处理,等接收人处理后再回到原审批人手中审批 * * @param reqVO 被委派人和被委派的任务编号理由参数 - * @param userId 委派人ID + * @param userId 用户编号 */ void delegateTask(BpmTaskDelegateReqVO reqVO, Long userId); + } diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmTaskServiceImpl.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmTaskServiceImpl.java index 39c21046d..86f1ea4ff 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmTaskServiceImpl.java +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmTaskServiceImpl.java @@ -189,25 +189,27 @@ public class BpmTaskServiceImpl implements BpmTaskService { @Override @Transactional(rollbackFor = Exception.class) public void approveTask(Long userId, @Valid BpmTaskApproveReqVO reqVO) { - // 校验任务存在 - Task task = checkTask(userId, reqVO.getId()); - // 校验流程实例存在 + // 1.1 校验任务存在 + Task task = validateTask(userId, reqVO.getId()); + // 1.2 校验流程实例存在 ProcessInstance instance = processInstanceService.getProcessInstance(task.getProcessInstanceId()); if (instance == null) { throw exception(PROCESS_INSTANCE_NOT_EXISTS); } - //被委派的任务,不调用 complete 去完成任务 - if (DelegationState.PENDING.equals(task.getDelegationState())) { - this.approveDelegateTask(reqVO, task); - } else { - // 完成任务,审批通过 - taskService.complete(task.getId(), instance.getProcessVariables()); - // 更新任务拓展表为通过 - taskExtMapper.updateByTaskId( - new BpmTaskExtDO().setTaskId(task.getId()).setResult(BpmProcessInstanceResultEnum.APPROVE.getResult()) - .setReason(reqVO.getReason())); + // 情况一:被委派的任务,不调用 complete 去完成任务 + if (DelegationState.PENDING.equals(task.getDelegationState())) { + approveDelegateTask(reqVO, task); + return; } + + // 情况二:自己审批的任务,调用 complete 去完成任务 + // 完成任务,审批通过 + taskService.complete(task.getId(), instance.getProcessVariables()); + // 更新任务拓展表为通过 + taskExtMapper.updateByTaskId( + new BpmTaskExtDO().setTaskId(task.getId()).setResult(BpmProcessInstanceResultEnum.APPROVE.getResult()) + .setReason(reqVO.getReason())); } /** @@ -217,19 +219,19 @@ public class BpmTaskServiceImpl implements BpmTaskService { * @param task 当前被审批的任务 */ private void approveDelegateTask(BpmTaskApproveReqVO reqVO, Task task) { - // 添加审批意见 + // 1. 添加审批意见 AdminUserRespDTO currentUser = adminUserApi.getUser(WebFrameworkUtils.getLoginUserId()); - //原审批人 AdminUserRespDTO sourceApproveUser = adminUserApi.getUser(NumberUtils.parseLong(task.getOwner())); Assert.notNull(sourceApproveUser, "委派任务找不到原审批人,需要检查数据"); - //添加审批意见 String comment = StrUtil.format("[{}]完成委派任务,任务重新回到[{}]手中,审批意见为:{}", currentUser.getNickname(), sourceApproveUser.getNickname(), reqVO.getReason()); - taskService.addComment(reqVO.getId(), task.getProcessInstanceId(), BpmProcessInstanceResultEnum.DELEGATE.getResult().toString(), comment); - //调用 resolveTask 完成任务,底层调用 TaskHelper.changeTaskAssignee(task, task.getOwner()); - //将 owner 设置为 assignee + taskService.addComment(reqVO.getId(), task.getProcessInstanceId(), + BpmProcessInstanceResultEnum.DELEGATE.getResult().toString(), comment); + + // 2.1 调用 resolveTask 完成任务。 + // 底层调用 TaskHelper.changeTaskAssignee(task, task.getOwner()):将 owner 设置为 assignee taskService.resolveTask(task.getId()); - // 更新任务拓展表为【处理中】 + // 2.2 更新任务拓展表为【处理中】 taskExtMapper.updateByTaskId( new BpmTaskExtDO().setTaskId(task.getId()).setResult(BpmProcessInstanceResultEnum.PROCESS.getResult()) .setReason(reqVO.getReason())); @@ -238,7 +240,7 @@ public class BpmTaskServiceImpl implements BpmTaskService { @Override @Transactional(rollbackFor = Exception.class) public void rejectTask(Long userId, @Valid BpmTaskRejectReqVO reqVO) { - Task task = checkTask(userId, reqVO.getId()); + Task task = validateTask(userId, reqVO.getId()); // 校验流程实例存在 ProcessInstance instance = processInstanceService.getProcessInstance(task.getProcessInstanceId()); if (instance == null) { @@ -257,7 +259,7 @@ public class BpmTaskServiceImpl implements BpmTaskService { @Override public void updateTaskAssignee(Long userId, BpmTaskUpdateAssigneeReqVO reqVO) { // 校验任务存在 - Task task = checkTask(userId, reqVO.getId()); + Task task = validateTask(userId, reqVO.getId()); // 更新负责人 updateTaskAssignee(task.getId(), reqVO.getAssigneeUserId()); } @@ -273,13 +275,13 @@ public class BpmTaskServiceImpl implements BpmTaskService { * @param userId 用户 id * @param taskId task id */ - private Task checkTask(Long userId, String taskId) { + private Task validateTask(Long userId, String taskId) { Task task = getTask(taskId); if (task == null) { - throw exception(TASK_COMPLETE_FAIL_NOT_EXISTS); + throw exception(TASK_NOT_EXISTS); } if (!Objects.equals(userId, NumberUtils.parseLong(task.getAssignee()))) { - throw exception(TASK_COMPLETE_FAIL_ASSIGN_NOT_SELF); + throw exception(TASK_OPERATE_FAIL_ASSIGN_NOT_SELF); } return task; } @@ -358,24 +360,6 @@ public class BpmTaskServiceImpl implements BpmTaskService { return task; } - /** - * 校验任务是否合法 - * - * @param taskId 任务编号 - * @return 任务 - */ - private Task validateTask(String taskId) { - // 当前任务 task - Task task = getTask(taskId); - if (task == null) { - throw exception(TASK_NOT_EXISTS); - } - if (task.isSuspended()) { - throw exception(TASK_IS_PENDING); - } - return task; - } - private HistoricTaskInstance getHistoricTask(String id) { return historyService.createHistoricTaskInstanceQuery().taskId(id).singleResult(); } @@ -406,9 +390,12 @@ public class BpmTaskServiceImpl implements BpmTaskService { @Override @Transactional(rollbackFor = Exception.class) - public void returnTask(BpmTaskReturnReqVO reqVO) { + public void returnTask(Long userId, BpmTaskReturnReqVO reqVO) { // 1.1 当前任务 task - Task task = validateTask(reqVO.getId()); + Task task = validateTask(userId, reqVO.getId()); + if (task.isSuspended()) { + throw exception(TASK_IS_PENDING); + } // 1.2 校验源头和目标节点的关系,并返回目标元素 FlowElement targetElement = validateTargetTaskCanReturn(task.getTaskDefinitionKey(), reqVO.getTargetDefinitionKey(), task.getProcessDefinitionId()); @@ -484,24 +471,29 @@ public class BpmTaskServiceImpl implements BpmTaskService { @Override @Transactional(rollbackFor = Exception.class) - public void delegateTask(BpmTaskDelegateReqVO reqVO,Long userId) { - // 校验任务 - Task task = this.validateTaskDelegate(reqVO); - // 添加审批意见 - AdminUserRespDTO currentUser = adminUserApi.getUser(userId); + public void delegateTask(BpmTaskDelegateReqVO reqVO, Long userId) { + // 1.1 校验任务 + Task task = validateTaskCanDelegate(userId, reqVO); + // 1.2 校验目标用户存在 AdminUserRespDTO delegateUser = adminUserApi.getUser(reqVO.getDelegateUserId()); if (delegateUser == null) { - throw exception(TASK_DELEGATE_USER_NULL); + throw exception(TASK_DELEGATE_FAIL_USER_NOT_EXISTS); } + + // 2. 添加审批意见 + AdminUserRespDTO currentUser = adminUserApi.getUser(userId); String comment = StrUtil.format("[{}]将任务委派给[{}],委派理由为:{}", currentUser.getNickname(), delegateUser.getNickname(), reqVO.getReason()); String taskId = reqVO.getId(); - taskService.addComment(taskId, task.getProcessInstanceId(), BpmProcessInstanceResultEnum.DELEGATE.getResult().toString(), comment); - // 设置任务所有人 (owner) 为原任务的处理人 (assignee) + // TODO 海:后面改;感觉 comment 应该 type 做个枚举;不和 result 耦合在一起; + taskService.addComment(taskId, task.getProcessInstanceId(), + BpmProcessInstanceResultEnum.DELEGATE.getResult().toString(), comment); + + // 3.1 设置任务所有人 (owner) 为原任务的处理人 (assignee) taskService.setOwner(taskId, task.getAssignee()); - // 执行委派,将任务委派给 receiveId + // 3.2 执行委派,将任务委派给 receiveId taskService.delegateTask(taskId, reqVO.getDelegateUserId().toString()); - // 更新任务拓展表为【委派】 + // 3.3 更新任务拓展表为【委派】 taskExtMapper.updateByTaskId( new BpmTaskExtDO().setTaskId(task.getId()).setResult(BpmProcessInstanceResultEnum.DELEGATE.getResult()) .setReason(reqVO.getReason())); @@ -510,16 +502,18 @@ public class BpmTaskServiceImpl implements BpmTaskService { /** * 校验任务委派参数 * + * @param userId 用户编号 * @param reqVO 任务编号,接收人ID * @return 当前任务信息 */ - private Task validateTaskDelegate(BpmTaskDelegateReqVO reqVO) { + private Task validateTaskCanDelegate(Long userId, BpmTaskDelegateReqVO reqVO) { // 校验任务 - Task task = checkTask(WebFrameworkUtils.getLoginUserId(), reqVO.getId()); - //校验当前审批人和被委派人不是同一人 + Task task = validateTask(userId, reqVO.getId()); + // 校验当前审批人和被委派人不是同一人 if (task.getAssignee().equals(reqVO.getDelegateUserId().toString())) { - throw exception(TASK_DELEGATE_USER_REPEAT); + throw exception(TASK_DELEGATE_FAIL_USER_REPEAT); } return task; } + }