浏览代码

实现 bpm 待办任务的后端接口

YunaiV 3 年之前
父节点
当前提交
b083795ad6
共有 19 个文件被更改,包括 312 次插入173 次删除
  1. 4 0
      yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/controller/task/BpmTaskController.http
  2. 16 24
      yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/controller/task/BpmTaskController.java
  3. 52 0
      yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/controller/task/vo/task/BpmTaskTodoPageItemRespVO.java
  4. 32 0
      yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/controller/task/vo/task/BpmTaskTodoPageReqVO.java
  5. 0 16
      yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/controller/task/vo/task/TodoTaskPageReqVO.java
  6. 0 37
      yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/controller/task/vo/task/TodoTaskRespVO.java
  7. 1 1
      yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/convert/task/BpmProcessInstanceConvert.java
  8. 62 0
      yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/convert/task/BpmTaskConvert.java
  9. 0 44
      yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/convert/task/TaskConvert.java
  10. 1 1
      yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/dal/dataobject/task/BpmProcessInstanceExtDO.java
  11. 1 1
      yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/dal/mysql/task/BpmProcessInstanceExtMapper.java
  12. 23 0
      yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/service/task/BpmProcessInstanceService.java
  13. 25 13
      yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/service/task/BpmTaskService.java
  14. 17 3
      yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/service/task/impl/BpmProcessInstanceServiceImpl.java
  15. 61 33
      yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/service/task/impl/BpmTaskServiceImpl.java
  16. 3 0
      yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/system/service/user/impl/SysUserServiceImpl.java
  17. 10 0
      yudao-admin-ui/src/api/bpm/task.js
  18. 0 0
      yudao-admin-ui/src/views/bpm/task/todo.vue
  19. 4 0
      yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/pojo/PageResult.java

+ 4 - 0
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}}

+ 16 - 24
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/controller/task/TaskController.java → 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<PageResult<TodoTaskRespVO>> getTodoTaskPage(@Valid TodoTaskPageReqVO pageVO) {
-        return success(bpmTaskService.getTodoTaskPage(pageVO));
-    }
+    // TODO 芋艿:权限、validation;
 
-    @GetMapping("/claim")
-    @ApiOperation("签收任务")
-    public CommonResult<Boolean> claimTask(@RequestParam("id") String taskId) {
-        bpmTaskService.claimTask(taskId);
-        return success(true);
+    @GetMapping("todo-page")
+    @ApiOperation("获取 TODO 待办任务分页")
+    public CommonResult<PageResult<BpmTaskTodoPageItemRespVO>> getTodoTaskPage(@Valid BpmTaskTodoPageReqVO pageVO) {
+        return success(taskService.getTodoTaskPage(getLoginUserId(), pageVO));
     }
 
     @PostMapping("/task-steps")
     public CommonResult<TaskHandleVO> getTaskSteps(@RequestBody TaskQueryReqVO taskQuery) {
-        return success(bpmTaskService.getTaskSteps(taskQuery));
-    }
-
-    @PostMapping("/formKey")
-    public CommonResult<TodoTaskRespVO> getTaskFormKey(@RequestBody TaskQueryReqVO taskQuery) {
-        return success(bpmTaskService.getTaskFormKey(taskQuery));
+        return success(taskService.getTaskSteps(taskQuery));
     }
 
     @PostMapping("/complete")
     public CommonResult<Boolean> complete(@RequestBody TaskReqVO taskReq) {
-        bpmTaskService.completeTask(taskReq);
+        taskService.completeTask(taskReq);
         return success(true);
     }
 
     @GetMapping("/process/history-steps")
     public CommonResult<List<TaskStepVO>> 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());
     }
 

+ 52 - 0
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;
+
+    }
+
+    // 任务编号、任务名称、任务节点、流程版本、流程发起人、接收时间【名称、开始时间】「处理」
+    // 任务编号、任务名称、所属流程、委托代办人、流程发起人、优先级、状态、创建时间【名称、开始时间】「申请详情、通过、驳回、转办、历史」
+
+    // 任务编号、任务名称、流程名称、流程发起人、接收时间、状态【名称、接收时间】【处理、委托】
+}

+ 32 - 0
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;
+
+}

+ 0 - 16
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/controller/task/vo/task/TodoTaskPageReqVO.java

@@ -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;
-}

+ 0 - 37
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/controller/task/vo/task/TodoTaskRespVO.java

@@ -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;
-
-}

+ 1 - 1
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"),

+ 62 - 0
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<BpmTaskTodoPageItemRespVO> convertList(List<Task> tasks, Map<String, ProcessInstance> processInstanceMap,
+                                                        Map<Long, SysUserDO> 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();
+    }
+
+}

+ 0 - 44
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/convert/task/TaskConvert.java

@@ -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);
-}

+ 1 - 1
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;
     /**
      * 流程实例的名字
      *

+ 1 - 1
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<BpmProcessInsta
 
     default PageResult<BpmProcessInstanceExtDO> selectPage(Long userId, BpmProcessInstanceMyPageReqVO reqVO) {
         return selectPage(reqVO, new QueryWrapperX<BpmProcessInstanceExtDO>()
-                .eqIfPresent("user_id", userId)
+                .eqIfPresent("start_user_id", userId)
                 .likeIfPresent("name", reqVO.getName())
                 .eqIfPresent("process_definition_id", reqVO.getProcessDefinitionId())
                 .eqIfPresent("category", reqVO.getCategory())

+ 23 - 0
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<BpmProcessInstancePageItemRespVO> getMyProcessInstancePage(Long userId,
                                                                           @Valid BpmProcessInstanceMyPageReqVO pageReqVO);
 
+    /**
+     * 获得流程实例列表
+     *
+     * @param ids 流程实例的编号集合
+     * @return 流程实例列表
+     */
+    List<ProcessInstance> getProcessInstances(Set<String> ids);
+
+    /**
+     * 获得流程实例 Map
+     *
+     * @param ids 流程实例的编号集合
+     * @return 流程实例列表 Map
+     */
+    default Map<String, ProcessInstance> getProcessInstanceMap(Set<String> ids) {
+        return CollectionUtils.convertMap(getProcessInstances(ids), ProcessInstance::getProcessInstanceId);
+    }
+
 }

