Commit 13da7eba6fcf2589b0ad589d61a06fa1fa13b3e3

Authored by YunaiV
1 parent ef19efb2

reactor:移除 bpm 的 api 包

Showing 267 changed files with 2552 additions and 2615 deletions
yudao-module-bpm/pom.xml
@@ -8,12 +8,8 @@ @@ -8,12 +8,8 @@
8 <version>${revision}</version> 8 <version>${revision}</version>
9 </parent> 9 </parent>
10 <modelVersion>4.0.0</modelVersion> 10 <modelVersion>4.0.0</modelVersion>
11 - <modules>  
12 - <module>yudao-module-bpm-api</module>  
13 - <module>yudao-module-bpm-biz</module>  
14 - </modules>  
15 <artifactId>yudao-module-bpm</artifactId> 11 <artifactId>yudao-module-bpm</artifactId>
16 - <packaging>pom</packaging> 12 + <packaging>jar</packaging>
17 13
18 <name>${project.artifactId}</name> 14 <name>${project.artifactId}</name>
19 <description> 15 <description>
@@ -24,4 +20,60 @@ @@ -24,4 +20,60 @@
24 工作流基于 Flowable 6 实现,分成流程定义、流程表单、流程实例、流程任务等功能模块。 20 工作流基于 Flowable 6 实现,分成流程定义、流程表单、流程实例、流程任务等功能模块。
25 </description> 21 </description>
26 22
  23 + <dependencies>
  24 + <dependency>
  25 + <groupId>cn.iocoder.boot</groupId>
  26 + <artifactId>yudao-module-system</artifactId>
  27 + <version>${revision}</version>
  28 + </dependency>
  29 +
  30 + <!-- 业务组件 -->
  31 + <dependency>
  32 + <groupId>cn.iocoder.boot</groupId>
  33 + <artifactId>yudao-spring-boot-starter-biz-data-permission</artifactId>
  34 + </dependency>
  35 + <dependency>
  36 + <groupId>cn.iocoder.boot</groupId>
  37 + <artifactId>yudao-spring-boot-starter-biz-tenant</artifactId>
  38 + </dependency>
  39 +
  40 + <!-- Web 相关 -->
  41 + <dependency>
  42 + <groupId>cn.iocoder.boot</groupId>
  43 + <artifactId>yudao-spring-boot-starter-web</artifactId>
  44 + </dependency>
  45 +
  46 + <dependency>
  47 + <groupId>cn.iocoder.boot</groupId>
  48 + <artifactId>yudao-spring-boot-starter-security</artifactId>
  49 + </dependency>
  50 +
  51 + <!-- DB 相关 -->
  52 + <dependency>
  53 + <groupId>cn.iocoder.boot</groupId>
  54 + <artifactId>yudao-spring-boot-starter-mybatis</artifactId>
  55 + </dependency>
  56 +
  57 + <!-- Test 测试相关 -->
  58 + <dependency>
  59 + <groupId>cn.iocoder.boot</groupId>
  60 + <artifactId>yudao-spring-boot-starter-test</artifactId>
  61 + </dependency>
  62 +
  63 + <!-- 工具类相关 -->
  64 + <dependency>
  65 + <groupId>cn.iocoder.boot</groupId>
  66 + <artifactId>yudao-spring-boot-starter-excel</artifactId>
  67 + </dependency>
  68 +
  69 + <!-- Flowable 工作流相关 -->
  70 + <dependency>
  71 + <groupId>org.flowable</groupId>
  72 + <artifactId>flowable-spring-boot-starter-process</artifactId>
  73 + </dependency>
  74 + <dependency>
  75 + <groupId>org.flowable</groupId>
  76 + <artifactId>flowable-spring-boot-starter-actuator</artifactId>
  77 + </dependency>
  78 + </dependencies>
27 </project> 79 </project>
yudao-module-bpm/yudao-module-bpm-api/src/main/java/cn/iocoder/yudao/module/bpm/event/BpmProcessInstanceStatusEvent.java renamed to yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/api/event/BpmProcessInstanceStatusEvent.java
1 -package cn.iocoder.yudao.module.bpm.event; 1 +package cn.iocoder.yudao.module.bpm.api.event;
2 2
3 import jakarta.validation.constraints.NotNull; 3 import jakarta.validation.constraints.NotNull;
4 import lombok.Data; 4 import lombok.Data;
yudao-module-bpm/yudao-module-bpm-api/src/main/java/cn/iocoder/yudao/module/bpm/event/BpmProcessInstanceStatusEventListener.java renamed to yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/api/event/BpmProcessInstanceStatusEventListener.java
1 -package cn.iocoder.yudao.module.bpm.event; 1 +package cn.iocoder.yudao.module.bpm.api.event;
2 2
3 import cn.hutool.core.util.StrUtil; 3 import cn.hutool.core.util.StrUtil;
4 import org.springframework.context.ApplicationListener; 4 import org.springframework.context.ApplicationListener;
yudao-module-bpm/yudao-module-bpm-api/src/main/java/cn/iocoder/yudao/module/bpm/api/package-info.java renamed to yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/api/package-info.java
1 /** 1 /**
2 - * bpm API 包,定义暴露给其它模块的 API 2 + * bpm API 包,定义并实现提供给其它模块的 API
3 */ 3 */
4 package cn.iocoder.yudao.module.bpm.api; 4 package cn.iocoder.yudao.module.bpm.api;
yudao-module-bpm/yudao-module-bpm-api/src/main/java/cn/iocoder/yudao/module/bpm/api/task/BpmProcessInstanceApi.java renamed to yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/api/task/BpmProcessInstanceApi.java
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/api/task/BpmProcessInstanceApiImpl.java renamed to yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/api/task/BpmProcessInstanceApiImpl.java
yudao-module-bpm/yudao-module-bpm-api/src/main/java/cn/iocoder/yudao/module/bpm/api/task/BpmProcessTaskApi.java renamed to yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/api/task/BpmProcessTaskApi.java
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/api/task/BpmProcessTaskApiImpl.java renamed to yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/api/task/BpmProcessTaskApiImpl.java
yudao-module-bpm/yudao-module-bpm-api/src/main/java/cn/iocoder/yudao/module/bpm/api/task/dto/BpmProcessInstanceCreateReqDTO.java renamed to yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/api/task/dto/BpmProcessInstanceCreateReqDTO.java
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/base/dept/DeptSimpleBaseVO.java renamed to yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/base/dept/DeptSimpleBaseVO.java
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/base/package-info.java renamed to yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/base/package-info.java
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/base/user/UserSimpleBaseVO.java renamed to yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/base/user/UserSimpleBaseVO.java
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/BpmCategoryController.java renamed to yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/BpmCategoryController.java
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/BpmFormController.java renamed to yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/BpmFormController.java
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/BpmModelController.java renamed to yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/BpmModelController.java
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/BpmProcessDefinitionController.java renamed to yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/BpmProcessDefinitionController.java
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/BpmProcessExpressionController.java renamed to yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/BpmProcessExpressionController.java
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/BpmProcessListenerController.java renamed to yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/BpmProcessListenerController.java
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/BpmUserGroupController.java renamed to yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/BpmUserGroupController.java
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/category/BpmCategoryPageReqVO.java renamed to yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/category/BpmCategoryPageReqVO.java
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/category/BpmCategoryRespVO.java renamed to yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/category/BpmCategoryRespVO.java
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/category/BpmCategorySaveReqVO.java renamed to yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/category/BpmCategorySaveReqVO.java
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/expression/BpmProcessExpressionPageReqVO.java renamed to yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/expression/BpmProcessExpressionPageReqVO.java
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/expression/BpmProcessExpressionRespVO.java renamed to yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/expression/BpmProcessExpressionRespVO.java
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/expression/BpmProcessExpressionSaveReqVO.java renamed to yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/expression/BpmProcessExpressionSaveReqVO.java
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/form/BpmFormFieldVO.java renamed to yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/form/BpmFormFieldVO.java
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/form/BpmFormPageReqVO.java renamed to yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/form/BpmFormPageReqVO.java
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/form/BpmFormRespVO.java renamed to yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/form/BpmFormRespVO.java
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/form/BpmFormSaveReqVO.java renamed to yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/form/BpmFormSaveReqVO.java
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/group/BpmUserGroupPageReqVO.java renamed to yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/group/BpmUserGroupPageReqVO.java
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/group/BpmUserGroupRespVO.java renamed to yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/group/BpmUserGroupRespVO.java
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/group/BpmUserGroupSaveReqVO.java renamed to yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/group/BpmUserGroupSaveReqVO.java
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/listener/BpmProcessListenerPageReqVO.java renamed to yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/listener/BpmProcessListenerPageReqVO.java
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/listener/BpmProcessListenerRespVO.java renamed to yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/listener/BpmProcessListenerRespVO.java
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/listener/BpmProcessListenerSaveReqVO.java renamed to yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/listener/BpmProcessListenerSaveReqVO.java
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/model/BpmModeUpdateBpmnReqVO.java renamed to yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/model/BpmModeUpdateBpmnReqVO.java
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/model/BpmModelMetaInfoVO.java renamed to yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/model/BpmModelMetaInfoVO.java
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/model/BpmModelRespVO.java renamed to yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/model/BpmModelRespVO.java
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/model/BpmModelSaveReqVO.java renamed to yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/model/BpmModelSaveReqVO.java
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/model/BpmModelUpdateStateReqVO.java renamed to yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/model/BpmModelUpdateStateReqVO.java
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/model/simple/BpmSimpleModelNodeVO.java renamed to yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/model/simple/BpmSimpleModelNodeVO.java
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/model/simple/BpmSimpleModelUpdateReqVO.java renamed to yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/model/simple/BpmSimpleModelUpdateReqVO.java
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/process/BpmProcessDefinitionPageReqVO.java renamed to yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/process/BpmProcessDefinitionPageReqVO.java
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/process/BpmProcessDefinitionRespVO.java renamed to yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/process/BpmProcessDefinitionRespVO.java
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/oa/BpmOALeaveController.http renamed to yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/oa/BpmOALeaveController.http
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/oa/BpmOALeaveController.java renamed to yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/oa/BpmOALeaveController.java
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/oa/package-info.java renamed to yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/oa/package-info.java
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/oa/vo/BpmOALeaveCreateReqVO.java renamed to yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/oa/vo/BpmOALeaveCreateReqVO.java
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/oa/vo/BpmOALeavePageReqVO.java renamed to yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/oa/vo/BpmOALeavePageReqVO.java
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/oa/vo/BpmOALeaveRespVO.java renamed to yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/oa/vo/BpmOALeaveRespVO.java
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/BpmProcessInstanceController.http renamed to yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/BpmProcessInstanceController.http
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/BpmProcessInstanceController.java renamed to yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/BpmProcessInstanceController.java
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/BpmProcessInstanceCopyController.java renamed to yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/BpmProcessInstanceCopyController.java
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/BpmTaskController.java renamed to yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/BpmTaskController.java
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/activity/BpmActivityRespVO.java renamed to yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/activity/BpmActivityRespVO.java
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/cc/BpmProcessInstanceCopyRespVO.java renamed to yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/cc/BpmProcessInstanceCopyRespVO.java
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/instance/BpmApprovalDetailReqVO.java renamed to yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/instance/BpmApprovalDetailReqVO.java
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/instance/BpmApprovalDetailRespVO.java renamed to yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/instance/BpmApprovalDetailRespVO.java
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/instance/BpmProcessInstanceBpmnModelViewRespVO.java renamed to yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/instance/BpmProcessInstanceBpmnModelViewRespVO.java
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/instance/BpmProcessInstanceCancelReqVO.java renamed to yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/instance/BpmProcessInstanceCancelReqVO.java
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/instance/BpmProcessInstanceCopyPageReqVO.java renamed to yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/instance/BpmProcessInstanceCopyPageReqVO.java
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/instance/BpmProcessInstanceCreateReqVO.java renamed to yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/instance/BpmProcessInstanceCreateReqVO.java
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/instance/BpmProcessInstancePageReqVO.java renamed to yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/instance/BpmProcessInstancePageReqVO.java
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/instance/BpmProcessInstanceRespVO.java renamed to yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/instance/BpmProcessInstanceRespVO.java
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/task/BpmTaskApproveReqVO.java renamed to yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/task/BpmTaskApproveReqVO.java
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/task/BpmTaskCopyReqVO.java renamed to yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/task/BpmTaskCopyReqVO.java
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/task/BpmTaskDelegateReqVO.java renamed to yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/task/BpmTaskDelegateReqVO.java
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/task/BpmTaskPageReqVO.java renamed to yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/task/BpmTaskPageReqVO.java
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/task/BpmTaskRejectReqVO.java renamed to yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/task/BpmTaskRejectReqVO.java
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/task/BpmTaskRespVO.java renamed to yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/task/BpmTaskRespVO.java
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/task/BpmTaskReturnReqVO.java renamed to yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/task/BpmTaskReturnReqVO.java
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/task/BpmTaskSignCreateReqVO.java renamed to yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/task/BpmTaskSignCreateReqVO.java
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/task/BpmTaskSignDeleteReqVO.java renamed to yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/task/BpmTaskSignDeleteReqVO.java
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/task/BpmTaskTransferReqVO.java renamed to yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/task/BpmTaskTransferReqVO.java
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/app/package-info.java renamed to yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/controller/app/package-info.java
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/package-info.java renamed to yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/controller/package-info.java
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/convert/definition/BpmModelConvert.java renamed to yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/convert/definition/BpmModelConvert.java
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/convert/definition/BpmProcessDefinitionConvert.java renamed to yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/convert/definition/BpmProcessDefinitionConvert.java
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/convert/message/BpmMessageConvert.java renamed to yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/convert/message/BpmMessageConvert.java
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/convert/package-info.java renamed to yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/convert/package-info.java
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/convert/task/BpmProcessInstanceConvert.java renamed to yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/convert/task/BpmProcessInstanceConvert.java
@@ -17,7 +17,7 @@ import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.task.BpmTaskRespVO; @@ -17,7 +17,7 @@ import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.task.BpmTaskRespVO;
17 import cn.iocoder.yudao.module.bpm.convert.definition.BpmProcessDefinitionConvert; 17 import cn.iocoder.yudao.module.bpm.convert.definition.BpmProcessDefinitionConvert;
18 import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmCategoryDO; 18 import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmCategoryDO;
19 import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmProcessDefinitionInfoDO; 19 import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmProcessDefinitionInfoDO;
20 -import cn.iocoder.yudao.module.bpm.event.BpmProcessInstanceStatusEvent; 20 +import cn.iocoder.yudao.module.bpm.api.event.BpmProcessInstanceStatusEvent;
21 import cn.iocoder.yudao.module.bpm.framework.flowable.core.util.BpmnModelUtils; 21 import cn.iocoder.yudao.module.bpm.framework.flowable.core.util.BpmnModelUtils;
22 import cn.iocoder.yudao.module.bpm.framework.flowable.core.util.FlowableUtils; 22 import cn.iocoder.yudao.module.bpm.framework.flowable.core.util.FlowableUtils;
23 import cn.iocoder.yudao.module.bpm.service.message.dto.BpmMessageSendWhenProcessInstanceApproveReqDTO; 23 import cn.iocoder.yudao.module.bpm.service.message.dto.BpmMessageSendWhenProcessInstanceApproveReqDTO;
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/convert/task/BpmTaskConvert.java renamed to yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/convert/task/BpmTaskConvert.java
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/convert/《芋道 Spring Boot 对象转换 MapStruct 入门》.md renamed to yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/convert/《芋道 Spring Boot 对象转换 MapStruct 入门》.md
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/dal/dataobject/definition/BpmCategoryDO.java renamed to yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/dal/dataobject/definition/BpmCategoryDO.java
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/dal/dataobject/definition/BpmFormDO.java renamed to yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/dal/dataobject/definition/BpmFormDO.java
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/dal/dataobject/definition/BpmProcessDefinitionInfoDO.java renamed to yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/dal/dataobject/definition/BpmProcessDefinitionInfoDO.java
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/dal/dataobject/definition/BpmProcessExpressionDO.java renamed to yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/dal/dataobject/definition/BpmProcessExpressionDO.java
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/dal/dataobject/definition/BpmProcessListenerDO.java renamed to yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/dal/dataobject/definition/BpmProcessListenerDO.java
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/dal/dataobject/definition/BpmUserGroupDO.java renamed to yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/dal/dataobject/definition/BpmUserGroupDO.java
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/dal/dataobject/oa/BpmOALeaveDO.java renamed to yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/dal/dataobject/oa/BpmOALeaveDO.java
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/dal/dataobject/task/BpmProcessInstanceCopyDO.java renamed to yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/dal/dataobject/task/BpmProcessInstanceCopyDO.java
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/dal/mysql/category/BpmCategoryMapper.java renamed to yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/dal/mysql/category/BpmCategoryMapper.java
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/dal/mysql/definition/BpmFormMapper.java renamed to yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/dal/mysql/definition/BpmFormMapper.java
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/dal/mysql/definition/BpmProcessDefinitionInfoMapper.java renamed to yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/dal/mysql/definition/BpmProcessDefinitionInfoMapper.java
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/dal/mysql/definition/BpmProcessExpressionMapper.java renamed to yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/dal/mysql/definition/BpmProcessExpressionMapper.java
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/dal/mysql/definition/BpmProcessListenerMapper.java renamed to yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/dal/mysql/definition/BpmProcessListenerMapper.java
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/dal/mysql/definition/BpmUserGroupMapper.java renamed to yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/dal/mysql/definition/BpmUserGroupMapper.java
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/dal/mysql/oa/BpmOALeaveMapper.java renamed to yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/dal/mysql/oa/BpmOALeaveMapper.java
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/dal/mysql/task/BpmProcessInstanceCopyMapper.java renamed to yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/dal/mysql/task/BpmProcessInstanceCopyMapper.java
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/dal/redis/BpmProcessIdRedisDAO.java renamed to yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/dal/redis/BpmProcessIdRedisDAO.java
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/dal/redis/RedisKeyConstants.java renamed to yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/dal/redis/RedisKeyConstants.java
yudao-module-bpm/yudao-module-bpm-api/src/main/java/cn/iocoder/yudao/module/bpm/enums/DictTypeConstants.java renamed to yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/enums/DictTypeConstants.java
yudao-module-bpm/yudao-module-bpm-api/src/main/java/cn/iocoder/yudao/module/bpm/enums/ErrorCodeConstants.java renamed to yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/enums/ErrorCodeConstants.java
yudao-module-bpm/yudao-module-bpm-api/src/main/java/cn/iocoder/yudao/module/bpm/enums/definition/BpmAutoApproveTypeEnum.java renamed to yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/enums/definition/BpmAutoApproveTypeEnum.java
yudao-module-bpm/yudao-module-bpm-api/src/main/java/cn/iocoder/yudao/module/bpm/enums/definition/BpmBoundaryEventTypeEnum.java renamed to yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/enums/definition/BpmBoundaryEventTypeEnum.java
yudao-module-bpm/yudao-module-bpm-api/src/main/java/cn/iocoder/yudao/module/bpm/enums/definition/BpmChildProcessMultiInstanceSourceTypeEnum.java renamed to yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/enums/definition/BpmChildProcessMultiInstanceSourceTypeEnum.java
yudao-module-bpm/yudao-module-bpm-api/src/main/java/cn/iocoder/yudao/module/bpm/enums/definition/BpmChildProcessStartUserEmptyTypeEnum.java renamed to yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/enums/definition/BpmChildProcessStartUserEmptyTypeEnum.java
yudao-module-bpm/yudao-module-bpm-api/src/main/java/cn/iocoder/yudao/module/bpm/enums/definition/BpmChildProcessStartUserTypeEnum.java renamed to yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/enums/definition/BpmChildProcessStartUserTypeEnum.java
yudao-module-bpm/yudao-module-bpm-api/src/main/java/cn/iocoder/yudao/module/bpm/enums/definition/BpmDelayTimerTypeEnum.java renamed to yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/enums/definition/BpmDelayTimerTypeEnum.java
yudao-module-bpm/yudao-module-bpm-api/src/main/java/cn/iocoder/yudao/module/bpm/enums/definition/BpmFieldPermissionEnum.java renamed to yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/enums/definition/BpmFieldPermissionEnum.java
yudao-module-bpm/yudao-module-bpm-api/src/main/java/cn/iocoder/yudao/module/bpm/enums/definition/BpmHttpRequestParamTypeEnum.java renamed to yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/enums/definition/BpmHttpRequestParamTypeEnum.java
yudao-module-bpm/yudao-module-bpm-api/src/main/java/cn/iocoder/yudao/module/bpm/enums/definition/BpmModelFormTypeEnum.java renamed to yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/enums/definition/BpmModelFormTypeEnum.java
yudao-module-bpm/yudao-module-bpm-api/src/main/java/cn/iocoder/yudao/module/bpm/enums/definition/BpmModelTypeEnum.java renamed to yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/enums/definition/BpmModelTypeEnum.java
yudao-module-bpm/yudao-module-bpm-api/src/main/java/cn/iocoder/yudao/module/bpm/enums/definition/BpmProcessListenerTypeEnum.java renamed to yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/enums/definition/BpmProcessListenerTypeEnum.java
yudao-module-bpm/yudao-module-bpm-api/src/main/java/cn/iocoder/yudao/module/bpm/enums/definition/BpmProcessListenerValueTypeEnum.java renamed to yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/enums/definition/BpmProcessListenerValueTypeEnum.java
yudao-module-bpm/yudao-module-bpm-api/src/main/java/cn/iocoder/yudao/module/bpm/enums/definition/BpmSimpleModeConditionTypeEnum.java renamed to yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/enums/definition/BpmSimpleModeConditionTypeEnum.java
yudao-module-bpm/yudao-module-bpm-api/src/main/java/cn/iocoder/yudao/module/bpm/enums/definition/BpmSimpleModelNodeTypeEnum.java renamed to yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/enums/definition/BpmSimpleModelNodeTypeEnum.java
yudao-module-bpm/yudao-module-bpm-api/src/main/java/cn/iocoder/yudao/module/bpm/enums/definition/BpmTriggerTypeEnum.java renamed to yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/enums/definition/BpmTriggerTypeEnum.java
yudao-module-bpm/yudao-module-bpm-api/src/main/java/cn/iocoder/yudao/module/bpm/enums/definition/BpmUserTaskApproveMethodEnum.java renamed to yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/enums/definition/BpmUserTaskApproveMethodEnum.java
yudao-module-bpm/yudao-module-bpm-api/src/main/java/cn/iocoder/yudao/module/bpm/enums/definition/BpmUserTaskApproveTypeEnum.java renamed to yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/enums/definition/BpmUserTaskApproveTypeEnum.java
yudao-module-bpm/yudao-module-bpm-api/src/main/java/cn/iocoder/yudao/module/bpm/enums/definition/BpmUserTaskAssignEmptyHandlerTypeEnum.java renamed to yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/enums/definition/BpmUserTaskAssignEmptyHandlerTypeEnum.java
yudao-module-bpm/yudao-module-bpm-api/src/main/java/cn/iocoder/yudao/module/bpm/enums/definition/BpmUserTaskAssignStartUserHandlerTypeEnum.java renamed to yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/enums/definition/BpmUserTaskAssignStartUserHandlerTypeEnum.java
yudao-module-bpm/yudao-module-bpm-api/src/main/java/cn/iocoder/yudao/module/bpm/enums/definition/BpmUserTaskRejectHandlerTypeEnum.java renamed to yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/enums/definition/BpmUserTaskRejectHandlerTypeEnum.java
yudao-module-bpm/yudao-module-bpm-api/src/main/java/cn/iocoder/yudao/module/bpm/enums/definition/BpmUserTaskTimeoutHandlerTypeEnum.java renamed to yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/enums/definition/BpmUserTaskTimeoutHandlerTypeEnum.java
yudao-module-bpm/yudao-module-bpm-api/src/main/java/cn/iocoder/yudao/module/bpm/enums/message/BpmMessageEnum.java renamed to yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/enums/message/BpmMessageEnum.java
yudao-module-bpm/yudao-module-bpm-api/src/main/java/cn/iocoder/yudao/module/bpm/enums/task/BpmCommentTypeEnum.java renamed to yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/enums/task/BpmCommentTypeEnum.java
yudao-module-bpm/yudao-module-bpm-api/src/main/java/cn/iocoder/yudao/module/bpm/enums/task/BpmProcessInstanceStatusEnum.java renamed to yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/enums/task/BpmProcessInstanceStatusEnum.java
yudao-module-bpm/yudao-module-bpm-api/src/main/java/cn/iocoder/yudao/module/bpm/enums/task/BpmReasonEnum.java renamed to yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/enums/task/BpmReasonEnum.java
yudao-module-bpm/yudao-module-bpm-api/src/main/java/cn/iocoder/yudao/module/bpm/enums/task/BpmTaskSignTypeEnum.java renamed to yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/enums/task/BpmTaskSignTypeEnum.java
yudao-module-bpm/yudao-module-bpm-api/src/main/java/cn/iocoder/yudao/module/bpm/enums/task/BpmTaskStatusEnum.java renamed to yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/enums/task/BpmTaskStatusEnum.java
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/config/BpmFlowableConfiguration.java renamed to yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/config/BpmFlowableConfiguration.java
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/behavior/BpmActivityBehaviorFactory.java renamed to yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/behavior/BpmActivityBehaviorFactory.java
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/behavior/BpmParallelMultiInstanceBehavior.java renamed to yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/behavior/BpmParallelMultiInstanceBehavior.java
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/behavior/BpmSequentialMultiInstanceBehavior.java renamed to yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/behavior/BpmSequentialMultiInstanceBehavior.java
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/behavior/BpmUserTaskActivityBehavior.java renamed to yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/behavior/BpmUserTaskActivityBehavior.java
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/candidate/BpmTaskCandidateInvoker.java renamed to yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/candidate/BpmTaskCandidateInvoker.java
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/candidate/BpmTaskCandidateStrategy.java renamed to yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/candidate/BpmTaskCandidateStrategy.java
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/candidate/expression/BpmTaskAssignLeaderExpression.java renamed to yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/candidate/expression/BpmTaskAssignLeaderExpression.java
@@ -14,6 +14,7 @@ import org.springframework.util.Assert; @@ -14,6 +14,7 @@ import org.springframework.util.Assert;
14 import jakarta.annotation.Resource; 14 import jakarta.annotation.Resource;
15 import java.util.Set; 15 import java.util.Set;
16 16
  17 +import static cn.iocoder.yudao.framework.common.util.collection.SetUtils.asSet;
17 import static java.util.Collections.emptySet; 18 import static java.util.Collections.emptySet;
18 19
19 /** 20 /**
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/candidate/expression/BpmTaskAssignStartUserExpression.java renamed to yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/candidate/expression/BpmTaskAssignStartUserExpression.java
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/candidate/strategy/dept/AbstractBpmTaskCandidateDeptLeaderStrategy.java renamed to yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/candidate/strategy/dept/AbstractBpmTaskCandidateDeptLeaderStrategy.java
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/candidate/strategy/dept/BpmTaskCandidateApproveUserSelectStrategy.java renamed to yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/candidate/strategy/dept/BpmTaskCandidateApproveUserSelectStrategy.java
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/candidate/strategy/dept/BpmTaskCandidateDeptLeaderMultiStrategy.java renamed to yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/candidate/strategy/dept/BpmTaskCandidateDeptLeaderMultiStrategy.java
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/candidate/strategy/dept/BpmTaskCandidateDeptLeaderStrategy.java renamed to yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/candidate/strategy/dept/BpmTaskCandidateDeptLeaderStrategy.java
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/candidate/strategy/dept/BpmTaskCandidateDeptMemberStrategy.java renamed to yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/candidate/strategy/dept/BpmTaskCandidateDeptMemberStrategy.java
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/candidate/strategy/dept/BpmTaskCandidateStartUserDeptLeaderMultiStrategy.java renamed to yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/candidate/strategy/dept/BpmTaskCandidateStartUserDeptLeaderMultiStrategy.java
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/candidate/strategy/dept/BpmTaskCandidateStartUserDeptLeaderStrategy.java renamed to yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/candidate/strategy/dept/BpmTaskCandidateStartUserDeptLeaderStrategy.java
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/candidate/strategy/dept/BpmTaskCandidateStartUserSelectStrategy.java renamed to yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/candidate/strategy/dept/BpmTaskCandidateStartUserSelectStrategy.java
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/candidate/strategy/form/BpmTaskCandidateFormDeptLeaderStrategy.java renamed to yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/candidate/strategy/form/BpmTaskCandidateFormDeptLeaderStrategy.java
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/candidate/strategy/form/BpmTaskCandidateFormUserStrategy.java renamed to yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/candidate/strategy/form/BpmTaskCandidateFormUserStrategy.java
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/candidate/strategy/other/BpmTaskCandidateAssignEmptyStrategy.java renamed to yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/candidate/strategy/other/BpmTaskCandidateAssignEmptyStrategy.java
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/candidate/strategy/other/BpmTaskCandidateExpressionStrategy.java renamed to yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/candidate/strategy/other/BpmTaskCandidateExpressionStrategy.java
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/candidate/strategy/user/BpmTaskCandidateGroupStrategy.java renamed to yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/candidate/strategy/user/BpmTaskCandidateGroupStrategy.java
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/candidate/strategy/user/BpmTaskCandidatePostStrategy.java renamed to yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/candidate/strategy/user/BpmTaskCandidatePostStrategy.java
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/candidate/strategy/user/BpmTaskCandidateRoleStrategy.java renamed to yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/candidate/strategy/user/BpmTaskCandidateRoleStrategy.java
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/candidate/strategy/user/BpmTaskCandidateStartUserStrategy.java renamed to yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/candidate/strategy/user/BpmTaskCandidateStartUserStrategy.java
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/candidate/strategy/user/BpmTaskCandidateUserStrategy.java renamed to yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/candidate/strategy/user/BpmTaskCandidateUserStrategy.java
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/el/VariableConvertByTypeExpressionFunction.java renamed to yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/el/VariableConvertByTypeExpressionFunction.java
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/enums/BpmTaskCandidateStrategyEnum.java renamed to yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/enums/BpmTaskCandidateStrategyEnum.java
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/enums/BpmnModelConstants.java renamed to yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/enums/BpmnModelConstants.java
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/enums/BpmnVariableConstants.java renamed to yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/enums/BpmnVariableConstants.java
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/event/BpmProcessInstanceEventPublisher.java renamed to yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/event/BpmProcessInstanceEventPublisher.java
1 package cn.iocoder.yudao.module.bpm.framework.flowable.core.event; 1 package cn.iocoder.yudao.module.bpm.framework.flowable.core.event;
2 2
3 -import cn.iocoder.yudao.module.bpm.event.BpmProcessInstanceStatusEvent; 3 +import cn.iocoder.yudao.module.bpm.api.event.BpmProcessInstanceStatusEvent;
4 import lombok.AllArgsConstructor; 4 import lombok.AllArgsConstructor;
5 import org.springframework.context.ApplicationEventPublisher; 5 import org.springframework.context.ApplicationEventPublisher;
6 import org.springframework.validation.annotation.Validated; 6 import org.springframework.validation.annotation.Validated;
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/listener/BpmCopyTaskDelegate.java renamed to yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/listener/BpmCopyTaskDelegate.java
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/listener/BpmProcessInstanceEventListener.java renamed to yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/listener/BpmProcessInstanceEventListener.java
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/listener/BpmTaskEventListener.java renamed to yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/listener/BpmTaskEventListener.java
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/listener/BpmTriggerTaskDelegate.java renamed to yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/listener/BpmTriggerTaskDelegate.java
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/listener/demo/exection/DemoDelegateClassExecutionListener.java renamed to yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/listener/demo/exection/DemoDelegateClassExecutionListener.java
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/listener/demo/exection/DemoDelegateExpressionExecutionListener.java renamed to yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/listener/demo/exection/DemoDelegateExpressionExecutionListener.java
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/listener/demo/exection/DemoSpringExpressionExecutionListener.java renamed to yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/listener/demo/exection/DemoSpringExpressionExecutionListener.java
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/listener/demo/task/DemoDelegateClassTaskListener.java renamed to yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/listener/demo/task/DemoDelegateClassTaskListener.java
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/listener/demo/task/DemoDelegateExpressionTaskListener.java renamed to yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/listener/demo/task/DemoDelegateExpressionTaskListener.java
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/listener/demo/task/DemoSpringExpressionTaskListener.java renamed to yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/listener/demo/task/DemoSpringExpressionTaskListener.java
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/util/BpmHttpRequestUtils.java renamed to yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/util/BpmHttpRequestUtils.java
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/util/BpmnModelUtils.java renamed to yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/util/BpmnModelUtils.java
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/util/FlowableUtils.java renamed to yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/util/FlowableUtils.java
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/util/SimpleModelUtils.java renamed to yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/util/SimpleModelUtils.java
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/package-info.java renamed to yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/framework/package-info.java
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/web/config/BpmWebConfiguration.java renamed to yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/framework/web/config/BpmWebConfiguration.java
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/web/core/FlowableWebFilter.java renamed to yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/framework/web/core/FlowableWebFilter.java
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/web/package-info.java renamed to yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/framework/web/package-info.java
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/package-info.java renamed to yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/package-info.java
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmCategoryService.java renamed to yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmCategoryService.java
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmCategoryServiceImpl.java renamed to yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmCategoryServiceImpl.java
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmFormService.java renamed to yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmFormService.java
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmFormServiceImpl.java renamed to yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmFormServiceImpl.java
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmModelService.java renamed to yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmModelService.java
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmModelServiceImpl.java renamed to yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmModelServiceImpl.java
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmProcessDefinitionService.java renamed to yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmProcessDefinitionService.java
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmProcessDefinitionServiceImpl.java renamed to yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmProcessDefinitionServiceImpl.java
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmProcessExpressionService.java renamed to yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmProcessExpressionService.java
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmProcessExpressionServiceImpl.java renamed to yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmProcessExpressionServiceImpl.java
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmProcessListenerService.java renamed to yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmProcessListenerService.java
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmProcessListenerServiceImpl.java renamed to yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmProcessListenerServiceImpl.java
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmUserGroupService.java renamed to yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmUserGroupService.java
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmUserGroupServiceImpl.java renamed to yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmUserGroupServiceImpl.java
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/dto/BpmFormFieldRespDTO.java renamed to yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/dto/BpmFormFieldRespDTO.java
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/dto/BpmProcessDefinitionCreateReqDTO.java renamed to yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/dto/BpmProcessDefinitionCreateReqDTO.java
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/message/BpmMessageService.java renamed to yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/service/message/BpmMessageService.java
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/message/BpmMessageServiceImpl.java renamed to yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/service/message/BpmMessageServiceImpl.java
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/message/dto/BpmMessageSendWhenProcessInstanceApproveReqDTO.java renamed to yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/service/message/dto/BpmMessageSendWhenProcessInstanceApproveReqDTO.java
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/message/dto/BpmMessageSendWhenProcessInstanceRejectReqDTO.java renamed to yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/service/message/dto/BpmMessageSendWhenProcessInstanceRejectReqDTO.java
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/message/dto/BpmMessageSendWhenTaskCreatedReqDTO.java renamed to yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/service/message/dto/BpmMessageSendWhenTaskCreatedReqDTO.java
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/message/dto/BpmMessageSendWhenTaskTimeoutReqDTO.java renamed to yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/service/message/dto/BpmMessageSendWhenTaskTimeoutReqDTO.java
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/oa/BpmOALeaveService.java renamed to yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/service/oa/BpmOALeaveService.java
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/oa/BpmOALeaveServiceImpl.java renamed to yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/service/oa/BpmOALeaveServiceImpl.java
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/oa/listener/BpmOALeaveStatusListener.java renamed to yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/service/oa/listener/BpmOALeaveStatusListener.java
1 package cn.iocoder.yudao.module.bpm.service.oa.listener; 1 package cn.iocoder.yudao.module.bpm.service.oa.listener;
2 2
3 -import cn.iocoder.yudao.module.bpm.event.BpmProcessInstanceStatusEvent;  
4 -import cn.iocoder.yudao.module.bpm.event.BpmProcessInstanceStatusEventListener; 3 +import cn.iocoder.yudao.module.bpm.api.event.BpmProcessInstanceStatusEvent;
  4 +import cn.iocoder.yudao.module.bpm.api.event.BpmProcessInstanceStatusEventListener;
5 import cn.iocoder.yudao.module.bpm.service.oa.BpmOALeaveService; 5 import cn.iocoder.yudao.module.bpm.service.oa.BpmOALeaveService;
6 import cn.iocoder.yudao.module.bpm.service.oa.BpmOALeaveServiceImpl; 6 import cn.iocoder.yudao.module.bpm.service.oa.BpmOALeaveServiceImpl;
7 import org.springframework.stereotype.Component; 7 import org.springframework.stereotype.Component;
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmProcessInstanceCopyService.java renamed to yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmProcessInstanceCopyService.java
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmProcessInstanceCopyServiceImpl.java renamed to yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmProcessInstanceCopyServiceImpl.java
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmProcessInstanceService.java renamed to yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmProcessInstanceService.java
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmProcessInstanceServiceImpl.java renamed to yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmProcessInstanceServiceImpl.java
1 -package cn.iocoder.yudao.module.bpm.service.task;  
2 -  
3 -import cn.hutool.core.collection.CollUtil;  
4 -import cn.hutool.core.collection.ListUtil;  
5 -import cn.hutool.core.date.DateUtil;  
6 -import cn.hutool.core.lang.Assert;  
7 -import cn.hutool.core.util.ArrayUtil;  
8 -import cn.hutool.core.util.ObjUtil;  
9 -import cn.hutool.core.util.ObjectUtil;  
10 -import cn.hutool.core.util.StrUtil;  
11 -import cn.iocoder.yudao.framework.common.pojo.PageResult;  
12 -import cn.iocoder.yudao.framework.common.util.date.DateUtils;  
13 -import cn.iocoder.yudao.framework.common.util.json.JsonUtils;  
14 -import cn.iocoder.yudao.framework.common.util.object.ObjectUtils;  
15 -import cn.iocoder.yudao.framework.common.util.object.PageUtils;  
16 -import cn.iocoder.yudao.module.bpm.api.task.dto.BpmProcessInstanceCreateReqDTO;  
17 -import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.model.BpmModelMetaInfoVO;  
18 -import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.model.simple.BpmSimpleModelNodeVO;  
19 -import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance.*;  
20 -import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance.BpmApprovalDetailRespVO.ActivityNodeTask;  
21 -import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.task.BpmTaskRespVO;  
22 -import cn.iocoder.yudao.module.bpm.convert.task.BpmProcessInstanceConvert;  
23 -import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmProcessDefinitionInfoDO;  
24 -import cn.iocoder.yudao.module.bpm.dal.redis.BpmProcessIdRedisDAO;  
25 -import cn.iocoder.yudao.module.bpm.enums.ErrorCodeConstants;  
26 -import cn.iocoder.yudao.module.bpm.enums.definition.BpmModelTypeEnum;  
27 -import cn.iocoder.yudao.module.bpm.enums.definition.BpmSimpleModelNodeTypeEnum;  
28 -import cn.iocoder.yudao.module.bpm.enums.task.BpmProcessInstanceStatusEnum;  
29 -import cn.iocoder.yudao.module.bpm.enums.task.BpmReasonEnum;  
30 -import cn.iocoder.yudao.module.bpm.enums.task.BpmTaskStatusEnum;  
31 -import cn.iocoder.yudao.module.bpm.framework.flowable.core.candidate.BpmTaskCandidateInvoker;  
32 -import cn.iocoder.yudao.module.bpm.framework.flowable.core.enums.BpmTaskCandidateStrategyEnum;  
33 -import cn.iocoder.yudao.module.bpm.framework.flowable.core.enums.BpmnModelConstants;  
34 -import cn.iocoder.yudao.module.bpm.framework.flowable.core.enums.BpmnVariableConstants;  
35 -import cn.iocoder.yudao.module.bpm.framework.flowable.core.event.BpmProcessInstanceEventPublisher;  
36 -import cn.iocoder.yudao.module.bpm.framework.flowable.core.util.BpmHttpRequestUtils;  
37 -import cn.iocoder.yudao.module.bpm.framework.flowable.core.util.BpmnModelUtils;  
38 -import cn.iocoder.yudao.module.bpm.framework.flowable.core.util.FlowableUtils;  
39 -import cn.iocoder.yudao.module.bpm.framework.flowable.core.util.SimpleModelUtils;  
40 -import cn.iocoder.yudao.module.bpm.service.definition.BpmProcessDefinitionService;  
41 -import cn.iocoder.yudao.module.bpm.service.message.BpmMessageService;  
42 -import cn.iocoder.yudao.module.system.api.dept.DeptApi;  
43 -import cn.iocoder.yudao.module.system.api.dept.dto.DeptRespDTO;  
44 -import cn.iocoder.yudao.module.system.api.user.AdminUserApi;  
45 -import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;  
46 -import jakarta.annotation.Resource;  
47 -import jakarta.validation.Valid;  
48 -import lombok.extern.slf4j.Slf4j;  
49 -import org.flowable.bpmn.constants.BpmnXMLConstants;  
50 -import org.flowable.bpmn.model.*;  
51 -import org.flowable.engine.HistoryService;  
52 -import org.flowable.engine.RuntimeService;  
53 -import org.flowable.engine.history.HistoricActivityInstance;  
54 -import org.flowable.engine.history.HistoricProcessInstance;  
55 -import org.flowable.engine.history.HistoricProcessInstanceQuery;  
56 -import org.flowable.engine.repository.ProcessDefinition;  
57 -import org.flowable.engine.runtime.ProcessInstance;  
58 -import org.flowable.engine.runtime.ProcessInstanceBuilder;  
59 -import org.flowable.task.api.Task;  
60 -import org.flowable.task.api.history.HistoricTaskInstance;  
61 -import org.springframework.context.annotation.Lazy;  
62 -import org.springframework.stereotype.Service;  
63 -import org.springframework.transaction.annotation.Transactional;  
64 -import org.springframework.validation.annotation.Validated;  
65 -  
66 -import java.util.*;  
67 -  
68 -import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;  
69 -import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.*;  
70 -import static cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance.BpmApprovalDetailRespVO.ActivityNode;  
71 -import static cn.iocoder.yudao.module.bpm.enums.ErrorCodeConstants.*;  
72 -import static cn.iocoder.yudao.module.bpm.framework.flowable.core.enums.BpmnModelConstants.START_USER_NODE_ID;  
73 -import static cn.iocoder.yudao.module.bpm.framework.flowable.core.util.BpmnModelUtils.parseNodeType;  
74 -import static java.util.Arrays.asList;  
75 -import static java.util.Collections.singletonList;  
76 -import static org.flowable.bpmn.constants.BpmnXMLConstants.*;  
77 -  
78 -/**  
79 - * 流程实例 Service 实现类  
80 - * <p>  
81 - * ProcessDefinition & ProcessInstance & Execution & Task 的关系:  
82 - * 1. <a href="https://blog.csdn.net/bobozai86/article/details/105210414" />  
83 - * <p>  
84 - * HistoricProcessInstance & ProcessInstance 的关系:  
85 - * 1. <a href=" https://my.oschina.net/843294669/blog/71902" />  
86 - * <p>  
87 - * 简单来说,前者 = 历史 + 运行中的流程实例,后者仅是运行中的流程实例  
88 - *  
89 - * @author 芋道源码  
90 - */  
91 -@Service  
92 -@Validated  
93 -@Slf4j  
94 -public class BpmProcessInstanceServiceImpl implements BpmProcessInstanceService {  
95 -  
96 - @Resource  
97 - private RuntimeService runtimeService;  
98 - @Resource  
99 - private HistoryService historyService;  
100 -  
101 - @Resource  
102 - private BpmProcessDefinitionService processDefinitionService;  
103 - @Resource  
104 - @Lazy // 避免循环依赖  
105 - private BpmTaskService taskService;  
106 - @Resource  
107 - private BpmMessageService messageService;  
108 -  
109 - @Resource  
110 - private AdminUserApi adminUserApi;  
111 - @Resource  
112 - private DeptApi deptApi;  
113 -  
114 - @Resource  
115 - private BpmProcessInstanceEventPublisher processInstanceEventPublisher;  
116 -  
117 - @Resource  
118 - private BpmTaskCandidateInvoker taskCandidateInvoker;  
119 -  
120 - @Resource  
121 - private BpmProcessIdRedisDAO processIdRedisDAO;  
122 -  
123 - // ========== Query 查询相关方法 ==========  
124 -  
125 - @Override  
126 - public ProcessInstance getProcessInstance(String id) {  
127 - return runtimeService.createProcessInstanceQuery()  
128 - .includeProcessVariables()  
129 - .processInstanceId(id)  
130 - .singleResult();  
131 - }  
132 -  
133 - @Override  
134 - public List<ProcessInstance> getProcessInstances(Set<String> ids) {  
135 - return runtimeService.createProcessInstanceQuery().processInstanceIds(ids).includeProcessVariables().list();  
136 - }  
137 -  
138 - @Override  
139 - public HistoricProcessInstance getHistoricProcessInstance(String id) {  
140 - return historyService.createHistoricProcessInstanceQuery().processInstanceId(id).includeProcessVariables()  
141 - .singleResult();  
142 - }  
143 -  
144 - @Override  
145 - public List<HistoricProcessInstance> getHistoricProcessInstances(Set<String> ids) {  
146 - return historyService.createHistoricProcessInstanceQuery().processInstanceIds(ids).includeProcessVariables()  
147 - .list();  
148 - }  
149 -  
150 - private Map<String, String> getFormFieldsPermission(BpmnModel bpmnModel,  
151 - String activityId, String taskId) {  
152 - // 1. 获取流程活动编号。流程活动 Id 为空事,从流程任务中获取流程活动 Id  
153 - if (StrUtil.isEmpty(activityId) && StrUtil.isNotEmpty(taskId)) {  
154 - activityId = Optional.ofNullable(taskService.getHistoricTask(taskId))  
155 - .map(HistoricTaskInstance::getTaskDefinitionKey).orElse(null);  
156 - }  
157 - if (StrUtil.isEmpty(activityId)) {  
158 - return null;  
159 - }  
160 -  
161 - // 2. 从 BpmnModel 中解析表单字段权限  
162 - return BpmnModelUtils.parseFormFieldsPermission(bpmnModel, activityId);  
163 - }  
164 -  
165 - @Override  
166 - public BpmApprovalDetailRespVO getApprovalDetail(Long loginUserId, BpmApprovalDetailReqVO reqVO) {  
167 - // 1.1 从 reqVO 中,读取公共变量  
168 - Long startUserId = loginUserId; // 流程发起人  
169 - HistoricProcessInstance historicProcessInstance = null; // 流程实例  
170 - Integer processInstanceStatus = BpmProcessInstanceStatusEnum.NOT_START.getStatus(); // 流程状态  
171 - Map<String, Object> processVariables = new HashMap<>(); // 流程变量  
172 - // 1.2 如果是流程已发起的场景,则使用流程实例的数据  
173 - if (reqVO.getProcessInstanceId() != null) {  
174 - historicProcessInstance = getHistoricProcessInstance(reqVO.getProcessInstanceId());  
175 - if (historicProcessInstance == null) {  
176 - throw exception(ErrorCodeConstants.PROCESS_INSTANCE_NOT_EXISTS);  
177 - }  
178 - startUserId = Long.valueOf(historicProcessInstance.getStartUserId());  
179 - processInstanceStatus = FlowableUtils.getProcessInstanceStatus(historicProcessInstance);  
180 - // 合并 DB 和前端传递的流量变量,以前端的为主  
181 - if (CollUtil.isNotEmpty(historicProcessInstance.getProcessVariables())) {  
182 - processVariables.putAll(historicProcessInstance.getProcessVariables());  
183 - }  
184 - }  
185 - if (CollUtil.isNotEmpty(reqVO.getProcessVariables())) {  
186 - processVariables.putAll(reqVO.getProcessVariables());  
187 - }  
188 - // 1.3 读取其它相关数据  
189 - ProcessDefinition processDefinition = processDefinitionService.getProcessDefinition(  
190 - historicProcessInstance != null ? historicProcessInstance.getProcessDefinitionId()  
191 - : reqVO.getProcessDefinitionId());  
192 - BpmProcessDefinitionInfoDO processDefinitionInfo = processDefinitionService  
193 - .getProcessDefinitionInfo(processDefinition.getId());  
194 - BpmnModel bpmnModel = processDefinitionService.getProcessDefinitionBpmnModel(processDefinition.getId());  
195 -  
196 - // 2.1 已结束 + 进行中的活动节点  
197 - List<ActivityNode> endActivityNodes = null; // 已结束的审批信息  
198 - List<ActivityNode> runActivityNodes = null; // 进行中的审批信息  
199 - List<HistoricActivityInstance> activities = null; // 流程实例列表  
200 - if (reqVO.getProcessInstanceId() != null) {  
201 - activities = taskService.getActivityListByProcessInstanceId(reqVO.getProcessInstanceId());  
202 - List<HistoricTaskInstance> tasks = taskService.getTaskListByProcessInstanceId(reqVO.getProcessInstanceId(),  
203 - true);  
204 - endActivityNodes = getEndActivityNodeList(startUserId, bpmnModel, processDefinitionInfo,  
205 - historicProcessInstance, processInstanceStatus, activities, tasks);  
206 - runActivityNodes = getRunApproveNodeList(startUserId, bpmnModel, processDefinition, processVariables,  
207 - activities, tasks);  
208 - }  
209 -  
210 - // 2.2 流程已经结束,直接 return,无需预测  
211 - if (BpmProcessInstanceStatusEnum.isProcessEndStatus(processInstanceStatus)) {  
212 - return buildApprovalDetail(reqVO, bpmnModel, processDefinition, processDefinitionInfo,  
213 - historicProcessInstance,  
214 - processInstanceStatus, endActivityNodes, runActivityNodes, null, null);  
215 - }  
216 -  
217 - // 3.1 计算当前登录用户的待办任务  
218 - BpmTaskRespVO todoTask = taskService.getTodoTask(loginUserId, reqVO.getTaskId(), reqVO.getProcessInstanceId());  
219 - // 3.2 预测未运行节点的审批信息  
220 - List<ActivityNode> simulateActivityNodes = getSimulateApproveNodeList(startUserId, bpmnModel,  
221 - processDefinitionInfo,  
222 - processVariables, activities);  
223 - // 3.3 如果是发起动作,activityId 为开始节点,不校验审批人自选节点  
224 - if (ObjUtil.equals(reqVO.getActivityId(), BpmnModelConstants.START_USER_NODE_ID)) {  
225 - simulateActivityNodes.removeIf(node ->  
226 - BpmTaskCandidateStrategyEnum.APPROVE_USER_SELECT.getStrategy().equals(node.getCandidateStrategy()));  
227 - }  
228 -  
229 - // 4. 拼接最终数据  
230 - return buildApprovalDetail(reqVO, bpmnModel, processDefinition, processDefinitionInfo, historicProcessInstance,  
231 - processInstanceStatus, endActivityNodes, runActivityNodes, simulateActivityNodes, todoTask);  
232 - }  
233 -  
234 - @Override  
235 - public List<ActivityNode> getNextApprovalNodes(Long loginUserId, BpmApprovalDetailReqVO reqVO) {  
236 - // 1.1 校验任务存在,且是当前用户的  
237 - Task task = taskService.validateTask(loginUserId, reqVO.getTaskId());  
238 - // 1.2 校验流程实例存在  
239 - ProcessInstance instance = getProcessInstance(task.getProcessInstanceId());  
240 - if (instance == null) {  
241 - throw exception(PROCESS_INSTANCE_NOT_EXISTS);  
242 - }  
243 - HistoricProcessInstance historicProcessInstance = getHistoricProcessInstance(task.getProcessInstanceId());  
244 - if (historicProcessInstance == null) {  
245 - throw exception(ErrorCodeConstants.PROCESS_INSTANCE_NOT_EXISTS);  
246 - }  
247 - // 1.3 校验BpmnModel  
248 - BpmnModel bpmnModel = processDefinitionService.getProcessDefinitionBpmnModel(task.getProcessDefinitionId());  
249 - if (bpmnModel == null) {  
250 - return null;  
251 - }  
252 -  
253 - // 2. 设置流程变量  
254 - Map<String, Object> processVariables = new HashMap<>();  
255 - // 2.1 获取历史中流程变量  
256 - if (CollUtil.isNotEmpty(historicProcessInstance.getProcessVariables())) {  
257 - processVariables.putAll(historicProcessInstance.getProcessVariables());  
258 - }  
259 - // 2.2 合并前端传递的流程变量,以前端为准  
260 - if (CollUtil.isNotEmpty(reqVO.getProcessVariables())) {  
261 - processVariables.putAll(reqVO.getProcessVariables());  
262 - }  
263 -  
264 - // 3. 获取下一个将要执行的节点集合  
265 - FlowElement flowElement = bpmnModel.getFlowElement(task.getTaskDefinitionKey());  
266 - List<FlowNode> nextFlowNodes = BpmnModelUtils.getNextFlowNodes(flowElement, bpmnModel, processVariables);  
267 - List<ActivityNode> nextActivityNodes = convertList(nextFlowNodes, node -> new ActivityNode().setId(node.getId())  
268 - .setName(node.getName()).setNodeType(BpmSimpleModelNodeTypeEnum.APPROVE_NODE.getType())  
269 - .setStatus(BpmTaskStatusEnum.RUNNING.getStatus())  
270 - .setCandidateStrategy(BpmnModelUtils.parseCandidateStrategy(node))  
271 - .setCandidateUserIds(getTaskCandidateUserList(bpmnModel, node.getId(),  
272 - loginUserId, historicProcessInstance.getProcessDefinitionId(), processVariables)));  
273 - if (CollUtil.isNotEmpty(nextActivityNodes)) {  
274 - return nextActivityNodes;  
275 - }  
276 -  
277 - // 4. 拼接基础信息  
278 - Map<Long, AdminUserRespDTO> userMap = adminUserApi.getUserMap(  
279 - convertSetByFlatMap(nextActivityNodes, ActivityNode::getCandidateUserIds, Collection::stream));  
280 - Map<Long, DeptRespDTO> deptMap = deptApi.getDeptMap(convertSet(userMap.values(), AdminUserRespDTO::getDeptId));  
281 - nextActivityNodes.forEach(node -> node.setCandidateUsers(convertList(node.getCandidateUserIds(), userId -> {  
282 - AdminUserRespDTO user = userMap.get(userId);  
283 - if (user != null) {  
284 - return BpmProcessInstanceConvert.INSTANCE.buildUser(userId, userMap, deptMap);  
285 - }  
286 - return null;  
287 - })));  
288 - return nextActivityNodes;  
289 - }  
290 -  
291 - @Override  
292 - @SuppressWarnings("unchecked")  
293 - public PageResult<HistoricProcessInstance> getProcessInstancePage(Long userId,  
294 - BpmProcessInstancePageReqVO pageReqVO) {  
295 - // 1. 构建查询条件  
296 - HistoricProcessInstanceQuery processInstanceQuery = historyService.createHistoricProcessInstanceQuery()  
297 - .includeProcessVariables()  
298 - .processInstanceTenantId(FlowableUtils.getTenantId())  
299 - .orderByProcessInstanceStartTime().desc();  
300 - if (userId != null) { // 【我的流程】菜单时,需要传递该字段  
301 - processInstanceQuery.startedBy(String.valueOf(userId));  
302 - } else if (pageReqVO.getStartUserId() != null) { // 【管理流程】菜单时,才会传递该字段  
303 - processInstanceQuery.startedBy(String.valueOf(pageReqVO.getStartUserId()));  
304 - }  
305 - if (StrUtil.isNotEmpty(pageReqVO.getName())) {  
306 - processInstanceQuery.processInstanceNameLike("%" + pageReqVO.getName() + "%");  
307 - }  
308 - if (StrUtil.isNotEmpty(pageReqVO.getProcessDefinitionKey())) {  
309 - processInstanceQuery.processDefinitionKey(pageReqVO.getProcessDefinitionKey());  
310 - }  
311 - if (StrUtil.isNotEmpty(pageReqVO.getCategory())) {  
312 - processInstanceQuery.processDefinitionCategory(pageReqVO.getCategory());  
313 - }  
314 - if (pageReqVO.getStatus() != null) {  
315 - processInstanceQuery.variableValueEquals(BpmnVariableConstants.PROCESS_INSTANCE_VARIABLE_STATUS,  
316 - pageReqVO.getStatus());  
317 - }  
318 - if (ArrayUtil.isNotEmpty(pageReqVO.getCreateTime())) {  
319 - processInstanceQuery.startedAfter(DateUtils.of(pageReqVO.getCreateTime()[0]));  
320 - processInstanceQuery.startedBefore(DateUtils.of(pageReqVO.getCreateTime()[1]));  
321 - }  
322 - if (ArrayUtil.isNotEmpty(pageReqVO.getEndTime())) {  
323 - processInstanceQuery.finishedAfter(DateUtils.of(pageReqVO.getEndTime()[0]));  
324 - processInstanceQuery.finishedBefore(DateUtils.of(pageReqVO.getEndTime()[1]));  
325 - }  
326 - // 表单字段查询  
327 - Map<String, Object> formFieldsParams = JsonUtils.parseObject(pageReqVO.getFormFieldsParams(), Map.class);  
328 - if (CollUtil.isNotEmpty(formFieldsParams)) {  
329 - formFieldsParams.forEach((key, value) -> {  
330 - if (StrUtil.isEmpty(String.valueOf(value))) {  
331 - return;  
332 - }  
333 - // TODO @lesan:应支持多种类型的查询方式,目前只有字符串全等  
334 - processInstanceQuery.variableValueEquals(key, value);  
335 - });  
336 - }  
337 -  
338 - // 2.1 查询数量  
339 - long processInstanceCount = processInstanceQuery.count();  
340 - if (processInstanceCount == 0) {  
341 - return PageResult.empty(processInstanceCount);  
342 - }  
343 - // 2.2 查询列表  
344 - List<HistoricProcessInstance> processInstanceList = processInstanceQuery.listPage(PageUtils.getStart(pageReqVO),  
345 - pageReqVO.getPageSize());  
346 - return new PageResult<>(processInstanceList, processInstanceCount);  
347 - }  
348 -  
349 - /**  
350 - * 拼接审批详情的最终数据  
351 - * <p>  
352 - * 主要是,拼接审批人的用户信息、部门信息  
353 - */  
354 - private BpmApprovalDetailRespVO buildApprovalDetail(BpmApprovalDetailReqVO reqVO,  
355 - BpmnModel bpmnModel,  
356 - ProcessDefinition processDefinition,  
357 - BpmProcessDefinitionInfoDO processDefinitionInfo,  
358 - HistoricProcessInstance processInstance,  
359 - Integer processInstanceStatus,  
360 - List<ActivityNode> endApprovalNodeInfos,  
361 - List<ActivityNode> runningApprovalNodeInfos,  
362 - List<ActivityNode> simulateApprovalNodeInfos,  
363 - BpmTaskRespVO todoTask) {  
364 - // 1. 获取所有需要读取用户信息的 userIds  
365 - List<ActivityNode> approveNodes = newArrayList(  
366 - asList(endApprovalNodeInfos, runningApprovalNodeInfos, simulateApprovalNodeInfos));  
367 - Set<Long> userIds = BpmProcessInstanceConvert.INSTANCE.parseUserIds(processInstance, approveNodes, todoTask);  
368 - Map<Long, AdminUserRespDTO> userMap = adminUserApi.getUserMap(userIds);  
369 - Map<Long, DeptRespDTO> deptMap = deptApi.getDeptMap(convertSet(userMap.values(), AdminUserRespDTO::getDeptId));  
370 -  
371 - // 2. 表单权限  
372 - String taskId = reqVO.getTaskId() == null && todoTask != null ? todoTask.getId() : reqVO.getTaskId();  
373 - Map<String, String> formFieldsPermission = getFormFieldsPermission(bpmnModel, reqVO.getActivityId(), taskId);  
374 -  
375 - // 3. 拼接数据  
376 - return BpmProcessInstanceConvert.INSTANCE.buildApprovalDetail(bpmnModel, processDefinition,  
377 - processDefinitionInfo, processInstance,  
378 - processInstanceStatus, approveNodes, todoTask, formFieldsPermission, userMap, deptMap);  
379 - }  
380 -  
381 - /**  
382 - * 获得【已结束】的活动节点们  
383 - */  
384 - private List<ActivityNode> getEndActivityNodeList(Long startUserId, BpmnModel bpmnModel,  
385 - BpmProcessDefinitionInfoDO processDefinitionInfo,  
386 - HistoricProcessInstance historicProcessInstance, Integer processInstanceStatus,  
387 - List<HistoricActivityInstance> activities, List<HistoricTaskInstance> tasks) {  
388 - // 遍历 tasks 列表,只处理已结束的 UserTask  
389 - // 为什么不通过 activities 呢?因为,加签场景下,它只存在于 tasks,没有 activities,导致如果遍历 activities 的话,它无法成为一个节点  
390 - List<HistoricTaskInstance> endTasks = filterList(tasks, task -> task.getEndTime() != null);  
391 - List<ActivityNode> approvalNodes = convertList(endTasks, task -> {  
392 - FlowElement flowNode = BpmnModelUtils.getFlowElementById(bpmnModel, task.getTaskDefinitionKey());  
393 - ActivityNode activityNode = new ActivityNode().setId(task.getTaskDefinitionKey()).setName(task.getName())  
394 - .setNodeType(START_USER_NODE_ID.equals(task.getTaskDefinitionKey())  
395 - ? BpmSimpleModelNodeTypeEnum.START_USER_NODE.getType()  
396 - : ObjUtil.defaultIfNull(parseNodeType(flowNode), // 目的:解决“办理节点”的识别  
397 - BpmSimpleModelNodeTypeEnum.APPROVE_NODE.getType()))  
398 - .setStatus(FlowableUtils.getTaskStatus(task))  
399 - .setCandidateStrategy(BpmnModelUtils.parseCandidateStrategy(flowNode))  
400 - .setStartTime(DateUtils.of(task.getCreateTime())).setEndTime(DateUtils.of(task.getEndTime()))  
401 - .setTasks(singletonList(BpmProcessInstanceConvert.INSTANCE.buildApprovalTaskInfo(task)));  
402 - // 如果是取消状态,则跳过  
403 - if (BpmTaskStatusEnum.isCancelStatus(activityNode.getStatus())) {  
404 - return null;  
405 - }  
406 - return activityNode;  
407 - });  
408 -  
409 - // 遍历 activities,只处理已结束的 StartEvent、EndEvent  
410 - List<HistoricActivityInstance> endActivities = filterList(activities, activity -> activity.getEndTime() != null  
411 - && (StrUtil.equalsAny(activity.getActivityType(), ELEMENT_EVENT_START, ELEMENT_CALL_ACTIVITY, ELEMENT_EVENT_END)));  
412 - endActivities.forEach(activity -> {  
413 - // StartEvent:只处理 BPMN 的场景。因为,SIMPLE 情况下,已经有 START_USER_NODE 节点  
414 - if (ELEMENT_EVENT_START.equals(activity.getActivityType())  
415 - && BpmModelTypeEnum.BPMN.getType().equals(processDefinitionInfo.getModelType())) {  
416 - ActivityNodeTask startTask = new ActivityNodeTask().setId(BpmnModelConstants.START_USER_NODE_ID)  
417 - .setAssignee(startUserId).setStatus(BpmTaskStatusEnum.APPROVE.getStatus());  
418 - ActivityNode startNode = new ActivityNode().setId(startTask.getId())  
419 - .setName(BpmSimpleModelNodeTypeEnum.START_USER_NODE.getName())  
420 - .setNodeType(BpmSimpleModelNodeTypeEnum.START_USER_NODE.getType())  
421 - .setStatus(startTask.getStatus()).setTasks(ListUtil.of(startTask))  
422 - .setStartTime(DateUtils.of(activity.getStartTime()))  
423 - .setEndTime(DateUtils.of(activity.getEndTime()));  
424 - approvalNodes.add(0, startNode);  
425 - return;  
426 - }  
427 - // EndEvent  
428 - if (ELEMENT_EVENT_END.equals(activity.getActivityType())) {  
429 - if (BpmProcessInstanceStatusEnum.isRejectStatus(processInstanceStatus)) {  
430 - // 拒绝情况下,不需要展示 EndEvent 结束节点。原因是:前端已经展示 x 效果,无需重复展示  
431 - return;  
432 - }  
433 - ActivityNode endNode = new ActivityNode().setId(activity.getId())  
434 - .setName(BpmSimpleModelNodeTypeEnum.END_NODE.getName())  
435 - .setNodeType(BpmSimpleModelNodeTypeEnum.END_NODE.getType()).setStatus(processInstanceStatus)  
436 - .setStartTime(DateUtils.of(activity.getStartTime()))  
437 - .setEndTime(DateUtils.of(activity.getEndTime()));  
438 - String reason = FlowableUtils.getProcessInstanceReason(historicProcessInstance);  
439 - if (StrUtil.isNotEmpty(reason)) {  
440 - endNode.setTasks(singletonList(new ActivityNodeTask().setId(endNode.getId())  
441 - .setStatus(endNode.getStatus()).setReason(reason)));  
442 - }  
443 - approvalNodes.add(endNode);  
444 - }  
445 - // CallActivity  
446 - if (ELEMENT_CALL_ACTIVITY.equals(activity.getActivityType())) {  
447 - ActivityNode callActivity = new ActivityNode().setId(activity.getId())  
448 - .setName(BpmSimpleModelNodeTypeEnum.CHILD_PROCESS.getName())  
449 - .setNodeType(BpmSimpleModelNodeTypeEnum.CHILD_PROCESS.getType()).setStatus(processInstanceStatus)  
450 - .setStartTime(DateUtils.of(activity.getStartTime()))  
451 - .setEndTime(DateUtils.of(activity.getEndTime()))  
452 - .setProcessInstanceId(activity.getProcessInstanceId());  
453 - approvalNodes.add(callActivity);  
454 - }  
455 - });  
456 -  
457 - // 按照时间排序  
458 - approvalNodes.sort(Comparator.comparing(ActivityNode::getStartTime));  
459 - return approvalNodes;  
460 - }  
461 -  
462 - /**  
463 - * 获得【进行中】的活动节点们  
464 - */  
465 - private List<ActivityNode> getRunApproveNodeList(Long startUserId,  
466 - BpmnModel bpmnModel,  
467 - ProcessDefinition processDefinition,  
468 - Map<String, Object> processVariables,  
469 - List<HistoricActivityInstance> activities,  
470 - List<HistoricTaskInstance> tasks) {  
471 - // 构建运行中的任务、子流程,基于 activityId 分组  
472 - List<HistoricActivityInstance> runActivities = filterList(activities, activity -> activity.getEndTime() == null  
473 - && (StrUtil.equalsAny(activity.getActivityType(), ELEMENT_TASK_USER, ELEMENT_CALL_ACTIVITY)));  
474 - Map<String, List<HistoricActivityInstance>> runningTaskMap = convertMultiMap(runActivities,  
475 - HistoricActivityInstance::getActivityId);  
476 -  
477 - // 按照 activityId 分组,构建 ApprovalNodeInfo 节点  
478 - Map<String, HistoricTaskInstance> taskMap = convertMap(tasks, HistoricTaskInstance::getId);  
479 - return convertList(runningTaskMap.entrySet(), entry -> {  
480 - String activityId = entry.getKey();  
481 - List<HistoricActivityInstance> taskActivities = entry.getValue();  
482 - // 构建活动节点  
483 - FlowElement flowNode = BpmnModelUtils.getFlowElementById(bpmnModel, activityId);  
484 - HistoricActivityInstance firstActivity = CollUtil.getFirst(taskActivities); // 取第一个任务,会签/或签的任务,开始时间相同  
485 - ActivityNode activityNode = new ActivityNode().setId(firstActivity.getActivityId())  
486 - .setName(firstActivity.getActivityName())  
487 - .setNodeType(ObjUtil.defaultIfNull(parseNodeType(flowNode), // 目的:解决“办理节点”和"子流程"的识别  
488 - BpmSimpleModelNodeTypeEnum.APPROVE_NODE.getType()))  
489 - .setStatus(BpmTaskStatusEnum.RUNNING.getStatus())  
490 - .setCandidateStrategy(BpmnModelUtils.parseCandidateStrategy(flowNode))  
491 - .setStartTime(DateUtils.of(CollUtil.getFirst(taskActivities).getStartTime()))  
492 - .setTasks(new ArrayList<>());  
493 - // 处理每个任务的 tasks 属性  
494 - for (HistoricActivityInstance activity : taskActivities) {  
495 - HistoricTaskInstance task = taskMap.get(activity.getTaskId());  
496 - // 特殊情况:子流程节点 ChildProcess 仅存在于 activity 中,并且没有自身的 task,需要跳过执行  
497 - // TODO @芋艿:后续看看怎么优化!  
498 - if (task == null) {  
499 - continue;  
500 - }  
501 - activityNode.getTasks().add(BpmProcessInstanceConvert.INSTANCE.buildApprovalTaskInfo(task));  
502 - // 加签子任务,需要过滤掉已经完成的加签子任务  
503 - List<HistoricTaskInstance> childrenTasks = filterList(  
504 - taskService.getAllChildrenTaskListByParentTaskId(activity.getTaskId(), tasks),  
505 - childTask -> childTask.getEndTime() == null);  
506 - if (CollUtil.isNotEmpty(childrenTasks)) {  
507 - activityNode.getTasks().addAll(  
508 - convertList(childrenTasks, BpmProcessInstanceConvert.INSTANCE::buildApprovalTaskInfo));  
509 - }  
510 - }  
511 - // 处理每个任务的 candidateUsers 属性:如果是依次审批,需要预测它的后续审批人。因为 Task 是审批完一个,创建一个新的 Task  
512 - if (BpmnModelUtils.isSequentialUserTask(flowNode)) {  
513 - List<Long> candidateUserIds = getTaskCandidateUserList(bpmnModel, flowNode.getId(),  
514 - startUserId, processDefinition.getId(), processVariables);  
515 - // 截取当前审批人位置后面的候选人,不包含当前审批人  
516 - ActivityNodeTask approvalTaskInfo = CollUtil.getFirst(activityNode.getTasks());  
517 - Assert.notNull(approvalTaskInfo, "任务不能为空");  
518 - int index = CollUtil.indexOf(candidateUserIds,  
519 - userId -> ObjectUtils.equalsAny(userId, approvalTaskInfo.getOwner(),  
520 - approvalTaskInfo.getAssignee())); // 委派或者向前加签情况,需要先比较 owner  
521 - activityNode.setCandidateUserIds(CollUtil.sub(candidateUserIds, index + 1, candidateUserIds.size()));  
522 - }  
523 - if (BpmSimpleModelNodeTypeEnum.CHILD_PROCESS.getType().equals(activityNode.getNodeType())) {  
524 - activityNode.setProcessInstanceId(firstActivity.getProcessInstanceId());  
525 - }  
526 - return activityNode;  
527 - });  
528 - }  
529 -  
530 - /**  
531 - * 获得【预测(未来)】的活动节点们  
532 - */  
533 - private List<ActivityNode> getSimulateApproveNodeList(Long startUserId, BpmnModel bpmnModel,  
534 - BpmProcessDefinitionInfoDO processDefinitionInfo,  
535 - Map<String, Object> processVariables,  
536 - List<HistoricActivityInstance> activities) {  
537 - // TODO @芋艿:【可优化】在驳回场景下,未来的预测准确性不高。原因是,驳回后,HistoricActivityInstance  
538 - // 包括了历史的操作,不是只有 startEvent 到当前节点的记录  
539 - Set<String> runActivityIds = convertSet(activities, HistoricActivityInstance::getActivityId);  
540 - // 情况一:BPMN 设计器  
541 - if (Objects.equals(BpmModelTypeEnum.BPMN.getType(), processDefinitionInfo.getModelType())) {  
542 - List<FlowElement> flowElements = BpmnModelUtils.simulateProcess(bpmnModel, processVariables);  
543 - return convertList(flowElements, flowElement -> buildNotRunApproveNodeForBpmn(startUserId, bpmnModel,  
544 - processDefinitionInfo, processVariables, flowElement, runActivityIds));  
545 - }  
546 - // 情况二:SIMPLE 设计器  
547 - if (Objects.equals(BpmModelTypeEnum.SIMPLE.getType(), processDefinitionInfo.getModelType())) {  
548 - BpmSimpleModelNodeVO simpleModel = JsonUtils.parseObject(processDefinitionInfo.getSimpleModel(),  
549 - BpmSimpleModelNodeVO.class);  
550 - List<BpmSimpleModelNodeVO> simpleNodes = SimpleModelUtils.simulateProcess(simpleModel, processVariables);  
551 - return convertList(simpleNodes, simpleNode -> buildNotRunApproveNodeForSimple(startUserId, bpmnModel,  
552 - processDefinitionInfo, processVariables, simpleNode, runActivityIds));  
553 - }  
554 - throw new IllegalArgumentException("未知设计器类型:" + processDefinitionInfo.getModelType());  
555 - }  
556 -  
557 - private ActivityNode buildNotRunApproveNodeForSimple(Long startUserId, BpmnModel bpmnModel,  
558 - BpmProcessDefinitionInfoDO processDefinitionInfo, Map<String, Object> processVariables,  
559 - BpmSimpleModelNodeVO node, Set<String> runActivityIds) {  
560 - // TODO @芋艿:【可优化】在驳回场景下,未来的预测准确性不高。原因是,驳回后,HistoricActivityInstance  
561 - // 包括了历史的操作,不是只有 startEvent 到当前节点的记录  
562 - if (runActivityIds.contains(node.getId())) {  
563 - return null;  
564 - }  
565 -  
566 - ActivityNode activityNode = new ActivityNode().setId(node.getId()).setName(node.getName())  
567 - .setNodeType(node.getType()).setCandidateStrategy(node.getCandidateStrategy())  
568 - .setStatus(BpmTaskStatusEnum.NOT_START.getStatus());  
569 -  
570 - // 1. 开始节点/审批节点  
571 - if (ObjectUtils.equalsAny(node.getType(),  
572 - BpmSimpleModelNodeTypeEnum.START_USER_NODE.getType(),  
573 - BpmSimpleModelNodeTypeEnum.APPROVE_NODE.getType(),  
574 - BpmSimpleModelNodeTypeEnum.TRANSACTOR_NODE.getType())) {  
575 - List<Long> candidateUserIds = getTaskCandidateUserList(bpmnModel, node.getId(),  
576 - startUserId, processDefinitionInfo.getProcessDefinitionId(), processVariables);  
577 - activityNode.setCandidateUserIds(candidateUserIds);  
578 - return activityNode;  
579 - }  
580 -  
581 - // 2. 结束节点  
582 - if (BpmSimpleModelNodeTypeEnum.END_NODE.getType().equals(node.getType())) {  
583 - return activityNode;  
584 - }  
585 -  
586 - // 3. 抄送节点  
587 - if (CollUtil.isEmpty(runActivityIds) && // 流程发起时:需要展示抄送节点,用于选择抄送人  
588 - BpmSimpleModelNodeTypeEnum.COPY_NODE.getType().equals(node.getType())) {  
589 - List<Long> candidateUserIds = getTaskCandidateUserList(bpmnModel, node.getId(),  
590 - startUserId, processDefinitionInfo.getProcessDefinitionId(), processVariables);  
591 - activityNode.setCandidateUserIds(candidateUserIds);  
592 - return activityNode;  
593 - }  
594 -  
595 - // 4. 子流程节点  
596 - if (BpmSimpleModelNodeTypeEnum.CHILD_PROCESS.getType().equals(node.getType())) {  
597 - return activityNode;  
598 - }  
599 - return null;  
600 - }  
601 -  
602 - private ActivityNode buildNotRunApproveNodeForBpmn(Long startUserId, BpmnModel bpmnModel,  
603 - BpmProcessDefinitionInfoDO processDefinitionInfo, Map<String, Object> processVariables,  
604 - FlowElement node, Set<String> runActivityIds) {  
605 - if (runActivityIds.contains(node.getId())) {  
606 - return null;  
607 - }  
608 - ActivityNode activityNode = new ActivityNode().setId(node.getId())  
609 - .setStatus(BpmTaskStatusEnum.NOT_START.getStatus());  
610 -  
611 - // 1. 开始节点  
612 - if (node instanceof StartEvent) {  
613 - return activityNode.setName(BpmSimpleModelNodeTypeEnum.START_USER_NODE.getName())  
614 - .setNodeType(BpmSimpleModelNodeTypeEnum.START_USER_NODE.getType());  
615 - }  
616 -  
617 - // 2. 审批节点  
618 - if (node instanceof UserTask) {  
619 - List<Long> candidateUserIds = getTaskCandidateUserList(bpmnModel, node.getId(),  
620 - startUserId, processDefinitionInfo.getProcessDefinitionId(), processVariables);  
621 - return activityNode.setName(node.getName()).setNodeType(BpmSimpleModelNodeTypeEnum.APPROVE_NODE.getType())  
622 - .setCandidateStrategy(BpmnModelUtils.parseCandidateStrategy(node))  
623 - .setCandidateUserIds(candidateUserIds);  
624 - }  
625 -  
626 - // 3. 结束节点  
627 - if (node instanceof EndEvent) {  
628 - return activityNode.setName(BpmSimpleModelNodeTypeEnum.END_NODE.getName())  
629 - .setNodeType(BpmSimpleModelNodeTypeEnum.END_NODE.getType());  
630 - }  
631 - return null;  
632 - }  
633 -  
634 - private List<Long> getTaskCandidateUserList(BpmnModel bpmnModel, String activityId,  
635 - Long startUserId, String processDefinitionId, Map<String, Object> processVariables) {  
636 - Set<Long> userIds = taskCandidateInvoker.calculateUsersByActivity(bpmnModel, activityId,  
637 - startUserId, processDefinitionId, processVariables);  
638 - return new ArrayList<>(userIds);  
639 - }  
640 -  
641 - @Override  
642 - public BpmProcessInstanceBpmnModelViewRespVO getProcessInstanceBpmnModelView(String id) {  
643 - // 1.1 获得流程实例  
644 - HistoricProcessInstance processInstance = getHistoricProcessInstance(id);  
645 - if (processInstance == null) {  
646 - return null;  
647 - }  
648 - // 1.2 获得流程定义  
649 - BpmnModel bpmnModel = processDefinitionService  
650 - .getProcessDefinitionBpmnModel(processInstance.getProcessDefinitionId());  
651 - if (bpmnModel == null) {  
652 - return null;  
653 - }  
654 - BpmSimpleModelNodeVO simpleModel = null;  
655 - BpmProcessDefinitionInfoDO processDefinitionInfo = processDefinitionService.getProcessDefinitionInfo(  
656 - processInstance.getProcessDefinitionId());  
657 - if (processDefinitionInfo != null  
658 - && BpmModelTypeEnum.SIMPLE.getType().equals(processDefinitionInfo.getModelType())) {  
659 - simpleModel = JsonUtils.parseObject(processDefinitionInfo.getSimpleModel(), BpmSimpleModelNodeVO.class);  
660 - }  
661 - // 1.3 获得流程实例对应的活动实例列表 + 任务列表  
662 - List<HistoricActivityInstance> activities = taskService.getActivityListByProcessInstanceId(id);  
663 - List<HistoricTaskInstance> tasks = taskService.getTaskListByProcessInstanceId(id, true);  
664 -  
665 - // 2.1 拼接进度信息  
666 - Set<String> unfinishedTaskActivityIds = convertSet(activities, HistoricActivityInstance::getActivityId,  
667 - activityInstance -> activityInstance.getEndTime() == null);  
668 - Set<String> finishedTaskActivityIds = convertSet(activities, HistoricActivityInstance::getActivityId,  
669 - activityInstance -> activityInstance.getEndTime() != null  
670 - && ObjectUtil.notEqual(activityInstance.getActivityType(),  
671 - BpmnXMLConstants.ELEMENT_SEQUENCE_FLOW));  
672 - Set<String> finishedSequenceFlowActivityIds = convertSet(activities, HistoricActivityInstance::getActivityId,  
673 - activityInstance -> activityInstance.getEndTime() != null  
674 - && ObjectUtil.equals(activityInstance.getActivityType(),  
675 - BpmnXMLConstants.ELEMENT_SEQUENCE_FLOW));  
676 - // 特殊:会签情况下,会有部分已完成(审批)、部分未完成(待审批),此时需要 finishedTaskActivityIds 移除掉  
677 - finishedTaskActivityIds.removeAll(unfinishedTaskActivityIds);  
678 - // 特殊:如果流程实例被拒绝,则需要计算是哪个活动节点。  
679 - // 注意,只取最后一个。因为会存在多次拒绝的情况,拒绝驳回到指定节点  
680 - Set<String> rejectTaskActivityIds = CollUtil.newHashSet();  
681 - if (BpmProcessInstanceStatusEnum.isRejectStatus(FlowableUtils.getProcessInstanceStatus(processInstance))) {  
682 - tasks.stream()  
683 - .filter(task -> BpmTaskStatusEnum.isRejectStatus(FlowableUtils.getTaskStatus(task)))  
684 - .max(Comparator.comparing(HistoricTaskInstance::getEndTime))  
685 - .ifPresent(reject -> rejectTaskActivityIds.add(reject.getTaskDefinitionKey()));  
686 - finishedTaskActivityIds.removeAll(rejectTaskActivityIds);  
687 - }  
688 -  
689 - // 2.2 拼接基础信息  
690 - Set<Long> userIds = BpmProcessInstanceConvert.INSTANCE.parseUserIds02(processInstance, tasks);  
691 - Map<Long, AdminUserRespDTO> userMap = adminUserApi.getUserMap(userIds);  
692 - Map<Long, DeptRespDTO> deptMap = deptApi.getDeptMap(convertSet(userMap.values(), AdminUserRespDTO::getDeptId));  
693 - return BpmProcessInstanceConvert.INSTANCE.buildProcessInstanceBpmnModelView(processInstance, tasks, bpmnModel,  
694 - simpleModel,  
695 - unfinishedTaskActivityIds, finishedTaskActivityIds, finishedSequenceFlowActivityIds,  
696 - rejectTaskActivityIds,  
697 - userMap, deptMap);  
698 - }  
699 -  
700 - // ========== Update 写入相关方法 ==========  
701 -  
702 - @Override  
703 - @Transactional(rollbackFor = Exception.class)  
704 - public String createProcessInstance(Long userId, @Valid BpmProcessInstanceCreateReqVO createReqVO) {  
705 - // 获得流程定义  
706 - ProcessDefinition definition = processDefinitionService  
707 - .getProcessDefinition(createReqVO.getProcessDefinitionId());  
708 - // 发起流程  
709 - return createProcessInstance0(userId, definition, createReqVO.getVariables(), null,  
710 - createReqVO.getStartUserSelectAssignees());  
711 - }  
712 -  
713 - @Override  
714 - public String createProcessInstance(Long userId, @Valid BpmProcessInstanceCreateReqDTO createReqDTO) {  
715 - return FlowableUtils.executeAuthenticatedUserId(userId, () -> {  
716 - // 获得流程定义  
717 - ProcessDefinition definition = processDefinitionService  
718 - .getActiveProcessDefinition(createReqDTO.getProcessDefinitionKey());  
719 - // 发起流程  
720 - return createProcessInstance0(userId, definition, createReqDTO.getVariables(),  
721 - createReqDTO.getBusinessKey(),  
722 - createReqDTO.getStartUserSelectAssignees());  
723 - });  
724 - }  
725 -  
726 - private String createProcessInstance0(Long userId, ProcessDefinition definition,  
727 - Map<String, Object> variables, String businessKey,  
728 - Map<String, List<Long>> startUserSelectAssignees) {  
729 - // 1.1 校验流程定义  
730 - if (definition == null) {  
731 - throw exception(PROCESS_DEFINITION_NOT_EXISTS);  
732 - }  
733 - if (definition.isSuspended()) {  
734 - throw exception(PROCESS_DEFINITION_IS_SUSPENDED);  
735 - }  
736 - BpmProcessDefinitionInfoDO processDefinitionInfo = processDefinitionService  
737 - .getProcessDefinitionInfo(definition.getId());  
738 - if (processDefinitionInfo == null) {  
739 - throw exception(PROCESS_DEFINITION_NOT_EXISTS);  
740 - }  
741 - // 1.2 校验是否能够发起  
742 - if (!processDefinitionService.canUserStartProcessDefinition(processDefinitionInfo, userId)) {  
743 - throw exception(PROCESS_INSTANCE_START_USER_CAN_START);  
744 - }  
745 - // 1.3 校验发起人自选审批人  
746 - validateStartUserSelectAssignees(userId, definition, startUserSelectAssignees, variables);  
747 -  
748 - // 2. 创建流程实例  
749 - if (variables == null) {  
750 - variables = new HashMap<>();  
751 - }  
752 - FlowableUtils.filterProcessInstanceFormVariable(variables); // 过滤一下,避免 ProcessInstance 系统级的变量被占用  
753 - variables.put(BpmnVariableConstants.PROCESS_INSTANCE_VARIABLE_START_USER_ID, userId); // 设置流程变量,发起人 ID  
754 - variables.put(BpmnVariableConstants.PROCESS_INSTANCE_VARIABLE_STATUS, // 流程实例状态:审批中  
755 - BpmProcessInstanceStatusEnum.RUNNING.getStatus());  
756 - variables.put(BpmnVariableConstants.PROCESS_INSTANCE_SKIP_EXPRESSION_ENABLED, true); // 跳过表达式需要添加此变量为 true,不影响没配置 skipExpression 的节点  
757 - if (CollUtil.isNotEmpty(startUserSelectAssignees)) {  
758 - // 设置流程变量,发起人自选审批人  
759 - variables.put(BpmnVariableConstants.PROCESS_INSTANCE_VARIABLE_START_USER_SELECT_ASSIGNEES,  
760 - startUserSelectAssignees);  
761 - }  
762 -  
763 - // 3. 创建流程  
764 - ProcessInstanceBuilder processInstanceBuilder = runtimeService.createProcessInstanceBuilder()  
765 - .processDefinitionId(definition.getId())  
766 - .businessKey(businessKey)  
767 - .variables(variables);  
768 - // 3.1 创建流程 ID  
769 - BpmModelMetaInfoVO.ProcessIdRule processIdRule = processDefinitionInfo.getProcessIdRule();  
770 - if (processIdRule != null && Boolean.TRUE.equals(processIdRule.getEnable())) {  
771 - processInstanceBuilder.predefineProcessInstanceId(processIdRedisDAO.generate(processIdRule));  
772 - }  
773 - // 3.2 流程名称  
774 - BpmModelMetaInfoVO.TitleSetting titleSetting = processDefinitionInfo.getTitleSetting();  
775 - if (titleSetting != null && Boolean.TRUE.equals(titleSetting.getEnable())) {  
776 - AdminUserRespDTO user = adminUserApi.getUser(userId);  
777 - Map<String, Object> cloneVariables = new HashMap<>(variables);  
778 - cloneVariables.put(BpmnVariableConstants.PROCESS_INSTANCE_VARIABLE_START_USER_ID, user.getNickname());  
779 - cloneVariables.put(BpmnVariableConstants.PROCESS_START_TIME, DateUtil.now());  
780 - cloneVariables.put(BpmnVariableConstants.PROCESS_DEFINITION_NAME, definition.getName().trim());  
781 - processInstanceBuilder.name(StrUtil.format(titleSetting.getTitle(), cloneVariables));  
782 - } else {  
783 - processInstanceBuilder.name(definition.getName().trim());  
784 - }  
785 - // 3.3 发起流程实例  
786 - ProcessInstance instance = processInstanceBuilder.start();  
787 - return instance.getId();  
788 - }  
789 -  
790 - private void validateStartUserSelectAssignees(Long userId, ProcessDefinition definition,  
791 - Map<String, List<Long>> startUserSelectAssignees,  
792 - Map<String, Object> variables) {  
793 - // 1. 获取预测的节点信息  
794 - BpmApprovalDetailRespVO detailRespVO = getApprovalDetail(userId, new BpmApprovalDetailReqVO()  
795 - .setProcessDefinitionId(definition.getId())  
796 - .setProcessVariables(variables));  
797 - List<ActivityNode> activityNodes = detailRespVO.getActivityNodes();  
798 - if (CollUtil.isEmpty(activityNodes)) {  
799 - return;  
800 - }  
801 -  
802 - // 2.1 移除掉不是发起人自选审批人节点  
803 - activityNodes.removeIf(task ->  
804 - ObjectUtil.notEqual(BpmTaskCandidateStrategyEnum.START_USER_SELECT.getStrategy(), task.getCandidateStrategy()));  
805 - // 2.2 流程发起时要先获取当前流程的预测走向节点,发起时只校验预测的节点发起人自选审批人的审批人和抄送人是否都配置了  
806 - activityNodes.forEach(task -> {  
807 - List<Long> assignees = startUserSelectAssignees != null ? startUserSelectAssignees.get(task.getId()) : null;  
808 - if (CollUtil.isEmpty(assignees)) {  
809 - throw exception(PROCESS_INSTANCE_START_USER_SELECT_ASSIGNEES_NOT_CONFIG, task.getName());  
810 - }  
811 - Map<Long, AdminUserRespDTO> userMap = adminUserApi.getUserMap(assignees);  
812 - assignees.forEach(assignee -> {  
813 - if (userMap.get(assignee) == null) {  
814 - throw exception(PROCESS_INSTANCE_START_USER_SELECT_ASSIGNEES_NOT_EXISTS, task.getName(), assignee);  
815 - }  
816 - });  
817 - });  
818 - }  
819 -  
820 - @Override  
821 - public void cancelProcessInstanceByStartUser(Long userId, @Valid BpmProcessInstanceCancelReqVO cancelReqVO) {  
822 - // 1.1 校验流程实例存在  
823 - ProcessInstance instance = getProcessInstance(cancelReqVO.getId());  
824 - if (instance == null) {  
825 - throw exception(PROCESS_INSTANCE_CANCEL_FAIL_NOT_EXISTS);  
826 - }  
827 - // 1.2 只能取消自己的  
828 - if (!Objects.equals(instance.getStartUserId(), String.valueOf(userId))) {  
829 - throw exception(PROCESS_INSTANCE_CANCEL_FAIL_NOT_SELF);  
830 - }  
831 - // 1.3 校验允许撤销审批中的申请  
832 - BpmProcessDefinitionInfoDO processDefinitionInfo = processDefinitionService  
833 - .getProcessDefinitionInfo(instance.getProcessDefinitionId());  
834 - Assert.notNull(processDefinitionInfo, "流程定义({})不存在", processDefinitionInfo);  
835 - if (processDefinitionInfo.getAllowCancelRunningProcess() != null // 防止未配置 AllowCancelRunningProcess , 默认为可取消  
836 - && Boolean.FALSE.equals(processDefinitionInfo.getAllowCancelRunningProcess())) {  
837 - throw exception(PROCESS_INSTANCE_CANCEL_FAIL_NOT_ALLOW);  
838 - }  
839 - // 1.4 子流程不允许取消  
840 - if (StrUtil.isNotBlank(instance.getSuperExecutionId())) {  
841 - throw exception(PROCESS_INSTANCE_CANCEL_CHILD_FAIL_NOT_ALLOW);  
842 - }  
843 -  
844 - // 2. 取消流程  
845 - updateProcessInstanceCancel(cancelReqVO.getId(),  
846 - BpmReasonEnum.CANCEL_PROCESS_INSTANCE_BY_START_USER.format(cancelReqVO.getReason()));  
847 - }  
848 -  
849 - @Override  
850 - public void cancelProcessInstanceByAdmin(Long userId, BpmProcessInstanceCancelReqVO cancelReqVO) {  
851 - // 1.1 校验流程实例存在  
852 - ProcessInstance instance = getProcessInstance(cancelReqVO.getId());  
853 - if (instance == null) {  
854 - throw exception(PROCESS_INSTANCE_CANCEL_FAIL_NOT_EXISTS);  
855 - }  
856 -  
857 - // 2. 取消流程  
858 - AdminUserRespDTO user = adminUserApi.getUser(userId);  
859 - updateProcessInstanceCancel(cancelReqVO.getId(),  
860 - BpmReasonEnum.CANCEL_PROCESS_INSTANCE_BY_ADMIN.format(user.getNickname(), cancelReqVO.getReason()));  
861 - }  
862 -  
863 - private void updateProcessInstanceCancel(String id, String reason) {  
864 - // 1. 更新流程实例 status  
865 - runtimeService.setVariable(id, BpmnVariableConstants.PROCESS_INSTANCE_VARIABLE_STATUS,  
866 - BpmProcessInstanceStatusEnum.CANCEL.getStatus());  
867 - runtimeService.setVariable(id, BpmnVariableConstants.PROCESS_INSTANCE_VARIABLE_REASON, reason);  
868 -  
869 - // 2. 取消所有子流程  
870 - List<ProcessInstance> childProcessInstances = runtimeService.createProcessInstanceQuery()  
871 - .superProcessInstanceId(id).list();  
872 - childProcessInstances.forEach(processInstance -> updateProcessInstanceCancel(  
873 - processInstance.getProcessInstanceId(), BpmReasonEnum.CANCEL_CHILD_PROCESS_INSTANCE_BY_MAIN_PROCESS.getReason()));  
874 -  
875 - // 3. 结束流程  
876 - taskService.moveTaskToEnd(id, reason);  
877 - }  
878 -  
879 - @Override  
880 - public void updateProcessInstanceReject(ProcessInstance processInstance, String reason) {  
881 - runtimeService.setVariable(processInstance.getProcessInstanceId(),  
882 - BpmnVariableConstants.PROCESS_INSTANCE_VARIABLE_STATUS,  
883 - BpmProcessInstanceStatusEnum.REJECT.getStatus());  
884 - runtimeService.setVariable(processInstance.getProcessInstanceId(),  
885 - BpmnVariableConstants.PROCESS_INSTANCE_VARIABLE_REASON,  
886 - BpmReasonEnum.REJECT_TASK.format(reason));  
887 - }  
888 -  
889 - @Override  
890 - public void updateProcessInstanceVariables(String id, Map<String, Object> variables) {  
891 - runtimeService.setVariables(id, variables);  
892 - }  
893 -  
894 - @Override  
895 - public void removeProcessInstanceVariables(String id, Collection<String> variableNames) {  
896 - runtimeService.removeVariables(id, variableNames);  
897 - }  
898 -  
899 - // ========== Event 事件相关方法 ==========  
900 -  
901 - @Override  
902 - public void processProcessInstanceCompleted(ProcessInstance instance) {  
903 - // 注意:需要基于 instance 设置租户编号,避免 Flowable 内部异步时,丢失租户编号  
904 - FlowableUtils.execute(instance.getTenantId(), () -> {  
905 - // 1.1 获取当前状态  
906 - Integer status = (Integer) instance.getProcessVariables()  
907 - .get(BpmnVariableConstants.PROCESS_INSTANCE_VARIABLE_STATUS);  
908 - String reason = (String) instance.getProcessVariables()  
909 - .get(BpmnVariableConstants.PROCESS_INSTANCE_VARIABLE_REASON);  
910 - // 1.2 当流程状态还是审批状态中,说明审批通过了,则变更下它的状态  
911 - // 为什么这么处理?因为流程完成,并且完成了,说明审批通过了  
912 - if (Objects.equals(status, BpmProcessInstanceStatusEnum.RUNNING.getStatus())) {  
913 - status = BpmProcessInstanceStatusEnum.APPROVE.getStatus();  
914 - runtimeService.setVariable(instance.getId(), BpmnVariableConstants.PROCESS_INSTANCE_VARIABLE_STATUS,  
915 - status);  
916 - }  
917 -  
918 - // 2. 发送对应的消息通知  
919 - if (Objects.equals(status, BpmProcessInstanceStatusEnum.APPROVE.getStatus())) {  
920 - messageService.sendMessageWhenProcessInstanceApprove(  
921 - BpmProcessInstanceConvert.INSTANCE.buildProcessInstanceApproveMessage(instance));  
922 - } else if (Objects.equals(status, BpmProcessInstanceStatusEnum.REJECT.getStatus())) {  
923 - messageService.sendMessageWhenProcessInstanceReject(  
924 - BpmProcessInstanceConvert.INSTANCE.buildProcessInstanceRejectMessage(instance, reason));  
925 - }  
926 -  
927 - // 3. 发送流程实例的状态事件  
928 - processInstanceEventPublisher.sendProcessInstanceResultEvent(  
929 - BpmProcessInstanceConvert.INSTANCE.buildProcessInstanceStatusEvent(this, instance, status));  
930 -  
931 - // 4. 流程后置通知  
932 - if (Objects.equals(status, BpmProcessInstanceStatusEnum.APPROVE.getStatus())) {  
933 - BpmProcessDefinitionInfoDO processDefinitionInfo = processDefinitionService.  
934 - getProcessDefinitionInfo(instance.getProcessDefinitionId());  
935 - if (ObjUtil.isNotNull(processDefinitionInfo) &&  
936 - ObjUtil.isNotNull(processDefinitionInfo.getProcessAfterTriggerSetting())) {  
937 - BpmModelMetaInfoVO.HttpRequestSetting setting = processDefinitionInfo.getProcessAfterTriggerSetting();  
938 -  
939 - BpmHttpRequestUtils.executeBpmHttpRequest(instance,  
940 - setting.getUrl(), setting.getHeader(), setting.getBody(), true, setting.getResponse());  
941 - }  
942 - }  
943 - });  
944 - }  
945 -  
946 - @Override  
947 - public void processProcessInstanceCreated(ProcessInstance instance) {  
948 - // 注意:需要基于 instance 设置租户编号,避免 Flowable 内部异步时,丢失租户编号  
949 - FlowableUtils.execute(instance.getTenantId(), () -> {  
950 - // 流程前置通知  
951 - BpmProcessDefinitionInfoDO processDefinitionInfo = processDefinitionService.  
952 - getProcessDefinitionInfo(instance.getProcessDefinitionId());  
953 - if (ObjUtil.isNull(processDefinitionInfo) ||  
954 - ObjUtil.isNull(processDefinitionInfo.getProcessBeforeTriggerSetting())) {  
955 - return;  
956 - }  
957 - BpmModelMetaInfoVO.HttpRequestSetting setting = processDefinitionInfo.getProcessBeforeTriggerSetting();  
958 - BpmHttpRequestUtils.executeBpmHttpRequest(instance,  
959 - setting.getUrl(), setting.getHeader(), setting.getBody(), true, setting.getResponse());  
960 - });  
961 - }  
962 -  
963 -} 1 +package cn.iocoder.yudao.module.bpm.service.task;
  2 +
  3 +import cn.hutool.core.collection.CollUtil;
  4 +import cn.hutool.core.collection.ListUtil;
  5 +import cn.hutool.core.date.DateUtil;
  6 +import cn.hutool.core.lang.Assert;
  7 +import cn.hutool.core.util.ArrayUtil;
  8 +import cn.hutool.core.util.ObjUtil;
  9 +import cn.hutool.core.util.ObjectUtil;
  10 +import cn.hutool.core.util.StrUtil;
  11 +import cn.iocoder.yudao.framework.common.pojo.PageResult;
  12 +import cn.iocoder.yudao.framework.common.util.date.DateUtils;
  13 +import cn.iocoder.yudao.framework.common.util.json.JsonUtils;
  14 +import cn.iocoder.yudao.framework.common.util.object.ObjectUtils;
  15 +import cn.iocoder.yudao.framework.common.util.object.PageUtils;
  16 +import cn.iocoder.yudao.module.bpm.api.task.dto.BpmProcessInstanceCreateReqDTO;
  17 +import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.model.BpmModelMetaInfoVO;
  18 +import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.model.simple.BpmSimpleModelNodeVO;
  19 +import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance.*;
  20 +import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance.BpmApprovalDetailRespVO.ActivityNodeTask;
  21 +import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.task.BpmTaskRespVO;
  22 +import cn.iocoder.yudao.module.bpm.convert.task.BpmProcessInstanceConvert;
  23 +import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmProcessDefinitionInfoDO;
  24 +import cn.iocoder.yudao.module.bpm.dal.redis.BpmProcessIdRedisDAO;
  25 +import cn.iocoder.yudao.module.bpm.enums.ErrorCodeConstants;
  26 +import cn.iocoder.yudao.module.bpm.enums.definition.BpmModelTypeEnum;
  27 +import cn.iocoder.yudao.module.bpm.enums.definition.BpmSimpleModelNodeTypeEnum;
  28 +import cn.iocoder.yudao.module.bpm.enums.task.BpmProcessInstanceStatusEnum;
  29 +import cn.iocoder.yudao.module.bpm.enums.task.BpmReasonEnum;
  30 +import cn.iocoder.yudao.module.bpm.enums.task.BpmTaskStatusEnum;
  31 +import cn.iocoder.yudao.module.bpm.framework.flowable.core.candidate.BpmTaskCandidateInvoker;
  32 +import cn.iocoder.yudao.module.bpm.framework.flowable.core.enums.BpmTaskCandidateStrategyEnum;
  33 +import cn.iocoder.yudao.module.bpm.framework.flowable.core.enums.BpmnModelConstants;
  34 +import cn.iocoder.yudao.module.bpm.framework.flowable.core.enums.BpmnVariableConstants;
  35 +import cn.iocoder.yudao.module.bpm.framework.flowable.core.event.BpmProcessInstanceEventPublisher;
  36 +import cn.iocoder.yudao.module.bpm.framework.flowable.core.util.BpmHttpRequestUtils;
  37 +import cn.iocoder.yudao.module.bpm.framework.flowable.core.util.BpmnModelUtils;
  38 +import cn.iocoder.yudao.module.bpm.framework.flowable.core.util.FlowableUtils;
  39 +import cn.iocoder.yudao.module.bpm.framework.flowable.core.util.SimpleModelUtils;
  40 +import cn.iocoder.yudao.module.bpm.service.definition.BpmProcessDefinitionService;
  41 +import cn.iocoder.yudao.module.bpm.service.message.BpmMessageService;
  42 +import cn.iocoder.yudao.module.system.api.dept.DeptApi;
  43 +import cn.iocoder.yudao.module.system.api.dept.dto.DeptRespDTO;
  44 +import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
  45 +import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
  46 +import jakarta.annotation.Resource;
  47 +import jakarta.validation.Valid;
  48 +import lombok.extern.slf4j.Slf4j;
  49 +import org.flowable.bpmn.constants.BpmnXMLConstants;
  50 +import org.flowable.bpmn.model.*;
  51 +import org.flowable.engine.HistoryService;
  52 +import org.flowable.engine.RuntimeService;
  53 +import org.flowable.engine.history.HistoricActivityInstance;
  54 +import org.flowable.engine.history.HistoricProcessInstance;
  55 +import org.flowable.engine.history.HistoricProcessInstanceQuery;
  56 +import org.flowable.engine.repository.ProcessDefinition;
  57 +import org.flowable.engine.runtime.ProcessInstance;
  58 +import org.flowable.engine.runtime.ProcessInstanceBuilder;
  59 +import org.flowable.task.api.Task;
  60 +import org.flowable.task.api.history.HistoricTaskInstance;
  61 +import org.springframework.context.annotation.Lazy;
  62 +import org.springframework.stereotype.Service;
  63 +import org.springframework.transaction.annotation.Transactional;
  64 +import org.springframework.validation.annotation.Validated;
  65 +
  66 +import java.util.*;
  67 +
  68 +import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
  69 +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.*;
  70 +import static cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance.BpmApprovalDetailRespVO.ActivityNode;
  71 +import static cn.iocoder.yudao.module.bpm.enums.ErrorCodeConstants.*;
  72 +import static cn.iocoder.yudao.module.bpm.framework.flowable.core.enums.BpmnModelConstants.START_USER_NODE_ID;
  73 +import static cn.iocoder.yudao.module.bpm.framework.flowable.core.util.BpmnModelUtils.parseNodeType;
  74 +import static java.util.Arrays.asList;
  75 +import static java.util.Collections.singletonList;
  76 +import static org.flowable.bpmn.constants.BpmnXMLConstants.*;
  77 +
  78 +/**
  79 + * 流程实例 Service 实现类
  80 + * <p>
  81 + * ProcessDefinition & ProcessInstance & Execution & Task 的关系:
  82 + * 1. <a href="https://blog.csdn.net/bobozai86/article/details/105210414" />
  83 + * <p>
  84 + * HistoricProcessInstance & ProcessInstance 的关系:
  85 + * 1. <a href=" https://my.oschina.net/843294669/blog/71902" />
  86 + * <p>
  87 + * 简单来说,前者 = 历史 + 运行中的流程实例,后者仅是运行中的流程实例
  88 + *
  89 + * @author 芋道源码
  90 + */
  91 +@Service
  92 +@Validated
  93 +@Slf4j
  94 +public class BpmProcessInstanceServiceImpl implements BpmProcessInstanceService {
  95 +
  96 + @Resource
  97 + private RuntimeService runtimeService;
  98 + @Resource
  99 + private HistoryService historyService;
  100 +
  101 + @Resource
  102 + private BpmProcessDefinitionService processDefinitionService;
  103 + @Resource
  104 + @Lazy // 避免循环依赖
  105 + private BpmTaskService taskService;
  106 + @Resource
  107 + private BpmMessageService messageService;
  108 +
  109 + @Resource
  110 + private AdminUserApi adminUserApi;
  111 + @Resource
  112 + private DeptApi deptApi;
  113 +
  114 + @Resource
  115 + private BpmProcessInstanceEventPublisher processInstanceEventPublisher;
  116 +
  117 + @Resource
  118 + private BpmTaskCandidateInvoker taskCandidateInvoker;
  119 +
  120 + @Resource
  121 + private BpmProcessIdRedisDAO processIdRedisDAO;
  122 +
  123 + // ========== Query 查询相关方法 ==========
  124 +
  125 + @Override
  126 + public ProcessInstance getProcessInstance(String id) {
  127 + return runtimeService.createProcessInstanceQuery()
  128 + .includeProcessVariables()
  129 + .processInstanceId(id)
  130 + .singleResult();
  131 + }
  132 +
  133 + @Override
  134 + public List<ProcessInstance> getProcessInstances(Set<String> ids) {
  135 + return runtimeService.createProcessInstanceQuery().processInstanceIds(ids).includeProcessVariables().list();
  136 + }
  137 +
  138 + @Override
  139 + public HistoricProcessInstance getHistoricProcessInstance(String id) {
  140 + return historyService.createHistoricProcessInstanceQuery().processInstanceId(id).includeProcessVariables()
  141 + .singleResult();
  142 + }
  143 +
  144 + @Override
  145 + public List<HistoricProcessInstance> getHistoricProcessInstances(Set<String> ids) {
  146 + return historyService.createHistoricProcessInstanceQuery().processInstanceIds(ids).includeProcessVariables()
  147 + .list();
  148 + }
  149 +
  150 + private Map<String, String> getFormFieldsPermission(BpmnModel bpmnModel,
  151 + String activityId, String taskId) {
  152 + // 1. 获取流程活动编号。流程活动 Id 为空事,从流程任务中获取流程活动 Id
  153 + if (StrUtil.isEmpty(activityId) && StrUtil.isNotEmpty(taskId)) {
  154 + activityId = Optional.ofNullable(taskService.getHistoricTask(taskId))
  155 + .map(HistoricTaskInstance::getTaskDefinitionKey).orElse(null);
  156 + }
  157 + if (StrUtil.isEmpty(activityId)) {
  158 + return null;
  159 + }
  160 +
  161 + // 2. 从 BpmnModel 中解析表单字段权限
  162 + return BpmnModelUtils.parseFormFieldsPermission(bpmnModel, activityId);
  163 + }
  164 +
  165 + @Override
  166 + public BpmApprovalDetailRespVO getApprovalDetail(Long loginUserId, BpmApprovalDetailReqVO reqVO) {
  167 + // 1.1 从 reqVO 中,读取公共变量
  168 + Long startUserId = loginUserId; // 流程发起人
  169 + HistoricProcessInstance historicProcessInstance = null; // 流程实例
  170 + Integer processInstanceStatus = BpmProcessInstanceStatusEnum.NOT_START.getStatus(); // 流程状态
  171 + Map<String, Object> processVariables = new HashMap<>(); // 流程变量
  172 + // 1.2 如果是流程已发起的场景,则使用流程实例的数据
  173 + if (reqVO.getProcessInstanceId() != null) {
  174 + historicProcessInstance = getHistoricProcessInstance(reqVO.getProcessInstanceId());
  175 + if (historicProcessInstance == null) {
  176 + throw exception(ErrorCodeConstants.PROCESS_INSTANCE_NOT_EXISTS);
  177 + }
  178 + startUserId = Long.valueOf(historicProcessInstance.getStartUserId());
  179 + processInstanceStatus = FlowableUtils.getProcessInstanceStatus(historicProcessInstance);
  180 + // 合并 DB 和前端传递的流量变量,以前端的为主
  181 + if (CollUtil.isNotEmpty(historicProcessInstance.getProcessVariables())) {
  182 + processVariables.putAll(historicProcessInstance.getProcessVariables());
  183 + }
  184 + }
  185 + if (CollUtil.isNotEmpty(reqVO.getProcessVariables())) {
  186 + processVariables.putAll(reqVO.getProcessVariables());
  187 + }
  188 + // 1.3 读取其它相关数据
  189 + ProcessDefinition processDefinition = processDefinitionService.getProcessDefinition(
  190 + historicProcessInstance != null ? historicProcessInstance.getProcessDefinitionId()
  191 + : reqVO.getProcessDefinitionId());
  192 + BpmProcessDefinitionInfoDO processDefinitionInfo = processDefinitionService
  193 + .getProcessDefinitionInfo(processDefinition.getId());
  194 + BpmnModel bpmnModel = processDefinitionService.getProcessDefinitionBpmnModel(processDefinition.getId());
  195 +
  196 + // 2.1 已结束 + 进行中的活动节点
  197 + List<ActivityNode> endActivityNodes = null; // 已结束的审批信息
  198 + List<ActivityNode> runActivityNodes = null; // 进行中的审批信息
  199 + List<HistoricActivityInstance> activities = null; // 流程实例列表
  200 + if (reqVO.getProcessInstanceId() != null) {
  201 + activities = taskService.getActivityListByProcessInstanceId(reqVO.getProcessInstanceId());
  202 + List<HistoricTaskInstance> tasks = taskService.getTaskListByProcessInstanceId(reqVO.getProcessInstanceId(),
  203 + true);
  204 + endActivityNodes = getEndActivityNodeList(startUserId, bpmnModel, processDefinitionInfo,
  205 + historicProcessInstance, processInstanceStatus, activities, tasks);
  206 + runActivityNodes = getRunApproveNodeList(startUserId, bpmnModel, processDefinition, processVariables,
  207 + activities, tasks);
  208 + }
  209 +
  210 + // 2.2 流程已经结束,直接 return,无需预测
  211 + if (BpmProcessInstanceStatusEnum.isProcessEndStatus(processInstanceStatus)) {
  212 + return buildApprovalDetail(reqVO, bpmnModel, processDefinition, processDefinitionInfo,
  213 + historicProcessInstance,
  214 + processInstanceStatus, endActivityNodes, runActivityNodes, null, null);
  215 + }
  216 +
  217 + // 3.1 计算当前登录用户的待办任务
  218 + BpmTaskRespVO todoTask = taskService.getTodoTask(loginUserId, reqVO.getTaskId(), reqVO.getProcessInstanceId());
  219 + // 3.2 预测未运行节点的审批信息
  220 + List<ActivityNode> simulateActivityNodes = getSimulateApproveNodeList(startUserId, bpmnModel,
  221 + processDefinitionInfo,
  222 + processVariables, activities);
  223 + // 3.3 如果是发起动作,activityId 为开始节点,不校验审批人自选节点
  224 + if (ObjUtil.equals(reqVO.getActivityId(), BpmnModelConstants.START_USER_NODE_ID)) {
  225 + simulateActivityNodes.removeIf(node ->
  226 + BpmTaskCandidateStrategyEnum.APPROVE_USER_SELECT.getStrategy().equals(node.getCandidateStrategy()));
  227 + }
  228 +
  229 + // 4. 拼接最终数据
  230 + return buildApprovalDetail(reqVO, bpmnModel, processDefinition, processDefinitionInfo, historicProcessInstance,
  231 + processInstanceStatus, endActivityNodes, runActivityNodes, simulateActivityNodes, todoTask);
  232 + }
  233 +
  234 + @Override
  235 + public List<ActivityNode> getNextApprovalNodes(Long loginUserId, BpmApprovalDetailReqVO reqVO) {
  236 + // 1.1 校验任务存在,且是当前用户的
  237 + Task task = taskService.validateTask(loginUserId, reqVO.getTaskId());
  238 + // 1.2 校验流程实例存在
  239 + ProcessInstance instance = getProcessInstance(task.getProcessInstanceId());
  240 + if (instance == null) {
  241 + throw exception(PROCESS_INSTANCE_NOT_EXISTS);
  242 + }
  243 + HistoricProcessInstance historicProcessInstance = getHistoricProcessInstance(task.getProcessInstanceId());
  244 + if (historicProcessInstance == null) {
  245 + throw exception(ErrorCodeConstants.PROCESS_INSTANCE_NOT_EXISTS);
  246 + }
  247 + // 1.3 校验BpmnModel
  248 + BpmnModel bpmnModel = processDefinitionService.getProcessDefinitionBpmnModel(task.getProcessDefinitionId());
  249 + if (bpmnModel == null) {
  250 + return null;
  251 + }
  252 +
  253 + // 2. 设置流程变量
  254 + Map<String, Object> processVariables = new HashMap<>();
  255 + // 2.1 获取历史中流程变量
  256 + if (CollUtil.isNotEmpty(historicProcessInstance.getProcessVariables())) {
  257 + processVariables.putAll(historicProcessInstance.getProcessVariables());
  258 + }
  259 + // 2.2 合并前端传递的流程变量,以前端为准
  260 + if (CollUtil.isNotEmpty(reqVO.getProcessVariables())) {
  261 + processVariables.putAll(reqVO.getProcessVariables());
  262 + }
  263 +
  264 + // 3. 获取下一个将要执行的节点集合
  265 + FlowElement flowElement = bpmnModel.getFlowElement(task.getTaskDefinitionKey());
  266 + List<FlowNode> nextFlowNodes = BpmnModelUtils.getNextFlowNodes(flowElement, bpmnModel, processVariables);
  267 + List<ActivityNode> nextActivityNodes = convertList(nextFlowNodes, node -> new ActivityNode().setId(node.getId())
  268 + .setName(node.getName()).setNodeType(BpmSimpleModelNodeTypeEnum.APPROVE_NODE.getType())
  269 + .setStatus(BpmTaskStatusEnum.RUNNING.getStatus())
  270 + .setCandidateStrategy(BpmnModelUtils.parseCandidateStrategy(node))
  271 + .setCandidateUserIds(getTaskCandidateUserList(bpmnModel, node.getId(),
  272 + loginUserId, historicProcessInstance.getProcessDefinitionId(), processVariables)));
  273 + if (CollUtil.isNotEmpty(nextActivityNodes)) {
  274 + return nextActivityNodes;
  275 + }
  276 +
  277 + // 4. 拼接基础信息
  278 + Map<Long, AdminUserRespDTO> userMap = adminUserApi.getUserMap(
  279 + convertSetByFlatMap(nextActivityNodes, ActivityNode::getCandidateUserIds, Collection::stream));
  280 + Map<Long, DeptRespDTO> deptMap = deptApi.getDeptMap(convertSet(userMap.values(), AdminUserRespDTO::getDeptId));
  281 + nextActivityNodes.forEach(node -> node.setCandidateUsers(convertList(node.getCandidateUserIds(), userId -> {
  282 + AdminUserRespDTO user = userMap.get(userId);
  283 + if (user != null) {
  284 + return BpmProcessInstanceConvert.INSTANCE.buildUser(userId, userMap, deptMap);
  285 + }
  286 + return null;
  287 + })));
  288 + return nextActivityNodes;
  289 + }
  290 +
  291 + @Override
  292 + @SuppressWarnings("unchecked")
  293 + public PageResult<HistoricProcessInstance> getProcessInstancePage(Long userId,
  294 + BpmProcessInstancePageReqVO pageReqVO) {
  295 + // 1. 构建查询条件
  296 + HistoricProcessInstanceQuery processInstanceQuery = historyService.createHistoricProcessInstanceQuery()
  297 + .includeProcessVariables()
  298 + .processInstanceTenantId(FlowableUtils.getTenantId())
  299 + .orderByProcessInstanceStartTime().desc();
  300 + if (userId != null) { // 【我的流程】菜单时,需要传递该字段
  301 + processInstanceQuery.startedBy(String.valueOf(userId));
  302 + } else if (pageReqVO.getStartUserId() != null) { // 【管理流程】菜单时,才会传递该字段
  303 + processInstanceQuery.startedBy(String.valueOf(pageReqVO.getStartUserId()));
  304 + }
  305 + if (StrUtil.isNotEmpty(pageReqVO.getName())) {
  306 + processInstanceQuery.processInstanceNameLike("%" + pageReqVO.getName() + "%");
  307 + }
  308 + if (StrUtil.isNotEmpty(pageReqVO.getProcessDefinitionKey())) {
  309 + processInstanceQuery.processDefinitionKey(pageReqVO.getProcessDefinitionKey());
  310 + }
  311 + if (StrUtil.isNotEmpty(pageReqVO.getCategory())) {
  312 + processInstanceQuery.processDefinitionCategory(pageReqVO.getCategory());
  313 + }
  314 + if (pageReqVO.getStatus() != null) {
  315 + processInstanceQuery.variableValueEquals(BpmnVariableConstants.PROCESS_INSTANCE_VARIABLE_STATUS,
  316 + pageReqVO.getStatus());
  317 + }
  318 + if (ArrayUtil.isNotEmpty(pageReqVO.getCreateTime())) {
  319 + processInstanceQuery.startedAfter(DateUtils.of(pageReqVO.getCreateTime()[0]));
  320 + processInstanceQuery.startedBefore(DateUtils.of(pageReqVO.getCreateTime()[1]));
  321 + }
  322 + if (ArrayUtil.isNotEmpty(pageReqVO.getEndTime())) {
  323 + processInstanceQuery.finishedAfter(DateUtils.of(pageReqVO.getEndTime()[0]));
  324 + processInstanceQuery.finishedBefore(DateUtils.of(pageReqVO.getEndTime()[1]));
  325 + }
  326 + // 表单字段查询
  327 + Map<String, Object> formFieldsParams = JsonUtils.parseObject(pageReqVO.getFormFieldsParams(), Map.class);
  328 + if (CollUtil.isNotEmpty(formFieldsParams)) {
  329 + formFieldsParams.forEach((key, value) -> {
  330 + if (StrUtil.isEmpty(String.valueOf(value))) {
  331 + return;
  332 + }
  333 + // TODO @lesan:应支持多种类型的查询方式,目前只有字符串全等
  334 + processInstanceQuery.variableValueEquals(key, value);
  335 + });
  336 + }
  337 +
  338 + // 2.1 查询数量
  339 + long processInstanceCount = processInstanceQuery.count();
  340 + if (processInstanceCount == 0) {
  341 + return PageResult.empty(processInstanceCount);
  342 + }
  343 + // 2.2 查询列表
  344 + List<HistoricProcessInstance> processInstanceList = processInstanceQuery.listPage(PageUtils.getStart(pageReqVO),
  345 + pageReqVO.getPageSize());
  346 + return new PageResult<>(processInstanceList, processInstanceCount);
  347 + }
  348 +
  349 + /**
  350 + * 拼接审批详情的最终数据
  351 + * <p>
  352 + * 主要是,拼接审批人的用户信息、部门信息
  353 + */
  354 + private BpmApprovalDetailRespVO buildApprovalDetail(BpmApprovalDetailReqVO reqVO,
  355 + BpmnModel bpmnModel,
  356 + ProcessDefinition processDefinition,
  357 + BpmProcessDefinitionInfoDO processDefinitionInfo,
  358 + HistoricProcessInstance processInstance,
  359 + Integer processInstanceStatus,
  360 + List<ActivityNode> endApprovalNodeInfos,
  361 + List<ActivityNode> runningApprovalNodeInfos,
  362 + List<ActivityNode> simulateApprovalNodeInfos,
  363 + BpmTaskRespVO todoTask) {
  364 + // 1. 获取所有需要读取用户信息的 userIds
  365 + List<ActivityNode> approveNodes = newArrayList(
  366 + asList(endApprovalNodeInfos, runningApprovalNodeInfos, simulateApprovalNodeInfos));
  367 + Set<Long> userIds = BpmProcessInstanceConvert.INSTANCE.parseUserIds(processInstance, approveNodes, todoTask);
  368 + Map<Long, AdminUserRespDTO> userMap = adminUserApi.getUserMap(userIds);
  369 + Map<Long, DeptRespDTO> deptMap = deptApi.getDeptMap(convertSet(userMap.values(), AdminUserRespDTO::getDeptId));
  370 +
  371 + // 2. 表单权限
  372 + String taskId = reqVO.getTaskId() == null && todoTask != null ? todoTask.getId() : reqVO.getTaskId();
  373 + Map<String, String> formFieldsPermission = getFormFieldsPermission(bpmnModel, reqVO.getActivityId(), taskId);
  374 +
  375 + // 3. 拼接数据
  376 + return BpmProcessInstanceConvert.INSTANCE.buildApprovalDetail(bpmnModel, processDefinition,
  377 + processDefinitionInfo, processInstance,
  378 + processInstanceStatus, approveNodes, todoTask, formFieldsPermission, userMap, deptMap);
  379 + }
  380 +
  381 + /**
  382 + * 获得【已结束】的活动节点们
  383 + */
  384 + private List<ActivityNode> getEndActivityNodeList(Long startUserId, BpmnModel bpmnModel,
  385 + BpmProcessDefinitionInfoDO processDefinitionInfo,
  386 + HistoricProcessInstance historicProcessInstance, Integer processInstanceStatus,
  387 + List<HistoricActivityInstance> activities, List<HistoricTaskInstance> tasks) {
  388 + // 遍历 tasks 列表,只处理已结束的 UserTask
  389 + // 为什么不通过 activities 呢?因为,加签场景下,它只存在于 tasks,没有 activities,导致如果遍历 activities 的话,它无法成为一个节点
  390 + List<HistoricTaskInstance> endTasks = filterList(tasks, task -> task.getEndTime() != null);
  391 + List<ActivityNode> approvalNodes = convertList(endTasks, task -> {
  392 + FlowElement flowNode = BpmnModelUtils.getFlowElementById(bpmnModel, task.getTaskDefinitionKey());
  393 + ActivityNode activityNode = new ActivityNode().setId(task.getTaskDefinitionKey()).setName(task.getName())
  394 + .setNodeType(START_USER_NODE_ID.equals(task.getTaskDefinitionKey())
  395 + ? BpmSimpleModelNodeTypeEnum.START_USER_NODE.getType()
  396 + : ObjUtil.defaultIfNull(parseNodeType(flowNode), // 目的:解决“办理节点”的识别
  397 + BpmSimpleModelNodeTypeEnum.APPROVE_NODE.getType()))
  398 + .setStatus(FlowableUtils.getTaskStatus(task))
  399 + .setCandidateStrategy(BpmnModelUtils.parseCandidateStrategy(flowNode))
  400 + .setStartTime(DateUtils.of(task.getCreateTime())).setEndTime(DateUtils.of(task.getEndTime()))
  401 + .setTasks(singletonList(BpmProcessInstanceConvert.INSTANCE.buildApprovalTaskInfo(task)));
  402 + // 如果是取消状态,则跳过
  403 + if (BpmTaskStatusEnum.isCancelStatus(activityNode.getStatus())) {
  404 + return null;
  405 + }
  406 + return activityNode;
  407 + });
  408 +
  409 + // 遍历 activities,只处理已结束的 StartEvent、EndEvent
  410 + List<HistoricActivityInstance> endActivities = filterList(activities, activity -> activity.getEndTime() != null
  411 + && (StrUtil.equalsAny(activity.getActivityType(), ELEMENT_EVENT_START, ELEMENT_CALL_ACTIVITY, ELEMENT_EVENT_END)));
  412 + endActivities.forEach(activity -> {
  413 + // StartEvent:只处理 BPMN 的场景。因为,SIMPLE 情况下,已经有 START_USER_NODE 节点
  414 + if (ELEMENT_EVENT_START.equals(activity.getActivityType())
  415 + && BpmModelTypeEnum.BPMN.getType().equals(processDefinitionInfo.getModelType())) {
  416 + ActivityNodeTask startTask = new ActivityNodeTask().setId(BpmnModelConstants.START_USER_NODE_ID)
  417 + .setAssignee(startUserId).setStatus(BpmTaskStatusEnum.APPROVE.getStatus());
  418 + ActivityNode startNode = new ActivityNode().setId(startTask.getId())
  419 + .setName(BpmSimpleModelNodeTypeEnum.START_USER_NODE.getName())
  420 + .setNodeType(BpmSimpleModelNodeTypeEnum.START_USER_NODE.getType())
  421 + .setStatus(startTask.getStatus()).setTasks(ListUtil.of(startTask))
  422 + .setStartTime(DateUtils.of(activity.getStartTime()))
  423 + .setEndTime(DateUtils.of(activity.getEndTime()));
  424 + approvalNodes.add(0, startNode);
  425 + return;
  426 + }
  427 + // EndEvent
  428 + if (ELEMENT_EVENT_END.equals(activity.getActivityType())) {
  429 + if (BpmProcessInstanceStatusEnum.isRejectStatus(processInstanceStatus)) {
  430 + // 拒绝情况下,不需要展示 EndEvent 结束节点。原因是:前端已经展示 x 效果,无需重复展示
  431 + return;
  432 + }
  433 + ActivityNode endNode = new ActivityNode().setId(activity.getId())
  434 + .setName(BpmSimpleModelNodeTypeEnum.END_NODE.getName())
  435 + .setNodeType(BpmSimpleModelNodeTypeEnum.END_NODE.getType()).setStatus(processInstanceStatus)
  436 + .setStartTime(DateUtils.of(activity.getStartTime()))
  437 + .setEndTime(DateUtils.of(activity.getEndTime()));
  438 + String reason = FlowableUtils.getProcessInstanceReason(historicProcessInstance);
  439 + if (StrUtil.isNotEmpty(reason)) {
  440 + endNode.setTasks(singletonList(new ActivityNodeTask().setId(endNode.getId())
  441 + .setStatus(endNode.getStatus()).setReason(reason)));
  442 + }
  443 + approvalNodes.add(endNode);
  444 + }
  445 + // CallActivity
  446 + if (ELEMENT_CALL_ACTIVITY.equals(activity.getActivityType())) {
  447 + ActivityNode callActivity = new ActivityNode().setId(activity.getId())
  448 + .setName(BpmSimpleModelNodeTypeEnum.CHILD_PROCESS.getName())
  449 + .setNodeType(BpmSimpleModelNodeTypeEnum.CHILD_PROCESS.getType()).setStatus(processInstanceStatus)
  450 + .setStartTime(DateUtils.of(activity.getStartTime()))
  451 + .setEndTime(DateUtils.of(activity.getEndTime()))
  452 + .setProcessInstanceId(activity.getProcessInstanceId());
  453 + approvalNodes.add(callActivity);
  454 + }
  455 + });
  456 +
  457 + // 按照时间排序
  458 + approvalNodes.sort(Comparator.comparing(ActivityNode::getStartTime));
  459 + return approvalNodes;
  460 + }
  461 +
  462 + /**
  463 + * 获得【进行中】的活动节点们
  464 + */
  465 + private List<ActivityNode> getRunApproveNodeList(Long startUserId,
  466 + BpmnModel bpmnModel,
  467 + ProcessDefinition processDefinition,
  468 + Map<String, Object> processVariables,
  469 + List<HistoricActivityInstance> activities,
  470 + List<HistoricTaskInstance> tasks) {
  471 + // 构建运行中的任务、子流程,基于 activityId 分组
  472 + List<HistoricActivityInstance> runActivities = filterList(activities, activity -> activity.getEndTime() == null
  473 + && (StrUtil.equalsAny(activity.getActivityType(), ELEMENT_TASK_USER, ELEMENT_CALL_ACTIVITY)));
  474 + Map<String, List<HistoricActivityInstance>> runningTaskMap = convertMultiMap(runActivities,
  475 + HistoricActivityInstance::getActivityId);
  476 +
  477 + // 按照 activityId 分组,构建 ApprovalNodeInfo 节点
  478 + Map<String, HistoricTaskInstance> taskMap = convertMap(tasks, HistoricTaskInstance::getId);
  479 + return convertList(runningTaskMap.entrySet(), entry -> {
  480 + String activityId = entry.getKey();
  481 + List<HistoricActivityInstance> taskActivities = entry.getValue();
  482 + // 构建活动节点
  483 + FlowElement flowNode = BpmnModelUtils.getFlowElementById(bpmnModel, activityId);
  484 + HistoricActivityInstance firstActivity = CollUtil.getFirst(taskActivities); // 取第一个任务,会签/或签的任务,开始时间相同
  485 + ActivityNode activityNode = new ActivityNode().setId(firstActivity.getActivityId())
  486 + .setName(firstActivity.getActivityName())
  487 + .setNodeType(ObjUtil.defaultIfNull(parseNodeType(flowNode), // 目的:解决“办理节点”和"子流程"的识别
  488 + BpmSimpleModelNodeTypeEnum.APPROVE_NODE.getType()))
  489 + .setStatus(BpmTaskStatusEnum.RUNNING.getStatus())
  490 + .setCandidateStrategy(BpmnModelUtils.parseCandidateStrategy(flowNode))
  491 + .setStartTime(DateUtils.of(CollUtil.getFirst(taskActivities).getStartTime()))
  492 + .setTasks(new ArrayList<>());
  493 + // 处理每个任务的 tasks 属性
  494 + for (HistoricActivityInstance activity : taskActivities) {
  495 + HistoricTaskInstance task = taskMap.get(activity.getTaskId());
  496 + // 特殊情况:子流程节点 ChildProcess 仅存在于 activity 中,并且没有自身的 task,需要跳过执行
  497 + // TODO @芋艿:后续看看怎么优化!
  498 + if (task == null) {
  499 + continue;
  500 + }
  501 + activityNode.getTasks().add(BpmProcessInstanceConvert.INSTANCE.buildApprovalTaskInfo(task));
  502 + // 加签子任务,需要过滤掉已经完成的加签子任务
  503 + List<HistoricTaskInstance> childrenTasks = filterList(
  504 + taskService.getAllChildrenTaskListByParentTaskId(activity.getTaskId(), tasks),
  505 + childTask -> childTask.getEndTime() == null);
  506 + if (CollUtil.isNotEmpty(childrenTasks)) {
  507 + activityNode.getTasks().addAll(
  508 + convertList(childrenTasks, BpmProcessInstanceConvert.INSTANCE::buildApprovalTaskInfo));
  509 + }
  510 + }
  511 + // 处理每个任务的 candidateUsers 属性:如果是依次审批,需要预测它的后续审批人。因为 Task 是审批完一个,创建一个新的 Task
  512 + if (BpmnModelUtils.isSequentialUserTask(flowNode)) {
  513 + List<Long> candidateUserIds = getTaskCandidateUserList(bpmnModel, flowNode.getId(),
  514 + startUserId, processDefinition.getId(), processVariables);
  515 + // 截取当前审批人位置后面的候选人,不包含当前审批人
  516 + ActivityNodeTask approvalTaskInfo = CollUtil.getFirst(activityNode.getTasks());
  517 + Assert.notNull(approvalTaskInfo, "任务不能为空");
  518 + int index = CollUtil.indexOf(candidateUserIds,
  519 + userId -> ObjectUtils.equalsAny(userId, approvalTaskInfo.getOwner(),
  520 + approvalTaskInfo.getAssignee())); // 委派或者向前加签情况,需要先比较 owner
  521 + activityNode.setCandidateUserIds(CollUtil.sub(candidateUserIds, index + 1, candidateUserIds.size()));
  522 + }
  523 + if (BpmSimpleModelNodeTypeEnum.CHILD_PROCESS.getType().equals(activityNode.getNodeType())) {
  524 + activityNode.setProcessInstanceId(firstActivity.getProcessInstanceId());
  525 + }
  526 + return activityNode;
  527 + });
  528 + }
  529 +
  530 + /**
  531 + * 获得【预测(未来)】的活动节点们
  532 + */
  533 + private List<ActivityNode> getSimulateApproveNodeList(Long startUserId, BpmnModel bpmnModel,
  534 + BpmProcessDefinitionInfoDO processDefinitionInfo,
  535 + Map<String, Object> processVariables,
  536 + List<HistoricActivityInstance> activities) {
  537 + // TODO @芋艿:【可优化】在驳回场景下,未来的预测准确性不高。原因是,驳回后,HistoricActivityInstance
  538 + // 包括了历史的操作,不是只有 startEvent 到当前节点的记录
  539 + Set<String> runActivityIds = convertSet(activities, HistoricActivityInstance::getActivityId);
  540 + // 情况一:BPMN 设计器
  541 + if (Objects.equals(BpmModelTypeEnum.BPMN.getType(), processDefinitionInfo.getModelType())) {
  542 + List<FlowElement> flowElements = BpmnModelUtils.simulateProcess(bpmnModel, processVariables);
  543 + return convertList(flowElements, flowElement -> buildNotRunApproveNodeForBpmn(startUserId, bpmnModel,
  544 + processDefinitionInfo, processVariables, flowElement, runActivityIds));
  545 + }
  546 + // 情况二:SIMPLE 设计器
  547 + if (Objects.equals(BpmModelTypeEnum.SIMPLE.getType(), processDefinitionInfo.getModelType())) {
  548 + BpmSimpleModelNodeVO simpleModel = JsonUtils.parseObject(processDefinitionInfo.getSimpleModel(),
  549 + BpmSimpleModelNodeVO.class);
  550 + List<BpmSimpleModelNodeVO> simpleNodes = SimpleModelUtils.simulateProcess(simpleModel, processVariables);
  551 + return convertList(simpleNodes, simpleNode -> buildNotRunApproveNodeForSimple(startUserId, bpmnModel,
  552 + processDefinitionInfo, processVariables, simpleNode, runActivityIds));
  553 + }
  554 + throw new IllegalArgumentException("未知设计器类型:" + processDefinitionInfo.getModelType());
  555 + }
  556 +
  557 + private ActivityNode buildNotRunApproveNodeForSimple(Long startUserId, BpmnModel bpmnModel,
  558 + BpmProcessDefinitionInfoDO processDefinitionInfo, Map<String, Object> processVariables,
  559 + BpmSimpleModelNodeVO node, Set<String> runActivityIds) {
  560 + // TODO @芋艿:【可优化】在驳回场景下,未来的预测准确性不高。原因是,驳回后,HistoricActivityInstance
  561 + // 包括了历史的操作,不是只有 startEvent 到当前节点的记录
  562 + if (runActivityIds.contains(node.getId())) {
  563 + return null;
  564 + }
  565 +
  566 + ActivityNode activityNode = new ActivityNode().setId(node.getId()).setName(node.getName())
  567 + .setNodeType(node.getType()).setCandidateStrategy(node.getCandidateStrategy())
  568 + .setStatus(BpmTaskStatusEnum.NOT_START.getStatus());
  569 +
  570 + // 1. 开始节点/审批节点
  571 + if (ObjectUtils.equalsAny(node.getType(),
  572 + BpmSimpleModelNodeTypeEnum.START_USER_NODE.getType(),
  573 + BpmSimpleModelNodeTypeEnum.APPROVE_NODE.getType(),
  574 + BpmSimpleModelNodeTypeEnum.TRANSACTOR_NODE.getType())) {
  575 + List<Long> candidateUserIds = getTaskCandidateUserList(bpmnModel, node.getId(),
  576 + startUserId, processDefinitionInfo.getProcessDefinitionId(), processVariables);
  577 + activityNode.setCandidateUserIds(candidateUserIds);
  578 + return activityNode;
  579 + }
  580 +
  581 + // 2. 结束节点
  582 + if (BpmSimpleModelNodeTypeEnum.END_NODE.getType().equals(node.getType())) {
  583 + return activityNode;
  584 + }
  585 +
  586 + // 3. 抄送节点
  587 + if (CollUtil.isEmpty(runActivityIds) && // 流程发起时:需要展示抄送节点,用于选择抄送人
  588 + BpmSimpleModelNodeTypeEnum.COPY_NODE.getType().equals(node.getType())) {
  589 + List<Long> candidateUserIds = getTaskCandidateUserList(bpmnModel, node.getId(),
  590 + startUserId, processDefinitionInfo.getProcessDefinitionId(), processVariables);
  591 + activityNode.setCandidateUserIds(candidateUserIds);
  592 + return activityNode;
  593 + }
  594 +
  595 + // 4. 子流程节点
  596 + if (BpmSimpleModelNodeTypeEnum.CHILD_PROCESS.getType().equals(node.getType())) {
  597 + return activityNode;
  598 + }
  599 + return null;
  600 + }
  601 +
  602 + private ActivityNode buildNotRunApproveNodeForBpmn(Long startUserId, BpmnModel bpmnModel,
  603 + BpmProcessDefinitionInfoDO processDefinitionInfo, Map<String, Object> processVariables,
  604 + FlowElement node, Set<String> runActivityIds) {
  605 + if (runActivityIds.contains(node.getId())) {
  606 + return null;
  607 + }
  608 + ActivityNode activityNode = new ActivityNode().setId(node.getId())
  609 + .setStatus(BpmTaskStatusEnum.NOT_START.getStatus());
  610 +
  611 + // 1. 开始节点
  612 + if (node instanceof StartEvent) {
  613 + return activityNode.setName(BpmSimpleModelNodeTypeEnum.START_USER_NODE.getName())
  614 + .setNodeType(BpmSimpleModelNodeTypeEnum.START_USER_NODE.getType());
  615 + }
  616 +
  617 + // 2. 审批节点
  618 + if (node instanceof UserTask) {
  619 + List<Long> candidateUserIds = getTaskCandidateUserList(bpmnModel, node.getId(),
  620 + startUserId, processDefinitionInfo.getProcessDefinitionId(), processVariables);
  621 + return activityNode.setName(node.getName()).setNodeType(BpmSimpleModelNodeTypeEnum.APPROVE_NODE.getType())
  622 + .setCandidateStrategy(BpmnModelUtils.parseCandidateStrategy(node))
  623 + .setCandidateUserIds(candidateUserIds);
  624 + }
  625 +
  626 + // 3. 结束节点
  627 + if (node instanceof EndEvent) {
  628 + return activityNode.setName(BpmSimpleModelNodeTypeEnum.END_NODE.getName())
  629 + .setNodeType(BpmSimpleModelNodeTypeEnum.END_NODE.getType());
  630 + }
  631 + return null;
  632 + }
  633 +
  634 + private List<Long> getTaskCandidateUserList(BpmnModel bpmnModel, String activityId,
  635 + Long startUserId, String processDefinitionId, Map<String, Object> processVariables) {
  636 + Set<Long> userIds = taskCandidateInvoker.calculateUsersByActivity(bpmnModel, activityId,
  637 + startUserId, processDefinitionId, processVariables);
  638 + return new ArrayList<>(userIds);
  639 + }
  640 +
  641 + @Override
  642 + public BpmProcessInstanceBpmnModelViewRespVO getProcessInstanceBpmnModelView(String id) {
  643 + // 1.1 获得流程实例
  644 + HistoricProcessInstance processInstance = getHistoricProcessInstance(id);
  645 + if (processInstance == null) {
  646 + return null;
  647 + }
  648 + // 1.2 获得流程定义
  649 + BpmnModel bpmnModel = processDefinitionService
  650 + .getProcessDefinitionBpmnModel(processInstance.getProcessDefinitionId());
  651 + if (bpmnModel == null) {
  652 + return null;
  653 + }
  654 + BpmSimpleModelNodeVO simpleModel = null;
  655 + BpmProcessDefinitionInfoDO processDefinitionInfo = processDefinitionService.getProcessDefinitionInfo(
  656 + processInstance.getProcessDefinitionId());
  657 + if (processDefinitionInfo != null
  658 + && BpmModelTypeEnum.SIMPLE.getType().equals(processDefinitionInfo.getModelType())) {
  659 + simpleModel = JsonUtils.parseObject(processDefinitionInfo.getSimpleModel(), BpmSimpleModelNodeVO.class);
  660 + }
  661 + // 1.3 获得流程实例对应的活动实例列表 + 任务列表
  662 + List<HistoricActivityInstance> activities = taskService.getActivityListByProcessInstanceId(id);
  663 + List<HistoricTaskInstance> tasks = taskService.getTaskListByProcessInstanceId(id, true);
  664 +
  665 + // 2.1 拼接进度信息
  666 + Set<String> unfinishedTaskActivityIds = convertSet(activities, HistoricActivityInstance::getActivityId,
  667 + activityInstance -> activityInstance.getEndTime() == null);
  668 + Set<String> finishedTaskActivityIds = convertSet(activities, HistoricActivityInstance::getActivityId,
  669 + activityInstance -> activityInstance.getEndTime() != null
  670 + && ObjectUtil.notEqual(activityInstance.getActivityType(),
  671 + BpmnXMLConstants.ELEMENT_SEQUENCE_FLOW));
  672 + Set<String> finishedSequenceFlowActivityIds = convertSet(activities, HistoricActivityInstance::getActivityId,
  673 + activityInstance -> activityInstance.getEndTime() != null
  674 + && ObjectUtil.equals(activityInstance.getActivityType(),
  675 + BpmnXMLConstants.ELEMENT_SEQUENCE_FLOW));
  676 + // 特殊:会签情况下,会有部分已完成(审批)、部分未完成(待审批),此时需要 finishedTaskActivityIds 移除掉
  677 + finishedTaskActivityIds.removeAll(unfinishedTaskActivityIds);
  678 + // 特殊:如果流程实例被拒绝,则需要计算是哪个活动节点。
  679 + // 注意,只取最后一个。因为会存在多次拒绝的情况,拒绝驳回到指定节点
  680 + Set<String> rejectTaskActivityIds = CollUtil.newHashSet();
  681 + if (BpmProcessInstanceStatusEnum.isRejectStatus(FlowableUtils.getProcessInstanceStatus(processInstance))) {
  682 + tasks.stream()
  683 + .filter(task -> BpmTaskStatusEnum.isRejectStatus(FlowableUtils.getTaskStatus(task)))
  684 + .max(Comparator.comparing(HistoricTaskInstance::getEndTime))
  685 + .ifPresent(reject -> rejectTaskActivityIds.add(reject.getTaskDefinitionKey()));
  686 + finishedTaskActivityIds.removeAll(rejectTaskActivityIds);
  687 + }
  688 +
  689 + // 2.2 拼接基础信息
  690 + Set<Long> userIds = BpmProcessInstanceConvert.INSTANCE.parseUserIds02(processInstance, tasks);
  691 + Map<Long, AdminUserRespDTO> userMap = adminUserApi.getUserMap(userIds);
  692 + Map<Long, DeptRespDTO> deptMap = deptApi.getDeptMap(convertSet(userMap.values(), AdminUserRespDTO::getDeptId));
  693 + return BpmProcessInstanceConvert.INSTANCE.buildProcessInstanceBpmnModelView(processInstance, tasks, bpmnModel,
  694 + simpleModel,
  695 + unfinishedTaskActivityIds, finishedTaskActivityIds, finishedSequenceFlowActivityIds,
  696 + rejectTaskActivityIds,
  697 + userMap, deptMap);
  698 + }
  699 +
  700 + // ========== Update 写入相关方法 ==========
  701 +
  702 + @Override
  703 + @Transactional(rollbackFor = Exception.class)
  704 + public String createProcessInstance(Long userId, @Valid BpmProcessInstanceCreateReqVO createReqVO) {
  705 + // 获得流程定义
  706 + ProcessDefinition definition = processDefinitionService
  707 + .getProcessDefinition(createReqVO.getProcessDefinitionId());
  708 + // 发起流程
  709 + return createProcessInstance0(userId, definition, createReqVO.getVariables(), null,
  710 + createReqVO.getStartUserSelectAssignees());
  711 + }
  712 +
  713 + @Override
  714 + public String createProcessInstance(Long userId, @Valid BpmProcessInstanceCreateReqDTO createReqDTO) {
  715 + return FlowableUtils.executeAuthenticatedUserId(userId, () -> {
  716 + // 获得流程定义
  717 + ProcessDefinition definition = processDefinitionService
  718 + .getActiveProcessDefinition(createReqDTO.getProcessDefinitionKey());
  719 + // 发起流程
  720 + return createProcessInstance0(userId, definition, createReqDTO.getVariables(),
  721 + createReqDTO.getBusinessKey(),
  722 + createReqDTO.getStartUserSelectAssignees());
  723 + });
  724 + }
  725 +
  726 + private String createProcessInstance0(Long userId, ProcessDefinition definition,
  727 + Map<String, Object> variables, String businessKey,
  728 + Map<String, List<Long>> startUserSelectAssignees) {
  729 + // 1.1 校验流程定义
  730 + if (definition == null) {
  731 + throw exception(PROCESS_DEFINITION_NOT_EXISTS);
  732 + }
  733 + if (definition.isSuspended()) {
  734 + throw exception(PROCESS_DEFINITION_IS_SUSPENDED);
  735 + }
  736 + BpmProcessDefinitionInfoDO processDefinitionInfo = processDefinitionService
  737 + .getProcessDefinitionInfo(definition.getId());
  738 + if (processDefinitionInfo == null) {
  739 + throw exception(PROCESS_DEFINITION_NOT_EXISTS);
  740 + }
  741 + // 1.2 校验是否能够发起
  742 + if (!processDefinitionService.canUserStartProcessDefinition(processDefinitionInfo, userId)) {
  743 + throw exception(PROCESS_INSTANCE_START_USER_CAN_START);
  744 + }
  745 + // 1.3 校验发起人自选审批人
  746 + validateStartUserSelectAssignees(userId, definition, startUserSelectAssignees, variables);
  747 +
  748 + // 2. 创建流程实例
  749 + if (variables == null) {
  750 + variables = new HashMap<>();
  751 + }
  752 + FlowableUtils.filterProcessInstanceFormVariable(variables); // 过滤一下,避免 ProcessInstance 系统级的变量被占用
  753 + variables.put(BpmnVariableConstants.PROCESS_INSTANCE_VARIABLE_START_USER_ID, userId); // 设置流程变量,发起人 ID
  754 + variables.put(BpmnVariableConstants.PROCESS_INSTANCE_VARIABLE_STATUS, // 流程实例状态:审批中
  755 + BpmProcessInstanceStatusEnum.RUNNING.getStatus());
  756 + variables.put(BpmnVariableConstants.PROCESS_INSTANCE_SKIP_EXPRESSION_ENABLED, true); // 跳过表达式需要添加此变量为 true,不影响没配置 skipExpression 的节点
  757 + if (CollUtil.isNotEmpty(startUserSelectAssignees)) {
  758 + // 设置流程变量,发起人自选审批人
  759 + variables.put(BpmnVariableConstants.PROCESS_INSTANCE_VARIABLE_START_USER_SELECT_ASSIGNEES,
  760 + startUserSelectAssignees);
  761 + }
  762 +
  763 + // 3. 创建流程
  764 + ProcessInstanceBuilder processInstanceBuilder = runtimeService.createProcessInstanceBuilder()
  765 + .processDefinitionId(definition.getId())
  766 + .businessKey(businessKey)
  767 + .variables(variables);
  768 + // 3.1 创建流程 ID
  769 + BpmModelMetaInfoVO.ProcessIdRule processIdRule = processDefinitionInfo.getProcessIdRule();
  770 + if (processIdRule != null && Boolean.TRUE.equals(processIdRule.getEnable())) {
  771 + processInstanceBuilder.predefineProcessInstanceId(processIdRedisDAO.generate(processIdRule));
  772 + }
  773 + // 3.2 流程名称
  774 + BpmModelMetaInfoVO.TitleSetting titleSetting = processDefinitionInfo.getTitleSetting();
  775 + if (titleSetting != null && Boolean.TRUE.equals(titleSetting.getEnable())) {
  776 + AdminUserRespDTO user = adminUserApi.getUser(userId);
  777 + Map<String, Object> cloneVariables = new HashMap<>(variables);
  778 + cloneVariables.put(BpmnVariableConstants.PROCESS_INSTANCE_VARIABLE_START_USER_ID, user.getNickname());
  779 + cloneVariables.put(BpmnVariableConstants.PROCESS_START_TIME, DateUtil.now());
  780 + cloneVariables.put(BpmnVariableConstants.PROCESS_DEFINITION_NAME, definition.getName().trim());
  781 + processInstanceBuilder.name(StrUtil.format(titleSetting.getTitle(), cloneVariables));
  782 + } else {
  783 + processInstanceBuilder.name(definition.getName().trim());
  784 + }
  785 + // 3.3 发起流程实例
  786 + ProcessInstance instance = processInstanceBuilder.start();
  787 + return instance.getId();
  788 + }
  789 +
  790 + private void validateStartUserSelectAssignees(Long userId, ProcessDefinition definition,
  791 + Map<String, List<Long>> startUserSelectAssignees,
  792 + Map<String, Object> variables) {
  793 + // 1. 获取预测的节点信息
  794 + BpmApprovalDetailRespVO detailRespVO = getApprovalDetail(userId, new BpmApprovalDetailReqVO()
  795 + .setProcessDefinitionId(definition.getId())
  796 + .setProcessVariables(variables));
  797 + List<ActivityNode> activityNodes = detailRespVO.getActivityNodes();
  798 + if (CollUtil.isEmpty(activityNodes)) {
  799 + return;
  800 + }
  801 +
  802 + // 2.1 移除掉不是发起人自选审批人节点
  803 + activityNodes.removeIf(task ->
  804 + ObjectUtil.notEqual(BpmTaskCandidateStrategyEnum.START_USER_SELECT.getStrategy(), task.getCandidateStrategy()));
  805 + // 2.2 流程发起时要先获取当前流程的预测走向节点,发起时只校验预测的节点发起人自选审批人的审批人和抄送人是否都配置了
  806 + activityNodes.forEach(task -> {
  807 + List<Long> assignees = startUserSelectAssignees != null ? startUserSelectAssignees.get(task.getId()) : null;
  808 + if (CollUtil.isEmpty(assignees)) {
  809 + throw exception(PROCESS_INSTANCE_START_USER_SELECT_ASSIGNEES_NOT_CONFIG, task.getName());
  810 + }
  811 + Map<Long, AdminUserRespDTO> userMap = adminUserApi.getUserMap(assignees);
  812 + assignees.forEach(assignee -> {
  813 + if (userMap.get(assignee) == null) {
  814 + throw exception(PROCESS_INSTANCE_START_USER_SELECT_ASSIGNEES_NOT_EXISTS, task.getName(), assignee);
  815 + }
  816 + });
  817 + });
  818 + }
  819 +
  820 + @Override
  821 + public void cancelProcessInstanceByStartUser(Long userId, @Valid BpmProcessInstanceCancelReqVO cancelReqVO) {
  822 + // 1.1 校验流程实例存在
  823 + ProcessInstance instance = getProcessInstance(cancelReqVO.getId());
  824 + if (instance == null) {
  825 + throw exception(PROCESS_INSTANCE_CANCEL_FAIL_NOT_EXISTS);
  826 + }
  827 + // 1.2 只能取消自己的
  828 + if (!Objects.equals(instance.getStartUserId(), String.valueOf(userId))) {
  829 + throw exception(PROCESS_INSTANCE_CANCEL_FAIL_NOT_SELF);
  830 + }
  831 + // 1.3 校验允许撤销审批中的申请
  832 + BpmProcessDefinitionInfoDO processDefinitionInfo = processDefinitionService
  833 + .getProcessDefinitionInfo(instance.getProcessDefinitionId());
  834 + Assert.notNull(processDefinitionInfo, "流程定义({})不存在", processDefinitionInfo);
  835 + if (processDefinitionInfo.getAllowCancelRunningProcess() != null // 防止未配置 AllowCancelRunningProcess , 默认为可取消
  836 + && Boolean.FALSE.equals(processDefinitionInfo.getAllowCancelRunningProcess())) {
  837 + throw exception(PROCESS_INSTANCE_CANCEL_FAIL_NOT_ALLOW);
  838 + }
  839 + // 1.4 子流程不允许取消
  840 + if (StrUtil.isNotBlank(instance.getSuperExecutionId())) {
  841 + throw exception(PROCESS_INSTANCE_CANCEL_CHILD_FAIL_NOT_ALLOW);
  842 + }
  843 +
  844 + // 2. 取消流程
  845 + updateProcessInstanceCancel(cancelReqVO.getId(),
  846 + BpmReasonEnum.CANCEL_PROCESS_INSTANCE_BY_START_USER.format(cancelReqVO.getReason()));
  847 + }
  848 +
  849 + @Override
  850 + public void cancelProcessInstanceByAdmin(Long userId, BpmProcessInstanceCancelReqVO cancelReqVO) {
  851 + // 1.1 校验流程实例存在
  852 + ProcessInstance instance = getProcessInstance(cancelReqVO.getId());
  853 + if (instance == null) {
  854 + throw exception(PROCESS_INSTANCE_CANCEL_FAIL_NOT_EXISTS);
  855 + }
  856 +
  857 + // 2. 取消流程
  858 + AdminUserRespDTO user = adminUserApi.getUser(userId);
  859 + updateProcessInstanceCancel(cancelReqVO.getId(),
  860 + BpmReasonEnum.CANCEL_PROCESS_INSTANCE_BY_ADMIN.format(user.getNickname(), cancelReqVO.getReason()));
  861 + }
  862 +
  863 + private void updateProcessInstanceCancel(String id, String reason) {
  864 + // 1. 更新流程实例 status
  865 + runtimeService.setVariable(id, BpmnVariableConstants.PROCESS_INSTANCE_VARIABLE_STATUS,
  866 + BpmProcessInstanceStatusEnum.CANCEL.getStatus());
  867 + runtimeService.setVariable(id, BpmnVariableConstants.PROCESS_INSTANCE_VARIABLE_REASON, reason);
  868 +
  869 + // 2. 取消所有子流程
  870 + List<ProcessInstance> childProcessInstances = runtimeService.createProcessInstanceQuery()
  871 + .superProcessInstanceId(id).list();
  872 + childProcessInstances.forEach(processInstance -> updateProcessInstanceCancel(
  873 + processInstance.getProcessInstanceId(), BpmReasonEnum.CANCEL_CHILD_PROCESS_INSTANCE_BY_MAIN_PROCESS.getReason()));
  874 +
  875 + // 3. 结束流程
  876 + taskService.moveTaskToEnd(id, reason);
  877 + }
  878 +
  879 + @Override
  880 + public void updateProcessInstanceReject(ProcessInstance processInstance, String reason) {
  881 + runtimeService.setVariable(processInstance.getProcessInstanceId(),
  882 + BpmnVariableConstants.PROCESS_INSTANCE_VARIABLE_STATUS,
  883 + BpmProcessInstanceStatusEnum.REJECT.getStatus());
  884 + runtimeService.setVariable(processInstance.getProcessInstanceId(),
  885 + BpmnVariableConstants.PROCESS_INSTANCE_VARIABLE_REASON,
  886 + BpmReasonEnum.REJECT_TASK.format(reason));
  887 + }
  888 +
  889 + @Override
  890 + public void updateProcessInstanceVariables(String id, Map<String, Object> variables) {
  891 + runtimeService.setVariables(id, variables);
  892 + }
  893 +
  894 + @Override
  895 + public void removeProcessInstanceVariables(String id, Collection<String> variableNames) {
  896 + runtimeService.removeVariables(id, variableNames);
  897 + }
  898 +
  899 + // ========== Event 事件相关方法 ==========
  900 +
  901 + @Override
  902 + public void processProcessInstanceCompleted(ProcessInstance instance) {
  903 + // 注意:需要基于 instance 设置租户编号,避免 Flowable 内部异步时,丢失租户编号
  904 + FlowableUtils.execute(instance.getTenantId(), () -> {
  905 + // 1.1 获取当前状态
  906 + Integer status = (Integer) instance.getProcessVariables()
  907 + .get(BpmnVariableConstants.PROCESS_INSTANCE_VARIABLE_STATUS);
  908 + String reason = (String) instance.getProcessVariables()
  909 + .get(BpmnVariableConstants.PROCESS_INSTANCE_VARIABLE_REASON);
  910 + // 1.2 当流程状态还是审批状态中,说明审批通过了,则变更下它的状态
  911 + // 为什么这么处理?因为流程完成,并且完成了,说明审批通过了
  912 + if (Objects.equals(status, BpmProcessInstanceStatusEnum.RUNNING.getStatus())) {
  913 + status = BpmProcessInstanceStatusEnum.APPROVE.getStatus();
  914 + runtimeService.setVariable(instance.getId(), BpmnVariableConstants.PROCESS_INSTANCE_VARIABLE_STATUS,
  915 + status);
  916 + }
  917 +
  918 + // 2. 发送对应的消息通知
  919 + if (Objects.equals(status, BpmProcessInstanceStatusEnum.APPROVE.getStatus())) {
  920 + messageService.sendMessageWhenProcessInstanceApprove(
  921 + BpmProcessInstanceConvert.INSTANCE.buildProcessInstanceApproveMessage(instance));
  922 + } else if (Objects.equals(status, BpmProcessInstanceStatusEnum.REJECT.getStatus())) {
  923 + messageService.sendMessageWhenProcessInstanceReject(
  924 + BpmProcessInstanceConvert.INSTANCE.buildProcessInstanceRejectMessage(instance, reason));
  925 + }
  926 +
  927 + // 3. 发送流程实例的状态事件
  928 + processInstanceEventPublisher.sendProcessInstanceResultEvent(
  929 + BpmProcessInstanceConvert.INSTANCE.buildProcessInstanceStatusEvent(this, instance, status));
  930 +
  931 + // 4. 流程后置通知
  932 + if (Objects.equals(status, BpmProcessInstanceStatusEnum.APPROVE.getStatus())) {
  933 + BpmProcessDefinitionInfoDO processDefinitionInfo = processDefinitionService.
  934 + getProcessDefinitionInfo(instance.getProcessDefinitionId());
  935 + if (ObjUtil.isNotNull(processDefinitionInfo) &&
  936 + ObjUtil.isNotNull(processDefinitionInfo.getProcessAfterTriggerSetting())) {
  937 + BpmModelMetaInfoVO.HttpRequestSetting setting = processDefinitionInfo.getProcessAfterTriggerSetting();
  938 +
  939 + BpmHttpRequestUtils.executeBpmHttpRequest(instance,
  940 + setting.getUrl(), setting.getHeader(), setting.getBody(), true, setting.getResponse());
  941 + }
  942 + }
  943 + });
  944 + }
  945 +
  946 + @Override
  947 + public void processProcessInstanceCreated(ProcessInstance instance) {
  948 + // 注意:需要基于 instance 设置租户编号,避免 Flowable 内部异步时,丢失租户编号
  949 + FlowableUtils.execute(instance.getTenantId(), () -> {
  950 + // 流程前置通知
  951 + BpmProcessDefinitionInfoDO processDefinitionInfo = processDefinitionService.
  952 + getProcessDefinitionInfo(instance.getProcessDefinitionId());
  953 + if (ObjUtil.isNull(processDefinitionInfo) ||
  954 + ObjUtil.isNull(processDefinitionInfo.getProcessBeforeTriggerSetting())) {
  955 + return;
  956 + }
  957 + BpmModelMetaInfoVO.HttpRequestSetting setting = processDefinitionInfo.getProcessBeforeTriggerSetting();
  958 + BpmHttpRequestUtils.executeBpmHttpRequest(instance,
  959 + setting.getUrl(), setting.getHeader(), setting.getBody(), true, setting.getResponse());
  960 + });
  961 + }
  962 +
  963 +}
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmTaskService.java renamed to yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmTaskService.java
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmTaskServiceImpl.java renamed to yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmTaskServiceImpl.java
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/task/listener/BpmCallActivityListener.java renamed to yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/service/task/listener/BpmCallActivityListener.java
yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/service/task/listener/BpmUserTaskListener.java 0 → 100644
  1 +package cn.iocoder.yudao.module.bpm.service.task.listener;
  2 +
  3 +import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.model.simple.BpmSimpleModelNodeVO;
  4 +import cn.iocoder.yudao.module.bpm.enums.definition.BpmHttpRequestParamTypeEnum;
  5 +import cn.iocoder.yudao.module.bpm.framework.flowable.core.util.BpmHttpRequestUtils;
  6 +import cn.iocoder.yudao.module.bpm.service.task.BpmProcessInstanceService;
  7 +import jakarta.annotation.Resource;
  8 +import lombok.Setter;
  9 +import lombok.extern.slf4j.Slf4j;
  10 +import org.flowable.engine.delegate.TaskListener;
  11 +import org.flowable.engine.impl.el.FixedValue;
  12 +import org.flowable.engine.runtime.ProcessInstance;
  13 +import org.flowable.task.service.delegate.DelegateTask;
  14 +import org.springframework.context.annotation.Scope;
  15 +import org.springframework.stereotype.Component;
  16 +
  17 +import static cn.iocoder.yudao.module.bpm.framework.flowable.core.util.BpmnModelUtils.parseListenerConfig;
  18 +
  19 +// TODO @芋艿:可能会想换个包地址
  20 +/**
  21 + * BPM 用户任务通用监听器
  22 + *
  23 + * @author Lesan
  24 + */
  25 +@Component
  26 +@Slf4j
  27 +@Scope("prototype")
  28 +public class BpmUserTaskListener implements TaskListener {
  29 +
  30 + public static final String DELEGATE_EXPRESSION = "${bpmUserTaskListener}";
  31 +
  32 + @Resource
  33 + private BpmProcessInstanceService processInstanceService;
  34 +
  35 + @Setter
  36 + private FixedValue listenerConfig;
  37 +
  38 + @Override
  39 + public void notify(DelegateTask delegateTask) {
  40 + // 1. 获取所需基础信息
  41 + ProcessInstance processInstance = processInstanceService.getProcessInstance(delegateTask.getProcessInstanceId());
  42 + BpmSimpleModelNodeVO.ListenerHandler listenerHandler = parseListenerConfig(listenerConfig);
  43 +
  44 + // 2. 发起请求
  45 + // TODO @芋艿:哪些默认参数,后续再调研下;感觉可以搞个 task 字段,把整个 delegateTask 放进去;
  46 + listenerHandler.getBody().add(new BpmSimpleModelNodeVO.HttpRequestParam().setKey("processInstanceId")
  47 + .setType(BpmHttpRequestParamTypeEnum.FIXED_VALUE.getType()).setValue(delegateTask.getProcessInstanceId()));
  48 + listenerHandler.getBody().add(new BpmSimpleModelNodeVO.HttpRequestParam().setKey("assignee")
  49 + .setType(BpmHttpRequestParamTypeEnum.FIXED_VALUE.getType()).setValue(delegateTask.getAssignee()));
  50 + listenerHandler.getBody().add(new BpmSimpleModelNodeVO.HttpRequestParam().setKey("taskDefinitionKey")
  51 + .setType(BpmHttpRequestParamTypeEnum.FIXED_VALUE.getType()).setValue(delegateTask.getTaskDefinitionKey()));
  52 + listenerHandler.getBody().add(new BpmSimpleModelNodeVO.HttpRequestParam().setKey("taskId")
  53 + .setType(BpmHttpRequestParamTypeEnum.FIXED_VALUE.getType()).setValue(delegateTask.getId()));
  54 + BpmHttpRequestUtils.executeBpmHttpRequest(processInstance,
  55 + listenerHandler.getPath(), listenerHandler.getHeader(), listenerHandler.getBody(), false, null);
  56 +
  57 + // 3. 是否需要后续操作?TODO 芋艿:待定!
  58 + }
  59 +}
0 \ No newline at end of file 60 \ No newline at end of file
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/task/trigger/BpmTrigger.java renamed to yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/service/task/trigger/BpmTrigger.java
yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/service/task/trigger/form/BpmFormDeleteTrigger.java 0 → 100644
  1 +package cn.iocoder.yudao.module.bpm.service.task.trigger.form;
  2 +
  3 +import cn.hutool.core.collection.CollUtil;
  4 +import cn.iocoder.yudao.framework.common.util.json.JsonUtils;
  5 +import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.model.simple.BpmSimpleModelNodeVO;
  6 +import cn.iocoder.yudao.module.bpm.enums.definition.BpmTriggerTypeEnum;
  7 +import cn.iocoder.yudao.module.bpm.framework.flowable.core.util.BpmnModelUtils;
  8 +import cn.iocoder.yudao.module.bpm.framework.flowable.core.util.SimpleModelUtils;
  9 +import cn.iocoder.yudao.module.bpm.service.task.BpmProcessInstanceService;
  10 +import cn.iocoder.yudao.module.bpm.service.task.trigger.BpmTrigger;
  11 +import com.fasterxml.jackson.core.type.TypeReference;
  12 +import jakarta.annotation.Resource;
  13 +import lombok.extern.slf4j.Slf4j;
  14 +import org.springframework.stereotype.Component;
  15 +
  16 +import java.util.HashSet;
  17 +import java.util.List;
  18 +import java.util.Map;
  19 +import java.util.Set;
  20 +
  21 +/**
  22 + * BPM 删除流程表单数据触发器
  23 + *
  24 + * @author jason
  25 + */
  26 +@Component
  27 +@Slf4j
  28 +public class BpmFormDeleteTrigger implements BpmTrigger {
  29 +
  30 + @Resource
  31 + private BpmProcessInstanceService processInstanceService;
  32 +
  33 + @Override
  34 + public BpmTriggerTypeEnum getType() {
  35 + return BpmTriggerTypeEnum.FORM_DELETE;
  36 + }
  37 +
  38 + @Override
  39 + public void execute(String processInstanceId, String param) {
  40 + // 1. 解析删除流程表单数据配置
  41 + List<BpmSimpleModelNodeVO.TriggerSetting.FormTriggerSetting> settings = JsonUtils.parseObject(param, new TypeReference<>() {});
  42 + if (CollUtil.isEmpty(settings)) {
  43 + log.error("[execute][流程({}) 删除流程表单数据触发器配置为空]", processInstanceId);
  44 + return;
  45 + }
  46 +
  47 + // 2. 获取流程变量
  48 + Map<String, Object> processVariables = processInstanceService.getProcessInstance(processInstanceId).getProcessVariables();
  49 +
  50 + // 3.1 获取需要删除的表单字段
  51 + Set<String> deleteFields = new HashSet<>();
  52 + settings.forEach(setting -> {
  53 + if (CollUtil.isEmpty(setting.getDeleteFields())) {
  54 + return;
  55 + }
  56 + // 配置了条件,判断条件是否满足
  57 + boolean isFieldDeletedNeeded = true;
  58 + if (setting.getConditionType() != null) {
  59 + String conditionExpression = SimpleModelUtils.buildConditionExpression(
  60 + setting.getConditionType(), setting.getConditionExpression(), setting.getConditionGroups());
  61 + isFieldDeletedNeeded = BpmnModelUtils.evalConditionExpress(processVariables, conditionExpression);
  62 + }
  63 + if (isFieldDeletedNeeded) {
  64 + deleteFields.addAll(setting.getDeleteFields());
  65 + }
  66 + });
  67 +
  68 + // 3.2 删除流程变量
  69 + if (CollUtil.isNotEmpty(deleteFields)) {
  70 + processInstanceService.removeProcessInstanceVariables(processInstanceId, deleteFields);
  71 + }
  72 + }
  73 +}
yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/service/task/trigger/form/BpmFormUpdateTrigger.java 0 → 100644
  1 +package cn.iocoder.yudao.module.bpm.service.task.trigger.form;
  2 +
  3 +import cn.hutool.core.collection.CollUtil;
  4 +import cn.iocoder.yudao.framework.common.util.json.JsonUtils;
  5 +import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.model.simple.BpmSimpleModelNodeVO.TriggerSetting.FormTriggerSetting;
  6 +import cn.iocoder.yudao.module.bpm.enums.definition.BpmTriggerTypeEnum;
  7 +import cn.iocoder.yudao.module.bpm.framework.flowable.core.util.BpmnModelUtils;
  8 +import cn.iocoder.yudao.module.bpm.framework.flowable.core.util.SimpleModelUtils;
  9 +import cn.iocoder.yudao.module.bpm.service.task.BpmProcessInstanceService;
  10 +import cn.iocoder.yudao.module.bpm.service.task.trigger.BpmTrigger;
  11 +import com.fasterxml.jackson.core.type.TypeReference;
  12 +import jakarta.annotation.Resource;
  13 +import lombok.extern.slf4j.Slf4j;
  14 +import org.springframework.stereotype.Component;
  15 +
  16 +import java.util.List;
  17 +import java.util.Map;
  18 +
  19 +/**
  20 + * BPM 更新流程表单触发器
  21 + *
  22 + * @author jason
  23 + */
  24 +@Component
  25 +@Slf4j
  26 +public class BpmFormUpdateTrigger implements BpmTrigger {
  27 +
  28 + @Resource
  29 + private BpmProcessInstanceService processInstanceService;
  30 +
  31 + @Override
  32 + public BpmTriggerTypeEnum getType() {
  33 + return BpmTriggerTypeEnum.FORM_UPDATE;
  34 + }
  35 +
  36 + @Override
  37 + public void execute(String processInstanceId, String param) {
  38 + // 1. 解析更新流程表单配置
  39 + List<FormTriggerSetting> settings = JsonUtils.parseObject(param, new TypeReference<>() {});
  40 + if (CollUtil.isEmpty(settings)) {
  41 + log.error("[execute][流程({}) 更新流程表单触发器配置为空]", processInstanceId);
  42 + return;
  43 + }
  44 +
  45 + // 2. 获取流程变量
  46 + Map<String, Object> processVariables = processInstanceService.getProcessInstance(processInstanceId).getProcessVariables();
  47 +
  48 + // 3. 更新流程变量
  49 + for (FormTriggerSetting setting : settings) {
  50 + if (CollUtil.isEmpty(setting.getUpdateFormFields())) {
  51 + continue;
  52 + }
  53 + // 配置了条件,判断条件是否满足
  54 + boolean isFormUpdateNeeded = true;
  55 + if (setting.getConditionType() != null) {
  56 + String conditionExpression = SimpleModelUtils.buildConditionExpression(
  57 + setting.getConditionType(), setting.getConditionExpression(), setting.getConditionGroups());
  58 + isFormUpdateNeeded = BpmnModelUtils.evalConditionExpress(processVariables, conditionExpression);
  59 + }
  60 + // 更新流程表单
  61 + if (isFormUpdateNeeded) {
  62 + processInstanceService.updateProcessInstanceVariables(processInstanceId, setting.getUpdateFormFields());
  63 + }
  64 + }
  65 + }
  66 +}
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/task/trigger/http/BpmAbstractHttpRequestTrigger.java renamed to yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/service/task/trigger/http/BpmAbstractHttpRequestTrigger.java
yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/service/task/trigger/http/BpmHttpCallbackTrigger.java 0 → 100644
  1 +package cn.iocoder.yudao.module.bpm.service.task.trigger.http;
  2 +
  3 +import cn.iocoder.yudao.framework.common.util.json.JsonUtils;
  4 +import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.model.simple.BpmSimpleModelNodeVO;
  5 +import cn.iocoder.yudao.module.bpm.enums.definition.BpmHttpRequestParamTypeEnum;
  6 +import cn.iocoder.yudao.module.bpm.enums.definition.BpmTriggerTypeEnum;
  7 +import cn.iocoder.yudao.module.bpm.framework.flowable.core.util.BpmHttpRequestUtils;
  8 +import cn.iocoder.yudao.module.bpm.service.task.BpmProcessInstanceService;
  9 +import jakarta.annotation.Resource;
  10 +import lombok.extern.slf4j.Slf4j;
  11 +import org.flowable.engine.runtime.ProcessInstance;
  12 +import org.springframework.stereotype.Component;
  13 +import org.springframework.web.client.RestTemplate;
  14 +
  15 +/**
  16 + * BPM HTTP 回调触发器
  17 + *
  18 + * @author jason
  19 + */
  20 +@Component
  21 +@Slf4j
  22 +public class BpmHttpCallbackTrigger extends BpmAbstractHttpRequestTrigger {
  23 +
  24 + @Resource
  25 + private BpmProcessInstanceService processInstanceService;
  26 +
  27 + @Override
  28 + public BpmTriggerTypeEnum getType() {
  29 + return BpmTriggerTypeEnum.HTTP_CALLBACK;
  30 + }
  31 +
  32 + @Override
  33 + public void execute(String processInstanceId, String param) {
  34 + // 1. 解析 http 请求配置
  35 + BpmSimpleModelNodeVO.TriggerSetting.HttpRequestTriggerSetting setting = JsonUtils.parseObject(param,
  36 + BpmSimpleModelNodeVO.TriggerSetting.HttpRequestTriggerSetting.class);
  37 + if (setting == null) {
  38 + log.error("[execute][流程({}) HTTP 回调触发器配置为空]", processInstanceId);
  39 + return;
  40 + }
  41 +
  42 + // 2. 发起请求
  43 + ProcessInstance processInstance = processInstanceService.getProcessInstance(processInstanceId);
  44 + setting.getBody().add(new BpmSimpleModelNodeVO.HttpRequestParam()
  45 + .setKey("taskDefineKey") // 重要:回调请求 taskDefineKey 需要传给被调用方,用于回调执行
  46 + .setType(BpmHttpRequestParamTypeEnum.FIXED_VALUE.getType()).setValue(setting.getCallbackTaskDefineKey()));
  47 + BpmHttpRequestUtils.executeBpmHttpRequest(processInstance,
  48 + setting.getUrl(), setting.getHeader(), setting.getBody(), false, null);
  49 + }
  50 +
  51 +}
yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/service/task/trigger/http/BpmSyncHttpRequestTrigger.java 0 → 100644
  1 +package cn.iocoder.yudao.module.bpm.service.task.trigger.http;
  2 +
  3 +import cn.iocoder.yudao.framework.common.util.json.JsonUtils;
  4 +import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.model.simple.BpmSimpleModelNodeVO.TriggerSetting.HttpRequestTriggerSetting;
  5 +import cn.iocoder.yudao.module.bpm.enums.definition.BpmTriggerTypeEnum;
  6 +import cn.iocoder.yudao.module.bpm.framework.flowable.core.util.BpmHttpRequestUtils;
  7 +import cn.iocoder.yudao.module.bpm.service.task.BpmProcessInstanceService;
  8 +import jakarta.annotation.Resource;
  9 +import lombok.extern.slf4j.Slf4j;
  10 +import org.flowable.engine.runtime.ProcessInstance;
  11 +import org.springframework.stereotype.Component;
  12 +import org.springframework.web.client.RestTemplate;
  13 +
  14 +/**
  15 + * BPM 发送同步 HTTP 请求触发器
  16 + *
  17 + * @author jason
  18 + */
  19 +@Component
  20 +@Slf4j
  21 +public class BpmSyncHttpRequestTrigger extends BpmAbstractHttpRequestTrigger {
  22 +
  23 + @Resource
  24 + private BpmProcessInstanceService processInstanceService;
  25 +
  26 + @Override
  27 + public BpmTriggerTypeEnum getType() {
  28 + return BpmTriggerTypeEnum.HTTP_REQUEST;
  29 + }
  30 +
  31 + @Override
  32 + public void execute(String processInstanceId, String param) {
  33 + // 1. 解析 http 请求配置
  34 + HttpRequestTriggerSetting setting = JsonUtils.parseObject(param, HttpRequestTriggerSetting.class);
  35 + if (setting == null) {
  36 + log.error("[execute][流程({}) HTTP 触发器请求配置为空]", processInstanceId);
  37 + return;
  38 + }
  39 +
  40 + // 2. 发起请求
  41 + ProcessInstance processInstance = processInstanceService.getProcessInstance(processInstanceId);
  42 + BpmHttpRequestUtils.executeBpmHttpRequest(processInstance,
  43 + setting.getUrl(), setting.getHeader(), setting.getBody(), true, setting.getResponse());
  44 + }
  45 +
  46 +}
yudao-module-bpm/yudao-module-bpm-biz/src/test/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/candidate/BpmTaskCandidateInvokerTest.java renamed to yudao-module-bpm/src/test/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/candidate/BpmTaskCandidateInvokerTest.java
yudao-module-bpm/yudao-module-bpm-biz/src/test/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/candidate/expression/BpmTaskAssignLeaderExpressionTest.java renamed to yudao-module-bpm/src/test/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/candidate/expression/BpmTaskAssignLeaderExpressionTest.java
yudao-module-bpm/src/test/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/candidate/strategy/dept/BpmTaskCandidateDeptLeaderMultiStrategyTest.java 0 → 100644
  1 +package cn.iocoder.yudao.module.bpm.framework.flowable.core.candidate.strategy.dept;
  2 +
  3 +import cn.iocoder.yudao.framework.test.core.ut.BaseMockitoUnitTest;
  4 +import cn.iocoder.yudao.module.system.api.dept.DeptApi;
  5 +import cn.iocoder.yudao.module.system.api.dept.dto.DeptRespDTO;
  6 +import org.assertj.core.util.Sets;
  7 +import org.junit.jupiter.api.Test;
  8 +import org.mockito.InjectMocks;
  9 +import org.mockito.Mock;
  10 +import org.mockito.stubbing.Answer;
  11 +
  12 +import java.util.Set;
  13 +
  14 +import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomPojo;
  15 +import static org.junit.jupiter.api.Assertions.assertEquals;
  16 +import static org.mockito.ArgumentMatchers.any;
  17 +import static org.mockito.Mockito.when;
  18 +
  19 +public class BpmTaskCandidateDeptLeaderMultiStrategyTest extends BaseMockitoUnitTest {
  20 +
  21 + @InjectMocks
  22 + private BpmTaskCandidateDeptLeaderMultiStrategy strategy;
  23 +
  24 + @Mock
  25 + private DeptApi deptApi;
  26 +
  27 + @Test
  28 + public void testCalculateUsers() {
  29 + // 准备参数
  30 + String param = "10,20|2";
  31 + // mock 方法
  32 + when(deptApi.getDept(any())).thenAnswer((Answer<DeptRespDTO>) invocationOnMock -> {
  33 + Long deptId = invocationOnMock.getArgument(0);
  34 + return randomPojo(DeptRespDTO.class, o -> o.setId(deptId).setParentId(deptId * 100).setLeaderUserId(deptId + 1));
  35 + });
  36 +
  37 + // 调用
  38 + Set<Long> userIds = strategy.calculateUsers(param);
  39 + // 断言结果
  40 + assertEquals(Sets.newLinkedHashSet(11L, 1001L, 21L, 2001L), userIds);
  41 + }
  42 +
  43 +}
yudao-module-bpm/src/test/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/candidate/strategy/dept/BpmTaskCandidateDeptLeaderStrategyTest.java 0 → 100644
  1 +package cn.iocoder.yudao.module.bpm.framework.flowable.core.candidate.strategy.dept;
  2 +
  3 +import cn.iocoder.yudao.framework.common.util.collection.SetUtils;
  4 +import cn.iocoder.yudao.framework.test.core.ut.BaseMockitoUnitTest;
  5 +import cn.iocoder.yudao.module.system.api.dept.DeptApi;
  6 +import cn.iocoder.yudao.module.system.api.dept.dto.DeptRespDTO;
  7 +import org.assertj.core.util.Sets;
  8 +import org.junit.jupiter.api.Test;
  9 +import org.mockito.InjectMocks;
  10 +import org.mockito.Mock;
  11 +
  12 +import java.util.Set;
  13 +
  14 +import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomPojo;
  15 +import static java.util.Arrays.asList;
  16 +import static org.junit.jupiter.api.Assertions.assertEquals;
  17 +import static org.mockito.ArgumentMatchers.eq;
  18 +import static org.mockito.Mockito.when;
  19 +
  20 +public class BpmTaskCandidateDeptLeaderStrategyTest extends BaseMockitoUnitTest {
  21 +
  22 + @InjectMocks
  23 + private BpmTaskCandidateDeptLeaderStrategy strategy;
  24 +
  25 + @Mock
  26 + private DeptApi deptApi;
  27 +
  28 + @Test
  29 + public void testCalculateUsers() {
  30 + // 准备参数
  31 + String param = "10,20";
  32 + // mock 方法
  33 + when(deptApi.getDeptList(eq(SetUtils.asSet(10L, 20L)))).thenReturn(asList(
  34 + randomPojo(DeptRespDTO.class, o -> o.setId(10L).setParentId(10L).setLeaderUserId(11L)),
  35 + randomPojo(DeptRespDTO.class, o -> o.setId(20L).setParentId(20L).setLeaderUserId(21L))));
  36 +
  37 + // 调用
  38 + Set<Long> userIds = strategy.calculateUsers(param);
  39 + // 断言结果
  40 + assertEquals(Sets.newLinkedHashSet(11L, 21L), userIds);
  41 + }
  42 +
  43 +}
yudao-module-bpm/src/test/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/candidate/strategy/dept/BpmTaskCandidateDeptMemberStrategyTest.java 0 → 100644
  1 +package cn.iocoder.yudao.module.bpm.framework.flowable.core.candidate.strategy.dept;
  2 +
  3 +import cn.iocoder.yudao.framework.common.util.collection.SetUtils;
  4 +import cn.iocoder.yudao.framework.test.core.ut.BaseMockitoUnitTest;
  5 +import cn.iocoder.yudao.module.system.api.dept.DeptApi;
  6 +import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
  7 +import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
  8 +import org.assertj.core.util.Sets;
  9 +import org.junit.jupiter.api.Test;
  10 +import org.mockito.InjectMocks;
  11 +import org.mockito.Mock;
  12 +
  13 +import java.util.Set;
  14 +
  15 +import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomPojo;
  16 +import static java.util.Arrays.asList;
  17 +import static org.junit.jupiter.api.Assertions.assertEquals;
  18 +import static org.mockito.ArgumentMatchers.eq;
  19 +import static org.mockito.Mockito.when;
  20 +
  21 +public class BpmTaskCandidateDeptMemberStrategyTest extends BaseMockitoUnitTest {
  22 +
  23 + @InjectMocks
  24 + private BpmTaskCandidateDeptMemberStrategy strategy;
  25 +
  26 + @Mock
  27 + private DeptApi deptApi;
  28 + @Mock
  29 + private AdminUserApi adminUserApi;
  30 +
  31 + @Test
  32 + public void testCalculateUsers() {
  33 + // 准备参数
  34 + String param = "10,20";
  35 + // mock 方法
  36 + when(adminUserApi.getUserListByDeptIds(eq(SetUtils.asSet(10L, 20L)))).thenReturn(asList(
  37 + randomPojo(AdminUserRespDTO.class, o -> o.setId(11L)),
  38 + randomPojo(AdminUserRespDTO.class, o -> o.setId(21L))));
  39 +
  40 + // 调用
  41 + Set<Long> userIds = strategy.calculateUsers(param);
  42 + // 断言结果
  43 + assertEquals(Sets.newLinkedHashSet(11L, 21L), userIds);
  44 + }
  45 +
  46 +}
yudao-module-bpm/src/test/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/candidate/strategy/dept/BpmTaskCandidateStartUserDeptLeaderMultiStrategyTest.java 0 → 100644
  1 +package cn.iocoder.yudao.module.bpm.framework.flowable.core.candidate.strategy.dept;
  2 +
  3 +import cn.iocoder.yudao.framework.test.core.ut.BaseMockitoUnitTest;
  4 +import cn.iocoder.yudao.module.bpm.service.task.BpmProcessInstanceService;
  5 +import cn.iocoder.yudao.module.system.api.dept.DeptApi;
  6 +import cn.iocoder.yudao.module.system.api.dept.dto.DeptRespDTO;
  7 +import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
  8 +import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
  9 +import org.assertj.core.util.Sets;
  10 +import org.flowable.engine.delegate.DelegateExecution;
  11 +import org.flowable.engine.runtime.ProcessInstance;
  12 +import org.junit.jupiter.api.Test;
  13 +import org.mockito.InjectMocks;
  14 +import org.mockito.Mock;
  15 +import org.mockito.stubbing.Answer;
  16 +
  17 +import java.util.Set;
  18 +
  19 +import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomPojo;
  20 +import static org.junit.jupiter.api.Assertions.assertEquals;
  21 +import static org.mockito.ArgumentMatchers.any;
  22 +import static org.mockito.ArgumentMatchers.eq;
  23 +import static org.mockito.Mockito.mock;
  24 +import static org.mockito.Mockito.when;
  25 +
  26 +public class BpmTaskCandidateStartUserDeptLeaderMultiStrategyTest extends BaseMockitoUnitTest {
  27 +
  28 + @InjectMocks
  29 + private BpmTaskCandidateStartUserDeptLeaderMultiStrategy strategy;
  30 +
  31 + @Mock
  32 + private BpmProcessInstanceService processInstanceService;
  33 +
  34 + @Mock
  35 + private AdminUserApi adminUserApi;
  36 + @Mock
  37 + private DeptApi deptApi;
  38 +
  39 + @Test
  40 + public void testCalculateUsersByTask() {
  41 + // 准备参数
  42 + String param = "2";
  43 + // mock 方法(获得流程发起人)
  44 + Long startUserId = 1L;
  45 + ProcessInstance processInstance = mock(ProcessInstance.class);
  46 + DelegateExecution execution = mock(DelegateExecution.class);
  47 + when(processInstanceService.getProcessInstance(eq(execution.getProcessInstanceId()))).thenReturn(processInstance);
  48 + when(processInstance.getStartUserId()).thenReturn(startUserId.toString());
  49 + // mock 方法(获取发起人的 multi 部门负责人)
  50 + mockGetStartUserDept(startUserId);
  51 +
  52 + // 调用
  53 + Set<Long> userIds = strategy.calculateUsersByTask(execution, param);
  54 + // 断言
  55 + assertEquals(Sets.newLinkedHashSet(11L, 1001L), userIds);
  56 + }
  57 +
  58 + @Test
  59 + public void testCalculateUsersByActivity() {
  60 + // 准备参数
  61 + String param = "2";
  62 + // mock 方法
  63 + Long startUserId = 1L;
  64 + mockGetStartUserDept(startUserId);
  65 +
  66 + // 调用
  67 + Set<Long> userIds = strategy.calculateUsersByActivity(null, null, param,
  68 + startUserId, null, null);
  69 + // 断言
  70 + assertEquals(Sets.newLinkedHashSet(11L, 1001L), userIds);
  71 + }
  72 +
  73 + private void mockGetStartUserDept(Long startUserId) {
  74 + when(adminUserApi.getUser(eq(startUserId))).thenReturn(
  75 + randomPojo(AdminUserRespDTO.class, o -> o.setId(startUserId).setDeptId(10L)));
  76 + when(deptApi.getDept(any())).thenAnswer((Answer<DeptRespDTO>) invocationOnMock -> {
  77 + Long deptId = invocationOnMock.getArgument(0);
  78 + return randomPojo(DeptRespDTO.class, o -> o.setId(deptId).setParentId(deptId * 100).setLeaderUserId(deptId + 1));
  79 + });
  80 + }
  81 +
  82 +}
yudao-module-bpm/src/test/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/candidate/strategy/dept/BpmTaskCandidateStartUserDeptLeaderStrategyTest.java 0 → 100644
  1 +package cn.iocoder.yudao.module.bpm.framework.flowable.core.candidate.strategy.dept;
  2 +
  3 +import cn.iocoder.yudao.framework.test.core.ut.BaseMockitoUnitTest;
  4 +import cn.iocoder.yudao.module.bpm.service.task.BpmProcessInstanceService;
  5 +import cn.iocoder.yudao.module.system.api.dept.DeptApi;
  6 +import cn.iocoder.yudao.module.system.api.dept.dto.DeptRespDTO;
  7 +import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
  8 +import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
  9 +import org.assertj.core.util.Sets;
  10 +import org.flowable.engine.delegate.DelegateExecution;
  11 +import org.flowable.engine.runtime.ProcessInstance;
  12 +import org.junit.jupiter.api.Test;
  13 +import org.mockito.InjectMocks;
  14 +import org.mockito.Mock;
  15 +import org.mockito.stubbing.Answer;
  16 +
  17 +import java.util.Set;
  18 +
  19 +import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomPojo;
  20 +import static org.junit.jupiter.api.Assertions.assertEquals;
  21 +import static org.mockito.ArgumentMatchers.any;
  22 +import static org.mockito.ArgumentMatchers.eq;
  23 +import static org.mockito.Mockito.mock;
  24 +import static org.mockito.Mockito.when;
  25 +
  26 +public class BpmTaskCandidateStartUserDeptLeaderStrategyTest extends BaseMockitoUnitTest {
  27 +
  28 + @InjectMocks
  29 + private BpmTaskCandidateStartUserDeptLeaderStrategy strategy;
  30 +
  31 + @Mock
  32 + private BpmProcessInstanceService processInstanceService;
  33 +
  34 + @Mock
  35 + private AdminUserApi adminUserApi;
  36 + @Mock
  37 + private DeptApi deptApi;
  38 +
  39 + @Test
  40 + public void testCalculateUsersByTask() {
  41 + // 准备参数
  42 + String param = "2";
  43 + // mock 方法(获得流程发起人)
  44 + Long startUserId = 1L;
  45 + ProcessInstance processInstance = mock(ProcessInstance.class);
  46 + DelegateExecution execution = mock(DelegateExecution.class);
  47 + when(processInstanceService.getProcessInstance(eq(execution.getProcessInstanceId()))).thenReturn(processInstance);
  48 + when(processInstance.getStartUserId()).thenReturn(startUserId.toString());
  49 + // mock 方法(获取发起人的部门负责人)
  50 + mockGetStartUserDeptLeader(startUserId);
  51 +
  52 + // 调用
  53 + Set<Long> userIds = strategy.calculateUsersByTask(execution, param);
  54 + // 断言
  55 + assertEquals(Sets.newLinkedHashSet(1001L), userIds);
  56 + }
  57 +
  58 + @Test
  59 + public void testGetStartUserDeptLeader() {
  60 + // 准备参数
  61 + String param = "2";
  62 + // mock 方法
  63 + Long startUserId = 1L;
  64 + mockGetStartUserDeptLeader(startUserId);
  65 +
  66 + // 调用
  67 + Set<Long> userIds = strategy.calculateUsersByActivity(null, null, param,
  68 + startUserId, null, null);
  69 + // 断言
  70 + assertEquals(Sets.newLinkedHashSet(1001L), userIds);
  71 + }
  72 +
  73 + private void mockGetStartUserDeptLeader(Long startUserId) {
  74 + when(adminUserApi.getUser(eq(startUserId))).thenReturn(
  75 + randomPojo(AdminUserRespDTO.class, o -> o.setId(startUserId).setDeptId(10L)));
  76 + when(deptApi.getDept(any())).thenAnswer((Answer<DeptRespDTO>) invocationOnMock -> {
  77 + Long deptId = invocationOnMock.getArgument(0);
  78 + return randomPojo(DeptRespDTO.class, o -> o.setId(deptId).setParentId(deptId * 100).setLeaderUserId(deptId + 1));
  79 + });
  80 + }
  81 +
  82 +}
yudao-module-bpm/src/test/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/candidate/strategy/dept/BpmTaskCandidateStartUserSelectStrategyTest.java 0 → 100644
  1 +package cn.iocoder.yudao.module.bpm.framework.flowable.core.candidate.strategy.dept;
  2 +
  3 +import cn.hutool.core.map.MapUtil;
  4 +import cn.iocoder.yudao.framework.test.core.ut.BaseMockitoUnitTest;
  5 +import cn.iocoder.yudao.module.bpm.framework.flowable.core.enums.BpmnVariableConstants;
  6 +import cn.iocoder.yudao.module.bpm.service.task.BpmProcessInstanceService;
  7 +import org.assertj.core.util.Sets;
  8 +import org.flowable.engine.delegate.DelegateExecution;
  9 +import org.flowable.engine.runtime.ProcessInstance;
  10 +import org.junit.jupiter.api.Test;
  11 +import org.mockito.InjectMocks;
  12 +import org.mockito.Mock;
  13 +
  14 +import java.util.HashMap;
  15 +import java.util.List;
  16 +import java.util.Map;
  17 +import java.util.Set;
  18 +
  19 +import static org.junit.jupiter.api.Assertions.assertEquals;
  20 +import static org.mockito.ArgumentMatchers.eq;
  21 +import static org.mockito.Mockito.mock;
  22 +import static org.mockito.Mockito.when;
  23 +
  24 +public class BpmTaskCandidateStartUserSelectStrategyTest extends BaseMockitoUnitTest {
  25 +
  26 + @InjectMocks
  27 + private BpmTaskCandidateStartUserSelectStrategy strategy;
  28 +
  29 + @Mock
  30 + private BpmProcessInstanceService processInstanceService;
  31 +
  32 + @Test
  33 + public void testCalculateUsersByTask() {
  34 + // 准备参数
  35 + String param = "2";
  36 + // mock 方法(获得流程发起人)
  37 + ProcessInstance processInstance = mock(ProcessInstance.class);
  38 + DelegateExecution execution = mock(DelegateExecution.class);
  39 + when(processInstanceService.getProcessInstance(eq(execution.getProcessInstanceId()))).thenReturn(processInstance);
  40 + when(execution.getCurrentActivityId()).thenReturn("activity_001");
  41 + // mock 方法(FlowableUtils)
  42 + Map<String, Object> processVariables = new HashMap<>();
  43 + processVariables.put(BpmnVariableConstants.PROCESS_INSTANCE_VARIABLE_START_USER_SELECT_ASSIGNEES,
  44 + MapUtil.of("activity_001", List.of(1L, 2L)));
  45 + when(processInstance.getProcessVariables()).thenReturn(processVariables);
  46 +
  47 + // 调用
  48 + Set<Long> userIds = strategy.calculateUsersByTask(execution, param);
  49 + // 断言
  50 + assertEquals(Sets.newLinkedHashSet(1L, 2L), userIds);
  51 + }
  52 +
  53 + @Test
  54 + public void testCalculateUsersByActivity() {
  55 + // 准备参数
  56 + String activityId = "activity_001";
  57 + Map<String, Object> processVariables = new HashMap<>();
  58 + processVariables.put(BpmnVariableConstants.PROCESS_INSTANCE_VARIABLE_START_USER_SELECT_ASSIGNEES,
  59 + MapUtil.of("activity_001", List.of(1L, 2L)));
  60 +
  61 + // 调用
  62 + Set<Long> userIds = strategy.calculateUsersByActivity(null, activityId, null,
  63 + null, null, processVariables);
  64 + // 断言
  65 + assertEquals(Sets.newLinkedHashSet(1L, 2L), userIds);
  66 + }
  67 +
  68 +}
yudao-module-bpm/src/test/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/candidate/strategy/other/BpmTaskCandidateAssignEmptyStrategyTest.java 0 → 100644
  1 +package cn.iocoder.yudao.module.bpm.framework.flowable.core.candidate.strategy.other;
  2 +
  3 +import cn.hutool.core.collection.ListUtil;
  4 +import cn.iocoder.yudao.framework.common.util.collection.SetUtils;
  5 +import cn.iocoder.yudao.framework.test.core.ut.BaseMockitoUnitTest;
  6 +import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmProcessDefinitionInfoDO;
  7 +import cn.iocoder.yudao.module.bpm.enums.definition.BpmUserTaskAssignEmptyHandlerTypeEnum;
  8 +import cn.iocoder.yudao.module.bpm.framework.flowable.core.util.BpmnModelUtils;
  9 +import cn.iocoder.yudao.module.bpm.framework.flowable.core.util.FlowableUtils;
  10 +import cn.iocoder.yudao.module.bpm.service.definition.BpmProcessDefinitionService;
  11 +import org.flowable.bpmn.model.BpmnModel;
  12 +import org.flowable.bpmn.model.FlowElement;
  13 +import org.flowable.engine.delegate.DelegateExecution;
  14 +import org.junit.jupiter.api.Test;
  15 +import org.mockito.InjectMocks;
  16 +import org.mockito.Mock;
  17 +import org.mockito.MockedStatic;
  18 +
  19 +import java.util.Set;
  20 +
  21 +import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomPojo;
  22 +import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomString;
  23 +import static org.junit.jupiter.api.Assertions.assertEquals;
  24 +import static org.mockito.Mockito.*;
  25 +
  26 +public class BpmTaskCandidateAssignEmptyStrategyTest extends BaseMockitoUnitTest {
  27 +
  28 + @InjectMocks
  29 + private BpmTaskCandidateAssignEmptyStrategy strategy;
  30 +
  31 + @Mock
  32 + private BpmProcessDefinitionService processDefinitionService;
  33 +
  34 + @Test
  35 + public void testCalculateUsersByTask() {
  36 + try (MockedStatic<FlowableUtils> flowableUtilMockedStatic = mockStatic(FlowableUtils.class);
  37 + MockedStatic<BpmnModelUtils> bpmnModelUtilsMockedStatic = mockStatic(BpmnModelUtils.class)) {
  38 + // 准备参数
  39 + DelegateExecution execution = mock(DelegateExecution.class);
  40 + String param = randomString();
  41 + // mock 方法(execution)
  42 + String processDefinitionId = randomString();
  43 + when(execution.getProcessDefinitionId()).thenReturn(processDefinitionId);
  44 + FlowElement flowElement = mock(FlowElement.class);
  45 + when(execution.getCurrentFlowElement()).thenReturn(flowElement);
  46 + // mock 方法(parseAssignEmptyHandlerType)
  47 + bpmnModelUtilsMockedStatic.when(() -> BpmnModelUtils.parseAssignEmptyHandlerType(same(flowElement)))
  48 + .thenReturn(BpmUserTaskAssignEmptyHandlerTypeEnum.ASSIGN_USER.getType());
  49 + bpmnModelUtilsMockedStatic.when(() -> BpmnModelUtils.parseAssignEmptyHandlerUserIds(same(flowElement)))
  50 + .thenReturn(ListUtil.of(1L, 2L));
  51 +
  52 + // 调用
  53 + Set<Long> userIds = strategy.calculateUsersByTask(execution, param);
  54 + // 断言
  55 + assertEquals(SetUtils.asSet(1L, 2L), userIds);
  56 + }
  57 +
  58 + }
  59 +
  60 + @Test
  61 + public void testCalculateUsersByActivity() {
  62 + try (MockedStatic<BpmnModelUtils> bpmnModelUtilsMockedStatic = mockStatic(BpmnModelUtils.class)) {
  63 + // 准备参数
  64 + String processDefinitionId = randomString();
  65 + String activityId = randomString();
  66 + String param = randomString();
  67 + // mock 方法(getFlowElementById)
  68 + FlowElement flowElement = mock(FlowElement.class);
  69 + BpmnModel bpmnModel = mock(BpmnModel.class);
  70 + bpmnModelUtilsMockedStatic.when(() -> BpmnModelUtils.getFlowElementById(same(bpmnModel), eq(activityId)))
  71 + .thenReturn(flowElement);
  72 + // mock 方法(parseAssignEmptyHandlerType)
  73 + bpmnModelUtilsMockedStatic.when(() -> BpmnModelUtils.parseAssignEmptyHandlerType(same(flowElement)))
  74 + .thenReturn(BpmUserTaskAssignEmptyHandlerTypeEnum.ASSIGN_ADMIN.getType());
  75 + // mock 方法(getProcessDefinitionInfo)
  76 + BpmProcessDefinitionInfoDO processDefinition = randomPojo(BpmProcessDefinitionInfoDO.class,
  77 + o -> o.setManagerUserIds(ListUtil.of(1L, 2L)));
  78 + when(processDefinitionService.getProcessDefinitionInfo(eq(processDefinitionId))).thenReturn(processDefinition);
  79 +
  80 + // 调用
  81 + Set<Long> userIds = strategy.calculateUsersByActivity(bpmnModel, activityId, param,
  82 + null, processDefinitionId, null);
  83 + // 断言
  84 + assertEquals(SetUtils.asSet(1L, 2L), userIds);
  85 + }
  86 + }
  87 +
  88 +}
yudao-module-bpm/src/test/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/candidate/strategy/other/BpmTaskCandidateExpressionStrategyTest.java 0 → 100644
  1 +package cn.iocoder.yudao.module.bpm.framework.flowable.core.candidate.strategy.other;
  2 +
  3 +import cn.iocoder.yudao.framework.test.core.ut.BaseMockitoUnitTest;
  4 +import cn.iocoder.yudao.module.bpm.framework.flowable.core.util.FlowableUtils;
  5 +import org.flowable.engine.delegate.DelegateExecution;
  6 +import org.junit.jupiter.api.Disabled;
  7 +import org.junit.jupiter.api.Test;
  8 +import org.mockito.InjectMocks;
  9 +import org.mockito.MockedStatic;
  10 +
  11 +import java.util.HashMap;
  12 +import java.util.Map;
  13 +import java.util.Set;
  14 +
  15 +import static cn.iocoder.yudao.framework.common.util.collection.SetUtils.asSet;
  16 +import static org.junit.jupiter.api.Assertions.assertEquals;
  17 +import static org.mockito.ArgumentMatchers.eq;
  18 +import static org.mockito.Mockito.*;
  19 +
  20 +@Disabled // TODO 芋艿:临时注释
  21 +public class BpmTaskCandidateExpressionStrategyTest extends BaseMockitoUnitTest {
  22 +
  23 + @InjectMocks
  24 + private BpmTaskCandidateExpressionStrategy strategy;
  25 +
  26 + @Test
  27 + public void testCalculateUsersByTask() {
  28 + try (MockedStatic<FlowableUtils> flowableUtilMockedStatic = mockStatic(FlowableUtils.class)) {
  29 + // 准备参数
  30 + String param = "1,2";
  31 + DelegateExecution execution = mock(DelegateExecution.class);
  32 + // mock 方法
  33 + flowableUtilMockedStatic.when(() -> FlowableUtils.getExpressionValue(same(execution), eq(param)))
  34 + .thenReturn(asSet(1L, 2L));
  35 +
  36 + // 调用
  37 + Set<Long> results = strategy.calculateUsersByTask(execution, param);
  38 + // 断言
  39 + assertEquals(asSet(1L, 2L), results);
  40 + }
  41 + }
  42 +
  43 + @Test
  44 + public void testCalculateUsersByActivity() {
  45 + try (MockedStatic<FlowableUtils> flowableUtilMockedStatic = mockStatic(FlowableUtils.class)) {
  46 + // 准备参数
  47 + String param = "1,2";
  48 + Map<String, Object> processVariables = new HashMap<>();
  49 + // mock 方法
  50 + flowableUtilMockedStatic.when(() -> FlowableUtils.getExpressionValue(same(processVariables), eq(param)))
  51 + .thenReturn(asSet(1L, 2L));
  52 +
  53 + // 调用
  54 + Set<Long> results = strategy.calculateUsersByActivity(null, null, param,
  55 + null, null, processVariables);
  56 + // 断言
  57 + assertEquals(asSet(1L, 2L), results);
  58 + }
  59 + }
  60 +
  61 +}
yudao-module-bpm/src/test/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/candidate/strategy/user/BpmTaskCandidateGroupStrategyTest.java 0 → 100644
  1 +package cn.iocoder.yudao.module.bpm.framework.flowable.core.candidate.strategy.user;
  2 +
  3 +import cn.iocoder.yudao.framework.test.core.ut.BaseMockitoUnitTest;
  4 +import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmUserGroupDO;
  5 +import cn.iocoder.yudao.module.bpm.service.definition.BpmUserGroupService;
  6 +import org.junit.jupiter.api.Disabled;
  7 +import org.junit.jupiter.api.Test;
  8 +import org.mockito.InjectMocks;
  9 +import org.mockito.Mock;
  10 +
  11 +import java.util.Arrays;
  12 +import java.util.Set;
  13 +
  14 +import static cn.iocoder.yudao.framework.common.util.collection.SetUtils.asSet;
  15 +import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomPojo;
  16 +import static org.junit.jupiter.api.Assertions.assertEquals;
  17 +import static org.mockito.ArgumentMatchers.eq;
  18 +import static org.mockito.Mockito.when;
  19 +
  20 +@Disabled // TODO 芋艿:临时注释
  21 +public class BpmTaskCandidateGroupStrategyTest extends BaseMockitoUnitTest {
  22 +
  23 + @InjectMocks
  24 + private BpmTaskCandidateGroupStrategy strategy;
  25 +
  26 + @Mock
  27 + private BpmUserGroupService userGroupService;
  28 +
  29 + @Test
  30 + public void testCalculateUsers() {
  31 + // 准备参数
  32 + String param = "1,2";
  33 + // mock 方法
  34 + BpmUserGroupDO userGroup1 = randomPojo(BpmUserGroupDO.class, o -> o.setUserIds(asSet(11L, 12L)));
  35 + BpmUserGroupDO userGroup2 = randomPojo(BpmUserGroupDO.class, o -> o.setUserIds(asSet(21L, 22L)));
  36 + when(userGroupService.getUserGroupList(eq(asSet(1L, 2L)))).thenReturn(Arrays.asList(userGroup1, userGroup2));
  37 +
  38 + // 调用
  39 + Set<Long> userIds = strategy.calculateUsersByTask(null, param);
  40 + // 断言
  41 + assertEquals(asSet(11L, 12L, 21L, 22L), userIds);
  42 + }
  43 +
  44 +}
yudao-module-bpm/src/test/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/candidate/strategy/user/BpmTaskCandidatePostStrategyTest.java 0 → 100644
  1 +package cn.iocoder.yudao.module.bpm.framework.flowable.core.candidate.strategy.user;
  2 +
  3 +import cn.iocoder.yudao.framework.test.core.ut.BaseMockitoUnitTest;
  4 +import cn.iocoder.yudao.module.system.api.dept.PostApi;
  5 +import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
  6 +import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
  7 +import org.junit.jupiter.api.Disabled;
  8 +import org.junit.jupiter.api.Test;
  9 +import org.mockito.InjectMocks;
  10 +import org.mockito.Mock;
  11 +
  12 +import java.util.List;
  13 +import java.util.Set;
  14 +
  15 +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList;
  16 +import static cn.iocoder.yudao.framework.common.util.collection.SetUtils.asSet;
  17 +import static org.junit.jupiter.api.Assertions.assertEquals;
  18 +import static org.mockito.ArgumentMatchers.eq;
  19 +import static org.mockito.Mockito.when;
  20 +
  21 +@Disabled // TODO 芋艿:临时注释
  22 +public class BpmTaskCandidatePostStrategyTest extends BaseMockitoUnitTest {
  23 +
  24 + @InjectMocks
  25 + private BpmTaskCandidatePostStrategy strategy;
  26 +
  27 + @Mock
  28 + private PostApi postApi;
  29 + @Mock
  30 + private AdminUserApi adminUserApi;
  31 +
  32 + @Test
  33 + public void testCalculateUsers() {
  34 + // 准备参数
  35 + String param = "1,2";
  36 + // mock 方法
  37 + List<AdminUserRespDTO> users = convertList(asSet(11L, 22L),
  38 + id -> new AdminUserRespDTO().setId(id));
  39 + when(adminUserApi.getUserListByPostIds(eq(asSet(1L, 2L)))).thenReturn(users);
  40 +
  41 + // 调用
  42 + Set<Long> userIds = strategy.calculateUsersByTask(null, param);
  43 + // 断言
  44 + assertEquals(asSet(11L, 22L), userIds);
  45 + }
  46 +
  47 +}
yudao-module-bpm/src/test/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/candidate/strategy/user/BpmTaskCandidateRoleStrategyTest.java 0 → 100644
  1 +package cn.iocoder.yudao.module.bpm.framework.flowable.core.candidate.strategy.user;
  2 +
  3 +import cn.iocoder.yudao.framework.test.core.ut.BaseMockitoUnitTest;
  4 +import cn.iocoder.yudao.module.system.api.permission.PermissionApi;
  5 +import cn.iocoder.yudao.module.system.api.permission.RoleApi;
  6 +import org.junit.jupiter.api.Disabled;
  7 +import org.junit.jupiter.api.Test;
  8 +import org.mockito.InjectMocks;
  9 +import org.mockito.Mock;
  10 +
  11 +import java.util.Set;
  12 +
  13 +import static cn.iocoder.yudao.framework.common.util.collection.SetUtils.asSet;
  14 +import static org.junit.jupiter.api.Assertions.assertEquals;
  15 +import static org.mockito.ArgumentMatchers.eq;
  16 +import static org.mockito.Mockito.when;
  17 +
  18 +@Disabled // TODO 芋艿:临时注释
  19 +public class BpmTaskCandidateRoleStrategyTest extends BaseMockitoUnitTest {
  20 +
  21 + @InjectMocks
  22 + private BpmTaskCandidateRoleStrategy strategy;
  23 +
  24 + @Mock
  25 + private RoleApi roleApi;
  26 + @Mock
  27 + private PermissionApi permissionApi;
  28 +
  29 + @Test
  30 + public void testCalculateUsers() {
  31 + // 准备参数
  32 + String param = "1,2";
  33 + // mock 方法
  34 + when(permissionApi.getUserRoleIdListByRoleIds(eq(asSet(1L, 2L))))
  35 + .thenReturn(asSet(11L, 22L));
  36 +
  37 + // 调用
  38 + Set<Long> userIds = strategy.calculateUsersByTask(null, param);
  39 + // 断言
  40 + assertEquals(asSet(11L, 22L), userIds);
  41 + }
  42 +
  43 +}
yudao-module-bpm/src/test/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/candidate/strategy/user/BpmTaskCandidateStartUserStrategyTest.java 0 → 100644
  1 +package cn.iocoder.yudao.module.bpm.framework.flowable.core.candidate.strategy.user;
  2 +
  3 +import cn.iocoder.yudao.framework.test.core.ut.BaseMockitoUnitTest;
  4 +import cn.iocoder.yudao.module.bpm.service.task.BpmProcessInstanceService;
  5 +import org.assertj.core.util.Sets;
  6 +import org.flowable.engine.delegate.DelegateExecution;
  7 +import org.flowable.engine.runtime.ProcessInstance;
  8 +import org.junit.jupiter.api.Test;
  9 +import org.mockito.InjectMocks;
  10 +import org.mockito.Mock;
  11 +
  12 +import java.util.Set;
  13 +
  14 +import static org.junit.jupiter.api.Assertions.assertEquals;
  15 +import static org.mockito.ArgumentMatchers.eq;
  16 +import static org.mockito.Mockito.mock;
  17 +import static org.mockito.Mockito.when;
  18 +
  19 +public class BpmTaskCandidateStartUserStrategyTest extends BaseMockitoUnitTest {
  20 +
  21 + @InjectMocks
  22 + private BpmTaskCandidateStartUserStrategy strategy;
  23 +
  24 + @Mock
  25 + private BpmProcessInstanceService processInstanceService;
  26 +
  27 + @Test
  28 + public void testCalculateUsersByTask() {
  29 + // 准备参数
  30 + String param = "2";
  31 + // mock 方法(获得流程发起人)
  32 + Long startUserId = 1L;
  33 + ProcessInstance processInstance = mock(ProcessInstance.class);
  34 + DelegateExecution execution = mock(DelegateExecution.class);
  35 + when(processInstanceService.getProcessInstance(eq(execution.getProcessInstanceId()))).thenReturn(processInstance);
  36 + when(processInstance.getStartUserId()).thenReturn(startUserId.toString());
  37 +
  38 + // 调用
  39 + Set<Long> userIds = strategy.calculateUsersByTask(execution, param);
  40 + // 断言
  41 + assertEquals(Sets.newLinkedHashSet(startUserId), userIds);
  42 + }
  43 +
  44 + @Test
  45 + public void testCalculateUsersByActivity() {
  46 + // 准备参数
  47 + Long startUserId = 1L;
  48 +
  49 + // 调用
  50 + Set<Long> userIds = strategy.calculateUsersByActivity(null, null, null,
  51 + startUserId, null, null);
  52 + // 断言
  53 + assertEquals(Sets.newLinkedHashSet(startUserId), userIds);
  54 + }
  55 +
  56 +}
yudao-module-bpm/src/test/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/candidate/strategy/user/BpmTaskCandidateUserStrategyTest.java 0 → 100644
  1 +package cn.iocoder.yudao.module.bpm.framework.flowable.core.candidate.strategy.user;
  2 +
  3 +import cn.iocoder.yudao.framework.test.core.ut.BaseMockitoUnitTest;
  4 +import org.junit.jupiter.api.Disabled;
  5 +import org.junit.jupiter.api.Test;
  6 +import org.mockito.InjectMocks;
  7 +
  8 +import java.util.Set;
  9 +
  10 +import static cn.iocoder.yudao.framework.common.util.collection.SetUtils.asSet;
  11 +import static org.junit.jupiter.api.Assertions.assertEquals;
  12 +
  13 +@Disabled // TODO 芋艿:临时注释
  14 +public class BpmTaskCandidateUserStrategyTest extends BaseMockitoUnitTest {
  15 +
  16 + @InjectMocks
  17 + private BpmTaskCandidateUserStrategy strategy;
  18 +
  19 + @Test
  20 + public void test() {
  21 + // 准备参数
  22 + String param = "1,2";
  23 +
  24 + // 调用
  25 + Set<Long> userIds = strategy.calculateUsersByTask(null, param);
  26 + // 断言
  27 + assertEquals(asSet(1L, 2L), userIds);
  28 + }
  29 +
  30 +
  31 +}
yudao-module-bpm/src/test/java/cn/iocoder/yudao/module/bpm/service/category/BpmCategoryServiceImplTest.java 0 → 100644
  1 +package cn.iocoder.yudao.module.bpm.service.category;
  2 +
  3 +import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
  4 +import cn.iocoder.yudao.framework.common.pojo.PageResult;
  5 +import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest;
  6 +import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.category.BpmCategoryPageReqVO;
  7 +import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.category.BpmCategorySaveReqVO;
  8 +import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmCategoryDO;
  9 +import cn.iocoder.yudao.module.bpm.dal.mysql.category.BpmCategoryMapper;
  10 +import cn.iocoder.yudao.module.bpm.service.definition.BpmCategoryServiceImpl;
  11 +import jakarta.annotation.Resource;
  12 +import org.junit.jupiter.api.Test;
  13 +import org.springframework.context.annotation.Import;
  14 +
  15 +import static cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils.buildBetweenTime;
  16 +import static cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils.buildTime;
  17 +import static cn.iocoder.yudao.framework.common.util.object.ObjectUtils.cloneIgnoreId;
  18 +import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertPojoEquals;
  19 +import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertServiceException;
  20 +import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.*;
  21 +import static cn.iocoder.yudao.module.bpm.enums.ErrorCodeConstants.CATEGORY_NOT_EXISTS;
  22 +import static org.junit.jupiter.api.Assertions.*;
  23 +
  24 +/**
  25 + * {@link BpmCategoryServiceImpl} 的单元测试类
  26 + *
  27 + * @author 芋道源码
  28 + */
  29 +@Import(BpmCategoryServiceImpl.class)
  30 +public class BpmCategoryServiceImplTest extends BaseDbUnitTest {
  31 +
  32 + @Resource
  33 + private BpmCategoryServiceImpl categoryService;
  34 +
  35 + @Resource
  36 + private BpmCategoryMapper categoryMapper;
  37 +
  38 + @Test
  39 + public void testCreateCategory_success() {
  40 + // 准备参数
  41 + BpmCategorySaveReqVO createReqVO = randomPojo(BpmCategorySaveReqVO.class).setId(null)
  42 + .setStatus(randomCommonStatus());
  43 +
  44 + // 调用
  45 + Long categoryId = categoryService.createCategory(createReqVO);
  46 + // 断言
  47 + assertNotNull(categoryId);
  48 + // 校验记录的属性是否正确
  49 + BpmCategoryDO category = categoryMapper.selectById(categoryId);
  50 + assertPojoEquals(createReqVO, category, "id");
  51 + }
  52 +
  53 + @Test
  54 + public void testUpdateCategory_success() {
  55 + // mock 数据
  56 + BpmCategoryDO dbCategory = randomPojo(BpmCategoryDO.class);
  57 + categoryMapper.insert(dbCategory);// @Sql: 先插入出一条存在的数据
  58 + // 准备参数
  59 + BpmCategorySaveReqVO updateReqVO = randomPojo(BpmCategorySaveReqVO.class, o -> {
  60 + o.setId(dbCategory.getId()); // 设置更新的 ID
  61 + o.setStatus(randomCommonStatus());
  62 + });
  63 +
  64 + // 调用
  65 + categoryService.updateCategory(updateReqVO);
  66 + // 校验是否更新正确
  67 + BpmCategoryDO category = categoryMapper.selectById(updateReqVO.getId()); // 获取最新的
  68 + assertPojoEquals(updateReqVO, category);
  69 + }
  70 +
  71 + @Test
  72 + public void testUpdateCategory_notExists() {
  73 + // 准备参数
  74 + BpmCategorySaveReqVO updateReqVO = randomPojo(BpmCategorySaveReqVO.class);
  75 +
  76 + // 调用, 并断言异常
  77 + assertServiceException(() -> categoryService.updateCategory(updateReqVO), CATEGORY_NOT_EXISTS);
  78 + }
  79 +
  80 + @Test
  81 + public void testDeleteCategory_success() {
  82 + // mock 数据
  83 + BpmCategoryDO dbCategory = randomPojo(BpmCategoryDO.class);
  84 + categoryMapper.insert(dbCategory);// @Sql: 先插入出一条存在的数据
  85 + // 准备参数
  86 + Long id = dbCategory.getId();
  87 +
  88 + // 调用
  89 + categoryService.deleteCategory(id);
  90 + // 校验数据不存在了
  91 + assertNull(categoryMapper.selectById(id));
  92 + }
  93 +
  94 + @Test
  95 + public void testDeleteCategory_notExists() {
  96 + // 准备参数
  97 + Long id = randomLongId();
  98 +
  99 + // 调用, 并断言异常
  100 + assertServiceException(() -> categoryService.deleteCategory(id), CATEGORY_NOT_EXISTS);
  101 + }
  102 +
  103 + @Test
  104 + public void testGetCategoryPage() {
  105 + // mock 数据
  106 + BpmCategoryDO dbCategory = randomPojo(BpmCategoryDO.class, o -> { // 等会查询到
  107 + o.setName("芋头");
  108 + o.setCode("xiaodun");
  109 + o.setStatus(CommonStatusEnum.ENABLE.getStatus());
  110 + o.setCreateTime(buildTime(2023, 2, 2));
  111 + });
  112 + categoryMapper.insert(dbCategory);
  113 + // 测试 name 不匹配
  114 + categoryMapper.insert(cloneIgnoreId(dbCategory, o -> o.setName("小盾")));
  115 + // 测试 code 不匹配
  116 + categoryMapper.insert(cloneIgnoreId(dbCategory, o -> o.setCode("tudou")));
  117 + // 测试 status 不匹配
  118 + categoryMapper.insert(cloneIgnoreId(dbCategory, o -> o.setStatus(CommonStatusEnum.DISABLE.getStatus())));
  119 + // 测试 createTime 不匹配
  120 + categoryMapper.insert(cloneIgnoreId(dbCategory, o -> o.setCreateTime(buildTime(2024, 2, 2))));
  121 + // 准备参数
  122 + BpmCategoryPageReqVO reqVO = new BpmCategoryPageReqVO();
  123 + reqVO.setName("芋");
  124 + reqVO.setCode("xiao");
  125 + reqVO.setStatus(CommonStatusEnum.ENABLE.getStatus());
  126 + reqVO.setCreateTime(buildBetweenTime(2023, 2, 1, 2023, 2, 28));
  127 +
  128 + // 调用
  129 + PageResult<BpmCategoryDO> pageResult = categoryService.getCategoryPage(reqVO);
  130 + // 断言
  131 + assertEquals(1, pageResult.getTotal());
  132 + assertEquals(1, pageResult.getList().size());
  133 + assertPojoEquals(dbCategory, pageResult.getList().get(0));
  134 + }
  135 +
  136 +}
0 \ No newline at end of file 137 \ No newline at end of file
yudao-module-bpm/src/test/java/cn/iocoder/yudao/module/bpm/service/definition/BpmFormServiceTest.java 0 → 100644
  1 +package cn.iocoder.yudao.module.bpm.service.definition;
  2 +
  3 +import cn.hutool.core.util.RandomUtil;
  4 +import cn.iocoder.yudao.framework.common.pojo.PageResult;
  5 +import cn.iocoder.yudao.framework.common.util.json.JsonUtils;
  6 +import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest;
  7 +import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.form.BpmFormSaveReqVO;
  8 +import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.form.BpmFormPageReqVO;
  9 +import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmFormDO;
  10 +import cn.iocoder.yudao.module.bpm.dal.mysql.definition.BpmFormMapper;
  11 +import cn.iocoder.yudao.module.bpm.service.definition.dto.BpmFormFieldRespDTO;
  12 +import org.junit.jupiter.api.Test;
  13 +import org.springframework.context.annotation.Import;
  14 +
  15 +import jakarta.annotation.Resource;
  16 +import java.util.List;
  17 +import java.util.stream.Collectors;
  18 +import java.util.stream.Stream;
  19 +
  20 +import static cn.iocoder.yudao.framework.common.util.object.ObjectUtils.cloneIgnoreId;
  21 +import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertPojoEquals;
  22 +import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertServiceException;
  23 +import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomLongId;
  24 +import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomPojo;
  25 +import static cn.iocoder.yudao.module.bpm.enums.ErrorCodeConstants.FORM_NOT_EXISTS;
  26 +import static org.junit.jupiter.api.Assertions.*;
  27 +
  28 +/**
  29 + * {@link BpmFormServiceImpl} 的单元测试类
  30 + *
  31 + * @author 芋道源码
  32 + */
  33 +@Import(BpmFormServiceImpl.class)
  34 +public class BpmFormServiceTest extends BaseDbUnitTest {
  35 +
  36 + @Resource
  37 + private BpmFormServiceImpl formService;
  38 +
  39 + @Resource
  40 + private BpmFormMapper formMapper;
  41 +
  42 + @Test
  43 + public void testCreateForm_success() {
  44 + // 准备参数
  45 + BpmFormSaveReqVO reqVO = randomPojo(BpmFormSaveReqVO.class, o -> {
  46 + o.setConf("{}");
  47 + o.setFields(randomFields());
  48 + });
  49 +
  50 + // 调用
  51 + Long formId = formService.createForm(reqVO);
  52 + // 断言
  53 + assertNotNull(formId);
  54 + // 校验记录的属性是否正确
  55 + BpmFormDO form = formMapper.selectById(formId);
  56 + assertPojoEquals(reqVO, form);
  57 + }
  58 +
  59 + @Test
  60 + public void testUpdateForm_success() {
  61 + // mock 数据
  62 + BpmFormDO dbForm = randomPojo(BpmFormDO.class, o -> {
  63 + o.setConf("{}");
  64 + o.setFields(randomFields());
  65 + });
  66 + formMapper.insert(dbForm);// @Sql: 先插入出一条存在的数据
  67 + // 准备参数
  68 + BpmFormSaveReqVO reqVO = randomPojo(BpmFormSaveReqVO.class, o -> {
  69 + o.setId(dbForm.getId()); // 设置更新的 ID
  70 + o.setConf("{'yudao': 'yuanma'}");
  71 + o.setFields(randomFields());
  72 + });
  73 +
  74 + // 调用
  75 + formService.updateForm(reqVO);
  76 + // 校验是否更新正确
  77 + BpmFormDO form = formMapper.selectById(reqVO.getId()); // 获取最新的
  78 + assertPojoEquals(reqVO, form);
  79 + }
  80 +
  81 + @Test
  82 + public void testUpdateForm_notExists() {
  83 + // 准备参数
  84 + BpmFormSaveReqVO reqVO = randomPojo(BpmFormSaveReqVO.class, o -> {
  85 + o.setConf("{'yudao': 'yuanma'}");
  86 + o.setFields(randomFields());
  87 + });
  88 +
  89 + // 调用, 并断言异常
  90 + assertServiceException(() -> formService.updateForm(reqVO), FORM_NOT_EXISTS);
  91 + }
  92 +
  93 + @Test
  94 + public void testDeleteForm_success() {
  95 + // mock 数据
  96 + BpmFormDO dbForm = randomPojo(BpmFormDO.class);
  97 + formMapper.insert(dbForm);// @Sql: 先插入出一条存在的数据
  98 + // 准备参数
  99 + Long id = dbForm.getId();
  100 +
  101 + // 调用
  102 + formService.deleteForm(id);
  103 + // 校验数据不存在了
  104 + assertNull(formMapper.selectById(id));
  105 + }
  106 +
  107 + @Test
  108 + public void testDeleteForm_notExists() {
  109 + // 准备参数
  110 + Long id = randomLongId();
  111 +
  112 + // 调用, 并断言异常
  113 + assertServiceException(() -> formService.deleteForm(id), FORM_NOT_EXISTS);
  114 + }
  115 +
  116 + @Test
  117 + public void testGetFormPage() {
  118 + // mock 数据
  119 + BpmFormDO dbForm = randomPojo(BpmFormDO.class, o -> { // 等会查询到
  120 + o.setName("芋道源码");
  121 + });
  122 + formMapper.insert(dbForm);
  123 + // 测试 name 不匹配
  124 + formMapper.insert(cloneIgnoreId(dbForm, o -> o.setName("源码")));
  125 + // 准备参数
  126 + BpmFormPageReqVO reqVO = new BpmFormPageReqVO();
  127 + reqVO.setName("芋道");
  128 +
  129 + // 调用
  130 + PageResult<BpmFormDO> pageResult = formService.getFormPage(reqVO);
  131 + // 断言
  132 + assertEquals(1, pageResult.getTotal());
  133 + assertEquals(1, pageResult.getList().size());
  134 + assertPojoEquals(dbForm, pageResult.getList().get(0));
  135 + }
  136 +
  137 + private List<String> randomFields() {
  138 + int size = RandomUtil.randomInt(1, 3);
  139 + return Stream.iterate(0, i -> i).limit(size)
  140 + .map(i -> JsonUtils.toJsonString(randomPojo(BpmFormFieldRespDTO.class)))
  141 + .collect(Collectors.toList());
  142 + }
  143 +
  144 +}
yudao-module-bpm/src/test/java/cn/iocoder/yudao/module/bpm/service/definition/BpmUserGroupServiceTest.java 0 → 100644
  1 +package cn.iocoder.yudao.module.bpm.service.definition;
  2 +
  3 +import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
  4 +import cn.iocoder.yudao.framework.common.pojo.PageResult;
  5 +import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest;
  6 +import cn.iocoder.yudao.framework.test.core.util.AssertUtils;
  7 +import cn.iocoder.yudao.framework.test.core.util.RandomUtils;
  8 +import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.group.BpmUserGroupSaveReqVO;
  9 +import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.group.BpmUserGroupPageReqVO;
  10 +import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmUserGroupDO;
  11 +import cn.iocoder.yudao.module.bpm.dal.mysql.definition.BpmUserGroupMapper;
  12 +import org.junit.jupiter.api.Assertions;
  13 +import org.junit.jupiter.api.Test;
  14 +import org.springframework.context.annotation.Import;
  15 +
  16 +import jakarta.annotation.Resource;
  17 +
  18 +import java.time.LocalDateTime;
  19 +
  20 +import static cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils.buildTime;
  21 +import static cn.iocoder.yudao.framework.common.util.object.ObjectUtils.cloneIgnoreId;
  22 +import static cn.iocoder.yudao.module.bpm.enums.ErrorCodeConstants.USER_GROUP_NOT_EXISTS;
  23 +
  24 +/**
  25 + * {@link BpmUserGroupServiceImpl} 的单元测试类
  26 + *
  27 + * @author 芋道源码
  28 + */
  29 +@Import(BpmUserGroupServiceImpl.class)
  30 +public class BpmUserGroupServiceTest extends BaseDbUnitTest {
  31 +
  32 + @Resource
  33 + private BpmUserGroupServiceImpl userGroupService;
  34 +
  35 + @Resource
  36 + private BpmUserGroupMapper userGroupMapper;
  37 +
  38 + @Test
  39 + public void testCreateUserGroup_success() {
  40 + // 准备参数
  41 + BpmUserGroupSaveReqVO reqVO = RandomUtils.randomPojo(BpmUserGroupSaveReqVO.class);
  42 +
  43 + // 调用
  44 + Long userGroupId = userGroupService.createUserGroup(reqVO);
  45 + // 断言
  46 + Assertions.assertNotNull(userGroupId);
  47 + // 校验记录的属性是否正确
  48 + BpmUserGroupDO userGroup = userGroupMapper.selectById(userGroupId);
  49 + AssertUtils.assertPojoEquals(reqVO, userGroup);
  50 + }
  51 +
  52 + @Test
  53 + public void testUpdateUserGroup_success() {
  54 + // mock 数据
  55 + BpmUserGroupDO dbUserGroup = RandomUtils.randomPojo(BpmUserGroupDO.class);
  56 + userGroupMapper.insert(dbUserGroup);// @Sql: 先插入出一条存在的数据
  57 + // 准备参数
  58 + BpmUserGroupSaveReqVO reqVO = RandomUtils.randomPojo(BpmUserGroupSaveReqVO.class, o -> {
  59 + o.setId(dbUserGroup.getId()); // 设置更新的 ID
  60 + });
  61 +
  62 + // 调用
  63 + userGroupService.updateUserGroup(reqVO);
  64 + // 校验是否更新正确
  65 + BpmUserGroupDO userGroup = userGroupMapper.selectById(reqVO.getId()); // 获取最新的
  66 + AssertUtils.assertPojoEquals(reqVO, userGroup);
  67 + }
  68 +
  69 + @Test
  70 + public void testUpdateUserGroup_notExists() {
  71 + // 准备参数
  72 + BpmUserGroupSaveReqVO reqVO = RandomUtils.randomPojo(BpmUserGroupSaveReqVO.class);
  73 +
  74 + // 调用, 并断言异常
  75 + AssertUtils.assertServiceException(() -> userGroupService.updateUserGroup(reqVO), USER_GROUP_NOT_EXISTS);
  76 + }
  77 +
  78 + @Test
  79 + public void testDeleteUserGroup_success() {
  80 + // mock 数据
  81 + BpmUserGroupDO dbUserGroup = RandomUtils.randomPojo(BpmUserGroupDO.class);
  82 + userGroupMapper.insert(dbUserGroup);// @Sql: 先插入出一条存在的数据
  83 + // 准备参数
  84 + Long id = dbUserGroup.getId();
  85 +
  86 + // 调用
  87 + userGroupService.deleteUserGroup(id);
  88 + // 校验数据不存在了
  89 + Assertions.assertNull(userGroupMapper.selectById(id));
  90 + }
  91 +
  92 + @Test
  93 + public void testDeleteUserGroup_notExists() {
  94 + // 准备参数
  95 + Long id = RandomUtils.randomLongId();
  96 +
  97 + // 调用, 并断言异常
  98 + AssertUtils.assertServiceException(() -> userGroupService.deleteUserGroup(id), USER_GROUP_NOT_EXISTS);
  99 + }
  100 +
  101 + @Test
  102 + public void testGetUserGroupPage() {
  103 + // mock 数据
  104 + BpmUserGroupDO dbUserGroup = RandomUtils.randomPojo(BpmUserGroupDO.class, o -> { // 等会查询到
  105 + o.setName("芋道源码");
  106 + o.setStatus(CommonStatusEnum.ENABLE.getStatus());
  107 + o.setCreateTime(buildTime(2021, 11, 11));
  108 + });
  109 + userGroupMapper.insert(dbUserGroup);
  110 + // 测试 name 不匹配
  111 + userGroupMapper.insert(cloneIgnoreId(dbUserGroup, o -> o.setName("芋道")));
  112 + // 测试 status 不匹配
  113 + userGroupMapper.insert(cloneIgnoreId(dbUserGroup, o -> o.setStatus(CommonStatusEnum.DISABLE.getStatus())));
  114 + // 测试 createTime 不匹配
  115 + userGroupMapper.insert(cloneIgnoreId(dbUserGroup, o -> o.setCreateTime(buildTime(2021, 12, 12))));
  116 + // 准备参数
  117 + BpmUserGroupPageReqVO reqVO = new BpmUserGroupPageReqVO();
  118 + reqVO.setName("源码");
  119 + reqVO.setStatus(CommonStatusEnum.ENABLE.getStatus());
  120 + reqVO.setCreateTime((new LocalDateTime[]{buildTime(2021, 11, 10),buildTime(2021, 11, 12)}));
  121 +
  122 + // 调用
  123 + PageResult<BpmUserGroupDO> pageResult = userGroupService.getUserGroupPage(reqVO);
  124 + // 断言
  125 + Assertions.assertEquals(1, pageResult.getTotal());
  126 + Assertions.assertEquals(1, pageResult.getList().size());
  127 + AssertUtils.assertPojoEquals(dbUserGroup, pageResult.getList().get(0));
  128 + }
  129 +
  130 +}
yudao-module-bpm/src/test/resources/application-unit-test.yaml 0 → 100644
  1 +spring:
  2 + main:
  3 + lazy-initialization: true # 开启懒加载,加快速度
  4 + banner-mode: off # 单元测试,禁用 Banner
  5 +
  6 +--- #################### 数据库相关配置 ####################
  7 +
  8 +spring:
  9 + # 数据源配置项
  10 + datasource:
  11 + name: ruoyi-vue-pro
  12 + url: jdbc:h2:mem:testdb;MODE=MYSQL;DATABASE_TO_UPPER=false;NON_KEYWORDS=value; # MODE 使用 MySQL 模式;DATABASE_TO_UPPER 配置表和字段使用小写
  13 + driver-class-name: org.h2.Driver
  14 + username: sa
  15 + password:
  16 + druid:
  17 + async-init: true # 单元测试,异步初始化 Druid 连接池,提升启动速度
  18 + initial-size: 1 # 单元测试,配置为 1,提升启动速度
  19 + sql:
  20 + init:
  21 + schema-locations: classpath:/sql/create_tables.sql
  22 +
  23 +mybatis-plus:
  24 + lazy-initialization: true # 单元测试,设置 MyBatis Mapper 延迟加载,加速每个单元测试
  25 + type-aliases-package: ${yudao.info.base-package}.module.*.dal.dataobject
  26 +
  27 +--- #################### 定时任务相关配置 ####################
  28 +
  29 +--- #################### 配置中心相关配置 ####################
  30 +
  31 +--- #################### 服务保障相关配置 ####################
  32 +
  33 +# Lock4j 配置项(单元测试,禁用 Lock4j)
  34 +
  35 +--- #################### 监控相关配置 ####################
  36 +
  37 +--- #################### 芋道相关配置 ####################
  38 +
  39 +# 芋道配置项,设置当前项目所有自定义的配置
  40 +yudao:
  41 + info:
  42 + base-package: cn.iocoder.yudao.module
yudao-module-bpm/yudao-module-bpm-biz/src/test/resources/logback.xml renamed to yudao-module-bpm/src/test/resources/logback.xml
yudao-module-bpm/yudao-module-bpm-biz/src/test/resources/sql/clean.sql renamed to yudao-module-bpm/src/test/resources/sql/clean.sql
yudao-module-bpm/src/test/resources/sql/create_tables.sql 0 → 100644
  1 +CREATE TABLE IF NOT EXISTS "bpm_user_group" (
  2 + "id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY,
  3 + "name" varchar(63) NOT NULL,
  4 + "description" varchar(255) NOT NULL,
  5 + "status" tinyint NOT NULL,
  6 + "user_ids" varchar(255) NOT NULL,
  7 + "creator" varchar(64) DEFAULT '',
  8 + "create_time" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
  9 + "updater" varchar(64) DEFAULT '',
  10 + "update_time" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
  11 + "deleted" bit NOT NULL DEFAULT FALSE,
  12 + PRIMARY KEY ("id")
  13 +) COMMENT '用户组';
  14 +
  15 +CREATE TABLE IF NOT EXISTS "bpm_category" (
  16 + "id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY,
  17 + "name" varchar(63) NOT NULL,
  18 + "code" varchar(63) NOT NULL,
  19 + "description" varchar(255) NOT NULL,
  20 + "status" tinyint NOT NULL,
  21 + "sort" int NOT NULL,
  22 + "creator" varchar(64) DEFAULT '',
  23 + "create_time" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
  24 + "updater" varchar(64) DEFAULT '',
  25 + "update_time" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
  26 + "deleted" bit NOT NULL DEFAULT FALSE,
  27 + PRIMARY KEY ("id")
  28 +) COMMENT '分类';
  29 +
  30 +CREATE TABLE IF NOT EXISTS "bpm_form" (
  31 + "id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY,
  32 + "name" varchar(63) NOT NULL,
  33 + "status" tinyint NOT NULL,
  34 + "fields" varchar(255) NOT NULL,
  35 + "conf" varchar(255) NOT NULL,
  36 + "remark" varchar(255),
  37 + "creator" varchar(64) DEFAULT '',
  38 + "create_time" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
  39 + "updater" varchar(64) DEFAULT '',
  40 + "update_time" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
  41 + "deleted" bit NOT NULL DEFAULT FALSE,
  42 + PRIMARY KEY ("id")
  43 +) COMMENT '动态表单';
yudao-module-bpm/yudao-module-bpm-api/pom.xml deleted
1 -<?xml version="1.0" encoding="UTF-8"?>  
2 -<project xmlns="http://maven.apache.org/POM/4.0.0"  
3 - xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
4 - xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">  
5 - <parent>  
6 - <groupId>cn.iocoder.boot</groupId>  
7 - <artifactId>yudao-module-bpm</artifactId>  
8 - <version>${revision}</version>  
9 - </parent>  
10 - <modelVersion>4.0.0</modelVersion>  
11 - <artifactId>yudao-module-bpm-api</artifactId>  
12 - <packaging>jar</packaging>  
13 -  
14 - <name>${project.artifactId}</name>  
15 - <description>  
16 - bpm 模块 API,暴露给其它模块调用  
17 - </description>  
18 -  
19 - <dependencies>  
20 - <dependency>  
21 - <groupId>cn.iocoder.boot</groupId>  
22 - <artifactId>yudao-common</artifactId>  
23 - </dependency>  
24 -  
25 - <!-- 参数校验 -->  
26 - <dependency>  
27 - <groupId>org.springframework.boot</groupId>  
28 - <artifactId>spring-boot-starter-validation</artifactId>  
29 - <optional>true</optional>  
30 - </dependency>  
31 - </dependencies>  
32 -  
33 -</project>  
yudao-module-bpm/yudao-module-bpm-biz/pom.xml deleted
1 -<?xml version="1.0" encoding="UTF-8"?>  
2 -<project xmlns="http://maven.apache.org/POM/4.0.0"  
3 - xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
4 - xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">  
5 - <parent>  
6 - <groupId>cn.iocoder.boot</groupId>  
7 - <artifactId>yudao-module-bpm</artifactId>  
8 - <version>${revision}</version>  
9 - </parent>  
10 - <modelVersion>4.0.0</modelVersion>  
11 - <artifactId>yudao-module-bpm-biz</artifactId>  
12 -  
13 - <name>${project.artifactId}</name>  
14 - <description>  
15 - bpm 包下,业务流程管理(Business Process Management),我们放工作流的功能,基于 Flowable 6 版本实现。  
16 - 例如说:流程定义、表单配置、审核中心(我的申请、我的待办、我的已办)等等  
17 - </description>  
18 - <dependencies>  
19 - <dependency>  
20 - <groupId>cn.iocoder.boot</groupId>  
21 - <artifactId>yudao-module-bpm-api</artifactId>  
22 - <version>${revision}</version>  
23 - </dependency>  
24 - <dependency>  
25 - <groupId>cn.iocoder.boot</groupId>  
26 - <artifactId>yudao-module-system-api</artifactId>  
27 - <version>${revision}</version>  
28 - </dependency>  
29 -  
30 - <!-- 业务组件 -->  
31 - <dependency>  
32 - <groupId>cn.iocoder.boot</groupId>  
33 - <artifactId>yudao-spring-boot-starter-biz-data-permission</artifactId>  
34 - </dependency>  
35 - <dependency>  
36 - <groupId>cn.iocoder.boot</groupId>  
37 - <artifactId>yudao-spring-boot-starter-biz-tenant</artifactId>  
38 - </dependency>  
39 -  
40 - <!-- Web 相关 -->  
41 - <dependency>  
42 - <groupId>cn.iocoder.boot</groupId>  
43 - <artifactId>yudao-spring-boot-starter-web</artifactId>  
44 - </dependency>  
45 -  
46 - <dependency>  
47 - <groupId>cn.iocoder.boot</groupId>  
48 - <artifactId>yudao-spring-boot-starter-security</artifactId>  
49 - </dependency>  
50 -  
51 - <!-- DB 相关 -->  
52 - <dependency>  
53 - <groupId>cn.iocoder.boot</groupId>  
54 - <artifactId>yudao-spring-boot-starter-mybatis</artifactId>  
55 - </dependency>  
56 -  
57 - <!-- Test 测试相关 -->  
58 - <dependency>  
59 - <groupId>cn.iocoder.boot</groupId>  
60 - <artifactId>yudao-spring-boot-starter-test</artifactId>  
61 - </dependency>  
62 -  
63 - <!-- 工具类相关 -->  
64 - <dependency>  
65 - <groupId>cn.iocoder.boot</groupId>  
66 - <artifactId>yudao-spring-boot-starter-excel</artifactId>  
67 - </dependency>  
68 -  
69 - <!-- Flowable 工作流相关 -->  
70 - <dependency>  
71 - <groupId>org.flowable</groupId>  
72 - <artifactId>flowable-spring-boot-starter-process</artifactId>  
73 - </dependency>  
74 - <dependency>  
75 - <groupId>org.flowable</groupId>  
76 - <artifactId>flowable-spring-boot-starter-actuator</artifactId>  
77 - </dependency>  
78 - </dependencies>  
79 -</project>  
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/api/package-info.java deleted
1 -/**  
2 - * bpm API 实现类,定义暴露给其它模块的 API  
3 - */  
4 -package cn.iocoder.yudao.module.bpm.api;  
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/task/listener/BpmUserTaskListener.java deleted
1 -package cn.iocoder.yudao.module.bpm.service.task.listener;  
2 -  
3 -import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.model.simple.BpmSimpleModelNodeVO;  
4 -import cn.iocoder.yudao.module.bpm.enums.definition.BpmHttpRequestParamTypeEnum;  
5 -import cn.iocoder.yudao.module.bpm.framework.flowable.core.util.BpmHttpRequestUtils;  
6 -import cn.iocoder.yudao.module.bpm.service.task.BpmProcessInstanceService;  
7 -import jakarta.annotation.Resource;  
8 -import lombok.Setter;  
9 -import lombok.extern.slf4j.Slf4j;  
10 -import org.flowable.engine.delegate.TaskListener;  
11 -import org.flowable.engine.impl.el.FixedValue;  
12 -import org.flowable.engine.runtime.ProcessInstance;  
13 -import org.flowable.task.service.delegate.DelegateTask;  
14 -import org.springframework.context.annotation.Scope;  
15 -import org.springframework.stereotype.Component;  
16 -  
17 -import static cn.iocoder.yudao.module.bpm.framework.flowable.core.util.BpmnModelUtils.parseListenerConfig;  
18 -  
19 -// TODO @芋艿:可能会想换个包地址  
20 -/**  
21 - * BPM 用户任务通用监听器  
22 - *  
23 - * @author Lesan  
24 - */  
25 -@Component  
26 -@Slf4j  
27 -@Scope("prototype")  
28 -public class BpmUserTaskListener implements TaskListener {  
29 -  
30 - public static final String DELEGATE_EXPRESSION = "${bpmUserTaskListener}";  
31 -  
32 - @Resource  
33 - private BpmProcessInstanceService processInstanceService;  
34 -  
35 - @Setter  
36 - private FixedValue listenerConfig;  
37 -  
38 - @Override  
39 - public void notify(DelegateTask delegateTask) {  
40 - // 1. 获取所需基础信息  
41 - ProcessInstance processInstance = processInstanceService.getProcessInstance(delegateTask.getProcessInstanceId());  
42 - BpmSimpleModelNodeVO.ListenerHandler listenerHandler = parseListenerConfig(listenerConfig);  
43 -  
44 - // 2. 发起请求  
45 - // TODO @芋艿:哪些默认参数,后续再调研下;感觉可以搞个 task 字段,把整个 delegateTask 放进去;  
46 - listenerHandler.getBody().add(new BpmSimpleModelNodeVO.HttpRequestParam().setKey("processInstanceId")  
47 - .setType(BpmHttpRequestParamTypeEnum.FIXED_VALUE.getType()).setValue(delegateTask.getProcessInstanceId()));  
48 - listenerHandler.getBody().add(new BpmSimpleModelNodeVO.HttpRequestParam().setKey("assignee")  
49 - .setType(BpmHttpRequestParamTypeEnum.FIXED_VALUE.getType()).setValue(delegateTask.getAssignee()));  
50 - listenerHandler.getBody().add(new BpmSimpleModelNodeVO.HttpRequestParam().setKey("taskDefinitionKey")  
51 - .setType(BpmHttpRequestParamTypeEnum.FIXED_VALUE.getType()).setValue(delegateTask.getTaskDefinitionKey()));  
52 - listenerHandler.getBody().add(new BpmSimpleModelNodeVO.HttpRequestParam().setKey("taskId")  
53 - .setType(BpmHttpRequestParamTypeEnum.FIXED_VALUE.getType()).setValue(delegateTask.getId()));  
54 - BpmHttpRequestUtils.executeBpmHttpRequest(processInstance,  
55 - listenerHandler.getPath(), listenerHandler.getHeader(), listenerHandler.getBody(), false, null);  
56 -  
57 - // 3. 是否需要后续操作?TODO 芋艿:待定!  
58 - }  
59 -}  
60 \ No newline at end of file 0 \ No newline at end of file
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/task/trigger/form/BpmFormDeleteTrigger.java deleted
1 -package cn.iocoder.yudao.module.bpm.service.task.trigger.form;  
2 -  
3 -import cn.hutool.core.collection.CollUtil;  
4 -import cn.iocoder.yudao.framework.common.util.json.JsonUtils;  
5 -import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.model.simple.BpmSimpleModelNodeVO;  
6 -import cn.iocoder.yudao.module.bpm.enums.definition.BpmTriggerTypeEnum;  
7 -import cn.iocoder.yudao.module.bpm.framework.flowable.core.util.BpmnModelUtils;  
8 -import cn.iocoder.yudao.module.bpm.framework.flowable.core.util.SimpleModelUtils;  
9 -import cn.iocoder.yudao.module.bpm.service.task.BpmProcessInstanceService;  
10 -import cn.iocoder.yudao.module.bpm.service.task.trigger.BpmTrigger;  
11 -import com.fasterxml.jackson.core.type.TypeReference;  
12 -import jakarta.annotation.Resource;  
13 -import lombok.extern.slf4j.Slf4j;  
14 -import org.springframework.stereotype.Component;  
15 -  
16 -import java.util.HashSet;  
17 -import java.util.List;  
18 -import java.util.Map;  
19 -import java.util.Set;  
20 -  
21 -/**  
22 - * BPM 删除流程表单数据触发器  
23 - *  
24 - * @author jason  
25 - */  
26 -@Component  
27 -@Slf4j  
28 -public class BpmFormDeleteTrigger implements BpmTrigger {  
29 -  
30 - @Resource  
31 - private BpmProcessInstanceService processInstanceService;  
32 -  
33 - @Override  
34 - public BpmTriggerTypeEnum getType() {  
35 - return BpmTriggerTypeEnum.FORM_DELETE;  
36 - }  
37 -  
38 - @Override  
39 - public void execute(String processInstanceId, String param) {  
40 - // 1. 解析删除流程表单数据配置  
41 - List<BpmSimpleModelNodeVO.TriggerSetting.FormTriggerSetting> settings = JsonUtils.parseObject(param, new TypeReference<>() {});  
42 - if (CollUtil.isEmpty(settings)) {  
43 - log.error("[execute][流程({}) 删除流程表单数据触发器配置为空]", processInstanceId);  
44 - return;  
45 - }  
46 -  
47 - // 2. 获取流程变量  
48 - Map<String, Object> processVariables = processInstanceService.getProcessInstance(processInstanceId).getProcessVariables();  
49 -  
50 - // 3.1 获取需要删除的表单字段  
51 - Set<String> deleteFields = new HashSet<>();  
52 - settings.forEach(setting -> {  
53 - if (CollUtil.isEmpty(setting.getDeleteFields())) {  
54 - return;  
55 - }  
56 - // 配置了条件,判断条件是否满足  
57 - boolean isFieldDeletedNeeded = true;  
58 - if (setting.getConditionType() != null) {  
59 - String conditionExpression = SimpleModelUtils.buildConditionExpression(  
60 - setting.getConditionType(), setting.getConditionExpression(), setting.getConditionGroups());  
61 - isFieldDeletedNeeded = BpmnModelUtils.evalConditionExpress(processVariables, conditionExpression);  
62 - }  
63 - if (isFieldDeletedNeeded) {  
64 - deleteFields.addAll(setting.getDeleteFields());  
65 - }  
66 - });  
67 -  
68 - // 3.2 删除流程变量  
69 - if (CollUtil.isNotEmpty(deleteFields)) {  
70 - processInstanceService.removeProcessInstanceVariables(processInstanceId, deleteFields);  
71 - }  
72 - }  
73 -}  
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/task/trigger/form/BpmFormUpdateTrigger.java deleted
1 -package cn.iocoder.yudao.module.bpm.service.task.trigger.form;  
2 -  
3 -import cn.hutool.core.collection.CollUtil;  
4 -import cn.iocoder.yudao.framework.common.util.json.JsonUtils;  
5 -import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.model.simple.BpmSimpleModelNodeVO.TriggerSetting.FormTriggerSetting;  
6 -import cn.iocoder.yudao.module.bpm.enums.definition.BpmTriggerTypeEnum;  
7 -import cn.iocoder.yudao.module.bpm.framework.flowable.core.util.BpmnModelUtils;  
8 -import cn.iocoder.yudao.module.bpm.framework.flowable.core.util.SimpleModelUtils;  
9 -import cn.iocoder.yudao.module.bpm.service.task.BpmProcessInstanceService;  
10 -import cn.iocoder.yudao.module.bpm.service.task.trigger.BpmTrigger;  
11 -import com.fasterxml.jackson.core.type.TypeReference;  
12 -import jakarta.annotation.Resource;  
13 -import lombok.extern.slf4j.Slf4j;  
14 -import org.springframework.stereotype.Component;  
15 -  
16 -import java.util.List;  
17 -import java.util.Map;  
18 -  
19 -/**  
20 - * BPM 更新流程表单触发器  
21 - *  
22 - * @author jason  
23 - */  
24 -@Component  
25 -@Slf4j  
26 -public class BpmFormUpdateTrigger implements BpmTrigger {  
27 -  
28 - @Resource  
29 - private BpmProcessInstanceService processInstanceService;  
30 -  
31 - @Override  
32 - public BpmTriggerTypeEnum getType() {  
33 - return BpmTriggerTypeEnum.FORM_UPDATE;  
34 - }  
35 -  
36 - @Override  
37 - public void execute(String processInstanceId, String param) {  
38 - // 1. 解析更新流程表单配置  
39 - List<FormTriggerSetting> settings = JsonUtils.parseObject(param, new TypeReference<>() {});  
40 - if (CollUtil.isEmpty(settings)) {  
41 - log.error("[execute][流程({}) 更新流程表单触发器配置为空]", processInstanceId);  
42 - return;  
43 - }  
44 -  
45 - // 2. 获取流程变量  
46 - Map<String, Object> processVariables = processInstanceService.getProcessInstance(processInstanceId).getProcessVariables();  
47 -  
48 - // 3. 更新流程变量  
49 - for (FormTriggerSetting setting : settings) {  
50 - if (CollUtil.isEmpty(setting.getUpdateFormFields())) {  
51 - continue;  
52 - }  
53 - // 配置了条件,判断条件是否满足  
54 - boolean isFormUpdateNeeded = true;  
55 - if (setting.getConditionType() != null) {  
56 - String conditionExpression = SimpleModelUtils.buildConditionExpression(  
57 - setting.getConditionType(), setting.getConditionExpression(), setting.getConditionGroups());  
58 - isFormUpdateNeeded = BpmnModelUtils.evalConditionExpress(processVariables, conditionExpression);  
59 - }  
60 - // 更新流程表单  
61 - if (isFormUpdateNeeded) {  
62 - processInstanceService.updateProcessInstanceVariables(processInstanceId, setting.getUpdateFormFields());  
63 - }  
64 - }  
65 - }  
66 -}  
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/task/trigger/http/BpmHttpCallbackTrigger.java deleted
1 -package cn.iocoder.yudao.module.bpm.service.task.trigger.http;  
2 -  
3 -import cn.iocoder.yudao.framework.common.util.json.JsonUtils;  
4 -import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.model.simple.BpmSimpleModelNodeVO;  
5 -import cn.iocoder.yudao.module.bpm.enums.definition.BpmHttpRequestParamTypeEnum;  
6 -import cn.iocoder.yudao.module.bpm.enums.definition.BpmTriggerTypeEnum;  
7 -import cn.iocoder.yudao.module.bpm.framework.flowable.core.util.BpmHttpRequestUtils;  
8 -import cn.iocoder.yudao.module.bpm.service.task.BpmProcessInstanceService;  
9 -import jakarta.annotation.Resource;  
10 -import lombok.extern.slf4j.Slf4j;  
11 -import org.flowable.engine.runtime.ProcessInstance;  
12 -import org.springframework.stereotype.Component;  
13 -import org.springframework.web.client.RestTemplate;  
14 -  
15 -/**  
16 - * BPM HTTP 回调触发器  
17 - *  
18 - * @author jason  
19 - */  
20 -@Component  
21 -@Slf4j  
22 -public class BpmHttpCallbackTrigger extends BpmAbstractHttpRequestTrigger {  
23 -  
24 - @Resource  
25 - private BpmProcessInstanceService processInstanceService;  
26 -  
27 - @Override  
28 - public BpmTriggerTypeEnum getType() {  
29 - return BpmTriggerTypeEnum.HTTP_CALLBACK;  
30 - }  
31 -  
32 - @Override  
33 - public void execute(String processInstanceId, String param) {  
34 - // 1. 解析 http 请求配置  
35 - BpmSimpleModelNodeVO.TriggerSetting.HttpRequestTriggerSetting setting = JsonUtils.parseObject(param,  
36 - BpmSimpleModelNodeVO.TriggerSetting.HttpRequestTriggerSetting.class);  
37 - if (setting == null) {  
38 - log.error("[execute][流程({}) HTTP 回调触发器配置为空]", processInstanceId);  
39 - return;  
40 - }  
41 -  
42 - // 2. 发起请求  
43 - ProcessInstance processInstance = processInstanceService.getProcessInstance(processInstanceId);  
44 - setting.getBody().add(new BpmSimpleModelNodeVO.HttpRequestParam()  
45 - .setKey("taskDefineKey") // 重要:回调请求 taskDefineKey 需要传给被调用方,用于回调执行  
46 - .setType(BpmHttpRequestParamTypeEnum.FIXED_VALUE.getType()).setValue(setting.getCallbackTaskDefineKey()));  
47 - BpmHttpRequestUtils.executeBpmHttpRequest(processInstance,  
48 - setting.getUrl(), setting.getHeader(), setting.getBody(), false, null);  
49 - }  
50 -  
51 -}  
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/task/trigger/http/BpmSyncHttpRequestTrigger.java deleted
1 -package cn.iocoder.yudao.module.bpm.service.task.trigger.http;  
2 -  
3 -import cn.iocoder.yudao.framework.common.util.json.JsonUtils;  
4 -import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.model.simple.BpmSimpleModelNodeVO.TriggerSetting.HttpRequestTriggerSetting;  
5 -import cn.iocoder.yudao.module.bpm.enums.definition.BpmTriggerTypeEnum;  
6 -import cn.iocoder.yudao.module.bpm.framework.flowable.core.util.BpmHttpRequestUtils;  
7 -import cn.iocoder.yudao.module.bpm.service.task.BpmProcessInstanceService;  
8 -import jakarta.annotation.Resource;  
9 -import lombok.extern.slf4j.Slf4j;  
10 -import org.flowable.engine.runtime.ProcessInstance;  
11 -import org.springframework.stereotype.Component;  
12 -import org.springframework.web.client.RestTemplate;  
13 -  
14 -/**  
15 - * BPM 发送同步 HTTP 请求触发器  
16 - *  
17 - * @author jason  
18 - */  
19 -@Component  
20 -@Slf4j  
21 -public class BpmSyncHttpRequestTrigger extends BpmAbstractHttpRequestTrigger {  
22 -  
23 - @Resource  
24 - private BpmProcessInstanceService processInstanceService;  
25 -  
26 - @Override  
27 - public BpmTriggerTypeEnum getType() {  
28 - return BpmTriggerTypeEnum.HTTP_REQUEST;  
29 - }  
30 -  
31 - @Override  
32 - public void execute(String processInstanceId, String param) {  
33 - // 1. 解析 http 请求配置  
34 - HttpRequestTriggerSetting setting = JsonUtils.parseObject(param, HttpRequestTriggerSetting.class);  
35 - if (setting == null) {  
36 - log.error("[execute][流程({}) HTTP 触发器请求配置为空]", processInstanceId);  
37 - return;  
38 - }  
39 -  
40 - // 2. 发起请求  
41 - ProcessInstance processInstance = processInstanceService.getProcessInstance(processInstanceId);  
42 - BpmHttpRequestUtils.executeBpmHttpRequest(processInstance,  
43 - setting.getUrl(), setting.getHeader(), setting.getBody(), true, setting.getResponse());  
44 - }  
45 -  
46 -}  
yudao-module-bpm/yudao-module-bpm-biz/src/test/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/candidate/strategy/dept/BpmTaskCandidateDeptLeaderMultiStrategyTest.java deleted
1 -package cn.iocoder.yudao.module.bpm.framework.flowable.core.candidate.strategy.dept;  
2 -  
3 -import cn.iocoder.yudao.framework.test.core.ut.BaseMockitoUnitTest;  
4 -import cn.iocoder.yudao.module.system.api.dept.DeptApi;  
5 -import cn.iocoder.yudao.module.system.api.dept.dto.DeptRespDTO;  
6 -import org.assertj.core.util.Sets;  
7 -import org.junit.jupiter.api.Test;  
8 -import org.mockito.InjectMocks;  
9 -import org.mockito.Mock;  
10 -import org.mockito.stubbing.Answer;  
11 -  
12 -import java.util.Set;  
13 -  
14 -import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomPojo;  
15 -import static org.junit.jupiter.api.Assertions.assertEquals;  
16 -import static org.mockito.ArgumentMatchers.any;  
17 -import static org.mockito.Mockito.when;  
18 -  
19 -public class BpmTaskCandidateDeptLeaderMultiStrategyTest extends BaseMockitoUnitTest {  
20 -  
21 - @InjectMocks  
22 - private BpmTaskCandidateDeptLeaderMultiStrategy strategy;  
23 -  
24 - @Mock  
25 - private DeptApi deptApi;  
26 -  
27 - @Test  
28 - public void testCalculateUsers() {  
29 - // 准备参数  
30 - String param = "10,20|2";  
31 - // mock 方法  
32 - when(deptApi.getDept(any())).thenAnswer((Answer<DeptRespDTO>) invocationOnMock -> {  
33 - Long deptId = invocationOnMock.getArgument(0);  
34 - return randomPojo(DeptRespDTO.class, o -> o.setId(deptId).setParentId(deptId * 100).setLeaderUserId(deptId + 1));  
35 - });  
36 -  
37 - // 调用  
38 - Set<Long> userIds = strategy.calculateUsers(param);  
39 - // 断言结果  
40 - assertEquals(Sets.newLinkedHashSet(11L, 1001L, 21L, 2001L), userIds);  
41 - }  
42 -  
43 -}  
yudao-module-bpm/yudao-module-bpm-biz/src/test/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/candidate/strategy/dept/BpmTaskCandidateDeptLeaderStrategyTest.java deleted
1 -package cn.iocoder.yudao.module.bpm.framework.flowable.core.candidate.strategy.dept;  
2 -  
3 -import cn.iocoder.yudao.framework.common.util.collection.SetUtils;  
4 -import cn.iocoder.yudao.framework.test.core.ut.BaseMockitoUnitTest;  
5 -import cn.iocoder.yudao.module.system.api.dept.DeptApi;  
6 -import cn.iocoder.yudao.module.system.api.dept.dto.DeptRespDTO;  
7 -import org.assertj.core.util.Sets;  
8 -import org.junit.jupiter.api.Test;  
9 -import org.mockito.InjectMocks;  
10 -import org.mockito.Mock;  
11 -  
12 -import java.util.Set;  
13 -  
14 -import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomPojo;  
15 -import static java.util.Arrays.asList;  
16 -import static org.junit.jupiter.api.Assertions.assertEquals;  
17 -import static org.mockito.ArgumentMatchers.eq;  
18 -import static org.mockito.Mockito.when;  
19 -  
20 -public class BpmTaskCandidateDeptLeaderStrategyTest extends BaseMockitoUnitTest {  
21 -  
22 - @InjectMocks  
23 - private BpmTaskCandidateDeptLeaderStrategy strategy;  
24 -  
25 - @Mock  
26 - private DeptApi deptApi;  
27 -  
28 - @Test  
29 - public void testCalculateUsers() {  
30 - // 准备参数  
31 - String param = "10,20";  
32 - // mock 方法  
33 - when(deptApi.getDeptList(eq(SetUtils.asSet(10L, 20L)))).thenReturn(asList(  
34 - randomPojo(DeptRespDTO.class, o -> o.setId(10L).setParentId(10L).setLeaderUserId(11L)),  
35 - randomPojo(DeptRespDTO.class, o -> o.setId(20L).setParentId(20L).setLeaderUserId(21L))));  
36 -  
37 - // 调用  
38 - Set<Long> userIds = strategy.calculateUsers(param);  
39 - // 断言结果  
40 - assertEquals(Sets.newLinkedHashSet(11L, 21L), userIds);  
41 - }  
42 -  
43 -}  
yudao-module-bpm/yudao-module-bpm-biz/src/test/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/candidate/strategy/dept/BpmTaskCandidateDeptMemberStrategyTest.java deleted
1 -package cn.iocoder.yudao.module.bpm.framework.flowable.core.candidate.strategy.dept;  
2 -  
3 -import cn.iocoder.yudao.framework.common.util.collection.SetUtils;  
4 -import cn.iocoder.yudao.framework.test.core.ut.BaseMockitoUnitTest;  
5 -import cn.iocoder.yudao.module.system.api.dept.DeptApi;  
6 -import cn.iocoder.yudao.module.system.api.user.AdminUserApi;  
7 -import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;  
8 -import org.assertj.core.util.Sets;  
9 -import org.junit.jupiter.api.Test;  
10 -import org.mockito.InjectMocks;  
11 -import org.mockito.Mock;  
12 -  
13 -import java.util.Set;  
14 -  
15 -import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomPojo;  
16 -import static java.util.Arrays.asList;  
17 -import static org.junit.jupiter.api.Assertions.assertEquals;  
18 -import static org.mockito.ArgumentMatchers.eq;  
19 -import static org.mockito.Mockito.when;  
20 -  
21 -public class BpmTaskCandidateDeptMemberStrategyTest extends BaseMockitoUnitTest {  
22 -  
23 - @InjectMocks  
24 - private BpmTaskCandidateDeptMemberStrategy strategy;  
25 -  
26 - @Mock  
27 - private DeptApi deptApi;  
28 - @Mock  
29 - private AdminUserApi adminUserApi;  
30 -  
31 - @Test  
32 - public void testCalculateUsers() {  
33 - // 准备参数  
34 - String param = "10,20";  
35 - // mock 方法  
36 - when(adminUserApi.getUserListByDeptIds(eq(SetUtils.asSet(10L, 20L)))).thenReturn(asList(  
37 - randomPojo(AdminUserRespDTO.class, o -> o.setId(11L)),  
38 - randomPojo(AdminUserRespDTO.class, o -> o.setId(21L))));  
39 -  
40 - // 调用  
41 - Set<Long> userIds = strategy.calculateUsers(param);  
42 - // 断言结果  
43 - assertEquals(Sets.newLinkedHashSet(11L, 21L), userIds);  
44 - }  
45 -  
46 -}  
yudao-module-bpm/yudao-module-bpm-biz/src/test/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/candidate/strategy/dept/BpmTaskCandidateStartUserDeptLeaderMultiStrategyTest.java deleted
1 -package cn.iocoder.yudao.module.bpm.framework.flowable.core.candidate.strategy.dept;  
2 -  
3 -import cn.iocoder.yudao.framework.test.core.ut.BaseMockitoUnitTest;  
4 -import cn.iocoder.yudao.module.bpm.service.task.BpmProcessInstanceService;  
5 -import cn.iocoder.yudao.module.system.api.dept.DeptApi;  
6 -import cn.iocoder.yudao.module.system.api.dept.dto.DeptRespDTO;  
7 -import cn.iocoder.yudao.module.system.api.user.AdminUserApi;  
8 -import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;  
9 -import org.assertj.core.util.Sets;  
10 -import org.flowable.engine.delegate.DelegateExecution;  
11 -import org.flowable.engine.runtime.ProcessInstance;  
12 -import org.junit.jupiter.api.Test;  
13 -import org.mockito.InjectMocks;  
14 -import org.mockito.Mock;  
15 -import org.mockito.stubbing.Answer;  
16 -  
17 -import java.util.Set;  
18 -  
19 -import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomPojo;  
20 -import static org.junit.jupiter.api.Assertions.assertEquals;  
21 -import static org.mockito.ArgumentMatchers.any;  
22 -import static org.mockito.ArgumentMatchers.eq;  
23 -import static org.mockito.Mockito.mock;  
24 -import static org.mockito.Mockito.when;  
25 -  
26 -public class BpmTaskCandidateStartUserDeptLeaderMultiStrategyTest extends BaseMockitoUnitTest {  
27 -  
28 - @InjectMocks  
29 - private BpmTaskCandidateStartUserDeptLeaderMultiStrategy strategy;  
30 -  
31 - @Mock  
32 - private BpmProcessInstanceService processInstanceService;  
33 -  
34 - @Mock  
35 - private AdminUserApi adminUserApi;  
36 - @Mock  
37 - private DeptApi deptApi;  
38 -  
39 - @Test  
40 - public void testCalculateUsersByTask() {  
41 - // 准备参数  
42 - String param = "2";  
43 - // mock 方法(获得流程发起人)  
44 - Long startUserId = 1L;  
45 - ProcessInstance processInstance = mock(ProcessInstance.class);  
46 - DelegateExecution execution = mock(DelegateExecution.class);  
47 - when(processInstanceService.getProcessInstance(eq(execution.getProcessInstanceId()))).thenReturn(processInstance);  
48 - when(processInstance.getStartUserId()).thenReturn(startUserId.toString());  
49 - // mock 方法(获取发起人的 multi 部门负责人)  
50 - mockGetStartUserDept(startUserId);  
51 -  
52 - // 调用  
53 - Set<Long> userIds = strategy.calculateUsersByTask(execution, param);  
54 - // 断言  
55 - assertEquals(Sets.newLinkedHashSet(11L, 1001L), userIds);  
56 - }  
57 -  
58 - @Test  
59 - public void testCalculateUsersByActivity() {  
60 - // 准备参数  
61 - String param = "2";  
62 - // mock 方法  
63 - Long startUserId = 1L;  
64 - mockGetStartUserDept(startUserId);  
65 -  
66 - // 调用  
67 - Set<Long> userIds = strategy.calculateUsersByActivity(null, null, param,  
68 - startUserId, null, null);  
69 - // 断言  
70 - assertEquals(Sets.newLinkedHashSet(11L, 1001L), userIds);  
71 - }  
72 -  
73 - private void mockGetStartUserDept(Long startUserId) {  
74 - when(adminUserApi.getUser(eq(startUserId))).thenReturn(  
75 - randomPojo(AdminUserRespDTO.class, o -> o.setId(startUserId).setDeptId(10L)));  
76 - when(deptApi.getDept(any())).thenAnswer((Answer<DeptRespDTO>) invocationOnMock -> {  
77 - Long deptId = invocationOnMock.getArgument(0);  
78 - return randomPojo(DeptRespDTO.class, o -> o.setId(deptId).setParentId(deptId * 100).setLeaderUserId(deptId + 1));  
79 - });  
80 - }  
81 -  
82 -}  
yudao-module-bpm/yudao-module-bpm-biz/src/test/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/candidate/strategy/dept/BpmTaskCandidateStartUserDeptLeaderStrategyTest.java deleted
1 -package cn.iocoder.yudao.module.bpm.framework.flowable.core.candidate.strategy.dept;  
2 -  
3 -import cn.iocoder.yudao.framework.test.core.ut.BaseMockitoUnitTest;  
4 -import cn.iocoder.yudao.module.bpm.service.task.BpmProcessInstanceService;  
5 -import cn.iocoder.yudao.module.system.api.dept.DeptApi;  
6 -import cn.iocoder.yudao.module.system.api.dept.dto.DeptRespDTO;  
7 -import cn.iocoder.yudao.module.system.api.user.AdminUserApi;  
8 -import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;  
9 -import org.assertj.core.util.Sets;  
10 -import org.flowable.engine.delegate.DelegateExecution;  
11 -import org.flowable.engine.runtime.ProcessInstance;  
12 -import org.junit.jupiter.api.Test;  
13 -import org.mockito.InjectMocks;  
14 -import org.mockito.Mock;  
15 -import org.mockito.stubbing.Answer;  
16 -  
17 -import java.util.Set;  
18 -  
19 -import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomPojo;  
20 -import static org.junit.jupiter.api.Assertions.assertEquals;  
21 -import static org.mockito.ArgumentMatchers.any;  
22 -import static org.mockito.ArgumentMatchers.eq;  
23 -import static org.mockito.Mockito.mock;  
24 -import static org.mockito.Mockito.when;  
25 -  
26 -public class BpmTaskCandidateStartUserDeptLeaderStrategyTest extends BaseMockitoUnitTest {  
27 -  
28 - @InjectMocks  
29 - private BpmTaskCandidateStartUserDeptLeaderStrategy strategy;  
30 -  
31 - @Mock  
32 - private BpmProcessInstanceService processInstanceService;  
33 -  
34 - @Mock  
35 - private AdminUserApi adminUserApi;  
36 - @Mock  
37 - private DeptApi deptApi;  
38 -  
39 - @Test  
40 - public void testCalculateUsersByTask() {  
41 - // 准备参数  
42 - String param = "2";  
43 - // mock 方法(获得流程发起人)  
44 - Long startUserId = 1L;  
45 - ProcessInstance processInstance = mock(ProcessInstance.class);  
46 - DelegateExecution execution = mock(DelegateExecution.class);  
47 - when(processInstanceService.getProcessInstance(eq(execution.getProcessInstanceId()))).thenReturn(processInstance);  
48 - when(processInstance.getStartUserId()).thenReturn(startUserId.toString());  
49 - // mock 方法(获取发起人的部门负责人)  
50 - mockGetStartUserDeptLeader(startUserId);  
51 -  
52 - // 调用  
53 - Set<Long> userIds = strategy.calculateUsersByTask(execution, param);  
54 - // 断言  
55 - assertEquals(Sets.newLinkedHashSet(1001L), userIds);  
56 - }  
57 -  
58 - @Test  
59 - public void testGetStartUserDeptLeader() {  
60 - // 准备参数  
61 - String param = "2";  
62 - // mock 方法  
63 - Long startUserId = 1L;  
64 - mockGetStartUserDeptLeader(startUserId);  
65 -  
66 - // 调用  
67 - Set<Long> userIds = strategy.calculateUsersByActivity(null, null, param,  
68 - startUserId, null, null);  
69 - // 断言  
70 - assertEquals(Sets.newLinkedHashSet(1001L), userIds);  
71 - }  
72 -  
73 - private void mockGetStartUserDeptLeader(Long startUserId) {  
74 - when(adminUserApi.getUser(eq(startUserId))).thenReturn(  
75 - randomPojo(AdminUserRespDTO.class, o -> o.setId(startUserId).setDeptId(10L)));  
76 - when(deptApi.getDept(any())).thenAnswer((Answer<DeptRespDTO>) invocationOnMock -> {  
77 - Long deptId = invocationOnMock.getArgument(0);  
78 - return randomPojo(DeptRespDTO.class, o -> o.setId(deptId).setParentId(deptId * 100).setLeaderUserId(deptId + 1));  
79 - });  
80 - }  
81 -  
82 -}  
yudao-module-bpm/yudao-module-bpm-biz/src/test/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/candidate/strategy/dept/BpmTaskCandidateStartUserSelectStrategyTest.java deleted
1 -package cn.iocoder.yudao.module.bpm.framework.flowable.core.candidate.strategy.dept;  
2 -  
3 -import cn.hutool.core.map.MapUtil;  
4 -import cn.iocoder.yudao.framework.test.core.ut.BaseMockitoUnitTest;  
5 -import cn.iocoder.yudao.module.bpm.framework.flowable.core.enums.BpmnVariableConstants;  
6 -import cn.iocoder.yudao.module.bpm.service.task.BpmProcessInstanceService;  
7 -import org.assertj.core.util.Sets;  
8 -import org.flowable.engine.delegate.DelegateExecution;  
9 -import org.flowable.engine.runtime.ProcessInstance;  
10 -import org.junit.jupiter.api.Test;  
11 -import org.mockito.InjectMocks;  
12 -import org.mockito.Mock;  
13 -  
14 -import java.util.HashMap;  
15 -import java.util.List;  
16 -import java.util.Map;  
17 -import java.util.Set;  
18 -  
19 -import static org.junit.jupiter.api.Assertions.assertEquals;  
20 -import static org.mockito.ArgumentMatchers.eq;  
21 -import static org.mockito.Mockito.mock;  
22 -import static org.mockito.Mockito.when;  
23 -  
24 -public class BpmTaskCandidateStartUserSelectStrategyTest extends BaseMockitoUnitTest {  
25 -  
26 - @InjectMocks  
27 - private BpmTaskCandidateStartUserSelectStrategy strategy;  
28 -  
29 - @Mock  
30 - private BpmProcessInstanceService processInstanceService;  
31 -  
32 - @Test  
33 - public void testCalculateUsersByTask() {  
34 - // 准备参数  
35 - String param = "2";  
36 - // mock 方法(获得流程发起人)  
37 - ProcessInstance processInstance = mock(ProcessInstance.class);  
38 - DelegateExecution execution = mock(DelegateExecution.class);  
39 - when(processInstanceService.getProcessInstance(eq(execution.getProcessInstanceId()))).thenReturn(processInstance);  
40 - when(execution.getCurrentActivityId()).thenReturn("activity_001");  
41 - // mock 方法(FlowableUtils)  
42 - Map<String, Object> processVariables = new HashMap<>();  
43 - processVariables.put(BpmnVariableConstants.PROCESS_INSTANCE_VARIABLE_START_USER_SELECT_ASSIGNEES,  
44 - MapUtil.of("activity_001", List.of(1L, 2L)));  
45 - when(processInstance.getProcessVariables()).thenReturn(processVariables);  
46 -  
47 - // 调用  
48 - Set<Long> userIds = strategy.calculateUsersByTask(execution, param);  
49 - // 断言  
50 - assertEquals(Sets.newLinkedHashSet(1L, 2L), userIds);  
51 - }  
52 -  
53 - @Test  
54 - public void testCalculateUsersByActivity() {  
55 - // 准备参数  
56 - String activityId = "activity_001";  
57 - Map<String, Object> processVariables = new HashMap<>();  
58 - processVariables.put(BpmnVariableConstants.PROCESS_INSTANCE_VARIABLE_START_USER_SELECT_ASSIGNEES,  
59 - MapUtil.of("activity_001", List.of(1L, 2L)));  
60 -  
61 - // 调用  
62 - Set<Long> userIds = strategy.calculateUsersByActivity(null, activityId, null,  
63 - null, null, processVariables);  
64 - // 断言  
65 - assertEquals(Sets.newLinkedHashSet(1L, 2L), userIds);  
66 - }  
67 -  
68 -}  
yudao-module-bpm/yudao-module-bpm-biz/src/test/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/candidate/strategy/other/BpmTaskCandidateAssignEmptyStrategyTest.java deleted
1 -package cn.iocoder.yudao.module.bpm.framework.flowable.core.candidate.strategy.other;  
2 -  
3 -import cn.hutool.core.collection.ListUtil;  
4 -import cn.iocoder.yudao.framework.common.util.collection.SetUtils;  
5 -import cn.iocoder.yudao.framework.test.core.ut.BaseMockitoUnitTest;  
6 -import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmProcessDefinitionInfoDO;  
7 -import cn.iocoder.yudao.module.bpm.enums.definition.BpmUserTaskAssignEmptyHandlerTypeEnum;  
8 -import cn.iocoder.yudao.module.bpm.framework.flowable.core.util.BpmnModelUtils;  
9 -import cn.iocoder.yudao.module.bpm.framework.flowable.core.util.FlowableUtils;  
10 -import cn.iocoder.yudao.module.bpm.service.definition.BpmProcessDefinitionService;  
11 -import org.flowable.bpmn.model.BpmnModel;  
12 -import org.flowable.bpmn.model.FlowElement;  
13 -import org.flowable.engine.delegate.DelegateExecution;  
14 -import org.junit.jupiter.api.Test;  
15 -import org.mockito.InjectMocks;  
16 -import org.mockito.Mock;  
17 -import org.mockito.MockedStatic;  
18 -  
19 -import java.util.Set;  
20 -  
21 -import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomPojo;  
22 -import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomString;  
23 -import static org.junit.jupiter.api.Assertions.assertEquals;  
24 -import static org.mockito.Mockito.*;  
25 -  
26 -public class BpmTaskCandidateAssignEmptyStrategyTest extends BaseMockitoUnitTest {  
27 -  
28 - @InjectMocks  
29 - private BpmTaskCandidateAssignEmptyStrategy strategy;  
30 -  
31 - @Mock  
32 - private BpmProcessDefinitionService processDefinitionService;  
33 -  
34 - @Test  
35 - public void testCalculateUsersByTask() {  
36 - try (MockedStatic<FlowableUtils> flowableUtilMockedStatic = mockStatic(FlowableUtils.class);  
37 - MockedStatic<BpmnModelUtils> bpmnModelUtilsMockedStatic = mockStatic(BpmnModelUtils.class)) {  
38 - // 准备参数  
39 - DelegateExecution execution = mock(DelegateExecution.class);  
40 - String param = randomString();  
41 - // mock 方法(execution)  
42 - String processDefinitionId = randomString();  
43 - when(execution.getProcessDefinitionId()).thenReturn(processDefinitionId);  
44 - FlowElement flowElement = mock(FlowElement.class);  
45 - when(execution.getCurrentFlowElement()).thenReturn(flowElement);  
46 - // mock 方法(parseAssignEmptyHandlerType)  
47 - bpmnModelUtilsMockedStatic.when(() -> BpmnModelUtils.parseAssignEmptyHandlerType(same(flowElement)))  
48 - .thenReturn(BpmUserTaskAssignEmptyHandlerTypeEnum.ASSIGN_USER.getType());  
49 - bpmnModelUtilsMockedStatic.when(() -> BpmnModelUtils.parseAssignEmptyHandlerUserIds(same(flowElement)))  
50 - .thenReturn(ListUtil.of(1L, 2L));  
51 -  
52 - // 调用  
53 - Set<Long> userIds = strategy.calculateUsersByTask(execution, param);  
54 - // 断言  
55 - assertEquals(SetUtils.asSet(1L, 2L), userIds);  
56 - }  
57 -  
58 - }  
59 -  
60 - @Test  
61 - public void testCalculateUsersByActivity() {  
62 - try (MockedStatic<BpmnModelUtils> bpmnModelUtilsMockedStatic = mockStatic(BpmnModelUtils.class)) {  
63 - // 准备参数  
64 - String processDefinitionId = randomString();  
65 - String activityId = randomString();  
66 - String param = randomString();  
67 - // mock 方法(getFlowElementById)  
68 - FlowElement flowElement = mock(FlowElement.class);  
69 - BpmnModel bpmnModel = mock(BpmnModel.class);  
70 - bpmnModelUtilsMockedStatic.when(() -> BpmnModelUtils.getFlowElementById(same(bpmnModel), eq(activityId)))  
71 - .thenReturn(flowElement);  
72 - // mock 方法(parseAssignEmptyHandlerType)  
73 - bpmnModelUtilsMockedStatic.when(() -> BpmnModelUtils.parseAssignEmptyHandlerType(same(flowElement)))  
74 - .thenReturn(BpmUserTaskAssignEmptyHandlerTypeEnum.ASSIGN_ADMIN.getType());  
75 - // mock 方法(getProcessDefinitionInfo)  
76 - BpmProcessDefinitionInfoDO processDefinition = randomPojo(BpmProcessDefinitionInfoDO.class,  
77 - o -> o.setManagerUserIds(ListUtil.of(1L, 2L)));  
78 - when(processDefinitionService.getProcessDefinitionInfo(eq(processDefinitionId))).thenReturn(processDefinition);  
79 -  
80 - // 调用  
81 - Set<Long> userIds = strategy.calculateUsersByActivity(bpmnModel, activityId, param,  
82 - null, processDefinitionId, null);  
83 - // 断言  
84 - assertEquals(SetUtils.asSet(1L, 2L), userIds);  
85 - }  
86 - }  
87 -  
88 -}  
yudao-module-bpm/yudao-module-bpm-biz/src/test/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/candidate/strategy/other/BpmTaskCandidateExpressionStrategyTest.java deleted
1 -package cn.iocoder.yudao.module.bpm.framework.flowable.core.candidate.strategy.other;  
2 -  
3 -import cn.iocoder.yudao.framework.test.core.ut.BaseMockitoUnitTest;  
4 -import cn.iocoder.yudao.module.bpm.framework.flowable.core.util.FlowableUtils;  
5 -import org.flowable.engine.delegate.DelegateExecution;  
6 -import org.junit.jupiter.api.Disabled;  
7 -import org.junit.jupiter.api.Test;  
8 -import org.mockito.InjectMocks;  
9 -import org.mockito.MockedStatic;  
10 -  
11 -import java.util.HashMap;  
12 -import java.util.Map;  
13 -import java.util.Set;  
14 -  
15 -import static cn.iocoder.yudao.framework.common.util.collection.SetUtils.asSet;  
16 -import static org.junit.jupiter.api.Assertions.assertEquals;  
17 -import static org.mockito.ArgumentMatchers.eq;  
18 -import static org.mockito.Mockito.*;  
19 -  
20 -@Disabled // TODO 芋艿:临时注释  
21 -public class BpmTaskCandidateExpressionStrategyTest extends BaseMockitoUnitTest {  
22 -  
23 - @InjectMocks  
24 - private BpmTaskCandidateExpressionStrategy strategy;  
25 -  
26 - @Test  
27 - public void testCalculateUsersByTask() {  
28 - try (MockedStatic<FlowableUtils> flowableUtilMockedStatic = mockStatic(FlowableUtils.class)) {  
29 - // 准备参数  
30 - String param = "1,2";  
31 - DelegateExecution execution = mock(DelegateExecution.class);  
32 - // mock 方法  
33 - flowableUtilMockedStatic.when(() -> FlowableUtils.getExpressionValue(same(execution), eq(param)))  
34 - .thenReturn(asSet(1L, 2L));  
35 -  
36 - // 调用  
37 - Set<Long> results = strategy.calculateUsersByTask(execution, param);  
38 - // 断言  
39 - assertEquals(asSet(1L, 2L), results);  
40 - }  
41 - }  
42 -  
43 - @Test  
44 - public void testCalculateUsersByActivity() {  
45 - try (MockedStatic<FlowableUtils> flowableUtilMockedStatic = mockStatic(FlowableUtils.class)) {  
46 - // 准备参数  
47 - String param = "1,2";  
48 - Map<String, Object> processVariables = new HashMap<>();  
49 - // mock 方法  
50 - flowableUtilMockedStatic.when(() -> FlowableUtils.getExpressionValue(same(processVariables), eq(param)))  
51 - .thenReturn(asSet(1L, 2L));  
52 -  
53 - // 调用  
54 - Set<Long> results = strategy.calculateUsersByActivity(null, null, param,  
55 - null, null, processVariables);  
56 - // 断言  
57 - assertEquals(asSet(1L, 2L), results);  
58 - }  
59 - }  
60 -  
61 -}  
yudao-module-bpm/yudao-module-bpm-biz/src/test/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/candidate/strategy/user/BpmTaskCandidateGroupStrategyTest.java deleted
1 -package cn.iocoder.yudao.module.bpm.framework.flowable.core.candidate.strategy.user;  
2 -  
3 -import cn.iocoder.yudao.framework.test.core.ut.BaseMockitoUnitTest;  
4 -import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmUserGroupDO;  
5 -import cn.iocoder.yudao.module.bpm.service.definition.BpmUserGroupService;  
6 -import org.junit.jupiter.api.Disabled;  
7 -import org.junit.jupiter.api.Test;  
8 -import org.mockito.InjectMocks;  
9 -import org.mockito.Mock;  
10 -  
11 -import java.util.Arrays;  
12 -import java.util.Set;  
13 -  
14 -import static cn.iocoder.yudao.framework.common.util.collection.SetUtils.asSet;  
15 -import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomPojo;  
16 -import static org.junit.jupiter.api.Assertions.assertEquals;  
17 -import static org.mockito.ArgumentMatchers.eq;  
18 -import static org.mockito.Mockito.when;  
19 -  
20 -@Disabled // TODO 芋艿:临时注释  
21 -public class BpmTaskCandidateGroupStrategyTest extends BaseMockitoUnitTest {  
22 -  
23 - @InjectMocks  
24 - private BpmTaskCandidateGroupStrategy strategy;  
25 -  
26 - @Mock  
27 - private BpmUserGroupService userGroupService;  
28 -  
29 - @Test  
30 - public void testCalculateUsers() {  
31 - // 准备参数  
32 - String param = "1,2";  
33 - // mock 方法  
34 - BpmUserGroupDO userGroup1 = randomPojo(BpmUserGroupDO.class, o -> o.setUserIds(asSet(11L, 12L)));  
35 - BpmUserGroupDO userGroup2 = randomPojo(BpmUserGroupDO.class, o -> o.setUserIds(asSet(21L, 22L)));  
36 - when(userGroupService.getUserGroupList(eq(asSet(1L, 2L)))).thenReturn(Arrays.asList(userGroup1, userGroup2));  
37 -  
38 - // 调用  
39 - Set<Long> userIds = strategy.calculateUsersByTask(null, param);  
40 - // 断言  
41 - assertEquals(asSet(11L, 12L, 21L, 22L), userIds);  
42 - }  
43 -  
44 -}  
yudao-module-bpm/yudao-module-bpm-biz/src/test/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/candidate/strategy/user/BpmTaskCandidatePostStrategyTest.java deleted
1 -package cn.iocoder.yudao.module.bpm.framework.flowable.core.candidate.strategy.user;  
2 -  
3 -import cn.iocoder.yudao.framework.test.core.ut.BaseMockitoUnitTest;  
4 -import cn.iocoder.yudao.module.system.api.dept.PostApi;  
5 -import cn.iocoder.yudao.module.system.api.user.AdminUserApi;  
6 -import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;  
7 -import org.junit.jupiter.api.Disabled;  
8 -import org.junit.jupiter.api.Test;  
9 -import org.mockito.InjectMocks;  
10 -import org.mockito.Mock;  
11 -  
12 -import java.util.List;  
13 -import java.util.Set;  
14 -  
15 -import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList;  
16 -import static cn.iocoder.yudao.framework.common.util.collection.SetUtils.asSet;  
17 -import static org.junit.jupiter.api.Assertions.assertEquals;  
18 -import static org.mockito.ArgumentMatchers.eq;  
19 -import static org.mockito.Mockito.when;  
20 -  
21 -@Disabled // TODO 芋艿:临时注释  
22 -public class BpmTaskCandidatePostStrategyTest extends BaseMockitoUnitTest {  
23 -  
24 - @InjectMocks  
25 - private BpmTaskCandidatePostStrategy strategy;  
26 -  
27 - @Mock  
28 - private PostApi postApi;  
29 - @Mock  
30 - private AdminUserApi adminUserApi;  
31 -  
32 - @Test  
33 - public void testCalculateUsers() {  
34 - // 准备参数  
35 - String param = "1,2";  
36 - // mock 方法  
37 - List<AdminUserRespDTO> users = convertList(asSet(11L, 22L),  
38 - id -> new AdminUserRespDTO().setId(id));  
39 - when(adminUserApi.getUserListByPostIds(eq(asSet(1L, 2L)))).thenReturn(users);  
40 -  
41 - // 调用  
42 - Set<Long> userIds = strategy.calculateUsersByTask(null, param);  
43 - // 断言  
44 - assertEquals(asSet(11L, 22L), userIds);  
45 - }  
46 -  
47 -}  
yudao-module-bpm/yudao-module-bpm-biz/src/test/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/candidate/strategy/user/BpmTaskCandidateRoleStrategyTest.java deleted
1 -package cn.iocoder.yudao.module.bpm.framework.flowable.core.candidate.strategy.user;  
2 -  
3 -import cn.iocoder.yudao.framework.test.core.ut.BaseMockitoUnitTest;  
4 -import cn.iocoder.yudao.module.system.api.permission.PermissionApi;  
5 -import cn.iocoder.yudao.module.system.api.permission.RoleApi;  
6 -import org.junit.jupiter.api.Disabled;  
7 -import org.junit.jupiter.api.Test;  
8 -import org.mockito.InjectMocks;  
9 -import org.mockito.Mock;  
10 -  
11 -import java.util.Set;  
12 -  
13 -import static cn.iocoder.yudao.framework.common.util.collection.SetUtils.asSet;  
14 -import static org.junit.jupiter.api.Assertions.assertEquals;  
15 -import static org.mockito.ArgumentMatchers.eq;  
16 -import static org.mockito.Mockito.when;  
17 -  
18 -@Disabled // TODO 芋艿:临时注释  
19 -public class BpmTaskCandidateRoleStrategyTest extends BaseMockitoUnitTest {  
20 -  
21 - @InjectMocks  
22 - private BpmTaskCandidateRoleStrategy strategy;  
23 -  
24 - @Mock  
25 - private RoleApi roleApi;  
26 - @Mock  
27 - private PermissionApi permissionApi;  
28 -  
29 - @Test  
30 - public void testCalculateUsers() {  
31 - // 准备参数  
32 - String param = "1,2";  
33 - // mock 方法  
34 - when(permissionApi.getUserRoleIdListByRoleIds(eq(asSet(1L, 2L))))  
35 - .thenReturn(asSet(11L, 22L));  
36 -  
37 - // 调用  
38 - Set<Long> userIds = strategy.calculateUsersByTask(null, param);  
39 - // 断言  
40 - assertEquals(asSet(11L, 22L), userIds);  
41 - }  
42 -  
43 -}  
yudao-module-bpm/yudao-module-bpm-biz/src/test/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/candidate/strategy/user/BpmTaskCandidateStartUserStrategyTest.java deleted
1 -package cn.iocoder.yudao.module.bpm.framework.flowable.core.candidate.strategy.user;  
2 -  
3 -import cn.iocoder.yudao.framework.test.core.ut.BaseMockitoUnitTest;  
4 -import cn.iocoder.yudao.module.bpm.service.task.BpmProcessInstanceService;  
5 -import org.assertj.core.util.Sets;  
6 -import org.flowable.engine.delegate.DelegateExecution;  
7 -import org.flowable.engine.runtime.ProcessInstance;  
8 -import org.junit.jupiter.api.Test;  
9 -import org.mockito.InjectMocks;  
10 -import org.mockito.Mock;  
11 -  
12 -import java.util.Set;  
13 -  
14 -import static org.junit.jupiter.api.Assertions.assertEquals;  
15 -import static org.mockito.ArgumentMatchers.eq;  
16 -import static org.mockito.Mockito.mock;  
17 -import static org.mockito.Mockito.when;  
18 -  
19 -public class BpmTaskCandidateStartUserStrategyTest extends BaseMockitoUnitTest {  
20 -  
21 - @InjectMocks  
22 - private BpmTaskCandidateStartUserStrategy strategy;  
23 -  
24 - @Mock  
25 - private BpmProcessInstanceService processInstanceService;  
26 -  
27 - @Test  
28 - public void testCalculateUsersByTask() {  
29 - // 准备参数  
30 - String param = "2";  
31 - // mock 方法(获得流程发起人)  
32 - Long startUserId = 1L;  
33 - ProcessInstance processInstance = mock(ProcessInstance.class);  
34 - DelegateExecution execution = mock(DelegateExecution.class);  
35 - when(processInstanceService.getProcessInstance(eq(execution.getProcessInstanceId()))).thenReturn(processInstance);  
36 - when(processInstance.getStartUserId()).thenReturn(startUserId.toString());  
37 -  
38 - // 调用  
39 - Set<Long> userIds = strategy.calculateUsersByTask(execution, param);  
40 - // 断言  
41 - assertEquals(Sets.newLinkedHashSet(startUserId), userIds);  
42 - }  
43 -  
44 - @Test  
45 - public void testCalculateUsersByActivity() {  
46 - // 准备参数  
47 - Long startUserId = 1L;  
48 -  
49 - // 调用  
50 - Set<Long> userIds = strategy.calculateUsersByActivity(null, null, null,  
51 - startUserId, null, null);  
52 - // 断言  
53 - assertEquals(Sets.newLinkedHashSet(startUserId), userIds);  
54 - }  
55 -  
56 -}  
yudao-module-bpm/yudao-module-bpm-biz/src/test/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/candidate/strategy/user/BpmTaskCandidateUserStrategyTest.java deleted
1 -package cn.iocoder.yudao.module.bpm.framework.flowable.core.candidate.strategy.user;  
2 -  
3 -import cn.iocoder.yudao.framework.test.core.ut.BaseMockitoUnitTest;  
4 -import org.junit.jupiter.api.Disabled;  
5 -import org.junit.jupiter.api.Test;  
6 -import org.mockito.InjectMocks;  
7 -  
8 -import java.util.Set;  
9 -  
10 -import static cn.iocoder.yudao.framework.common.util.collection.SetUtils.asSet;  
11 -import static org.junit.jupiter.api.Assertions.assertEquals;  
12 -  
13 -@Disabled // TODO 芋艿:临时注释  
14 -public class BpmTaskCandidateUserStrategyTest extends BaseMockitoUnitTest {  
15 -  
16 - @InjectMocks  
17 - private BpmTaskCandidateUserStrategy strategy;  
18 -  
19 - @Test  
20 - public void test() {  
21 - // 准备参数  
22 - String param = "1,2";  
23 -  
24 - // 调用  
25 - Set<Long> userIds = strategy.calculateUsersByTask(null, param);  
26 - // 断言  
27 - assertEquals(asSet(1L, 2L), userIds);  
28 - }  
29 -  
30 -  
31 -}  
yudao-module-bpm/yudao-module-bpm-biz/src/test/java/cn/iocoder/yudao/module/bpm/service/category/BpmCategoryServiceImplTest.java deleted
1 -package cn.iocoder.yudao.module.bpm.service.category;  
2 -  
3 -import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;  
4 -import cn.iocoder.yudao.framework.common.pojo.PageResult;  
5 -import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest;  
6 -import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.category.BpmCategoryPageReqVO;  
7 -import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.category.BpmCategorySaveReqVO;  
8 -import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmCategoryDO;  
9 -import cn.iocoder.yudao.module.bpm.dal.mysql.category.BpmCategoryMapper;  
10 -import cn.iocoder.yudao.module.bpm.service.definition.BpmCategoryServiceImpl;  
11 -import jakarta.annotation.Resource;  
12 -import org.junit.jupiter.api.Test;  
13 -import org.springframework.context.annotation.Import;  
14 -  
15 -import static cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils.buildBetweenTime;  
16 -import static cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils.buildTime;  
17 -import static cn.iocoder.yudao.framework.common.util.object.ObjectUtils.cloneIgnoreId;  
18 -import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertPojoEquals;  
19 -import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertServiceException;  
20 -import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.*;  
21 -import static cn.iocoder.yudao.module.bpm.enums.ErrorCodeConstants.CATEGORY_NOT_EXISTS;  
22 -import static org.junit.jupiter.api.Assertions.*;  
23 -  
24 -/**  
25 - * {@link BpmCategoryServiceImpl} 的单元测试类  
26 - *  
27 - * @author 芋道源码  
28 - */  
29 -@Import(BpmCategoryServiceImpl.class)  
30 -public class BpmCategoryServiceImplTest extends BaseDbUnitTest {  
31 -  
32 - @Resource  
33 - private BpmCategoryServiceImpl categoryService;  
34 -  
35 - @Resource  
36 - private BpmCategoryMapper categoryMapper;  
37 -  
38 - @Test  
39 - public void testCreateCategory_success() {  
40 - // 准备参数  
41 - BpmCategorySaveReqVO createReqVO = randomPojo(BpmCategorySaveReqVO.class).setId(null)  
42 - .setStatus(randomCommonStatus());  
43 -  
44 - // 调用  
45 - Long categoryId = categoryService.createCategory(createReqVO);  
46 - // 断言  
47 - assertNotNull(categoryId);  
48 - // 校验记录的属性是否正确  
49 - BpmCategoryDO category = categoryMapper.selectById(categoryId);  
50 - assertPojoEquals(createReqVO, category, "id");  
51 - }  
52 -  
53 - @Test  
54 - public void testUpdateCategory_success() {  
55 - // mock 数据  
56 - BpmCategoryDO dbCategory = randomPojo(BpmCategoryDO.class);  
57 - categoryMapper.insert(dbCategory);// @Sql: 先插入出一条存在的数据  
58 - // 准备参数  
59 - BpmCategorySaveReqVO updateReqVO = randomPojo(BpmCategorySaveReqVO.class, o -> {  
60 - o.setId(dbCategory.getId()); // 设置更新的 ID  
61 - o.setStatus(randomCommonStatus());  
62 - });  
63 -  
64 - // 调用  
65 - categoryService.updateCategory(updateReqVO);  
66 - // 校验是否更新正确  
67 - BpmCategoryDO category = categoryMapper.selectById(updateReqVO.getId()); // 获取最新的  
68 - assertPojoEquals(updateReqVO, category);  
69 - }  
70 -  
71 - @Test  
72 - public void testUpdateCategory_notExists() {  
73 - // 准备参数  
74 - BpmCategorySaveReqVO updateReqVO = randomPojo(BpmCategorySaveReqVO.class);  
75 -  
76 - // 调用, 并断言异常  
77 - assertServiceException(() -> categoryService.updateCategory(updateReqVO), CATEGORY_NOT_EXISTS);  
78 - }  
79 -  
80 - @Test  
81 - public void testDeleteCategory_success() {  
82 - // mock 数据  
83 - BpmCategoryDO dbCategory = randomPojo(BpmCategoryDO.class);  
84 - categoryMapper.insert(dbCategory);// @Sql: 先插入出一条存在的数据  
85 - // 准备参数  
86 - Long id = dbCategory.getId();  
87 -  
88 - // 调用  
89 - categoryService.deleteCategory(id);  
90 - // 校验数据不存在了  
91 - assertNull(categoryMapper.selectById(id));  
92 - }  
93 -  
94 - @Test  
95 - public void testDeleteCategory_notExists() {  
96 - // 准备参数  
97 - Long id = randomLongId();  
98 -  
99 - // 调用, 并断言异常  
100 - assertServiceException(() -> categoryService.deleteCategory(id), CATEGORY_NOT_EXISTS);  
101 - }  
102 -  
103 - @Test  
104 - public void testGetCategoryPage() {  
105 - // mock 数据  
106 - BpmCategoryDO dbCategory = randomPojo(BpmCategoryDO.class, o -> { // 等会查询到  
107 - o.setName("芋头");  
108 - o.setCode("xiaodun");  
109 - o.setStatus(CommonStatusEnum.ENABLE.getStatus());  
110 - o.setCreateTime(buildTime(2023, 2, 2));  
111 - });  
112 - categoryMapper.insert(dbCategory);  
113 - // 测试 name 不匹配  
114 - categoryMapper.insert(cloneIgnoreId(dbCategory, o -> o.setName("小盾")));  
115 - // 测试 code 不匹配  
116 - categoryMapper.insert(cloneIgnoreId(dbCategory, o -> o.setCode("tudou")));  
117 - // 测试 status 不匹配  
118 - categoryMapper.insert(cloneIgnoreId(dbCategory, o -> o.setStatus(CommonStatusEnum.DISABLE.getStatus())));  
119 - // 测试 createTime 不匹配  
120 - categoryMapper.insert(cloneIgnoreId(dbCategory, o -> o.setCreateTime(buildTime(2024, 2, 2))));  
121 - // 准备参数  
122 - BpmCategoryPageReqVO reqVO = new BpmCategoryPageReqVO();  
123 - reqVO.setName("芋");  
124 - reqVO.setCode("xiao");  
125 - reqVO.setStatus(CommonStatusEnum.ENABLE.getStatus());  
126 - reqVO.setCreateTime(buildBetweenTime(2023, 2, 1, 2023, 2, 28));  
127 -  
128 - // 调用  
129 - PageResult<BpmCategoryDO> pageResult = categoryService.getCategoryPage(reqVO);  
130 - // 断言  
131 - assertEquals(1, pageResult.getTotal());  
132 - assertEquals(1, pageResult.getList().size());  
133 - assertPojoEquals(dbCategory, pageResult.getList().get(0));  
134 - }  
135 -  
136 -}  
137 \ No newline at end of file 0 \ No newline at end of file
yudao-module-bpm/yudao-module-bpm-biz/src/test/java/cn/iocoder/yudao/module/bpm/service/definition/BpmFormServiceTest.java deleted
1 -package cn.iocoder.yudao.module.bpm.service.definition;  
2 -  
3 -import cn.hutool.core.util.RandomUtil;  
4 -import cn.iocoder.yudao.framework.common.pojo.PageResult;  
5 -import cn.iocoder.yudao.framework.common.util.json.JsonUtils;  
6 -import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest;  
7 -import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.form.BpmFormSaveReqVO;  
8 -import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.form.BpmFormPageReqVO;  
9 -import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmFormDO;  
10 -import cn.iocoder.yudao.module.bpm.dal.mysql.definition.BpmFormMapper;  
11 -import cn.iocoder.yudao.module.bpm.service.definition.dto.BpmFormFieldRespDTO;  
12 -import org.junit.jupiter.api.Test;  
13 -import org.springframework.context.annotation.Import;  
14 -  
15 -import jakarta.annotation.Resource;  
16 -import java.util.List;  
17 -import java.util.stream.Collectors;  
18 -import java.util.stream.Stream;  
19 -  
20 -import static cn.iocoder.yudao.framework.common.util.object.ObjectUtils.cloneIgnoreId;  
21 -import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertPojoEquals;  
22 -import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertServiceException;  
23 -import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomLongId;  
24 -import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomPojo;  
25 -import static cn.iocoder.yudao.module.bpm.enums.ErrorCodeConstants.FORM_NOT_EXISTS;  
26 -import static org.junit.jupiter.api.Assertions.*;  
27 -  
28 -/**  
29 - * {@link BpmFormServiceImpl} 的单元测试类  
30 - *  
31 - * @author 芋道源码  
32 - */  
33 -@Import(BpmFormServiceImpl.class)  
34 -public class BpmFormServiceTest extends BaseDbUnitTest {  
35 -  
36 - @Resource  
37 - private BpmFormServiceImpl formService;  
38 -  
39 - @Resource  
40 - private BpmFormMapper formMapper;  
41 -  
42 - @Test  
43 - public void testCreateForm_success() {  
44 - // 准备参数  
45 - BpmFormSaveReqVO reqVO = randomPojo(BpmFormSaveReqVO.class, o -> {  
46 - o.setConf("{}");  
47 - o.setFields(randomFields());  
48 - });  
49 -  
50 - // 调用  
51 - Long formId = formService.createForm(reqVO);  
52 - // 断言  
53 - assertNotNull(formId);  
54 - // 校验记录的属性是否正确  
55 - BpmFormDO form = formMapper.selectById(formId);  
56 - assertPojoEquals(reqVO, form);  
57 - }  
58 -  
59 - @Test  
60 - public void testUpdateForm_success() {  
61 - // mock 数据  
62 - BpmFormDO dbForm = randomPojo(BpmFormDO.class, o -> {  
63 - o.setConf("{}");  
64 - o.setFields(randomFields());  
65 - });  
66 - formMapper.insert(dbForm);// @Sql: 先插入出一条存在的数据  
67 - // 准备参数  
68 - BpmFormSaveReqVO reqVO = randomPojo(BpmFormSaveReqVO.class, o -> {  
69 - o.setId(dbForm.getId()); // 设置更新的 ID  
70 - o.setConf("{'yudao': 'yuanma'}");  
71 - o.setFields(randomFields());  
72 - });  
73 -  
74 - // 调用  
75 - formService.updateForm(reqVO);  
76 - // 校验是否更新正确  
77 - BpmFormDO form = formMapper.selectById(reqVO.getId()); // 获取最新的  
78 - assertPojoEquals(reqVO, form);  
79 - }  
80 -  
81 - @Test  
82 - public void testUpdateForm_notExists() {  
83 - // 准备参数  
84 - BpmFormSaveReqVO reqVO = randomPojo(BpmFormSaveReqVO.class, o -> {  
85 - o.setConf("{'yudao': 'yuanma'}");  
86 - o.setFields(randomFields());  
87 - });  
88 -  
89 - // 调用, 并断言异常  
90 - assertServiceException(() -> formService.updateForm(reqVO), FORM_NOT_EXISTS);  
91 - }  
92 -  
93 - @Test  
94 - public void testDeleteForm_success() {  
95 - // mock 数据  
96 - BpmFormDO dbForm = randomPojo(BpmFormDO.class);  
97 - formMapper.insert(dbForm);// @Sql: 先插入出一条存在的数据  
98 - // 准备参数  
99 - Long id = dbForm.getId();  
100 -  
101 - // 调用  
102 - formService.deleteForm(id);  
103 - // 校验数据不存在了  
104 - assertNull(formMapper.selectById(id));  
105 - }  
106 -  
107 - @Test  
108 - public void testDeleteForm_notExists() {  
109 - // 准备参数  
110 - Long id = randomLongId();  
111 -  
112 - // 调用, 并断言异常  
113 - assertServiceException(() -> formService.deleteForm(id), FORM_NOT_EXISTS);  
114 - }  
115 -  
116 - @Test  
117 - public void testGetFormPage() {  
118 - // mock 数据  
119 - BpmFormDO dbForm = randomPojo(BpmFormDO.class, o -> { // 等会查询到  
120 - o.setName("芋道源码");  
121 - });  
122 - formMapper.insert(dbForm);  
123 - // 测试 name 不匹配  
124 - formMapper.insert(cloneIgnoreId(dbForm, o -> o.setName("源码")));  
125 - // 准备参数  
126 - BpmFormPageReqVO reqVO = new BpmFormPageReqVO();  
127 - reqVO.setName("芋道");  
128 -  
129 - // 调用  
130 - PageResult<BpmFormDO> pageResult = formService.getFormPage(reqVO);  
131 - // 断言  
132 - assertEquals(1, pageResult.getTotal());  
133 - assertEquals(1, pageResult.getList().size());  
134 - assertPojoEquals(dbForm, pageResult.getList().get(0));  
135 - }  
136 -  
137 - private List<String> randomFields() {  
138 - int size = RandomUtil.randomInt(1, 3);  
139 - return Stream.iterate(0, i -> i).limit(size)  
140 - .map(i -> JsonUtils.toJsonString(randomPojo(BpmFormFieldRespDTO.class)))  
141 - .collect(Collectors.toList());  
142 - }  
143 -  
144 -}  
yudao-module-bpm/yudao-module-bpm-biz/src/test/java/cn/iocoder/yudao/module/bpm/service/definition/BpmUserGroupServiceTest.java deleted
1 -package cn.iocoder.yudao.module.bpm.service.definition;  
2 -  
3 -import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;  
4 -import cn.iocoder.yudao.framework.common.pojo.PageResult;  
5 -import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest;  
6 -import cn.iocoder.yudao.framework.test.core.util.AssertUtils;  
7 -import cn.iocoder.yudao.framework.test.core.util.RandomUtils;  
8 -import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.group.BpmUserGroupSaveReqVO;  
9 -import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.group.BpmUserGroupPageReqVO;  
10 -import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmUserGroupDO;  
11 -import cn.iocoder.yudao.module.bpm.dal.mysql.definition.BpmUserGroupMapper;  
12 -import org.junit.jupiter.api.Assertions;  
13 -import org.junit.jupiter.api.Test;  
14 -import org.springframework.context.annotation.Import;  
15 -  
16 -import jakarta.annotation.Resource;  
17 -  
18 -import java.time.LocalDateTime;  
19 -  
20 -import static cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils.buildTime;  
21 -import static cn.iocoder.yudao.framework.common.util.object.ObjectUtils.cloneIgnoreId;  
22 -import static cn.iocoder.yudao.module.bpm.enums.ErrorCodeConstants.USER_GROUP_NOT_EXISTS;  
23 -  
24 -/**  
25 - * {@link BpmUserGroupServiceImpl} 的单元测试类  
26 - *  
27 - * @author 芋道源码  
28 - */  
29 -@Import(BpmUserGroupServiceImpl.class)  
30 -public class BpmUserGroupServiceTest extends BaseDbUnitTest {  
31 -  
32 - @Resource  
33 - private BpmUserGroupServiceImpl userGroupService;  
34 -  
35 - @Resource  
36 - private BpmUserGroupMapper userGroupMapper;  
37 -  
38 - @Test  
39 - public void testCreateUserGroup_success() {  
40 - // 准备参数  
41 - BpmUserGroupSaveReqVO reqVO = RandomUtils.randomPojo(BpmUserGroupSaveReqVO.class);  
42 -  
43 - // 调用  
44 - Long userGroupId = userGroupService.createUserGroup(reqVO);  
45 - // 断言  
46 - Assertions.assertNotNull(userGroupId);  
47 - // 校验记录的属性是否正确  
48 - BpmUserGroupDO userGroup = userGroupMapper.selectById(userGroupId);  
49 - AssertUtils.assertPojoEquals(reqVO, userGroup);  
50 - }  
51 -  
52 - @Test  
53 - public void testUpdateUserGroup_success() {  
54 - // mock 数据  
55 - BpmUserGroupDO dbUserGroup = RandomUtils.randomPojo(BpmUserGroupDO.class);  
56 - userGroupMapper.insert(dbUserGroup);// @Sql: 先插入出一条存在的数据  
57 - // 准备参数  
58 - BpmUserGroupSaveReqVO reqVO = RandomUtils.randomPojo(BpmUserGroupSaveReqVO.class, o -> {  
59 - o.setId(dbUserGroup.getId()); // 设置更新的 ID  
60 - });  
61 -  
62 - // 调用  
63 - userGroupService.updateUserGroup(reqVO);  
64 - // 校验是否更新正确  
65 - BpmUserGroupDO userGroup = userGroupMapper.selectById(reqVO.getId()); // 获取最新的  
66 - AssertUtils.assertPojoEquals(reqVO, userGroup);  
67 - }  
68 -  
69 - @Test  
70 - public void testUpdateUserGroup_notExists() {  
71 - // 准备参数  
72 - BpmUserGroupSaveReqVO reqVO = RandomUtils.randomPojo(BpmUserGroupSaveReqVO.class);  
73 -  
74 - // 调用, 并断言异常  
75 - AssertUtils.assertServiceException(() -> userGroupService.updateUserGroup(reqVO), USER_GROUP_NOT_EXISTS);  
76 - }  
77 -  
78 - @Test  
79 - public void testDeleteUserGroup_success() {  
80 - // mock 数据  
81 - BpmUserGroupDO dbUserGroup = RandomUtils.randomPojo(BpmUserGroupDO.class);  
82 - userGroupMapper.insert(dbUserGroup);// @Sql: 先插入出一条存在的数据  
83 - // 准备参数  
84 - Long id = dbUserGroup.getId();  
85 -  
86 - // 调用  
87 - userGroupService.deleteUserGroup(id);  
88 - // 校验数据不存在了  
89 - Assertions.assertNull(userGroupMapper.selectById(id));  
90 - }  
91 -  
92 - @Test  
93 - public void testDeleteUserGroup_notExists() {  
94 - // 准备参数  
95 - Long id = RandomUtils.randomLongId();  
96 -  
97 - // 调用, 并断言异常  
98 - AssertUtils.assertServiceException(() -> userGroupService.deleteUserGroup(id), USER_GROUP_NOT_EXISTS);  
99 - }  
100 -  
101 - @Test  
102 - public void testGetUserGroupPage() {  
103 - // mock 数据  
104 - BpmUserGroupDO dbUserGroup = RandomUtils.randomPojo(BpmUserGroupDO.class, o -> { // 等会查询到  
105 - o.setName("芋道源码");  
106 - o.setStatus(CommonStatusEnum.ENABLE.getStatus());  
107 - o.setCreateTime(buildTime(2021, 11, 11));  
108 - });  
109 - userGroupMapper.insert(dbUserGroup);  
110 - // 测试 name 不匹配  
111 - userGroupMapper.insert(cloneIgnoreId(dbUserGroup, o -> o.setName("芋道")));  
112 - // 测试 status 不匹配  
113 - userGroupMapper.insert(cloneIgnoreId(dbUserGroup, o -> o.setStatus(CommonStatusEnum.DISABLE.getStatus())));  
114 - // 测试 createTime 不匹配  
115 - userGroupMapper.insert(cloneIgnoreId(dbUserGroup, o -> o.setCreateTime(buildTime(2021, 12, 12))));  
116 - // 准备参数  
117 - BpmUserGroupPageReqVO reqVO = new BpmUserGroupPageReqVO();  
118 - reqVO.setName("源码");  
119 - reqVO.setStatus(CommonStatusEnum.ENABLE.getStatus());  
120 - reqVO.setCreateTime((new LocalDateTime[]{buildTime(2021, 11, 10),buildTime(2021, 11, 12)}));  
121 -  
122 - // 调用  
123 - PageResult<BpmUserGroupDO> pageResult = userGroupService.getUserGroupPage(reqVO);  
124 - // 断言  
125 - Assertions.assertEquals(1, pageResult.getTotal());  
126 - Assertions.assertEquals(1, pageResult.getList().size());  
127 - AssertUtils.assertPojoEquals(dbUserGroup, pageResult.getList().get(0));  
128 - }  
129 -  
130 -}  
yudao-module-bpm/yudao-module-bpm-biz/src/test/resources/application-unit-test.yaml deleted
1 -spring:  
2 - main:  
3 - lazy-initialization: true # 开启懒加载,加快速度  
4 - banner-mode: off # 单元测试,禁用 Banner  
5 -  
6 ---- #################### 数据库相关配置 ####################  
7 -  
8 -spring:  
9 - # 数据源配置项  
10 - datasource:  
11 - name: ruoyi-vue-pro  
12 - url: jdbc:h2:mem:testdb;MODE=MYSQL;DATABASE_TO_UPPER=false;NON_KEYWORDS=value; # MODE 使用 MySQL 模式;DATABASE_TO_UPPER 配置表和字段使用小写  
13 - driver-class-name: org.h2.Driver  
14 - username: sa  
15 - password:  
16 - druid:  
17 - async-init: true # 单元测试,异步初始化 Druid 连接池,提升启动速度  
18 - initial-size: 1 # 单元测试,配置为 1,提升启动速度  
19 - sql:  
20 - init:  
21 - schema-locations: classpath:/sql/create_tables.sql  
22 -  
23 -mybatis-plus:  
24 - lazy-initialization: true # 单元测试,设置 MyBatis Mapper 延迟加载,加速每个单元测试  
25 - type-aliases-package: ${yudao.info.base-package}.module.*.dal.dataobject  
26 -  
27 ---- #################### 定时任务相关配置 ####################  
28 -  
29 ---- #################### 配置中心相关配置 ####################  
30 -  
31 ---- #################### 服务保障相关配置 ####################  
32 -  
33 -# Lock4j 配置项(单元测试,禁用 Lock4j)  
34 -  
35 ---- #################### 监控相关配置 ####################  
36 -  
37 ---- #################### 芋道相关配置 ####################  
38 -  
39 -# 芋道配置项,设置当前项目所有自定义的配置  
40 -yudao:  
41 - info:  
42 - base-package: cn.iocoder.yudao.module  
yudao-module-bpm/yudao-module-bpm-biz/src/test/resources/sql/create_tables.sql deleted
1 -CREATE TABLE IF NOT EXISTS "bpm_user_group" (  
2 - "id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY,  
3 - "name" varchar(63) NOT NULL,  
4 - "description" varchar(255) NOT NULL,  
5 - "status" tinyint NOT NULL,  
6 - "user_ids" varchar(255) NOT NULL,  
7 - "creator" varchar(64) DEFAULT '',  
8 - "create_time" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,  
9 - "updater" varchar(64) DEFAULT '',  
10 - "update_time" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,  
11 - "deleted" bit NOT NULL DEFAULT FALSE,  
12 - PRIMARY KEY ("id")  
13 -) COMMENT '用户组';  
14 -  
15 -CREATE TABLE IF NOT EXISTS "bpm_category" (  
16 - "id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY,  
17 - "name" varchar(63) NOT NULL,  
18 - "code" varchar(63) NOT NULL,  
19 - "description" varchar(255) NOT NULL,  
20 - "status" tinyint NOT NULL,  
21 - "sort" int NOT NULL,  
22 - "creator" varchar(64) DEFAULT '',  
23 - "create_time" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,  
24 - "updater" varchar(64) DEFAULT '',  
25 - "update_time" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,  
26 - "deleted" bit NOT NULL DEFAULT FALSE,  
27 - PRIMARY KEY ("id")  
28 -) COMMENT '分类';  
29 -  
30 -CREATE TABLE IF NOT EXISTS "bpm_form" (  
31 - "id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY,  
32 - "name" varchar(63) NOT NULL,  
33 - "status" tinyint NOT NULL,  
34 - "fields" varchar(255) NOT NULL,  
35 - "conf" varchar(255) NOT NULL,  
36 - "remark" varchar(255),  
37 - "creator" varchar(64) DEFAULT '',  
38 - "create_time" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,  
39 - "updater" varchar(64) DEFAULT '',  
40 - "update_time" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,  
41 - "deleted" bit NOT NULL DEFAULT FALSE,  
42 - PRIMARY KEY ("id")  
43 -) COMMENT '动态表单';