瀏覽代碼

工作流 Flowable 流程实例 相关实现

jason 3 年之前
父節點
當前提交
c761f5258a
共有 17 個文件被更改,包括 822 次插入0 次删除
  1. 0 0
      yudao-module-bpm/yudao-module-bpm-impl-activiti/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/BpmTaskAssignRuleController.http
  2. 0 0
      yudao-module-bpm/yudao-module-bpm-impl-activiti/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/BpmTaskAssignRuleController.java
  3. 0 0
      yudao-module-bpm/yudao-module-bpm-impl-activiti/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmTaskAssignRuleService.java
  4. 12 0
      yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/BpmProcessDefinitionController.java
  5. 59 0
      yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/BpmTaskAssignRuleController.java
  6. 53 0
      yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/BpmProcessInstanceController.java
  7. 39 0
      yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/BpmTaskController.java
  8. 21 0
      yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/convert/definition/BpmProcessDefinitionConvert.java
  9. 76 0
      yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/convert/task/BpmProcessInstanceConvert.java
  10. 68 0
      yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/convert/task/BpmTaskConvert.java
  11. 10 0
      yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmProcessDefinitionService.java
  12. 25 0
      yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmProcessDefinitionServiceImpl.java
  13. 87 0
      yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmTaskAssignRuleService.java
  14. 76 0
      yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmProcessInstanceService.java
  15. 167 0
      yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmProcessInstanceServiceImpl.java
  16. 47 0
      yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmTaskService.java
  17. 82 0
      yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmTaskServiceImpl.java

+ 0 - 0
yudao-module-bpm/yudao-module-bpm-base/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/BpmTaskAssignRuleController.http → yudao-module-bpm/yudao-module-bpm-impl-activiti/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/BpmTaskAssignRuleController.http


+ 0 - 0
yudao-module-bpm/yudao-module-bpm-base/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/BpmTaskAssignRuleController.java → yudao-module-bpm/yudao-module-bpm-impl-activiti/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/BpmTaskAssignRuleController.java


+ 0 - 0
yudao-module-bpm/yudao-module-bpm-base/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmTaskAssignRuleService.java → yudao-module-bpm/yudao-module-bpm-impl-activiti/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmTaskAssignRuleService.java


+ 12 - 0
yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/BpmProcessDefinitionController.java

@@ -2,8 +2,10 @@ package cn.iocoder.yudao.module.bpm.controller.admin.definition;
 
 import cn.iocoder.yudao.framework.common.pojo.CommonResult;
 import cn.iocoder.yudao.framework.common.pojo.PageResult;
+import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.process.BpmProcessDefinitionListReqVO;
 import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.process.BpmProcessDefinitionPageItemRespVO;
 import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.process.BpmProcessDefinitionPageReqVO;
+import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.process.BpmProcessDefinitionRespVO;
 import cn.iocoder.yudao.module.bpm.service.definition.BpmProcessDefinitionService;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiImplicitParam;
@@ -17,6 +19,8 @@ import org.springframework.web.bind.annotation.RestController;
 
 import javax.annotation.Resource;
 
+import java.util.List;
+
 import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
 
 @Api(tags = "管理后台 - 流程定义")
@@ -36,6 +40,14 @@ public class BpmProcessDefinitionController {
         return success(bpmDefinitionService.getProcessDefinitionPage(pageReqVO));
     }
 
+    @GetMapping ("/list")
+    @ApiOperation(value = "获得流程定义列表")
+    @PreAuthorize("@ss.hasPermission('bpm:process-definition:query')")
+    public CommonResult<List<BpmProcessDefinitionRespVO>> getProcessDefinitionList(
+            BpmProcessDefinitionListReqVO listReqVO) {
+        return success(bpmDefinitionService.getProcessDefinitionList(listReqVO));
+    }
+
     @GetMapping ("/get-bpmn-xml")
     @ApiOperation(value = "获得流程定义的 BPMN XML")
     @ApiImplicitParam(name = "id", value = "编号", required = true, example = "1024", dataTypeClass = String.class)

+ 59 - 0
yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/BpmTaskAssignRuleController.java

