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

This commit is contained in:
YunaiV 2022-01-16 13:27:09 +08:00
parent f9b6eef4d2
commit a4d31f9c45
7 changed files with 115 additions and 100 deletions

View File

@ -7,3 +7,8 @@ Authorization: Bearer {{token}}
GET {{baseUrl}}/bpm/task/done-page?pageSize=100
tenant-id: 1
Authorization: Bearer {{token}}
### 请求 /bpm/task/list-by-process-instance-id 接口 => 成功
GET {{baseUrl}}/bpm/task/list-by-process-instance-id?processInstanceId=537cceb3-768c-11ec-afcd-a2380e71991a
tenant-id: 1
Authorization: Bearer {{token}}

View File

@ -57,10 +57,10 @@ public class BpmTaskController {
}
@GetMapping("/list-by-process-instance-id")
@ApiOperation(value = "获得指定流程实例的任务列表", notes = "包括完成的、未完成的")
@ApiOperation(value = "获得指定流程实例的任务列表", notes = "包括完成的、未完成的") // TODO 芋艿注解
public CommonResult<List<BpmTaskRespVO>> getTaskListByProcessInstanceId(
@RequestParam("processInstanceId") String processInstanceId) {
return success(taskService.getTaskSteps(taskQuery));
return success(taskService.getTaskListByProcessInstanceId(processInstanceId));
}
/**

View File

@ -3,24 +3,17 @@ package cn.iocoder.yudao.adminserver.modules.bpm.controller.task.vo.task;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
import java.util.Date;
@ApiModel("流程任务的 Done 已完成的分页项 Response VO")
@Data
public class BpmTaskDonePageItemRespVO {
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class BpmTaskDonePageItemRespVO extends BpmTaskTodoPageItemRespVO {
@ApiModelProperty(value = "任务编号", required = true, example = "1024")
private String id;
@ApiModelProperty(value = "任务名字", required = true, example = "芋道")
private String name;
@ApiModelProperty(value = "接收时间", required = true)
private Date claimTime;
@ApiModelProperty(value = "创建时间", required = true)
private Date createTime;
@ApiModelProperty(value = "结束时间", required = true)
private Date endTime;
@ApiModelProperty(value = "持续时间", required = true, example = "1000")
@ -31,30 +24,4 @@ public class BpmTaskDonePageItemRespVO {
@ApiModelProperty(value = "审批建议", required = true, example = "不请假了!")
private String comment;
/**
* 所属流程实例
*/
private ProcessInstance processInstance;
@Data
@ApiModel("流程实例")
public static class ProcessInstance {
@ApiModelProperty(value = "流程实例编号", required = true, example = "1024")
private String id;
@ApiModelProperty(value = "流程实例名称", required = true, example = "芋道")
private String name;
@ApiModelProperty(value = "发起人的用户编号", required = true, example = "1024")
private Long startUserId;
@ApiModelProperty(value = "发起人的用户昵称", required = true, example = "芋艿")
private String startUserNickname;
@ApiModelProperty(value = "流程定义的编号", required = true, example = "2048")
private String processDefinitionId;
}
}

View File