+ 25 - 13
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<Task> getTasksByProcessInstanceId(String processInstanceId);
+
     /**
      * 获得流程任务列表
      *
@@ -38,15 +44,28 @@ public interface BpmTaskService {
     }
 
     /**
-     * 获取当前用户的待办任务, 分页
+     * 获得流程任务分页
+     *
+     * @param userId 用户编号
+     * @param pageReqVO 分页请求
+     * @return 流程任务分页
+     */
+    PageResult<BpmTaskTodoPageItemRespVO> getTodoTaskPage(Long userId, BpmTaskTodoPageReqVO pageReqVO);
+
+    /**
+     * 将流程任务分配给指定用户
+     *
+     * @param id 流程任务编号
+     * @param userId 用户编号
      */
-    PageResult<TodoTaskRespVO> getTodoTaskPage(TodoTaskPageReqVO pageReqVO);
+    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<TaskStepVO> getHistorySteps(String processInstanceId);
 
-    /**
-     * 获取用户任务的 formKey, 对应外置表单, 需要根据formKey 对应业务表单
-     * @param taskQuery 查询参数 ,一般taskId
-     */
-    TodoTaskRespVO getTaskFormKey(TaskQueryReqVO taskQuery);
-
-
     /**
      * 返回高亮的流转进程
      * @param processInstanceId 实例Id

+ 17 - 3
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<Task> 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<ProcessInstance> getProcessInstances(Set<String> ids) {
+        return runtimeService.createProcessInstanceQuery().processInstanceIds(ids).list();
+    }
+
     /**
      * 获得流程实例
      *

+ 61 - 33
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<Task> getTasksByProcessInstanceId(String processInstanceId) {
+        return taskService.createTaskQuery().processInstanceId(processInstanceId).list();
+    }
+
     @Override
     public List<Task> getTasksByProcessInstanceIds(List<String> processInstanceIds) {
         if (CollUtil.isEmpty(processInstanceIds)) {
@@ -67,30 +80,52 @@ public class BpmTaskServiceImpl implements BpmTaskService {
     }
 
     @Override
-    public PageResult<TodoTaskRespVO> getTodoTaskPage(TodoTaskPageReqVO pageReqVO) {
-        // TODO @jason:封装一个方法,用于转换成 activiti 的分页对象
-//        final Pageable pageable = Pageable.of((pageReqVO.getPageNo() - 1) * pageReqVO.getPageSize(), pageReqVO.getPageSize());
-//        Page<Task> pageTasks = taskRuntime.tasks(pageable);
-//        int totalItems = pageTasks.getTotalItems();
-//        List<Task> tasks = pageTasks.getContent();
-//        final List<TodoTaskRespVO> 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<BpmTaskTodoPageItemRespVO> 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<Task> tasks = taskQuery.orderByTaskCreateTime().desc() // 创建时间倒序
+                .listPage(PageUtils.getStart(pageVO), pageVO.getPageSize());
+        if (CollUtil.isEmpty(tasks)) {
+            return PageResult.empty(taskQuery.count());
+        }
+
+        // 获得 ProcessInstance Map
+        Map<String, ProcessInstance> processInstanceMap = processInstanceService.getProcessInstanceMap(
+                convertSet(tasks, Task::getProcessInstanceId));
+
+        // 获得 User Map
+        Map<Long, SysUserDO> 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 updateTaskAssign(String id, Long userId) {
+        taskService.setAssignee(id, String.valueOf(userId));
+    }
 
     @Override
-    public void claimTask(String taskId) {
-        taskRuntime.claim(new ClaimTaskPayloadBuilder()
-                                .withTaskId(taskId)
-                                .withAssignee(SecurityFrameworkUtils.getLoginUser().getUsername())
-                                .build());
+    public void claimTask(String id) {
+
     }
 
+    // 任务编号、流程名称、任务节点、流程发起人、接收时间、审批时间、耗时【名称、开始时间】「流程记录、撤回」
+    // 任务编号、任务名称、所属流程、委托代办人、流程发起人、优先级、审批操作、审批意见、耗时、创建时间【名称、开始时间】「申请详情」
 
+    // 任务编号、任务名称、流程名称、流程发起人、接收时间、审批时间、耗时【名称、接收时间】「详情」TODO 撤回
 
     @Override
     @Transactional
@@ -126,7 +161,7 @@ public class BpmTaskServiceImpl implements BpmTaskService {
         // 获得对应的步骤
         List<TaskStepVO> 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<Comment> 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) {
         // 查询历史

+ 3 - 0
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<SysUserDO> getUsers(Collection<Long> ids) {
+        if (CollUtil.isEmpty(ids)) {
+            return Collections.emptyList();
+        }
         return userMapper.selectBatchIds(ids);
     }
 

+ 10 - 0
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
+  })
+}
+

+ 0 - 0
yudao-admin-ui/src/views/oa/todo/index.vue → yudao-admin-ui/src/views/bpm/task/todo.vue


+ 4 - 0
yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/pojo/PageResult.java

@@ -35,4 +35,8 @@ public final class PageResult<T> implements Serializable {
         return new PageResult<>(0L);
     }
 
+    public static <T> PageResult<T> empty(Long total) {
+        return new PageResult<>(total);
+    }
+
 }