Commit a4d31f9c453bbaa7e2f7c9d653e3b454be22e84a

Authored by YunaiV
1 parent f9b6eef4

新增 bpm 基于流程实例查询任务列表

yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/controller/task/BpmTaskController.http
... ... @@ -7,3 +7,8 @@ Authorization: Bearer {{token}}
7 7 GET {{baseUrl}}/bpm/task/done-page?pageSize=100
8 8 tenant-id: 1
9 9 Authorization: Bearer {{token}}
  10 +
  11 +### 请求 /bpm/task/list-by-process-instance-id 接口 => 成功
  12 +GET {{baseUrl}}/bpm/task/list-by-process-instance-id?processInstanceId=537cceb3-768c-11ec-afcd-a2380e71991a
  13 +tenant-id: 1
  14 +Authorization: Bearer {{token}}
... ...
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/controller/task/BpmTaskController.java
... ... @@ -57,10 +57,10 @@ public class BpmTaskController {
57 57 }
58 58  
59 59 @GetMapping("/list-by-process-instance-id")
60   - @ApiOperation(value = "获得指定流程实例的任务列表", notes = "包括完成的、未完成的")
  60 + @ApiOperation(value = "获得指定流程实例的任务列表", notes = "包括完成的、未完成的") // TODO 芋艿:注解
61 61 public CommonResult<List<BpmTaskRespVO>> getTaskListByProcessInstanceId(
62 62 @RequestParam("processInstanceId") String processInstanceId) {
63   - return success(taskService.getTaskSteps(taskQuery));
  63 + return success(taskService.getTaskListByProcessInstanceId(processInstanceId));
64 64 }
65 65  
66 66 /**
... ...
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/controller/task/vo/task/BpmTaskDonePageItemRespVO.java
... ... @@ -3,24 +3,17 @@ package cn.iocoder.yudao.adminserver.modules.bpm.controller.task.vo.task;
3 3 import io.swagger.annotations.ApiModel;
4 4 import io.swagger.annotations.ApiModelProperty;
5 5 import lombok.Data;
  6 +import lombok.EqualsAndHashCode;
  7 +import lombok.ToString;
6 8  
7 9 import java.util.Date;
8 10  
9 11 @ApiModel("流程任务的 Done 已完成的分页项 Response VO")
10 12 @Data
11   -public class BpmTaskDonePageItemRespVO {
  13 +@EqualsAndHashCode(callSuper = true)
  14 +@ToString(callSuper = true)
  15 +public class BpmTaskDonePageItemRespVO extends BpmTaskTodoPageItemRespVO {
12 16  
13   - @ApiModelProperty(value = "任务编号", required = true, example = "1024")
14   - private String id;
15   -
16   - @ApiModelProperty(value = "任务名字", required = true, example = "芋道")
17   - private String name;
18   -
19   - @ApiModelProperty(value = "接收时间", required = true)
20   - private Date claimTime;
21   -
22   - @ApiModelProperty(value = "创建时间", required = true)
23   - private Date createTime;
24 17 @ApiModelProperty(value = "结束时间", required = true)
25 18 private Date endTime;
26 19 @ApiModelProperty(value = "持续时间", required = true, example = "1000")
... ... @@ -31,30 +24,4 @@ public class BpmTaskDonePageItemRespVO {
31 24 @ApiModelProperty(value = "审批建议", required = true, example = "不请假了!")
32 25 private String comment;
33 26  
34   - /**
35   - * 所属流程实例
36   - */
37   - private ProcessInstance processInstance;
38   -
39   - @Data
40   - @ApiModel("流程实例")
41   - public static class ProcessInstance {
42   -
43   - @ApiModelProperty(value = "流程实例编号", required = true, example = "1024")
44   - private String id;
45   -
46   - @ApiModelProperty(value = "流程实例名称", required = true, example = "芋道")
47   - private String name;
48   -
49   - @ApiModelProperty(value = "发起人的用户编号", required = true, example = "1024")
50   - private Long startUserId;
51   -
52   - @ApiModelProperty(value = "发起人的用户昵称", required = true, example = "芋艿")
53   - private String startUserNickname;
54   -
55   - @ApiModelProperty(value = "流程定义的编号", required = true, example = "2048")
56   - private String processDefinitionId;
57   -
58   - }
59   -
60 27 }
... ...
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/controller/task/vo/task/BpmTaskRespVO.java
1 1 package cn.iocoder.yudao.adminserver.modules.bpm.controller.task.vo.task;
2 2  
3 3 import io.swagger.annotations.ApiModel;
  4 +import io.swagger.annotations.ApiModelProperty;