@@ -0,0 +1,59 @@
+package cn.iocoder.yudao.module.bpm.controller.admin.definition;
+
+import cn.iocoder.yudao.framework.common.pojo.CommonResult;
+import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.rule.BpmTaskAssignRuleCreateReqVO;
+import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.rule.BpmTaskAssignRuleRespVO;
+import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.rule.BpmTaskAssignRuleUpdateReqVO;
+import cn.iocoder.yudao.module.bpm.service.definition.BpmTaskAssignRuleService;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiImplicitParam;
+import io.swagger.annotations.ApiImplicitParams;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.*;
+
+import javax.annotation.Resource;
+import javax.validation.Valid;
+import java.util.List;
+
+import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
+
+@Api(tags = "管理后台 - 任务分配规则")
+@RestController
+@RequestMapping("/bpm/task-assign-rule")
+@Validated
+public class BpmTaskAssignRuleController {
+
+    @Resource
+    private BpmTaskAssignRuleService taskAssignRuleService;
+
+    @GetMapping("/list")
+    @ApiOperation(value = "获得任务分配规则列表")
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "modelId", value = "模型编号", example = "1024", dataTypeClass = String.class),
+            @ApiImplicitParam(name = "processDefinitionId", value = "流程定义的编号", example = "2048", dataTypeClass = String.class)
+    })
+    @PreAuthorize("@ss.hasPermission('bpm:task-assign-rule:query')")
+    public CommonResult<List<BpmTaskAssignRuleRespVO>> getTaskAssignRuleList(
+            @RequestParam(value = "modelId", required = false) String modelId,
+            @RequestParam(value = "processDefinitionId", required = false) String processDefinitionId) {
+        return success(taskAssignRuleService.getTaskAssignRuleList(modelId, processDefinitionId));
+    }
+
+    @PostMapping("/create")
+    @ApiOperation(value = "创建任务分配规则")
+    @PreAuthorize("@ss.hasPermission('bpm:task-assign-rule:create')")
+    public CommonResult<Long> createTaskAssignRule(@Valid @RequestBody BpmTaskAssignRuleCreateReqVO reqVO) {
+        return success(taskAssignRuleService.createTaskAssignRule(reqVO));
+    }
+
+    @PutMapping("/update")
+    @ApiOperation(value = "更新任务分配规则")
+    @PreAuthorize("@ss.hasPermission('bpm:task-assign-rule:update')")
+    public CommonResult<Boolean> updateTaskAssignRule(@Valid @RequestBody BpmTaskAssignRuleUpdateReqVO reqVO) {
+        taskAssignRuleService.updateTaskAssignRule(reqVO);
+        return success(true);
+    }
+
+}

+ 53 - 0
yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/BpmProcessInstanceController.java

@@ -0,0 +1,53 @@
+package cn.iocoder.yudao.module.bpm.controller.admin.task;
+
+import cn.iocoder.yudao.framework.common.pojo.CommonResult;
+import cn.iocoder.yudao.framework.common.pojo.PageResult;
+import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance.BpmProcessInstanceCreateReqVO;
+import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance.BpmProcessInstanceMyPageReqVO;
+import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance.BpmProcessInstancePageItemRespVO;
+import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance.BpmProcessInstanceRespVO;
+import cn.iocoder.yudao.module.bpm.service.task.BpmProcessInstanceService;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiImplicitParam;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.*;
+
+import javax.annotation.Resource;
+import javax.validation.Valid;
+
+import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
+import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;
+
+@Api(tags = "管理后台 - 流程实例") // 流程实例,通过流程定义创建的一次“申请”
+@RestController
+@RequestMapping("/bpm/process-instance")
+@Validated
+public class BpmProcessInstanceController {
+    @Resource
+    private BpmProcessInstanceService processInstanceService;
+
+    @GetMapping("/my-page")
+    @ApiOperation(value = "获得我的实例分页列表", notes = "在【我的流程】菜单中,进行调用")
+    @PreAuthorize("@ss.hasPermission('bpm:process-instance:query')")
+    public CommonResult<PageResult<BpmProcessInstancePageItemRespVO>> getMyProcessInstancePage(
+            @Valid BpmProcessInstanceMyPageReqVO pageReqVO) {
+        return success(processInstanceService.getMyProcessInstancePage(getLoginUserId(), pageReqVO));
+    }
+
+    @PostMapping("/create")
+    @ApiOperation("新建流程实例")
+    @PreAuthorize("@ss.hasPermission('bpm:process-instance:query')")
+    public CommonResult<String> createProcessInstance(@Valid @RequestBody BpmProcessInstanceCreateReqVO createReqVO) {
+        return success(processInstanceService.createProcessInstance(getLoginUserId(), createReqVO));
+    }
+
+    @GetMapping("/get")
+    @ApiOperation(value = "获得指定流程实例", notes = "在【流程详细】界面中,进行调用")
+    @ApiImplicitParam(name = "id", value = "流程实例的编号", required = true, dataTypeClass = String.class)
+    @PreAuthorize("@ss.hasPermission('bpm:process-instance:query')")
+    public CommonResult<BpmProcessInstanceRespVO> getProcessInstance(@RequestParam("id") String id) {
+        return success(processInstanceService.getProcessInstanceVO(id));
+    }
+}

+ 39 - 0
yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/BpmTaskController.java

