Commit c70ef4493a5c6035fce29b97627f4841c9b32e18

Authored by jason
1 parent c05f9fe9

【功能修改】 新增我的待办任务接口

yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/BpmTaskController.java
@@ -30,10 +30,7 @@ import org.springframework.security.access.prepost.PreAuthorize; @@ -30,10 +30,7 @@ import org.springframework.security.access.prepost.PreAuthorize;
30 import org.springframework.validation.annotation.Validated; 30 import org.springframework.validation.annotation.Validated;
31 import org.springframework.web.bind.annotation.*; 31 import org.springframework.web.bind.annotation.*;
32 32
33 -import java.util.Collections;  
34 -import java.util.List;  
35 -import java.util.Map;  
36 -import java.util.Set; 33 +import java.util.*;
37 import java.util.stream.Stream; 34 import java.util.stream.Stream;
38 35
39 import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; 36 import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
@@ -77,6 +74,15 @@ public class BpmTaskController { @@ -77,6 +74,15 @@ public class BpmTaskController {
77 return success(BpmTaskConvert.INSTANCE.buildTodoTaskPage(pageResult, processInstanceMap, userMap)); 74 return success(BpmTaskConvert.INSTANCE.buildTodoTaskPage(pageResult, processInstanceMap, userMap));
78 } 75 }
79 76
  77 + @GetMapping("my-todo")
  78 + @Operation(summary = "获取我的待办任务,取第一条")
  79 + @Parameter(name = "processInstanceId", description = "流程实例的编号", required = true)
  80 + @PreAuthorize("@ss.hasPermission('bpm:task:query')")
  81 + public CommonResult<BpmTaskRespVO> getMyTodoTask(@RequestParam("processInstanceId") String processInstanceId) {
  82 + List<BpmTaskRespVO> taskList = taskService.getTodoTask(getLoginUserId(), processInstanceId);
  83 + return success(findFirst(taskList, Objects::nonNull));
  84 + }
  85 +