@ -1,15 +1,38 @@
package cn.iocoder.yudao.adminserver.modules.bpm.controller.task.vo.task;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
import java.util.List;
@ApiModel("流程任务的 Response VO")
@Data
public class BpmTaskRespVO extends Page{
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class BpmTaskRespVO extends BpmTaskDonePageItemRespVO {
/**
* 审核的用户信息
*/
private User assigneeUser;
@ApiModel("用户信息")
@Data
public static class User {
@ApiModelProperty(value = "用户编号", required = true, example = "1")
private Long id;
@ApiModelProperty(value = "用户昵称", required = true, example = "芋艿")
private String nickname;
@ApiModelProperty(value = "部门编号", required = true, example = "1")
private Long deptId;
@ApiModelProperty(value = "部门名称", required = true, example = "研发部")
private String deptName;
}
}

View File

@ -1,21 +1,19 @@
package cn.iocoder.yudao.adminserver.modules.bpm.convert.task;
import cn.iocoder.yudao.adminserver.modules.bpm.controller.task.vo.task.BpmTaskDonePageItemRespVO;
import cn.iocoder.yudao.adminserver.modules.bpm.controller.task.vo.task.BpmTaskRespVO;
import cn.iocoder.yudao.adminserver.modules.bpm.controller.task.vo.task.BpmTaskTodoPageItemRespVO;
import cn.iocoder.yudao.adminserver.modules.bpm.controller.task.vo.task.TaskStepVO;
import cn.iocoder.yudao.adminserver.modules.bpm.dal.dataobject.task.BpmTaskExtDO;
import cn.iocoder.yudao.adminserver.modules.system.dal.dataobject.dept.SysDeptDO;
import cn.iocoder.yudao.coreservice.modules.system.dal.dataobject.user.SysUserDO;
import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
import org.activiti.engine.history.HistoricActivityInstance;
import cn.iocoder.yudao.framework.common.util.number.NumberUtils;
import org.activiti.engine.history.HistoricProcessInstance;
import org.activiti.engine.history.HistoricTaskInstance;
import org.activiti.engine.impl.persistence.entity.SuspensionState;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.Task;
import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
import org.mapstruct.Mappings;
import org.mapstruct.Named;
import org.mapstruct.*;
import org.mapstruct.factory.Mappers;
import java.util.List;
@ -31,12 +29,6 @@ public interface BpmTaskConvert {
BpmTaskConvert INSTANCE = Mappers.getMapper(BpmTaskConvert.class);
@Mappings(value = {
@Mapping(source = "activityName", target = "stepName"),
@Mapping(source = "assignee", target = "assignee")
})
TaskStepVO convert(HistoricActivityInstance instance);
default List<BpmTaskTodoPageItemRespVO> convertList(List<Task> tasks, Map<String, ProcessInstance> processInstanceMap,
Map<Long, SysUserDO> userMap) {
return CollectionUtils.convertList(tasks, task -> {
@ -89,9 +81,9 @@ public interface BpmTaskConvert {
@Mapping(source = "processInstance.name", target = "processInstance.name"),
@Mapping(source = "processInstance.startUserId", target = "processInstance.startUserId"),
@Mapping(source = "processInstance.processDefinitionId", target = "processInstance.processDefinitionId"),
@Mapping(source = "user.nickname", target = "processInstance.startUserNickname")
@Mapping(source = "startUser.nickname", target = "processInstance.startUserNickname")
})
BpmTaskDonePageItemRespVO convert(HistoricTaskInstance task, BpmTaskExtDO taskExtDO, HistoricProcessInstance processInstance, SysUserDO user);
BpmTaskDonePageItemRespVO convert(HistoricTaskInstance task, BpmTaskExtDO taskExtDO, HistoricProcessInstance processInstance, SysUserDO startUser);
@Mappings({
@Mapping(source = "id", target = "taskId"),
@ -100,4 +92,40 @@ public interface BpmTaskConvert {
})
BpmTaskExtDO convert(org.activiti.api.task.model.Task bean);
default List<BpmTaskRespVO> convertList3(List<HistoricTaskInstance> tasks, Map<String, BpmTaskExtDO> bpmTaskExtDOMap,
HistoricProcessInstance processInstance, Map<Long, SysUserDO> userMap,
Map<Long, SysDeptDO> deptMap) {
return CollectionUtils.convertList(tasks, task -> {
BpmTaskRespVO respVO = convert3(task);
BpmTaskExtDO taskExtDO = bpmTaskExtDOMap.get(task.getId());
copyTo3(taskExtDO, respVO);
if (processInstance != null) {
SysUserDO startUser = userMap.get(NumberUtils.parseLong(processInstance.getStartUserId()));
respVO.setProcessInstance(convert(processInstance, startUser));
}
SysUserDO assignUser = userMap.get(NumberUtils.parseLong(task.getAssignee()));
if (assignUser != null) {
respVO.setAssigneeUser(convert3(assignUser));
SysDeptDO dept = deptMap.get(assignUser.getDeptId());
if (dept != null) {
respVO.getAssigneeUser().setDeptName(dept.getName());
}
}
return respVO;
});
}
BpmTaskRespVO convert3(HistoricTaskInstance bean);
BpmTaskRespVO.User convert3(SysUserDO bean);
void copyTo3(BpmTaskExtDO from, @MappingTarget BpmTaskRespVO to);
@Mappings({
@Mapping(source = "processInstance.id", target = "id"),
@Mapping(source = "processInstance.name", target = "name"),
@Mapping(source = "processInstance.startUserId", target = "startUserId"),
@Mapping(source = "processInstance.processDefinitionId", target = "processDefinitionId"),
@Mapping(source = "startUser.nickname", target = "startUserNickname")
})
BpmTaskTodoPageItemRespVO.ProcessInstance convert(HistoricProcessInstance processInstance, SysUserDO startUser);
}

View File

@ -2,6 +2,7 @@ package cn.iocoder.yudao.adminserver.modules.bpm.service.task.impl;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.io.IoUtil;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.StrUtil;
import cn.iocoder.yudao.adminserver.modules.bpm.controller.task.vo.task.*;
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;
import cn.iocoder.yudao.adminserver.modules.bpm.enums.task.BpmProcessInstanceResultEnum;
import cn.iocoder.yudao.adminserver.modules.bpm.service.task.BpmProcessInstanceService;
import cn.iocoder.yudao.adminserver.modules.bpm.service.task.BpmTaskService;
import cn.iocoder.yudao.adminserver.modules.system.dal.dataobject.dept.SysDeptDO;
import cn.iocoder.yudao.adminserver.modules.system.service.dept.SysDeptService;
import cn.iocoder.yudao.adminserver.modules.system.service.user.SysUserService;
import cn.iocoder.yudao.coreservice.modules.system.dal.dataobject.user.SysUserDO;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
import cn.iocoder.yudao.framework.common.util.number.NumberUtils;
import cn.iocoder.yudao.framework.common.util.object.PageUtils;
import lombok.extern.slf4j.Slf4j;
import org.activiti.bpmn.constants.BpmnXMLConstants;
@ -44,6 +48,7 @@ import javax.validation.Valid;
import java.io.IOException;
import java.io.InputStream;
import java.util.*;
import java.util.function.Function;
import static cn.iocoder.yudao.adminserver.modules.bpm.enums.BpmErrorCodeConstants.*;
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
@ -75,6 +80,8 @@ public class BpmTaskServiceImpl implements BpmTaskService {
@Resource
private SysUserService userService;
@Resource
private SysDeptService deptService;
@Resource
@Lazy // 解决循环依赖
private BpmProcessInstanceService processInstanceService;
@ -91,13 +98,25 @@ public class BpmTaskServiceImpl implements BpmTaskService {
// 获得任务列表
List<HistoricTaskInstance> tasks = historyService.createHistoricTaskInstanceQuery()
.processInstanceId(processInstanceId)
.orderByTaskCreateTime().list();
.orderByTaskCreateTime().desc().list();
if (CollUtil.isEmpty(tasks)) {
return Collections.emptyList();
}
// 获得 TaskExtDO Map
List<BpmTaskExtDO> bpmTaskExtDOs = taskExtMapper.selectListByTaskIds(convertSet(tasks, HistoricTaskInstance::getId));
Map<String, BpmTaskExtDO> bpmTaskExtDOMap = convertMap(bpmTaskExtDOs, BpmTaskExtDO::getTaskId);
// 获得 ProcessInstance Map
HistoricProcessInstance processInstance = processInstanceService.getHistoricProcessInstance(processInstanceId);
// 获得 User Map
Set<Long> userIds = convertSet(tasks, task -> NumberUtils.parseLong(task.getAssignee()));
userIds.add(NumberUtils.parseLong(processInstance.getStartUserId()));
Map<Long, SysUserDO> userMap = userService.getUserMap(userIds);
// 获得 Dept Map
Map<Long, SysDeptDO> deptMap = deptService.getDeptMap(convertSet(userMap.values(), SysUserDO::getDeptId));
// 拼接数据
return null;
return BpmTaskConvert.INSTANCE.convertList3(tasks, bpmTaskExtDOMap, processInstance, userMap, deptMap);
}
@Override
@ -113,7 +132,6 @@ public class BpmTaskServiceImpl implements BpmTaskService {
// 查询待办任务
TaskQuery taskQuery = taskService.createTaskQuery()
.taskAssignee(String.valueOf(userId)) // 分配给自己
.taskCandidateUser(String.valueOf(userId))
.orderByTaskCreateTime().desc(); // 创建时间倒序
if (StrUtil.isNotBlank(pageVO.getName())) {
taskQuery.taskNameLike("%" + pageVO.getName() + "%");
@ -232,48 +250,6 @@ public class BpmTaskServiceImpl implements BpmTaskService {
// taskService.addComment(task.getId(), task.getProcessInstanceId(), reqVO.getComment());
}
private List<TaskStepVO> getTaskSteps(String processInstanceId) {
// 获得已完成的活动
List<HistoricActivityInstance> finished = historyService.createHistoricActivityInstanceQuery()
.processInstanceId(processInstanceId)
.activityType("userTask")
.finished()
.orderByHistoricActivityInstanceStartTime().asc().list();
// 获得对应的步骤
List<TaskStepVO> steps = new ArrayList<>();
finished.forEach(instance -> {
TaskStepVO stepVO = BpmTaskConvert.INSTANCE.convert(instance);
stepVO.setStatus(1); // TODO @jason1 这个 magic number 要枚举起来
// TODO @jason可以考虑把 comments 读取后在统一调用 convert 拼接另外 Comment 是废弃的类有没其它可以使用的哈
List<Comment> comments = taskService.getTaskComments(instance.getTaskId());
if (!CollUtil.isEmpty(comments)) {
stepVO.setComment(Optional.ofNullable(comments.get(0)).map(Comment::getFullMessage).orElse(""));
}
steps.add(stepVO);
});
// 获得未完成的活动
List<HistoricActivityInstance> unfinished = historyService
.createHistoricActivityInstanceQuery()
.processInstanceId(processInstanceId)
.activityType("userTask")
.unfinished().list();
// 获得对应的步骤
for (HistoricActivityInstance instance : unfinished) {
TaskStepVO stepVO = BpmTaskConvert.INSTANCE.convert(instance);
stepVO.setComment("");
stepVO.setStatus(0);
steps.add(stepVO);
}
return steps;
}
@Override
public List<TaskStepVO> getHistorySteps(String processInstanceId) {
return getTaskSteps(processInstanceId);
}
@Override
public FileResp getHighlightImg(String processInstanceId) {
// 查询历史

View File

@ -0,0 +1,16 @@
package cn.iocoder.yudao.framework.common.util.number;
import cn.hutool.core.util.StrUtil;
/**
* 数字的工具类补全 {@link cn.hutool.core.util.NumberUtil} 的功能
*
* @author 芋道源码
*/
public class NumberUtils {
public static Long parseLong(String str) {
return StrUtil.isNotEmpty(str) ? Long.valueOf(str) : null;
}
}