From e69e9d30870272408fa8a349463eb39912f2fd9d Mon Sep 17 00:00:00 2001 From: songgaoshuai <1742057357@qq.com> Date: Thu, 8 Jun 2023 12:33:48 +0800 Subject: [PATCH] =?UTF-8?q?add=20=E6=B7=BB=E5=8A=A0=E6=B5=81=E7=A8=8B?= =?UTF-8?q?=E5=8A=9E=E7=90=86=EF=BC=8C=E6=B5=81=E7=A8=8B=E5=BE=85=E5=8A=9E?= =?UTF-8?q?=EF=BC=8C=E5=B7=B2=E5=8A=9E=E5=88=86=E9=A1=B5=E6=9F=A5=E8=AF=A2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../common/constant/FlowConstant.java | 2 + .../controller/ActModelController.java | 2 +- .../ActProcessDefinitionController.java | 5 +- .../controller/ActTaskController.java | 40 ++++++- .../workflow/domain/bo/CompleteTaskBo.java | 48 +++++++++ .../dromara/workflow/domain/bo/TaskBo.java | 26 +++++ .../dromara/workflow/domain/vo/TaskVo.java | 99 +++++++++++++++++ .../workflow/service/IActTaskService.java | 29 +++++ .../service/impl/ActTaskServiceImpl.java | 100 +++++++++++++++++- 9 files changed, 344 insertions(+), 7 deletions(-) create mode 100644 ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/domain/bo/CompleteTaskBo.java create mode 100644 ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/domain/bo/TaskBo.java create mode 100644 ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/domain/vo/TaskVo.java diff --git a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/common/constant/FlowConstant.java b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/common/constant/FlowConstant.java index e69e4e79a..e5462f1ce 100644 --- a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/common/constant/FlowConstant.java +++ b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/common/constant/FlowConstant.java @@ -13,4 +13,6 @@ public interface FlowConstant { */ String NAMESPACE = "http://b3mn.org/stencilset/bpmn2.0#"; + String MESSAGE_CURRENT_TASK_IS_NULL = "当前任务不存在或你不是任务办理人"; + } diff --git a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/controller/ActModelController.java b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/controller/ActModelController.java index 73f19ee02..8d5e75d88 100644 --- a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/controller/ActModelController.java +++ b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/controller/ActModelController.java @@ -101,7 +101,7 @@ public class ActModelController extends BaseController { * @param modelId 模型id */ @GetMapping("/rest/models/{modelId}/editor/json") - public ObjectNode getModelInfo(@PathVariable String modelId) { + public ObjectNode getModelInfo(@NotBlank(message = "模型id不能为空") @PathVariable String modelId) { return iActModelService.getModelInfo(modelId); } diff --git a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/controller/ActProcessDefinitionController.java b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/controller/ActProcessDefinitionController.java index 4933b0937..9c0ca92d3 100644 --- a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/controller/ActProcessDefinitionController.java +++ b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/controller/ActProcessDefinitionController.java @@ -97,7 +97,7 @@ public class ActProcessDefinitionController extends BaseController { */ @Log(title = "流程定义管理", businessType = BusinessType.UPDATE) @PutMapping("/updateProcessDefState/{processDefinitionId}") - public R updateProcDefState(@PathVariable String processDefinitionId) { + public R updateProcDefState(@NotBlank(message = "流程定义id不能为空") @PathVariable String processDefinitionId) { return toAjax(iActProcessDefinitionService.updateProcessDefState(processDefinitionId)); } @@ -109,7 +109,8 @@ public class ActProcessDefinitionController extends BaseController { */ @Log(title = "流程定义管理", businessType = BusinessType.UPDATE) @PutMapping("/migrationProcessDefinition/{currentProcessDefinitionId}/{fromProcessDefinitionId}") - public R migrationProcessDefinition(@PathVariable String currentProcessDefinitionId, @PathVariable String fromProcessDefinitionId) { + public R migrationProcessDefinition(@NotBlank(message = "当前流程定义id") @PathVariable String currentProcessDefinitionId, + @NotBlank(message = "需要迁移到的流程定义id") @PathVariable String fromProcessDefinitionId) { return toAjax(iActProcessDefinitionService.migrationProcessDefinition(currentProcessDefinitionId, fromProcessDefinitionId)); } diff --git a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/controller/ActTaskController.java b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/controller/ActTaskController.java index c66a68027..886cf67c6 100644 --- a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/controller/ActTaskController.java +++ b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/controller/ActTaskController.java @@ -2,10 +2,16 @@ package org.dromara.workflow.controller; import lombok.RequiredArgsConstructor; import org.dromara.common.core.domain.R; +import org.dromara.common.core.validate.AddGroup; import org.dromara.common.idempotent.annotation.RepeatSubmit; import org.dromara.common.log.annotation.Log; import org.dromara.common.log.enums.BusinessType; +import org.dromara.common.mybatis.core.page.TableDataInfo; +import org.dromara.common.web.core.BaseController; +import org.dromara.workflow.domain.bo.CompleteTaskBo; import org.dromara.workflow.domain.bo.StartProcessBo; +import org.dromara.workflow.domain.bo.TaskBo; +import org.dromara.workflow.domain.vo.TaskVo; import org.dromara.workflow.service.IActTaskService; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; @@ -21,7 +27,7 @@ import java.util.Map; @RequiredArgsConstructor @RestController @RequestMapping("/workflow/task") -public class ActTaskController { +public class ActTaskController extends BaseController { private final IActTaskService iActTaskService; @@ -38,4 +44,36 @@ public class ActTaskController { Map map = iActTaskService.startWorkFlow(startProcessBo); return R.ok("提交成功", map); } + + /** + * 办理任务 + * + * @param completeTaskBo 办理任务参数 + */ + @Log(title = "任务管理", businessType = BusinessType.INSERT) + @RepeatSubmit() + @PostMapping("/completeTask") + public R completeTask(@Validated(AddGroup.class) @RequestBody CompleteTaskBo completeTaskBo) { + return toAjax(iActTaskService.completeTask(completeTaskBo)); + } + + /** + * 查询当前用户的待办任务 + * + * @param taskBo 参数 + */ + @GetMapping("/getTaskWaitByPage") + public TableDataInfo getTaskWaitByPage(TaskBo taskBo) { + return iActTaskService.getTaskWaitByPage(taskBo); + } + + /** + * 查询当前用户的已办任务 + * + * @param taskBo 参数 + */ + @GetMapping("/getTaskFinishByPage") + public TableDataInfo getTaskFinishByPage(TaskBo taskBo) { + return iActTaskService.getTaskFinishByPage(taskBo); + } } diff --git a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/domain/bo/CompleteTaskBo.java b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/domain/bo/CompleteTaskBo.java new file mode 100644 index 000000000..65bd42a49 --- /dev/null +++ b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/domain/bo/CompleteTaskBo.java @@ -0,0 +1,48 @@ +package org.dromara.workflow.domain.bo; + +import jakarta.validation.constraints.NotBlank; +import lombok.Data; +import org.dromara.common.core.validate.AddGroup; + +import java.io.Serial; +import java.io.Serializable; +import java.util.HashMap; +import java.util.Map; +import java.util.Objects; + +/** + * 办理任务请求对象 + * + * @author may + */ +@Data +public class CompleteTaskBo implements Serializable { + + @Serial + private static final long serialVersionUID = 1L; + + /** + * 任务id + */ + @NotBlank(message = "任务id不能为空", groups = {AddGroup.class}) + private String taskId; + + /** + * 办理意见 + */ + private String message; + + /** + * 流程变量 + */ + private Map variables; + + public Map getVariables() { + if (variables == null) { + return new HashMap<>(16); + } + variables.entrySet().removeIf(entry -> Objects.isNull(entry.getValue())); + return variables; + } + +} diff --git a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/domain/bo/TaskBo.java b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/domain/bo/TaskBo.java new file mode 100644 index 000000000..0064be79a --- /dev/null +++ b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/domain/bo/TaskBo.java @@ -0,0 +1,26 @@ +package org.dromara.workflow.domain.bo; + +import lombok.Data; +import lombok.EqualsAndHashCode; +import org.dromara.workflow.common.PageEntity; + +import java.io.Serial; +import java.io.Serializable; + +/** + * 任务请求对象 + * + * @author may + */ +@Data +@EqualsAndHashCode(callSuper = true) +public class TaskBo extends PageEntity implements Serializable { + + @Serial + private static final long serialVersionUID = 1L; + + /** + * 任务名称 + */ + private String name; +} diff --git a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/domain/vo/TaskVo.java b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/domain/vo/TaskVo.java new file mode 100644 index 000000000..4169de0a1 --- /dev/null +++ b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/domain/vo/TaskVo.java @@ -0,0 +1,99 @@ +package org.dromara.workflow.domain.vo; + +import lombok.Data; + +import java.util.Date; + +/** + * 任务视图 + * + * @author may + */ +@Data +public class TaskVo { + + /** + * 任务id + */ + private String id; + + /** + * 任务名称 + */ + private String name; + + /** + * 描述 + */ + private String description; + + /** + * 优先级 + */ + private Integer priority; + + /** + * 负责此任务的人员的用户id + */ + private String owner; + + /** + * 办理人id + */ + private String assignee; + + /** + * 流程实例id + */ + private String processInstanceId; + + /** + * 执行id + */ + private String executionId; + + /** + * 无用 + */ + private String taskDefinitionId; + + /** + * 流程定义id + */ + private String processDefinitionId; + + /** + * 创建时间 + */ + private Date createTime; + + /** + * 节点id + */ + private String taskDefinitionKey; + + /** + * 任务截止日期 + */ + private Date dueDate; + + /** + * 流程类别 + */ + private String category; + + /** + * 父级任务id + */ + private String parentTaskId; + + /** + * 租户id + */ + private String tenantId; + + /** + * 认领时间 + */ + private Date claimTime; +} diff --git a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/IActTaskService.java b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/IActTaskService.java index b90001d77..15b149b0e 100644 --- a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/IActTaskService.java +++ b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/IActTaskService.java @@ -1,6 +1,10 @@ package org.dromara.workflow.service; +import org.dromara.common.mybatis.core.page.TableDataInfo; +import org.dromara.workflow.domain.bo.CompleteTaskBo; import org.dromara.workflow.domain.bo.StartProcessBo; +import org.dromara.workflow.domain.bo.TaskBo; +import org.dromara.workflow.domain.vo.TaskVo; import java.util.Map; @@ -17,4 +21,29 @@ public interface IActTaskService { * @return 结果 */ Map startWorkFlow(StartProcessBo startProcessBo); + + + /** + * 办理任务 + * + * @param completeTaskBo 办理任务参数 + * @return 结果 + */ + boolean completeTask(CompleteTaskBo completeTaskBo); + + /** + * 查询当前用户的待办任务 + * + * @param taskBo 参数 + * @return 结果 + */ + TableDataInfo getTaskWaitByPage(TaskBo taskBo); + + /** + * 查询当前用户的已办任务 + * + * @param taskBo 参数 + * @return 结果 + */ + TableDataInfo getTaskFinishByPage(TaskBo taskBo); } diff --git a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/impl/ActTaskServiceImpl.java b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/impl/ActTaskServiceImpl.java index 7b085832b..a02dadabc 100644 --- a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/impl/ActTaskServiceImpl.java +++ b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/impl/ActTaskServiceImpl.java @@ -1,12 +1,19 @@ package org.dromara.workflow.service.impl; +import cn.hutool.core.bean.BeanUtil; import cn.hutool.core.collection.CollUtil; import lombok.RequiredArgsConstructor; +import org.dromara.common.core.domain.dto.RoleDTO; import org.dromara.common.core.exception.ServiceException; import org.dromara.common.core.utils.StringUtils; +import org.dromara.common.mybatis.core.page.TableDataInfo; import org.dromara.common.satoken.utils.LoginHelper; import org.dromara.common.tenant.helper.TenantHelper; +import org.dromara.workflow.common.constant.FlowConstant; +import org.dromara.workflow.domain.bo.CompleteTaskBo; import org.dromara.workflow.domain.bo.StartProcessBo; +import org.dromara.workflow.domain.bo.TaskBo; +import org.dromara.workflow.domain.vo.TaskVo; import org.dromara.workflow.service.IActTaskService; import org.flowable.common.engine.impl.identity.Authentication; import org.flowable.engine.HistoryService; @@ -16,11 +23,16 @@ import org.flowable.engine.history.HistoricProcessInstance; 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.annotation.Transactional; +import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.stream.Collectors; /** * 任务 服务层实现 @@ -47,9 +59,10 @@ public class ActTaskServiceImpl implements IActTaskService { throw new ServiceException("启动工作流时必须包含业务ID"); } // 判断当前业务是否启动过流程 - List instanceList = historyService.createHistoricProcessInstanceQuery().processInstanceBusinessKey(startProcessBo.getBusinessKey()).list(); + List instanceList = historyService.createHistoricProcessInstanceQuery() + .processInstanceBusinessKey(startProcessBo.getBusinessKey()).processInstanceTenantIdLike(TenantHelper.getTenantId()).list(); TaskQuery taskQuery = taskService.createTaskQuery(); - List taskResult = taskQuery.processInstanceBusinessKey(startProcessBo.getBusinessKey()).list(); + List taskResult = taskQuery.processInstanceBusinessKey(startProcessBo.getBusinessKey()).taskTenantId(TenantHelper.getTenantId()).list(); if (CollUtil.isNotEmpty(instanceList)) { map.put("processInstanceId", taskResult.get(0).getProcessInstanceId()); map.put("taskId", taskResult.get(0).getId()); @@ -70,7 +83,7 @@ public class ActTaskServiceImpl implements IActTaskService { // 将流程定义名称 作为 流程实例名称 runtimeService.setProcessInstanceName(pi.getProcessInstanceId(), pi.getProcessDefinitionName()); // 申请人执行流程 - List taskList = taskService.createTaskQuery().processInstanceId(pi.getId()).list(); + List taskList = taskService.createTaskQuery().processInstanceId(pi.getId()).taskTenantId(TenantHelper.getTenantId()).list(); if (taskList.size() > 1) { throw new ServiceException("请检查流程第一个环节是否为申请人!"); } @@ -80,4 +93,85 @@ public class ActTaskServiceImpl implements IActTaskService { map.put("taskId", taskList.get(0).getId()); return map; } + + /** + * 办理任务 + * + * @param completeTaskBo 办理任务参数 + */ + @Override + @Transactional(rollbackFor = Exception.class) + public boolean completeTask(CompleteTaskBo completeTaskBo) { + try { + List roles = LoginHelper.getLoginUser().getRoles(); + String userId = LoginHelper.getUserId().toString(); + TaskQuery taskQuery = taskService.createTaskQuery(); + taskQuery.taskId(completeTaskBo.getTaskId()) + .taskTenantId(TenantHelper.getTenantId()).taskCandidateOrAssigned(userId); + if (CollUtil.isNotEmpty(roles)) { + List groupIds = roles.stream().map(e -> String.valueOf(e.getRoleId())).collect(Collectors.toList()); + taskQuery.taskCandidateGroupIn(groupIds); + } + Task task = taskQuery.singleResult(); + if (task == null) { + throw new ServiceException(FlowConstant.MESSAGE_CURRENT_TASK_IS_NULL); + } + //办理任务 + taskService.complete(completeTaskBo.getTaskId(), completeTaskBo.getVariables()); + //办理意见 + taskService.addComment(completeTaskBo.getTaskId(), task.getProcessInstanceId(), StringUtils.isBlank(completeTaskBo.getMessage()) ? "同意" : completeTaskBo.getMessage()); + return true; + } catch (Exception e) { + throw new ServiceException(e.getMessage()); + } + } + + /** + * 查询当前用户的待办任务 + * + * @param taskBo 参数 + */ + @Override + public TableDataInfo getTaskWaitByPage(TaskBo taskBo) { + List roles = LoginHelper.getLoginUser().getRoles(); + String userId = LoginHelper.getUserId().toString(); + TaskQuery query = taskService.createTaskQuery(); + query.taskTenantId(TenantHelper.getTenantId()).taskCandidateOrAssigned(userId); + if (CollUtil.isNotEmpty(roles)) { + List groupIds = roles.stream().map(e -> String.valueOf(e.getRoleId())).collect(Collectors.toList()); + query.taskCandidateGroupIn(groupIds); + } + if (StringUtils.isNotBlank(taskBo.getName())) { + query.taskNameLike(taskBo.getName()); + } + List taskList = query.listPage(taskBo.getPageNum(), taskBo.getPageSize()); + List list = new ArrayList<>(); + for (Task task : taskList) { + list.add(BeanUtil.toBean(task, TaskVo.class)); + } + long count = query.count(); + return new TableDataInfo<>(list, count); + } + + /** + * 查询当前用户的已办任务 + * + * @param taskBo 参数 + */ + @Override + public TableDataInfo getTaskFinishByPage(TaskBo taskBo) { + String userId = LoginHelper.getUserId().toString(); + HistoricTaskInstanceQuery query = historyService.createHistoricTaskInstanceQuery() + .taskAssignee(userId).taskTenantId(TenantHelper.getTenantId()).finished().orderByHistoricTaskInstanceStartTime().asc(); + if (StringUtils.isNotBlank(taskBo.getName())) { + query.taskNameLike(taskBo.getName()); + } + List taskInstanceList = query.listPage(taskBo.getPageNum(), taskBo.getPageSize()); + List list = new ArrayList<>(); + for (HistoricTaskInstance task : taskInstanceList) { + list.add(BeanUtil.toBean(task, TaskVo.class)); + } + long count = query.count(); + return new TableDataInfo<>(list, count); + } }