80 @GetMapping("done-page") 86 @GetMapping("done-page")
81 @Operation(summary = "获取 Done 已办任务分页") 87 @Operation(summary = "获取 Done 已办任务分页")
82 @PreAuthorize("@ss.hasPermission('bpm:task:query')") 88 @PreAuthorize("@ss.hasPermission('bpm:task:query')")
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/task/BpmTaskRespVO.java
@@ -67,9 +67,6 @@ public class BpmTaskRespVO { @@ -67,9 +67,6 @@ public class BpmTaskRespVO {
67 private List<String> formFields; 67 private List<String> formFields;
68 @Schema(description = "提交的表单值", requiredMode = Schema.RequiredMode.REQUIRED) 68 @Schema(description = "提交的表单值", requiredMode = Schema.RequiredMode.REQUIRED)
69 private Map<String, Object> formVariables; 69 private Map<String, Object> formVariables;
70 - // @芋艿 都改成了 fieldsPermission。 buttonsSetting。和 BpmSimpleModelNodeVO 统一  
71 - @Schema(description = "表单字段权限值")  
72 - private Map<String, String> fieldsPermission;  
73 @Schema(description = "操作按钮设置值") 70 @Schema(description = "操作按钮设置值")
74 private Map<Integer, OperationButtonSetting> buttonsSetting; 71 private Map<Integer, OperationButtonSetting> buttonsSetting;
75 72
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/convert/task/BpmTaskConvert.java
@@ -112,10 +112,6 @@ public interface BpmTaskConvert { @@ -112,10 +112,6 @@ public interface BpmTaskConvert {
112 findAndThen(deptMap, ownerUser.getDeptId(), dept -> taskVO.getOwnerUser().setDeptName(dept.getName())); 112 findAndThen(deptMap, ownerUser.getDeptId(), dept -> taskVO.getOwnerUser().setDeptName(dept.getName()));
113 } 113 }
114 if (BpmTaskStatusEnum.RUNNING.getStatus().equals(taskStatus)){ 114 if (BpmTaskStatusEnum.RUNNING.getStatus().equals(taskStatus)){
115 - // 设置表单权限 TODO @芋艿 是不是还要加一个全局的权限 基于 processInstance 的权限;回复:可能不需要,但是发起人,需要有个权限配置  
116 - // TODO @jason:貌似这么返回,主要解决当前审批 task 的表单权限,但是不同抄送人的表单权限,可能不太对。例如说,对 A 抄送人是隐藏某个字段。  
117 - // @芋艿 表单权限需要分离开。单独的接口来获取了 BpmProcessInstanceService.getProcessInstanceFormFieldsPermission  
118 - taskVO.setFieldsPermission(BpmnModelUtils.parseFormFieldsPermission(bpmnModel, task.getTaskDefinitionKey()));  
119 // 操作按钮设置 115 // 操作按钮设置
120 taskVO.setButtonsSetting(BpmnModelUtils.parseButtonsSetting(bpmnModel, task.getTaskDefinitionKey())); 116 taskVO.setButtonsSetting(BpmnModelUtils.parseButtonsSetting(bpmnModel, task.getTaskDefinitionKey()));
121 } 117 }
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmTaskService.java
@@ -33,6 +33,15 @@ public interface BpmTaskService { @@ -33,6 +33,15 @@ public interface BpmTaskService {
33 PageResult<Task> getTaskTodoPage(Long userId, BpmTaskPageReqVO pageReqVO); 33 PageResult<Task> getTaskTodoPage(Long userId, BpmTaskPageReqVO pageReqVO);
34 34
35 /** 35 /**
  36 + * 获得待办任务列表
  37 + *
  38 + * @param userId 用户编号
  39 + * @param processInstanceId 流程实例编号
  40 + * @return 流程任务列表
  41 + */
  42 + List<BpmTaskRespVO> getTodoTask(Long userId, String processInstanceId);
  43 +
  44 + /**
36 * 获得已办的流程任务分页 45 * 获得已办的流程任务分页
37 * 46 *
38 * @param userId 用户编号 47 * @param userId 用户编号
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmTaskServiceImpl.java
@@ -5,11 +5,14 @@ import cn.hutool.core.lang.Assert; @@ -5,11 +5,14 @@ import cn.hutool.core.lang.Assert;
5 import cn.hutool.core.util.*; 5 import cn.hutool.core.util.*;
6 import cn.hutool.extra.spring.SpringUtil; 6 import cn.hutool.extra.spring.SpringUtil;
7 import cn.iocoder.yudao.framework.common.pojo.PageResult; 7 import cn.iocoder.yudao.framework.common.pojo.PageResult;
  8 +import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
8 import cn.iocoder.yudao.framework.common.util.date.DateUtils; 9 import cn.iocoder.yudao.framework.common.util.date.DateUtils;
9 import cn.iocoder.yudao.framework.common.util.number.NumberUtils; 10 import cn.iocoder.yudao.framework.common.util.number.NumberUtils;
  11 +import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
10 import cn.iocoder.yudao.framework.common.util.object.ObjectUtils; 12 import cn.iocoder.yudao.framework.common.util.object.ObjectUtils;
11 import cn.iocoder.yudao.framework.common.util.object.PageUtils; 13 import cn.iocoder.yudao.framework.common.util.object.PageUtils;
12 import cn.iocoder.yudao.framework.web.core.util.WebFrameworkUtils; 14 import cn.iocoder.yudao.framework.web.core.util.WebFrameworkUtils;
  15 +import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance.BpmProcessInstanceRespVO;
13 import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.task.*; 16 import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.task.*;
14 import cn.iocoder.yudao.module.bpm.convert.task.BpmTaskConvert; 17 import cn.iocoder.yudao.module.bpm.convert.task.BpmTaskConvert;
15 import cn.iocoder.yudao.module.bpm.enums.definition.*; 18 import cn.iocoder.yudao.module.bpm.enums.definition.*;
@@ -21,6 +24,7 @@ import cn.iocoder.yudao.module.bpm.framework.flowable.core.enums.BpmnVariableCon @@ -21,6 +24,7 @@ import cn.iocoder.yudao.module.bpm.framework.flowable.core.enums.BpmnVariableCon
21 import cn.iocoder.yudao.module.bpm.framework.flowable.core.util.BpmnModelUtils; 24 import cn.iocoder.yudao.module.bpm.framework.flowable.core.util.BpmnModelUtils;
22 import cn.iocoder.yudao.module.bpm.framework.flowable.core.util.FlowableUtils; 25 import cn.iocoder.yudao.module.bpm.framework.flowable.core.util.FlowableUtils;
23 import cn.iocoder.yudao.module.bpm.service.definition.BpmModelService; 26 import cn.iocoder.yudao.module.bpm.service.definition.BpmModelService;
  27 +import cn.iocoder.yudao.module.bpm.service.definition.BpmProcessDefinitionService;
24 import cn.iocoder.yudao.module.bpm.service.message.BpmMessageService; 28 import cn.iocoder.yudao.module.bpm.service.message.BpmMessageService;
25 import cn.iocoder.yudao.module.bpm.service.message.dto.BpmMessageSendWhenTaskTimeoutReqDTO; 29 import cn.iocoder.yudao.module.bpm.service.message.dto.BpmMessageSendWhenTaskTimeoutReqDTO;
26 import cn.iocoder.yudao.module.system.api.dept.DeptApi; 30 import cn.iocoder.yudao.module.system.api.dept.DeptApi;
@@ -38,6 +42,7 @@ import org.flowable.engine.HistoryService; @@ -38,6 +42,7 @@ import org.flowable.engine.HistoryService;
38 import org.flowable.engine.ManagementService; 42 import org.flowable.engine.ManagementService;
39 import org.flowable.engine.RuntimeService; 43 import org.flowable.engine.RuntimeService;
40 import org.flowable.engine.TaskService; 44 import org.flowable.engine.TaskService;
  45 +import org.flowable.engine.history.HistoricProcessInstance;
41 import org.flowable.engine.runtime.ProcessInstance; 46 import org.flowable.engine.runtime.ProcessInstance;
42 import org.flowable.task.api.DelegationState; 47 import org.flowable.task.api.DelegationState;
43 import org.flowable.task.api.Task; 48 import org.flowable.task.api.Task;
@@ -56,6 +61,7 @@ import java.util.stream.Stream; @@ -56,6 +61,7 @@ import java.util.stream.Stream;
56 61
57 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; 62 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
58 import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.*; 63 import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.*;
  64 +import static cn.iocoder.yudao.framework.common.util.collection.MapUtils.findAndThen;
59 import static cn.iocoder.yudao.module.bpm.enums.ErrorCodeConstants.*; 65 import static cn.iocoder.yudao.module.bpm.enums.ErrorCodeConstants.*;
60 import static cn.iocoder.yudao.module.bpm.framework.flowable.core.enums.BpmnVariableConstants.PROCESS_INSTANCE_VARIABLE_RETURN_FLAG; 66 import static cn.iocoder.yudao.module.bpm.framework.flowable.core.enums.BpmnVariableConstants.PROCESS_INSTANCE_VARIABLE_RETURN_FLAG;
61 67
@@ -81,6 +87,8 @@ public class BpmTaskServiceImpl implements BpmTaskService { @@ -81,6 +87,8 @@ public class BpmTaskServiceImpl implements BpmTaskService {
81 @Resource 87 @Resource
82 private BpmProcessInstanceService processInstanceService; 88 private BpmProcessInstanceService processInstanceService;
83 @Resource 89 @Resource
  90 + private BpmProcessDefinitionService bpmProcessDefinitionService;
  91 + @Resource
84 private BpmProcessInstanceCopyService processInstanceCopyService; 92 private BpmProcessInstanceCopyService processInstanceCopyService;
85 @Resource 93 @Resource
86 private BpmModelService modelService; 94 private BpmModelService modelService;
@@ -117,6 +125,68 @@ public class BpmTaskServiceImpl implements BpmTaskService { @@ -117,6 +125,68 @@ public class BpmTaskServiceImpl implements BpmTaskService {
117 } 125 }
118 126
119 @Override 127 @Override
  128 + public List<BpmTaskRespVO> getTodoTask(Long userId, String processInstanceId) {
  129 + TaskQuery taskQuery = taskService.createTaskQuery()
  130 + .active()
  131 + .processInstanceId(processInstanceId)
  132 + .includeTaskLocalVariables()
  133 + .includeProcessVariables()
  134 + .orderByTaskCreateTime().asc(); // 按创建时间升序
  135 + HistoricProcessInstance processInstance = processInstanceService.getHistoricProcessInstance(processInstanceId);
  136 + BpmnModel bpmnModel = bpmProcessDefinitionService.getProcessDefinitionBpmnModel(processInstance.getProcessDefinitionId());
  137 + List<Task> todoList = taskQuery.list();
  138 + // 找到子任务。用于减签
  139 + Map<String, List<Task>> childrenTaskMap = convertMultiMap(
  140 + filterList(todoList, r -> StrUtil.isNotEmpty(r.getParentTaskId())),
  141 + Task::getParentTaskId);
  142 + // 获取用户信息
  143 + Set<Long> userIds = CollUtil.newHashSet();
  144 + todoList.forEach(task -> {
  145 + CollUtil.addIfAbsent(userIds, NumberUtils.parseLong((task.getAssignee())));
  146 + CollUtil.addIfAbsent(userIds, NumberUtils.parseLong((task.getOwner())));
  147 + });
  148 + Map<Long, AdminUserRespDTO> userMap = adminUserApi.getUserMap(userIds);
  149 + Map<Long, DeptRespDTO> deptMap = deptApi.getDeptMap(
  150 + convertSet(userMap.values(), AdminUserRespDTO::getDeptId));
  151 + return CollectionUtils.convertList(todoList, task -> {
  152 + // 找到分配给当前用户,或者当前用户加签的任务(为了减签)
  153 + if (!userId.equals(NumberUtil.parseLong(task.getAssignee(), null)) &&
  154 + (!userId.equals(NumberUtil.parseLong(task.getOwner(), null)) || BpmTaskSignTypeEnum.of(task.getScopeType()) == null)) {
  155 + return null;
  156 + }
  157 + BpmTaskRespVO taskVO = BeanUtils.toBean(task, BpmTaskRespVO.class);
  158 + taskVO.setStatus(FlowableUtils.getTaskStatus(task)).setReason(FlowableUtils.getTaskReason(task));
  159 + taskVO.setButtonsSetting(BpmnModelUtils.parseButtonsSetting(bpmnModel, task.getTaskDefinitionKey()));
  160 + AdminUserRespDTO ownerUser = userMap.get(NumberUtils.parseLong(task.getOwner()));
  161 + if (ownerUser != null) {
  162 + taskVO.setOwnerUser(BeanUtils.toBean(ownerUser, BpmProcessInstanceRespVO.User.class));
  163 + findAndThen(deptMap, ownerUser.getDeptId(), dept -> taskVO.getOwnerUser().setDeptName(dept.getName()));
  164 + }
  165 + // 当前用户加签的任务. 找到它的子任务 (为了减签)
  166 + if (userId.equals(NumberUtil.parseLong(task.getOwner(), null))
  167 + && BpmTaskSignTypeEnum.of(task.getScopeType()) != null) {
  168 + List<Task> childTasks = childrenTaskMap.get(task.getId());
  169 + if (CollUtil.isNotEmpty(childTasks)) {
  170 + taskVO.setChildren(
  171 + CollectionUtils.convertList(childTasks, childTask -> {
  172 + BpmTaskRespVO childTaskVO = BeanUtils.toBean(task, BpmTaskRespVO.class);
  173 + childTaskVO.setStatus(FlowableUtils.getTaskStatus(task));
  174 + AdminUserRespDTO assignUser = userMap.get(NumberUtils.parseLong(childTask.getAssignee()));
  175 + if (assignUser != null) {
  176 + childTaskVO.setAssigneeUser(BeanUtils.toBean(assignUser, BpmProcessInstanceRespVO.User.class));
  177 + findAndThen(deptMap, assignUser.getDeptId(), dept -> childTaskVO.getAssigneeUser().setDeptName(dept.getName()));
  178 + }
  179 + return childTaskVO;
  180 + })
  181 + );
  182 + }
  183 +
  184 + }
  185 + return taskVO;
  186 + });
  187 + }
  188 +
  189 + @Override
120 public PageResult<HistoricTaskInstance> getTaskDonePage(Long userId, BpmTaskPageReqVO pageVO) { 190 public PageResult<HistoricTaskInstance> getTaskDonePage(Long userId, BpmTaskPageReqVO pageVO) {
121 HistoricTaskInstanceQuery taskQuery = historyService.createHistoricTaskInstanceQuery() 191 HistoricTaskInstanceQuery taskQuery = historyService.createHistoricTaskInstanceQuery()
122 .finished() // 已完成 192 .finished() // 已完成