4 5 import lombok.Data;
  6 +import lombok.EqualsAndHashCode;
5 7 import lombok.ToString;
6 8  
7 9 import java.util.List;
8 10  
9 11 @ApiModel("流程任务的 Response VO")
10 12 @Data
11   -public class BpmTaskRespVO extends Page{
  13 +@EqualsAndHashCode(callSuper = true)
  14 +@ToString(callSuper = true)
  15 +public class BpmTaskRespVO extends BpmTaskDonePageItemRespVO {
12 16  
  17 + /**
  18 + * 审核的用户信息
  19 + */
  20 + private User assigneeUser;
13 21  
  22 + @ApiModel("用户信息")
  23 + @Data
  24 + public static class User {
  25 +
  26 + @ApiModelProperty(value = "用户编号", required = true, example = "1")
  27 + private Long id;
  28 + @ApiModelProperty(value = "用户昵称", required = true, example = "芋艿")
  29 + private String nickname;
  30 +
  31 + @ApiModelProperty(value = "部门编号", required = true, example = "1")
  32 + private Long deptId;
  33 + @ApiModelProperty(value = "部门名称", required = true, example = "研发部")
  34 + private String deptName;
  35 +
  36 + }
14 37  
15 38 }
... ...
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/convert/task/BpmTaskConvert.java
1 1 package cn.iocoder.yudao.adminserver.modules.bpm.convert.task;
2 2  
3 3 import cn.iocoder.yudao.adminserver.modules.bpm.controller.task.vo.task.BpmTaskDonePageItemRespVO;
  4 +import cn.iocoder.yudao.adminserver.modules.bpm.controller.task.vo.task.BpmTaskRespVO;
4 5 import cn.iocoder.yudao.adminserver.modules.bpm.controller.task.vo.task.BpmTaskTodoPageItemRespVO;
5   -import cn.iocoder.yudao.adminserver.modules.bpm.controller.task.vo.task.TaskStepVO;
6 6 import cn.iocoder.yudao.adminserver.modules.bpm.dal.dataobject.task.BpmTaskExtDO;
  7 +import cn.iocoder.yudao.adminserver.modules.system.dal.dataobject.dept.SysDeptDO;
7 8 import cn.iocoder.yudao.coreservice.modules.system.dal.dataobject.user.SysUserDO;
8 9 import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
9   -import org.activiti.engine.history.HistoricActivityInstance;
  10 +import cn.iocoder.yudao.framework.common.util.number.NumberUtils;
10 11 import org.activiti.engine.history.HistoricProcessInstance;
11 12 import org.activiti.engine.history.HistoricTaskInstance;
12 13 import org.activiti.engine.impl.persistence.entity.SuspensionState;
13 14 import org.activiti.engine.runtime.ProcessInstance;
14 15 import org.activiti.engine.task.Task;
15   -import org.mapstruct.Mapper;
16   -import org.mapstruct.Mapping;
17   -import org.mapstruct.Mappings;
18   -import org.mapstruct.Named;
  16 +import org.mapstruct.*;
19 17 import org.mapstruct.factory.Mappers;
20 18  
21 19 import java.util.List;
... ... @@ -31,12 +29,6 @@ public interface BpmTaskConvert {
31 29  
32 30 BpmTaskConvert INSTANCE = Mappers.getMapper(BpmTaskConvert.class);
33 31  
34   - @Mappings(value = {
35   - @Mapping(source = "activityName", target = "stepName"),
36   - @Mapping(source = "assignee", target = "assignee")
37   - })
38   - TaskStepVO convert(HistoricActivityInstance instance);
39   -
40 32 default List<BpmTaskTodoPageItemRespVO> convertList(List<Task> tasks, Map<String, ProcessInstance> processInstanceMap,
41 33 Map<Long, SysUserDO> userMap) {
42 34 return CollectionUtils.convertList(tasks, task -> {
... ... @@ -89,9 +81,9 @@ public interface BpmTaskConvert {
89 81 @Mapping(source = "processInstance.name", target = "processInstance.name"),
90 82 @Mapping(source = "processInstance.startUserId", target = "processInstance.startUserId"),
91 83 @Mapping(source = "processInstance.processDefinitionId", target = "processInstance.processDefinitionId"),
92   - @Mapping(source = "user.nickname", target = "processInstance.startUserNickname")
  84 + @Mapping(source = "startUser.nickname", target = "processInstance.startUserNickname")
93 85 })
94   - BpmTaskDonePageItemRespVO convert(HistoricTaskInstance task, BpmTaskExtDO taskExtDO, HistoricProcessInstance processInstance, SysUserDO user);
  86 + BpmTaskDonePageItemRespVO convert(HistoricTaskInstance task, BpmTaskExtDO taskExtDO, HistoricProcessInstance processInstance, SysUserDO startUser);
95 87  
96 88 @Mappings({
97 89 @Mapping(source = "id", target = "taskId"),
... ... @@ -100,4 +92,40 @@ public interface BpmTaskConvert {
100 92 })
101 93 BpmTaskExtDO convert(org.activiti.api.task.model.Task bean);
102 94  
  95 + default List<BpmTaskRespVO> convertList3(List<HistoricTaskInstance> tasks, Map<String, BpmTaskExtDO> bpmTaskExtDOMap,
  96 + HistoricProcessInstance processInstance, Map<Long, SysUserDO> userMap,
  97 + Map<Long, SysDeptDO> deptMap) {
  98 + return CollectionUtils.convertList(tasks, task -> {
  99 + BpmTaskRespVO respVO = convert3(task);
  100 + BpmTaskExtDO taskExtDO = bpmTaskExtDOMap.get(task.getId());
  101 + copyTo3(taskExtDO, respVO);
  102 + if (processInstance != null) {
  103 + SysUserDO startUser = userMap.get(NumberUtils.parseLong(processInstance.getStartUserId()));
  104 + respVO.setProcessInstance(convert(processInstance, startUser));
  105 + }
  106 + SysUserDO assignUser = userMap.get(NumberUtils.parseLong(task.getAssignee()));
  107 + if (assignUser != null) {
  108 + respVO.setAssigneeUser(convert3(assignUser));
  109 + SysDeptDO dept = deptMap.get(assignUser.getDeptId());
  110 + if (dept != null) {
  111 + respVO.getAssigneeUser().setDeptName(dept.getName());
  112 + }
  113 + }
  114 + return respVO;
  115 + });
  116 + }
  117 +
  118 + BpmTaskRespVO convert3(HistoricTaskInstance bean);
  119 + BpmTaskRespVO.User convert3(SysUserDO bean);
  120 + void copyTo3(BpmTaskExtDO from, @MappingTarget BpmTaskRespVO to);
  121 +
  122 + @Mappings({
  123 + @Mapping(source = "processInstance.id", target = "id"),
  124 + @Mapping(source = "processInstance.name", target = "name"),
  125 + @Mapping(source = "processInstance.startUserId", target = "startUserId"),
  126 + @Mapping(source = "processInstance.processDefinitionId", target = "processDefinitionId"),
  127 + @Mapping(source = "startUser.nickname", target = "startUserNickname")
  128 + })
  129 + BpmTaskTodoPageItemRespVO.ProcessInstance convert(HistoricProcessInstance processInstance, SysUserDO startUser);
  130 +
103 131 }
... ...
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/service/task/impl/BpmTaskServiceImpl.java
... ... @@ -2,6 +2,7 @@ package cn.iocoder.yudao.adminserver.modules.bpm.service.task.impl;
2 2  
3 3 import cn.hutool.core.collection.CollUtil;
4 4 import cn.hutool.core.io.IoUtil;
  5 +import cn.hutool.core.util.NumberUtil;
5 6 import cn.hutool.core.util.StrUtil;
6 7 import cn.iocoder.yudao.adminserver.modules.bpm.controller.task.vo.task.*;
7 8 import cn.iocoder.yudao.adminserver.modules.bpm.convert.task.BpmTaskConvert;
... ... @@ -10,10 +11,13 @@ import cn.iocoder.yudao.adminserver.modules.bpm.dal.mysql.task.BpmTaskExtMapper;
10 11 import cn.iocoder.yudao.adminserver.modules.bpm.enums.task.BpmProcessInstanceResultEnum;
11 12 import cn.iocoder.yudao.adminserver.modules.bpm.service.task.BpmProcessInstanceService;
12 13 import cn.iocoder.yudao.adminserver.modules.bpm.service.task.BpmTaskService;
  14 +import cn.iocoder.yudao.adminserver.modules.system.dal.dataobject.dept.SysDeptDO;
  15 +import cn.iocoder.yudao.adminserver.modules.system.service.dept.SysDeptService;
13 16 import cn.iocoder.yudao.adminserver.modules.system.service.user.SysUserService;
14 17 import cn.iocoder.yudao.coreservice.modules.system.dal.dataobject.user.SysUserDO;
15 18 import cn.iocoder.yudao.framework.common.pojo.PageResult;
16 19 import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
  20 +import cn.iocoder.yudao.framework.common.util.number.NumberUtils;
17 21 import cn.iocoder.yudao.framework.common.util.object.PageUtils;
18 22 import lombok.extern.slf4j.Slf4j;
19 23 import org.activiti.bpmn.constants.BpmnXMLConstants;
... ... @@ -44,6 +48,7 @@ import javax.validation.Valid;
44 48 import java.io.IOException;
45 49 import java.io.InputStream;
46 50 import java.util.*;
  51 +import java.util.function.Function;
47 52  
48 53 import static cn.iocoder.yudao.adminserver.modules.bpm.enums.BpmErrorCodeConstants.*;
49 54 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
... ... @@ -75,6 +80,8 @@ public class BpmTaskServiceImpl implements BpmTaskService {
75 80 @Resource
76 81 private SysUserService userService;
77 82 @Resource
  83 + private SysDeptService deptService;
  84 + @Resource
78 85 @Lazy // 解决循环依赖
79 86 private BpmProcessInstanceService processInstanceService;
80 87  
... ... @@ -91,13 +98,25 @@ public class BpmTaskServiceImpl implements BpmTaskService {
91 98 // 获得任务列表
92 99 List<HistoricTaskInstance> tasks = historyService.createHistoricTaskInstanceQuery()
93 100 .processInstanceId(processInstanceId)
94   - .orderByTaskCreateTime().list();
  101 + .orderByTaskCreateTime().desc().list();
95 102 if (CollUtil.isEmpty(tasks)) {
96 103 return Collections.emptyList();
97 104 }
98 105  
  106 + // 获得 TaskExtDO Map
  107 + List<BpmTaskExtDO> bpmTaskExtDOs = taskExtMapper.selectListByTaskIds(convertSet(tasks, HistoricTaskInstance::getId));
  108 + Map<String, BpmTaskExtDO> bpmTaskExtDOMap = convertMap(bpmTaskExtDOs, BpmTaskExtDO::getTaskId);
  109 + // 获得 ProcessInstance Map
  110 + HistoricProcessInstance processInstance = processInstanceService.getHistoricProcessInstance(processInstanceId);
  111 + // 获得 User Map
  112 + Set<Long> userIds = convertSet(tasks, task -> NumberUtils.parseLong(task.getAssignee()));
  113 + userIds.add(NumberUtils.parseLong(processInstance.getStartUserId()));
  114 + Map<Long, SysUserDO> userMap = userService.getUserMap(userIds);
  115 + // 获得 Dept Map
  116 + Map<Long, SysDeptDO> deptMap = deptService.getDeptMap(convertSet(userMap.values(), SysUserDO::getDeptId));
  117 +
99 118 // 拼接数据
100   - return null;
  119 + return BpmTaskConvert.INSTANCE.convertList3(tasks, bpmTaskExtDOMap, processInstance, userMap, deptMap);
101 120 }
102 121  
103 122 @Override
... ... @@ -113,7 +132,6 @@ public class BpmTaskServiceImpl implements BpmTaskService {
113 132 // 查询待办任务
114 133 TaskQuery taskQuery = taskService.createTaskQuery()
115 134 .taskAssignee(String.valueOf(userId)) // 分配给自己
116   - .taskCandidateUser(String.valueOf(userId))
117 135 .orderByTaskCreateTime().desc(); // 创建时间倒序
118 136 if (StrUtil.isNotBlank(pageVO.getName())) {
119 137 taskQuery.taskNameLike("%" + pageVO.getName() + "%");
... ... @@ -232,48 +250,6 @@ public class BpmTaskServiceImpl implements BpmTaskService {
232 250 // taskService.addComment(task.getId(), task.getProcessInstanceId(), reqVO.getComment());
233 251 }
234 252  
235   - private List<TaskStepVO> getTaskSteps(String processInstanceId) {
236   - // 获得已完成的活动
237   - List<HistoricActivityInstance> finished = historyService.createHistoricActivityInstanceQuery()
238   - .processInstanceId(processInstanceId)
239   - .activityType("userTask")
240   - .finished()
241   - .orderByHistoricActivityInstanceStartTime().asc().list();
242   - // 获得对应的步骤
243   - List<TaskStepVO> steps = new ArrayList<>();
244   - finished.forEach(instance -> {
245   - TaskStepVO stepVO = BpmTaskConvert.INSTANCE.convert(instance);
246   - stepVO.setStatus(1); // TODO @jason:1 这个 magic number 要枚举起来。
247   - // TODO @jason:可以考虑把 comments 读取后,在统一调用 convert 拼接。另外 Comment 是废弃的类,有没其它可以使用的哈?
248   - List<Comment> comments = taskService.getTaskComments(instance.getTaskId());
249   - if (!CollUtil.isEmpty(comments)) {
250   - stepVO.setComment(Optional.ofNullable(comments.get(0)).map(Comment::getFullMessage).orElse(""));
251   - }
252   - steps.add(stepVO);
253   - });
254   -
255   - // 获得未完成的活动
256   - List<HistoricActivityInstance> unfinished = historyService
257   - .createHistoricActivityInstanceQuery()
258   - .processInstanceId(processInstanceId)
259   - .activityType("userTask")
260   - .unfinished().list();
261   - // 获得对应的步骤
262   - for (HistoricActivityInstance instance : unfinished) {
263   - TaskStepVO stepVO = BpmTaskConvert.INSTANCE.convert(instance);
264   - stepVO.setComment("");
265   - stepVO.setStatus(0);
266   - steps.add(stepVO);
267   - }
268   - return steps;
269   - }
270   -
271   -
272   - @Override
273   - public List<TaskStepVO> getHistorySteps(String processInstanceId) {
274   - return getTaskSteps(processInstanceId);
275   - }
276   -
277 253 @Override
278 254 public FileResp getHighlightImg(String processInstanceId) {
279 255 // 查询历史
... ...
yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/util/number/NumberUtils.java 0 → 100644
  1 +package cn.iocoder.yudao.framework.common.util.number;
  2 +
  3 +import cn.hutool.core.util.StrUtil;
  4 +
  5 +/**
  6 + * 数字的工具类,补全 {@link cn.hutool.core.util.NumberUtil} 的功能
  7 + *
  8 + * @author 芋道源码
  9 + */
  10 +public class NumberUtils {
  11 +
  12 + public static Long parseLong(String str) {
  13 + return StrUtil.isNotEmpty(str) ? Long.valueOf(str) : null;
  14 + }
  15 +
  16 +}
... ...