From 41e4283f992d951944b185ed3e6e66cd88263ebf Mon Sep 17 00:00:00 2001 From: jason <2667446@qq.com> Date: Wed, 16 Feb 2022 17:12:48 +0800 Subject: [PATCH] =?UTF-8?q?=E5=B7=A5=E4=BD=9C=E6=B5=81=20Flowable=20?= =?UTF-8?q?=E8=BD=AC=E5=8A=9E=E4=BB=BB=E5=8A=A1=E7=9A=84=E5=AE=9E=E7=8E=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../admin/task/BpmTaskController.java | 2 +- ...pl.java => BpmProcessInstanceApiImpl.java} | 9 ++- .../admin/task/BpmTaskController.java | 15 ++++ .../bpm/convert/task/BpmTaskConvert.java | 30 ++++++++ .../core/listener/BpmTaskEventListener.java | 5 ++ .../task/BpmProcessInstanceService.java | 29 +++++++- .../task/BpmProcessInstanceServiceImpl.java | 14 ++++ .../bpm/service/task/BpmTaskService.java | 31 ++++++++ .../bpm/service/task/BpmTaskServiceImpl.java | 73 +++++++++++++++++++ 9 files changed, 203 insertions(+), 5 deletions(-) rename yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/api/task/{FlowableProcessInstanceApiImpl.java => BpmProcessInstanceApiImpl.java} (63%) diff --git a/yudao-module-bpm/yudao-module-bpm-impl-activiti/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/BpmTaskController.java b/yudao-module-bpm/yudao-module-bpm-impl-activiti/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/BpmTaskController.java index 3c3542aa3..6b8f6dff0 100644 --- a/yudao-module-bpm/yudao-module-bpm-impl-activiti/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/BpmTaskController.java +++ b/yudao-module-bpm/yudao-module-bpm-impl-activiti/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/BpmTaskController.java @@ -37,7 +37,7 @@ public class BpmTaskController { @GetMapping("done-page") @ApiOperation("获取 Done 已办任务分页") @PreAuthorize("@ss.hasPermission('bpm:task:query')") - public CommonResult> getTodoTaskPage(@Valid BpmTaskDonePageReqVO pageVO) { + public CommonResult> getDoneTaskPage(@Valid BpmTaskDonePageReqVO pageVO) { return success(taskService.getDoneTaskPage(getLoginUserId(), pageVO)); } diff --git a/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/api/task/FlowableProcessInstanceApiImpl.java b/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/api/task/BpmProcessInstanceApiImpl.java similarity index 63% rename from yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/api/task/FlowableProcessInstanceApiImpl.java rename to yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/api/task/BpmProcessInstanceApiImpl.java index 0f455ed99..745a61a51 100644 --- a/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/api/task/FlowableProcessInstanceApiImpl.java +++ b/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/api/task/BpmProcessInstanceApiImpl.java @@ -1,6 +1,7 @@ package cn.iocoder.yudao.module.bpm.api.task; import cn.iocoder.yudao.module.bpm.api.task.dto.BpmProcessInstanceCreateReqDTO; +import cn.iocoder.yudao.module.bpm.service.task.BpmProcessInstanceService; import org.springframework.stereotype.Service; import org.springframework.validation.annotation.Validated; @@ -14,11 +15,13 @@ import javax.validation.Valid; */ @Service @Validated -public class FlowableProcessInstanceApiImpl implements BpmProcessInstanceApi { +public class BpmProcessInstanceApiImpl implements BpmProcessInstanceApi { + + @Resource + private BpmProcessInstanceService processInstanceService; @Override public String createProcessInstance(Long userId, @Valid BpmProcessInstanceCreateReqDTO reqDTO) { - //TODO - return null; + return processInstanceService.createProcessInstance(userId, reqDTO); } } diff --git a/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/BpmTaskController.java b/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/BpmTaskController.java index 6d5eeb467..52b16297d 100644 --- a/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/BpmTaskController.java +++ b/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/BpmTaskController.java @@ -37,6 +37,13 @@ public class BpmTaskController { return success(taskService.getTodoTaskPage(getLoginUserId(), pageVO)); } + @GetMapping("done-page") + @ApiOperation("获取 Done 已办任务分页") + @PreAuthorize("@ss.hasPermission('bpm:task:query')") + public CommonResult> getDoneTaskPage(@Valid BpmTaskDonePageReqVO pageVO) { + return success(taskService.getDoneTaskPage(getLoginUserId(), pageVO)); + } + @GetMapping("/list-by-process-instance-id") @ApiOperation(value = "获得指定流程实例的任务列表", notes = "包括完成的、未完成的") @ApiImplicitParam(name = "processInstanceId", value = "流程实例的编号", required = true, dataTypeClass = String.class) @@ -61,4 +68,12 @@ public class BpmTaskController { taskService.rejectTask(getLoginUserId(), reqVO); return success(true); } + + @PutMapping("/update-assignee") + @ApiOperation(value = "更新任务的负责人", notes = "用于【流程详情】的【转派】按钮") + @PreAuthorize("@ss.hasPermission('bpm:task:update')") + public CommonResult updateTaskAssignee(@Valid @RequestBody BpmTaskUpdateAssigneeReqVO reqVO) { + taskService.updateTaskAssignee(getLoginUserId(), reqVO); + return success(true); + } } diff --git a/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/convert/task/BpmTaskConvert.java b/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/convert/task/BpmTaskConvert.java index 44d92354f..32f536959 100644 --- a/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/convert/task/BpmTaskConvert.java +++ b/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/convert/task/BpmTaskConvert.java @@ -53,6 +53,24 @@ public interface BpmTaskConvert { SuspensionState.ACTIVE.getStateCode(); } + default List convertList2(List tasks, Map bpmTaskExtDOMap, + Map historicProcessInstanceMap, + Map userMap) { + return CollectionUtils.convertList(tasks, task -> { + BpmTaskDonePageItemRespVO respVO = convert2(task); + BpmTaskExtDO taskExtDO = bpmTaskExtDOMap.get(task.getId()); + copyTo(taskExtDO, respVO); + HistoricProcessInstance processInstance = historicProcessInstanceMap.get(task.getProcessInstanceId()); + if (processInstance != null) { + AdminUserRespDTO startUser = userMap.get(NumberUtils.parseLong(processInstance.getStartUserId())); + respVO.setProcessInstance(convert(processInstance, startUser)); + } + return respVO; + }); + } + + BpmTaskDonePageItemRespVO convert2(HistoricTaskInstance bean); + @Mappings({ @Mapping(source = "processInstance.id", target = "id"), @Mapping(source = "processInstance.name", target = "name"), @@ -111,6 +129,18 @@ public interface BpmTaskConvert { taskExtDO.setCreateTime(task.getCreateTime()); return taskExtDO; } + + default BpmMessageSendWhenTaskCreatedReqDTO convert(ProcessInstance processInstance, AdminUserRespDTO startUser, Task task) { + BpmMessageSendWhenTaskCreatedReqDTO reqDTO = new BpmMessageSendWhenTaskCreatedReqDTO(); + reqDTO.setProcessInstanceId(processInstance.getProcessInstanceId()) + .setProcessInstanceName(processInstance.getName()) + .setStartUserId(startUser.getId()) + .setStartUserNickname(startUser.getNickname()) + .setTaskId(task.getId()) + .setTaskName(task.getName()) + .setAssigneeUserId(NumberUtils.parseLong(task.getAssignee())); + return reqDTO; + } } diff --git a/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/listener/BpmTaskEventListener.java b/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/listener/BpmTaskEventListener.java index 35d3d0e32..f9c9cb769 100644 --- a/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/listener/BpmTaskEventListener.java +++ b/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/listener/BpmTaskEventListener.java @@ -44,4 +44,9 @@ public class BpmTaskEventListener extends AbstractFlowableEngineEventListener { protected void taskCompleted(FlowableEngineEntityEvent event) { taskService.updateTaskExtComplete((Task)event.getEntity()); } + + @Override + protected void taskAssigned(FlowableEngineEntityEvent event) { + taskService.updateTaskExtAssign((Task)event.getEntity()); + } } diff --git a/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmProcessInstanceService.java b/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmProcessInstanceService.java index 6ca19bb93..831af4d3d 100644 --- a/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmProcessInstanceService.java +++ b/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmProcessInstanceService.java @@ -2,6 +2,7 @@ package cn.iocoder.yudao.module.bpm.service.task; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; +import cn.iocoder.yudao.module.bpm.api.task.dto.BpmProcessInstanceCreateReqDTO; import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance.*; import org.flowable.common.engine.api.delegate.event.FlowableEngineEntityEvent; import org.flowable.engine.delegate.event.FlowableCancelledEvent; @@ -55,7 +56,6 @@ public interface BpmProcessInstanceService { */ PageResult getMyProcessInstancePage(Long userId, @Valid BpmProcessInstanceMyPageReqVO pageReqVO); - /** * 创建流程实例(提供给前端) * @@ -65,6 +65,15 @@ public interface BpmProcessInstanceService { */ String createProcessInstance(Long userId, @Valid BpmProcessInstanceCreateReqVO createReqVO); + /** + * 创建流程实例(提供给内部) + * + * @param userId 用户编号 + * @param createReqDTO 创建信息 + * @return 实例的编号 + */ + String createProcessInstance(Long userId, @Valid BpmProcessInstanceCreateReqDTO createReqDTO); + /** * 获得流程实例 VO 信息 * @@ -89,6 +98,24 @@ public interface BpmProcessInstanceService { */ HistoricProcessInstance getHistoricProcessInstance(String id); + /** + * 获得历史的流程实例列表 + * + * @param ids 流程实例的编号集合 + * @return 历史的流程实例列表 + */ + List getHistoricProcessInstances(Set ids); + + /** + * 获得历史的流程实例 Map + * + * @param ids 流程实例的编号集合 + * @return 历史的流程实例列表 Map + */ + default Map getHistoricProcessInstanceMap(Set ids) { + return CollectionUtils.convertMap(getHistoricProcessInstances(ids), HistoricProcessInstance::getId); + } + /** * 创建 ProcessInstance 拓展记录 * diff --git a/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmProcessInstanceServiceImpl.java b/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmProcessInstanceServiceImpl.java index c55e49032..440ecd916 100644 --- a/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmProcessInstanceServiceImpl.java +++ b/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmProcessInstanceServiceImpl.java @@ -5,6 +5,7 @@ import cn.hutool.core.lang.Assert; import cn.hutool.core.util.StrUtil; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.common.util.number.NumberUtils; +import cn.iocoder.yudao.module.bpm.api.task.dto.BpmProcessInstanceCreateReqDTO; import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance.*; import cn.iocoder.yudao.module.bpm.convert.task.BpmProcessInstanceConvert; import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmProcessDefinitionExtDO; @@ -112,6 +113,14 @@ public class BpmProcessInstanceServiceImpl implements BpmProcessInstanceService return createProcessInstance0(userId, definition, createReqVO.getVariables(), null); } + @Override + public String createProcessInstance(Long userId, @Valid BpmProcessInstanceCreateReqDTO createReqDTO) { + // 获得流程定义 + ProcessDefinition definition = processDefinitionService.getActiveProcessDefinition(createReqDTO.getProcessDefinitionKey()); + // 发起流程 + return createProcessInstance0(userId, definition, createReqDTO.getVariables(), createReqDTO.getBusinessKey()); + } + @Override public BpmProcessInstanceRespVO getProcessInstanceVO(String id) { // 获得流程实例 @@ -172,6 +181,11 @@ public class BpmProcessInstanceServiceImpl implements BpmProcessInstanceService return historyService.createHistoricProcessInstanceQuery().processInstanceId(id).singleResult(); } + @Override + public List getHistoricProcessInstances(Set ids) { + return historyService.createHistoricProcessInstanceQuery().processInstanceIds(ids).list(); + } + @Override public void createProcessInstanceExt(ProcessInstance instance) { // 获得流程定义 diff --git a/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmTaskService.java b/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmTaskService.java index 339234826..e8aab6aa8 100644 --- a/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmTaskService.java +++ b/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmTaskService.java @@ -25,6 +25,14 @@ public interface BpmTaskService { * @return 流程任务分页 */ PageResult getTodoTaskPage(Long userId, BpmTaskTodoPageReqVO pageReqVO); + /** + * 获得已办的流程任务分页 + * + * @param userId 用户编号 + * @param pageReqVO 分页请求 + * @return 流程任务分页 + */ + PageResult getDoneTaskPage(Long userId, BpmTaskDonePageReqVO pageReqVO); /** * 获得流程任务 Map @@ -69,6 +77,22 @@ public interface BpmTaskService { */ void rejectTask(Long userId, @Valid BpmTaskRejectReqVO reqVO); + /** + * 将流程任务分配给指定用户 + * + * @param userId 用户编号 + * @param reqVO 分配请求 + */ + void updateTaskAssignee(Long userId, BpmTaskUpdateAssigneeReqVO reqVO); + + /** + * 将流程任务分配给指定用户 + * + * @param id 流程任务编号 + * @param userId 用户编号 + */ + void updateTaskAssignee(String id, Long userId); + /** * 创建 Task 拓展记录 * @@ -83,4 +107,11 @@ public interface BpmTaskService { */ void updateTaskExtComplete(Task task); + /** + * 更新 Task 拓展记录,并发送通知 + * + * @param task 任务实体 + */ + void updateTaskExtAssign(Task task); + } diff --git a/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmTaskServiceImpl.java b/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmTaskServiceImpl.java index d0e983702..4028679e0 100644 --- a/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmTaskServiceImpl.java +++ b/yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmTaskServiceImpl.java @@ -10,6 +10,7 @@ import cn.iocoder.yudao.module.bpm.convert.task.BpmTaskConvert; import cn.iocoder.yudao.module.bpm.dal.dataobject.task.BpmTaskExtDO; import cn.iocoder.yudao.module.bpm.dal.mysql.task.BpmTaskExtMapper; import cn.iocoder.yudao.module.bpm.enums.task.BpmProcessInstanceResultEnum; +import cn.iocoder.yudao.module.bpm.service.message.BpmMessageService; import cn.iocoder.yudao.module.system.api.dept.DeptApi; import cn.iocoder.yudao.module.system.api.dept.dto.DeptRespDTO; import cn.iocoder.yudao.module.system.api.user.AdminUserApi; @@ -22,7 +23,10 @@ import org.flowable.engine.runtime.ProcessInstance; import org.flowable.task.api.Task; import org.flowable.task.api.TaskQuery; import org.flowable.task.api.history.HistoricTaskInstance; +import org.flowable.task.api.history.HistoricTaskInstanceQuery; import org.springframework.stereotype.Service; +import org.springframework.transaction.support.TransactionSynchronization; +import org.springframework.transaction.support.TransactionSynchronizationManager; import javax.annotation.Resource; import javax.validation.Valid; @@ -56,6 +60,8 @@ public class BpmTaskServiceImpl implements BpmTaskService{ private DeptApi deptApi; @Resource private BpmTaskExtMapper taskExtMapper; + @Resource + private BpmMessageService messageService; @Override public PageResult getTodoTaskPage(Long userId, BpmTaskTodoPageReqVO pageVO) { @@ -89,6 +95,42 @@ public class BpmTaskServiceImpl implements BpmTaskService{ taskQuery.count()); } + @Override + public PageResult getDoneTaskPage(Long userId, BpmTaskDonePageReqVO pageVO) { + // 查询已办任务 + HistoricTaskInstanceQuery taskQuery = historyService.createHistoricTaskInstanceQuery() + .finished() // 已完成 + .taskAssignee(String.valueOf(userId)) // 分配给自己 + .orderByHistoricTaskInstanceEndTime().desc(); // 审批时间倒序 + if (StrUtil.isNotBlank(pageVO.getName())) { + taskQuery.taskNameLike("%" + pageVO.getName() + "%"); + } + if (pageVO.getBeginCreateTime() != null) { + taskQuery.taskCreatedAfter(pageVO.getBeginCreateTime()); + } + if (pageVO.getEndCreateTime() != null) { + taskQuery.taskCreatedBefore(pageVO.getEndCreateTime()); + } + // 执行查询 + List tasks = taskQuery.listPage(PageUtils.getStart(pageVO), pageVO.getPageSize()); + if (CollUtil.isEmpty(tasks)) { + return PageResult.empty(taskQuery.count()); + } + + // 获得 TaskExtDO Map + List bpmTaskExtDOs = taskExtMapper.selectListByTaskIds(convertSet(tasks, HistoricTaskInstance::getId)); + Map bpmTaskExtDOMap = convertMap(bpmTaskExtDOs, BpmTaskExtDO::getTaskId); + // 获得 ProcessInstance Map + Map historicProcessInstanceMap = processInstanceService.getHistoricProcessInstanceMap( + convertSet(tasks, HistoricTaskInstance::getProcessInstanceId)); + // 获得 User Map + Map userMap = adminUserApi.getUserMap( + convertSet(historicProcessInstanceMap.values(), instance -> Long.valueOf(instance.getStartUserId()))); + // 拼接结果 + return new PageResult<>(BpmTaskConvert.INSTANCE.convertList2(tasks, bpmTaskExtDOMap, historicProcessInstanceMap, userMap), + taskQuery.count()); + } + @Override public List getTasksByProcessInstanceIds(List processInstanceIds) { if (CollUtil.isEmpty(processInstanceIds)) { @@ -158,6 +200,19 @@ public class BpmTaskServiceImpl implements BpmTaskService{ .setResult(BpmProcessInstanceResultEnum.REJECT.getResult()).setComment(reqVO.getComment())); } + @Override + public void updateTaskAssignee(Long userId, BpmTaskUpdateAssigneeReqVO reqVO) { + // 校验任务存在 + Task task = checkTask(userId, reqVO.getId()); + // 更新负责人 + updateTaskAssignee(task.getId(), reqVO.getAssigneeUserId()); + } + + @Override + public void updateTaskAssignee(String id, Long userId) { + taskService.setAssignee(id, String.valueOf(userId)); + } + @Override public void createTaskExt(Task task) { @@ -173,6 +228,24 @@ public class BpmTaskServiceImpl implements BpmTaskService{ taskExtMapper.updateByTaskId(taskExtDO); } + @Override + public void updateTaskExtAssign(Task task) { + BpmTaskExtDO taskExtDO = new BpmTaskExtDO() + .setAssigneeUserId(NumberUtils.parseLong(task.getAssignee())) + .setTaskId(task.getId()); + taskExtMapper.updateByTaskId(taskExtDO); + //TODO 创建任务时候 也会调用 updateTaskExtAssign, processInstance 名称为空 校验不通过 + // 发送通知。在事务提交时,批量执行操作,所以直接查询会无法查询到 ProcessInstance,所以这里是通过监听事务的提交来实现。 +// TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronization() { +// @Override +// public void afterCommit() { +// ProcessInstance processInstance = processInstanceService.getProcessInstance(task.getProcessInstanceId()); +// AdminUserRespDTO startUser = adminUserApi.getUser(Long.valueOf(processInstance.getStartUserId())); +// messageService.sendMessageWhenTaskAssigned(BpmTaskConvert.INSTANCE.convert(processInstance, startUser, task)); +// } +// }); + } + /** * 校验任务是否存在, 并且是否是分配给自己的任务 * @param userId 用户 id