@@ -0,0 +1,39 @@
+package cn.iocoder.yudao.module.bpm.controller.admin.task;
+
+import cn.iocoder.yudao.framework.common.pojo.CommonResult;
+import cn.iocoder.yudao.framework.common.pojo.PageResult;
+import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.task.BpmTaskTodoPageItemRespVO;
+import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.task.BpmTaskTodoPageReqVO;
+import cn.iocoder.yudao.module.bpm.service.task.BpmTaskService;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.flowable.bpmn.model.BpmnModel;
+import org.flowable.engine.TaskService;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.annotation.Resource;
+import javax.validation.Valid;
+
+import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
+import static cn.iocoder.yudao.framework.web.core.util.WebFrameworkUtils.getLoginUserId;
+
+@Api(tags = "管理后台 - 流程任务实例")
+@RestController
+@RequestMapping("/bpm/task")
+@Validated
+public class BpmTaskController {
+
+    @Resource
+    private BpmTaskService taskService;
+
+    @GetMapping("todo-page")
+    @ApiOperation("获取 Todo 待办任务分页")
+    @PreAuthorize("@ss.hasPermission('bpm:task:query')")
+    public CommonResult<PageResult<BpmTaskTodoPageItemRespVO>> getTodoTaskPage(@Valid BpmTaskTodoPageReqVO pageVO) {
+        return success(taskService.getTodoTaskPage(getLoginUserId(), pageVO));
+    }
+}

+ 21 - 0
yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/convert/definition/BpmProcessDefinitionConvert.java

@@ -12,6 +12,7 @@ import org.flowable.engine.repository.ProcessDefinition;
 import org.mapstruct.Mapper;
 import org.mapstruct.Mapping;
 import org.mapstruct.MappingTarget;
+import org.mapstruct.Named;
 import org.mapstruct.factory.Mappers;
 
 import java.util.List;
@@ -41,6 +42,26 @@ public interface BpmProcessDefinitionConvert {
         });
     }
 
