Commit 8469b2b8cb7e54fbee344ab26370b0edcbc492b2

Authored by jason
1 parent 7b57c7d0

【代码评审修改】 getTodoTask 评审修改

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;
17 17 public enum BpmUserTaskApproveMethodEnum implements IntArrayValuable {
18 18  
19 19 RANDOM(1, "随机挑选一人审批", null),
20   - RATIO(2, "多人会签(按通过比例)", "${ nrOfCompletedInstances >= nrOfInstances }"), // 会签(按通过比例)
  20 + RATIO(2, "多人会签(按通过比例)", "${ nrOfCompletedInstances/nrOfInstances >= %s}"), // 会签(按通过比例)
21 21 ANY(3, "多人或签(一人通过或拒绝)", "${ nrOfCompletedInstances > 0 }"), // 或签(通过只需一人,拒绝只需一人)
22   - SEQUENTIAL(4, "依次审批", "${ nrOfCompletedInstances/nrOfInstances >= %s}"); // 依次审批
  22 + SEQUENTIAL(4, "依次审批", "${ nrOfCompletedInstances >= nrOfInstances }"); // 依次审批
23 23  
24 24 /**
25 25 * 审批方式
... ...
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;
10 10 @Data
11 11 public class BpmApprovalDetailReqVO {
12 12  
13   - // TODO @jason:这里要不注释说明下,什么情况下,使用 processDefinitionId、processInstanceId、activityId、taskId。
14   -
15 13 @Schema(description = "流程定义的编号", example = "1024")
16   - private String processDefinitionId;
  14 + private String processDefinitionId; // 发起流程的时候传流程定义 Id
17 15  
18 16 @Schema(description = "流程实例的编号", example = "1024")
19   - private String processInstanceId;
  17 + private String processInstanceId; // 流程已发起时候传流程实例 Id
20 18  
21 19 @Schema(description = "流程活动编号", example = "StartUserNode")
22   - private String activityId; // 对应 BPMN XML 节点 Id
  20 + private String activityId; // 用于获取表单权限。 发起流程时, 传‘发起人节点’ activityId 可获取发起人的表单权限
23 21  
24 22 @Schema(description = "流程任务编号", example = "95f2f08b-621b-11ef-bf39-00ff4722db8b")
25   - private String taskId; // 对应的 UserTask Id
  23 + private String taskId; // 用于获取表单权限。流程已发起时,传任务 Id, 获取任务节点的变得权限
26 24  
27 25 @AssertTrue(message = "流程定义的编号和流程实例的编号不能同时为空")
28 26 @JsonIgnore
... ...
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/convert/task/BpmTaskConvert.java
1 1 package cn.iocoder.yudao.module.bpm.convert.task;
2 2  
  3 +import cn.hutool.core.collection.CollUtil;
3 4 import cn.hutool.core.map.MapUtil;
4 5 import cn.hutool.core.util.StrUtil;
5 6 import cn.iocoder.yudao.framework.common.pojo.PageResult;
... ... @@ -101,21 +102,13 @@ public interface BpmTaskConvert {
101 102 .setFormFields(form.getFields()).setFormVariables(FlowableUtils.getTaskFormVariable(task));
102 103 }
103 104 // 用户信息
104   - AdminUserRespDTO assignUser = userMap.get(NumberUtils.parseLong(task.getAssignee()));
105   - if (assignUser != null) {
106   - taskVO.setAssigneeUser(BeanUtils.toBean(assignUser, BpmProcessInstanceRespVO.User.class));
107   - findAndThen(deptMap, assignUser.getDeptId(), dept -> taskVO.getAssigneeUser().setDeptName(dept.getName()));
108   - }
109   - AdminUserRespDTO ownerUser = userMap.get(NumberUtils.parseLong(task.getOwner()));
110   - if (ownerUser != null) {
111   - taskVO.setOwnerUser(BeanUtils.toBean(ownerUser, BpmProcessInstanceRespVO.User.class));
112   - findAndThen(deptMap, ownerUser.getDeptId(), dept -> taskVO.getOwnerUser().setDeptName(dept.getName()));
113   - }
114   - if (BpmTaskStatusEnum.RUNNING.getStatus().equals(taskStatus)){
  105 + buildTaskAssignee(taskVO, task.getAssignee(), userMap, deptMap);
  106 + buildTaskOwner(taskVO, task.getOwner(), userMap, deptMap);
  107 + if (BpmTaskStatusEnum.RUNNING.getStatus().equals(taskStatus)) {
115 108 // 操作按钮设置
116 109 taskVO.setButtonsSetting(BpmnModelUtils.parseButtonsSetting(bpmnModel, task.getTaskDefinitionKey()));
117 110 }
118   - return taskVO;
  111 + return taskVO;
119 112 });
120 113  
121 114 // 拼接父子关系
... ... @@ -158,6 +151,41 @@ public interface BpmTaskConvert {
158 151 return reqDTO;
159 152 }
160 153  
  154 + default void buildTaskOwner(BpmTaskRespVO task, String taskOwner,
  155 + Map<Long, AdminUserRespDTO> userMap,
  156 + Map<Long, DeptRespDTO> deptMap) {
  157 + AdminUserRespDTO ownerUser = userMap.get(NumberUtils.parseLong(taskOwner));
  158 + if (ownerUser != null) {
  159 + task.setOwnerUser(BeanUtils.toBean(ownerUser, BpmProcessInstanceRespVO.User.class));
  160 + findAndThen(deptMap, ownerUser.getDeptId(), dept -> task.getOwnerUser().setDeptName(dept.getName()));
  161 + }
  162 + }
  163 +
  164 + default void buildTaskChildren(BpmTaskRespVO task, Map<String, List<Task>> childrenTaskMap,
  165 + Map<Long, AdminUserRespDTO> userMap, Map<Long, DeptRespDTO> deptMap) {
  166 + List<Task> childTasks = childrenTaskMap.get(task.getId());
  167 + if (CollUtil.isNotEmpty(childTasks)) {
  168 + task.setChildren(
  169 + convertList(childTasks, childTask -> {
  170 + BpmTaskRespVO childTaskVO = BeanUtils.toBean(childTask, BpmTaskRespVO.class);
  171 + childTaskVO.setStatus(FlowableUtils.getTaskStatus(childTask));
  172 + buildTaskAssignee(childTaskVO, childTask.getAssignee(), userMap, deptMap);
  173 + return childTaskVO;
  174 + })
  175 + );
  176 + }
  177 + }
  178 +
  179 + default void buildTaskAssignee(BpmTaskRespVO task, String taskAssignee,
  180 + Map<Long, AdminUserRespDTO> userMap,
  181 + Map<Long, DeptRespDTO> deptMap) {
  182 + AdminUserRespDTO assignUser = userMap.get(NumberUtils.parseLong(taskAssignee));
  183 + if (assignUser != null) {
  184 + task.setAssigneeUser(BeanUtils.toBean(assignUser, BpmProcessInstanceRespVO.User.class));
  185 + findAndThen(deptMap, assignUser.getDeptId(), dept -> task.getAssigneeUser().setDeptName(dept.getName()));
  186 + }
  187 + }
  188 +
161 189 /**
162 190 * 将父任务的属性,拷贝到子任务(加签任务)
163 191 * <p>
... ...
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 {
33 33 PageResult<Task> getTaskTodoPage(Long userId, BpmTaskPageReqVO pageReqVO);
34 34  
35 35 /**
36   - * 获得用户在指定流程下,收个需要处理(待办)的任务
  36 + * 获得用户在指定流程下,首个需要处理(待办)的任务
37 37 *
38 38 * @param userId 用户编号
39 39 * @param processInstanceId 流程实例编号
... ...
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;
11 11 import cn.iocoder.yudao.framework.common.util.object.ObjectUtils;
12 12 import cn.iocoder.yudao.framework.common.util.object.PageUtils;
13 13 import cn.iocoder.yudao.framework.web.core.util.WebFrameworkUtils;
14   -import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance.BpmProcessInstanceRespVO;
15 14 import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.task.*;
16 15 import cn.iocoder.yudao.module.bpm.convert.task.BpmTaskConvert;
17 16 import cn.iocoder.yudao.module.bpm.enums.definition.*;
... ... @@ -60,7 +59,6 @@ import java.util.stream.Stream;
60 59  
61 60 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
62 61 import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.*;
63   -import static cn.iocoder.yudao.framework.common.util.collection.MapUtils.findAndThen;
64 62 import static cn.iocoder.yudao.module.bpm.enums.ErrorCodeConstants.*;
65 63 import static cn.iocoder.yudao.module.bpm.framework.flowable.core.enums.BpmnVariableConstants.PROCESS_INSTANCE_VARIABLE_RETURN_FLAG;
66 64  
... ... @@ -158,41 +156,18 @@ public class BpmTaskServiceImpl implements BpmTaskService {
158 156 BpmnModel bpmnModel = bpmProcessDefinitionService.getProcessDefinitionBpmnModel(processInstance.getProcessDefinitionId());
159 157 List<BpmTaskRespVO> taskList = convertList(todoList, task -> {
160 158 // 找到分配给当前用户,或者当前用户加签的任务(为了减签)
161   - // TODO @jason:1)可以抽个小方法,判断是否是当前用户的任务;2)尽量不做取反,而是通过 ObjUtil.notEquals 。
162 159 // TODO 3)(!userId.equals(NumberUtil.parseLong(task.getOwner(), null)) || BpmTaskSignTypeEnum.of(task.getScopeType()) == null) 这个判断的目的是啥?
163   - if (!userId.equals(NumberUtil.parseLong(task.getAssignee(), null)) &&
164   - (!userId.equals(NumberUtil.parseLong(task.getOwner(), null)) || BpmTaskSignTypeEnum.of(task.getScopeType()) == null)) {
  160 + // @芋艿 !isAddSignTask(userId, task) 该判断的目的被用户加签的任务。该用户可以进行减签操作
  161 + if (!isAssignUserTask(userId, task) && !isAddSignTask(userId, task)) {
165 162 return null;
166 163 }
167 164 BpmTaskRespVO taskVO = BeanUtils.toBean(task, BpmTaskRespVO.class);
168 165 taskVO.setStatus(FlowableUtils.getTaskStatus(task)).setReason(FlowableUtils.getTaskReason(task));
169 166 taskVO.setButtonsSetting(BpmnModelUtils.parseButtonsSetting(bpmnModel, task.getTaskDefinitionKey()));
170   - AdminUserRespDTO ownerUser = userMap.get(NumberUtils.parseLong(task.getOwner()));
171   - if (ownerUser != null) {
172   - taskVO.setOwnerUser(BeanUtils.toBean(ownerUser, BpmProcessInstanceRespVO.User.class));
173   - findAndThen(deptMap, ownerUser.getDeptId(), dept -> taskVO.getOwnerUser().setDeptName(dept.getName()));
174   - }
175   - // 当前用户加签的任务. 找到它的子任务 (为了减签)
176   - // TODO @json:这里最好也抽个小方法,userId.equals(NumberUtil.parseLong(task.getOwner(), null))
177   - // && BpmTaskSignTypeEnum.of(task.getScopeType()) != null
178   - if (userId.equals(NumberUtil.parseLong(task.getOwner(), null))
179   - && BpmTaskSignTypeEnum.of(task.getScopeType()) != null) {
180   - // TODO @jason:170 到 173,和 181 到 192 这段拼接的逻辑,可以拿到 convert 里面。这样,这块 Service 更聚焦。
181   - List<Task> childTasks = childrenTaskMap.get(task.getId());
182   - if (CollUtil.isNotEmpty(childTasks)) {
183   - taskVO.setChildren(
184   - convertList(childTasks, childTask -> {
185   - BpmTaskRespVO childTaskVO = BeanUtils.toBean(task, BpmTaskRespVO.class);
186   - childTaskVO.setStatus(FlowableUtils.getTaskStatus(task));
187   - AdminUserRespDTO assignUser = userMap.get(NumberUtils.parseLong(childTask.getAssignee()));
188   - if (assignUser != null) {
189   - childTaskVO.setAssigneeUser(BeanUtils.toBean(assignUser, BpmProcessInstanceRespVO.User.class));
190   - findAndThen(deptMap, assignUser.getDeptId(), dept -> childTaskVO.getAssigneeUser().setDeptName(dept.getName()));
191   - }
192   - return childTaskVO;
193   - })
194   - );
195   - }
  167 + BpmTaskConvert.INSTANCE.buildTaskOwner(taskVO, task.getOwner(), userMap, deptMap);
  168 + // 如果是被加签的任务. 找到它的子任务 (为了减签)
  169 + if (isAddSignTask(userId, task)) {
  170 + BpmTaskConvert.INSTANCE.buildTaskChildren(taskVO, childrenTaskMap, userMap, deptMap);
196 171  
197 172 }
198 173 return taskVO;
... ... @@ -200,6 +175,21 @@ public class BpmTaskServiceImpl implements BpmTaskService {
200 175 return findFirst(taskList, Objects::nonNull);
201 176 }
202 177  
  178 + /**
  179 + * 判断是否为被分配给用户的任务
  180 + */
  181 + private boolean isAssignUserTask(Long userId, Task task) {
  182 + return ObjectUtil.equal(userId, NumberUtil.parseLong(task.getAssignee(), null));
  183 + }
  184 +
  185 + /**
  186 + * 判断是否为被用户加签的任务
  187 + */
  188 + private boolean isAddSignTask(Long userId, Task task) {
  189 + return userId.equals(NumberUtil.parseLong(task.getOwner(), null))
  190 + && BpmTaskSignTypeEnum.of(task.getScopeType()) != null;
  191 + }
  192 +
203 193 @Override
204 194 public PageResult<HistoricTaskInstance> getTaskDonePage(Long userId, BpmTaskPageReqVO pageVO) {
205 195 HistoricTaskInstanceQuery taskQuery = historyService.createHistoricTaskInstanceQuery()
... ...