From 8469b2b8cb7e54fbee344ab26370b0edcbc492b2 Mon Sep 17 00:00:00 2001 From: jason <2667446@qq.com> Date: Fri, 18 Oct 2024 23:35:18 +0800 Subject: [PATCH] =?UTF-8?q?=E3=80=90=E4=BB=A3=E7=A0=81=E8=AF=84=E5=AE=A1?= =?UTF-8?q?=E4=BF=AE=E6=94=B9=E3=80=91=20getTodoTask=20=E8=AF=84=E5=AE=A1?= =?UTF-8?q?=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../BpmUserTaskApproveMethodEnum.java | 4 +- .../vo/instance/BpmApprovalDetailReqVO.java | 10 ++-- .../bpm/convert/task/BpmTaskConvert.java | 52 ++++++++++++++----- .../bpm/service/task/BpmTaskService.java | 2 +- .../bpm/service/task/BpmTaskServiceImpl.java | 52 ++++++++----------- 5 files changed, 68 insertions(+), 52 deletions(-) diff --git a/yudao-module-bpm/yudao-module-bpm-api/src/main/java/cn/iocoder/yudao/module/bpm/enums/definition/BpmUserTaskApproveMethodEnum.java b/yudao-module-bpm/yudao-module-bpm-api/src/main/java/cn/iocoder/yudao/module/bpm/enums/definition/BpmUserTaskApproveMethodEnum.java index 01b19f2fa..1089f181d 100644 --- a/yudao-module-bpm/yudao-module-bpm-api/src/main/java/cn/iocoder/yudao/module/bpm/enums/definition/BpmUserTaskApproveMethodEnum.java +++ b/yudao-module-bpm/yudao-module-bpm-api/src/main/java/cn/iocoder/yudao/module/bpm/enums/definition/BpmUserTaskApproveMethodEnum.java @@ -17,9 +17,9 @@ import java.util.Arrays; public enum BpmUserTaskApproveMethodEnum implements IntArrayValuable { RANDOM(1, "随机挑选一人审批", null), - RATIO(2, "多人会签(按通过比例)", "${ nrOfCompletedInstances >= nrOfInstances }"), // 会签(按通过比例) + RATIO(2, "多人会签(按通过比例)", "${ nrOfCompletedInstances/nrOfInstances >= %s}"), // 会签(按通过比例) ANY(3, "多人或签(一人通过或拒绝)", "${ nrOfCompletedInstances > 0 }"), // 或签(通过只需一人,拒绝只需一人) - SEQUENTIAL(4, "依次审批", "${ nrOfCompletedInstances/nrOfInstances >= %s}"); // 依次审批 + SEQUENTIAL(4, "依次审批", "${ nrOfCompletedInstances >= nrOfInstances }"); // 依次审批 /** * 审批方式 diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/instance/BpmApprovalDetailReqVO.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/instance/BpmApprovalDetailReqVO.java index 271c42f51..36bd35bb6 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/instance/BpmApprovalDetailReqVO.java +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/instance/BpmApprovalDetailReqVO.java @@ -10,19 +10,17 @@ import lombok.Data; @Data public class BpmApprovalDetailReqVO { - // TODO @jason:这里要不注释说明下,什么情况下,使用 processDefinitionId、processInstanceId、activityId、taskId。 - @Schema(description = "流程定义的编号", example = "1024") - private String processDefinitionId; + private String processDefinitionId; // 发起流程的时候传流程定义 Id @Schema(description = "流程实例的编号", example = "1024") - private String processInstanceId; + private String processInstanceId; // 流程已发起时候传流程实例 Id @Schema(description = "流程活动编号", example = "StartUserNode") - private String activityId; // 对应 BPMN XML 节点 Id + private String activityId; // 用于获取表单权限。 发起流程时, 传‘发起人节点’ activityId 可获取发起人的表单权限 @Schema(description = "流程任务编号", example = "95f2f08b-621b-11ef-bf39-00ff4722db8b") - private String taskId; // 对应的 UserTask Id + private String taskId; // 用于获取表单权限。流程已发起时,传任务 Id, 获取任务节点的变得权限 @AssertTrue(message = "流程定义的编号和流程实例的编号不能同时为空") @JsonIgnore diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/convert/task/BpmTaskConvert.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/convert/task/BpmTaskConvert.java index fa672c8dd..2665bb0b9 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/convert/task/BpmTaskConvert.java +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/convert/task/BpmTaskConvert.java @@ -1,5 +1,6 @@ package cn.iocoder.yudao.module.bpm.convert.task; +import cn.hutool.core.collection.CollUtil; import cn.hutool.core.map.MapUtil; import cn.hutool.core.util.StrUtil; import cn.iocoder.yudao.framework.common.pojo.PageResult; @@ -101,21 +102,13 @@ public interface BpmTaskConvert { .setFormFields(form.getFields()).setFormVariables(FlowableUtils.getTaskFormVariable(task)); } // 用户信息 - AdminUserRespDTO assignUser = userMap.get(NumberUtils.parseLong(task.getAssignee())); - if (assignUser != null) { - taskVO.setAssigneeUser(BeanUtils.toBean(assignUser, BpmProcessInstanceRespVO.User.class)); - findAndThen(deptMap, assignUser.getDeptId(), dept -> taskVO.getAssigneeUser().setDeptName(dept.getName())); - } - AdminUserRespDTO ownerUser = userMap.get(NumberUtils.parseLong(task.getOwner())); - if (ownerUser != null) { - taskVO.setOwnerUser(BeanUtils.toBean(ownerUser, BpmProcessInstanceRespVO.User.class)); - findAndThen(deptMap, ownerUser.getDeptId(), dept -> taskVO.getOwnerUser().setDeptName(dept.getName())); - } - if (BpmTaskStatusEnum.RUNNING.getStatus().equals(taskStatus)){ + buildTaskAssignee(taskVO, task.getAssignee(), userMap, deptMap); + buildTaskOwner(taskVO, task.getOwner(), userMap, deptMap); + if (BpmTaskStatusEnum.RUNNING.getStatus().equals(taskStatus)) { // 操作按钮设置 taskVO.setButtonsSetting(BpmnModelUtils.parseButtonsSetting(bpmnModel, task.getTaskDefinitionKey())); } - return taskVO; + return taskVO; }); // 拼接父子关系 @@ -158,6 +151,41 @@ public interface BpmTaskConvert { return reqDTO; } + default void buildTaskOwner(BpmTaskRespVO task, String taskOwner, + Map userMap, + Map deptMap) { + AdminUserRespDTO ownerUser = userMap.get(NumberUtils.parseLong(taskOwner)); + if (ownerUser != null) { + task.setOwnerUser(BeanUtils.toBean(ownerUser, BpmProcessInstanceRespVO.User.class)); + findAndThen(deptMap, ownerUser.getDeptId(), dept -> task.getOwnerUser().setDeptName(dept.getName())); + } + } + + default void buildTaskChildren(BpmTaskRespVO task, Map> childrenTaskMap, + Map userMap, Map deptMap) { + List childTasks = childrenTaskMap.get(task.getId()); + if (CollUtil.isNotEmpty(childTasks)) { + task.setChildren( + convertList(childTasks, childTask -> { + BpmTaskRespVO childTaskVO = BeanUtils.toBean(childTask, BpmTaskRespVO.class); + childTaskVO.setStatus(FlowableUtils.getTaskStatus(childTask)); + buildTaskAssignee(childTaskVO, childTask.getAssignee(), userMap, deptMap); + return childTaskVO; + }) + ); + } + } + + default void buildTaskAssignee(BpmTaskRespVO task, String taskAssignee, + Map userMap, + Map deptMap) { + AdminUserRespDTO assignUser = userMap.get(NumberUtils.parseLong(taskAssignee)); + if (assignUser != null) { + task.setAssigneeUser(BeanUtils.toBean(assignUser, BpmProcessInstanceRespVO.User.class)); + findAndThen(deptMap, assignUser.getDeptId(), dept -> task.getAssigneeUser().setDeptName(dept.getName())); + } + } + /** * 将父任务的属性,拷贝到子任务(加签任务) *

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 eae1a21b7..e92f43ac3 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 @@ -33,7 +33,7 @@ public interface BpmTaskService { PageResult getTaskTodoPage(Long userId, BpmTaskPageReqVO pageReqVO); /** - * 获得用户在指定流程下,收个需要处理(待办)的任务 + * 获得用户在指定流程下,首个需要处理(待办)的任务 * * @param userId 用户编号 * @param processInstanceId 流程实例编号 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 6795891fa..70626a03e 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 @@ -11,7 +11,6 @@ import cn.iocoder.yudao.framework.common.util.object.BeanUtils; import cn.iocoder.yudao.framework.common.util.object.ObjectUtils; import cn.iocoder.yudao.framework.common.util.object.PageUtils; import cn.iocoder.yudao.framework.web.core.util.WebFrameworkUtils; -import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance.BpmProcessInstanceRespVO; import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.task.*; import cn.iocoder.yudao.module.bpm.convert.task.BpmTaskConvert; import cn.iocoder.yudao.module.bpm.enums.definition.*; @@ -60,7 +59,6 @@ import java.util.stream.Stream; import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.*; -import static cn.iocoder.yudao.framework.common.util.collection.MapUtils.findAndThen; import static cn.iocoder.yudao.module.bpm.enums.ErrorCodeConstants.*; import static cn.iocoder.yudao.module.bpm.framework.flowable.core.enums.BpmnVariableConstants.PROCESS_INSTANCE_VARIABLE_RETURN_FLAG; @@ -158,41 +156,18 @@ public class BpmTaskServiceImpl implements BpmTaskService { BpmnModel bpmnModel = bpmProcessDefinitionService.getProcessDefinitionBpmnModel(processInstance.getProcessDefinitionId()); List taskList = convertList(todoList, task -> { // 找到分配给当前用户,或者当前用户加签的任务(为了减签) - // TODO @jason:1)可以抽个小方法,判断是否是当前用户的任务;2)尽量不做取反,而是通过 ObjUtil.notEquals 。 // TODO 3)(!userId.equals(NumberUtil.parseLong(task.getOwner(), null)) || BpmTaskSignTypeEnum.of(task.getScopeType()) == null) 这个判断的目的是啥? - if (!userId.equals(NumberUtil.parseLong(task.getAssignee(), null)) && - (!userId.equals(NumberUtil.parseLong(task.getOwner(), null)) || BpmTaskSignTypeEnum.of(task.getScopeType()) == null)) { + // @芋艿 !isAddSignTask(userId, task) 该判断的目的被用户加签的任务。该用户可以进行减签操作 + if (!isAssignUserTask(userId, task) && !isAddSignTask(userId, task)) { return null; } BpmTaskRespVO taskVO = BeanUtils.toBean(task, BpmTaskRespVO.class); taskVO.setStatus(FlowableUtils.getTaskStatus(task)).setReason(FlowableUtils.getTaskReason(task)); taskVO.setButtonsSetting(BpmnModelUtils.parseButtonsSetting(bpmnModel, task.getTaskDefinitionKey())); - AdminUserRespDTO ownerUser = userMap.get(NumberUtils.parseLong(task.getOwner())); - if (ownerUser != null) { - taskVO.setOwnerUser(BeanUtils.toBean(ownerUser, BpmProcessInstanceRespVO.User.class)); - findAndThen(deptMap, ownerUser.getDeptId(), dept -> taskVO.getOwnerUser().setDeptName(dept.getName())); - } - // 当前用户加签的任务. 找到它的子任务 (为了减签) - // TODO @json:这里最好也抽个小方法,userId.equals(NumberUtil.parseLong(task.getOwner(), null)) - // && BpmTaskSignTypeEnum.of(task.getScopeType()) != null - if (userId.equals(NumberUtil.parseLong(task.getOwner(), null)) - && BpmTaskSignTypeEnum.of(task.getScopeType()) != null) { - // TODO @jason:170 到 173,和 181 到 192 这段拼接的逻辑,可以拿到 convert 里面。这样,这块 Service 更聚焦。 - List childTasks = childrenTaskMap.get(task.getId()); - if (CollUtil.isNotEmpty(childTasks)) { - taskVO.setChildren( - convertList(childTasks, childTask -> { - BpmTaskRespVO childTaskVO = BeanUtils.toBean(task, BpmTaskRespVO.class); - childTaskVO.setStatus(FlowableUtils.getTaskStatus(task)); - AdminUserRespDTO assignUser = userMap.get(NumberUtils.parseLong(childTask.getAssignee())); - if (assignUser != null) { - childTaskVO.setAssigneeUser(BeanUtils.toBean(assignUser, BpmProcessInstanceRespVO.User.class)); - findAndThen(deptMap, assignUser.getDeptId(), dept -> childTaskVO.getAssigneeUser().setDeptName(dept.getName())); - } - return childTaskVO; - }) - ); - } + BpmTaskConvert.INSTANCE.buildTaskOwner(taskVO, task.getOwner(), userMap, deptMap); + // 如果是被加签的任务. 找到它的子任务 (为了减签) + if (isAddSignTask(userId, task)) { + BpmTaskConvert.INSTANCE.buildTaskChildren(taskVO, childrenTaskMap, userMap, deptMap); } return taskVO; @@ -200,6 +175,21 @@ public class BpmTaskServiceImpl implements BpmTaskService { return findFirst(taskList, Objects::nonNull); } + /** + * 判断是否为被分配给用户的任务 + */ + private boolean isAssignUserTask(Long userId, Task task) { + return ObjectUtil.equal(userId, NumberUtil.parseLong(task.getAssignee(), null)); + } + + /** + * 判断是否为被用户加签的任务 + */ + private boolean isAddSignTask(Long userId, Task task) { + return userId.equals(NumberUtil.parseLong(task.getOwner(), null)) + && BpmTaskSignTypeEnum.of(task.getScopeType()) != null; + } + @Override public PageResult getTaskDonePage(Long userId, BpmTaskPageReqVO pageVO) { HistoricTaskInstanceQuery taskQuery = historyService.createHistoricTaskInstanceQuery()