+    default List<BpmProcessDefinitionRespVO> convertList3(List<ProcessDefinition> list,
+                                                          Map<String, BpmProcessDefinitionExtDO> processDefinitionDOMap) {
+        return CollectionUtils.convertList(list, processDefinition -> {
+            BpmProcessDefinitionRespVO respVO = convert3(processDefinition);
+            BpmProcessDefinitionExtDO processDefinitionExtDO = processDefinitionDOMap.get(processDefinition.getId());
+            // 复制通用属性
+            copyTo(processDefinitionExtDO, respVO);
+            return respVO;
+        });
+    }
+
+    @Mapping(source = "suspended", target = "suspensionState", qualifiedByName = "convertSuspendedToSuspensionState")
+    BpmProcessDefinitionRespVO convert3(ProcessDefinition bean);
+
+    @Named("convertSuspendedToSuspensionState")
+    default Integer convertSuspendedToSuspensionState(boolean suspended) {
+        return suspended ? SuspensionState.SUSPENDED.getStateCode() :
+                SuspensionState.ACTIVE.getStateCode();
+    }
+
     default BpmProcessDefinitionPageItemRespVO convert(ProcessDefinition bean, Deployment deployment,
                                                        BpmProcessDefinitionExtDO processDefinitionExtDO, BpmFormDO form) {
         BpmProcessDefinitionPageItemRespVO respVO = convert(bean);

+ 76 - 0
yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/convert/task/BpmProcessInstanceConvert.java

@@ -0,0 +1,76 @@
+package cn.iocoder.yudao.module.bpm.convert.task;
+
+import cn.iocoder.yudao.framework.common.pojo.PageResult;
+import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance.BpmProcessInstancePageItemRespVO;
+import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance.BpmProcessInstanceRespVO;
+import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmProcessDefinitionExtDO;
+import cn.iocoder.yudao.module.bpm.dal.dataobject.task.BpmProcessInstanceExtDO;
+import cn.iocoder.yudao.module.system.api.dept.dto.DeptRespDTO;
+import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
+import org.flowable.engine.history.HistoricProcessInstance;
+import org.flowable.engine.repository.ProcessDefinition;
+import org.flowable.task.api.Task;
+import org.mapstruct.Mapper;
+import org.mapstruct.Mapping;
+import org.mapstruct.MappingTarget;
+import org.mapstruct.factory.Mappers;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * 流程实例 Convert
+ *
+ * @author 芋道源码
+ */
+@Mapper
+public interface BpmProcessInstanceConvert {
+
+    BpmProcessInstanceConvert INSTANCE = Mappers.getMapper(BpmProcessInstanceConvert.class);
+
+    default PageResult<BpmProcessInstancePageItemRespVO> convertPage(PageResult<BpmProcessInstanceExtDO> page,
+                                                                     Map<String, List<Task>> taskMap) {
+        List<BpmProcessInstancePageItemRespVO> list = convertList(page.getList());
+        list.forEach(respVO -> respVO.setTasks(convertList2(taskMap.get(respVO.getId()))));
+        return new PageResult<>(list, page.getTotal());
+    }
+
+    List<BpmProcessInstancePageItemRespVO> convertList(List<BpmProcessInstanceExtDO> list);
+
+    List<BpmProcessInstancePageItemRespVO.Task> convertList2(List<Task> tasks);
+
+    default BpmProcessInstanceRespVO convert2(HistoricProcessInstance processInstance, BpmProcessInstanceExtDO processInstanceExt,
+                                              ProcessDefinition processDefinition, BpmProcessDefinitionExtDO processDefinitionExt,
+                                              String bpmnXml, AdminUserRespDTO startUser, DeptRespDTO dept) {
+        BpmProcessInstanceRespVO respVO = convert2(processInstance);
+        copyTo(processInstanceExt, respVO);
+        // definition
+        respVO.setProcessDefinition(convert2(processDefinition));
+        copyTo(processDefinitionExt, respVO.getProcessDefinition());
+        respVO.getProcessDefinition().setBpmnXml(bpmnXml);
+        // user
+        if (startUser != null) {
+            respVO.setStartUser(convert2(startUser));
+            if (dept != null) {
+                respVO.getStartUser().setDeptName(dept.getName());
+            }
+        }
+        return respVO;
+    }
+
+    BpmProcessInstanceRespVO convert2(HistoricProcessInstance bean);
+
+    @Mapping(source = "from.id", target = "to.id", ignore = true)
+    void copyTo(BpmProcessInstanceExtDO from, @MappingTarget BpmProcessInstanceRespVO to);
+
+    BpmProcessInstanceRespVO.ProcessDefinition convert2(ProcessDefinition bean);
+
+    @Mapping(source = "from.id", target = "to.id", ignore = true)
+    void copyTo(BpmProcessDefinitionExtDO from, @MappingTarget BpmProcessInstanceRespVO.ProcessDefinition to);
+
+    BpmProcessInstanceRespVO.User convert2(AdminUserRespDTO bean);
+
+
+
+
+}

+ 68 - 0
yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/convert/task/BpmTaskConvert.java

@@ -0,0 +1,68 @@
+package cn.iocoder.yudao.module.bpm.convert.task;
+
+import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
+import cn.iocoder.yudao.framework.common.util.number.NumberUtils;
+import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.task.BpmTaskDonePageItemRespVO;
+import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.task.BpmTaskRespVO;
+import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.task.BpmTaskTodoPageItemRespVO;
+import cn.iocoder.yudao.module.bpm.dal.dataobject.task.BpmTaskExtDO;
+import cn.iocoder.yudao.module.bpm.service.message.dto.BpmMessageSendWhenTaskCreatedReqDTO;
+import cn.iocoder.yudao.module.system.api.dept.dto.DeptRespDTO;
+import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
+
+import org.flowable.common.engine.impl.db.SuspensionState;
+import org.flowable.engine.history.HistoricProcessInstance;
+import org.flowable.engine.runtime.ProcessInstance;
+import org.flowable.task.api.Task;
+import org.flowable.task.api.history.HistoricTaskInstance;
+import org.mapstruct.*;
+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);
+
+    default List<BpmTaskTodoPageItemRespVO> convertList1(List<Task> tasks, Map<String, ProcessInstance> processInstanceMap,
+                                                         Map<Long, AdminUserRespDTO> userMap) {
+        return CollectionUtils.convertList(tasks, task -> {
+            BpmTaskTodoPageItemRespVO respVO = convert1(task);
+            ProcessInstance processInstance = processInstanceMap.get(task.getProcessInstanceId());
+            if (processInstance != null) {
+                AdminUserRespDTO startUser = userMap.get(NumberUtils.parseLong(processInstance.getStartUserId()));
+                respVO.setProcessInstance(convert(processInstance, startUser));
+            }
+            return respVO;
+        });
+    }
+
+    @Mapping(source = "suspended", target = "suspensionState", qualifiedByName = "convertSuspendedToSuspensionState")
+    BpmTaskTodoPageItemRespVO convert1(Task bean);
+
+    @Named("convertSuspendedToSuspensionState")
+    default Integer convertSuspendedToSuspensionState(boolean suspended) {
+        return suspended ? SuspensionState.SUSPENDED.getStateCode() :
+                SuspensionState.ACTIVE.getStateCode();
+    }
+
+    @Mappings({
+            @Mapping(source = "processInstance.id", target = "id"),
+            @Mapping(source = "processInstance.name", target = "name"),
+            @Mapping(source = "processInstance.startUserId", target = "startUserId"),
+            @Mapping(source = "processInstance.processDefinitionId", target = "processDefinitionId"),
+            @Mapping(source = "startUser.nickname", target = "startUserNickname")
+    })
+    BpmTaskTodoPageItemRespVO.ProcessInstance convert(ProcessInstance processInstance, AdminUserRespDTO startUser);
+
+
+}
+
+

+ 10 - 0
yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmProcessDefinitionService.java

@@ -2,8 +2,10 @@ package cn.iocoder.yudao.module.bpm.service.definition;
 
 import cn.iocoder.yudao.framework.common.pojo.PageResult;
 import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
+import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.process.BpmProcessDefinitionListReqVO;
 import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.process.BpmProcessDefinitionPageItemRespVO;
 import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.process.BpmProcessDefinitionPageReqVO;
+import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.process.BpmProcessDefinitionRespVO;
 import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmProcessDefinitionExtDO;
 import cn.iocoder.yudao.module.bpm.service.definition.dto.BpmProcessDefinitionCreateReqDTO;
 import org.flowable.bpmn.model.BpmnModel;
