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,9 +17,9 @@ import java.util.Arrays;
17 public enum BpmUserTaskApproveMethodEnum implements IntArrayValuable { 17 public enum BpmUserTaskApproveMethodEnum implements IntArrayValuable {
18 18
19 RANDOM(1, "随机挑选一人审批", null), 19 RANDOM(1, "随机挑选一人审批", null),
20 - RATIO(2, "多人会签(按通过比例)", "${ nrOfCompletedInstances >= nrOfInstances }"), // 会签(按通过比例) 20 + RATIO(2, "多人会签(按通过比例)", "${ nrOfCompletedInstances/nrOfInstances >= %s}"), // 会签(按通过比例)
21 ANY(3, "多人或签(一人通过或拒绝)", "${ nrOfCompletedInstances > 0 }"), // 或签(通过只需一人,拒绝只需一人) 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,19 +10,17 @@ import lombok.Data;
10 @Data 10 @Data
11 public class BpmApprovalDetailReqVO { 11 public class BpmApprovalDetailReqVO {
12 12
13 - // TODO @jason:这里要不注释说明下,什么情况下,使用 processDefinitionId、processInstanceId、activityId、taskId。  
14 -  
15 @Schema(description = "流程定义的编号", example = "1024") 13 @Schema(description = "流程定义的编号", example = "1024")
16 - private String processDefinitionId; 14 + private String processDefinitionId; // 发起流程的时候传流程定义 Id
17 15
18 @Schema(description = "流程实例的编号", example = "1024") 16 @Schema(description = "流程实例的编号", example = "1024")
19 - private String processInstanceId; 17 + private String processInstanceId; // 流程已发起时候传流程实例 Id
20 18
21 @Schema(description = "流程活动编号", example = "StartUserNode") 19 @Schema(description = "流程活动编号", example = "StartUserNode")
22 - private String activityId; // 对应 BPMN XML 节点 Id 20 + private String activityId; // 用于获取表单权限。 发起流程时, 传‘发起人节点’ activityId 可获取发起人的表单权限
23 21
24 @Schema(description = "流程任务编号", example = "95f2f08b-621b-11ef-bf39-00ff4722db8b") 22 @Schema(description = "流程任务编号", example = "95f2f08b-621b-11ef-bf39-00ff4722db8b")
25 - private String taskId; // 对应的 UserTask Id 23 + private String taskId; // 用于获取表单权限。流程已发起时,传任务 Id, 获取任务节点的变得权限
26 24
27 @AssertTrue(message = "流程定义的编号和流程实例的编号不能同时为空") 25 @AssertTrue(message = "流程定义的编号和流程实例的编号不能同时为空")
28 @JsonIgnore 26 @JsonIgnore
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/convert/task/BpmTaskConvert.java
1 package cn.iocoder.yudao.module.bpm.convert.task; 1 package cn.iocoder.yudao.module.bpm.convert.task;
2 2
  3 +import cn.hutool.core.collection.CollUtil;
3 import cn.hutool.core.map.MapUtil; 4 import cn.hutool.core.map.MapUtil;
4 import cn.hutool.core.util.StrUtil; 5 import cn.hutool.core.util.StrUtil;
5 import cn.iocoder.yudao.framework.common.pojo.PageResult; 6 import cn.iocoder.yudao.framework.common.pojo.PageResult;
@@ -101,21 +102,13 @@ public interface BpmTaskConvert { @@ -101,21 +102,13 @@ public interface BpmTaskConvert {
101 .setFormFields(form.getFields()).setFormVariables(FlowableUtils.getTaskFormVariable(task)); 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 taskVO.setButtonsSetting(BpmnModelUtils.parseButtonsSetting(bpmnModel, task.getTaskDefinitionKey())); 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,6 +151,41 @@ public interface BpmTaskConvert {
158 return reqDTO; 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 * <p> 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,7 +33,7 @@ public interface BpmTaskService {
33 PageResult<Task> getTaskTodoPage(Long userId, BpmTaskPageReqVO pageReqVO); 33 PageResult<Task> getTaskTodoPage(Long userId, BpmTaskPageReqVO pageReqVO);
34 34
35 /** 35 /**
36 - * 获得用户在指定流程下,收个需要处理(待办)的任务 36 + * 获得用户在指定流程下,首个需要处理(待办)的任务
37 * 37 *
38 * @param userId 用户编号 38 * @param userId 用户编号
39 * @param processInstanceId 流程实例编号 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,7 +11,6 @@ import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
11 import cn.iocoder.yudao.framework.common.util.object.ObjectUtils; 11 import cn.iocoder.yudao.framework.common.util.object.ObjectUtils;
12 import cn.iocoder.yudao.framework.common.util.object.PageUtils; 12 import cn.iocoder.yudao.framework.common.util.object.PageUtils;
13 import cn.iocoder.yudao.framework.web.core.util.WebFrameworkUtils; 13 import cn.iocoder.yudao.framework.web.core.util.WebFrameworkUtils;
14 -import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance.BpmProcessInstanceRespVO;  
15 import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.task.*; 14 import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.task.*;
16 import cn.iocoder.yudao.module.bpm.convert.task.BpmTaskConvert; 15 import cn.iocoder.yudao.module.bpm.convert.task.BpmTaskConvert;
17 import cn.iocoder.yudao.module.bpm.enums.definition.*; 16 import cn.iocoder.yudao.module.bpm.enums.definition.*;
@@ -60,7 +59,6 @@ import java.util.stream.Stream; @@ -60,7 +59,6 @@ import java.util.stream.Stream;
60 59
61 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; 60 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
62 import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.*; 61 import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.*;
63 -import static cn.iocoder.yudao.framework.common.util.collection.MapUtils.findAndThen;  
64 import static cn.iocoder.yudao.module.bpm.enums.ErrorCodeConstants.*; 62 import static cn.iocoder.yudao.module.bpm.enums.ErrorCodeConstants.*;
65 import static cn.iocoder.yudao.module.bpm.framework.flowable.core.enums.BpmnVariableConstants.PROCESS_INSTANCE_VARIABLE_RETURN_FLAG; 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,41 +156,18 @@ public class BpmTaskServiceImpl implements BpmTaskService {
158 BpmnModel bpmnModel = bpmProcessDefinitionService.getProcessDefinitionBpmnModel(processInstance.getProcessDefinitionId()); 156 BpmnModel bpmnModel = bpmProcessDefinitionService.getProcessDefinitionBpmnModel(processInstance.getProcessDefinitionId());
159 List<BpmTaskRespVO> taskList = convertList(todoList, task -> { 157 List<BpmTaskRespVO> taskList = convertList(todoList, task -> {
160 // 找到分配给当前用户,或者当前用户加签的任务(为了减签) 158 // 找到分配给当前用户,或者当前用户加签的任务(为了减签)
161 - // TODO @jason:1)可以抽个小方法,判断是否是当前用户的任务;2)尽量不做取反,而是通过 ObjUtil.notEquals 。  
162 // TODO 3)(!userId.equals(NumberUtil.parseLong(task.getOwner(), null)) || BpmTaskSignTypeEnum.of(task.getScopeType()) == null) 这个判断的目的是啥? 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 return null; 162 return null;
166 } 163 }
167 BpmTaskRespVO taskVO = BeanUtils.toBean(task, BpmTaskRespVO.class); 164 BpmTaskRespVO taskVO = BeanUtils.toBean(task, BpmTaskRespVO.class);
168 taskVO.setStatus(FlowableUtils.getTaskStatus(task)).setReason(FlowableUtils.getTaskReason(task)); 165 taskVO.setStatus(FlowableUtils.getTaskStatus(task)).setReason(FlowableUtils.getTaskReason(task));
169 taskVO.setButtonsSetting(BpmnModelUtils.parseButtonsSetting(bpmnModel, task.getTaskDefinitionKey())); 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 return taskVO; 173 return taskVO;
@@ -200,6 +175,21 @@ public class BpmTaskServiceImpl implements BpmTaskService { @@ -200,6 +175,21 @@ public class BpmTaskServiceImpl implements BpmTaskService {
200 return findFirst(taskList, Objects::nonNull); 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 @Override 193 @Override
204 public PageResult<HistoricTaskInstance> getTaskDonePage(Long userId, BpmTaskPageReqVO pageVO) { 194 public PageResult<HistoricTaskInstance> getTaskDonePage(Long userId, BpmTaskPageReqVO pageVO) {
205 HistoricTaskInstanceQuery taskQuery = historyService.createHistoricTaskInstanceQuery() 195 HistoricTaskInstanceQuery taskQuery = historyService.createHistoricTaskInstanceQuery()