diff --git a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/controller/task/BpmTaskController.http b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/controller/task/BpmTaskController.http new file mode 100644 index 000000000..40bd2ccf5 --- /dev/null +++ b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/controller/task/BpmTaskController.http @@ -0,0 +1,4 @@ +### 请求 /bpm/task/todo-page 接口 => 成功 +GET {{baseUrl}}/bpm/task/todo-page +tenant-id: 1 +Authorization: Bearer {{token}} diff --git a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/controller/task/TaskController.java b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/controller/task/BpmTaskController.java similarity index 57% rename from yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/controller/task/TaskController.java rename to yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/controller/task/BpmTaskController.java index 877ee7fac..137b01a0d 100644 --- a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/controller/task/TaskController.java +++ b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/controller/task/BpmTaskController.java @@ -7,6 +7,7 @@ import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.common.util.servlet.ServletUtils; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; +import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; import javax.annotation.Resource; @@ -16,48 +17,39 @@ import java.io.IOException; import java.util.List; import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; +import static cn.iocoder.yudao.framework.web.core.util.WebFrameworkUtils.getLoginUserId; -// TODO @json:swagger 和 validation 的注解,后续要补全下哈。可以等 workflow 基本写的差不多之后 -@Api(tags = "工作流待办任务") +@Api(tags = "流程任务") @RestController -@RequestMapping("/workflow/task") -public class TaskController { +@RequestMapping("/bpm/task") +@Validated +public class BpmTaskController { @Resource - private BpmTaskService bpmTaskService; + private BpmTaskService taskService; - @GetMapping("/todo/page") - @ApiOperation("获取待办任务分页") - public CommonResult> getTodoTaskPage(@Valid TodoTaskPageReqVO pageVO) { - return success(bpmTaskService.getTodoTaskPage(pageVO)); - } + // TODO 芋艿:权限、validation; - @GetMapping("/claim") - @ApiOperation("签收任务") - public CommonResult claimTask(@RequestParam("id") String taskId) { - bpmTaskService.claimTask(taskId); - return success(true); + @GetMapping("todo-page") + @ApiOperation("获取 TODO 待办任务分页") + public CommonResult> getTodoTaskPage(@Valid BpmTaskTodoPageReqVO pageVO) { + return success(taskService.getTodoTaskPage(getLoginUserId(), pageVO)); } @PostMapping("/task-steps") public CommonResult getTaskSteps(@RequestBody TaskQueryReqVO taskQuery) { - return success(bpmTaskService.getTaskSteps(taskQuery)); - } - - @PostMapping("/formKey") - public CommonResult getTaskFormKey(@RequestBody TaskQueryReqVO taskQuery) { - return success(bpmTaskService.getTaskFormKey(taskQuery)); + return success(taskService.getTaskSteps(taskQuery)); } @PostMapping("/complete") public CommonResult complete(@RequestBody TaskReqVO taskReq) { - bpmTaskService.completeTask(taskReq); + taskService.completeTask(taskReq); return success(true); } @GetMapping("/process/history-steps") public CommonResult> getHistorySteps(@RequestParam("id") String processInstanceId) { - return success(bpmTaskService.getHistorySteps(processInstanceId)); + return success(taskService.getHistorySteps(processInstanceId)); } /** @@ -66,7 +58,7 @@ public class TaskController { */ @GetMapping("/process/highlight-img") public void getHighlightImg(@RequestParam String processInstanceId, HttpServletResponse response) throws IOException { - FileResp fileResp = bpmTaskService.getHighlightImg(processInstanceId); + FileResp fileResp = taskService.getHighlightImg(processInstanceId); ServletUtils.writeAttachment(response, fileResp.getFileName(), fileResp.getFileByte()); } diff --git a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/controller/task/vo/task/BpmTaskTodoPageItemRespVO.java b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/controller/task/vo/task/BpmTaskTodoPageItemRespVO.java new file mode 100644 index 000000000..1eccc3eba --- /dev/null +++ b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/controller/task/vo/task/BpmTaskTodoPageItemRespVO.java @@ -0,0 +1,52 @@ +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 java.util.Date; + +@ApiModel(value = "流程任务的 Running 进行中的分页项 Response VO", description = "待办任务") +@Data +public class 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 = "任务状态", notes = "参见 bpm_process_instance_status", example = "1") + private Integer status; + + /** + * 所属流程实例 + */ + private ProcessInstance processInstance; + + @Data + @ApiModel("流程实例") + public static class ProcessInstance { + + @ApiModelProperty(value = "流程实例编号", required = true, example = "1024") + private String id; + + @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; + + } + + // 任务编号、任务名称、任务节点、流程版本、流程发起人、接收时间【名称、开始时间】「处理」 + // 任务编号、任务名称、所属流程、委托代办人、流程发起人、优先级、状态、创建时间【名称、开始时间】「申请详情、通过、驳回、转办、历史」 + + // 任务编号、任务名称、流程名称、流程发起人、接收时间、状态【名称、接收时间】【处理、委托】 +} diff --git a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/controller/task/vo/task/BpmTaskTodoPageReqVO.java b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/controller/task/vo/task/BpmTaskTodoPageReqVO.java new file mode 100644 index 000000000..d89e582f1 --- /dev/null +++ b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/controller/task/vo/task/BpmTaskTodoPageReqVO.java @@ -0,0 +1,32 @@ +package cn.iocoder.yudao.adminserver.modules.bpm.controller.task.vo.task; + +import cn.iocoder.yudao.framework.common.pojo.PageParam; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.ToString; +import org.springframework.format.annotation.DateTimeFormat; + +import java.util.Date; + +import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; + +@ApiModel("流程任务的 TODO 待办的分页 Request VO") +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +public class BpmTaskTodoPageReqVO extends PageParam { + + @ApiModelProperty(value = "流程任务名", example = "芋道") + private String name; + + @ApiModelProperty(value = "开始的创建收间") + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) + private Date beginCreateTime; + + @ApiModelProperty(value = "结束的创建时间") + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) + private Date endCreateTime; + +} diff --git a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/controller/task/vo/task/TodoTaskPageReqVO.java b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/controller/task/vo/task/TodoTaskPageReqVO.java deleted file mode 100644 index 78691d2fa..000000000 --- a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/controller/task/vo/task/TodoTaskPageReqVO.java +++ /dev/null @@ -1,16 +0,0 @@ -package cn.iocoder.yudao.adminserver.modules.bpm.controller.task.vo.task; - -import cn.iocoder.yudao.framework.common.pojo.PageParam; -import io.swagger.annotations.ApiModel; -import lombok.Data; -import lombok.EqualsAndHashCode; -import lombok.ToString; - -@ApiModel("待办任务申请分页 Request VO") -@Data -@EqualsAndHashCode(callSuper = true) -@ToString(callSuper = true) -public class TodoTaskPageReqVO extends PageParam { - - private String assignee; -} diff --git a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/controller/task/vo/task/TodoTaskRespVO.java b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/controller/task/vo/task/TodoTaskRespVO.java deleted file mode 100644 index 8ffd3d56f..000000000 --- a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/controller/task/vo/task/TodoTaskRespVO.java +++ /dev/null @@ -1,37 +0,0 @@ -package cn.iocoder.yudao.adminserver.modules.bpm.controller.task.vo.task; - -import io.swagger.annotations.ApiModel; -import lombok.Data; -import lombok.ToString; - -@ApiModel("待办任务 Response VO") -@Data -@ToString -public class TodoTaskRespVO { - - // TODO @jason:swagger 注解。这样接口文档才完整哈 - - private String id; - - - private String processInstanceId; - - /** - * 1:未签收 - * 2:已签收 - */ - private Integer status; - - - private String processName; - - - private String processKey; - - - private String businessKey; - - - private String formKey; - -} diff --git a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/convert/task/BpmProcessInstanceConvert.java b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/convert/task/BpmProcessInstanceConvert.java index c1263e5d8..e630b9aab 100644 --- a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/convert/task/BpmProcessInstanceConvert.java +++ b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/convert/task/BpmProcessInstanceConvert.java @@ -26,7 +26,7 @@ public interface BpmProcessInstanceConvert { BpmProcessInstanceConvert INSTANCE = Mappers.getMapper(BpmProcessInstanceConvert.class); @Mappings({ - @Mapping(source = "instance.startUserId", target = "userId"), + @Mapping(source = "instance.startUserId", target = "startUserId"), @Mapping(source = "instance.id", target = "processInstanceId"), @Mapping(source = "instance.startTime", target = "createTime"), @Mapping(source = "definition.id", target = "processDefinitionId"), diff --git a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/convert/task/BpmTaskConvert.java b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/convert/task/BpmTaskConvert.java new file mode 100644 index 000000000..ff2e6482e --- /dev/null +++ b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/convert/task/BpmTaskConvert.java @@ -0,0 +1,62 @@ +package cn.iocoder.yudao.adminserver.modules.bpm.convert.task; + +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.coreservice.modules.system.dal.dataobject.user.SysUserDO; +import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; +import org.activiti.engine.history.HistoricActivityInstance; +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.factory.Mappers; + +import java.util.List; +import java.util.Map; + +/** + * Bpm 任务 Convert + * + * @author 芋道源码 + */ +@Mapper +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 convertList(List tasks, Map processInstanceMap, + Map userMap) { + return CollectionUtils.convertList(tasks, task -> { + ProcessInstance processInstance = processInstanceMap.get(task.getProcessInstanceId()); + return convert(task, processInstance, userMap.get(Long.valueOf(processInstance.getStartUserId()))); + }); + } + + @Mappings({ + @Mapping(source = "task.id", target = "id"), + @Mapping(source = "task.name", target = "name"), + @Mapping(source = "task.claimTime", target = "claimTime"), + @Mapping(source = "task.suspended", target = "status", qualifiedByName = "convertSuspendedToStatus"), + @Mapping(source = "processInstance.id", target = "processInstance.id"), + @Mapping(source = "processInstance.startUserId", target = "processInstance.startUserId"), + @Mapping(source = "processInstance.processDefinitionId", target = "processInstance.processDefinitionId"), + @Mapping(source = "user.nickname", target = "processInstance.startUserNickname") + }) + BpmTaskTodoPageItemRespVO convert(Task task, ProcessInstance processInstance, SysUserDO user); + + @Named("convertSuspendedToStatus") + default Integer convertAssigneeToStatus(boolean suspended) { + return suspended ? SuspensionState.SUSPENDED.getStateCode() : + SuspensionState.ACTIVE.getStateCode(); + } + +} diff --git a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/convert/task/TaskConvert.java b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/convert/task/TaskConvert.java deleted file mode 100644 index c300df396..000000000 --- a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/convert/task/TaskConvert.java +++ /dev/null @@ -1,44 +0,0 @@ -package cn.iocoder.yudao.adminserver.modules.bpm.convert.task; - -import cn.iocoder.yudao.adminserver.modules.bpm.controller.task.vo.task.TaskStepVO; -import cn.iocoder.yudao.adminserver.modules.bpm.controller.task.vo.task.TodoTaskRespVO; -import org.activiti.api.task.model.Task; -import org.activiti.engine.history.HistoricActivityInstance; -import org.activiti.engine.repository.ProcessDefinition; -import org.mapstruct.Mapper; -import org.mapstruct.Mapping; -import org.mapstruct.Mappings; -import org.mapstruct.Named; -import org.mapstruct.factory.Mappers; - -@Mapper -public interface TaskConvert { - TaskConvert INSTANCE = Mappers.getMapper(TaskConvert.class); - - @Mappings(value = { - @Mapping(source = "task.id", target = "id"), - @Mapping(source = "task.businessKey", target = "businessKey"), - @Mapping(source = "task.assignee", target = "status",qualifiedByName = "convertAssigneeToStatus"), - @Mapping(source = "definition.name", target = "processName"), - @Mapping(source = "definition.key", target = "processKey"), - @Mapping(source = "definition.id", target = "processInstanceId") - }) - TodoTaskRespVO convert(Task task, ProcessDefinition definition); - - @Mappings(value = { - @Mapping(source = "assignee", target = "status",qualifiedByName = "convertAssigneeToStatus") - }) - TodoTaskRespVO convert(Task task); - - @Named("convertAssigneeToStatus") - default Integer convertAssigneeToStatus(String assignee) { - //TODO 不应该通过 assignee 定义状态 需要定义更多的状态 - return assignee == null ? 1 : 2; - } - - @Mappings(value = { - @Mapping(source = "activityName", target = "stepName"), - @Mapping(source = "assignee", target = "assignee") - }) - TaskStepVO convert(HistoricActivityInstance instance); -} diff --git a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/dal/dataobject/task/BpmProcessInstanceExtDO.java b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/dal/dataobject/task/BpmProcessInstanceExtDO.java index 53fc87931..36a2490e1 100644 --- a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/dal/dataobject/task/BpmProcessInstanceExtDO.java +++ b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/dal/dataobject/task/BpmProcessInstanceExtDO.java @@ -33,7 +33,7 @@ public class BpmProcessInstanceExtDO extends BaseDO { * * 冗余 {@link HistoricProcessInstance#getStartUserId()} */ - private Long userId; + private Long startUserId; /** * 流程实例的名字 * diff --git a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/dal/mysql/task/BpmProcessInstanceExtMapper.java b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/dal/mysql/task/BpmProcessInstanceExtMapper.java index 1b40e7b12..fab9ab804 100644 --- a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/dal/mysql/task/BpmProcessInstanceExtMapper.java +++ b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/dal/mysql/task/BpmProcessInstanceExtMapper.java @@ -12,7 +12,7 @@ public interface BpmProcessInstanceExtMapper extends BaseMapperX selectPage(Long userId, BpmProcessInstanceMyPageReqVO reqVO) { return selectPage(reqVO, new QueryWrapperX() - .eqIfPresent("user_id", userId) + .eqIfPresent("start_user_id", userId) .likeIfPresent("name", reqVO.getName()) .eqIfPresent("process_definition_id", reqVO.getProcessDefinitionId()) .eqIfPresent("category", reqVO.getCategory()) diff --git a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/service/task/BpmProcessInstanceService.java b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/service/task/BpmProcessInstanceService.java index 58cb2aeb6..f176c7dbe 100644 --- a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/service/task/BpmProcessInstanceService.java +++ b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/service/task/BpmProcessInstanceService.java @@ -4,8 +4,13 @@ import cn.iocoder.yudao.adminserver.modules.bpm.controller.task.vo.instance.BpmP import cn.iocoder.yudao.adminserver.modules.bpm.controller.task.vo.instance.BpmProcessInstanceMyPageReqVO; import cn.iocoder.yudao.adminserver.modules.bpm.controller.task.vo.instance.BpmProcessInstancePageItemRespVO; import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; +import org.activiti.engine.runtime.ProcessInstance; import javax.validation.Valid; +import java.util.List; +import java.util.Map; +import java.util.Set; /** * 流程实例 Service 接口 @@ -33,4 +38,22 @@ public interface BpmProcessInstanceService { PageResult getMyProcessInstancePage(Long userId, @Valid BpmProcessInstanceMyPageReqVO pageReqVO); + /** + * 获得流程实例列表 + * + * @param ids 流程实例的编号集合 + * @return 流程实例列表 + */ + List getProcessInstances(Set ids); + + /** + * 获得流程实例 Map + * + * @param ids 流程实例的编号集合 + * @return 流程实例列表 Map + */ + default Map getProcessInstanceMap(Set ids) { + return CollectionUtils.convertMap(getProcessInstances(ids), ProcessInstance::getProcessInstanceId); + } + } diff --git a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/service/task/BpmTaskService.java b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/service/task/BpmTaskService.java index 30f257628..e7a734943 100644 --- a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/service/task/BpmTaskService.java +++ b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/service/task/BpmTaskService.java @@ -1,6 +1,5 @@ package cn.iocoder.yudao.adminserver.modules.bpm.service.task; -import cn.hutool.core.collection.CollUtil; import cn.iocoder.yudao.adminserver.modules.bpm.controller.task.vo.task.*; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; @@ -8,7 +7,6 @@ import org.activiti.engine.task.Task; import java.util.List; import java.util.Map; -import java.util.Set; /** * 工作任务 Service 接口 @@ -18,6 +16,14 @@ import java.util.Set; */ public interface BpmTaskService { + /** + * 获得流程任务列表 + * + * @param processInstanceId 流程实例的编号 + * @return 流程任务列表 + */ + List getTasksByProcessInstanceId(String processInstanceId); + /** * 获得流程任务列表 * @@ -38,15 +44,28 @@ public interface BpmTaskService { } /** - * 获取当前用户的待办任务, 分页 + * 获得流程任务分页 + * + * @param userId 用户编号 + * @param pageReqVO 分页请求 + * @return 流程任务分页 */ - PageResult getTodoTaskPage(TodoTaskPageReqVO pageReqVO); + PageResult getTodoTaskPage(Long userId, BpmTaskTodoPageReqVO pageReqVO); + + /** + * 将流程任务分配给指定用户 + * + * @param id 流程任务编号 + * @param userId 用户编号 + */ + void updateTaskAssign(String id, Long userId); /** * 签收任务 - * @param taskId 用户任务id + * + * @param id 任务编号 */ - void claimTask(String taskId); + void claimTask(String id); /** * 工作流,完成 userTask, 完成用户任务 一般传入参数 1。是否同意(variables). 2. 评论(comment) @@ -67,13 +86,6 @@ public interface BpmTaskService { */ List getHistorySteps(String processInstanceId); - /** - * 获取用户任务的 formKey, 对应外置表单, 需要根据formKey 对应业务表单 - * @param taskQuery 查询参数 ,一般taskId - */ - TodoTaskRespVO getTaskFormKey(TaskQueryReqVO taskQuery); - - /** * 返回高亮的流转进程 * @param processInstanceId 实例Id diff --git a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/service/task/impl/BpmProcessInstanceServiceImpl.java b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/service/task/impl/BpmProcessInstanceServiceImpl.java index 0c3696a8d..45bd9e410 100644 --- a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/service/task/impl/BpmProcessInstanceServiceImpl.java +++ b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/service/task/impl/BpmProcessInstanceServiceImpl.java @@ -26,12 +26,16 @@ import org.activiti.engine.history.HistoricProcessInstanceQuery; import org.activiti.engine.repository.ProcessDefinition; import org.activiti.engine.runtime.ProcessInstance; import org.activiti.engine.task.Task; +import org.springframework.context.annotation.Lazy; import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; import org.springframework.validation.annotation.Validated; import javax.annotation.Resource; import java.util.List; import java.util.Map; +import java.util.Set; +import java.util.function.Consumer; import static cn.iocoder.yudao.adminserver.modules.bpm.enums.BpmErrorCodeConstants.PROCESS_DEFINITION_IS_SUSPENDED; import static cn.iocoder.yudao.adminserver.modules.bpm.enums.BpmErrorCodeConstants.PROCESS_DEFINITION_NOT_EXISTS; @@ -58,20 +62,21 @@ public class BpmProcessInstanceServiceImpl implements BpmProcessInstanceService @Resource private RuntimeService runtimeService; @Resource - private BpmTaskService taskService; - @Resource private HistoryService historyService; @Resource private SysUserService userService; @Resource + @Lazy // 解决循环依赖 + private BpmTaskService taskService; + @Resource private BpmProcessDefinitionService processDefinitionService; @Resource private BpmProcessInstanceExtMapper processInstanceExtMapper; @Override -// @Transactional(rollbackFor = Exception.class) + @Transactional(rollbackFor = Exception.class) public String createProcessInstance(Long userId, BpmProcessInstanceCreateReqVO createReqVO) { // 校验流程定义 ProcessDefinition definition = processDefinitionService.getProcessDefinition(createReqVO.getProcessDefinitionId()); @@ -90,6 +95,10 @@ public class BpmProcessInstanceServiceImpl implements BpmProcessInstanceService // 记录流程实例的拓展表 createProcessInstanceExt(instance, definition); + // TODO 芋艿:临时使用, 保证分配 + List tasks = taskService.getTasksByProcessInstanceId(instance.getId()); + tasks.forEach(task -> taskService.updateTaskAssign(task.getId(), userId)); + // 添加初始的评论 TODO 芋艿:在思考下 // Task task = taskService.createTaskQuery().processInstanceId(instance.getId()).singleResult(); // if (task != null) { @@ -134,6 +143,11 @@ public class BpmProcessInstanceServiceImpl implements BpmProcessInstanceService return BpmProcessInstanceConvert.INSTANCE.convertPage(pageResult, taskMap); } + @Override + public List getProcessInstances(Set ids) { + return runtimeService.createProcessInstanceQuery().processInstanceIds(ids).list(); + } + /** * 获得流程实例 * diff --git a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/service/task/impl/BpmTaskServiceImpl.java b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/service/task/impl/BpmTaskServiceImpl.java index 28f4d1ece..4a033198d 100644 --- a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/service/task/impl/BpmTaskServiceImpl.java +++ b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/service/task/impl/BpmTaskServiceImpl.java @@ -2,16 +2,17 @@ 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.StrUtil; import cn.iocoder.yudao.adminserver.modules.bpm.controller.task.vo.task.*; -import cn.iocoder.yudao.adminserver.modules.bpm.convert.task.TaskConvert; +import cn.iocoder.yudao.adminserver.modules.bpm.convert.task.BpmTaskConvert; +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.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.security.core.util.SecurityFrameworkUtils; +import cn.iocoder.yudao.framework.common.util.object.PageUtils; import lombok.extern.slf4j.Slf4j; -import org.activiti.api.task.model.builders.ClaimTaskPayloadBuilder; -import org.activiti.api.task.model.builders.TaskPayloadBuilder; -import org.activiti.api.task.runtime.TaskRuntime; import org.activiti.bpmn.constants.BpmnXMLConstants; import org.activiti.bpmn.model.BpmnModel; import org.activiti.bpmn.model.FlowNode; @@ -26,7 +27,9 @@ import org.activiti.engine.repository.ProcessDefinition; import org.activiti.engine.runtime.ProcessInstance; import org.activiti.engine.task.Comment; import org.activiti.engine.task.Task; +import org.activiti.engine.task.TaskQuery; import org.activiti.image.ProcessDiagramGenerator; +import org.springframework.context.annotation.Lazy; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import org.springframework.util.ObjectUtils; @@ -39,13 +42,12 @@ import java.util.*; import static cn.iocoder.yudao.adminserver.modules.bpm.enums.BpmErrorCodeConstants.HIGHLIGHT_IMG_ERROR; import static cn.iocoder.yudao.adminserver.modules.bpm.enums.BpmErrorCodeConstants.PROCESS_INSTANCE_NOT_EXISTS; import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet; @Slf4j @Service public class BpmTaskServiceImpl implements BpmTaskService { - @Resource - private TaskRuntime taskRuntime; @Resource private TaskService taskService; @Resource @@ -58,6 +60,17 @@ public class BpmTaskServiceImpl implements BpmTaskService { @Resource private ProcessDiagramGenerator processDiagramGenerator; + @Resource + private SysUserService userService; + @Resource + @Lazy // 解决循环依赖 + private BpmProcessInstanceService processInstanceService; + + @Override + public List getTasksByProcessInstanceId(String processInstanceId) { + return taskService.createTaskQuery().processInstanceId(processInstanceId).list(); + } + @Override public List getTasksByProcessInstanceIds(List processInstanceIds) { if (CollUtil.isEmpty(processInstanceIds)) { @@ -67,30 +80,52 @@ public class BpmTaskServiceImpl implements BpmTaskService { } @Override - public PageResult getTodoTaskPage(TodoTaskPageReqVO pageReqVO) { - // TODO @jason:封装一个方法,用于转换成 activiti 的分页对象 -// final Pageable pageable = Pageable.of((pageReqVO.getPageNo() - 1) * pageReqVO.getPageSize(), pageReqVO.getPageSize()); -// Page pageTasks = taskRuntime.tasks(pageable); -// int totalItems = pageTasks.getTotalItems(); -// List tasks = pageTasks.getContent(); -// final List respVOList = tasks.stream().map(task -> { -// ProcessDefinition definition = repositoryService.getProcessDefinition(task.getProcessDefinitionId()); -// return TaskConvert.INSTANCE.convert(task, definition); -// }).collect(Collectors.toList()); -// return new PageResult<>(respVOList, (long)totalItems); - return null; - } + public PageResult getTodoTaskPage(Long userId, BpmTaskTodoPageReqVO pageVO) { + // 查询待办任务 + TaskQuery taskQuery = taskService.createTaskQuery() + .taskAssignee(String.valueOf(userId)); + if (StrUtil.isNotBlank(pageVO.getName())) { + taskQuery.taskName("%s" + pageVO.getName() + "%s"); + } + if (pageVO.getBeginCreateTime() != null) { + taskQuery.taskCreatedAfter(pageVO.getBeginCreateTime()); + } + if (pageVO.getEndCreateTime() != null) { + taskQuery.taskCreatedBefore(pageVO.getEndCreateTime()); + } + // 执行查询 + List tasks = taskQuery.orderByTaskCreateTime().desc() // 创建时间倒序 + .listPage(PageUtils.getStart(pageVO), pageVO.getPageSize()); + if (CollUtil.isEmpty(tasks)) { + return PageResult.empty(taskQuery.count()); + } + // 获得 ProcessInstance Map + Map processInstanceMap = processInstanceService.getProcessInstanceMap( + convertSet(tasks, Task::getProcessInstanceId)); + + // 获得 User Map + Map userMap = userService.getUserMap( + convertSet(processInstanceMap.values(), instance -> Long.valueOf(instance.getStartUserId()))); + // 拼接结果 + return new PageResult<>(BpmTaskConvert.INSTANCE.convertList(tasks, processInstanceMap, userMap), + taskQuery.count()); + } @Override - public void claimTask(String taskId) { - taskRuntime.claim(new ClaimTaskPayloadBuilder() - .withTaskId(taskId) - .withAssignee(SecurityFrameworkUtils.getLoginUser().getUsername()) - .build()); + public void updateTaskAssign(String id, Long userId) { + taskService.setAssignee(id, String.valueOf(userId)); } + @Override + public void claimTask(String id) { + } + + // 任务编号、流程名称、任务节点、流程发起人、接收时间、审批时间、耗时【名称、开始时间】「流程记录、撤回」 + // 任务编号、任务名称、所属流程、委托代办人、流程发起人、优先级、审批操作、审批意见、耗时、创建时间【名称、开始时间】「申请详情」 + + // 任务编号、任务名称、流程名称、流程发起人、接收时间、审批时间、耗时【名称、接收时间】「详情」TODO 撤回 @Override @Transactional @@ -126,7 +161,7 @@ public class BpmTaskServiceImpl implements BpmTaskService { // 获得对应的步骤 List steps = new ArrayList<>(); finished.forEach(instance -> { - TaskStepVO stepVO = TaskConvert.INSTANCE.convert(instance); + TaskStepVO stepVO = BpmTaskConvert.INSTANCE.convert(instance); stepVO.setStatus(1); // TODO @jason:1 这个 magic number 要枚举起来。 // TODO @jason:可以考虑把 comments 读取后,在统一调用 convert 拼接。另外 Comment 是废弃的类,有没其它可以使用的哈? List comments = taskService.getTaskComments(instance.getTaskId()); @@ -144,7 +179,7 @@ public class BpmTaskServiceImpl implements BpmTaskService { .unfinished().list(); // 获得对应的步骤 for (HistoricActivityInstance instance : unfinished) { - TaskStepVO stepVO = TaskConvert.INSTANCE.convert(instance); + TaskStepVO stepVO = BpmTaskConvert.INSTANCE.convert(instance); stepVO.setComment(""); stepVO.setStatus(0); steps.add(stepVO); @@ -158,13 +193,6 @@ public class BpmTaskServiceImpl implements BpmTaskService { return getTaskSteps(processInstanceId); } - @Override - public TodoTaskRespVO getTaskFormKey(TaskQueryReqVO taskQuery) { -// final Task task = taskRuntime.task(taskQuery.getTaskId()); -// return TaskConvert.INSTANCE.convert(task); - return null; - } - @Override public FileResp getHighlightImg(String processInstanceId) { // 查询历史 diff --git a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/system/service/user/impl/SysUserServiceImpl.java b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/system/service/user/impl/SysUserServiceImpl.java index 61bca4cfb..43156f1d5 100644 --- a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/system/service/user/impl/SysUserServiceImpl.java +++ b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/system/service/user/impl/SysUserServiceImpl.java @@ -176,6 +176,9 @@ public class SysUserServiceImpl implements SysUserService { @Override public List getUsers(Collection ids) { + if (CollUtil.isEmpty(ids)) { + return Collections.emptyList(); + } return userMapper.selectBatchIds(ids); } diff --git a/yudao-admin-ui/src/api/bpm/task.js b/yudao-admin-ui/src/api/bpm/task.js new file mode 100644 index 000000000..2c8f93e9b --- /dev/null +++ b/yudao-admin-ui/src/api/bpm/task.js @@ -0,0 +1,10 @@ +import request from '@/utils/request' + +export function getTodoTaskPage(query) { + return request({ + url: '/bpm/task/todo-page', + method: 'get', + params: query + }) +} + diff --git a/yudao-admin-ui/src/views/oa/todo/index.vue b/yudao-admin-ui/src/views/bpm/task/todo.vue similarity index 100% rename from yudao-admin-ui/src/views/oa/todo/index.vue rename to yudao-admin-ui/src/views/bpm/task/todo.vue diff --git a/yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/pojo/PageResult.java b/yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/pojo/PageResult.java index 7da1f86f4..dbdeb85ba 100644 --- a/yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/pojo/PageResult.java +++ b/yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/pojo/PageResult.java @@ -35,4 +35,8 @@ public final class PageResult implements Serializable { return new PageResult<>(0L); } + public static PageResult empty(Long total) { + return new PageResult<>(total); + } + }