@@ -31,6 +33,14 @@ public interface BpmProcessDefinitionService {
      */
     PageResult<BpmProcessDefinitionPageItemRespVO> getProcessDefinitionPage(BpmProcessDefinitionPageReqVO pageReqVO);
 
+    /**
+     * 获得流程定义列表
+     *
+     * @param listReqVO 列表入参
+     * @return 流程定义列表
+     */
+    List<BpmProcessDefinitionRespVO> getProcessDefinitionList(BpmProcessDefinitionListReqVO listReqVO);
+
     /**
      * 创建流程定义
      *

+ 25 - 0
yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmProcessDefinitionServiceImpl.java

@@ -5,8 +5,10 @@ import cn.hutool.core.util.ObjectUtil;
 import cn.hutool.core.util.StrUtil;
 import cn.iocoder.yudao.framework.common.pojo.PageResult;
 import cn.iocoder.yudao.framework.common.util.object.PageUtils;
+import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.process.BpmProcessDefinitionListReqVO;
 import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.process.BpmProcessDefinitionPageItemRespVO;
 import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.process.BpmProcessDefinitionPageReqVO;
+import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.process.BpmProcessDefinitionRespVO;
 import cn.iocoder.yudao.module.bpm.convert.definition.BpmProcessDefinitionConvert;
 import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmFormDO;
 import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmProcessDefinitionExtDO;
@@ -228,6 +230,27 @@ public class BpmProcessDefinitionServiceImpl implements BpmProcessDefinitionServ
         return processDefinitionMapper.selectByProcessDefinitionId(id);
     }
 
+    @Override
+    public List<BpmProcessDefinitionRespVO> getProcessDefinitionList(BpmProcessDefinitionListReqVO listReqVO) {
+        // 拼接查询条件
+        ProcessDefinitionQuery definitionQuery = repositoryService.createProcessDefinitionQuery();
+        if (Objects.equals(SuspensionState.SUSPENDED.getStateCode(), listReqVO.getSuspensionState())) {
+            definitionQuery.suspended();
+        } else if (Objects.equals(SuspensionState.ACTIVE.getStateCode(), listReqVO.getSuspensionState())) {
+            definitionQuery.active();
+        }
+        // 执行查询
+        List<ProcessDefinition> processDefinitions = definitionQuery.list();
+
+        // 获得 BpmProcessDefinitionDO Map
+        List<BpmProcessDefinitionExtDO> processDefinitionDOs = processDefinitionMapper.selectListByProcessDefinitionIds(
+                convertList(processDefinitions, ProcessDefinition::getId));
+        Map<String, BpmProcessDefinitionExtDO> processDefinitionDOMap = convertMap(processDefinitionDOs,
+                BpmProcessDefinitionExtDO::getProcessDefinitionId);
+        // 执行查询,并返回
+        return BpmProcessDefinitionConvert.INSTANCE.convertList3(processDefinitions, processDefinitionDOMap);
+    }
+
     @Override
     public PageResult<BpmProcessDefinitionPageItemRespVO> getProcessDefinitionPage(BpmProcessDefinitionPageReqVO pageVO) {
         ProcessDefinitionQuery definitionQuery = repositoryService.createProcessDefinitionQuery();
@@ -262,4 +285,6 @@ public class BpmProcessDefinitionServiceImpl implements BpmProcessDefinitionServ
         return new PageResult<>(BpmProcessDefinitionConvert.INSTANCE.convertList(processDefinitions, deploymentMap,
                 processDefinitionDOMap, formMap), definitionCount);
     }
+
+
 }

+ 87 - 0
yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmTaskAssignRuleService.java

@@ -0,0 +1,87 @@
+package cn.iocoder.yudao.module.bpm.service.definition;
+
+import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.rule.BpmTaskAssignRuleCreateReqVO;
+import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.rule.BpmTaskAssignRuleRespVO;
+import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.rule.BpmTaskAssignRuleUpdateReqVO;
+import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmTaskAssignRuleDO;
+import org.springframework.lang.Nullable;
+
+import javax.validation.Valid;
+import java.util.List;
+
+/**
+ * BPM 任务分配规则 Service 接口
+ *
+ * @author 芋道源码
+ */
+public interface BpmTaskAssignRuleService {
+
+    /**
+     * 获得流程定义的任务分配规则数组
+     *
+     * @param processDefinitionId 流程定义的编号
+     * @param taskDefinitionKey 流程任务定义的 Key。允许空
+     * @return 任务规则数组
+     */
+    List<BpmTaskAssignRuleDO> getTaskAssignRuleListByProcessDefinitionId(String processDefinitionId,
+                                                                         @Nullable String taskDefinitionKey);
+
+    /**
+     * 获得流程模型的任务规则数组
+     *
+     * @param modelId 流程模型的编号
+     * @return 任务规则数组
+     */
+    List<BpmTaskAssignRuleDO> getTaskAssignRuleListByModelId(String modelId);
+
+    /**
+     * 获得流程定义的任务分配规则数组
+     *
+     * @param modelId 流程模型的编号
+     * @param processDefinitionId 流程定义的编号
+     * @return 任务规则数组
+     */
+    List<BpmTaskAssignRuleRespVO> getTaskAssignRuleList(String modelId, String processDefinitionId);
+
+    /**
+     * 创建任务分配规则
+     *
+     * @param reqVO 创建信息
+     * @return 规则编号
+     */
+    Long createTaskAssignRule(@Valid BpmTaskAssignRuleCreateReqVO reqVO);
+
+    /**
+     * 更新任务分配规则
+     *
+     * @param reqVO 创建信息
+     */
+    void updateTaskAssignRule(@Valid BpmTaskAssignRuleUpdateReqVO reqVO);
+
+    /**
+     * 判断指定流程模型和流程定义的分配规则是否相等
+     *
+     * @param modelId 流程模型编号
+     * @param processDefinitionId 流程定义编号
+     * @return 是否相等
+     */
+    boolean isTaskAssignRulesEquals(String modelId, String processDefinitionId);
+
+    /**
+     * 将流程流程模型的任务分配规则,复制一份给流程定义
+     * 目的:每次流程模型部署时,都会生成一个新的流程定义,此时考虑到每次部署的流程不可变性,所以需要复制一份给该流程定义
+     *
+     * @param fromModelId 流程模型编号
+     * @param toProcessDefinitionId 流程定义编号
+     */
+    void copyTaskAssignRules(String fromModelId, String toProcessDefinitionId);
+
+    /**
+     * 校验流程模型的任务分配规则全部都配置了
+     * 目的:如果有规则未配置,会导致流程任务找不到负责人,进而流程无法进行下去!
+     *
+     * @param id 流程模型编号
+     */
+    void checkTaskAssignRuleAllConfig(String id);
+
+}

+ 76 - 0
yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmProcessInstanceService.java

@@ -0,0 +1,76 @@
+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.controller.admin.task.vo.instance.BpmProcessInstanceCreateReqVO;
+import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance.BpmProcessInstanceMyPageReqVO;
+import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance.BpmProcessInstancePageItemRespVO;
+import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance.BpmProcessInstanceRespVO;
+import org.flowable.engine.history.HistoricProcessInstance;
+import org.flowable.engine.runtime.ProcessInstance;
+
+import javax.validation.Valid;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * 流程实例 Service 接口
+ *
+ * @author 芋道源码
+ */
+public interface BpmProcessInstanceService {
+
+    /**
+     * 获得流程实例列表
+     *
+     * @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);
+    }
+
+    /**
+     * 获得流程实例的分页
+     *
+     * @param userId 用户编号
+     * @param pageReqVO 分页请求
+     * @return 流程实例的分页
+     */
+    PageResult<BpmProcessInstancePageItemRespVO> getMyProcessInstancePage(Long userId,
+                                                                          @Valid BpmProcessInstanceMyPageReqVO pageReqVO);
+
+    /**
+     * 创建流程实例(提供给前端)
+     *
+     * @param userId 用户编号
+     * @param createReqVO 创建信息
+     * @return 实例的编号
+     */
+    String createProcessInstance(Long userId, @Valid BpmProcessInstanceCreateReqVO createReqVO);
+
+    /**
+     * 获得流程实例 VO 信息
+     *
+     * @param id 流程实例的编号
+     * @return 流程实例
+     */
+    BpmProcessInstanceRespVO getProcessInstanceVO(String id);
+
+    /**
+     * 获得历史的流程实例
+     *
+     * @param id 流程实例的编号
+     * @return 历史的流程实例
+     */
+    HistoricProcessInstance getHistoricProcessInstance(String id);
+}

+ 167 - 0
yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmProcessInstanceServiceImpl.java

@@ -0,0 +1,167 @@
+package cn.iocoder.yudao.module.bpm.service.task;
+
+import cn.hutool.core.collection.CollUtil;
+import cn.hutool.core.lang.Assert;
+import cn.iocoder.yudao.framework.common.pojo.PageResult;
+import cn.iocoder.yudao.framework.common.util.number.NumberUtils;
+import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance.BpmProcessInstanceCreateReqVO;
+import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance.BpmProcessInstanceMyPageReqVO;
+import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance.BpmProcessInstancePageItemRespVO;
+import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance.BpmProcessInstanceRespVO;
+import cn.iocoder.yudao.module.bpm.convert.task.BpmProcessInstanceConvert;
+import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmProcessDefinitionExtDO;
+import cn.iocoder.yudao.module.bpm.dal.dataobject.task.BpmProcessInstanceExtDO;
+import cn.iocoder.yudao.module.bpm.dal.mysql.task.BpmProcessInstanceExtMapper;
+import cn.iocoder.yudao.module.bpm.service.definition.BpmProcessDefinitionService;
+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;
+import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
+import lombok.extern.slf4j.Slf4j;
+import org.flowable.engine.HistoryService;
+import org.flowable.engine.RuntimeService;
+import org.flowable.engine.history.HistoricProcessInstance;
+import org.flowable.engine.repository.ProcessDefinition;
+import org.flowable.engine.runtime.ProcessInstance;
+import org.flowable.task.api.Task;
+import org.springframework.context.annotation.Lazy;
+import org.springframework.stereotype.Service;
+import org.springframework.validation.annotation.Validated;
+
+import javax.annotation.Resource;
+import javax.validation.Valid;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
+import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList;
+import static cn.iocoder.yudao.module.bpm.enums.ErrorCodeConstants.PROCESS_DEFINITION_IS_SUSPENDED;
+import static cn.iocoder.yudao.module.bpm.enums.ErrorCodeConstants.PROCESS_DEFINITION_NOT_EXISTS;
+
+/**
+ * 流程实例 Service 实现类
+ *
+ * ProcessDefinition & ProcessInstance & Execution & Task 的关系:
+ *     1. https://blog.csdn.net/bobozai86/article/details/105210414
+ *
+ * HistoricProcessInstance & ProcessInstance 的关系:
+ *     1.https://my.oschina.net/843294669/blog/719024
+ * 简单来说,前者 = 历史 + 运行中的流程实例,后者仅是运行中的流程实例
+ *
+ * @author 芋道源码
+ */
+@Service
+@Validated
+@Slf4j
+public class BpmProcessInstanceServiceImpl implements BpmProcessInstanceService {
+
+    @Resource
+    private RuntimeService runtimeService;
+    @Resource
+    private BpmProcessInstanceExtMapper processInstanceExtMapper;
+    @Resource
+    @Lazy // 解决循环依赖
+    private BpmTaskService taskService;
+    @Resource
+    private BpmProcessDefinitionService processDefinitionService;
+    @Resource
+    private HistoryService historyService;
+    @Resource
+    private AdminUserApi adminUserApi;
+    @Resource
+    private DeptApi deptApi;
+    @Override
+    public List<ProcessInstance> getProcessInstances(Set<String> ids) {
+        return runtimeService.createProcessInstanceQuery().processDefinitionIds(ids).list();
+    }
+
+    @Override
+    public PageResult<BpmProcessInstancePageItemRespVO> getMyProcessInstancePage(Long userId,
+                                                                                 BpmProcessInstanceMyPageReqVO pageReqVO) {
+        // 通过 BpmProcessInstanceExtDO 表,先查询到对应的分页
+        PageResult<BpmProcessInstanceExtDO> pageResult = processInstanceExtMapper.selectPage(userId, pageReqVO);
+        if (CollUtil.isEmpty(pageResult.getList())) {
+            return new PageResult<>(pageResult.getTotal());
+        }
+
+        // 获得流程 Task Map
+        List<String> processInstanceIds = convertList(pageResult.getList(), BpmProcessInstanceExtDO::getProcessInstanceId);
+        Map<String, List<Task>> taskMap = taskService.getTaskMapByProcessInstanceIds(processInstanceIds);
+        // 转换返回
+        return BpmProcessInstanceConvert.INSTANCE.convertPage(pageResult, taskMap);
+    }
+
+    @Override
+    public String createProcessInstance(Long userId, @Valid BpmProcessInstanceCreateReqVO createReqVO) {
+        // 获得流程定义
+        ProcessDefinition definition = processDefinitionService.getProcessDefinition(createReqVO.getProcessDefinitionId());
+        // 发起流程
+        return createProcessInstance0(userId, definition, createReqVO.getVariables(), null);
+    }
+
+    @Override
+    public BpmProcessInstanceRespVO getProcessInstanceVO(String id) {
+        // 获得流程实例
+        HistoricProcessInstance processInstance = getHistoricProcessInstance(id);
+        if (processInstance == null) {
+            return null;
+        }
+        BpmProcessInstanceExtDO processInstanceExt = processInstanceExtMapper.selectByProcessInstanceId(id);
+        Assert.notNull(processInstanceExt, "流程实例拓展({}) 不存在", id);
+
+        // 获得流程定义
+        ProcessDefinition processDefinition = processDefinitionService
+                                                    .getProcessDefinition(processInstance.getProcessDefinitionId());
+        Assert.notNull(processDefinition, "流程定义({}) 不存在", processInstance.getProcessDefinitionId());
+        BpmProcessDefinitionExtDO processDefinitionExt = processDefinitionService.getProcessDefinitionExt(
+                processInstance.getProcessDefinitionId());
+        Assert.notNull(processDefinitionExt, "流程定义拓展({}) 不存在", id);
+        String bpmnXml = processDefinitionService.getProcessDefinitionBpmnXML(processInstance.getProcessDefinitionId());
+
+        // 获得 User
+        AdminUserRespDTO startUser = adminUserApi.getUser(NumberUtils.parseLong(processInstance.getStartUserId()));
+        DeptRespDTO dept = null;
+        if (startUser != null) {
+            dept = deptApi.getDept(startUser.getDeptId());
+        }
+
+        // 拼接结果
+        return BpmProcessInstanceConvert.INSTANCE.convert2(processInstance, processInstanceExt,
+                processDefinition, processDefinitionExt, bpmnXml, startUser, dept);
+    }
+
+    /**
+     * 获得历史的流程实例
+     *
+     * @param id 流程实例的编号
+     * @return 历史的流程实例
+     */
+    @Override
+    public HistoricProcessInstance getHistoricProcessInstance(String id) {
+        return historyService.createHistoricProcessInstanceQuery().processInstanceId(id).singleResult();
+    }
+
+    private String createProcessInstance0(Long userId, ProcessDefinition definition,
+                                          Map<String, Object> variables, String businessKey) {
+        // 校验流程定义
+        if (definition == null) {
+            throw exception(PROCESS_DEFINITION_NOT_EXISTS);
+        }
+        if (definition.isSuspended()) {
+            throw exception(PROCESS_DEFINITION_IS_SUSPENDED);
+        }
+
+        // 创建流程实例
+        ProcessInstance instance = runtimeService.startProcessInstanceById(definition.getId(), businessKey, variables);
+        // 设置流程名字
+        runtimeService.setProcessInstanceName(instance.getId(), definition.getName());
+
+        // 补全流程实例的拓展表
+        processInstanceExtMapper.updateByProcessInstanceId(new BpmProcessInstanceExtDO().setProcessInstanceId(instance.getId())
+                .setFormVariables(variables));
+
+
+        return instance.getId();
+    }
+}

+ 47 - 0
yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmTaskService.java

@@ -0,0 +1,47 @@
+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.controller.admin.task.vo.task.BpmTaskTodoPageItemRespVO;
+import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.task.BpmTaskTodoPageReqVO;
+import org.flowable.task.api.Task;
+
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * 流程任务实例 Service 接口
+ *
+ * @author jason
+ * @author 芋道源码
+ */
+public interface BpmTaskService {
+    /**
+     * 获得待办的流程任务分页
+     *
+     * @param userId 用户编号
+     * @param pageReqVO 分页请求
+     * @return 流程任务分页
+     */
+    PageResult<BpmTaskTodoPageItemRespVO> getTodoTaskPage(Long userId, BpmTaskTodoPageReqVO pageReqVO);
+
+    /**
+     * 获得流程任务 Map
+     *
+     * @param processInstanceIds 流程实例的编号数组
+     * @return 流程任务 Map
+     */
+    default Map<String, List<Task>> getTaskMapByProcessInstanceIds(List<String> processInstanceIds) {
+        return CollectionUtils.convertMultiMap(getTasksByProcessInstanceIds(processInstanceIds),
+                Task::getProcessInstanceId);
+    }
+
+    /**
+     * 获得流程任务列表
+     *
+     * @param processInstanceIds 流程实例的编号数组
+     * @return 流程任务列表
+     */
+    List<Task> getTasksByProcessInstanceIds(List<String> processInstanceIds);
+}

+ 82 - 0
yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmTaskServiceImpl.java

@@ -0,0 +1,82 @@
+package cn.iocoder.yudao.module.bpm.service.task;
+
+import cn.hutool.core.collection.CollUtil;
+import cn.hutool.core.util.StrUtil;
+import cn.iocoder.yudao.framework.common.pojo.PageResult;
+import cn.iocoder.yudao.framework.common.util.object.PageUtils;
+import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.task.BpmTaskTodoPageItemRespVO;
+import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.task.BpmTaskTodoPageReqVO;
+import cn.iocoder.yudao.module.bpm.convert.task.BpmTaskConvert;
+import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
+import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
+import lombok.extern.slf4j.Slf4j;
+import org.flowable.engine.TaskService;
+import org.flowable.engine.runtime.ProcessInstance;
+import org.flowable.task.api.Task;
+import org.flowable.task.api.TaskQuery;
+import org.springframework.stereotype.Service;
+
+import javax.annotation.Resource;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+
+import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
+
+/**
+ * 流程任务实例 Service 实现类
+ *
+ * @author jason
+ * @author 芋道源码
+ */
+@Slf4j
+@Service
+public class BpmTaskServiceImpl implements BpmTaskService{
+
+    @Resource
+    private TaskService taskService;
+    @Resource
+    private AdminUserApi adminUserApi;
+    @Resource
+    private BpmProcessInstanceService processInstanceService;
+
+    @Override
+    public PageResult<BpmTaskTodoPageItemRespVO> getTodoTaskPage(Long userId, BpmTaskTodoPageReqVO pageVO) {
+        // 查询待办任务
+        TaskQuery taskQuery = taskService.createTaskQuery()
+                .taskAssignee(String.valueOf(userId)) // 分配给自己
+                .orderByTaskCreateTime().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<Task> tasks = taskQuery.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, AdminUserRespDTO> userMap = adminUserApi.getUserMap(
+                convertSet(processInstanceMap.values(), instance -> Long.valueOf(instance.getStartUserId())));
+        // 拼接结果
+        return new PageResult<>(BpmTaskConvert.INSTANCE.convertList1(tasks, processInstanceMap, userMap),
+                taskQuery.count());
+    }
+
+    @Override
+    public List<Task> getTasksByProcessInstanceIds(List<String> processInstanceIds) {
+        if (CollUtil.isEmpty(processInstanceIds)) {
+            return Collections.emptyList();
+        }
+        return taskService.createTaskQuery().processInstanceIdIn(processInstanceIds).list();
+    }
+}