Commit c70ef4493a5c6035fce29b97627f4841c9b32e18
1 parent
c05f9fe9
【功能修改】 新增我的待办任务接口
Showing
5 changed files
with
89 additions
and
11 deletions
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() // 已完成 |