Commit 6d30d56633d22960a227ebdd1a3bf2fbd1c4fe11

Authored by 芋道源码
Committed by Gitee
2 parents 8de74dc4 fceec9fa

!212 工作流支持会签、或签,可自定义任务分配方式

Merge pull request !212 from 芋道源码/feature/bpm-back
Showing 244 changed files with 993 additions and 5313 deletions
.gitignore
@@ -45,3 +45,5 @@ nbdist/ @@ -45,3 +45,5 @@ nbdist/
45 45
46 ### JRebel ### 46 ### JRebel ###
47 rebel.xml 47 rebel.xml
  48 +
  49 +application-my.yaml
README.md
@@ -23,7 +23,7 @@ @@ -23,7 +23,7 @@
23 * 权限认证使用 Spring Security & Token & Redis,支持多终端、多种用户的认证系统。 23 * 权限认证使用 Spring Security & Token & Redis,支持多终端、多种用户的认证系统。
24 * 支持加载动态权限菜单,按钮级别权限控制,本地缓存提升性能。 24 * 支持加载动态权限菜单,按钮级别权限控制,本地缓存提升性能。
25 * 支持 SaaS 多租户系统,可自定义每个租户的权限,提供透明化的多租户底层封装。 25 * 支持 SaaS 多租户系统,可自定义每个租户的权限,提供透明化的多租户底层封装。
26 -* 工作流使用 Activiti + Flowable,支持动态表单、在线设计流程、多种任务分配方式。 26 +* 工作流使用 Flowable,支持动态表单、在线设计流程、会签 / 或签、多种任务分配方式。
27 * 高效率开发,使用代码生成器可以一键生成前后端代码 + 单元测试 + Swagger 接口文档 + Validator 参数校验。 27 * 高效率开发,使用代码生成器可以一键生成前后端代码 + 单元测试 + Swagger 接口文档 + Validator 参数校验。
28 * 集成微信小程序、微信公众号、企业微信、钉钉等三方登陆,集成支付宝、微信等支付与退款。 28 * 集成微信小程序、微信公众号、企业微信、钉钉等三方登陆,集成支付宝、微信等支付与退款。
29 * 集成阿里云、腾讯云、云片等短信渠道,集成 MinIO、阿里云、腾讯云、七牛云等云存储服务。 29 * 集成阿里云、腾讯云、云片等短信渠道,集成 MinIO、阿里云、腾讯云、七牛云等云存储服务。
@@ -167,7 +167,7 @@ ps:核心功能已经实现,正在对接微信小程序中... @@ -167,7 +167,7 @@ ps:核心功能已经实现,正在对接微信小程序中...
167 | [Spring MVC](https://github.com/spring-projects/spring-framework/tree/master/spring-webmvc) | MVC 框架 | 5.3.20 | [文档](http://www.iocoder.cn/SpringMVC/MVC/?yudao) | 167 | [Spring MVC](https://github.com/spring-projects/spring-framework/tree/master/spring-webmvc) | MVC 框架 | 5.3.20 | [文档](http://www.iocoder.cn/SpringMVC/MVC/?yudao) |
168 | [Spring Security](https://github.com/spring-projects/spring-security) | Spring 安全框架 | 5.6.5 | [文档](http://www.iocoder.cn/Spring-Boot/Spring-Security/?yudao) | 168 | [Spring Security](https://github.com/spring-projects/spring-security) | Spring 安全框架 | 5.6.5 | [文档](http://www.iocoder.cn/Spring-Boot/Spring-Security/?yudao) |
169 | [Hibernate Validator](https://github.com/hibernate/hibernate-validator) | 参数校验组件 | 6.2.3 | [文档](http://www.iocoder.cn/Spring-Boot/Validation/?yudao) | 169 | [Hibernate Validator](https://github.com/hibernate/hibernate-validator) | 参数校验组件 | 6.2.3 | [文档](http://www.iocoder.cn/Spring-Boot/Validation/?yudao) |
170 -| [Activiti](https://github.com/Activiti/Activiti) | 工作流引擎 | 7.1.0.M6 | [文档](TODO) | 170 +| [Flowable](https://github.com/flowable/flowable-engine) | 工作流引擎 | 6.7.0 | [文档](https://doc.iocoder.cn/bpm/) |
171 | [Quartz](https://github.com/quartz-scheduler) | 任务调度组件 | 2.3.2 | [文档](http://www.iocoder.cn/Spring-Boot/Job/?yudao) | 171 | [Quartz](https://github.com/quartz-scheduler) | 任务调度组件 | 2.3.2 | [文档](http://www.iocoder.cn/Spring-Boot/Job/?yudao) |
172 | [Knife4j](https://gitee.com/xiaoym/knife4j) | Swagger 增强 UI 实现 | 3.0.3 | [文档](http://www.iocoder.cn/Spring-Boot/Swagger/?yudao) | 172 | [Knife4j](https://gitee.com/xiaoym/knife4j) | Swagger 增强 UI 实现 | 3.0.3 | [文档](http://www.iocoder.cn/Spring-Boot/Swagger/?yudao) |
173 | [Resilience4j](https://github.com/resilience4j/resilience4j) | 服务保障组件 | 1.7.1 | [文档](http://www.iocoder.cn/Spring-Boot/Resilience4j/?yudao) | 173 | [Resilience4j](https://github.com/resilience4j/resilience4j) | 服务保障组件 | 1.7.1 | [文档](http://www.iocoder.cn/Spring-Boot/Resilience4j/?yudao) |
yudao-dependencies/pom.xml
@@ -587,7 +587,6 @@ @@ -587,7 +587,6 @@
587 <artifactId>justauth-spring-boot-starter</artifactId> <!-- 社交登陆(例如说,个人微信、企业微信等等) --> 587 <artifactId>justauth-spring-boot-starter</artifactId> <!-- 社交登陆(例如说,个人微信、企业微信等等) -->
588 <version>${justauth.version}</version> 588 <version>${justauth.version}</version>
589 </dependency> 589 </dependency>
590 -  
591 </dependencies> 590 </dependencies>
592 </dependencyManagement> 591 </dependencyManagement>
593 592
yudao-framework/pom.xml
@@ -38,7 +38,6 @@ @@ -38,7 +38,6 @@
38 <module>yudao-spring-boot-starter-biz-data-permission</module> 38 <module>yudao-spring-boot-starter-biz-data-permission</module>
39 <module>yudao-spring-boot-starter-biz-error-code</module> 39 <module>yudao-spring-boot-starter-biz-error-code</module>
40 40
41 - <module>yudao-spring-boot-starter-activiti</module>  
42 <module>yudao-spring-boot-starter-flowable</module> 41 <module>yudao-spring-boot-starter-flowable</module>
43 </modules> 42 </modules>
44 43
yudao-framework/yudao-spring-boot-starter-activiti/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-framework</artifactId>  
8 - <version>${revision}</version>  
9 - </parent>  
10 - <modelVersion>4.0.0</modelVersion>  
11 - <artifactId>yudao-spring-boot-starter-activiti</artifactId>  
12 - <packaging>jar</packaging>  
13 -  
14 - <name>${project.artifactId}</name>  
15 - <description>Activiti 拓展</description>  
16 - <url>https://github.com/YunaiV/ruoyi-vue-pro</url>  
17 -  
18 - <dependencies>  
19 - <dependency>  
20 - <groupId>cn.iocoder.boot</groupId>  
21 - <artifactId>yudao-common</artifactId>  
22 - </dependency>  
23 -  
24 - <!-- Web 相关 -->  
25 - <dependency>  
26 - <groupId>cn.iocoder.boot</groupId>  
27 - <artifactId>yudao-spring-boot-starter-security</artifactId>  
28 - </dependency>  
29 -  
30 - <!-- DB 相关 -->  
31 - <dependency>  
32 - <groupId>cn.iocoder.boot</groupId>  
33 - <artifactId>yudao-spring-boot-starter-mybatis</artifactId>  
34 - </dependency>  
35 -  
36 - <!-- 工作流相关 -->  
37 - <dependency>  
38 - <groupId>org.activiti</groupId>  
39 - <artifactId>activiti-spring-boot-starter</artifactId>  
40 - </dependency>  
41 - <dependency>  
42 - <groupId>org.activiti</groupId>  
43 - <artifactId>activiti-image-generator</artifactId>  
44 - </dependency>  
45 -  
46 - </dependencies>  
47 -  
48 -</project>  
yudao-framework/yudao-spring-boot-starter-activiti/src/main/java/cn/iocoder/yudao/framework/activiti/config/YudaoActivitiConfiguration.java deleted
1 -package cn.iocoder.yudao.framework.activiti.config;  
2 -  
3 -import cn.iocoder.yudao.framework.activiti.core.web.ActivitiWebFilter;  
4 -import cn.iocoder.yudao.framework.common.enums.WebFilterOrderEnum;  
5 -import org.activiti.image.ProcessDiagramGenerator;  
6 -import org.activiti.image.impl.DefaultProcessDiagramGenerator;  
7 -import org.activiti.spring.SpringProcessEngineConfiguration;  
8 -import org.activiti.spring.boot.ProcessEngineConfigurationConfigurer;  
9 -import org.apache.ibatis.session.SqlSessionFactory;  
10 -import org.apache.ibatis.transaction.TransactionFactory;  
11 -import org.mybatis.spring.transaction.SpringManagedTransactionFactory;  
12 -import org.springframework.boot.web.servlet.FilterRegistrationBean;  
13 -import org.springframework.context.annotation.Bean;  
14 -import org.springframework.context.annotation.Configuration;  
15 -import org.springframework.transaction.PlatformTransactionManager;  
16 -  
17 -@Configuration  
18 -public class YudaoActivitiConfiguration {  
19 -  
20 - /**  
21 - * Activiti 流程图的生成器。目前管理后台的流程图 svg,通过它绘制生成。  
22 - */  
23 - @Bean  
24 - public ProcessDiagramGenerator processDiagramGenerator() {  
25 - return new DefaultProcessDiagramGenerator();  
26 - }  
27 -  
28 - @Bean  
29 - public FilterRegistrationBean<ActivitiWebFilter> activitiWebFilter() {  
30 - FilterRegistrationBean<ActivitiWebFilter> registrationBean = new FilterRegistrationBean<>();  
31 - registrationBean.setFilter(new ActivitiWebFilter());  
32 - registrationBean.setOrder(WebFilterOrderEnum.ACTIVITI_FILTER);  
33 - return registrationBean;  
34 - }  
35 -  
36 - /**  
37 - * ProcessEngineConfigurationConfigurer 实现类,设置事务管理器,保证 ACT_ 表和自己的表的事务一致性  
38 - */  
39 - @Bean  
40 - public ProcessEngineConfigurationConfigurer processEngineConfigurationConfigurer(  
41 - PlatformTransactionManager platformTransactionManager) {  
42 - return processEngineConfiguration -> processEngineConfiguration.setTransactionManager(platformTransactionManager);  
43 - }  
44 -  
45 -}  
yudao-framework/yudao-spring-boot-starter-activiti/src/main/java/cn/iocoder/yudao/framework/activiti/core/util/ActivitiUtils.java deleted
1 -package cn.iocoder.yudao.framework.activiti.core.util;  
2 -  
3 -import cn.hutool.core.util.ArrayUtil;  
4 -import cn.hutool.core.util.ObjectUtil;  
5 -import cn.hutool.core.util.ReflectUtil;  
6 -import cn.hutool.core.util.StrUtil;  
7 -import cn.iocoder.yudao.framework.common.util.number.NumberUtils;  
8 -import com.alibaba.ttl.TransmittableThreadLocal;  
9 -import org.activiti.bpmn.converter.BpmnXMLConverter;  
10 -import org.activiti.bpmn.model.BpmnModel;  
11 -import org.activiti.bpmn.model.FlowElement;  
12 -import org.activiti.bpmn.model.Process;  
13 -import org.activiti.engine.impl.identity.Authentication;  
14 -import org.activiti.engine.impl.util.io.BytesStreamSource;  
15 -  
16 -import java.util.ArrayList;  
17 -import java.util.Arrays;  
18 -import java.util.List;  
19 -import java.util.Objects;  
20 -import java.util.function.Consumer;  
21 -  
22 -/**  
23 - * Activiti 工具类  
24 - *  
25 - * @author 芋道源码  
26 - */  
27 -public class ActivitiUtils {  
28 -  
29 - static {  
30 - setAuthenticationThreadLocal();  
31 - }  
32 -  
33 - // ========== Authentication 相关 ==========  
34 -  
35 - /**  
36 - * 反射修改 Authentication 的 authenticatedUserIdThreadLocal 静态变量,使用 TTL 线程变量  
37 - * 目的:保证 @Async 等异步执行时,变量丢失的问题  
38 - */  
39 - private static void setAuthenticationThreadLocal() {  
40 - ReflectUtil.setFieldValue(Authentication.class, "authenticatedUserIdThreadLocal",  
41 - new TransmittableThreadLocal<String>());  
42 - }  
43 -  
44 - public static void setAuthenticatedUserId(Long userId) {  
45 - Authentication.setAuthenticatedUserId(String.valueOf(userId));  
46 - }  
47 -  
48 - public static void clearAuthenticatedUserId() {  
49 - Authentication.setAuthenticatedUserId(null);  
50 - }  
51 -  
52 - public static boolean equals(String userIdStr, Long userId) {  
53 - return Objects.equals(userId, NumberUtils.parseLong(userIdStr));  
54 - }  
55 -  
56 - // ========== BPMN XML 相关 ==========  
57 -  
58 - /**  
59 - * 构建对应的 BPMN Model  
60 - *  
61 - * @param bpmnBytes 原始的 BPMN XML 字节数组  
62 - * @return BPMN Model  
63 - */  
64 - public static BpmnModel buildBpmnModel(byte[] bpmnBytes) {  
65 - // 转换成 BpmnModel 对象  
66 - BpmnXMLConverter converter = new BpmnXMLConverter();  
67 - return converter.convertToBpmnModel(new BytesStreamSource(bpmnBytes), true, true);  
68 - }  
69 -  
70 - /**  
71 - * 获得 BPMN 流程中,指定的元素们  
72 - *  
73 - * @param model  
74 - * @param clazz 指定元素。例如说,{@link org.activiti.bpmn.model.UserTask}、{@link org.activiti.bpmn.model.Gateway} 等等  
75 - * @return 元素们  
76 - */  
77 - public static <T extends FlowElement> List<T> getBpmnModelElements(BpmnModel model, Class<T> clazz) {  
78 - List<T> result = new ArrayList<>();  
79 - model.getProcesses().forEach(process -> {  
80 - process.getFlowElements().forEach(flowElement -> {  
81 - if (flowElement.getClass().isAssignableFrom(clazz)) {  
82 - result.add((T) flowElement);  
83 - }  
84 - });  
85 - });  
86 - return result;  
87 - }  
88 -  
89 - public static String getBpmnXml(BpmnModel model) {  
90 - if (model == null) {  
91 - return null;  
92 - }  
93 - return StrUtil.utf8Str(getBpmnBytes(model));  
94 - }  
95 -  
96 - public static byte[] getBpmnBytes(BpmnModel model) {  
97 - if (model == null) {  
98 - return new byte[0];  
99 - }  
100 - BpmnXMLConverter converter = new BpmnXMLConverter();  
101 - return converter.convertToXML(model);  
102 - }  
103 -  
104 - public static boolean equals(BpmnModel oldModel, BpmnModel newModel) {  
105 - // 由于 BpmnModel 未提供 equals 方法,所以只能转成字节数组,进行比较  
106 - return Arrays.equals(getBpmnBytes(oldModel), getBpmnBytes(newModel));  
107 - }  
108 -  
109 -}  
yudao-framework/yudao-spring-boot-starter-activiti/src/main/java/cn/iocoder/yudao/framework/activiti/core/web/ActivitiWebFilter.java deleted
1 -package cn.iocoder.yudao.framework.activiti.core.web;  
2 -  
3 -import cn.iocoder.yudao.framework.activiti.core.util.ActivitiUtils;  
4 -import cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils;  
5 -import org.springframework.web.filter.OncePerRequestFilter;  
6 -  
7 -import javax.servlet.FilterChain;  
8 -import javax.servlet.ServletException;  
9 -import javax.servlet.http.HttpServletRequest;  
10 -import javax.servlet.http.HttpServletResponse;  
11 -import java.io.IOException;  
12 -  
13 -/**  
14 - * Activiti Web 过滤器,将 userId 设置到 {@link org.activiti.engine.impl.identity.Authentication} 中  
15 - *  
16 - * @author 芋道源码  
17 - */  
18 -public class ActivitiWebFilter extends OncePerRequestFilter {  
19 -  
20 - @Override  
21 - protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain)  
22 - throws ServletException, IOException {  
23 - try {  
24 - // 设置工作流的用户  
25 - Long userId = SecurityFrameworkUtils.getLoginUserId();  
26 - if (userId != null) {  
27 - ActivitiUtils.setAuthenticatedUserId(userId);  
28 - }  
29 - // 过滤  
30 - chain.doFilter(request, response);  
31 - } finally {  
32 - // 清理  
33 - ActivitiUtils.clearAuthenticatedUserId();  
34 - }  
35 - }  
36 -  
37 -}  
yudao-framework/yudao-spring-boot-starter-activiti/src/main/java/cn/iocoder/yudao/framework/activiti/package-info.java deleted
1 -package cn.iocoder.yudao.framework.activiti;  
yudao-framework/yudao-spring-boot-starter-activiti/src/main/resources/META-INF/spring.factories deleted
1 -org.springframework.boot.autoconfigure.EnableAutoConfiguration=\  
2 - cn.iocoder.yudao.framework.activiti.config.YudaoActivitiConfiguration  
yudao-framework/yudao-spring-boot-starter-flowable/src/main/java/cn/iocoder/yudao/framework/flowable/core/util/FlowableUtils.java
@@ -9,8 +9,15 @@ import java.util.ArrayList; @@ -9,8 +9,15 @@ import java.util.ArrayList;
9 import java.util.Arrays; 9 import java.util.Arrays;
10 import java.util.List; 10 import java.util.List;
11 11
  12 +/**
  13 + * Flowable 相关的工具方法
  14 + *
  15 + * @author 芋道源码
  16 + */
12 public class FlowableUtils { 17 public class FlowableUtils {
13 18
  19 + // ========== User 相关的工具方法 ==========
  20 +
14 public static void setAuthenticatedUserId(Long userId) { 21 public static void setAuthenticatedUserId(Long userId) {
15 Authentication.setAuthenticatedUserId(String.valueOf(userId)); 22 Authentication.setAuthenticatedUserId(String.valueOf(userId));
16 } 23 }
@@ -19,6 +26,8 @@ public class FlowableUtils { @@ -19,6 +26,8 @@ public class FlowableUtils {
19 Authentication.setAuthenticatedUserId(null); 26 Authentication.setAuthenticatedUserId(null);
20 } 27 }
21 28
  29 + // ========== BPMN 相关的工具方法 ==========
  30 +
22 /** 31 /**
23 * 获得 BPMN 流程中,指定的元素们 32 * 获得 BPMN 流程中,指定的元素们
24 * 33 *
@@ -59,4 +68,15 @@ public class FlowableUtils { @@ -59,4 +68,15 @@ public class FlowableUtils {
59 BpmnXMLConverter converter = new BpmnXMLConverter(); 68 BpmnXMLConverter converter = new BpmnXMLConverter();
60 return converter.convertToXML(model); 69 return converter.convertToXML(model);
61 } 70 }
  71 +
  72 + // ========== Execution 相关的工具方法 ==========
  73 +
  74 + public static String formatCollectionVariable(String activityId) {
  75 + return activityId + "_assignees";
  76 + }
  77 +
  78 + public static String formatCollectionElementVariable(String activityId) {
  79 + return activityId + "_assignee";
  80 + }
  81 +
62 } 82 }
yudao-module-bpm/pom.xml
@@ -10,9 +10,7 @@ @@ -10,9 +10,7 @@
10 <modelVersion>4.0.0</modelVersion> 10 <modelVersion>4.0.0</modelVersion>
11 <modules> 11 <modules>
12 <module>yudao-module-bpm-api</module> 12 <module>yudao-module-bpm-api</module>
13 - <module>yudao-module-bpm-base</module>  
14 - <module>yudao-module-bpm-biz-flowable</module>  
15 - <module>yudao-module-bpm-biz-activiti</module> 13 + <module>yudao-module-bpm-biz</module>
16 </modules> 14 </modules>
17 <artifactId>yudao-module-bpm</artifactId> 15 <artifactId>yudao-module-bpm</artifactId>
18 <packaging>pom</packaging> 16 <packaging>pom</packaging>
@@ -23,10 +21,7 @@ @@ -23,10 +21,7 @@
23 例如说:流程定义、表单配置、审核中心(我的申请、我的待办、我的已办)等等 21 例如说:流程定义、表单配置、审核中心(我的申请、我的待办、我的已办)等等
24 bpm 解释:https://baike.baidu.com/item/BPM/1933 22 bpm 解释:https://baike.baidu.com/item/BPM/1933
25 23
26 - 目前提供两套实现方案:  
27 - 1. 基于 Activiti 7 实现的 yudao-module-bpm-biz-activiti  
28 - 2. 基于 Flowable 6 实现的 yudao-module-bpm-biz-flowable  
29 - 两套实现会存在共享的逻辑,所以会继承 yudao-module-bpm-base 24 + 工作流基于 Flowable 6 实现,分成流程定义、流程表单、流程实例、流程任务等功能模块。
30 </description> 25 </description>
31 26
32 </project> 27 </project>
yudao-module-bpm/yudao-module-bpm-base/src/main/java/cn/iocoder/yudao/module/bpm/enums/definition/BpmModelFormTypeEnum.java renamed to yudao-module-bpm/yudao-module-bpm-api/src/main/java/cn/iocoder/yudao/module/bpm/enums/definition/BpmModelFormTypeEnum.java
yudao-module-bpm/yudao-module-bpm-base/src/main/java/cn/iocoder/yudao/module/bpm/enums/definition/BpmTaskAssignRuleTypeEnum.java renamed to yudao-module-bpm/yudao-module-bpm-api/src/main/java/cn/iocoder/yudao/module/bpm/enums/definition/BpmTaskAssignRuleTypeEnum.java
@@ -13,15 +13,11 @@ import lombok.Getter; @@ -13,15 +13,11 @@ import lombok.Getter;
13 public enum BpmTaskAssignRuleTypeEnum { 13 public enum BpmTaskAssignRuleTypeEnum {
14 14
15 ROLE(10, "角色"), 15 ROLE(10, "角色"),
16 -  
17 DEPT_MEMBER(20, "部门的成员"), // 包括负责人 16 DEPT_MEMBER(20, "部门的成员"), // 包括负责人
18 DEPT_LEADER(21, "部门的负责人"), 17 DEPT_LEADER(21, "部门的负责人"),
19 POST(22, "岗位"), 18 POST(22, "岗位"),
20 -  
21 USER(30, "用户"), 19 USER(30, "用户"),
22 -  
23 USER_GROUP(40, "用户组"), 20 USER_GROUP(40, "用户组"),
24 -  
25 SCRIPT(50, "自定义脚本"), // 例如说,发起人所在部门的领导、发起人所在部门的领导的领导 21 SCRIPT(50, "自定义脚本"), // 例如说,发起人所在部门的领导、发起人所在部门的领导的领导
26 ; 22 ;
27 23
yudao-module-bpm/yudao-module-bpm-base/src/main/java/cn/iocoder/yudao/module/bpm/enums/definition/BpmTaskRuleScriptEnum.java renamed to yudao-module-bpm/yudao-module-bpm-api/src/main/java/cn/iocoder/yudao/module/bpm/enums/definition/BpmTaskRuleScriptEnum.java
yudao-module-bpm/yudao-module-bpm-base/src/main/java/cn/iocoder/yudao/module/bpm/enums/message/BpmMessageEnum.java renamed to yudao-module-bpm/yudao-module-bpm-api/src/main/java/cn/iocoder/yudao/module/bpm/enums/message/BpmMessageEnum.java
yudao-module-bpm/yudao-module-bpm-base/src/main/java/cn/iocoder/yudao/module/bpm/enums/task/BpmProcessInstanceDeleteReasonEnum.java renamed to yudao-module-bpm/yudao-module-bpm-api/src/main/java/cn/iocoder/yudao/module/bpm/enums/task/BpmProcessInstanceDeleteReasonEnum.java
@@ -14,7 +14,12 @@ import lombok.Getter; @@ -14,7 +14,12 @@ import lombok.Getter;
14 public enum BpmProcessInstanceDeleteReasonEnum { 14 public enum BpmProcessInstanceDeleteReasonEnum {
15 15
16 REJECT_TASK("不通过任务,原因:{}"), // 修改文案时,需要注意 isRejectReason 方法 16 REJECT_TASK("不通过任务,原因:{}"), // 修改文案时,需要注意 isRejectReason 方法
17 - CANCEL_TASK("主动取消任务,原因:{}"); 17 + CANCEL_TASK("主动取消任务,原因:{}"),
  18 +
  19 + // ========== 流程任务的独有原因 ==========
  20 + MULTI_TASK_END("系统自动取消,原因:多任务审批已经满足条件,无需审批该任务"), // 多实例满足 condition 而结束时,其它任务实例任务会被取消,对应的删除原因是 MI_END
  21 +
  22 + ;
18 23
19 private final String reason; 24 private final String reason;
20 25
@@ -34,4 +39,20 @@ public enum BpmProcessInstanceDeleteReasonEnum { @@ -34,4 +39,20 @@ public enum BpmProcessInstanceDeleteReasonEnum {
34 return StrUtil.startWith(reason, "不通过任务,原因:"); 39 return StrUtil.startWith(reason, "不通过任务,原因:");
35 } 40 }
36 41
  42 + /**
  43 + * 将 Flowable 的删除原因,翻译成对应的中文原因
  44 + *
  45 + * @param reason 原始原因
  46 + * @return 原因
  47 + */
  48 + public static String translateReason(String reason) {
  49 + if (StrUtil.isEmpty(reason)) {
  50 + return reason;
  51 + }
  52 + switch (reason) {
  53 + case "MI_END": return MULTI_TASK_END.getReason();
  54 + default: return reason;
  55 + }
  56 + }
  57 +
37 } 58 }
yudao-module-bpm/yudao-module-bpm-base/src/main/java/cn/iocoder/yudao/module/bpm/enums/task/BpmProcessInstanceResultEnum.java renamed to yudao-module-bpm/yudao-module-bpm-api/src/main/java/cn/iocoder/yudao/module/bpm/enums/task/BpmProcessInstanceResultEnum.java
1 package cn.iocoder.yudao.module.bpm.enums.task; 1 package cn.iocoder.yudao.module.bpm.enums.task;
2 2
  3 +import cn.iocoder.yudao.framework.common.util.object.ObjectUtils;
3 import lombok.AllArgsConstructor; 4 import lombok.AllArgsConstructor;
4 import lombok.Getter; 5 import lombok.Getter;
5 6
@@ -15,10 +16,16 @@ public enum BpmProcessInstanceResultEnum { @@ -15,10 +16,16 @@ public enum BpmProcessInstanceResultEnum {
15 PROCESS(1, "处理中"), 16 PROCESS(1, "处理中"),
16 APPROVE(2, "通过"), 17 APPROVE(2, "通过"),
17 REJECT(3, "不通过"), 18 REJECT(3, "不通过"),
18 - CANCEL(4, "已取消"); 19 + CANCEL(4, "已取消"),
  20 +
  21 + // ========== 流程任务独有的状态 ==========
  22 +
  23 + BACK(5, "退回/驳回");
19 24
20 /** 25 /**
21 * 结果 26 * 结果
  27 + *
  28 + * 如果新增时,注意 {@link #isEndResult(Integer)} 是否需要变更
22 */ 29 */
23 private final Integer result; 30 private final Integer result;
24 /** 31 /**
@@ -26,4 +33,16 @@ public enum BpmProcessInstanceResultEnum { @@ -26,4 +33,16 @@ public enum BpmProcessInstanceResultEnum {
26 */ 33 */
27 private final String desc; 34 private final String desc;
28 35
  36 + /**
  37 + * 判断该结果是否已经处于 End 最终结果
  38 + *
  39 + * 主要用于一些结果更新的逻辑,如果已经是最终结果,就不再进行更新
  40 + *
  41 + * @param result 结果
  42 + * @return 是否
  43 + */
  44 + public static boolean isEndResult(Integer result) {
  45 + return ObjectUtils.equalsAny(result, APPROVE.getResult(), REJECT.getResult(), CANCEL.getResult(), BACK.getResult());
  46 + }
  47 +
29 } 48 }
yudao-module-bpm/yudao-module-bpm-base/src/main/java/cn/iocoder/yudao/module/bpm/enums/task/BpmProcessInstanceStatusEnum.java renamed to yudao-module-bpm/yudao-module-bpm-api/src/main/java/cn/iocoder/yudao/module/bpm/enums/task/BpmProcessInstanceStatusEnum.java
yudao-module-bpm/yudao-module-bpm-base/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/package-info.java deleted
1 -package cn.iocoder.yudao.module.bpm.controller.admin.task;  
yudao-module-bpm/yudao-module-bpm-base/src/main/java/cn/iocoder/yudao/module/bpm/package-info.java deleted
1 -/**  
2 - * bpm 包下,业务流程管理(Business Process Management),我们放工作流的功能。  
3 - * 例如说:流程定义、表单配置、审核中心(我的申请、我的待办、我的已办)等等  
4 - *  
5 - * bpm 解释:https://baike.baidu.com/item/BPM/1933  
6 - *  
7 - * 1. Controller URL:以 /bpm/ 开头,避免和其它 Module 冲突  
8 - * 2. DataObject 表名:以 bpm_ 开头,方便在数据库中区分  
9 - */  
10 -package cn.iocoder.yudao.module.bpm;  
yudao-module-bpm/yudao-module-bpm-biz-activiti/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-activiti</artifactId>  
12 - <packaging>jar</packaging>  
13 -  
14 - <name>${project.artifactId}</name>  
15 - <description>  
16 - bpm-activiti 模块,基于 Activiti 7 实现工作流  
17 - </description>  
18 -  
19 - <dependencies>  
20 - <dependency>  
21 - <groupId>cn.iocoder.boot</groupId>  
22 - <artifactId>yudao-module-bpm-base</artifactId>  
23 - <version>${revision}</version>  
24 - </dependency>  
25 -  
26 - <!-- 工作流相关 -->  
27 - <dependency>  
28 - <groupId>cn.iocoder.boot</groupId>  
29 - <artifactId>yudao-spring-boot-starter-activiti</artifactId>  
30 - </dependency>  
31 -  
32 - <!-- Test 测试相关 -->  
33 - <dependency>  
34 - <groupId>cn.iocoder.boot</groupId>  
35 - <artifactId>yudao-spring-boot-starter-test</artifactId>  
36 - <scope>test</scope>  
37 - </dependency>  
38 - </dependencies>  
39 -</project>  
yudao-module-bpm/yudao-module-bpm-biz-activiti/src/main/java/cn/iocoder/yudao/module/bpm/api/task/BpmProcessInstanceApiImpl.java deleted
1 -package cn.iocoder.yudao.module.bpm.api.task;  
2 -  
3 -import cn.iocoder.yudao.module.bpm.service.task.BpmProcessInstanceService;  
4 -import cn.iocoder.yudao.module.bpm.api.task.dto.BpmProcessInstanceCreateReqDTO;  
5 -import org.springframework.stereotype.Service;  
6 -import org.springframework.validation.annotation.Validated;  
7 -  
8 -import javax.annotation.Resource;  
9 -  
10 -/**  
11 - * Activiti 流程实例 Api 实现类  
12 - *  
13 - * @author 芋道源码  
14 - */  
15 -@Service  
16 -@Validated  
17 -public class BpmProcessInstanceApiImpl implements BpmProcessInstanceApi {  
18 -  
19 - @Resource  
20 - private BpmProcessInstanceService processInstanceService;  
21 -  
22 - @Override  
23 - public String createProcessInstance(Long userId, BpmProcessInstanceCreateReqDTO reqDTO) {  
24 - return processInstanceService.createProcessInstance(userId, reqDTO);  
25 - }  
26 -  
27 -}  
yudao-module-bpm/yudao-module-bpm-biz-activiti/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/BpmModelController.java deleted
1 -package cn.iocoder.yudao.module.bpm.controller.admin.definition;  
2 -  
3 -import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.model.*;  
4 -import cn.iocoder.yudao.module.bpm.convert.definition.BpmModelConvert;  
5 -import cn.iocoder.yudao.module.bpm.service.definition.BpmModelService;  
6 -import cn.iocoder.yudao.framework.common.pojo.CommonResult;  
7 -import cn.iocoder.yudao.framework.common.pojo.PageResult;  
8 -import cn.iocoder.yudao.framework.common.util.io.IoUtils;  
9 -import io.swagger.annotations.Api;  
10 -import io.swagger.annotations.ApiImplicitParam;  
11 -import io.swagger.annotations.ApiOperation;  
12 -import org.springframework.security.access.prepost.PreAuthorize;  
13 -import org.springframework.validation.annotation.Validated;  
14 -import org.springframework.web.bind.annotation.*;  
15 -  
16 -import javax.annotation.Resource;  
17 -import javax.validation.Valid;  
18 -import java.io.IOException;  
19 -  
20 -import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;  
21 -  
22 -@Api(tags = "管理后台 - 流程模型")  
23 -@RestController  
24 -@RequestMapping("/bpm/model")  
25 -@Validated  
26 -public class BpmModelController {  
27 -  
28 - @Resource  
29 - private BpmModelService bpmModelService;  
30 -  
31 - @GetMapping("/page")  
32 - @ApiOperation(value = "获得模型分页")  
33 - public CommonResult<PageResult<BpmModelPageItemRespVO>> getModelPage(BpmModelPageReqVO pageVO) {  
34 - return success(bpmModelService.getModelPage(pageVO));  
35 - }  
36 -  
37 - @GetMapping("/get")  
38 - @ApiOperation("获得模型")  
39 - @ApiImplicitParam(name = "id", value = "编号", required = true, example = "1024", dataTypeClass = String.class)  
40 - @PreAuthorize("@ss.hasPermission('bpm:model:query')")  
41 - public CommonResult<BpmModelRespVO> getModel(@RequestParam("id") String id) {  
42 - BpmModelRespVO model = bpmModelService.getModel(id);  
43 - return success(model);  
44 - }  
45 -  
46 - @PostMapping("/create")  
47 - @ApiOperation(value = "新建模型")  
48 - @PreAuthorize("@ss.hasPermission('bpm:model:create')")  
49 - public CommonResult<String> createModel(@Valid @RequestBody BpmModelCreateReqVO createRetVO) {  
50 - return success(bpmModelService.createModel(createRetVO, null));  
51 - }  
52 -  
53 - @PostMapping("/import")  
54 - @ApiOperation(value = "导入模型")  
55 - @PreAuthorize("@ss.hasPermission('bpm:model:import')")  
56 - public CommonResult<String> importModel(@Valid BpmModeImportReqVO importReqVO) throws IOException {  
57 - BpmModelCreateReqVO createReqVO = BpmModelConvert.INSTANCE.convert(importReqVO);  
58 - // 读取文件  
59 - String bpmnXml = IoUtils.readUtf8(importReqVO.getBpmnFile().getInputStream(), false);  
60 - return success(bpmModelService.createModel(createReqVO, bpmnXml));  
61 - }  
62 -  
63 - @PutMapping("/update")  
64 - @ApiOperation(value = "修改模型")  
65 - @PreAuthorize("@ss.hasPermission('bpm:model:update')")  
66 - public CommonResult<Boolean> updateModel(@Valid @RequestBody BpmModelUpdateReqVO modelVO) {  
67 - bpmModelService.updateModel(modelVO);  
68 - return success(true);  
69 - }  
70 -  
71 - @DeleteMapping("/delete")  
72 - @ApiOperation("删除模型")  
73 - @ApiImplicitParam(name = "id", value = "编号", required = true, example = "1024", dataTypeClass = String.class)  
74 - @PreAuthorize("@ss.hasPermission('bpm:model:delete')")  
75 - public CommonResult<Boolean> deleteModel(@RequestParam("id") String id) {  
76 - bpmModelService.deleteModel(id);  
77 - return success(true);  
78 - }  
79 -  
80 - @PostMapping("/deploy")  
81 - @ApiOperation(value = "部署模型")  
82 - @ApiImplicitParam(name = "id", value = "编号", required = true, example = "1024", dataTypeClass = String.class)  
83 - @PreAuthorize("@ss.hasPermission('bpm:model:deploy')")  
84 - public CommonResult<Boolean> deployModel(@RequestParam("id") String id) {  
85 - bpmModelService.deployModel(id);  
86 - return success(true);  
87 - }  
88 -  
89 - @PutMapping("/update-state")  
90 - @ApiOperation(value = "修改模型的状态", notes = "实际更新的部署的流程定义的状态")  
91 - @PreAuthorize("@ss.hasPermission('bpm:model:update')")  
92 - public CommonResult<Boolean> updateModelState(@Valid @RequestBody BpmModelUpdateStateReqVO reqVO) {  
93 - bpmModelService.updateModelState(reqVO.getId(), reqVO.getState());  
94 - return success(true);  
95 - }  
96 -}  
yudao-module-bpm/yudao-module-bpm-biz-activiti/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/BpmProcessDefinitionController.http deleted
1 -### 请求 /bpm/process-definition/list 接口 => 成功  
2 -GET {{baseUrl}}/bpm/process-definition/list?suspensionState=1  
3 -tenant-id: 1  
4 -Authorization: Bearer {{token}}  
yudao-module-bpm/yudao-module-bpm-biz-activiti/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/BpmProcessDefinitionController.java deleted
1 -package cn.iocoder.yudao.module.bpm.controller.admin.definition;  
2 -  
3 -import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.process.BpmProcessDefinitionListReqVO;  
4 -import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.process.BpmProcessDefinitionPageItemRespVO;  
5 -import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.process.BpmProcessDefinitionPageReqVO;  
6 -import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.process.BpmProcessDefinitionRespVO;  
7 -import cn.iocoder.yudao.module.bpm.service.definition.BpmProcessDefinitionService;  
8 -import cn.iocoder.yudao.framework.common.pojo.CommonResult;  
9 -import cn.iocoder.yudao.framework.common.pojo.PageResult;  
10 -import io.swagger.annotations.Api;  
11 -import io.swagger.annotations.ApiImplicitParam;  
12 -import io.swagger.annotations.ApiOperation;  
13 -import org.springframework.security.access.prepost.PreAuthorize;  
14 -import org.springframework.validation.annotation.Validated;  
15 -import org.springframework.web.bind.annotation.GetMapping;  
16 -import org.springframework.web.bind.annotation.RequestMapping;  
17 -import org.springframework.web.bind.annotation.RequestParam;  
18 -import org.springframework.web.bind.annotation.RestController;  
19 -  
20 -import javax.annotation.Resource;  
21 -  
22 -import java.util.List;  
23 -  
24 -import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;  
25 -  
26 -@Api(tags = "管理后台 - 流程定义")  
27 -@RestController  
28 -@RequestMapping("/bpm/process-definition")  
29 -@Validated  
30 -public class BpmProcessDefinitionController {  
31 -  
32 - @Resource  
33 - private BpmProcessDefinitionService bpmDefinitionService;  
34 -  
35 - @GetMapping ("/page")  
36 - @ApiOperation(value = "获得流程定义分页")  
37 - @PreAuthorize("@ss.hasPermission('bpm:process-definition:query')")  
38 - public CommonResult<PageResult<BpmProcessDefinitionPageItemRespVO>> getProcessDefinitionPage(  
39 - BpmProcessDefinitionPageReqVO pageReqVO) {  
40 - return success(bpmDefinitionService.getProcessDefinitionPage(pageReqVO));  
41 - }  
42 -  
43 - @GetMapping ("/list")  
44 - @ApiOperation(value = "获得流程定义列表")  
45 - @PreAuthorize("@ss.hasPermission('bpm:process-definition:query')")  
46 - public CommonResult<List<BpmProcessDefinitionRespVO>> getProcessDefinitionList(  
47 - BpmProcessDefinitionListReqVO listReqVO) {  
48 - return success(bpmDefinitionService.getProcessDefinitionList(listReqVO));  
49 - }  
50 -  
51 - @GetMapping ("/get-bpmn-xml")  
52 - @ApiOperation(value = "获得流程定义的 BPMN XML")  
53 - @ApiImplicitParam(name = "id", value = "编号", required = true, example = "1024", dataTypeClass = String.class)  
54 - @PreAuthorize("@ss.hasPermission('bpm:process-definition:query')")  
55 - public CommonResult<String> getProcessDefinitionBpmnXML(@RequestParam("id") String id) {  
56 - String bpmnXML = bpmDefinitionService.getProcessDefinitionBpmnXML(id);  
57 - return success(bpmnXML);  
58 - }  
59 -  
60 -}  
yudao-module-bpm/yudao-module-bpm-biz-activiti/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/BpmTaskAssignRuleController.http deleted
1 -### 请求 /bpm/task-assign-rule/list 接口 => 成功  
2 -GET {{baseUrl}}/bpm/task-assign-rule/list?processDefinitionId=leave:9:59689ba0-7284-11ec-965c-a2380e71991a  
3 -tenant-id: 1  
4 -Authorization: Bearer {{token}}  
yudao-module-bpm/yudao-module-bpm-biz-activiti/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/BpmActivityController.java deleted
1 -package cn.iocoder.yudao.module.bpm.controller.admin.task;  
2 -  
3 -import cn.hutool.core.util.StrUtil;  
4 -import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.activity.BpmActivityRespVO;  
5 -import cn.iocoder.yudao.module.bpm.service.task.BpmActivityService;  
6 -import cn.iocoder.yudao.framework.common.pojo.CommonResult;  
7 -import cn.iocoder.yudao.framework.common.util.servlet.ServletUtils;  
8 -import io.swagger.annotations.Api;  
9 -import io.swagger.annotations.ApiImplicitParam;  
10 -import io.swagger.annotations.ApiOperation;  
11 -import org.springframework.security.access.prepost.PreAuthorize;  
12 -import org.springframework.validation.annotation.Validated;  
13 -import org.springframework.web.bind.annotation.GetMapping;  
14 -import org.springframework.web.bind.annotation.RequestMapping;  
15 -import org.springframework.web.bind.annotation.RequestParam;  
16 -import org.springframework.web.bind.annotation.RestController;  
17 -  
18 -import javax.annotation.Resource;  
19 -import javax.servlet.http.HttpServletResponse;  
20 -import java.io.IOException;  
21 -import java.util.List;  
22 -  
23 -import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;  
24 -  
25 -@Api(tags = "管理后台 - 流程活动实例")  
26 -@RestController  
27 -@RequestMapping("/bpm/activity")  
28 -@Validated  
29 -public class BpmActivityController {  
30 -  
31 - @Resource  
32 - private BpmActivityService activityService;  
33 -  
34 - @GetMapping("/list")  
35 - @ApiOperation(value = "生成指定流程实例的高亮流程图",  
36 - notes = "只高亮进行中的任务。不过要注意,该接口暂时没用,通过前端的 ProcessViewer.vue 界面的 highlightDiagram 方法生成")  
37 - @ApiImplicitParam(name = "processInstanceId", value = "流程实例的编号", required = true, dataTypeClass = String.class)  
38 - @PreAuthorize("@ss.hasPermission('bpm:task:query')")  
39 - public CommonResult<List<BpmActivityRespVO>> getActivityList(  
40 - @RequestParam("processInstanceId") String processInstanceId) {  
41 - return success(activityService.getActivityListByProcessInstanceId(processInstanceId));  
42 - }  
43 -  
44 - @GetMapping("/generate-highlight-diagram")  
45 - @ApiOperation(value = "生成指定流程实例的高亮流程图",  
46 - notes = "只高亮进行中的任务。不过要注意,该接口暂时没用,通过前端的 ProcessViewer.vue 界面的 highlightDiagram 方法生成")  
47 - @ApiImplicitParam(name = "processInstanceId", value = "流程实例的编号", required = true, dataTypeClass = String.class)  
48 - @PreAuthorize("@ss.hasPermission('bpm:task:query')")  
49 - public void generateHighlightDiagram(@RequestParam("processInstanceId") String processInstanceId,  
50 - HttpServletResponse response) throws IOException {  
51 - byte[] bytes = activityService.generateHighlightDiagram(processInstanceId);  
52 - ServletUtils.writeAttachment(response, StrUtil.format("流程图-{}.svg", processInstanceId), bytes);  
53 - }  
54 -  
55 -}  
yudao-module-bpm/yudao-module-bpm-biz-activiti/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/BpmProcessInstanceController.http deleted
1 -### 请求 /bpm/process-instance/create 接口 => 成功  
2 -POST {{baseUrl}}/bpm/process-instance/create  
3 -Content-Type: application/json  
4 -tenant-id: 1  
5 -Authorization: Bearer {{token}}  
6 -  
7 -{  
8 - "processDefinitionId": "gateway_test:2:00e52d8e-701b-11ec-aca9-a2380e71991a",  
9 - "variables": {  
10 - "a": 1,  
11 - "b": "2"  
12 - }  
13 -}  
14 -  
15 -### 请求 /bpm/process-instance/cancel 接口 => 成功  
16 -DELETE {{baseUrl}}/bpm/process-instance/cancel  
17 -Content-Type: application/json  
18 -tenant-id: 1  
19 -Authorization: Bearer {{token}}  
20 -  
21 -{  
22 - "id": "b9220387-7088-11ec-bcae-a2380e71991a",  
23 - "reason": "我就取消"  
24 -}  
25 -  
26 -### 请求 /bpm/process-instance/get 接口 => 成功  
27 -GET {{baseUrl}}/bpm/process-instance/get?id=537cceb3-768c-11ec-afcd-a2380e71991a  
28 -tenant-id: 1  
29 -Authorization: Bearer {{token}}  
yudao-module-bpm/yudao-module-bpm-biz-activiti/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/BpmTaskController.http deleted
1 -### 请求 /bpm/task/todo-page 接口 => 成功  
2 -GET {{baseUrl}}/bpm/task/todo-page  
3 -tenant-id: 1  
4 -Authorization: Bearer {{token}}  
5 -  
6 -### 请求 /bpm/task/done-page 接口 => 成功  
7 -GET {{baseUrl}}/bpm/task/done-page?pageSize=100  
8 -tenant-id: 1  
9 -Authorization: Bearer {{token}}  
10 -  
11 -### 请求 /bpm/task/list-by-process-instance-id 接口 => 成功  
12 -GET {{baseUrl}}/bpm/task/list-by-process-instance-id?processInstanceId=537cceb3-768c-11ec-afcd-a2380e71991a  
13 -tenant-id: 1  
14 -Authorization: Bearer {{token}}  
yudao-module-bpm/yudao-module-bpm-biz-activiti/src/main/java/cn/iocoder/yudao/module/bpm/controller/app/package-info.java deleted
1 -/**  
2 - * 占位  
3 - */  
4 -package cn.iocoder.yudao.module.bpm.controller.app;  
yudao-module-bpm/yudao-module-bpm-biz-activiti/src/main/java/cn/iocoder/yudao/module/bpm/controller/package-info.java deleted
1 -/**  
2 - * 提供 RESTful API 给前端:  
3 - * 1. admin 包:提供给管理后台 yudao-ui-admin 前端项目  
4 - * 2. app 包:提供给用户 APP yudao-ui-app 前端项目,它的 Controller 和 VO 都要添加 App 前缀,用于和管理后台进行区分  
5 - */  
6 -package cn.iocoder.yudao.module.bpm.controller;  
yudao-module-bpm/yudao-module-bpm-biz-activiti/src/main/java/cn/iocoder/yudao/module/bpm/convert/definition/BpmModelConvert.java deleted
1 -package cn.iocoder.yudao.module.bpm.convert.definition;  
2 -  
3 -import cn.hutool.core.util.StrUtil;  
4 -import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.model.*;  
5 -import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;  
6 -import cn.iocoder.yudao.framework.common.util.json.JsonUtils;  
7 -import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmFormDO;  
8 -import cn.iocoder.yudao.module.bpm.service.definition.dto.BpmModelMetaInfoRespDTO;  
9 -import cn.iocoder.yudao.module.bpm.service.definition.dto.BpmProcessDefinitionCreateReqDTO;  
10 -import org.activiti.engine.impl.persistence.entity.SuspensionState;  
11 -import org.activiti.engine.repository.Deployment;  
12 -import org.activiti.engine.repository.Model;  
13 -import org.activiti.engine.repository.ProcessDefinition;  
14 -import org.mapstruct.Mapper;  
15 -import org.mapstruct.MappingTarget;  
16 -import org.mapstruct.factory.Mappers;  
17 -  
18 -import java.util.List;  
19 -import java.util.Map;  
20 -import java.util.Objects;  
21 -  
22 -  
23 -/**  
24 - * 流程模型 Convert  
25 - *  
26 - * @author yunlongn  
27 - */  
28 -@Mapper  
29 -public interface BpmModelConvert {  
30 -  
31 - BpmModelConvert INSTANCE = Mappers.getMapper(BpmModelConvert.class);  
32 -  
33 - default List<BpmModelPageItemRespVO> convertList(List<Model> list, Map<Long, BpmFormDO> formMap,  
34 - Map<String, Deployment> deploymentMap,  
35 - Map<String, ProcessDefinition> processDefinitionMap) {  
36 - return CollectionUtils.convertList(list, model -> {  
37 - BpmModelMetaInfoRespDTO metaInfo = JsonUtils.parseObject(model.getMetaInfo(), BpmModelMetaInfoRespDTO.class);  
38 - BpmFormDO form = metaInfo != null ? formMap.get(metaInfo.getFormId()) : null;  
39 - Deployment deployment = model.getDeploymentId() != null ? deploymentMap.get(model.getDeploymentId()) : null;  
40 - ProcessDefinition processDefinition = model.getDeploymentId() != null ? processDefinitionMap.get(model.getDeploymentId()) : null;  
41 - return convert(model, form, deployment, processDefinition);  
42 - });  
43 - }  
44 -  
45 - default BpmModelPageItemRespVO convert(Model model, BpmFormDO form, Deployment deployment, ProcessDefinition processDefinition) {  
46 - BpmModelPageItemRespVO modelRespVO = new BpmModelPageItemRespVO();  
47 - modelRespVO.setId(model.getId());  
48 - modelRespVO.setCreateTime(model.getCreateTime());  
49 - // 通用 copy  
50 - copyTo(model, modelRespVO);  
51 - // Form  
52 - if (form != null) {  
53 - modelRespVO.setFormId(form.getId());  
54 - modelRespVO.setFormName(form.getName());  
55 - }  
56 - // ProcessDefinition  
57 - modelRespVO.setProcessDefinition(this.convert(processDefinition));  
58 - if (modelRespVO.getProcessDefinition() != null) {  
59 - modelRespVO.getProcessDefinition().setSuspensionState(processDefinition.isSuspended() ?  
60 - SuspensionState.SUSPENDED.getStateCode() : SuspensionState.ACTIVE.getStateCode());  
61 - modelRespVO.getProcessDefinition().setDeploymentTime(deployment.getDeploymentTime());  
62 - }  
63 - return modelRespVO;  
64 - }  
65 -  
66 - default BpmModelRespVO convert(Model model) {  
67 - BpmModelRespVO modelRespVO = new BpmModelRespVO();  
68 - modelRespVO.setId(model.getId());  
69 - modelRespVO.setCreateTime(model.getCreateTime());  
70 - // 通用 copy  
71 - copyTo(model, modelRespVO);  
72 - return modelRespVO;  
73 - }  
74 -  
75 - default void copyTo(Model model, BpmModelBaseVO to) {  
76 - to.setName(model.getName());  
77 - to.setKey(model.getKey());  
78 - to.setCategory(model.getCategory());  
79 - // metaInfo  
80 - BpmModelMetaInfoRespDTO metaInfo = JsonUtils.parseObject(model.getMetaInfo(), BpmModelMetaInfoRespDTO.class);  
81 - copyTo(metaInfo, to);  
82 - }  
83 -  
84 - void copyTo(BpmModelMetaInfoRespDTO from, @MappingTarget BpmModelBaseVO to);  
85 -  
86 - default BpmProcessDefinitionCreateReqDTO convert2(Model model, BpmFormDO form) {  
87 - BpmProcessDefinitionCreateReqDTO createReqDTO = new BpmProcessDefinitionCreateReqDTO();  
88 - createReqDTO.setModelId(model.getId());  
89 - createReqDTO.setName(model.getName());  
90 - createReqDTO.setKey(model.getKey());  
91 - createReqDTO.setCategory(model.getCategory());  
92 - BpmModelMetaInfoRespDTO metaInfo = JsonUtils.parseObject(model.getMetaInfo(), BpmModelMetaInfoRespDTO.class);  
93 - // metaInfo  
94 - copyTo(metaInfo, createReqDTO);  
95 - // form  
96 - if (form != null) {  
97 - createReqDTO.setFormConf(form.getConf());  
98 - createReqDTO.setFormFields(form.getFields());  
99 - }  
100 - return createReqDTO;  
101 - }  
102 -  
103 - void copyTo(BpmModelMetaInfoRespDTO from, @MappingTarget BpmProcessDefinitionCreateReqDTO to);  
104 -  
105 - default void copy(Model model, BpmModelCreateReqVO bean) {  
106 - model.setName(bean.getName());  
107 - model.setKey(bean.getKey());  
108 - model.setMetaInfo(buildMetaInfoStr(null, bean.getDescription(), null, null,  
109 - null, null));  
110 - }  
111 -  
112 - default void copy(Model model, BpmModelUpdateReqVO bean) {  
113 - model.setName(bean.getName());  
114 - model.setCategory(bean.getCategory());  
115 - model.setMetaInfo(buildMetaInfoStr(JsonUtils.parseObject(model.getMetaInfo(), BpmModelMetaInfoRespDTO.class),  
116 - bean.getDescription(), bean.getFormType(), bean.getFormId(),  
117 - bean.getFormCustomCreatePath(), bean.getFormCustomViewPath()));  
118 - }  
119 -  
120 - default String buildMetaInfoStr(BpmModelMetaInfoRespDTO metaInfo, String description, Integer formType,  
121 - Long formId, String formCustomCreatePath, String formCustomViewPath) {  
122 - if (metaInfo == null) {  
123 - metaInfo = new BpmModelMetaInfoRespDTO();  
124 - }  
125 - // 只有非空,才进行设置,避免更新时的覆盖  
126 - if (StrUtil.isNotEmpty(description)) {  
127 - metaInfo.setDescription(description);  
128 - }  
129 - if (Objects.nonNull(formType)) {  
130 - metaInfo.setFormType(formType);  
131 - metaInfo.setFormId(formId);  
132 - metaInfo.setFormCustomCreatePath(formCustomCreatePath);  
133 - metaInfo.setFormCustomViewPath(formCustomViewPath);  
134 - }  
135 - return JsonUtils.toJsonString(metaInfo);  
136 - }  
137 -  
138 - BpmModelPageItemRespVO.ProcessDefinition convert(ProcessDefinition bean);  
139 -  
140 - BpmModelCreateReqVO convert(BpmModeImportReqVO bean);  
141 -  
142 -}  
yudao-module-bpm/yudao-module-bpm-biz-activiti/src/main/java/cn/iocoder/yudao/module/bpm/convert/definition/BpmProcessDefinitionConvert.java deleted
1 -package cn.iocoder.yudao.module.bpm.convert.definition;  
2 -  
3 -import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;  
4 -import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.process.BpmProcessDefinitionPageItemRespVO;  
5 -import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.process.BpmProcessDefinitionRespVO;  
6 -import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmFormDO;  
7 -import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmProcessDefinitionExtDO;  
8 -import cn.iocoder.yudao.module.bpm.service.definition.dto.BpmProcessDefinitionCreateReqDTO;  
9 -import org.activiti.engine.impl.persistence.entity.SuspensionState;  
10 -import org.activiti.engine.repository.Deployment;  
11 -import org.activiti.engine.repository.ProcessDefinition;  
12 -import org.mapstruct.Mapper;  
13 -import org.mapstruct.Mapping;  
14 -import org.mapstruct.MappingTarget;  
15 -import org.mapstruct.Named;  
16 -import org.mapstruct.factory.Mappers;  
17 -  
18 -import java.util.List;  
19 -import java.util.Map;  
20 -  
21 -/**  
22 - * Bpm 流程定义的 Convert  
23 - *  
24 - * @author yunlong.li  
25 - */  
26 -@Mapper  
27 -public interface BpmProcessDefinitionConvert {  
28 -  
29 - BpmProcessDefinitionConvert INSTANCE = Mappers.getMapper(BpmProcessDefinitionConvert.class);  
30 -  
31 - default List<BpmProcessDefinitionPageItemRespVO> convertList(List<ProcessDefinition> list, Map<String, Deployment> deploymentMap,  
32 - Map<String, BpmProcessDefinitionExtDO> processDefinitionDOMap, Map<Long, BpmFormDO> formMap) {  
33 - return CollectionUtils.convertList(list, definition -> {  
34 - Deployment deployment = definition.getDeploymentId() != null ? deploymentMap.get(definition.getDeploymentId()) : null;  
35 - BpmProcessDefinitionExtDO definitionDO = processDefinitionDOMap.get(definition.getId());  
36 - BpmFormDO form = definitionDO != null ? formMap.get(definitionDO.getFormId()) : null;  
37 - return convert(definition, deployment, definitionDO, form);  
38 - });  
39 - }  
40 -  
41 - default BpmProcessDefinitionPageItemRespVO convert(ProcessDefinition bean, Deployment deployment,  
42 - BpmProcessDefinitionExtDO processDefinitionExtDO, BpmFormDO form) {  
43 - BpmProcessDefinitionPageItemRespVO respVO = convert(bean);  
44 - respVO.setSuspensionState(bean.isSuspended() ? SuspensionState.SUSPENDED.getStateCode() : SuspensionState.ACTIVE.getStateCode());  
45 - if (deployment != null) {  
46 - respVO.setDeploymentTime(deployment.getDeploymentTime());  
47 - }  
48 - if (form != null) {  
49 - respVO.setFormName(form.getName());  
50 - }  
51 - // 复制通用属性  
52 - copyTo(processDefinitionExtDO, respVO);  
53 - return respVO;  
54 - }  
55 -  
56 - BpmProcessDefinitionPageItemRespVO convert(ProcessDefinition bean);  
57 -  
58 - BpmProcessDefinitionExtDO convert2(BpmProcessDefinitionCreateReqDTO bean);  
59 -  
60 - default List<BpmProcessDefinitionRespVO> convertList3(List<ProcessDefinition> list,  
61 - Map<String, BpmProcessDefinitionExtDO> processDefinitionDOMap) {  
62 - return CollectionUtils.convertList(list, processDefinition -> {  
63 - BpmProcessDefinitionRespVO respVO = convert3(processDefinition);  
64 - BpmProcessDefinitionExtDO processDefinitionExtDO = processDefinitionDOMap.get(processDefinition.getId());  
65 - // 复制通用属性  
66 - copyTo(processDefinitionExtDO, respVO);  
67 - return respVO;  
68 - });  
69 - }  
70 -  
71 - @Mapping(source = "suspended", target = "suspensionState", qualifiedByName = "convertSuspendedToSuspensionState")  
72 - BpmProcessDefinitionRespVO convert3(ProcessDefinition bean);  
73 -  
74 - @Named("convertSuspendedToSuspensionState")  
75 - default Integer convertSuspendedToSuspensionState(boolean suspended) {  
76 - return suspended ? SuspensionState.SUSPENDED.getStateCode() :  
77 - SuspensionState.ACTIVE.getStateCode();  
78 - }  
79 -  
80 - @Mapping(source = "from.id", target = "to.id", ignore = true)  
81 - void copyTo(BpmProcessDefinitionExtDO from, @MappingTarget BpmProcessDefinitionRespVO to);  
82 -  
83 -}  
yudao-module-bpm/yudao-module-bpm-biz-activiti/src/main/java/cn/iocoder/yudao/module/bpm/convert/definition/BpmTaskAssignRuleConvert.java deleted
1 -package cn.iocoder.yudao.module.bpm.convert.definition;  
2 -  
3 -import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.rule.BpmTaskAssignRuleCreateReqVO;  
4 -import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.rule.BpmTaskAssignRuleRespVO;  
5 -import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.rule.BpmTaskAssignRuleUpdateReqVO;  
6 -import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmTaskAssignRuleDO;  
7 -import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;  
8 -import org.activiti.bpmn.model.UserTask;  
9 -import org.mapstruct.Mapper;  
10 -import org.mapstruct.factory.Mappers;  
11 -  
12 -import java.util.List;  
13 -import java.util.Map;  
14 -  
15 -@Mapper  
16 -public interface BpmTaskAssignRuleConvert {  
17 -  
18 - BpmTaskAssignRuleConvert INSTANCE = Mappers.getMapper(BpmTaskAssignRuleConvert.class);  
19 -  
20 - default List<BpmTaskAssignRuleRespVO> convertList(List<UserTask> tasks, List<BpmTaskAssignRuleDO> rules) {  
21 - Map<String, BpmTaskAssignRuleDO> ruleMap = CollectionUtils.convertMap(rules, BpmTaskAssignRuleDO::getTaskDefinitionKey);  
22 - // 以 UserTask 为主维度,原因是:流程图编辑后,一些规则实际就没用了。  
23 - return CollectionUtils.convertList(tasks, task -> {  
24 - BpmTaskAssignRuleRespVO respVO = convert(ruleMap.get(task.getId()));  
25 - if (respVO == null) {  
26 - respVO = new BpmTaskAssignRuleRespVO();  
27 - respVO.setTaskDefinitionKey(task.getId());  
28 - }  
29 - respVO.setTaskDefinitionName(task.getName());  
30 - return respVO;  
31 - });  
32 - }  
33 -  
34 - BpmTaskAssignRuleRespVO convert(BpmTaskAssignRuleDO bean);  
35 -  
36 - BpmTaskAssignRuleDO convert(BpmTaskAssignRuleCreateReqVO bean);  
37 -  
38 - BpmTaskAssignRuleDO convert(BpmTaskAssignRuleUpdateReqVO bean);  
39 -  
40 - List<BpmTaskAssignRuleDO> convertList2(List<BpmTaskAssignRuleRespVO> list);  
41 -  
42 -}  
yudao-module-bpm/yudao-module-bpm-biz-activiti/src/main/java/cn/iocoder/yudao/module/bpm/convert/task/BpmActivityConvert.java deleted
1 -package cn.iocoder.yudao.module.bpm.convert.task;  
2 -  
3 -import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.activity.BpmActivityRespVO;  
4 -import org.activiti.engine.history.HistoricActivityInstance;  
5 -import org.mapstruct.Mapper;  
6 -import org.mapstruct.Mapping;  
7 -import org.mapstruct.Mappings;  
8 -import org.mapstruct.factory.Mappers;  
9 -  
10 -import java.util.List;  
11 -  
12 -/**  
13 - * BPM 活动 Convert  
14 - *  
15 - * @author 芋道源码  
16 - */  
17 -@Mapper  
18 -public interface BpmActivityConvert {  
19 -  
20 - BpmActivityConvert INSTANCE = Mappers.getMapper(BpmActivityConvert.class);  
21 -  
22 - List<BpmActivityRespVO> convertList(List<HistoricActivityInstance> list);  
23 -  
24 - @Mappings({  
25 - @Mapping(source = "activityId", target = "key"),  
26 - @Mapping(source = "activityType", target = "type")  
27 - })  
28 - BpmActivityRespVO convert(HistoricActivityInstance bean);  
29 -  
30 -}  
yudao-module-bpm/yudao-module-bpm-biz-activiti/src/main/java/cn/iocoder/yudao/module/bpm/convert/task/BpmProcessInstanceConvert.java deleted
1 -package cn.iocoder.yudao.module.bpm.convert.task;  
2 -  
3 -import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance.BpmProcessInstancePageItemRespVO;  
4 -import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance.BpmProcessInstanceRespVO;  
5 -import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmProcessDefinitionExtDO;  
6 -import cn.iocoder.yudao.module.bpm.dal.dataobject.task.BpmProcessInstanceExtDO;  
7 -import cn.iocoder.yudao.module.bpm.framework.bpm.core.event.BpmProcessInstanceResultEvent;  
8 -import cn.iocoder.yudao.module.bpm.service.message.dto.BpmMessageSendWhenProcessInstanceApproveReqDTO;  
9 -import cn.iocoder.yudao.module.bpm.service.message.dto.BpmMessageSendWhenProcessInstanceRejectReqDTO;  
10 -import cn.iocoder.yudao.module.system.api.dept.dto.DeptRespDTO;  
11 -import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;  
12 -import cn.iocoder.yudao.framework.common.pojo.PageResult;  
13 -import org.activiti.engine.history.HistoricProcessInstance;  
14 -import org.activiti.engine.repository.ProcessDefinition;  
15 -import org.activiti.engine.runtime.ProcessInstance;  
16 -import org.activiti.engine.task.Task;  
17 -import org.mapstruct.Mapper;  
18 -import org.mapstruct.Mapping;  
19 -import org.mapstruct.MappingTarget;  
20 -import org.mapstruct.Mappings;  
21 -import org.mapstruct.factory.Mappers;  
22 -  
23 -import java.util.List;  
24 -import java.util.Map;  
25 -  
26 -/**  
27 - * 流程实例 Convert  
28 - *  
29 - * @author 芋道源码  
30 - */  
31 -@Mapper  
32 -public interface BpmProcessInstanceConvert {  
33 -  
34 - BpmProcessInstanceConvert INSTANCE = Mappers.getMapper(BpmProcessInstanceConvert.class);  
35 -  
36 - default BpmProcessInstanceExtDO convert3(ProcessInstance instance, ProcessDefinition definition) {  
37 - BpmProcessInstanceExtDO ext = new BpmProcessInstanceExtDO();  
38 - copyTo(instance, ext);  
39 - copyTo(definition, ext);  
40 - return ext;  
41 - }  
42 -  
43 - @Mappings({  
44 - @Mapping(source = "from.id", target = "id", ignore = true),  
45 - @Mapping(source = "from.startTime", target = "createTime"),  
46 - })  
47 - void copyTo(ProcessInstance from, @MappingTarget BpmProcessInstanceExtDO to);  
48 - @Mapping(source = "from.id", target = "id", ignore = true)  
49 - void copyTo(ProcessDefinition from, @MappingTarget BpmProcessInstanceExtDO to);  
50 -  
51 - default PageResult<BpmProcessInstancePageItemRespVO> convertPage(PageResult<BpmProcessInstanceExtDO> page,  
52 - Map<String, List<Task>> taskMap) {  
53 - List<BpmProcessInstancePageItemRespVO> list = convertList(page.getList());  
54 - list.forEach(respVO -> respVO.setTasks(convertList2(taskMap.get(respVO.getId()))));  
55 - return new PageResult<>(list, page.getTotal());  
56 - }  
57 -  
58 - List<BpmProcessInstancePageItemRespVO> convertList(List<BpmProcessInstanceExtDO> list);  
59 -  
60 - List<BpmProcessInstancePageItemRespVO.Task> convertList2(List<Task> tasks);  
61 -  
62 - @Mapping(source = "processInstanceId", target = "id")  
63 - BpmProcessInstancePageItemRespVO convert(BpmProcessInstanceExtDO bean);  
64 -  
65 - @Mappings({  
66 - @Mapping(source = "id", target = "processInstanceId"),  
67 - @Mapping(source = "id", target = "id", ignore = true),  
68 - @Mapping(source = "startDate", target = "createTime"),  
69 - @Mapping(source = "initiator", target = "startUserId"),  
70 - @Mapping(source = "status", target = "status", ignore = true)  
71 - })  
72 - BpmProcessInstanceExtDO convert(org.activiti.api.process.model.ProcessInstance bean);  
73 -  
74 - default BpmProcessInstanceRespVO convert2(HistoricProcessInstance processInstance, BpmProcessInstanceExtDO processInstanceExt,  
75 - ProcessDefinition processDefinition, BpmProcessDefinitionExtDO processDefinitionExt,  
76 - String bpmnXml, AdminUserRespDTO startUser, DeptRespDTO dept) {  
77 - BpmProcessInstanceRespVO respVO = convert2(processInstance);  
78 - copyTo(processInstanceExt, respVO);  
79 - // definition  
80 - respVO.setProcessDefinition(convert2(processDefinition));  
81 - copyTo(processDefinitionExt, respVO.getProcessDefinition());  
82 - respVO.getProcessDefinition().setBpmnXml(bpmnXml);  
83 - // user  
84 - if (startUser != null) {  
85 - respVO.setStartUser(convert2(startUser));  
86 - if (dept != null) {  
87 - respVO.getStartUser().setDeptName(dept.getName());  
88 - }  
89 - }  
90 - return respVO;  
91 - }  
92 -  
93 - BpmProcessInstanceRespVO convert2(HistoricProcessInstance bean);  
94 - @Mapping(source = "from.id", target = "to.id", ignore = true)  
95 - void copyTo(BpmProcessInstanceExtDO from, @MappingTarget BpmProcessInstanceRespVO to);  
96 - BpmProcessInstanceRespVO.ProcessDefinition convert2(ProcessDefinition bean);  
97 - @Mapping(source = "from.id", target = "to.id", ignore = true)  
98 - void copyTo(BpmProcessDefinitionExtDO from, @MappingTarget BpmProcessInstanceRespVO.ProcessDefinition to);  
99 - BpmProcessInstanceRespVO.User convert2(AdminUserRespDTO bean);  
100 -  
101 - default BpmProcessInstanceResultEvent convert(Object source, ProcessInstance instance, Integer result) {  
102 - BpmProcessInstanceResultEvent event = new BpmProcessInstanceResultEvent(source);  
103 - event.setId(instance.getId());  
104 - event.setProcessDefinitionKey(instance.getProcessDefinitionKey());  
105 - event.setBusinessKey(instance.getBusinessKey());  
106 - event.setResult(result);  
107 - return event;  
108 - }  
109 -  
110 - default BpmProcessInstanceResultEvent convert(Object source, HistoricProcessInstance instance, Integer result) {  
111 - BpmProcessInstanceResultEvent event = new BpmProcessInstanceResultEvent(source);  
112 - event.setId(instance.getId());  
113 - event.setProcessDefinitionKey(instance.getProcessDefinitionKey());  
114 - event.setBusinessKey(instance.getBusinessKey());  
115 - event.setResult(result);  
116 - return event;  
117 - }  
118 -  
119 - default BpmMessageSendWhenProcessInstanceRejectReqDTO convert(ProcessInstance processInstance, String reason) {  
120 - BpmMessageSendWhenProcessInstanceRejectReqDTO reqDTO = new BpmMessageSendWhenProcessInstanceRejectReqDTO();  
121 - copyTo(processInstance, reqDTO);  
122 - reqDTO.setReason(reason);  
123 - return reqDTO;  
124 - }  
125 - @Mapping(source = "name", target = "processInstanceName")  
126 - void copyTo(ProcessInstance from, @MappingTarget BpmMessageSendWhenProcessInstanceRejectReqDTO to);  
127 -  
128 - @Mappings({  
129 - @Mapping(source = "id", target = "processInstanceId"),  
130 - @Mapping(source = "name", target = "processInstanceName"),  
131 - @Mapping(source = "initiator", target = "startUserId")  
132 - })  
133 - BpmMessageSendWhenProcessInstanceApproveReqDTO convert2(org.activiti.api.process.model.ProcessInstance processInstance);  
134 -  
135 -}  
yudao-module-bpm/yudao-module-bpm-biz-activiti/src/main/java/cn/iocoder/yudao/module/bpm/convert/task/BpmTaskConvert.java deleted
1 -package cn.iocoder.yudao.module.bpm.convert.task;  
2 -  
3 -import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.task.BpmTaskDonePageItemRespVO;  
4 -import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.task.BpmTaskRespVO;  
5 -import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.task.BpmTaskTodoPageItemRespVO;  
6 -import cn.iocoder.yudao.module.bpm.dal.dataobject.task.BpmTaskExtDO;  
7 -import cn.iocoder.yudao.module.bpm.service.message.dto.BpmMessageSendWhenTaskCreatedReqDTO;  
8 -import cn.iocoder.yudao.module.system.api.dept.dto.DeptRespDTO;  
9 -import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;  
10 -import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;  
11 -import cn.iocoder.yudao.framework.common.util.number.NumberUtils;  
12 -import org.activiti.engine.history.HistoricProcessInstance;  
13 -import org.activiti.engine.history.HistoricTaskInstance;  
14 -import org.activiti.engine.impl.persistence.entity.SuspensionState;  
15 -import org.activiti.engine.runtime.ProcessInstance;  
16 -import org.activiti.engine.task.Task;  
17 -import org.mapstruct.*;  
18 -import org.mapstruct.factory.Mappers;  
19 -  
20 -import java.util.List;  
21 -import java.util.Map;  
22 -  
23 -/**  
24 - * Bpm 任务 Convert  
25 - *  
26 - * @author 芋道源码  
27 - */  
28 -@Mapper  
29 -public interface BpmTaskConvert {  
30 -  
31 - BpmTaskConvert INSTANCE = Mappers.getMapper(BpmTaskConvert.class);  
32 -  
33 - default List<BpmTaskTodoPageItemRespVO> convertList1(List<Task> tasks, Map<String, ProcessInstance> processInstanceMap,  
34 - Map<Long, AdminUserRespDTO> userMap) {  
35 - return CollectionUtils.convertList(tasks, task -> {  
36 - BpmTaskTodoPageItemRespVO respVO = convert1(task);  
37 - ProcessInstance processInstance = processInstanceMap.get(task.getProcessInstanceId());  
38 - if (processInstance != null) {  
39 - AdminUserRespDTO startUser = userMap.get(NumberUtils.parseLong(processInstance.getStartUserId()));  
40 - respVO.setProcessInstance(convert(processInstance, startUser));  
41 - }  
42 - return respVO;  
43 - });  
44 - }  
45 -  
46 - @Mapping(source = "suspended", target = "suspensionState", qualifiedByName = "convertSuspendedToSuspensionState")  
47 - BpmTaskTodoPageItemRespVO convert1(Task bean);  
48 -  
49 - @Named("convertSuspendedToSuspensionState")  
50 - default Integer convertSuspendedToSuspensionState(boolean suspended) {  
51 - return suspended ? SuspensionState.SUSPENDED.getStateCode() :  
52 - SuspensionState.ACTIVE.getStateCode();  
53 - }  
54 -  
55 - default List<BpmTaskDonePageItemRespVO> convertList2(List<HistoricTaskInstance> tasks, Map<String, BpmTaskExtDO> bpmTaskExtDOMap,  
56 - Map<String, HistoricProcessInstance> historicProcessInstanceMap,  
57 - Map<Long, AdminUserRespDTO> userMap) {  
58 - return CollectionUtils.convertList(tasks, task -> {  
59 - BpmTaskDonePageItemRespVO respVO = convert2(task);  
60 - BpmTaskExtDO taskExtDO = bpmTaskExtDOMap.get(task.getId());  
61 - copyTo(taskExtDO, respVO);  
62 - HistoricProcessInstance processInstance = historicProcessInstanceMap.get(task.getProcessInstanceId());  
63 - if (processInstance != null) {  
64 - AdminUserRespDTO startUser = userMap.get(NumberUtils.parseLong(processInstance.getStartUserId()));  
65 - respVO.setProcessInstance(convert(processInstance, startUser));  
66 - }  
67 - return respVO;  
68 - });  
69 - }  
70 -  
71 - BpmTaskDonePageItemRespVO convert2(HistoricTaskInstance bean);  
72 -  
73 - @Mappings({  
74 - @Mapping(source = "id", target = "taskId"),  
75 - @Mapping(source = "assignee", target = "assigneeUserId"),  
76 - @Mapping(source = "createdDate", target = "createTime"),  
77 - @Mapping(target = "id", ignore = true)  
78 - })  
79 - BpmTaskExtDO convert(org.activiti.api.task.model.Task bean);  
80 -  
81 - default List<BpmTaskRespVO> convertList3(List<HistoricTaskInstance> tasks, Map<String, BpmTaskExtDO> bpmTaskExtDOMap,  
82 - HistoricProcessInstance processInstance, Map<Long, AdminUserRespDTO> userMap,  
83 - Map<Long, DeptRespDTO> deptMap) {  
84 - return CollectionUtils.convertList(tasks, task -> {  
85 - BpmTaskRespVO respVO = convert3(task);  
86 - BpmTaskExtDO taskExtDO = bpmTaskExtDOMap.get(task.getId());  
87 - copyTo(taskExtDO, respVO);  
88 - if (processInstance != null) {  
89 - AdminUserRespDTO startUser = userMap.get(NumberUtils.parseLong(processInstance.getStartUserId()));  
90 - respVO.setProcessInstance(convert(processInstance, startUser));  
91 - }  
92 - AdminUserRespDTO assignUser = userMap.get(NumberUtils.parseLong(task.getAssignee()));  
93 - if (assignUser != null) {  
94 - respVO.setAssigneeUser(convert3(assignUser));  
95 - DeptRespDTO dept = deptMap.get(assignUser.getDeptId());  
96 - if (dept != null) {  
97 - respVO.getAssigneeUser().setDeptName(dept.getName());  
98 - }  
99 - }  
100 - return respVO;  
101 - });  
102 - }  
103 -  
104 - @Mapping(source = "taskDefinitionKey", target = "definitionKey")  
105 - BpmTaskRespVO convert3(HistoricTaskInstance bean);  
106 - BpmTaskRespVO.User convert3(AdminUserRespDTO bean);  
107 -  
108 - @Mapping(target = "id", ignore = true)  
109 - void copyTo(BpmTaskExtDO from, @MappingTarget BpmTaskDonePageItemRespVO to);  
110 -  
111 - @Mappings({  
112 - @Mapping(source = "processInstance.id", target = "id"),  
113 - @Mapping(source = "processInstance.name", target = "name"),  
114 - @Mapping(source = "processInstance.startUserId", target = "startUserId"),  
115 - @Mapping(source = "processInstance.processDefinitionId", target = "processDefinitionId"),  
116 - @Mapping(source = "startUser.nickname", target = "startUserNickname")  
117 - })  
118 - BpmTaskTodoPageItemRespVO.ProcessInstance convert(ProcessInstance processInstance, AdminUserRespDTO startUser);  
119 -  
120 - @Mappings({  
121 - @Mapping(source = "processInstance.id", target = "id"),  
122 - @Mapping(source = "processInstance.name", target = "name"),  
123 - @Mapping(source = "processInstance.startUserId", target = "startUserId"),  
124 - @Mapping(source = "processInstance.processDefinitionId", target = "processDefinitionId"),  
125 - @Mapping(source = "startUser.nickname", target = "startUserNickname")  
126 - })  
127 - BpmTaskTodoPageItemRespVO.ProcessInstance convert(HistoricProcessInstance processInstance, AdminUserRespDTO startUser);  
128 -  
129 - default BpmMessageSendWhenTaskCreatedReqDTO convert(ProcessInstance processInstance, AdminUserRespDTO startUser, org.activiti.api.task.model.Task task) {  
130 - BpmMessageSendWhenTaskCreatedReqDTO reqDTO = new BpmMessageSendWhenTaskCreatedReqDTO();  
131 - copyTo(processInstance, reqDTO);  
132 - copyTo(startUser, reqDTO);  
133 - copyTo(task, reqDTO);  
134 - return reqDTO;  
135 - }  
136 - @Mapping(source = "name", target = "processInstanceName")  
137 - void copyTo(ProcessInstance from, @MappingTarget BpmMessageSendWhenTaskCreatedReqDTO to);  
138 - @Mappings({  
139 - @Mapping(source = "id", target = "startUserId"),  
140 - @Mapping(source = "nickname", target = "startUserNickname")  
141 - })  
142 - void copyTo(AdminUserRespDTO from, @MappingTarget BpmMessageSendWhenTaskCreatedReqDTO to);  
143 - @Mappings({  
144 - @Mapping(source = "id", target = "taskId"),  
145 - @Mapping(source = "name", target = "taskName"),  
146 - @Mapping(source = "assignee", target = "assigneeUserId")  
147 - })  
148 - void copyTo(org.activiti.api.task.model.Task task, @MappingTarget BpmMessageSendWhenTaskCreatedReqDTO to);  
149 -}  
yudao-module-bpm/yudao-module-bpm-biz-activiti/src/main/java/cn/iocoder/yudao/module/bpm/framework/activiti/config/BpmActivitiConfiguration.java deleted
1 -package cn.iocoder.yudao.module.bpm.framework.activiti.config;  
2 -  
3 -import cn.iocoder.yudao.module.bpm.framework.activiti.core.behavior.BpmActivityBehaviorFactory;  
4 -import cn.iocoder.yudao.module.bpm.framework.activiti.core.behavior.script.BpmTaskAssignScript;  
5 -import cn.iocoder.yudao.module.bpm.framework.activiti.core.identity.EmptyUserGroupManager;  
6 -import cn.iocoder.yudao.module.bpm.framework.activiti.core.listener.BpmTackActivitiEventListener;  
7 -import cn.iocoder.yudao.module.bpm.service.definition.BpmTaskAssignRuleService;  
8 -import cn.iocoder.yudao.module.bpm.service.definition.BpmUserGroupService;  
9 -import cn.iocoder.yudao.module.system.api.dept.DeptApi;  
10 -import cn.iocoder.yudao.module.system.api.permission.PermissionApi;  
11 -import cn.iocoder.yudao.module.system.api.user.AdminUserApi;  
12 -import org.activiti.api.runtime.shared.identity.UserGroupManager;  
13 -import org.activiti.spring.boot.ProcessEngineConfigurationConfigurer;  
14 -import org.springframework.context.annotation.Bean;  
15 -import org.springframework.context.annotation.Configuration;  
16 -  
17 -import java.util.Collections;  
18 -import java.util.List;  
19 -  
20 -import static org.activiti.spring.boot.ProcessEngineAutoConfiguration.BEHAVIOR_FACTORY_MAPPING_CONFIGURER;  
21 -  
22 -/**  
23 - * BPM 模块的 Activiti 配置类  
24 - */  
25 -@Configuration  
26 -public class BpmActivitiConfiguration {  
27 -  
28 - /**  
29 - * 空用户组的 Bean  
30 - */  
31 - @Bean  
32 - public UserGroupManager userGroupManager() {  
33 - return new EmptyUserGroupManager();  
34 - }  
35 -  
36 - /**  
37 - * BPM 模块的 ProcessEngineConfigurationConfigurer 实现类,主要设置各种监听器  
38 - */  
39 - @Bean  
40 - public ProcessEngineConfigurationConfigurer bpmProcessEngineConfigurationConfigurer(  
41 - BpmTackActivitiEventListener taskActivitiEventListener) {  
42 - return configuration -> {  
43 - // 注册监听器,例如说 BpmActivitiEventListener  
44 - configuration.setEventListeners(Collections.singletonList(taskActivitiEventListener));  
45 - };  
46 - }  
47 -  
48 - /**  
49 - * 用于设置自定义的 ActivityBehaviorFactory 实现的 ProcessEngineConfigurationConfigurer 实现类  
50 - *  
51 - * 目的:覆盖 {@link org.activiti.spring.boot.ProcessEngineAutoConfiguration} 的  
52 - * defaultActivityBehaviorFactoryMappingConfigurer 方法创建的 Bean  
53 - */  
54 - @Bean(name = BEHAVIOR_FACTORY_MAPPING_CONFIGURER)  
55 - public ProcessEngineConfigurationConfigurer defaultActivityBehaviorFactoryMappingConfigurer(  
56 - BpmActivityBehaviorFactory bpmActivityBehaviorFactory) {  
57 - return configuration -> {  
58 - // 设置 ActivityBehaviorFactory 实现类,用于流程任务的审核人的自定义  
59 - configuration.setActivityBehaviorFactory(bpmActivityBehaviorFactory);  
60 - };  
61 - }  
62 -  
63 - @Bean  
64 - public BpmActivityBehaviorFactory bpmActivityBehaviorFactory(BpmTaskAssignRuleService taskRuleService,  
65 - BpmUserGroupService userGroupService,  
66 - PermissionApi permissionApi,  
67 - DeptApi deptApi,  
68 - AdminUserApi adminUserApi,  
69 - List<BpmTaskAssignScript> scripts) {  
70 - BpmActivityBehaviorFactory bpmActivityBehaviorFactory = new BpmActivityBehaviorFactory();  
71 - bpmActivityBehaviorFactory.setBpmTaskRuleService(taskRuleService);  
72 - bpmActivityBehaviorFactory.setUserGroupService(userGroupService);  
73 - bpmActivityBehaviorFactory.setAdminUserApi(adminUserApi);  
74 - bpmActivityBehaviorFactory.setPermissionApi(permissionApi);  
75 - bpmActivityBehaviorFactory.setDeptApi(deptApi);  
76 - bpmActivityBehaviorFactory.setScripts(scripts);  
77 - return bpmActivityBehaviorFactory;  
78 - }  
79 -  
80 -}  
yudao-module-bpm/yudao-module-bpm-biz-activiti/src/main/java/cn/iocoder/yudao/module/bpm/framework/activiti/core/behavior/BpmActivityBehaviorFactory.java deleted
1 -package cn.iocoder.yudao.module.bpm.framework.activiti.core.behavior;  
2 -  
3 -import cn.iocoder.yudao.module.bpm.framework.activiti.core.behavior.script.BpmTaskAssignScript;  
4 -import cn.iocoder.yudao.module.bpm.service.definition.BpmTaskAssignRuleService;  
5 -import cn.iocoder.yudao.module.bpm.service.definition.BpmUserGroupService;  
6 -import cn.iocoder.yudao.module.system.api.dept.DeptApi;  
7 -import cn.iocoder.yudao.module.system.api.permission.PermissionApi;  
8 -import cn.iocoder.yudao.module.system.api.user.AdminUserApi;  
9 -import lombok.Data;  
10 -import lombok.EqualsAndHashCode;  
11 -import lombok.Setter;  
12 -import lombok.ToString;  
13 -import org.activiti.bpmn.model.UserTask;  
14 -import org.activiti.engine.impl.bpmn.behavior.UserTaskActivityBehavior;  
15 -import org.activiti.engine.impl.bpmn.parser.factory.DefaultActivityBehaviorFactory;  
16 -  
17 -import java.util.List;  
18 -  
19 -/**  
20 - * 自定义的 ActivityBehaviorFactory 实现类,目的如下:  
21 - * 1. 自定义 {@link #createUserTaskActivityBehavior(UserTask)}:实现自定义的流程任务的 assignee 负责人的分配  
22 - *  
23 - * @author 芋道源码  
24 - */  
25 -@Data  
26 -@EqualsAndHashCode(callSuper = true)  
27 -@ToString(callSuper = true)  
28 -public class BpmActivityBehaviorFactory extends DefaultActivityBehaviorFactory {  
29 -  
30 - @Setter  
31 - private BpmTaskAssignRuleService bpmTaskRuleService;  
32 - @Setter  
33 - private BpmUserGroupService userGroupService;  
34 -  
35 - @Setter  
36 - private PermissionApi permissionApi;  
37 - @Setter  
38 - private DeptApi deptApi;  
39 - @Setter  
40 - private AdminUserApi adminUserApi;  
41 -  
42 - @Setter  
43 - private List<BpmTaskAssignScript> scripts;  
44 -  
45 - @Override  
46 - public UserTaskActivityBehavior createUserTaskActivityBehavior(UserTask userTask) {  
47 - BpmUserTaskActivityBehavior userTaskActivityBehavior = new BpmUserTaskActivityBehavior(userTask);  
48 - userTaskActivityBehavior.setBpmTaskRuleService(bpmTaskRuleService);  
49 - userTaskActivityBehavior.setPermissionApi(permissionApi);  
50 - userTaskActivityBehavior.setDeptApi(deptApi);  
51 - userTaskActivityBehavior.setUserGroupService(userGroupService);  
52 - userTaskActivityBehavior.setAdminUserApi(adminUserApi);  
53 - userTaskActivityBehavior.setScripts(scripts);  
54 - return userTaskActivityBehavior;  
55 - }  
56 -  
57 - // TODO 芋艿:并行任务 ParallelMultiInstanceBehavior  
58 -  
59 - // TODO 芋艿:并行任务 SequentialMultiInstanceBehavior  
60 -  
61 -}  
yudao-module-bpm/yudao-module-bpm-biz-activiti/src/main/java/cn/iocoder/yudao/module/bpm/framework/activiti/core/behavior/BpmUserTaskActivityBehavior.java deleted
1 -package cn.iocoder.yudao.module.bpm.framework.activiti.core.behavior;  
2 -  
3 -import cn.hutool.core.collection.CollUtil;  
4 -import cn.hutool.core.util.RandomUtil;  
5 -import cn.hutool.core.util.StrUtil;  
6 -import cn.iocoder.yudao.module.bpm.framework.activiti.core.behavior.script.BpmTaskAssignScript;  
7 -import cn.iocoder.yudao.module.bpm.service.definition.BpmTaskAssignRuleService;  
8 -import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;  
9 -import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmTaskAssignRuleDO;  
10 -import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmUserGroupDO;  
11 -import cn.iocoder.yudao.module.bpm.enums.definition.BpmTaskAssignRuleTypeEnum;  
12 -import cn.iocoder.yudao.module.bpm.service.definition.BpmUserGroupService;  
13 -import cn.iocoder.yudao.module.system.api.dept.DeptApi;  
14 -import cn.iocoder.yudao.module.system.api.dept.dto.DeptRespDTO;  
15 -import cn.iocoder.yudao.module.system.api.permission.PermissionApi;  
16 -import cn.iocoder.yudao.module.system.api.user.AdminUserApi;  
17 -import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;  
18 -import com.google.common.annotations.VisibleForTesting;  
19 -import lombok.Setter;  
20 -import lombok.extern.slf4j.Slf4j;  
21 -import org.activiti.bpmn.model.UserTask;  
22 -import org.activiti.engine.ActivitiException;  
23 -import org.activiti.engine.delegate.DelegateExecution;  
24 -import org.activiti.engine.impl.bpmn.behavior.UserTaskActivityBehavior;  
25 -import org.activiti.engine.impl.el.ExpressionManager;  
26 -import org.activiti.engine.impl.persistence.entity.TaskEntity;  
27 -import org.activiti.engine.impl.persistence.entity.TaskEntityManager;  
28 -  
29 -import java.util.*;  
30 -  
31 -import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;  
32 -import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap;  
33 -import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;  
34 -import static cn.iocoder.yudao.framework.common.util.json.JsonUtils.toJsonString;  
35 -import static cn.iocoder.yudao.module.bpm.enums.ErrorCodeConstants.TASK_ASSIGN_SCRIPT_NOT_EXISTS;  
36 -import static cn.iocoder.yudao.module.bpm.enums.ErrorCodeConstants.TASK_CREATE_FAIL_NO_CANDIDATE_USER;  
37 -  
38 -/**  
39 - * 自定义的流程任务的 assignee 负责人的分配  
40 - * 第一步,获得对应的分配规则;  
41 - * 第二步,根据分配规则,计算出分配任务的候选人。如果找不到,则直接报业务异常,不继续执行后续的流程;  
42 - * 第三步,随机选择一个候选人,则选择作为 assignee 负责人。  
43 - *  
44 - * @author 芋道源码  
45 - */  
46 -@Slf4j  
47 -public class BpmUserTaskActivityBehavior extends UserTaskActivityBehavior {  
48 -  
49 - @Setter  
50 - private BpmTaskAssignRuleService bpmTaskRuleService;  
51 -  
52 - @Setter  
53 - private BpmUserGroupService userGroupService;  
54 -  
55 - @Setter  
56 - private DeptApi deptApi;  
57 - @Setter  
58 - private AdminUserApi adminUserApi;  
59 - @Setter  
60 - private PermissionApi permissionApi;  
61 -  
62 - /**  
63 - * 任务分配脚本  
64 - */  
65 - private Map<Long, BpmTaskAssignScript> scriptMap = Collections.emptyMap();  
66 -  
67 - public BpmUserTaskActivityBehavior(UserTask userTask) {  
68 - super(userTask);  
69 - }  
70 -  
71 - public void setScripts(List<BpmTaskAssignScript> scripts) {  
72 - this.scriptMap = convertMap(scripts, script -> script.getEnum().getId());  
73 - }  
74 -  
75 - @Override  
76 - protected void handleAssignments(TaskEntityManager taskEntityManager,  
77 - String assignee, String owner, List<String> candidateUsers, List<String> candidateGroups,  
78 - TaskEntity task, ExpressionManager expressionManager, DelegateExecution execution) {  
79 - // 第一步,获得任务的规则  
80 - BpmTaskAssignRuleDO rule = getTaskRule(task);  
81 - // 第二步,获得任务的候选用户们  
82 - Set<Long> candidateUserIds = calculateTaskCandidateUsers(task, rule);  
83 - // 第三步,设置一个作为负责人  
84 - Long assigneeUserId = chooseTaskAssignee(candidateUserIds);  
85 - taskEntityManager.changeTaskAssignee(task, String.valueOf(assigneeUserId));  
86 - }  
87 -  
88 - private BpmTaskAssignRuleDO getTaskRule(TaskEntity task) {  
89 - List<BpmTaskAssignRuleDO> taskRules = bpmTaskRuleService.getTaskAssignRuleListByProcessDefinitionId(task.getProcessDefinitionId(),  
90 - task.getTaskDefinitionKey());  
91 - if (CollUtil.isEmpty(taskRules)) {  
92 - throw new ActivitiException(StrUtil.format("流程任务({}/{}/{}) 找不到符合的任务规则",  
93 - task.getId(), task.getProcessDefinitionId(), task.getTaskDefinitionKey()));  
94 - }  
95 - if (taskRules.size() > 1) {  
96 - throw new ActivitiException(StrUtil.format("流程任务({}/{}/{}) 找到过多任务规则({})",  
97 - task.getId(), task.getProcessDefinitionId(), task.getTaskDefinitionKey(), taskRules.size()));  
98 - }  
99 - return taskRules.get(0);  
100 - }  
101 -  
102 - private Long chooseTaskAssignee(Set<Long> candidateUserIds) {  
103 - // TODO 芋艿:未来可以优化下,改成轮询的策略  
104 - int index = RandomUtil.randomInt(candidateUserIds.size());  
105 - return CollUtil.get(candidateUserIds, index);  
106 - }  
107 -  
108 - @VisibleForTesting  
109 - Set<Long> calculateTaskCandidateUsers(TaskEntity task, BpmTaskAssignRuleDO rule) {  
110 - Set<Long> assigneeUserIds = null;  
111 - if (Objects.equals(BpmTaskAssignRuleTypeEnum.ROLE.getType(), rule.getType())) {  
112 - assigneeUserIds = calculateTaskCandidateUsersByRole(task, rule);  
113 - } else if (Objects.equals(BpmTaskAssignRuleTypeEnum.DEPT_MEMBER.getType(), rule.getType())) {  
114 - assigneeUserIds = calculateTaskCandidateUsersByDeptMember(task, rule);  
115 - } else if (Objects.equals(BpmTaskAssignRuleTypeEnum.DEPT_LEADER.getType(), rule.getType())) {  
116 - assigneeUserIds = calculateTaskCandidateUsersByDeptLeader(task, rule);  
117 - } else if (Objects.equals(BpmTaskAssignRuleTypeEnum.POST.getType(), rule.getType())) {  
118 - assigneeUserIds = calculateTaskCandidateUsersByPost(task, rule);  
119 - } else if (Objects.equals(BpmTaskAssignRuleTypeEnum.USER.getType(), rule.getType())) {  
120 - assigneeUserIds = calculateTaskCandidateUsersByUser(task, rule);  
121 - } else if (Objects.equals(BpmTaskAssignRuleTypeEnum.USER_GROUP.getType(), rule.getType())) {  
122 - assigneeUserIds = calculateTaskCandidateUsersByUserGroup(task, rule);  
123 - } else if (Objects.equals(BpmTaskAssignRuleTypeEnum.SCRIPT.getType(), rule.getType())) {  
124 - assigneeUserIds = calculateTaskCandidateUsersByScript(task, rule);  
125 - }  
126 -  
127 - // 移除被禁用的用户  
128 - removeDisableUsers(assigneeUserIds);  
129 - // 如果候选人为空,抛出异常 TODO 芋艿:没候选人的策略选择。1 - 挂起;2 - 直接结束;3 - 强制一个兜底人  
130 - if (CollUtil.isEmpty(assigneeUserIds)) {  
131 - log.error("[calculateTaskCandidateUsers][流程任务({}/{}/{}) 任务规则({}) 找不到候选人]",  
132 - task.getId(), task.getProcessDefinitionId(), task.getTaskDefinitionKey(), toJsonString(rule));  
133 - throw exception(TASK_CREATE_FAIL_NO_CANDIDATE_USER);  
134 - }  
135 - return assigneeUserIds;  
136 - }  
137 -  
138 - private Set<Long> calculateTaskCandidateUsersByRole(TaskEntity task, BpmTaskAssignRuleDO rule) {  
139 - return permissionApi.getUserRoleIdListByRoleIds(rule.getOptions());  
140 - }  
141 -  
142 - private Set<Long> calculateTaskCandidateUsersByDeptMember(TaskEntity task, BpmTaskAssignRuleDO rule) {  
143 - List<AdminUserRespDTO> users = adminUserApi.getUsersByDeptIds(rule.getOptions());  
144 - return convertSet(users, AdminUserRespDTO::getId);  
145 - }  
146 -  
147 - private Set<Long> calculateTaskCandidateUsersByDeptLeader(TaskEntity task, BpmTaskAssignRuleDO rule) {  
148 - List<DeptRespDTO> depts = deptApi.getDepts(rule.getOptions());  
149 - return convertSet(depts, DeptRespDTO::getLeaderUserId);  
150 - }  
151 -  
152 - private Set<Long> calculateTaskCandidateUsersByPost(TaskEntity task, BpmTaskAssignRuleDO rule) {  
153 - List<AdminUserRespDTO> users = adminUserApi.getUsersByPostIds(rule.getOptions());  
154 - return convertSet(users, AdminUserRespDTO::getId);  
155 - }  
156 -  
157 - private Set<Long> calculateTaskCandidateUsersByUser(TaskEntity task, BpmTaskAssignRuleDO rule) {  
158 - return rule.getOptions();  
159 - }  
160 -  
161 - private Set<Long> calculateTaskCandidateUsersByUserGroup(TaskEntity task, BpmTaskAssignRuleDO rule) {  
162 - List<BpmUserGroupDO> userGroups = userGroupService.getUserGroupList(rule.getOptions());  
163 - Set<Long> userIds = new HashSet<>();  
164 - userGroups.forEach(group -> userIds.addAll(group.getMemberUserIds()));  
165 - return userIds;  
166 - }  
167 -  
168 - private Set<Long> calculateTaskCandidateUsersByScript(TaskEntity task, BpmTaskAssignRuleDO rule) {  
169 - // 获得对应的脚本  
170 - List<BpmTaskAssignScript> scripts = new ArrayList<>(rule.getOptions().size());  
171 - rule.getOptions().forEach(id -> {  
172 - BpmTaskAssignScript script = scriptMap.get(id);  
173 - if (script == null) {  
174 - throw exception(TASK_ASSIGN_SCRIPT_NOT_EXISTS, id);  
175 - }  
176 - scripts.add(script);  
177 - });  
178 - // 逐个计算任务  
179 - Set<Long> userIds = new HashSet<>();  
180 - scripts.forEach(script -> CollUtil.addAll(userIds, script.calculateTaskCandidateUsers(task)));  
181 - return userIds;  
182 - }  
183 -  
184 - @VisibleForTesting  
185 - void removeDisableUsers(Set<Long> assigneeUserIds) {  
186 - if (CollUtil.isEmpty(assigneeUserIds)) {  
187 - return;  
188 - }  
189 - Map<Long, AdminUserRespDTO> userMap = adminUserApi.getUserMap(assigneeUserIds);  
190 - assigneeUserIds.removeIf(id -> {  
191 - AdminUserRespDTO user = userMap.get(id);  
192 - return user == null || !CommonStatusEnum.ENABLE.getStatus().equals(user.getStatus());  
193 - });  
194 - }  
195 -  
196 -}  
yudao-module-bpm/yudao-module-bpm-biz-activiti/src/main/java/cn/iocoder/yudao/module/bpm/framework/activiti/core/behavior/package-info.java deleted
1 -/**  
2 - * 拓展 {@link org.activiti.engine.impl.bpmn.behavior.UserTaskActivityBehavior} 实现,基于 {@link cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmTaskAssignRuleDO} 实现自定义的任务分配规则。  
3 - * 原因:BPMN 默认的 assign、candidateUsers、candidateGroups 拓展起来有一定的难度,所以选择放弃它们,使用自己定义的规则。  
4 - *  
5 - * @author 芋道源码  
6 - */  
7 -package cn.iocoder.yudao.module.bpm.framework.activiti.core.behavior;  
yudao-module-bpm/yudao-module-bpm-biz-activiti/src/main/java/cn/iocoder/yudao/module/bpm/framework/activiti/core/behavior/script/BpmTaskAssignScript.java deleted
1 -package cn.iocoder.yudao.module.bpm.framework.activiti.core.behavior.script;  
2 -  
3 -import cn.iocoder.yudao.module.bpm.enums.definition.BpmTaskRuleScriptEnum;  
4 -import org.activiti.engine.impl.persistence.entity.TaskEntity;  
5 -  
6 -import java.util.Set;  
7 -  
8 -/**  
9 - * Bpm 任务分配的自定义 Script 脚本  
10 - * 使用场景:  
11 - * 1. 设置审批人为发起人  
12 - * 2. 设置审批人为发起人的 Leader  
13 - * 3. 甚至审批人为发起人的 Leader 的 Leader  
14 - *  
15 - * @author 芋道源码  
16 - */  
17 -public interface BpmTaskAssignScript {  
18 -  
19 - /**  
20 - * 基于流程任务,获得任务的候选用户们  
21 - *  
22 - * @param task 任务  
23 - * @return 候选人用户的编号数组  
24 - */  
25 - Set<Long> calculateTaskCandidateUsers(TaskEntity task);  
26 -  
27 - /**  
28 - * 获得枚举值  
29 - *  
30 - * @return 枚举值  
31 - */  
32 - BpmTaskRuleScriptEnum getEnum();  
33 -  
34 -}  
yudao-module-bpm/yudao-module-bpm-biz-activiti/src/main/java/cn/iocoder/yudao/module/bpm/framework/activiti/core/behavior/script/impl/BpmTaskAssignLeaderAbstractScript.java deleted
1 -package cn.iocoder.yudao.module.bpm.framework.activiti.core.behavior.script.impl;  
2 -  
3 -import cn.iocoder.yudao.module.bpm.framework.activiti.core.behavior.script.BpmTaskAssignScript;  
4 -  
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.activiti.engine.impl.persistence.entity.TaskEntity;  
10 -import org.springframework.util.Assert;  
11 -  
12 -import javax.annotation.Resource;  
13 -import java.util.Set;  
14 -  
15 -import static cn.iocoder.yudao.framework.common.util.collection.SetUtils.asSet;  
16 -import static java.util.Collections.emptySet;  
17 -  
18 -/**  
19 - * 分配给发起人的 Leader 审批的 Script 实现类  
20 - * 目前 Leader 的定义是,  
21 - *  
22 - * @author 芋道源码  
23 - */  
24 -public abstract class BpmTaskAssignLeaderAbstractScript implements BpmTaskAssignScript {  
25 -  
26 - @Resource  
27 - private AdminUserApi adminUserApi;  
28 - @Resource  
29 - private DeptApi deptApi;  
30 -  
31 - protected Set<Long> calculateTaskCandidateUsers(TaskEntity task, int level) {  
32 - Assert.isTrue(level > 0, "level 必须大于 0");  
33 - // 获得发起人  
34 - Long startUserId = Long.parseLong(task.getProcessInstance().getStartUserId());  
35 - // 获得对应 leve 的部门  
36 - DeptRespDTO dept = null;  
37 - for (int i = 0; i < level; i++) {  
38 - // 获得 level 对应的部门  
39 - if (dept == null) {  
40 - dept = getStartUserDept(startUserId);  
41 - if (dept == null) { // 找不到发起人的部门,所以无法使用该规则  
42 - return emptySet();  
43 - }  
44 - } else {  
45 - DeptRespDTO parentDept = deptApi.getDept(dept.getParentId());  
46 - if (parentDept == null) { // 找不到父级部门,所以只好结束寻找。原因是:例如说,级别比较高的人,所在部门层级比较少  
47 - break;  
48 - }  
49 - dept = parentDept;  
50 - }  
51 - }  
52 - return dept.getLeaderUserId() != null ? asSet(dept.getLeaderUserId()) : emptySet();  
53 - }  
54 -  
55 - private DeptRespDTO getStartUserDept(Long startUserId) {  
56 - AdminUserRespDTO startUser = adminUserApi.getUser(startUserId);  
57 - if (startUser.getDeptId() == null) { // 找不到部门,所以无法使用该规则  
58 - return null;  
59 - }  
60 - return deptApi.getDept(startUser.getDeptId());  
61 - }  
62 -  
63 -}  
yudao-module-bpm/yudao-module-bpm-biz-activiti/src/main/java/cn/iocoder/yudao/module/bpm/framework/activiti/core/behavior/script/impl/BpmTaskAssignLeaderX1Script.java deleted
1 -package cn.iocoder.yudao.module.bpm.framework.activiti.core.behavior.script.impl;  
2 -  
3 -import cn.iocoder.yudao.framework.datapermission.core.annotation.DataPermission;  
4 -import cn.iocoder.yudao.module.bpm.enums.definition.BpmTaskRuleScriptEnum;  
5 -import org.activiti.engine.impl.persistence.entity.TaskEntity;  
6 -import org.springframework.stereotype.Component;  
7 -  
8 -import java.util.Set;  
9 -  
10 -/**  
11 - * 分配给发起人的一级 Leader 审批的 Script 实现类  
12 - *  
13 - * @author 芋道源码  
14 - */  
15 -@Component  
16 -public class BpmTaskAssignLeaderX1Script extends BpmTaskAssignLeaderAbstractScript {  
17 -  
18 - @Override  
19 - @DataPermission(enable = false) // 不需要处理数据权限, 不然会有问题,查询不到数据  
20 - public Set<Long> calculateTaskCandidateUsers(TaskEntity task) {  
21 - return calculateTaskCandidateUsers(task, 1);  
22 - }  
23 -  
24 - @Override  
25 - public BpmTaskRuleScriptEnum getEnum() {  
26 - return BpmTaskRuleScriptEnum.LEADER_X1;  
27 - }  
28 -  
29 -}  
yudao-module-bpm/yudao-module-bpm-biz-activiti/src/main/java/cn/iocoder/yudao/module/bpm/framework/activiti/core/behavior/script/impl/BpmTaskAssignLeaderX2Script.java deleted
1 -package cn.iocoder.yudao.module.bpm.framework.activiti.core.behavior.script.impl;  
2 -  
3 -import cn.iocoder.yudao.framework.datapermission.core.annotation.DataPermission;  
4 -import cn.iocoder.yudao.module.bpm.enums.definition.BpmTaskRuleScriptEnum;  
5 -import org.activiti.engine.impl.persistence.entity.TaskEntity;  
6 -import org.springframework.stereotype.Component;  
7 -  
8 -import java.util.Set;  
9 -  
10 -/**  
11 - * 分配给发起人的二级 Leader 审批的 Script 实现类  
12 - *  
13 - * @author 芋道源码  
14 - */  
15 -@Component  
16 -public class BpmTaskAssignLeaderX2Script extends BpmTaskAssignLeaderAbstractScript {  
17 -  
18 - @Override  
19 - @DataPermission(enable = false) // 不需要处理数据权限, 不然会有问题,查询不到数据  
20 - public Set<Long> calculateTaskCandidateUsers(TaskEntity task) {  
21 - return calculateTaskCandidateUsers(task, 2);  
22 - }  
23 -  
24 - @Override  
25 - public BpmTaskRuleScriptEnum getEnum() {  
26 - return BpmTaskRuleScriptEnum.LEADER_X2;  
27 - }  
28 -  
29 -}  
yudao-module-bpm/yudao-module-bpm-biz-activiti/src/main/java/cn/iocoder/yudao/module/bpm/framework/activiti/core/behavior/script/impl/BpmTaskAssignStartUserScript.java deleted
1 -package cn.iocoder.yudao.module.bpm.framework.activiti.core.behavior.script.impl;  
2 -  
3 -import cn.iocoder.yudao.module.bpm.enums.definition.BpmTaskRuleScriptEnum;  
4 -import cn.iocoder.yudao.module.bpm.framework.activiti.core.behavior.script.BpmTaskAssignScript;  
5 -import cn.iocoder.yudao.framework.common.util.collection.SetUtils;  
6 -import org.activiti.engine.impl.persistence.entity.TaskEntity;  
7 -import org.springframework.stereotype.Component;  
8 -  
9 -import java.util.Set;  
10 -  
11 -/**  
12 - * 分配给发起人审批的 Script 实现类  
13 - *  
14 - * @author 芋道源码  
15 - */  
16 -@Component  
17 -public class BpmTaskAssignStartUserScript implements BpmTaskAssignScript {  
18 -  
19 - @Override  
20 - public Set<Long> calculateTaskCandidateUsers(TaskEntity task) {  
21 - Long userId = Long.parseLong(task.getProcessInstance().getStartUserId());  
22 - return SetUtils.asSet(userId);  
23 - }  
24 -  
25 - @Override  
26 - public BpmTaskRuleScriptEnum getEnum() {  
27 - return BpmTaskRuleScriptEnum.START_USER;  
28 - }  
29 -  
30 -}  
yudao-module-bpm/yudao-module-bpm-biz-activiti/src/main/java/cn/iocoder/yudao/module/bpm/framework/activiti/core/identity/EmptyUserGroupManager.java deleted
1 -package cn.iocoder.yudao.module.bpm.framework.activiti.core.identity;  
2 -  
3 -import org.activiti.api.runtime.shared.identity.UserGroupManager;  
4 -  
5 -import java.util.Collections;  
6 -import java.util.List;  
7 -  
8 -/**  
9 - * 空的 UserGroupManager 实现类,用于禁用 Activiti 自带的用户组实现。  
10 - * 原因是,我们使用了自己实现的任务分配规则,所以不需要 Activiti。  
11 - * 如果不去禁用,会存在一些场景下,会去查询用户所在的用户组,导致报错。  
12 - *  
13 - * @author 芋道源码  
14 - */  
15 -public class EmptyUserGroupManager implements UserGroupManager {  
16 -  
17 - @Override  
18 - public List<String> getUserGroups(String s) {  
19 - return Collections.emptyList();  
20 - }  
21 -  
22 - @Override  
23 - public List<String> getUserRoles(String s) {  
24 - return Collections.emptyList();  
25 - }  
26 -  
27 - @Override  
28 - public List<String> getGroups() {  
29 - return Collections.emptyList();  
30 - }  
31 -  
32 - @Override  
33 - public List<String> getUsers() {  
34 - return Collections.emptyList();  
35 - }  
36 -  
37 -}  
yudao-module-bpm/yudao-module-bpm-biz-activiti/src/main/java/cn/iocoder/yudao/module/bpm/framework/activiti/core/listener/BpmProcessInstanceEventListener.java deleted
1 -package cn.iocoder.yudao.module.bpm.framework.activiti.core.listener;  
2 -  
3 -import cn.iocoder.yudao.module.bpm.dal.dataobject.task.BpmProcessInstanceExtDO;  
4 -import cn.iocoder.yudao.module.bpm.service.task.BpmProcessInstanceService;  
5 -import org.activiti.api.model.shared.event.RuntimeEvent;  
6 -import org.activiti.api.process.model.ProcessInstance;  
7 -import org.activiti.api.process.model.events.ProcessRuntimeEvent;  
8 -import org.activiti.api.process.runtime.events.ProcessCancelledEvent;  
9 -import org.activiti.api.process.runtime.events.listener.ProcessRuntimeEventListener;  
10 -import org.springframework.context.annotation.Lazy;  
11 -import org.springframework.stereotype.Component;  
12 -  
13 -import javax.annotation.Resource;  
14 -  
15 -/**  
16 - * 监听 {@link ProcessInstance} 的开始与完成,创建与更新对应的 {@link BpmProcessInstanceExtDO} 记录  
17 - *  
18 - * @author 芋道源码  
19 - */  
20 -@Component  
21 -public class BpmProcessInstanceEventListener<T extends RuntimeEvent<?, ?>>  
22 - implements ProcessRuntimeEventListener<T> {  
23 -  
24 - @Resource  
25 - @Lazy // 解决循环依赖  
26 - private BpmProcessInstanceService processInstanceService;  
27 -  
28 - @Override  
29 - @SuppressWarnings("unchecked")  
30 - public void onEvent(T rawEvent) {  
31 - // 由于 ProcessRuntimeEventListener 无法保证只监听 ProcessRuntimeEvent 事件,所以通过这样的方式  
32 - if (!(rawEvent instanceof ProcessRuntimeEvent)) {  
33 - return;  
34 - }  
35 - ProcessRuntimeEvent<ProcessInstance> event = (ProcessRuntimeEvent<ProcessInstance>) rawEvent;  
36 -  
37 - // 创建时,插入拓展表  
38 - if (event.getEventType() == ProcessRuntimeEvent.ProcessEvents.PROCESS_CREATED) {  
39 - processInstanceService.createProcessInstanceExt(event.getEntity());  
40 - return;  
41 - }  
42 - // 取消时,更新拓展表为取消  
43 - if (event.getEventType() == ProcessRuntimeEvent.ProcessEvents.PROCESS_CANCELLED) {  
44 - processInstanceService.updateProcessInstanceExtCancel(event.getEntity(),  
45 - ((ProcessCancelledEvent) event).getCause());  
46 - return;  
47 - }  
48 - // 完成时,更新拓展表为已完成  
49 - if (event.getEventType() == ProcessRuntimeEvent.ProcessEvents.PROCESS_COMPLETED) {  
50 - processInstanceService.updateProcessInstanceExtComplete(event.getEntity());  
51 - return;  
52 - }  
53 -  
54 - // 其它事件,进行更新拓展表  
55 - processInstanceService.updateProcessInstanceExt(event.getEntity());  
56 - }  
57 -  
58 -}  
yudao-module-bpm/yudao-module-bpm-biz-activiti/src/main/java/cn/iocoder/yudao/module/bpm/framework/activiti/core/listener/BpmTackActivitiEventListener.java deleted
1 -package cn.iocoder.yudao.module.bpm.framework.activiti.core.listener;  
2 -  
3 -import cn.hutool.core.util.StrUtil;  
4 -import cn.iocoder.yudao.module.bpm.service.definition.BpmProcessDefinitionService;  
5 -import org.activiti.api.task.runtime.events.listener.TaskEventListener;  
6 -import org.activiti.engine.delegate.event.ActivitiEvent;  
7 -import org.activiti.engine.delegate.event.ActivitiEventListener;  
8 -import org.activiti.engine.delegate.event.ActivitiEventType;  
9 -import org.activiti.engine.delegate.event.impl.ActivitiEntityEventImpl;  
10 -import org.activiti.engine.impl.persistence.entity.TaskEntity;  
11 -import org.activiti.engine.repository.ProcessDefinition;  
12 -import org.springframework.context.annotation.Lazy;  
13 -import org.springframework.stereotype.Component;  
14 -  
15 -import javax.annotation.Resource;  
16 -  
17 -/**  
18 - * 监听 {@link TaskEntity} 相关的事件,设置相关属性。  
19 - * 目的:解决 {@link TaskEventListener} 无法解决的场景  
20 - *  
21 - * @author 芋道源码  
22 - */  
23 -@Component  
24 -public class BpmTackActivitiEventListener implements ActivitiEventListener {  
25 -  
26 - @Resource  
27 - @Lazy // 解决循环依赖  
28 - private BpmProcessDefinitionService processDefinitionService;  
29 -  
30 - @Override  
31 - public void onEvent(ActivitiEvent event) {  
32 - // Task 创建时,设置其分类,解决 TaskService 未提供 name 的设置方法  
33 - if (ActivitiEventType.TASK_CREATED == event.getType()) {  
34 - TaskEntity task = ((TaskEntity) ((ActivitiEntityEventImpl) event).getEntity());  
35 - if (StrUtil.isNotEmpty(task.getCategory())) {  
36 - return;  
37 - }  
38 - // 设置 name  
39 - ProcessDefinition processDefinition = processDefinitionService.getProcessDefinition2(task.getProcessDefinitionId());  
40 - if (processDefinition == null) {  
41 - return;  
42 - }  
43 - task.setCategory(processDefinition.getCategory());  
44 - }  
45 - }  
46 -  
47 - @Override  
48 - public boolean isFailOnException() {  
49 - return true;  
50 - }  
51 -  
52 -}  
yudao-module-bpm/yudao-module-bpm-biz-activiti/src/main/java/cn/iocoder/yudao/module/bpm/framework/activiti/core/listener/BpmTaskEventListener.java deleted
1 -package cn.iocoder.yudao.module.bpm.framework.activiti.core.listener;  
2 -  
3 -import cn.iocoder.yudao.module.bpm.dal.dataobject.task.BpmTaskExtDO;  
4 -import cn.iocoder.yudao.module.bpm.service.task.BpmTaskService;  
5 -import org.activiti.api.model.shared.event.RuntimeEvent;  
6 -import org.activiti.api.task.model.Task;  
7 -import org.activiti.api.task.model.events.TaskRuntimeEvent;  
8 -import org.activiti.api.task.runtime.events.listener.TaskRuntimeEventListener;  
9 -import org.springframework.context.annotation.Lazy;  
10 -import org.springframework.stereotype.Component;  
11 -  
12 -import javax.annotation.Resource;  
13 -  
14 -/**  
15 - * 监听 {@link Task} 的开始与完成,创建与更新对应的 {@link BpmTaskExtDO} 记录  
16 - *  
17 - * @author 芋道源码  
18 - */  
19 -@Component  
20 -public class BpmTaskEventListener<T extends RuntimeEvent<?, ?>>  
21 - implements TaskRuntimeEventListener<T> {  
22 -  
23 - @Resource  
24 - @Lazy // 解决循环依赖  
25 - private BpmTaskService taskService;  
26 -  
27 - @Override  
28 - @SuppressWarnings("unchecked")  
29 - public void onEvent(T rawEvent) {  
30 - // 由于 TaskRuntimeEventListener 无法保证只监听 TaskRuntimeEvent 事件,所以通过这样的方式  
31 - if (!(rawEvent instanceof TaskRuntimeEvent)) {  
32 - return;  
33 - }  
34 - TaskRuntimeEvent<Task> event = (TaskRuntimeEvent<Task>) rawEvent;  
35 -  
36 - // 创建时,插入拓展表  
37 - if (event.getEventType() == TaskRuntimeEvent.TaskEvents.TASK_CREATED) {  
38 - taskService.createTaskExt(event.getEntity());  
39 - return;  
40 - }  
41 -  
42 - // 取消时,更新拓展表为取消  
43 - if (event.getEventType() == TaskRuntimeEvent.TaskEvents.TASK_CANCELLED) {  
44 - taskService.updateTaskExtCancel(event.getEntity());  
45 - return;  
46 - }  
47 - // 完成时,更新拓展表为已完成。要注意,在调用 delete ProcessInstance 才会触发该逻辑  
48 - if (event.getEventType() == TaskRuntimeEvent.TaskEvents.TASK_COMPLETED) {  
49 - taskService.updateTaskExtComplete(event.getEntity());  
50 - return;  
51 - }  
52 -  
53 - // 审核人修改时,进行拓展表,并额外发送通知  
54 - if (event.getEventType() == TaskRuntimeEvent.TaskEvents.TASK_ASSIGNED) {  
55 - taskService.updateTaskExtAssign(event.getEntity());  
56 - return;  
57 - }  
58 -  
59 - // 其它事件,进行更新拓展表  
60 - taskService.updateTaskExt(event.getEntity());  
61 - }  
62 -  
63 -}  
yudao-module-bpm/yudao-module-bpm-biz-activiti/src/main/java/cn/iocoder/yudao/module/bpm/framework/activiti/core/listener/package-info.java deleted
1 -/**  
2 - * 自定义各种 Activiti 的监听器,实现流程示例、流程任务的拓展表信息的同步  
3 - * 例如说,{@link org.activiti.api.task.model.Task} 新建时,我们也要新建对应的 {@link cn.iocoder.yudao.module.bpm.dal.dataobject.task.BpmTaskExtDO} 记录  
4 - *  
5 - * @author 芋道源码  
6 - */  
7 -package cn.iocoder.yudao.module.bpm.framework.activiti.core.listener;  
yudao-module-bpm/yudao-module-bpm-biz-activiti/src/main/java/cn/iocoder/yudao/module/bpm/framework/package-info.java deleted
1 -/**  
2 - * 属于 bpm 模块的 framework 封装  
3 - *  
4 - * @author 芋道源码  
5 - */  
6 -package cn.iocoder.yudao.module.bpm.framework;  
yudao-module-bpm/yudao-module-bpm-biz-activiti/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmModelService.java deleted
1 -package cn.iocoder.yudao.module.bpm.service.definition;  
2 -  
3 -import cn.iocoder.yudao.framework.common.pojo.PageResult;  
4 -import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.model.*;  
5 -import org.activiti.bpmn.model.BpmnModel;  
6 -  
7 -import javax.validation.Valid;  
8 -  
9 -/**  
10 - * 流程模型接口  
11 - *  
12 - * @author yunlongn  
13 - */  
14 -public interface BpmModelService {  
15 - /**  
16 - * 获得流程模型分页  
17 - *  
18 - * @param pageVO 分页查询  
19 - * @return 流程模型分页  
20 - */  
21 - PageResult<BpmModelPageItemRespVO> getModelPage(BpmModelPageReqVO pageVO);  
22 -  
23 - /**  
24 - * 创建流程模型  
25 - *  
26 - * @param modelVO 创建信息  
27 - * @param bpmnXml BPMN XML  
28 - * @return 创建的流程模型的编号  
29 - */  
30 - String createModel(@Valid BpmModelCreateReqVO modelVO, String bpmnXml);  
31 -  
32 - /**  
33 - * 获得流程模块  
34 - *  
35 - * @param id 编号  
36 - * @return 流程模型  
37 - */  
38 - BpmModelRespVO getModel(String id);  
39 -  
40 - /**  
41 - * 修改流程模型  
42 - *  
43 - * @param updateReqVO 更新信息  
44 - */  
45 - void updateModel(@Valid BpmModelUpdateReqVO updateReqVO);  
46 -  
47 - /**  
48 - * 将流程模型,部署成一个流程定义  
49 - *  
50 - * @param id 编号  
51 - */  
52 - void deployModel(String id);  
53 -  
54 - /**  
55 - * 删除模型  
56 - *  
57 - * @param id 编号  
58 - */  
59 - void deleteModel(String id);  
60 -  
61 - /**  
62 - * 修改模型的状态,实际更新的部署的流程定义的状态  
63 - *  
64 - * @param id 编号  
65 - * @param state 状态  
66 - */  
67 - void updateModelState(String id, Integer state);  
68 -  
69 - /**  
70 - * 获得流程模型编号对应的 BPMN Model  
71 - *  
72 - * @param id 流程模型编号  
73 - * @return BPMN Model  
74 - */  
75 - BpmnModel getBpmnModel(String id);  
76 -  
77 -}  
yudao-module-bpm/yudao-module-bpm-biz-activiti/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmModelServiceImpl.java deleted
1 -package cn.iocoder.yudao.module.bpm.service.definition;  
2 -  
3 -import cn.hutool.core.collection.CollUtil;  
4 -import cn.hutool.core.util.ArrayUtil;  
5 -import cn.hutool.core.util.StrUtil;  
6 -import cn.iocoder.yudao.framework.common.util.validation.ValidationUtils;  
7 -import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.model.*;  
8 -import cn.iocoder.yudao.module.bpm.convert.definition.BpmModelConvert;  
9 -import cn.iocoder.yudao.module.bpm.enums.definition.BpmModelFormTypeEnum;  
10 -import cn.iocoder.yudao.module.bpm.service.definition.dto.BpmModelMetaInfoRespDTO;  
11 -import cn.iocoder.yudao.framework.activiti.core.util.ActivitiUtils;  
12 -import cn.iocoder.yudao.framework.common.pojo.PageResult;  
13 -import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;  
14 -import cn.iocoder.yudao.framework.common.util.json.JsonUtils;  
15 -import cn.iocoder.yudao.framework.common.util.object.PageUtils;  
16 -import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.rule.BpmTaskAssignRuleRespVO;  
17 -import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmFormDO;  
18 -import cn.iocoder.yudao.module.bpm.service.definition.dto.BpmProcessDefinitionCreateReqDTO;  
19 -import lombok.extern.slf4j.Slf4j;  
20 -import org.activiti.bpmn.model.BpmnModel;  
21 -import org.activiti.engine.RepositoryService;  
22 -import org.activiti.engine.impl.persistence.entity.SuspensionState;  
23 -import org.activiti.engine.repository.Deployment;  
24 -import org.activiti.engine.repository.Model;  
25 -import org.activiti.engine.repository.ModelQuery;  
26 -import org.activiti.engine.repository.ProcessDefinition;  
27 -import org.springframework.context.annotation.Lazy;  
28 -import org.springframework.stereotype.Service;  
29 -import org.springframework.transaction.annotation.Transactional;  
30 -import org.springframework.util.ObjectUtils;  
31 -import org.springframework.validation.annotation.Validated;  
32 -  
33 -import javax.annotation.Resource;  
34 -import java.util.*;  
35 -  
36 -import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;  
37 -import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap;  
38 -import static cn.iocoder.yudao.module.bpm.enums.ErrorCodeConstants.*;  
39 -  
40 -/**  
41 - * 流程定义实现  
42 - * 主要进行 Activiti {@link Model} 的维护  
43 - *  
44 - * @author yunlongn  
45 - * @author 芋道源码  
46 - */  
47 -@Service  
48 -@Validated  
49 -@Slf4j  
50 -public class BpmModelServiceImpl implements BpmModelService {  
51 -  
52 - @Resource  
53 - private RepositoryService repositoryService;  
54 - @Resource  
55 - private BpmProcessDefinitionService processDefinitionService;  
56 - @Resource  
57 - private BpmFormService bpmFormService;  
58 - @Resource  
59 - private BpmTaskAssignRuleService taskAssignRuleService;  
60 -  
61 - @Override  
62 - public PageResult<BpmModelPageItemRespVO> getModelPage(BpmModelPageReqVO pageVO) {  
63 - ModelQuery modelQuery = repositoryService.createModelQuery();  
64 - if (StrUtil.isNotBlank(pageVO.getKey())) {  
65 - modelQuery.modelKey(pageVO.getKey());  
66 - }  
67 - if (StrUtil.isNotBlank(pageVO.getName())) {  
68 - modelQuery.modelNameLike("%" + pageVO.getName() + "%"); // 模糊匹配  
69 - }  
70 - if (StrUtil.isNotBlank(pageVO.getCategory())) {  
71 - modelQuery.modelCategory(pageVO.getCategory());  
72 - }  
73 - // 执行查询  
74 - List<Model> models = modelQuery.orderByCreateTime().desc()  
75 - .listPage(PageUtils.getStart(pageVO), pageVO.getPageSize());  
76 -  
77 - // 获得 Form Map  
78 - Set<Long> formIds = CollectionUtils.convertSet(models, model -> {  
79 - BpmModelMetaInfoRespDTO metaInfo = JsonUtils.parseObject(model.getMetaInfo(), BpmModelMetaInfoRespDTO.class);  
80 - return metaInfo != null ? metaInfo.getFormId() : null;  
81 - });  
82 - Map<Long, BpmFormDO> formMap = bpmFormService.getFormMap(formIds);  
83 -  
84 - // 获得 Deployment Map  
85 - Set<String> deploymentIds = new HashSet<>();  
86 - models.forEach(model -> CollectionUtils.addIfNotNull(deploymentIds, model.getDeploymentId()));  
87 - Map<String, Deployment> deploymentMap = processDefinitionService.getDeploymentMap(deploymentIds);  
88 - // 获得 ProcessDefinition Map  
89 - List<ProcessDefinition> processDefinitions = processDefinitionService.getProcessDefinitionListByDeploymentIds(deploymentIds);  
90 - Map<String, ProcessDefinition> processDefinitionMap = convertMap(processDefinitions, ProcessDefinition::getDeploymentId);  
91 -  
92 - // 拼接结果  
93 - long modelCount = modelQuery.count();  
94 - return new PageResult<>(BpmModelConvert.INSTANCE.convertList(models, formMap, deploymentMap, processDefinitionMap), modelCount);  
95 - }  
96 -  
97 - @Override  
98 - public BpmModelRespVO getModel(String id) {  
99 - Model model = repositoryService.getModel(id);  
100 - if (model == null) {  
101 - return null;  
102 - }  
103 - BpmModelRespVO modelRespVO = BpmModelConvert.INSTANCE.convert(model);  
104 - // 拼接 bpmn XML  
105 - byte[] bpmnBytes = repositoryService.getModelEditorSource(id);  
106 - modelRespVO.setBpmnXml(StrUtil.utf8Str(bpmnBytes));  
107 - return modelRespVO;  
108 - }  
109 -  
110 - @Override  
111 - @Transactional(rollbackFor = Exception.class) // 因为进行多个 activiti 操作,所以开启事务  
112 - public String createModel(BpmModelCreateReqVO createReqVO, String bpmnXml) {  
113 - checkKeyNCName(createReqVO.getKey());  
114 - // 校验流程标识已经存在  
115 - Model keyModel = this.getModelByKey(createReqVO.getKey());  
116 - if (keyModel != null) {  
117 - throw exception(MODEL_KEY_EXISTS, createReqVO.getKey());  
118 - }  
119 -  
120 - // 创建流程定义  
121 - Model model = repositoryService.newModel();  
122 - BpmModelConvert.INSTANCE.copy(model, createReqVO);  
123 - // 保存流程定义  
124 - repositoryService.saveModel(model);  
125 - // 保存 BPMN XML  
126 - saveModelBpmnXml(model, bpmnXml);  
127 - return model.getId();  
128 - }  
129 -  
130 - @Override  
131 - @Transactional(rollbackFor = Exception.class) // 因为进行多个 activiti 操作,所以开启事务  
132 - public void updateModel(BpmModelUpdateReqVO updateReqVO) {  
133 - // 校验流程模型存在  
134 - Model model = repositoryService.getModel(updateReqVO.getId());  
135 - if (model == null) {  
136 - throw exception(MODEL_NOT_EXISTS);  
137 - }  
138 -  
139 - // 修改流程定义  
140 - BpmModelConvert.INSTANCE.copy(model, updateReqVO);  
141 - // 更新模型  
142 - repositoryService.saveModel(model);  
143 - // 更新 BPMN XML  
144 - saveModelBpmnXml(model, updateReqVO.getBpmnXml());  
145 - }  
146 -  
147 - private void saveModelBpmnXml(Model model, String bpmnXml) {  
148 - if (StrUtil.isEmpty(bpmnXml)) {  
149 - return;  
150 - }  
151 - repositoryService.addModelEditorSource(model.getId(), StrUtil.utf8Bytes(bpmnXml));  
152 - }  
153 -  
154 - @Override  
155 - @Transactional(rollbackFor = Exception.class) // 因为进行多个 activiti 操作,所以开启事务  
156 - public void deployModel(String id) {  
157 - // 校验流程模型存在  
158 - Model model = repositoryService.getModel(id);  
159 - if (ObjectUtils.isEmpty(model)) {  
160 - throw exception(MODEL_NOT_EXISTS);  
161 - }  
162 - // 校验流程图  
163 - byte[] bpmnBytes = repositoryService.getModelEditorSource(model.getId());  
164 - if (bpmnBytes == null) {  
165 - throw exception(MODEL_NOT_EXISTS);  
166 - }  
167 - // TODO 芋艿:校验流程图的有效性;例如说,是否有开始的元素,是否有结束的元素;  
168 - // 校验表单已配  
169 - BpmFormDO form = checkFormConfig(model.getMetaInfo());  
170 - // 校验任务分配规则已配置  
171 - taskAssignRuleService.checkTaskAssignRuleAllConfig(id);  
172 -  
173 - // 校验模型是否发生修改。如果未修改,则不允许创建  
174 - BpmProcessDefinitionCreateReqDTO definitionCreateReqDTO = BpmModelConvert.INSTANCE.convert2(model, form).setBpmnBytes(bpmnBytes);  
175 - if (processDefinitionService.isProcessDefinitionEquals(definitionCreateReqDTO)) { // 流程定义的信息相等  
176 - ProcessDefinition oldProcessInstance = processDefinitionService.getProcessDefinitionByDeploymentId(model.getDeploymentId());  
177 - if (oldProcessInstance != null && taskAssignRuleService.isTaskAssignRulesEquals(model.getId(), oldProcessInstance.getId())) {  
178 - throw exception(MODEL_DEPLOY_FAIL_TASK_INFO_EQUALS);  
179 - }  
180 - }  
181 - // 创建流程定义  
182 - String definitionId = processDefinitionService.createProcessDefinition(definitionCreateReqDTO);  
183 -  
184 - // 将老的流程定义进行挂起。也就是说,只有最新部署的流程定义,才可以发起任务。  
185 - updateProcessDefinitionSuspended(model.getDeploymentId());  
186 -  
187 - // 更新 model 的 deploymentId,进行关联  
188 - ProcessDefinition definition = processDefinitionService.getProcessDefinition(definitionId);  
189 - model.setDeploymentId(definition.getDeploymentId());  
190 - repositoryService.saveModel(model);  
191 -  
192 - // 复制任务分配规则  
193 - taskAssignRuleService.copyTaskAssignRules(id, definition.getId());  
194 - }  
195 -  
196 - @Override  
197 - @Transactional(rollbackFor = Exception.class)  
198 - public void deleteModel(String id) {  
199 - // 校验流程模型存在  
200 - Model model = repositoryService.getModel(id);  
201 - if (model == null) {  
202 - throw exception(MODEL_NOT_EXISTS);  
203 - }  
204 - // 执行删除  
205 - repositoryService.deleteModel(id);  
206 - // 禁用流程实例  
207 - updateProcessDefinitionSuspended(model.getDeploymentId());  
208 - }  
209 -  
210 - private void updateProcessDefinitionSuspended(String deploymentId) {  
211 - if (StrUtil.isEmpty(deploymentId)) {  
212 - return;  
213 - }  
214 - ProcessDefinition oldDefinition = processDefinitionService.getProcessDefinitionByDeploymentId(deploymentId);  
215 - if (oldDefinition == null) {  
216 - return;  
217 - }  
218 - if(oldDefinition.isSuspended()) {  
219 - return;  
220 - }  
221 - processDefinitionService.updateProcessDefinitionState(oldDefinition.getId(), SuspensionState.SUSPENDED.getStateCode());  
222 - }  
223 -  
224 - @Override  
225 - public void updateModelState(String id, Integer state) {  
226 - // 校验流程模型存在  
227 - Model model = repositoryService.getModel(id);  
228 - if (model == null) {  
229 - throw exception(MODEL_NOT_EXISTS);  
230 - }  
231 - // 校验流程定义存在  
232 - ProcessDefinition definition = processDefinitionService.getProcessDefinitionByDeploymentId(model.getDeploymentId());  
233 - if (definition == null) {  
234 - throw exception(PROCESS_DEFINITION_NOT_EXISTS);  
235 - }  
236 -  
237 - // 更新状态  
238 - processDefinitionService.updateProcessDefinitionState(definition.getId(), state);  
239 - }  
240 -  
241 - @Override  
242 - public BpmnModel getBpmnModel(String id) {  
243 - byte[] bpmnBytes = repositoryService.getModelEditorSource(id);  
244 - if (ArrayUtil.isEmpty(bpmnBytes)) {  
245 - return null;  
246 - }  
247 - return ActivitiUtils.buildBpmnModel(bpmnBytes);  
248 - }  
249 -  
250 - private Model getModelByKey(String key) {  
251 - return repositoryService.createModelQuery().modelKey(key).singleResult();  
252 - }  
253 -  
254 - private void checkKeyNCName(String key) {  
255 - if (!ValidationUtils.isXmlNCName(key)) {  
256 - throw exception(MODEL_KEY_VALID);  
257 - }  
258 - }  
259 -  
260 - /**  
261 - * 校验流程表单已配置  
262 - *  
263 - * @param metaInfoStr 流程模型 metaInfo 字段  
264 - * @return 流程表单  
265 - */  
266 - private BpmFormDO checkFormConfig(String metaInfoStr) {  
267 - BpmModelMetaInfoRespDTO metaInfo = JsonUtils.parseObject(metaInfoStr, BpmModelMetaInfoRespDTO.class);  
268 - if (metaInfo == null || metaInfo.getFormType() == null) {  
269 - throw exception(MODEL_DEPLOY_FAIL_FORM_NOT_CONFIG);  
270 - }  
271 - // 校验表单存在  
272 - if (Objects.equals(metaInfo.getFormType(), BpmModelFormTypeEnum.NORMAL.getType())) {  
273 - BpmFormDO form = bpmFormService.getForm(metaInfo.getFormId());  
274 - if (form == null) {  
275 - throw exception(FORM_NOT_EXISTS);  
276 - }  
277 - return form;  
278 - }  
279 - return null;  
280 - }  
281 -  
282 -}  
yudao-module-bpm/yudao-module-bpm-biz-activiti/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmProcessDefinitionService.java deleted
1 -package cn.iocoder.yudao.module.bpm.service.definition;  
2 -  
3 -import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.process.BpmProcessDefinitionListReqVO;  
4 -import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.process.BpmProcessDefinitionPageItemRespVO;  
5 -import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.process.BpmProcessDefinitionPageReqVO;  
6 -import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.process.BpmProcessDefinitionRespVO;  
7 -import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmProcessDefinitionExtDO;  
8 -import cn.iocoder.yudao.framework.common.pojo.PageResult;  
9 -import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;  
10 -import cn.iocoder.yudao.module.bpm.service.definition.dto.BpmProcessDefinitionCreateReqDTO;  
11 -import org.activiti.bpmn.model.BpmnModel;  
12 -import org.activiti.engine.repository.Deployment;  
13 -import org.activiti.engine.repository.ProcessDefinition;  
14 -  
15 -import javax.validation.Valid;  
16 -import java.util.List;  
17 -import java.util.Map;  
18 -import java.util.Set;  
19 -  
20 -/**  
21 - * 流程定义接口  
22 - *  
23 - * @author yunlong.li  
24 - * @author ZJQ  
25 - * @author 芋道源码  
26 - */  
27 -public interface BpmProcessDefinitionService {  
28 -  
29 - /**  
30 - * 获得流程定义分页  
31 - *  
32 - * @param pageReqVO 分页入参  
33 - * @return 流程定义 Page  
34 - */  
35 - PageResult<BpmProcessDefinitionPageItemRespVO> getProcessDefinitionPage(BpmProcessDefinitionPageReqVO pageReqVO);  
36 -  
37 - /**  
38 - * 创建流程定义  
39 - *  
40 - * @param createReqDTO 创建信息  
41 - * @return 流程编号  
42 - */  
43 - String createProcessDefinition(@Valid BpmProcessDefinitionCreateReqDTO createReqDTO);  
44 -  
45 - /**  
46 - * 更新流程定义状态  
47 - *  
48 - * @param id 流程定义的编号  
49 - * @param state 状态  
50 - */  
51 - void updateProcessDefinitionState(String id, Integer state);  
52 -  
53 - /**  
54 - * 获得流程定义对应的 BPMN XML  
55 - *  
56 - * @param id 流程定义编号  
57 - * @return BPMN XML  
58 - */  
59 - String getProcessDefinitionBpmnXML(String id);  
60 -  
61 - /**  
62 - * 获得需要创建的流程定义,是否和当前激活的流程定义相等  
63 - *  
64 - * @param createReqDTO 创建信息  
65 - * @return 是否相等  
66 - */  
67 - boolean isProcessDefinitionEquals(@Valid BpmProcessDefinitionCreateReqDTO createReqDTO);  
68 -  
69 - /**  
70 - * 获得编号对应的 BpmProcessDefinitionExtDO  
71 - *  
72 - * @param id 编号  
73 - * @return 流程定义拓展  
74 - */  
75 - BpmProcessDefinitionExtDO getProcessDefinitionExt(String id);  
76 -  
77 - /**  
78 - * 获得流程定义列表  
79 - *  
80 - * @param listReqVO 列表入参  
81 - * @return 流程定义列表  
82 - */  
83 - List<BpmProcessDefinitionRespVO> getProcessDefinitionList(BpmProcessDefinitionListReqVO listReqVO);  
84 -  
85 - /**  
86 - * 获得 Bpmn 模型  
87 - *  
88 - * @param processDefinitionId 流程定义的编号  
89 - * @return Bpmn 模型  
90 - */  
91 - BpmnModel getBpmnModel(String processDefinitionId);  
92 -  
93 - /**  
94 - * 获得编号对应的 ProcessDefinition  
95 - *  
96 - * @param id 编号  
97 - * @return 流程定义  
98 - */  
99 - ProcessDefinition getProcessDefinition(String id);  
100 -  
101 - /**  
102 - * 获得编号对应的 ProcessDefinition  
103 - *  
104 - * 相比 {@link #getProcessDefinition(String)} 方法,category 的取值是正确  
105 - *  
106 - * @param id 编号  
107 - * @return 流程定义  
108 - */  
109 - ProcessDefinition getProcessDefinition2(String id);  
110 -  
111 - /**  
112 - * 获得流程定义标识对应的激活的流程定义  
113 - *  
114 - * @param key 流程定义的标识  
115 - * @return 流程定义  
116 - */  
117 - ProcessDefinition getActiveProcessDefinition(String key);  
118 -  
119 - /**  
120 - * 获得 id 对应的 Deployment  
121 - *  
122 - * @param id 部署编号  
123 - * @return 流程部署  
124 - */  
125 - Deployment getDeployment(String id);  
126 -  
127 - /**  
128 - * 获得 ids 对应的 Deployment 数组  
129 - *  
130 - * @param ids 部署编号的数组  
131 - * @return 流程部署的数组  
132 - */  
133 - List<Deployment> getDeployments(Set<String> ids);  
134 -  
135 - /**  
136 - * 获得 ids 对应的 Deployment Map  
137 - *  
138 - * @param ids 部署编号的数组  
139 - * @return 流程部署 Map  
140 - */  
141 - default Map<String, Deployment> getDeploymentMap(Set<String> ids) {  
142 - return CollectionUtils.convertMap(getDeployments(ids), Deployment::getId);  
143 - }  
144 -  
145 - /**  
146 - * 获得 deploymentId 对应的 ProcessDefinition  
147 - *  
148 - * @param deploymentId 部署编号  
149 - * @return 流程定义  
150 - */  
151 - ProcessDefinition getProcessDefinitionByDeploymentId(String deploymentId);  
152 -  
153 - /**  
154 - * 获得 deploymentIds 对应的 ProcessDefinition 数组  
155 - *  
156 - * @param deploymentIds 部署编号的数组  
157 - * @return 流程定义的数组  
158 - */  
159 - List<ProcessDefinition> getProcessDefinitionListByDeploymentIds(Set<String> deploymentIds);  
160 -  
161 -}  
yudao-module-bpm/yudao-module-bpm-biz-activiti/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmProcessDefinitionServiceImpl.java deleted
1 -package cn.iocoder.yudao.module.bpm.service.definition;  
2 -  
3 -import cn.hutool.core.collection.CollUtil;  
4 -import cn.hutool.core.util.ObjectUtil;  
5 -import cn.hutool.core.util.StrUtil;  
6 -import cn.iocoder.yudao.module.bpm.convert.definition.BpmProcessDefinitionConvert;  
7 -import cn.iocoder.yudao.framework.activiti.core.util.ActivitiUtils;  
8 -import cn.iocoder.yudao.framework.common.pojo.PageResult;  
9 -import cn.iocoder.yudao.framework.common.util.object.PageUtils;  
10 -import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.process.BpmProcessDefinitionListReqVO;  
11 -import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.process.BpmProcessDefinitionPageItemRespVO;  
12 -import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.process.BpmProcessDefinitionPageReqVO;  
13 -import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.process.BpmProcessDefinitionRespVO;  
14 -import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmFormDO;  
15 -import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmProcessDefinitionExtDO;  
16 -import cn.iocoder.yudao.module.bpm.dal.mysql.definition.BpmProcessDefinitionExtMapper;  
17 -import cn.iocoder.yudao.module.bpm.service.definition.dto.BpmProcessDefinitionCreateReqDTO;  
18 -import lombok.extern.slf4j.Slf4j;  
19 -import org.activiti.bpmn.model.BpmnModel;  
20 -import org.activiti.engine.RepositoryService;  
21 -import org.activiti.engine.impl.persistence.entity.SuspensionState;  
22 -import org.activiti.engine.repository.Deployment;  
23 -import org.activiti.engine.repository.ProcessDefinition;  
24 -import org.activiti.engine.repository.ProcessDefinitionQuery;  
25 -import org.springframework.stereotype.Service;  
26 -import org.springframework.transaction.annotation.Transactional;  
27 -import org.springframework.validation.annotation.Validated;  
28 -  
29 -import javax.annotation.Resource;  
30 -import java.util.*;  
31 -  
32 -import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;  
33 -import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.*;  
34 -import static cn.iocoder.yudao.module.bpm.enums.ErrorCodeConstants.PROCESS_DEFINITION_KEY_NOT_MATCH;  
35 -import static cn.iocoder.yudao.module.bpm.enums.ErrorCodeConstants.PROCESS_DEFINITION_NAME_NOT_MATCH;  
36 -import static java.util.Collections.emptyList;  
37 -  
38 -/**  
39 - * 流程定义实现  
40 - * 主要进行 Activiti {@link ProcessDefinition} 和 {@link Deployment} 的维护  
41 - *  
42 - * @author yunlongn  
43 - * @author ZJQ  
44 - * @author 芋道源码  
45 - */  
46 -@Service  
47 -@Validated  
48 -@Slf4j  
49 -public class BpmProcessDefinitionServiceImpl implements BpmProcessDefinitionService {  
50 -  
51 - private static final String BPMN_FILE_SUFFIX = ".bpmn";  
52 -  
53 - @Resource  
54 - private RepositoryService repositoryService;  
55 - @Resource  
56 - private BpmFormService formService;  
57 -  
58 - @Resource  
59 - private BpmProcessDefinitionExtMapper processDefinitionMapper;  
60 -  
61 - @Override  
62 - public PageResult<BpmProcessDefinitionPageItemRespVO> getProcessDefinitionPage(BpmProcessDefinitionPageReqVO pageVO) {  
63 - ProcessDefinitionQuery definitionQuery = repositoryService.createProcessDefinitionQuery();  
64 - if (StrUtil.isNotBlank(pageVO.getKey())) {  
65 - definitionQuery.processDefinitionKey(pageVO.getKey());  
66 - }  
67 - // 执行查询  
68 - List<ProcessDefinition> processDefinitions = definitionQuery.orderByProcessDefinitionVersion().desc()  
69 - .listPage(PageUtils.getStart(pageVO), pageVO.getPageSize());  
70 - if (CollUtil.isEmpty(processDefinitions)) {  
71 - return new PageResult<>(emptyList(), definitionQuery.count());  
72 - }  
73 -  
74 - // 获得 Deployment Map  
75 - Set<String> deploymentIds = new HashSet<>();  
76 - processDefinitions.forEach(definition -> addIfNotNull(deploymentIds, definition.getDeploymentId()));  
77 - Map<String, Deployment> deploymentMap = getDeploymentMap(deploymentIds);  
78 -  
79 - // 获得 BpmProcessDefinitionDO Map  
80 - List<BpmProcessDefinitionExtDO> processDefinitionDOs = processDefinitionMapper.selectListByProcessDefinitionIds(  
81 - convertList(processDefinitions, ProcessDefinition::getId));  
82 - Map<String, BpmProcessDefinitionExtDO> processDefinitionDOMap = convertMap(processDefinitionDOs,  
83 - BpmProcessDefinitionExtDO::getProcessDefinitionId);  
84 -  
85 - // 获得 Form Map  
86 - Set<Long> formIds = convertSet(processDefinitionDOs, BpmProcessDefinitionExtDO::getFormId);  
87 - Map<Long, BpmFormDO> formMap = formService.getFormMap(formIds);  
88 -  
89 - // 拼接结果  
90 - long definitionCount = definitionQuery.count();  
91 - return new PageResult<>(BpmProcessDefinitionConvert.INSTANCE.convertList(processDefinitions, deploymentMap,  
92 - processDefinitionDOMap, formMap), definitionCount);  
93 - }  
94 -  
95 - @Override  
96 - public List<BpmProcessDefinitionRespVO> getProcessDefinitionList(BpmProcessDefinitionListReqVO listReqVO) {  
97 - // 拼接查询条件  
98 - ProcessDefinitionQuery definitionQuery = repositoryService.createProcessDefinitionQuery();  
99 - if (Objects.equals(SuspensionState.SUSPENDED.getStateCode(), listReqVO.getSuspensionState())) {  
100 - definitionQuery.suspended();  
101 - } else if (Objects.equals(SuspensionState.ACTIVE.getStateCode(), listReqVO.getSuspensionState())) {  
102 - definitionQuery.active();  
103 - }  
104 - // 执行查询  
105 - List<ProcessDefinition> processDefinitions = definitionQuery.list();  
106 - if (CollUtil.isEmpty(processDefinitions)) {  
107 - return Collections.emptyList();  
108 - }  
109 -  
110 - // 获得 BpmProcessDefinitionDO Map  
111 - List<BpmProcessDefinitionExtDO> processDefinitionDOs = processDefinitionMapper.selectListByProcessDefinitionIds(  
112 - convertList(processDefinitions, ProcessDefinition::getId));  
113 - Map<String, BpmProcessDefinitionExtDO> processDefinitionDOMap = convertMap(processDefinitionDOs,  
114 - BpmProcessDefinitionExtDO::getProcessDefinitionId);  
115 - // 执行查询,并返回  
116 - return BpmProcessDefinitionConvert.INSTANCE.convertList3(processDefinitions, processDefinitionDOMap);  
117 - }  
118 -  
119 - @Override  
120 - public String getProcessDefinitionBpmnXML(String id) {  
121 - BpmnModel bpmnModel = repositoryService.getBpmnModel(id);  
122 - if (bpmnModel == null) {  
123 - return null;  
124 - }  
125 - return ActivitiUtils.getBpmnXml(bpmnModel);  
126 - }  
127 -  
128 - @Override  
129 - public BpmnModel getBpmnModel(String processDefinitionId) {  
130 - return repositoryService.getBpmnModel(processDefinitionId);  
131 - }  
132 -  
133 - @Override  
134 - public ProcessDefinition getProcessDefinition(String id) {  
135 - return repositoryService.getProcessDefinition(id);  
136 - }  
137 -  
138 - @Override  
139 - public ProcessDefinition getProcessDefinition2(String id) {  
140 - return repositoryService.createProcessDefinitionQuery().processDefinitionId(id).singleResult();  
141 - }  
142 -  
143 - @Override  
144 - public ProcessDefinition getActiveProcessDefinition(String key) {  
145 - return repositoryService.createProcessDefinitionQuery().processDefinitionKey(key).active().singleResult();  
146 - }  
147 -  
148 - @Override  
149 - public BpmProcessDefinitionExtDO getProcessDefinitionExt(String id) {  
150 - return processDefinitionMapper.selectByProcessDefinitionId(id);  
151 - }  
152 -  
153 - @Override  
154 - public Deployment getDeployment(String id) {  
155 - if (StrUtil.isEmpty(id)) {  
156 - return null;  
157 - }  
158 - return repositoryService.createDeploymentQuery().deploymentId(id).singleResult();  
159 - }  
160 -  
161 - @Override  
162 - public List<Deployment> getDeployments(Set<String> ids) {  
163 - if (CollUtil.isEmpty(ids)) {  
164 - return emptyList();  
165 - }  
166 - List<Deployment> list = new ArrayList<>(ids.size());  
167 - for (String id : ids) {  
168 - addIfNotNull(list, getDeployment(id));  
169 - }  
170 - return list;  
171 - }  
172 -  
173 - @Override  
174 - public ProcessDefinition getProcessDefinitionByDeploymentId(String deploymentId) {  
175 - if (StrUtil.isEmpty(deploymentId)) {  
176 - return null;  
177 - }  
178 - return repositoryService.createProcessDefinitionQuery().deploymentId(deploymentId).singleResult();  
179 - }  
180 -  
181 - @Override  
182 - public List<ProcessDefinition> getProcessDefinitionListByDeploymentIds(Set<String> deploymentIds) {  
183 - if (CollUtil.isEmpty(deploymentIds)) {  
184 - return emptyList();  
185 - }  
186 - return repositoryService.createProcessDefinitionQuery().deploymentIds(deploymentIds).list();  
187 - }  
188 -  
189 - @Override  
190 - public boolean isProcessDefinitionEquals(BpmProcessDefinitionCreateReqDTO createReqDTO) {  
191 - // 校验 name、description 是否更新  
192 - ProcessDefinition oldProcessDefinition = getActiveProcessDefinition(createReqDTO.getKey());  
193 - if (oldProcessDefinition == null) {  
194 - return false;  
195 - }  
196 - BpmProcessDefinitionExtDO oldProcessDefinitionExt = getProcessDefinitionExt(oldProcessDefinition.getId());  
197 - if (!StrUtil.equals(createReqDTO.getName(), oldProcessDefinition.getName())  
198 - || !StrUtil.equals(createReqDTO.getDescription(), oldProcessDefinitionExt.getDescription())  
199 - || !StrUtil.equals(createReqDTO.getCategory(), oldProcessDefinition.getCategory())) {  
200 - return false;  
201 - }  
202 - // 校验 form 信息是否更新  
203 - if (!ObjectUtil.equal(createReqDTO.getFormType(), oldProcessDefinitionExt.getFormType())  
204 - || !ObjectUtil.equal(createReqDTO.getFormId(), oldProcessDefinitionExt.getFormId())  
205 - || !ObjectUtil.equal(createReqDTO.getFormConf(), oldProcessDefinitionExt.getFormConf())  
206 - || !ObjectUtil.equal(createReqDTO.getFormFields(), oldProcessDefinitionExt.getFormFields())  
207 - || !ObjectUtil.equal(createReqDTO.getFormCustomCreatePath(), oldProcessDefinitionExt.getFormCustomCreatePath())  
208 - || !ObjectUtil.equal(createReqDTO.getFormCustomViewPath(), oldProcessDefinitionExt.getFormCustomViewPath())) {  
209 - return false;  
210 - }  
211 - // 校验 BPMN XML 信息  
212 - BpmnModel newModel = ActivitiUtils.buildBpmnModel(createReqDTO.getBpmnBytes());  
213 - BpmnModel oldModel = getBpmnModel(oldProcessDefinition.getId());  
214 - if (!ActivitiUtils.equals(oldModel, newModel)) {  
215 - return false;  
216 - }  
217 - // 最终发现都一致,则返回 true  
218 - return true;  
219 - }  
220 -  
221 - @Override  
222 - @Transactional(rollbackFor = Exception.class) // 因为进行多个 activiti 操作,所以开启事务  
223 - public String createProcessDefinition(BpmProcessDefinitionCreateReqDTO createReqDTO) {  
224 - // 创建 Deployment 部署  
225 - Deployment deploy = repositoryService.createDeployment()  
226 - .key(createReqDTO.getKey()).name(createReqDTO.getName()).category(createReqDTO.getCategory())  
227 - .addBytes(createReqDTO.getKey() + BPMN_FILE_SUFFIX, createReqDTO.getBpmnBytes())  
228 - .deploy();  
229 -  
230 - // 设置 ProcessDefinition 的 category 分类  
231 - ProcessDefinition definition = repositoryService.createProcessDefinitionQuery().deploymentId(deploy.getId()).singleResult();  
232 - repositoryService.setProcessDefinitionCategory(definition.getId(), createReqDTO.getCategory());  
233 - // 注意 1,ProcessDefinition 的 key 和 name 是通过 BPMN 中的 <bpmn2:process /> 的 id 和 name 决定  
234 - // 注意 2,目前该项目的设计上,需要保证 Model、Deployment、ProcessDefinition 使用相同的 key,保证关联性。  
235 - // 否则,会导致 ProcessDefinition 的分页无法查询到。  
236 - if (!Objects.equals(definition.getKey(), createReqDTO.getKey())) {  
237 - throw exception(PROCESS_DEFINITION_KEY_NOT_MATCH, createReqDTO.getKey(), definition.getKey());  
238 - }  
239 - if (!Objects.equals(definition.getName(), createReqDTO.getName())) {  
240 - throw exception(PROCESS_DEFINITION_NAME_NOT_MATCH, createReqDTO.getName(), definition.getName());  
241 - }  
242 -  
243 - // 插入拓展表  
244 - BpmProcessDefinitionExtDO definitionDO = BpmProcessDefinitionConvert.INSTANCE.convert2(createReqDTO)  
245 - .setProcessDefinitionId(definition.getId());  
246 - processDefinitionMapper.insert(definitionDO);  
247 - return definition.getId();  
248 - }  
249 -  
250 - @Override  
251 - public void updateProcessDefinitionState(String id, Integer state) {  
252 - // 激活  
253 - if (Objects.equals(SuspensionState.ACTIVE.getStateCode(), state)) {  
254 - repositoryService.activateProcessDefinitionById(id, false, null);  
255 - return;  
256 - }  
257 - // 挂起  
258 - if (Objects.equals(SuspensionState.SUSPENDED.getStateCode(), state)) {  
259 - // suspendProcessInstances = false,进行中的任务,不进行挂起。  
260 - // 原因:只要新的流程不允许发起即可,老流程继续可以执行。  
261 - repositoryService.suspendProcessDefinitionById(id, false, null);  
262 - return;  
263 - }  
264 - log.error("[updateProcessDefinitionState][流程定义({}) 修改未知状态({})]", id, state);  
265 - }  
266 -  
267 -}  
yudao-module-bpm/yudao-module-bpm-biz-activiti/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmTaskAssignRuleServiceImpl.java deleted
1 -package cn.iocoder.yudao.module.bpm.service.definition;  
2 -  
3 -import cn.hutool.core.collection.CollUtil;  
4 -import cn.hutool.core.util.ObjectUtil;  
5 -import cn.hutool.core.util.StrUtil;  
6 -import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.rule.BpmTaskAssignRuleCreateReqVO;  
7 -import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.rule.BpmTaskAssignRuleRespVO;  
8 -import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.rule.BpmTaskAssignRuleUpdateReqVO;  
9 -import cn.iocoder.yudao.module.bpm.convert.definition.BpmTaskAssignRuleConvert;  
10 -import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmTaskAssignRuleDO;  
11 -import cn.iocoder.yudao.module.bpm.dal.mysql.definition.BpmTaskAssignRuleMapper;  
12 -import cn.iocoder.yudao.module.bpm.enums.DictTypeConstants;  
13 -import cn.iocoder.yudao.module.bpm.enums.definition.BpmTaskAssignRuleTypeEnum;  
14 -import cn.iocoder.yudao.framework.activiti.core.util.ActivitiUtils;  
15 -import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;  
16 -import cn.iocoder.yudao.framework.common.util.object.ObjectUtils;  
17 -import cn.iocoder.yudao.module.system.api.dept.DeptApi;  
18 -import cn.iocoder.yudao.module.system.api.dept.PostApi;  
19 -import cn.iocoder.yudao.module.system.api.dict.DictDataApi;  
20 -import cn.iocoder.yudao.module.system.api.permission.RoleApi;  
21 -import cn.iocoder.yudao.module.system.api.user.AdminUserApi;  
22 -import lombok.extern.slf4j.Slf4j;  
23 -import org.activiti.bpmn.model.BpmnModel;  
24 -import org.activiti.bpmn.model.UserTask;  
25 -import org.springframework.context.annotation.Lazy;  
26 -import org.springframework.stereotype.Service;  
27 -import org.springframework.validation.annotation.Validated;  
28 -  
29 -import javax.annotation.Resource;  
30 -import java.util.*;  
31 -  
32 -import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;  
33 -import static cn.iocoder.yudao.module.bpm.enums.ErrorCodeConstants.*;  
34 -  
35 -/**  
36 - * BPM 任务分配规则 Service 实现类  
37 - */  
38 -@Service  
39 -@Validated  
40 -@Slf4j  
41 -public class BpmTaskAssignRuleServiceImpl implements BpmTaskAssignRuleService {  
42 -  
43 - @Resource  
44 - private BpmTaskAssignRuleMapper taskRuleMapper;  
45 -  
46 - @Resource  
47 - @Lazy // 解决循环依赖  
48 - private BpmModelService modelService;  
49 - @Resource  
50 - @Lazy // 解决循环依赖  
51 - private BpmProcessDefinitionService processDefinitionService;  
52 - @Resource  
53 - private BpmUserGroupService userGroupService;  
54 - @Resource  
55 - private RoleApi roleApi;  
56 - @Resource  
57 - private DeptApi deptApi;  
58 - @Resource  
59 - private PostApi postApi;  
60 - @Resource  
61 - private AdminUserApi adminUserApi;  
62 - @Resource  
63 - private DictDataApi dictDataApi;  
64 -  
65 - @Override  
66 - public List<BpmTaskAssignRuleDO> getTaskAssignRuleListByProcessDefinitionId(String processDefinitionId,  
67 - String taskDefinitionKey) {  
68 - return taskRuleMapper.selectListByProcessDefinitionId(processDefinitionId, taskDefinitionKey);  
69 - }  
70 -  
71 - @Override  
72 - public List<BpmTaskAssignRuleDO> getTaskAssignRuleListByModelId(String modelId) {  
73 - return taskRuleMapper.selectListByModelId(modelId);  
74 - }  
75 -  
76 - @Override  
77 - public List<BpmTaskAssignRuleRespVO> getTaskAssignRuleList(String modelId, String processDefinitionId) {  
78 - // 获得规则  
79 - List<BpmTaskAssignRuleDO> rules = Collections.emptyList();  
80 - BpmnModel model = null;  
81 - if (StrUtil.isNotEmpty(modelId)) {  
82 - rules = getTaskAssignRuleListByModelId(modelId);  
83 - model = modelService.getBpmnModel(modelId);  
84 - } else if (StrUtil.isNotEmpty(processDefinitionId)) {  
85 - rules = getTaskAssignRuleListByProcessDefinitionId(processDefinitionId, null);  
86 - model = processDefinitionService.getBpmnModel(processDefinitionId);  
87 - }  
88 - if (model == null) {  
89 - return Collections.emptyList();  
90 - }  
91 -  
92 - // 获得用户任务,只有用户任务才可以设置分配规则  
93 - List<UserTask> userTasks = ActivitiUtils.getBpmnModelElements(model, UserTask.class);  
94 - if (CollUtil.isEmpty(userTasks)) {  
95 - return Collections.emptyList();  
96 - }  
97 -  
98 - // 转换数据  
99 - return BpmTaskAssignRuleConvert.INSTANCE.convertList(userTasks, rules);  
100 - }  
101 -  
102 - @Override  
103 - public Long createTaskAssignRule(BpmTaskAssignRuleCreateReqVO reqVO) {  
104 - // 校验参数  
105 - validTaskAssignRuleOptions(reqVO.getType(), reqVO.getOptions());  
106 - // 校验是否已经配置  
107 - BpmTaskAssignRuleDO existRule = taskRuleMapper.selectListByModelIdAndTaskDefinitionKey(  
108 - reqVO.getModelId(), reqVO.getTaskDefinitionKey());  
109 - if (existRule != null) {  
110 - throw exception(TASK_ASSIGN_RULE_EXISTS, reqVO.getModelId(), reqVO.getTaskDefinitionKey());  
111 - }  
112 -  
113 - // 存储  
114 - BpmTaskAssignRuleDO rule = BpmTaskAssignRuleConvert.INSTANCE.convert(reqVO)  
115 - .setProcessDefinitionId(BpmTaskAssignRuleDO.PROCESS_DEFINITION_ID_NULL); // 只有流程模型,才允许新建  
116 - taskRuleMapper.insert(rule);  
117 - return rule.getId();  
118 - }  
119 -  
120 - @Override  
121 - public void updateTaskAssignRule(BpmTaskAssignRuleUpdateReqVO reqVO) {  
122 - // 校验参数  
123 - validTaskAssignRuleOptions(reqVO.getType(), reqVO.getOptions());  
124 - // 校验是否存在  
125 - BpmTaskAssignRuleDO existRule = taskRuleMapper.selectById(reqVO.getId());  
126 - if (existRule == null) {  
127 - throw exception(TASK_ASSIGN_RULE_NOT_EXISTS);  
128 - }  
129 - // 只允许修改流程模型的规则  
130 - if (!Objects.equals(BpmTaskAssignRuleDO.PROCESS_DEFINITION_ID_NULL, existRule.getProcessDefinitionId())) {  
131 - throw exception(TASK_UPDATE_FAIL_NOT_MODEL);  
132 - }  
133 -  
134 - // 执行更新  
135 - taskRuleMapper.updateById(BpmTaskAssignRuleConvert.INSTANCE.convert(reqVO));  
136 - }  
137 -  
138 - @Override  
139 - public boolean isTaskAssignRulesEquals(String modelId, String processDefinitionId) {  
140 - // 调用 VO 接口的原因是,过滤掉流程模型不需要的规则,保持和 copyTaskAssignRules 方法的一致性  
141 - List<BpmTaskAssignRuleRespVO> modelRules = getTaskAssignRuleList(modelId, null);  
142 - List<BpmTaskAssignRuleRespVO> processInstanceRules = getTaskAssignRuleList(null, processDefinitionId);  
143 - if (modelRules.size() != processInstanceRules.size()) {  
144 - return false;  
145 - }  
146 -  
147 - // 遍历,匹配对应的规则  
148 - Map<String, BpmTaskAssignRuleRespVO> processInstanceRuleMap = CollectionUtils.convertMap(processInstanceRules,  
149 - BpmTaskAssignRuleRespVO::getTaskDefinitionKey);  
150 - for (BpmTaskAssignRuleRespVO modelRule : modelRules) {  
151 - BpmTaskAssignRuleRespVO processInstanceRule = processInstanceRuleMap.get(modelRule.getTaskDefinitionKey());  
152 - if (processInstanceRule == null) {  
153 - return false;  
154 - }  
155 - if (!ObjectUtil.equals(modelRule.getType(), processInstanceRule.getType())  
156 - || !ObjectUtil.equal(modelRule.getOptions(), processInstanceRule.getOptions())) {  
157 - return false;  
158 - }  
159 - }  
160 - return true;  
161 - }  
162 -  
163 - @Override  
164 - public void copyTaskAssignRules(String fromModelId, String toProcessDefinitionId) {  
165 - List<BpmTaskAssignRuleRespVO> rules = getTaskAssignRuleList(fromModelId, null);  
166 - if (CollUtil.isEmpty(rules)) {  
167 - return;  
168 - }  
169 - // 开始复制  
170 - List<BpmTaskAssignRuleDO> newRules = BpmTaskAssignRuleConvert.INSTANCE.convertList2(rules);  
171 - newRules.forEach(rule -> rule.setProcessDefinitionId(toProcessDefinitionId).setId(null)  
172 - .setCreateTime(null).setUpdateTime(null));  
173 - taskRuleMapper.insertBatch(newRules);  
174 - }  
175 -  
176 - @Override  
177 - public void checkTaskAssignRuleAllConfig(String id) {  
178 - // 一个用户任务都没配置,所以无需配置规则  
179 - List<BpmTaskAssignRuleRespVO> taskAssignRules = getTaskAssignRuleList(id, null);  
180 - if (CollUtil.isEmpty(taskAssignRules)) {  
181 - return;  
182 - }  
183 - // 校验未配置规则的任务  
184 - taskAssignRules.forEach(rule -> {  
185 - if (CollUtil.isEmpty(rule.getOptions())) {  
186 - throw exception(MODEL_DEPLOY_FAIL_TASK_ASSIGN_RULE_NOT_CONFIG, rule.getTaskDefinitionName());  
187 - }  
188 - });  
189 - }  
190 -  
191 - private void validTaskAssignRuleOptions(Integer type, Set<Long> options) {  
192 - if (Objects.equals(type, BpmTaskAssignRuleTypeEnum.ROLE.getType())) {  
193 - roleApi.validRoles(options);  
194 - } else if (ObjectUtils.equalsAny(type, BpmTaskAssignRuleTypeEnum.DEPT_MEMBER.getType(),  
195 - BpmTaskAssignRuleTypeEnum.DEPT_LEADER.getType())) {  
196 - deptApi.validDepts(options);  
197 - } else if (Objects.equals(type, BpmTaskAssignRuleTypeEnum.POST.getType())) {  
198 - postApi.validPosts(options);  
199 - } else if (Objects.equals(type, BpmTaskAssignRuleTypeEnum.USER.getType())) {  
200 - adminUserApi.validUsers(options);  
201 - } else if (Objects.equals(type, BpmTaskAssignRuleTypeEnum.USER_GROUP.getType())) {  
202 - userGroupService.validUserGroups(options);  
203 - } else if (Objects.equals(type, BpmTaskAssignRuleTypeEnum.SCRIPT.getType())) {  
204 - dictDataApi.validDictDatas(DictTypeConstants.TASK_ASSIGN_SCRIPT,  
205 - CollectionUtils.convertSet(options, String::valueOf));  
206 - } else {  
207 - throw new IllegalArgumentException(StrUtil.format("未知的规则类型({})", type));  
208 - }  
209 - }  
210 -  
211 -}  
yudao-module-bpm/yudao-module-bpm-biz-activiti/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmActivityService.java deleted
1 -package cn.iocoder.yudao.module.bpm.service.task;  
2 -  
3 -import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.activity.BpmActivityRespVO;  
4 -  
5 -import java.util.List;  
6 -  
7 -/**  
8 - * BPM 活动实例 Service 接口  
9 - *  
10 - * @author 芋道源码  
11 - */  
12 -public interface BpmActivityService {  
13 -  
14 - /**  
15 - * 获得指定流程实例的活动实例列表  
16 - *  
17 - * @param processInstanceId 流程实例的编号  
18 - * @return 活动实例列表  
19 - */  
20 - List<BpmActivityRespVO> getActivityListByProcessInstanceId(String processInstanceId);  
21 -  
22 - /**  
23 - * 生成指定流程实例的高亮流程图,只高亮进行中的任务  
24 - *  
25 - * 友情提示,非该方法的注释。如果想实现更高级的高亮流程图(当前节点红色 + 完成节点为绿色),可参考如下内容:  
26 - * 博客一:https://blog.csdn.net/qq_40109075/article/details/110939639  
27 - * 博客二:https://gitee.com/tony2y/RuoYi-flowable/blob/master/ruoyi-flowable/src/main/java/com/ruoyi/flowable/flow/CustomProcessDiagramGenerator.java  
28 - * 这里不实现的原理,需要自定义实现 ProcessDiagramGenerator 和 ProcessDiagramCanvas,代码量有点大  
29 - *  
30 - * 如果你想实现高亮已完成的任务,可参考 https://blog.csdn.net/qiuxinfa123/article/details/119579863 博客。不过测试下来,貌似不太对~  
31 - *  
32 - * @param processInstanceId 流程实例的编号  
33 - * @return 图的字节数组  
34 - */  
35 - byte[] generateHighlightDiagram(String processInstanceId);  
36 -  
37 -}  
yudao-module-bpm/yudao-module-bpm-biz-activiti/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmActivityServiceImpl.java deleted
1 -package cn.iocoder.yudao.module.bpm.service.task;  
2 -  
3 -import cn.hutool.core.io.IoUtil;  
4 -import cn.iocoder.yudao.module.bpm.convert.task.BpmActivityConvert;  
5 -import cn.iocoder.yudao.module.bpm.service.definition.BpmProcessDefinitionService;  
6 -import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;  
7 -import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.activity.BpmActivityRespVO;  
8 -import lombok.extern.slf4j.Slf4j;  
9 -import org.activiti.bpmn.model.BpmnModel;  
10 -import org.activiti.engine.HistoryService;  
11 -import org.activiti.engine.history.HistoricActivityInstance;  
12 -import org.activiti.engine.history.HistoricProcessInstance;  
13 -import org.activiti.engine.task.Task;  
14 -import org.activiti.image.ProcessDiagramGenerator;  
15 -import org.springframework.stereotype.Service;  
16 -import org.springframework.validation.annotation.Validated;  
17 -  
18 -import javax.annotation.Resource;  
19 -import java.io.InputStream;  
20 -import java.util.Collections;  
21 -import java.util.List;  
22 -  
23 -import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;  
24 -import static cn.iocoder.yudao.module.bpm.enums.ErrorCodeConstants.*;  
25 -  
26 -/**  
27 - * BPM 活动实例 Service 实现类  
28 - *  
29 - * @author 芋道源码  
30 - */  
31 -@Service  
32 -@Slf4j  
33 -@Validated  
34 -public class BpmActivityServiceImpl implements BpmActivityService {  
35 -  
36 - private static final String FONT_NAME = "宋体";  
37 -  
38 - @Resource  
39 - private ProcessDiagramGenerator processDiagramGenerator;  
40 - @Resource  
41 - private HistoryService historyService;  
42 -  
43 - @Resource  
44 - private BpmProcessInstanceService processInstanceService;  
45 - @Resource  
46 - private BpmProcessDefinitionService processDefinitionService;  
47 - @Resource  
48 - private BpmTaskService taskService;  
49 -  
50 - @Override  
51 - public List<BpmActivityRespVO> getActivityListByProcessInstanceId(String processInstanceId) {  
52 - List<HistoricActivityInstance> activityList = historyService.createHistoricActivityInstanceQuery()  
53 - .processInstanceId(processInstanceId).list();  
54 - return BpmActivityConvert.INSTANCE.convertList(activityList);  
55 - }  
56 -  
57 - @Override  
58 - public byte[] generateHighlightDiagram(String processInstanceId) {  
59 - // 获得流程实例  
60 - HistoricProcessInstance processInstance = processInstanceService.getHistoricProcessInstance(processInstanceId);  
61 - if (processInstance == null) {  
62 - throw exception(PROCESS_INSTANCE_NOT_EXISTS);  
63 - }  
64 - // 获得流程定义的 BPMN 模型  
65 - BpmnModel bpmnModel = processDefinitionService.getBpmnModel(processInstance.getProcessDefinitionId());  
66 - if (bpmnModel == null) {  
67 - throw exception(PROCESS_DEFINITION_BPMN_MODEL_NOT_EXISTS);  
68 - }  
69 -  
70 - // 如果流程已经结束,则无进行中的任务,无法高亮  
71 - // 如果流程未结束,才需要高亮  
72 - List<String> highLightedActivities = Collections.emptyList();  
73 - if (processInstance.getEndTime() == null) {  
74 - List<Task> tasks = taskService.getTasksByProcessInstanceId(processInstanceId);  
75 - highLightedActivities = CollectionUtils.convertList(tasks, Task::getTaskDefinitionKey);  
76 - }  
77 -  
78 - // 生成高亮流程图  
79 - InputStream inputStream = processDiagramGenerator.generateDiagram(bpmnModel, highLightedActivities, Collections.emptyList(),  
80 - FONT_NAME, FONT_NAME, FONT_NAME);  
81 - return IoUtil.readBytes(inputStream);  
82 - }  
83 -  
84 -}  
yudao-module-bpm/yudao-module-bpm-biz-activiti/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmProcessInstanceService.java deleted
1 -package cn.iocoder.yudao.module.bpm.service.task;  
2 -  
3 -import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance.*;  
4 -import cn.iocoder.yudao.module.bpm.enums.task.BpmProcessInstanceDeleteReasonEnum;  
5 -import cn.iocoder.yudao.module.bpm.api.task.dto.BpmProcessInstanceCreateReqDTO;  
6 -import cn.iocoder.yudao.framework.common.pojo.PageResult;  
7 -import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;  
8 -import org.activiti.engine.history.HistoricProcessInstance;  
9 -import org.activiti.engine.runtime.ProcessInstance;  
10 -  
11 -import javax.validation.Valid;  
12 -import java.util.List;  
13 -import java.util.Map;  
14 -import java.util.Set;  
15 -  
16 -/**  
17 - * 流程实例 Service 接口  
18 - *  
19 - * @author 芋道源码  
20 - */  
21 -public interface BpmProcessInstanceService {  
22 -  
23 - /**  
24 - * 创建流程实例(提供给前端)  
25 - *  
26 - * @param userId 用户编号  
27 - * @param createReqVO 创建信息  
28 - * @return 实例的编号  
29 - */  
30 - String createProcessInstance(Long userId, @Valid BpmProcessInstanceCreateReqVO createReqVO);  
31 -  
32 - /**  
33 - * 创建流程实例(提供给内部)  
34 - *  
35 - * @param userId 用户编号  
36 - * @param createReqDTO 创建信息  
37 - * @return 实例的编号  
38 - */  
39 - String createProcessInstance(Long userId, @Valid BpmProcessInstanceCreateReqDTO createReqDTO);  
40 -  
41 - /**  
42 - * 取消流程实例  
43 - *  
44 - * @param userId 用户编号  
45 - * @param cancelReqVO 取消信息  
46 - */  
47 - void cancelProcessInstance(Long userId, @Valid BpmProcessInstanceCancelReqVO cancelReqVO);  
48 -  
49 - /**  
50 - * 删除流程实例  
51 - *  
52 - * @param id 流程编号  
53 - * @param reason 删除原因。可选 {@link BpmProcessInstanceDeleteReasonEnum}  
54 - */  
55 - @Deprecated  
56 - void deleteProcessInstance(String id, String reason);  
57 -  
58 - /**  
59 - * 获得流程实例的分页  
60 - *  
61 - * @param userId 用户编号  
62 - * @param pageReqVO 分页请求  
63 - * @return 流程实例的分页  
64 - */  
65 - PageResult<BpmProcessInstancePageItemRespVO> getMyProcessInstancePage(Long userId,  
66 - @Valid BpmProcessInstanceMyPageReqVO pageReqVO);  
67 -  
68 - /**  
69 - * 获得流程实例 VO 信息  
70 - *  
71 - * @param id 流程实例的编号  
72 - * @return 流程实例  
73 - */  
74 - BpmProcessInstanceRespVO getProcessInstanceVO(String id);  
75 -  
76 - /**  
77 - * 获得流程实例  
78 - *  
79 - * @param id 流程实例的编号  
80 - * @return 流程实例  
81 - */  
82 - ProcessInstance getProcessInstance(String id);  
83 -  
84 - /**  
85 - * 获得流程实例列表  
86 - *  
87 - * @param ids 流程实例的编号集合  
88 - * @return 流程实例列表  
89 - */  
90 - List<ProcessInstance> getProcessInstances(Set<String> ids);  
91 -  
92 - /**  
93 - * 获得流程实例 Map  
94 - *  
95 - * @param ids 流程实例的编号集合  
96 - * @return 流程实例列表 Map  
97 - */  
98 - default Map<String, ProcessInstance> getProcessInstanceMap(Set<String> ids) {  
99 - return CollectionUtils.convertMap(getProcessInstances(ids), ProcessInstance::getProcessInstanceId);  
100 - }  
101 -  
102 - /**  
103 - * 获得历史的流程实例  
104 - *  
105 - * @param id 流程实例的编号  
106 - * @return 历史的流程实例  
107 - */  
108 - HistoricProcessInstance getHistoricProcessInstance(String id);  
109 -  
110 - /**  
111 - * 获得历史的流程实例列表  
112 - *  
113 - * @param ids 流程实例的编号集合  
114 - * @return 历史的流程实例列表  
115 - */  
116 - List<HistoricProcessInstance> getHistoricProcessInstances(Set<String> ids);  
117 -  
118 - /**  
119 - * 获得历史的流程实例 Map  
120 - *  
121 - * @param ids 流程实例的编号集合  
122 - * @return 历史的流程实例列表 Map  
123 - */  
124 - default Map<String, HistoricProcessInstance> getHistoricProcessInstanceMap(Set<String> ids) {  
125 - return CollectionUtils.convertMap(getHistoricProcessInstances(ids), HistoricProcessInstance::getId);  
126 - }  
127 -  
128 - /**  
129 - * 创建 ProcessInstance 拓展记录  
130 - *  
131 - * @param instance 流程任务  
132 - */  
133 - void createProcessInstanceExt(org.activiti.api.process.model.ProcessInstance instance);  
134 -  
135 - /**  
136 - * 更新 ProcessInstance 拓展记录  
137 - *  
138 - * @param instance 流程任务  
139 - */  
140 - void updateProcessInstanceExt(org.activiti.api.process.model.ProcessInstance instance);  
141 -  
142 - /**  
143 - * 更新 ProcessInstance 拓展记录为取消  
144 - *  
145 - * @param instance 流程任务  
146 - * @param reason 取消原因  
147 - */  
148 - void updateProcessInstanceExtCancel(org.activiti.api.process.model.ProcessInstance instance, String reason);  
149 -  
150 - /**  
151 - * 更新 ProcessInstance 拓展记录为完成  
152 - *  
153 - * @param instance 流程任务  
154 - */  
155 - void updateProcessInstanceExtComplete(org.activiti.api.process.model.ProcessInstance instance);  
156 -  
157 - /**  
158 - * 更新 ProcessInstance 拓展记录为不通过  
159 - *  
160 - * @param id 流程编号  
161 - * @param reason 理由。例如说,审批不通过时,需要传递该值  
162 - */  
163 - void updateProcessInstanceExtReject(String id, String reason);  
164 -  
165 -}  
yudao-module-bpm/yudao-module-bpm-biz-activiti/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmProcessInstanceServiceImpl.java deleted
1 -package cn.iocoder.yudao.module.bpm.service.task;  
2 -  
3 -import cn.hutool.core.collection.CollUtil;  
4 -import cn.hutool.core.lang.Assert;  
5 -import cn.hutool.core.util.StrUtil;  
6 -import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance.*;  
7 -import cn.iocoder.yudao.module.bpm.convert.task.BpmProcessInstanceConvert;  
8 -import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmProcessDefinitionExtDO;  
9 -import cn.iocoder.yudao.module.bpm.dal.dataobject.task.BpmProcessInstanceExtDO;  
10 -import cn.iocoder.yudao.module.bpm.dal.mysql.task.BpmProcessInstanceExtMapper;  
11 -import cn.iocoder.yudao.module.bpm.enums.task.BpmProcessInstanceDeleteReasonEnum;  
12 -import cn.iocoder.yudao.module.bpm.enums.task.BpmProcessInstanceResultEnum;  
13 -import cn.iocoder.yudao.module.bpm.enums.task.BpmProcessInstanceStatusEnum;  
14 -import cn.iocoder.yudao.module.bpm.framework.bpm.core.event.BpmProcessInstanceResultEventPublisher;  
15 -import cn.iocoder.yudao.module.bpm.service.definition.BpmProcessDefinitionService;  
16 -import cn.iocoder.yudao.module.bpm.service.message.BpmMessageService;  
17 -import cn.iocoder.yudao.module.bpm.api.task.dto.BpmProcessInstanceCreateReqDTO;  
18 -import cn.iocoder.yudao.framework.common.pojo.PageResult;  
19 -import cn.iocoder.yudao.framework.common.util.number.NumberUtils;  
20 -import cn.iocoder.yudao.module.system.api.dept.DeptApi;  
21 -import cn.iocoder.yudao.module.system.api.dept.dto.DeptRespDTO;  
22 -import cn.iocoder.yudao.module.system.api.user.AdminUserApi;  
23 -import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;  
24 -import lombok.extern.slf4j.Slf4j;  
25 -import org.activiti.engine.HistoryService;  
26 -import org.activiti.engine.RuntimeService;  
27 -import org.activiti.engine.history.HistoricProcessInstance;  
28 -import org.activiti.engine.repository.ProcessDefinition;  
29 -import org.activiti.engine.runtime.ProcessInstance;  
30 -import org.activiti.engine.task.Task;  
31 -import org.springframework.context.annotation.Lazy;  
32 -import org.springframework.stereotype.Service;  
33 -import org.springframework.transaction.annotation.Transactional;  
34 -import org.springframework.validation.annotation.Validated;  
35 -  
36 -import javax.annotation.Resource;  
37 -import java.util.*;  
38 -  
39 -import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;  
40 -import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList;  
41 -import static cn.iocoder.yudao.module.bpm.enums.ErrorCodeConstants.*;  
42 -  
43 -/**  
44 - * 流程实例 Service 实现类  
45 - *  
46 - * ProcessDefinition & ProcessInstance & Execution & Task 的关系:  
47 - * 1. https://blog.csdn.net/bobozai86/article/details/105210414  
48 - *  
49 - * HistoricProcessInstance & ProcessInstance 的关系:  
50 - * 1.https://my.oschina.net/843294669/blog/719024  
51 - * 简单来说,前者 = 历史 + 运行中的流程实例,后者仅是运行中的流程实例  
52 - *  
53 - * @author 芋道源码  
54 - */  
55 -@Service  
56 -@Validated  
57 -@Slf4j  
58 -public class BpmProcessInstanceServiceImpl implements BpmProcessInstanceService {  
59 -  
60 - @Resource  
61 - private RuntimeService runtimeService;  
62 - @Resource  
63 - private HistoryService historyService;  
64 -  
65 - @Resource  
66 - private AdminUserApi adminUserApi;  
67 - @Resource  
68 - private DeptApi deptApi;  
69 - @Resource  
70 - @Lazy // 解决循环依赖  
71 - private BpmTaskService taskService;  
72 - @Resource  
73 - private BpmProcessDefinitionService processDefinitionService;  
74 - @Resource  
75 - private BpmMessageService messageService;  
76 -  
77 - @Resource  
78 - private BpmProcessInstanceResultEventPublisher processInstanceResultEventPublisher;  
79 -  
80 - @Resource  
81 - private BpmProcessInstanceExtMapper processInstanceExtMapper;  
82 -  
83 - @Override  
84 - @Transactional(rollbackFor = Exception.class)  
85 - public String createProcessInstance(Long userId, BpmProcessInstanceCreateReqVO createReqVO) {  
86 - // 获得流程定义  
87 - ProcessDefinition definition = processDefinitionService.getProcessDefinition(createReqVO.getProcessDefinitionId());  
88 - // 发起流程  
89 - return createProcessInstance0(userId, definition, createReqVO.getVariables(), null);  
90 - }  
91 -  
92 - @Override  
93 - public String createProcessInstance(Long userId, BpmProcessInstanceCreateReqDTO createReqDTO) {  
94 - // 获得流程定义  
95 - ProcessDefinition definition = processDefinitionService.getActiveProcessDefinition(createReqDTO.getProcessDefinitionKey());  
96 - // 发起流程  
97 - return createProcessInstance0(userId, definition, createReqDTO.getVariables(), createReqDTO.getBusinessKey());  
98 - }  
99 -  
100 - private String createProcessInstance0(Long userId, ProcessDefinition definition,  
101 - Map<String, Object> variables, String businessKey) {  
102 - // 校验流程定义  
103 - if (definition == null) {  
104 - throw exception(PROCESS_DEFINITION_NOT_EXISTS);  
105 - }  
106 - if (definition.isSuspended()) {  
107 - throw exception(PROCESS_DEFINITION_IS_SUSPENDED);  
108 - }  
109 -  
110 - // 创建流程实例  
111 - ProcessInstance instance = runtimeService.startProcessInstanceById(definition.getId(), businessKey, variables);  
112 - // 设置流程名字  
113 - runtimeService.setProcessInstanceName(instance.getId(), definition.getName());  
114 -  
115 - // 补全流程实例的拓展表  
116 - processInstanceExtMapper.updateByProcessInstanceId(new BpmProcessInstanceExtDO().setProcessInstanceId(instance.getId())  
117 - .setFormVariables(variables));  
118 -  
119 - // 添加初始的评论 TODO 芋艿:在思考下  
120 -// Task task = taskService.createTaskQuery().processInstanceId(instance.getId()).singleResult();  
121 -// if (task != null) {  
122 -// SysUserDO user = userService.getUser(userId);  
123 -// Assert.notNull(user, "用户({})不存在", userId);  
124 -// String type = "normal";  
125 -// taskService.addComment(task.getId(), instance.getProcessInstanceId(), type,  
126 -// String.format("%s 发起流程申请", user.getNickname()));  
127 -// }  
128 - return instance.getId();  
129 - }  
130 -  
131 - @Override  
132 - @Transactional(rollbackFor = Exception.class)  
133 - public void cancelProcessInstance(Long userId, BpmProcessInstanceCancelReqVO cancelReqVO) {  
134 - // 校验流程实例存在  
135 - ProcessInstance instance = getProcessInstance(cancelReqVO.getId());  
136 - if (instance == null) {  
137 - throw exception(PROCESS_INSTANCE_CANCEL_FAIL_NOT_EXISTS);  
138 - }  
139 - // 只能取消自己的  
140 - if (!Objects.equals(instance.getStartUserId(), String.valueOf(userId))) {  
141 - throw exception(PROCESS_INSTANCE_CANCEL_FAIL_NOT_SELF);  
142 - }  
143 -  
144 - // 通过删除流程实例,实现流程实例的取消  
145 - runtimeService.deleteProcessInstance(cancelReqVO.getId(),  
146 - BpmProcessInstanceDeleteReasonEnum.CANCEL_TASK.format(cancelReqVO.getReason()));  
147 - }  
148 -  
149 - @Override  
150 - public void deleteProcessInstance(String id, String reason) {  
151 - runtimeService.deleteProcessInstance(id, reason);  
152 - }  
153 -  
154 - @Override  
155 - public PageResult<BpmProcessInstancePageItemRespVO> getMyProcessInstancePage(Long userId,  
156 - BpmProcessInstanceMyPageReqVO pageReqVO) {  
157 - // 通过 BpmProcessInstanceExtDO 表,先查询到对应的分页  
158 - PageResult<BpmProcessInstanceExtDO> pageResult = processInstanceExtMapper.selectPage(userId, pageReqVO);  
159 - if (CollUtil.isEmpty(pageResult.getList())) {  
160 - return new PageResult<>(pageResult.getTotal());  
161 - }  
162 -  
163 - // 获得流程 Task Map  
164 - List<String> processInstanceIds = convertList(pageResult.getList(), BpmProcessInstanceExtDO::getProcessInstanceId);  
165 - Map<String, List<Task>> taskMap = taskService.getTaskMapByProcessInstanceIds(processInstanceIds);  
166 - // 转换返回  
167 - return BpmProcessInstanceConvert.INSTANCE.convertPage(pageResult, taskMap);  
168 - }  
169 -  
170 - @Override  
171 - public BpmProcessInstanceRespVO getProcessInstanceVO(String id) {  
172 - // 获得流程实例  
173 - HistoricProcessInstance processInstance = getHistoricProcessInstance(id);  
174 - if (processInstance == null) {  
175 - return null;  
176 - }  
177 - BpmProcessInstanceExtDO processInstanceExt = processInstanceExtMapper.selectByProcessInstanceId(id);  
178 - Assert.notNull(processInstanceExt, "流程实例拓展({}) 不存在", id);  
179 -  
180 - // 获得流程定义  
181 - ProcessDefinition processDefinition = processDefinitionService.getProcessDefinition(  
182 - processInstance.getProcessDefinitionId());  
183 - Assert.notNull(processDefinition, "流程定义({}) 不存在", processInstance.getProcessDefinitionId());  
184 - BpmProcessDefinitionExtDO processDefinitionExt = processDefinitionService.getProcessDefinitionExt(  
185 - processInstance.getProcessDefinitionId());  
186 - Assert.notNull(processDefinitionExt, "流程定义拓展({}) 不存在", id);  
187 - String bpmnXml = processDefinitionService.getProcessDefinitionBpmnXML(processInstance.getProcessDefinitionId());  
188 -  
189 - // 获得 User  
190 - AdminUserRespDTO startUser = adminUserApi.getUser(NumberUtils.parseLong(processInstance.getStartUserId()));  
191 - DeptRespDTO dept = null;  
192 - if (startUser != null) {  
193 - dept = deptApi.getDept(startUser.getDeptId());  
194 - }  
195 -  
196 - // 拼接结果  
197 - return BpmProcessInstanceConvert.INSTANCE.convert2(processInstance, processInstanceExt,  
198 - processDefinition, processDefinitionExt, bpmnXml, startUser, dept);  
199 - }  
200 -  
201 - @Override  
202 - public List<ProcessInstance> getProcessInstances(Set<String> ids) {  
203 - return runtimeService.createProcessInstanceQuery().processInstanceIds(ids).list();  
204 - }  
205 -  
206 - @Override  
207 - public ProcessInstance getProcessInstance(String id) {  
208 - return runtimeService.createProcessInstanceQuery().processInstanceId(id).singleResult();  
209 - }  
210 -  
211 - /**  
212 - * 获得历史的流程实例  
213 - *  
214 - * @param id 流程实例的编号  
215 - * @return 历史的流程实例  
216 - */  
217 - @Override  
218 - public HistoricProcessInstance getHistoricProcessInstance(String id) {  
219 - return historyService.createHistoricProcessInstanceQuery().processInstanceId(id).singleResult();  
220 - }  
221 -  
222 - @Override  
223 - public List<HistoricProcessInstance> getHistoricProcessInstances(Set<String> ids) {  
224 - return historyService.createHistoricProcessInstanceQuery().processInstanceIds(ids).list();  
225 - }  
226 -  
227 - @Override  
228 - public void createProcessInstanceExt(org.activiti.api.process.model.ProcessInstance instance) {  
229 - // 获得流程定义  
230 - ProcessDefinition definition = processDefinitionService.getProcessDefinition2(instance.getProcessDefinitionId());  
231 - // 插入 BpmProcessInstanceExtDO 对象  
232 - BpmProcessInstanceExtDO instanceExtDO = BpmProcessInstanceConvert.INSTANCE.convert(instance)  
233 - .setCategory(definition.getCategory())  
234 - .setStatus(BpmProcessInstanceStatusEnum.RUNNING.getStatus())  
235 - .setResult(BpmProcessInstanceResultEnum.PROCESS.getResult());  
236 - processInstanceExtMapper.insert(instanceExtDO);  
237 - }  
238 -  
239 - @Override  
240 - public void updateProcessInstanceExt(org.activiti.api.process.model.ProcessInstance instance) {  
241 - BpmProcessInstanceExtDO instanceExtDO = BpmProcessInstanceConvert.INSTANCE.convert(instance);  
242 - processInstanceExtMapper.updateByProcessInstanceId(instanceExtDO);  
243 - }  
244 -  
245 - @Override  
246 - public void updateProcessInstanceExtCancel(org.activiti.api.process.model.ProcessInstance instance, String reason) {  
247 - // 判断是否为 Reject 不通过。如果是,则不进行更新  
248 - if (BpmProcessInstanceDeleteReasonEnum.isRejectReason(reason)) {  
249 - return;  
250 - }  
251 -  
252 - // 需要主动查询,因为 instance 只有 id 属性  
253 - // 另外,此时如果去查询 ProcessInstance 的话,字段是不全的,所以去查询了 HistoricProcessInstance  
254 - HistoricProcessInstance processInstance = getHistoricProcessInstance(instance.getId());  
255 - // 更新拓展表  
256 - BpmProcessInstanceExtDO instanceExtDO = BpmProcessInstanceConvert.INSTANCE.convert(instance)  
257 - .setEndTime(new Date()) // 由于 ProcessInstance 里没有办法拿到 endTime,所以这里设置  
258 - .setStatus(BpmProcessInstanceStatusEnum.FINISH.getStatus())  
259 - .setResult(BpmProcessInstanceResultEnum.CANCEL.getResult());  
260 - processInstanceExtMapper.updateByProcessInstanceId(instanceExtDO);  
261 -  
262 - // 发送流程实例的状态事件  
263 - processInstanceResultEventPublisher.sendProcessInstanceResultEvent(  
264 - BpmProcessInstanceConvert.INSTANCE.convert(this, processInstance, instanceExtDO.getResult()));  
265 - }  
266 -  
267 - @Override  
268 - public void updateProcessInstanceExtComplete(org.activiti.api.process.model.ProcessInstance instance) {  
269 - // 需要主动查询,因为 instance 只有 id 属性  
270 - // 另外,此时如果去查询 ProcessInstance 的话,字段是不全的,所以去查询了 HistoricProcessInstance  
271 - HistoricProcessInstance processInstance = getHistoricProcessInstance(instance.getId());  
272 - // 更新拓展表  
273 - BpmProcessInstanceExtDO instanceExtDO = BpmProcessInstanceConvert.INSTANCE.convert(instance)  
274 - .setEndTime(new Date()) // 由于 ProcessInstance 里没有办法拿到 endTime,所以这里设置  
275 - .setStatus(BpmProcessInstanceStatusEnum.FINISH.getStatus())  
276 - .setResult(BpmProcessInstanceResultEnum.APPROVE.getResult()); // 如果正常完全,说明审批通过  
277 - processInstanceExtMapper.updateByProcessInstanceId(instanceExtDO);  
278 -  
279 - // 发送流程被通过的消息  
280 - messageService.sendMessageWhenProcessInstanceApprove(BpmProcessInstanceConvert.INSTANCE.convert2(instance));  
281 -  
282 - // 发送流程实例的状态事件  
283 - processInstanceResultEventPublisher.sendProcessInstanceResultEvent(  
284 - BpmProcessInstanceConvert.INSTANCE.convert(this, processInstance, instanceExtDO.getResult()));  
285 - }  
286 -  
287 - @Transactional(rollbackFor = Exception.class)  
288 - public void updateProcessInstanceExtReject(String id, String reason) {  
289 - // 需要主动查询,因为 instance 只有 id 属性  
290 - ProcessInstance processInstance = getProcessInstance(id);  
291 - // 删除流程实例,以实现驳回任务时,取消整个审批流程  
292 - deleteProcessInstance(id, StrUtil.format(BpmProcessInstanceDeleteReasonEnum.REJECT_TASK.format(reason)));  
293 -  
294 - // 更新 status + result  
295 - // 注意,不能和上面的逻辑更换位置。因为 deleteProcessInstance 会触发流程的取消,进而调用 updateProcessInstanceExtCancel 方法,  
296 - // 设置 result 为 BpmProcessInstanceStatusEnum.CANCEL,显然和 result 不一定是一致的  
297 - BpmProcessInstanceExtDO instanceExtDO = new BpmProcessInstanceExtDO().setProcessInstanceId(id)  
298 - .setStatus(BpmProcessInstanceStatusEnum.FINISH.getStatus())  
299 - .setResult(BpmProcessInstanceResultEnum.REJECT.getResult());  
300 - processInstanceExtMapper.updateByProcessInstanceId(instanceExtDO);  
301 -  
302 - // 发送流程被不通过的消息  
303 - messageService.sendMessageWhenProcessInstanceReject(BpmProcessInstanceConvert.INSTANCE.convert(processInstance, reason));  
304 -  
305 - // 发送流程实例的状态事件  
306 - processInstanceResultEventPublisher.sendProcessInstanceResultEvent(  
307 - BpmProcessInstanceConvert.INSTANCE.convert(this, processInstance, instanceExtDO.getResult()));  
308 - }  
309 -  
310 -}  
yudao-module-bpm/yudao-module-bpm-biz-activiti/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmTaskService.java deleted
1 -package cn.iocoder.yudao.module.bpm.service.task;  
2 -  
3 -import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.task.*;  
4 -import cn.iocoder.yudao.module.bpm.dal.dataobject.task.BpmTaskExtDO;  
5 -import cn.iocoder.yudao.framework.common.pojo.PageResult;  
6 -import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;  
7 -import org.activiti.engine.task.Task;  
8 -  
9 -import javax.validation.Valid;  
10 -import java.util.List;  
11 -import java.util.Map;  
12 -  
13 -/**  
14 - * 流程任务实例 Service 接口  
15 - *  
16 - * @author jason  
17 - * @author 芋道源码  
18 - */  
19 -public interface BpmTaskService {  
20 -  
21 - /**  
22 - * 获得指定流程实例的 Running 进行中的流程任务列表  
23 - *  
24 - * @param processInstanceId 流程实例的编号  
25 - */  
26 - List<Task> getRunningTaskListByProcessInstanceId(String processInstanceId);  
27 -  
28 - /**  
29 - * 获得指令流程实例的流程任务列表,包括所有状态的  
30 - *  
31 - * @param processInstanceId 流程实例的编号  
32 - * @return 流程任务列表  
33 - */  
34 - List<BpmTaskRespVO> getTaskListByProcessInstanceId(String processInstanceId);  
35 -  
36 - /**  
37 - * 获得流程任务列表  
38 - *  
39 - * @param processInstanceId 流程实例的编号  
40 - * @return 流程任务列表  
41 - */  
42 - List<Task> getTasksByProcessInstanceId(String processInstanceId);  
43 -  
44 - /**  
45 - * 获得流程任务列表  
46 - *  
47 - * @param processInstanceIds 流程实例的编号数组  
48 - * @return 流程任务列表  
49 - */  
50 - List<Task> getTasksByProcessInstanceIds(List<String> processInstanceIds);  
51 -  
52 - /**  
53 - * 获得流程任务 Map  
54 - *  
55 - * @param processInstanceIds 流程实例的编号数组  
56 - * @return 流程任务 Map  
57 - */  
58 - default Map<String, List<Task>> getTaskMapByProcessInstanceIds(List<String> processInstanceIds) {  
59 - return CollectionUtils.convertMultiMap(getTasksByProcessInstanceIds(processInstanceIds),  
60 - Task::getProcessInstanceId);  
61 - }  
62 -  
63 - /**  
64 - * 获得待办的流程任务分页  
65 - *  
66 - * @param userId 用户编号  
67 - * @param pageReqVO 分页请求  
68 - * @return 流程任务分页  
69 - */  
70 - PageResult<BpmTaskTodoPageItemRespVO> getTodoTaskPage(Long userId, BpmTaskTodoPageReqVO pageReqVO);  
71 -  
72 - /**  
73 - * 获得已办的流程任务分页  
74 - *  
75 - * @param userId 用户编号  
76 - * @param pageReqVO 分页请求  
77 - * @return 流程任务分页  
78 - */  
79 - PageResult<BpmTaskDonePageItemRespVO> getDoneTaskPage(Long userId, BpmTaskDonePageReqVO pageReqVO);  
80 -  
81 - /**  
82 - * 将流程任务分配给指定用户  
83 - *  
84 - * @param userId 用户编号  
85 - * @param reqVO 分配请求  
86 - */  
87 - void updateTaskAssignee(Long userId, BpmTaskUpdateAssigneeReqVO reqVO);  
88 -  
89 - /**  
90 - * 将流程任务分配给指定用户  
91 - *  
92 - * @param id 流程任务编号  
93 - * @param userId 用户编号  
94 - */  
95 - void updateTaskAssignee(String id, Long userId);  
96 -  
97 - /**  
98 - * 通过任务  
99 - *  
100 - * @param userId 用户编号  
101 - * @param reqVO 通过请求  
102 - */  
103 - void approveTask(Long userId, @Valid BpmTaskApproveReqVO reqVO);  
104 -  
105 - /**  
106 - * 不通过任务  
107 - *  
108 - * @param userId 用户编号  
109 - * @param reqVO 不通过请求  
110 - */  
111 - void rejectTask(Long userId, @Valid BpmTaskRejectReqVO reqVO);  
112 -  
113 - // ========== Task 拓展表相关 ==========  
114 -  
115 - /**  
116 - * 创建 Task 拓展记录  
117 - *  
118 - * @param task 任务实体  
119 - */  
120 - void createTaskExt(org.activiti.api.task.model.Task task);  
121 -  
122 - /**  
123 - * 更新 Task 拓展记录  
124 - *  
125 - * @param task 任务实体  
126 - */  
127 - void updateTaskExt(org.activiti.api.task.model.Task task);  
128 -  
129 - /**  
130 - * 更新 Task 拓展记录,并发送通知  
131 - *  
132 - * @param task 任务实体  
133 - */  
134 - void updateTaskExtAssign(org.activiti.api.task.model.Task task);  
135 -  
136 - /**  
137 - * 更新 Task 拓展记录为取消  
138 - *  
139 - * @param task 任务实体  
140 - */  
141 - void updateTaskExtCancel(org.activiti.api.task.model.Task task);  
142 -  
143 - /**  
144 - * 更新 Task 拓展记录为完成  
145 - *  
146 - * @param task 任务实体  
147 - */  
148 - void updateTaskExtComplete(org.activiti.api.task.model.Task task);  
149 -  
150 - /**  
151 - * 获得流程实例对应的 Task 拓展列表  
152 - *  
153 - * @param processInstanceId 流程实例的编号  
154 - * @return Task 拓展列表  
155 - */  
156 - List<BpmTaskExtDO> getTaskExtListByProcessInstanceId(String processInstanceId);  
157 -  
158 -  
159 -}  
yudao-module-bpm/yudao-module-bpm-biz-activiti/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmTaskServiceImpl.java deleted
1 -package cn.iocoder.yudao.module.bpm.service.task;  
2 -  
3 -import cn.hutool.core.collection.CollUtil;  
4 -import cn.hutool.core.util.StrUtil;  
5 -import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.task.*;  
6 -import cn.iocoder.yudao.module.bpm.convert.task.BpmTaskConvert;  
7 -import cn.iocoder.yudao.module.bpm.dal.dataobject.task.BpmTaskExtDO;  
8 -import cn.iocoder.yudao.module.bpm.dal.mysql.task.BpmTaskExtMapper;  
9 -import cn.iocoder.yudao.module.bpm.enums.task.BpmProcessInstanceResultEnum;  
10 -import cn.iocoder.yudao.module.bpm.service.message.BpmMessageService;  
11 -  
12 -import cn.iocoder.yudao.framework.activiti.core.util.ActivitiUtils;  
13 -import cn.iocoder.yudao.framework.common.pojo.PageResult;  
14 -import cn.iocoder.yudao.framework.common.util.number.NumberUtils;  
15 -import cn.iocoder.yudao.framework.common.util.object.PageUtils;  
16 -import cn.iocoder.yudao.module.system.api.dept.DeptApi;  
17 -import cn.iocoder.yudao.module.system.api.dept.dto.DeptRespDTO;  
18 -import cn.iocoder.yudao.module.system.api.user.AdminUserApi;  
19 -import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;  
20 -import lombok.extern.slf4j.Slf4j;  
21 -import org.activiti.engine.HistoryService;  
22 -import org.activiti.engine.TaskService;  
23 -import org.activiti.engine.history.HistoricProcessInstance;  
24 -import org.activiti.engine.history.HistoricTaskInstance;  
25 -import org.activiti.engine.history.HistoricTaskInstanceQuery;  
26 -import org.activiti.engine.runtime.ProcessInstance;  
27 -import org.activiti.engine.task.Task;  
28 -import org.activiti.engine.task.TaskQuery;  
29 -import org.springframework.context.annotation.Lazy;  
30 -import org.springframework.stereotype.Service;  
31 -import org.springframework.transaction.annotation.Transactional;  
32 -import org.springframework.transaction.support.TransactionSynchronization;  
33 -import org.springframework.transaction.support.TransactionSynchronizationManager;  
34 -  
35 -import javax.annotation.Resource;  
36 -import javax.validation.Valid;  
37 -import java.util.*;  
38 -  
39 -import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;  
40 -import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap;  
41 -import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;  
42 -import static cn.iocoder.yudao.module.bpm.enums.ErrorCodeConstants.*;  
43 -  
44 -/**  
45 - * 流程任务实例 Service 实现类  
46 - *  
47 - * @author jason  
48 - * @author 芋道源码  
49 - */  
50 -@Slf4j  
51 -@Service  
52 -public class BpmTaskServiceImpl implements BpmTaskService {  
53 -  
54 - @Resource  
55 - private TaskService taskService;  
56 - @Resource  
57 - private HistoryService historyService;  
58 -  
59 - @Resource  
60 - private AdminUserApi adminUserApi;  
61 - @Resource  
62 - private DeptApi deptApi;  
63 - @Resource  
64 - @Lazy // 解决循环依赖  
65 - private BpmProcessInstanceService processInstanceService;  
66 - @Resource  
67 - private BpmMessageService messageService;  
68 -  
69 - @Resource  
70 - private BpmTaskExtMapper taskExtMapper;  
71 -  
72 - @Override  
73 - public List<Task> getRunningTaskListByProcessInstanceId(String processInstanceId) {  
74 - return taskService.createTaskQuery().processInstanceId(processInstanceId).list();  
75 - }  
76 -  
77 - @Override  
78 - public List<BpmTaskRespVO> getTaskListByProcessInstanceId(String processInstanceId) {  
79 - // 获得任务列表  
80 - List<HistoricTaskInstance> tasks = historyService.createHistoricTaskInstanceQuery()  
81 - .processInstanceId(processInstanceId)  
82 - .orderByHistoricTaskInstanceStartTime().desc() // 创建时间倒序  
83 - .list();  
84 - if (CollUtil.isEmpty(tasks)) {  
85 - return Collections.emptyList();  
86 - }  
87 -  
88 - // 获得 TaskExtDO Map  
89 - List<BpmTaskExtDO> bpmTaskExtDOs = taskExtMapper.selectListByTaskIds(convertSet(tasks, HistoricTaskInstance::getId));  
90 - Map<String, BpmTaskExtDO> bpmTaskExtDOMap = convertMap(bpmTaskExtDOs, BpmTaskExtDO::getTaskId);  
91 - // 获得 ProcessInstance Map  
92 - HistoricProcessInstance processInstance = processInstanceService.getHistoricProcessInstance(processInstanceId);  
93 - // 获得 User Map  
94 - Set<Long> userIds = convertSet(tasks, task -> NumberUtils.parseLong(task.getAssignee()));  
95 - userIds.add(NumberUtils.parseLong(processInstance.getStartUserId()));  
96 - Map<Long, AdminUserRespDTO> userMap = adminUserApi.getUserMap(userIds);  
97 - // 获得 Dept Map  
98 - Map<Long, DeptRespDTO> deptMap = deptApi.getDeptMap(convertSet(userMap.values(), AdminUserRespDTO::getDeptId));  
99 -  
100 - // 拼接数据  
101 - return BpmTaskConvert.INSTANCE.convertList3(tasks, bpmTaskExtDOMap, processInstance, userMap, deptMap);  
102 - }  
103 -  
104 - @Override  
105 - public List<Task> getTasksByProcessInstanceId(String processInstanceId) {  
106 - if (StrUtil.isEmpty(processInstanceId)) {  
107 - return Collections.emptyList();  
108 - }  
109 - return taskService.createTaskQuery().processInstanceId(processInstanceId).list();  
110 - }  
111 -  
112 - @Override  
113 - public List<Task> getTasksByProcessInstanceIds(List<String> processInstanceIds) {  
114 - if (CollUtil.isEmpty(processInstanceIds)) {  
115 - return Collections.emptyList();  
116 - }  
117 - return taskService.createTaskQuery().processInstanceIdIn(processInstanceIds).list();  
118 - }  
119 -  
120 - @Override  
121 - public PageResult<BpmTaskTodoPageItemRespVO> getTodoTaskPage(Long userId, BpmTaskTodoPageReqVO pageVO) {  
122 - // 查询待办任务  
123 - TaskQuery taskQuery = taskService.createTaskQuery()  
124 - .taskAssignee(String.valueOf(userId)) // 分配给自己  
125 - .orderByTaskCreateTime().desc(); // 创建时间倒序  
126 - if (StrUtil.isNotBlank(pageVO.getName())) {  
127 - taskQuery.taskNameLike("%" + pageVO.getName() + "%");  
128 - }  
129 - if (pageVO.getBeginCreateTime() != null) {  
130 - taskQuery.taskCreatedAfter(pageVO.getBeginCreateTime());  
131 - }  
132 - if (pageVO.getEndCreateTime() != null) {  
133 - taskQuery.taskCreatedBefore(pageVO.getEndCreateTime());  
134 - }  
135 - // 执行查询  
136 - List<Task> tasks = taskQuery.listPage(PageUtils.getStart(pageVO), pageVO.getPageSize());  
137 - if (CollUtil.isEmpty(tasks)) {  
138 - return PageResult.empty(taskQuery.count());  
139 - }  
140 -  
141 - // 获得 ProcessInstance Map  
142 - Map<String, ProcessInstance> processInstanceMap = processInstanceService.getProcessInstanceMap(  
143 - convertSet(tasks, Task::getProcessInstanceId));  
144 - // 获得 User Map  
145 - Map<Long, AdminUserRespDTO> userMap = adminUserApi.getUserMap(  
146 - convertSet(processInstanceMap.values(), instance -> Long.valueOf(instance.getStartUserId())));  
147 - // 拼接结果  
148 - return new PageResult<>(BpmTaskConvert.INSTANCE.convertList1(tasks, processInstanceMap, userMap),  
149 - taskQuery.count());  
150 - }  
151 -  
152 - @Override  
153 - public PageResult<BpmTaskDonePageItemRespVO> getDoneTaskPage(Long userId, BpmTaskDonePageReqVO pageVO) {  
154 - // 查询已办任务  
155 - HistoricTaskInstanceQuery taskQuery = historyService.createHistoricTaskInstanceQuery()  
156 - .finished() // 已完成  
157 - .taskAssignee(String.valueOf(userId)) // 分配给自己  
158 - .orderByHistoricTaskInstanceEndTime().desc(); // 审批时间倒序  
159 - if (StrUtil.isNotBlank(pageVO.getName())) {  
160 - taskQuery.taskNameLike("%" + pageVO.getName() + "%");  
161 - }  
162 - if (pageVO.getBeginCreateTime() != null) {  
163 - taskQuery.taskCreatedAfter(pageVO.getBeginCreateTime());  
164 - }  
165 - if (pageVO.getEndCreateTime() != null) {  
166 - taskQuery.taskCreatedBefore(pageVO.getEndCreateTime());  
167 - }  
168 - // 执行查询  
169 - List<HistoricTaskInstance> tasks = taskQuery.listPage(PageUtils.getStart(pageVO), pageVO.getPageSize());  
170 - if (CollUtil.isEmpty(tasks)) {  
171 - return PageResult.empty(taskQuery.count());  
172 - }  
173 -  
174 - // 获得 TaskExtDO Map  
175 - List<BpmTaskExtDO> bpmTaskExtDOs = taskExtMapper.selectListByTaskIds(convertSet(tasks, HistoricTaskInstance::getId));  
176 - Map<String, BpmTaskExtDO> bpmTaskExtDOMap = convertMap(bpmTaskExtDOs, BpmTaskExtDO::getTaskId);  
177 - // 获得 ProcessInstance Map  
178 - Map<String, HistoricProcessInstance> historicProcessInstanceMap = processInstanceService.getHistoricProcessInstanceMap(  
179 - convertSet(tasks, HistoricTaskInstance::getProcessInstanceId));  
180 - // 获得 User Map  
181 - Map<Long, AdminUserRespDTO> userMap = adminUserApi.getUserMap(  
182 - convertSet(historicProcessInstanceMap.values(), instance -> Long.valueOf(instance.getStartUserId())));  
183 - // 拼接结果  
184 - return new PageResult<>(BpmTaskConvert.INSTANCE.convertList2(tasks, bpmTaskExtDOMap, historicProcessInstanceMap, userMap),  
185 - taskQuery.count());  
186 - }  
187 -  
188 - @Override  
189 - public void updateTaskAssignee(Long userId, BpmTaskUpdateAssigneeReqVO reqVO) {  
190 - // 校验任务存在  
191 - Task task = getTask(reqVO.getId());  
192 - if (task == null) {  
193 - throw exception(TASK_COMPLETE_FAIL_NOT_EXISTS);  
194 - }  
195 - if (!ActivitiUtils.equals(task.getAssignee(), userId)) {  
196 - throw exception(TASK_COMPLETE_FAIL_ASSIGN_NOT_SELF);  
197 - }  
198 -  
199 - // 更新负责人  
200 - updateTaskAssignee(task.getId(), reqVO.getAssigneeUserId());  
201 - }  
202 -  
203 - @Override  
204 - public void updateTaskAssignee(String id, Long userId) {  
205 - taskService.setAssignee(id, String.valueOf(userId));  
206 - }  
207 -  
208 - @Override  
209 - @Transactional(rollbackFor = Exception.class)  
210 - public void approveTask(Long userId, BpmTaskApproveReqVO reqVO) {  
211 - // 校验任务存在  
212 - Task task = getTask(reqVO.getId());  
213 - if (task == null) {  
214 - throw exception(TASK_COMPLETE_FAIL_NOT_EXISTS);  
215 - }  
216 - if (!ActivitiUtils.equals(task.getAssignee(), userId)) {  
217 - throw exception(TASK_COMPLETE_FAIL_ASSIGN_NOT_SELF);  
218 - }  
219 - // 校验流程实例存在  
220 - ProcessInstance instance = processInstanceService.getProcessInstance(task.getProcessInstanceId());  
221 - if (instance == null) {  
222 - throw exception(PROCESS_INSTANCE_NOT_EXISTS);  
223 - }  
224 -  
225 - // 完成任务,审批通过  
226 - taskService.complete(task.getId(), instance.getProcessVariables()); // TODO 芋艿:variables 的选择  
227 - // 更新任务拓展表为通过  
228 - taskExtMapper.updateByTaskId(new BpmTaskExtDO().setTaskId(task.getId())  
229 - .setResult(BpmProcessInstanceResultEnum.APPROVE.getResult()).setReason(reqVO.getReason()));  
230 -  
231 - // TODO 芋艿:添加评论  
232 -// taskService.addComment(task.getId(), task.getProcessInstanceId(), reqVO.getComment());  
233 - }  
234 -  
235 - @Override  
236 - @Transactional(rollbackFor = Exception.class)  
237 - public void rejectTask(Long userId, @Valid BpmTaskRejectReqVO reqVO) {  
238 - // 校验任务存在  
239 - Task task = getTask(reqVO.getId());  
240 - if (task == null) {  
241 - throw exception(TASK_COMPLETE_FAIL_NOT_EXISTS);  
242 - }  
243 - if (!ActivitiUtils.equals(task.getAssignee(), userId)) {  
244 - throw exception(TASK_COMPLETE_FAIL_ASSIGN_NOT_SELF);  
245 - }  
246 - // 校验流程实例存在  
247 - ProcessInstance instance = processInstanceService.getProcessInstance(task.getProcessInstanceId());  
248 - if (instance == null) {  
249 - throw exception(PROCESS_INSTANCE_NOT_EXISTS);  
250 - }  
251 -  
252 - // 更新流程实例为不通过  
253 - processInstanceService.updateProcessInstanceExtReject(instance.getProcessInstanceId(), reqVO.getReason());  
254 -  
255 - // 更新任务拓展表为不通过  
256 - taskExtMapper.updateByTaskId(new BpmTaskExtDO().setTaskId(task.getId())  
257 - .setResult(BpmProcessInstanceResultEnum.REJECT.getResult()).setReason(reqVO.getReason()));  
258 -  
259 - // TODO 芋艿:添加评论  
260 -// taskService.addComment(task.getId(), task.getProcessInstanceId(), reqVO.getComment());  
261 - }  
262 -  
263 - private Task getTask(String id) {  
264 - return taskService.createTaskQuery().taskId(id).singleResult();  
265 - }  
266 -  
267 - // ========== Task 拓展表相关 ==========  
268 -  
269 - @Override  
270 - public void createTaskExt(org.activiti.api.task.model.Task task) {  
271 - // 插入 BpmTaskExtDO 记录  
272 - BpmTaskExtDO taskExtDO = BpmTaskConvert.INSTANCE.convert(task)  
273 - .setResult(BpmProcessInstanceResultEnum.PROCESS.getResult());  
274 - taskExtMapper.insert(taskExtDO);  
275 - }  
276 -  
277 - @Override  
278 - public void updateTaskExt(org.activiti.api.task.model.Task task) {  
279 - BpmTaskExtDO taskExtDO = BpmTaskConvert.INSTANCE.convert(task);  
280 - taskExtMapper.updateByTaskId(taskExtDO);  
281 - }  
282 -  
283 - @Override  
284 - public void updateTaskExtAssign(org.activiti.api.task.model.Task task) {  
285 - // 更新  
286 - updateTaskExt(task);  
287 - // 发送通知。由于 Activiti 操作是在事务提交时,批量执行操作,所以直接查询会无法查询到 ProcessInstance,所以这里是通过监听事务的提交来实现。  
288 - TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronization() {  
289 - @Override  
290 - public void afterCommit() {  
291 - ProcessInstance processInstance = processInstanceService.getProcessInstance(task.getProcessInstanceId());  
292 - AdminUserRespDTO startUser = adminUserApi.getUser(Long.valueOf(processInstance.getStartUserId()));  
293 - messageService.sendMessageWhenTaskAssigned(BpmTaskConvert.INSTANCE.convert(processInstance, startUser, task));  
294 - }  
295 - });  
296 - }  
297 -  
298 - @Override  
299 - public void updateTaskExtCancel(org.activiti.api.task.model.Task task) {  
300 - BpmTaskExtDO taskExtDO = BpmTaskConvert.INSTANCE.convert(task)  
301 - .setEndTime(new Date()) // 由于 Task 里没有办法拿到 endTime,所以这里设置  
302 - .setResult(BpmProcessInstanceResultEnum.CANCEL.getResult());  
303 - taskExtMapper.updateByTaskId(taskExtDO);  
304 - }  
305 -  
306 - @Override  
307 - public void updateTaskExtComplete(org.activiti.api.task.model.Task task) {  
308 - BpmTaskExtDO taskExtDO = BpmTaskConvert.INSTANCE.convert(task)  
309 - .setEndTime(new Date()) // 此时不能使用 task 的 completeData,因为还是空的。  
310 - .setResult(BpmProcessInstanceResultEnum.APPROVE.getResult());  
311 - taskExtMapper.updateByTaskId(taskExtDO);  
312 - }  
313 -  
314 - @Override  
315 - public List<BpmTaskExtDO> getTaskExtListByProcessInstanceId(String processInstanceId) {  
316 - return taskExtMapper.selectListByProcessInstanceId(processInstanceId);  
317 - }  
318 -  
319 -}  
yudao-module-bpm/yudao-module-bpm-biz-activiti/src/main/java/cn/iocoder/yudao/module/bpm/service/task/package-info.java deleted
1 -/**  
2 - * task 包下,存放的都是 xxx 实例。例如说:  
3 - * 1. ProcessInstance 是 ProcessDefinition 创建而来的实例;  
4 - * 2. TaskInstance 是 TaskDefinition 创建而来的实例;  
5 - * 3. ActivityInstance 是 BPMN 流程图的每个元素创建的实例;  
6 - *  
7 - * 考虑到 Task 和 Activity 可以比较明确表示名字,所以对应的 Service 就没有使用 Instance 后缀~  
8 - * 嘿嘿,其实也是实现到比较后面的阶段,所以就暂时没去统一和修改了~  
9 - *  
10 - * @author 芋道源码  
11 - */  
12 -package cn.iocoder.yudao.module.bpm.service.task;  
yudao-module-bpm/yudao-module-bpm-biz-activiti/src/test/java/cn/iocoder/yudao/module/bpm/service/package-info.java deleted
1 -package cn.iocoder.yudao.module.bpm.service;  
yudao-module-bpm/yudao-module-bpm-biz-activiti/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; # 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 - # Redis 配置。Redisson 默认的配置足够使用,一般不需要进行调优  
24 - redis:  
25 - host: 127.0.0.1 # 地址  
26 - port: 16379 # 端口(单元测试,使用 16379 端口)  
27 - database: 0 # 数据库索引  
28 -  
29 -mybatis:  
30 - lazy-initialization: true # 单元测试,设置 MyBatis Mapper 延迟加载,加速每个单元测试  
31 -  
32 ---- #################### 定时任务相关配置 ####################  
33 -  
34 ---- #################### 配置中心相关配置 ####################  
35 -  
36 ---- #################### 服务保障相关配置 ####################  
37 -  
38 -# Lock4j 配置项(单元测试,禁用 Lock4j)  
39 -  
40 -# Resilience4j 配置项  
41 -  
42 ---- #################### 监控相关配置 ####################  
43 -  
44 ---- #################### 芋道相关配置 ####################  
45 -  
46 -# 芋道配置项,设置当前项目所有自定义的配置  
47 -yudao:  
48 - info:  
49 - base-package: cn.iocoder.yudao.module  
yudao-module-bpm/yudao-module-bpm-biz-activiti/src/test/resources/logback.xml deleted
1 -<configuration>  
2 - <!-- 引用 Spring Boot 的 logback 基础配置 -->  
3 - <include resource="org/springframework/boot/logging/logback/defaults.xml" />  
4 -</configuration>  
yudao-module-bpm/yudao-module-bpm-biz-activiti/src/test/resources/sql/clean.sql deleted
yudao-module-bpm/yudao-module-bpm-biz-activiti/src/test/resources/sql/create_tables.sql deleted
yudao-module-bpm/yudao-module-bpm-biz-flowable/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-flowable</artifactId>  
12 - <packaging>jar</packaging>  
13 -  
14 - <name>${project.artifactId}</name>  
15 - <description>  
16 - bpm-flowable 模块,基于 Flowable 6 实现工作流  
17 - </description>  
18 -  
19 - <dependencies>  
20 - <dependency>  
21 - <groupId>cn.iocoder.boot</groupId>  
22 - <artifactId>yudao-module-bpm-base</artifactId>  
23 - <version>${revision}</version>  
24 - </dependency>  
25 -  
26 - <!-- 工作流相关 -->  
27 - <dependency>  
28 - <groupId>cn.iocoder.boot</groupId>  
29 - <artifactId>yudao-spring-boot-starter-flowable</artifactId>  
30 - </dependency>  
31 -  
32 - <!-- Test 测试相关 -->  
33 - <dependency>  
34 - <groupId>cn.iocoder.boot</groupId>  
35 - <artifactId>yudao-spring-boot-starter-test</artifactId>  
36 - <scope>test</scope>  
37 - </dependency>  
38 - </dependencies>  
39 -  
40 -</project>  
yudao-module-bpm/yudao-module-bpm-biz-flowable/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-flowable/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/BpmTaskAssignRuleController.java deleted
1 -package cn.iocoder.yudao.module.bpm.controller.admin.definition;  
2 -  
3 -import cn.iocoder.yudao.framework.common.pojo.CommonResult;  
4 -import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.rule.BpmTaskAssignRuleCreateReqVO;  
5 -import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.rule.BpmTaskAssignRuleRespVO;  
6 -import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.rule.BpmTaskAssignRuleUpdateReqVO;  
7 -import cn.iocoder.yudao.module.bpm.service.definition.BpmTaskAssignRuleService;  
8 -import io.swagger.annotations.Api;  
9 -import io.swagger.annotations.ApiImplicitParam;  
10 -import io.swagger.annotations.ApiImplicitParams;  
11 -import io.swagger.annotations.ApiOperation;  
12 -import org.springframework.security.access.prepost.PreAuthorize;  
13 -import org.springframework.validation.annotation.Validated;  
14 -import org.springframework.web.bind.annotation.*;  
15 -  
16 -import javax.annotation.Resource;  
17 -import javax.validation.Valid;  
18 -import java.util.List;  
19 -  
20 -import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;  
21 -  
22 -@Api(tags = "管理后台 - 任务分配规则")  
23 -@RestController  
24 -@RequestMapping("/bpm/task-assign-rule")  
25 -@Validated  
26 -public class BpmTaskAssignRuleController {  
27 -  
28 - @Resource  
29 - private BpmTaskAssignRuleService taskAssignRuleService;  
30 -  
31 - @GetMapping("/list")  
32 - @ApiOperation(value = "获得任务分配规则列表")  
33 - @ApiImplicitParams({  
34 - @ApiImplicitParam(name = "modelId", value = "模型编号", example = "1024", dataTypeClass = String.class),  
35 - @ApiImplicitParam(name = "processDefinitionId", value = "流程定义的编号", example = "2048", dataTypeClass = String.class)  
36 - })  
37 - @PreAuthorize("@ss.hasPermission('bpm:task-assign-rule:query')")  
38 - public CommonResult<List<BpmTaskAssignRuleRespVO>> getTaskAssignRuleList(  
39 - @RequestParam(value = "modelId", required = false) String modelId,  
40 - @RequestParam(value = "processDefinitionId", required = false) String processDefinitionId) {  
41 - return success(taskAssignRuleService.getTaskAssignRuleList(modelId, processDefinitionId));  
42 - }  
43 -  
44 - @PostMapping("/create")  
45 - @ApiOperation(value = "创建任务分配规则")  
46 - @PreAuthorize("@ss.hasPermission('bpm:task-assign-rule:create')")  
47 - public CommonResult<Long> createTaskAssignRule(@Valid @RequestBody BpmTaskAssignRuleCreateReqVO reqVO) {  
48 - return success(taskAssignRuleService.createTaskAssignRule(reqVO));  
49 - }  
50 -  
51 - @PutMapping("/update")  
52 - @ApiOperation(value = "更新任务分配规则")  
53 - @PreAuthorize("@ss.hasPermission('bpm:task-assign-rule:update')")  
54 - public CommonResult<Boolean> updateTaskAssignRule(@Valid @RequestBody BpmTaskAssignRuleUpdateReqVO reqVO) {  
55 - taskAssignRuleService.updateTaskAssignRule(reqVO);  
56 - return success(true);  
57 - }  
58 -}  
yudao-module-bpm/yudao-module-bpm-biz-flowable/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/BpmProcessInstanceController.java deleted
1 -package cn.iocoder.yudao.module.bpm.controller.admin.task;  
2 -  
3 -import cn.iocoder.yudao.framework.common.pojo.CommonResult;  
4 -import cn.iocoder.yudao.framework.common.pojo.PageResult;  
5 -import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance.*;  
6 -import cn.iocoder.yudao.module.bpm.service.task.BpmProcessInstanceService;  
7 -import io.swagger.annotations.Api;  
8 -import io.swagger.annotations.ApiImplicitParam;  
9 -import io.swagger.annotations.ApiOperation;  
10 -import org.springframework.security.access.prepost.PreAuthorize;  
11 -import org.springframework.validation.annotation.Validated;  
12 -import org.springframework.web.bind.annotation.*;  
13 -  
14 -import javax.annotation.Resource;  
15 -import javax.validation.Valid;  
16 -  
17 -import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;  
18 -import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;  
19 -  
20 -@Api(tags = "管理后台 - 流程实例") // 流程实例,通过流程定义创建的一次“申请”  
21 -@RestController  
22 -@RequestMapping("/bpm/process-instance")  
23 -@Validated  
24 -public class BpmProcessInstanceController {  
25 - @Resource  
26 - private BpmProcessInstanceService processInstanceService;  
27 -  
28 - @GetMapping("/my-page")  
29 - @ApiOperation(value = "获得我的实例分页列表", notes = "在【我的流程】菜单中,进行调用")  
30 - @PreAuthorize("@ss.hasPermission('bpm:process-instance:query')")  
31 - public CommonResult<PageResult<BpmProcessInstancePageItemRespVO>> getMyProcessInstancePage(  
32 - @Valid BpmProcessInstanceMyPageReqVO pageReqVO) {  
33 - return success(processInstanceService.getMyProcessInstancePage(getLoginUserId(), pageReqVO));  
34 - }  
35 -  
36 - @PostMapping("/create")  
37 - @ApiOperation("新建流程实例")  
38 - @PreAuthorize("@ss.hasPermission('bpm:process-instance:query')")  
39 - public CommonResult<String> createProcessInstance(@Valid @RequestBody BpmProcessInstanceCreateReqVO createReqVO) {  
40 - return success(processInstanceService.createProcessInstance(getLoginUserId(), createReqVO));  
41 - }  
42 -  
43 - @GetMapping("/get")  
44 - @ApiOperation(value = "获得指定流程实例", notes = "在【流程详细】界面中,进行调用")  
45 - @ApiImplicitParam(name = "id", value = "流程实例的编号", required = true, dataTypeClass = String.class)  
46 - @PreAuthorize("@ss.hasPermission('bpm:process-instance:query')")  
47 - public CommonResult<BpmProcessInstanceRespVO> getProcessInstance(@RequestParam("id") String id) {  
48 - return success(processInstanceService.getProcessInstanceVO(id));  
49 - }  
50 -  
51 - @DeleteMapping("/cancel")  
52 - @ApiOperation(value = "取消流程实例", notes = "撤回发起的流程")  
53 - @PreAuthorize("@ss.hasPermission('bpm:process-instance:cancel')")  
54 - public CommonResult<Boolean> cancelProcessInstance(@Valid @RequestBody BpmProcessInstanceCancelReqVO cancelReqVO) {  
55 - processInstanceService.cancelProcessInstance(getLoginUserId(), cancelReqVO);  
56 - return success(true);  
57 - }  
58 -}  
yudao-module-bpm/yudao-module-bpm-biz-flowable/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/BpmTaskController.java deleted
1 -package cn.iocoder.yudao.module.bpm.controller.admin.task;  
2 -  
3 -import cn.iocoder.yudao.framework.common.pojo.CommonResult;  
4 -import cn.iocoder.yudao.framework.common.pojo.PageResult;  
5 -import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.task.*;  
6 -import cn.iocoder.yudao.module.bpm.service.task.BpmTaskService;  
7 -import io.swagger.annotations.Api;  
8 -import io.swagger.annotations.ApiImplicitParam;  
9 -import io.swagger.annotations.ApiOperation;  
10 -import org.flowable.bpmn.model.BpmnModel;  
11 -import org.flowable.engine.TaskService;  
12 -import org.springframework.security.access.prepost.PreAuthorize;  
13 -import org.springframework.validation.annotation.Validated;  
14 -import org.springframework.web.bind.annotation.*;  
15 -  
16 -import javax.annotation.Resource;  
17 -import javax.validation.Valid;  
18 -  
19 -import java.util.List;  
20 -  
21 -import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;  
22 -import static cn.iocoder.yudao.framework.web.core.util.WebFrameworkUtils.getLoginUserId;  
23 -  
24 -@Api(tags = "管理后台 - 流程任务实例")  
25 -@RestController  
26 -@RequestMapping("/bpm/task")  
27 -@Validated  
28 -public class BpmTaskController {  
29 -  
30 - @Resource  
31 - private BpmTaskService taskService;  
32 -  
33 - @GetMapping("todo-page")  
34 - @ApiOperation("获取 Todo 待办任务分页")  
35 - @PreAuthorize("@ss.hasPermission('bpm:task:query')")  
36 - public CommonResult<PageResult<BpmTaskTodoPageItemRespVO>> getTodoTaskPage(@Valid BpmTaskTodoPageReqVO pageVO) {  
37 - return success(taskService.getTodoTaskPage(getLoginUserId(), pageVO));  
38 - }  
39 -  
40 - @GetMapping("done-page")  
41 - @ApiOperation("获取 Done 已办任务分页")  
42 - @PreAuthorize("@ss.hasPermission('bpm:task:query')")  
43 - public CommonResult<PageResult<BpmTaskDonePageItemRespVO>> getDoneTaskPage(@Valid BpmTaskDonePageReqVO pageVO) {  
44 - return success(taskService.getDoneTaskPage(getLoginUserId(), pageVO));  
45 - }  
46 -  
47 - @GetMapping("/list-by-process-instance-id")  
48 - @ApiOperation(value = "获得指定流程实例的任务列表", notes = "包括完成的、未完成的")  
49 - @ApiImplicitParam(name = "processInstanceId", value = "流程实例的编号", required = true, dataTypeClass = String.class)  
50 - @PreAuthorize("@ss.hasPermission('bpm:task:query')")  
51 - public CommonResult<List<BpmTaskRespVO>> getTaskListByProcessInstanceId(  
52 - @RequestParam("processInstanceId") String processInstanceId) {  
53 - return success(taskService.getTaskListByProcessInstanceId(processInstanceId));  
54 - }  
55 -  
56 - @PutMapping("/approve")  
57 - @ApiOperation("通过任务")  
58 - @PreAuthorize("@ss.hasPermission('bpm:task:update')")  
59 - public CommonResult<Boolean> approveTask(@Valid @RequestBody BpmTaskApproveReqVO reqVO) {  
60 - taskService.approveTask(getLoginUserId(), reqVO);  
61 - return success(true);  
62 - }  
63 -  
64 - @PutMapping("/reject")  
65 - @ApiOperation("不通过任务")  
66 - @PreAuthorize("@ss.hasPermission('bpm:task:update')")  
67 - public CommonResult<Boolean> rejectTask(@Valid @RequestBody BpmTaskRejectReqVO reqVO) {  
68 - taskService.rejectTask(getLoginUserId(), reqVO);  
69 - return success(true);  
70 - }  
71 -  
72 - @PutMapping("/update-assignee")  
73 - @ApiOperation(value = "更新任务的负责人", notes = "用于【流程详情】的【转派】按钮")  
74 - @PreAuthorize("@ss.hasPermission('bpm:task:update')")  
75 - public CommonResult<Boolean> updateTaskAssignee(@Valid @RequestBody BpmTaskUpdateAssigneeReqVO reqVO) {  
76 - taskService.updateTaskAssignee(getLoginUserId(), reqVO);  
77 - return success(true);  
78 - }  
79 -}  
yudao-module-bpm/yudao-module-bpm-biz-flowable/src/main/java/cn/iocoder/yudao/module/bpm/controller/app/package-info.java deleted
1 -/**  
2 - * 占位  
3 - */  
4 -package cn.iocoder.yudao.module.bpm.controller.app;  
yudao-module-bpm/yudao-module-bpm-biz-flowable/src/main/java/cn/iocoder/yudao/module/bpm/controller/package-info.java deleted
1 -/**  
2 - * 提供 RESTful API 给前端:  
3 - * 1. admin 包:提供给管理后台 yudao-ui-admin 前端项目  
4 - * 2. app 包:提供给用户 APP yudao-ui-app 前端项目,它的 Controller 和 VO 都要添加 App 前缀,用于和管理后台进行区分  
5 - */  
6 -package cn.iocoder.yudao.module.bpm.controller;  
yudao-module-bpm/yudao-module-bpm-biz-flowable/src/main/java/cn/iocoder/yudao/module/bpm/convert/package-info.java deleted
1 -/**  
2 - * 提供 POJO 类的实体转换  
3 - *  
4 - * 目前使用 MapStruct 框架  
5 - */  
6 -package cn.iocoder.yudao.module.bpm.convert;  
yudao-module-bpm/yudao-module-bpm-biz-flowable/src/main/java/cn/iocoder/yudao/module/bpm/convert/《芋道 Spring Boot 对象转换 MapStruct 入门》.md deleted
1 -<http://www.iocoder.cn/Spring-Boot/MapStruct/?yudao>  
yudao-module-bpm/yudao-module-bpm-biz-flowable/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/behavior/BpmUserTaskActivityBehavior.java deleted
1 -package cn.iocoder.yudao.module.bpm.framework.flowable.core.behavior;  
2 -  
3 -import cn.hutool.core.collection.CollUtil;  
4 -import cn.hutool.core.util.RandomUtil;  
5 -import cn.hutool.core.util.StrUtil;  
6 -import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;  
7 -import cn.iocoder.yudao.framework.datapermission.core.annotation.DataPermission;  
8 -import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmTaskAssignRuleDO;  
9 -import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmUserGroupDO;  
10 -import cn.iocoder.yudao.module.bpm.enums.definition.BpmTaskAssignRuleTypeEnum;  
11 -import cn.iocoder.yudao.module.bpm.framework.flowable.core.behavior.script.BpmTaskAssignScript;  
12 -import cn.iocoder.yudao.module.bpm.service.definition.BpmTaskAssignRuleService;  
13 -import cn.iocoder.yudao.module.bpm.service.definition.BpmUserGroupService;  
14 -import cn.iocoder.yudao.module.system.api.dept.DeptApi;  
15 -import cn.iocoder.yudao.module.system.api.dept.dto.DeptRespDTO;  
16 -import cn.iocoder.yudao.module.system.api.permission.PermissionApi;  
17 -import cn.iocoder.yudao.module.system.api.user.AdminUserApi;  
18 -import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;  
19 -import com.google.common.annotations.VisibleForTesting;  
20 -import lombok.Setter;  
21 -import lombok.extern.slf4j.Slf4j;  
22 -import org.flowable.bpmn.model.UserTask;  
23 -import org.flowable.common.engine.api.FlowableException;  
24 -import org.flowable.common.engine.impl.el.ExpressionManager;  
25 -import org.flowable.engine.delegate.DelegateExecution;  
26 -import org.flowable.engine.impl.bpmn.behavior.UserTaskActivityBehavior;  
27 -import org.flowable.engine.impl.cfg.ProcessEngineConfigurationImpl;  
28 -import org.flowable.engine.impl.util.TaskHelper;  
29 -import org.flowable.task.service.TaskService;  
30 -import org.flowable.task.service.impl.persistence.entity.TaskEntity;  
31 -  
32 -import java.util.*;  
33 -  
34 -import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;  
35 -import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap;  
36 -import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;  
37 -import static cn.iocoder.yudao.framework.common.util.json.JsonUtils.toJsonString;  
38 -import static cn.iocoder.yudao.module.bpm.enums.ErrorCodeConstants.TASK_ASSIGN_SCRIPT_NOT_EXISTS;  
39 -import static cn.iocoder.yudao.module.bpm.enums.ErrorCodeConstants.TASK_CREATE_FAIL_NO_CANDIDATE_USER;  
40 -  
41 -/**  
42 - * 自定义的流程任务的 assignee 负责人的分配  
43 - * 第一步,获得对应的分配规则;  
44 - * 第二步,根据分配规则,计算出分配任务的候选人。如果找不到,则直接报业务异常,不继续执行后续的流程;  
45 - * 第三步,随机选择一个候选人,则选择作为 assignee 负责人。  
46 - *  
47 - * @author 芋道源码  
48 - */  
49 -@Slf4j  
50 -public class BpmUserTaskActivityBehavior extends UserTaskActivityBehavior {  
51 -  
52 - @Setter  
53 - private BpmTaskAssignRuleService bpmTaskRuleService;  
54 - @Setter  
55 - private BpmUserGroupService userGroupService;  
56 - @Setter  
57 - private DeptApi deptApi;  
58 - @Setter  
59 - private AdminUserApi adminUserApi;  
60 - @Setter  
61 - private PermissionApi permissionApi;  
62 -  
63 - /**  
64 - * 任务分配脚本  
65 - */  
66 - private Map<Long, BpmTaskAssignScript> scriptMap = Collections.emptyMap();  
67 -  
68 - public BpmUserTaskActivityBehavior(UserTask userTask) {  
69 - super(userTask);  
70 - }  
71 -  
72 - public void setScripts(List<BpmTaskAssignScript> scripts) {  
73 - this.scriptMap = convertMap(scripts, script -> script.getEnum().getId());  
74 - }  
75 -  
76 - @Override  
77 - @DataPermission(enable = false) // 不需要处理数据权限, 不然会有问题,查询不到数据  
78 - protected void handleAssignments(TaskService taskService, String assignee, String owner, List<String> candidateUsers, List<String> candidateGroups, TaskEntity task, ExpressionManager expressionManager, DelegateExecution execution, ProcessEngineConfigurationImpl processEngineConfiguration) {  
79 - // 第一步,获得任务的规则  
80 - BpmTaskAssignRuleDO rule = getTaskRule(task);  
81 - // 第二步,获得任务的候选用户们  
82 - Set<Long> candidateUserIds = calculateTaskCandidateUsers(task, rule);  
83 - // 第三步,设置一个作为负责人  
84 - Long assigneeUserId = chooseTaskAssignee(candidateUserIds);  
85 - TaskHelper.changeTaskAssignee(task, String.valueOf(assigneeUserId));  
86 - }  
87 -  
88 - private BpmTaskAssignRuleDO getTaskRule(TaskEntity task) {  
89 - List<BpmTaskAssignRuleDO> taskRules = bpmTaskRuleService.getTaskAssignRuleListByProcessDefinitionId(task.getProcessDefinitionId(),  
90 - task.getTaskDefinitionKey());  
91 - if (CollUtil.isEmpty(taskRules)) {  
92 - throw new FlowableException(StrUtil.format("流程任务({}/{}/{}) 找不到符合的任务规则",  
93 - task.getId(), task.getProcessDefinitionId(), task.getTaskDefinitionKey()));  
94 - }  
95 - if (taskRules.size() > 1) {  
96 - throw new FlowableException(StrUtil.format("流程任务({}/{}/{}) 找到过多任务规则({})",  
97 - task.getId(), task.getProcessDefinitionId(), task.getTaskDefinitionKey(), taskRules.size()));  
98 - }  
99 - return taskRules.get(0);  
100 - }  
101 -  
102 - Set<Long> calculateTaskCandidateUsers(TaskEntity task, BpmTaskAssignRuleDO rule) {  
103 - Set<Long> assigneeUserIds = null;  
104 - if (Objects.equals(BpmTaskAssignRuleTypeEnum.ROLE.getType(), rule.getType())) {  
105 - assigneeUserIds = calculateTaskCandidateUsersByRole(task, rule);  
106 - } else if (Objects.equals(BpmTaskAssignRuleTypeEnum.DEPT_MEMBER.getType(), rule.getType())) {  
107 - assigneeUserIds = calculateTaskCandidateUsersByDeptMember(task, rule);  
108 - } else if (Objects.equals(BpmTaskAssignRuleTypeEnum.DEPT_LEADER.getType(), rule.getType())) {  
109 - assigneeUserIds = calculateTaskCandidateUsersByDeptLeader(task, rule);  
110 - } else if (Objects.equals(BpmTaskAssignRuleTypeEnum.POST.getType(), rule.getType())) {  
111 - assigneeUserIds = calculateTaskCandidateUsersByPost(task, rule);  
112 - } else if (Objects.equals(BpmTaskAssignRuleTypeEnum.USER.getType(), rule.getType())) {  
113 - assigneeUserIds = calculateTaskCandidateUsersByUser(task, rule);  
114 - } else if (Objects.equals(BpmTaskAssignRuleTypeEnum.USER_GROUP.getType(), rule.getType())) {  
115 - assigneeUserIds = calculateTaskCandidateUsersByUserGroup(task, rule);  
116 - } else if (Objects.equals(BpmTaskAssignRuleTypeEnum.SCRIPT.getType(), rule.getType())) {  
117 - assigneeUserIds = calculateTaskCandidateUsersByScript(task, rule);  
118 - }  
119 -  
120 - // 移除被禁用的用户  
121 - removeDisableUsers(assigneeUserIds);  
122 - // 如果候选人为空,抛出异常 TODO 芋艿:没候选人的策略选择。1 - 挂起;2 - 直接结束;3 - 强制一个兜底人  
123 - if (CollUtil.isEmpty(assigneeUserIds)) {  
124 - log.error("[calculateTaskCandidateUsers][流程任务({}/{}/{}) 任务规则({}) 找不到候选人]",  
125 - task.getId(), task.getProcessDefinitionId(), task.getTaskDefinitionKey(), toJsonString(rule));  
126 - throw exception(TASK_CREATE_FAIL_NO_CANDIDATE_USER);  
127 - }  
128 - return assigneeUserIds;  
129 - }  
130 -  
131 - private Set<Long> calculateTaskCandidateUsersByRole(TaskEntity task, BpmTaskAssignRuleDO rule) {  
132 - return permissionApi.getUserRoleIdListByRoleIds(rule.getOptions());  
133 - }  
134 -  
135 - private Set<Long> calculateTaskCandidateUsersByDeptMember(TaskEntity task, BpmTaskAssignRuleDO rule) {  
136 - List<AdminUserRespDTO> users = adminUserApi.getUsersByDeptIds(rule.getOptions());  
137 - return convertSet(users, AdminUserRespDTO::getId);  
138 - }  
139 -  
140 - private Set<Long> calculateTaskCandidateUsersByDeptLeader(TaskEntity task, BpmTaskAssignRuleDO rule) {  
141 - List<DeptRespDTO> depts = deptApi.getDepts(rule.getOptions());  
142 - return convertSet(depts, DeptRespDTO::getLeaderUserId);  
143 - }  
144 -  
145 - private Set<Long> calculateTaskCandidateUsersByPost(TaskEntity task, BpmTaskAssignRuleDO rule) {  
146 - List<AdminUserRespDTO> users = adminUserApi.getUsersByPostIds(rule.getOptions());  
147 - return convertSet(users, AdminUserRespDTO::getId);  
148 - }  
149 -  
150 - private Set<Long> calculateTaskCandidateUsersByUser(TaskEntity task, BpmTaskAssignRuleDO rule) {  
151 - return rule.getOptions();  
152 - }  
153 -  
154 - private Set<Long> calculateTaskCandidateUsersByUserGroup(TaskEntity task, BpmTaskAssignRuleDO rule) {  
155 - List<BpmUserGroupDO> userGroups = userGroupService.getUserGroupList(rule.getOptions());  
156 - Set<Long> userIds = new HashSet<>();  
157 - userGroups.forEach(group -> userIds.addAll(group.getMemberUserIds()));  
158 - return userIds;  
159 - }  
160 -  
161 - private Set<Long> calculateTaskCandidateUsersByScript(TaskEntity task, BpmTaskAssignRuleDO rule) {  
162 - // 获得对应的脚本  
163 - List<BpmTaskAssignScript> scripts = new ArrayList<>(rule.getOptions().size());  
164 - rule.getOptions().forEach(id -> {  
165 - BpmTaskAssignScript script = scriptMap.get(id);  
166 - if (script == null) {  
167 - throw exception(TASK_ASSIGN_SCRIPT_NOT_EXISTS, id);  
168 - }  
169 - scripts.add(script);  
170 - });  
171 - // 逐个计算任务  
172 - Set<Long> userIds = new HashSet<>();  
173 - scripts.forEach(script -> CollUtil.addAll(userIds, script.calculateTaskCandidateUsers(task)));  
174 - return userIds;  
175 - }  
176 -  
177 - private Long chooseTaskAssignee(Set<Long> candidateUserIds) {  
178 - // TODO 芋艿:未来可以优化下,改成轮询的策略  
179 - int index = RandomUtil.randomInt(candidateUserIds.size());  
180 - return CollUtil.get(candidateUserIds, index);  
181 - }  
182 -  
183 - @VisibleForTesting  
184 - void removeDisableUsers(Set<Long> assigneeUserIds) {  
185 - if (CollUtil.isEmpty(assigneeUserIds)) {  
186 - return;  
187 - }  
188 - //TODO 芋艿 这里有数据权限的问题。默认会加上数据权限 dept_id IN (deptId). 导致查询不到数据  
189 - Map<Long, AdminUserRespDTO> userMap = adminUserApi.getUserMap(assigneeUserIds);  
190 - assigneeUserIds.removeIf(id -> {  
191 - AdminUserRespDTO user = userMap.get(id);  
192 - return user == null || !CommonStatusEnum.ENABLE.getStatus().equals(user.getStatus());  
193 - });  
194 - }  
195 -}  
yudao-module-bpm/yudao-module-bpm-biz-flowable/src/main/java/cn/iocoder/yudao/module/bpm/framework/package-info.java deleted
1 -/**  
2 - * 属于 bpm 模块的 framework 封装  
3 - *  
4 - * @author 芋道源码  
5 - */  
6 -package cn.iocoder.yudao.module.bpm.framework;  
yudao-module-bpm/yudao-module-bpm-biz-flowable/src/main/java/cn/iocoder/yudao/module/bpm/package-info.java deleted
1 -/**  
2 - * bpm 包下,业务流程管理(Business Process Management),我们放工作流的功能,基于 activiti 7 版本实现。  
3 - * 例如说:流程定义、表单配置、审核中心(我的申请、我的待办、我的已办)等等  
4 - *  
5 - * bpm 解释:https://baike.baidu.com/item/BPM/1933  
6 - *  
7 - * 1. Controller URL:以 /bpm/ 开头,避免和其它 Module 冲突  
8 - * 2. DataObject 表名:以 bpm_ 开头,方便在数据库中区分  
9 - *  
10 - * 注意,由于 Bpm 模块下,容易和其它模块重名,所以类名都加载 Pay 的前缀~  
11 - */  
12 -package cn.iocoder.yudao.module.bpm;  
yudao-module-bpm/yudao-module-bpm-biz-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmTaskAssignRuleService.java deleted
1 -package cn.iocoder.yudao.module.bpm.service.definition;  
2 -  
3 -import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.rule.BpmTaskAssignRuleCreateReqVO;  
4 -import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.rule.BpmTaskAssignRuleRespVO;  
5 -import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.rule.BpmTaskAssignRuleUpdateReqVO;  
6 -import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmTaskAssignRuleDO;  
7 -import org.springframework.lang.Nullable;  
8 -  
9 -import javax.validation.Valid;  
10 -import java.util.List;  
11 -  
12 -/**  
13 - * BPM 任务分配规则 Service 接口  
14 - *  
15 - * @author 芋道源码  
16 - */  
17 -public interface BpmTaskAssignRuleService {  
18 -  
19 - /**  
20 - * 获得流程定义的任务分配规则数组  
21 - *  
22 - * @param processDefinitionId 流程定义的编号  
23 - * @param taskDefinitionKey 流程任务定义的 Key。允许空  
24 - * @return 任务规则数组  
25 - */  
26 - List<BpmTaskAssignRuleDO> getTaskAssignRuleListByProcessDefinitionId(String processDefinitionId,  
27 - @Nullable String taskDefinitionKey);  
28 -  
29 - /**  
30 - * 获得流程模型的任务规则数组  
31 - *  
32 - * @param modelId 流程模型的编号  
33 - * @return 任务规则数组  
34 - */  
35 - List<BpmTaskAssignRuleDO> getTaskAssignRuleListByModelId(String modelId);  
36 -  
37 - /**  
38 - * 获得流程定义的任务分配规则数组  
39 - *  
40 - * @param modelId 流程模型的编号  
41 - * @param processDefinitionId 流程定义的编号  
42 - * @return 任务规则数组  
43 - */  
44 - List<BpmTaskAssignRuleRespVO> getTaskAssignRuleList(String modelId, String processDefinitionId);  
45 -  
46 - /**  
47 - * 创建任务分配规则  
48 - *  
49 - * @param reqVO 创建信息  
50 - * @return 规则编号  
51 - */  
52 - Long createTaskAssignRule(@Valid BpmTaskAssignRuleCreateReqVO reqVO);  
53 -  
54 - /**  
55 - * 更新任务分配规则  
56 - *  
57 - * @param reqVO 创建信息  
58 - */  
59 - void updateTaskAssignRule(@Valid BpmTaskAssignRuleUpdateReqVO reqVO);  
60 -  
61 - /**  
62 - * 判断指定流程模型和流程定义的分配规则是否相等  
63 - *  
64 - * @param modelId 流程模型编号  
65 - * @param processDefinitionId 流程定义编号  
66 - * @return 是否相等  
67 - */  
68 - boolean isTaskAssignRulesEquals(String modelId, String processDefinitionId);  
69 -  
70 - /**  
71 - * 将流程流程模型的任务分配规则,复制一份给流程定义  
72 - * 目的:每次流程模型部署时,都会生成一个新的流程定义,此时考虑到每次部署的流程不可变性,所以需要复制一份给该流程定义  
73 - *  
74 - * @param fromModelId 流程模型编号  
75 - * @param toProcessDefinitionId 流程定义编号  
76 - */  
77 - void copyTaskAssignRules(String fromModelId, String toProcessDefinitionId);  
78 -  
79 - /**  
80 - * 校验流程模型的任务分配规则全部都配置了  
81 - * 目的:如果有规则未配置,会导致流程任务找不到负责人,进而流程无法进行下去!  
82 - *  
83 - * @param id 流程模型编号  
84 - */  
85 - void checkTaskAssignRuleAllConfig(String id);  
86 -  
87 -}  
yudao-module-bpm/yudao-module-bpm-biz-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmProcessInstanceServiceImpl.java deleted
1 -package cn.iocoder.yudao.module.bpm.service.task;  
2 -  
3 -import cn.hutool.core.collection.CollUtil;  
4 -import cn.hutool.core.lang.Assert;  
5 -import cn.hutool.core.util.StrUtil;  
6 -import cn.iocoder.yudao.framework.common.pojo.PageResult;  
7 -import cn.iocoder.yudao.framework.common.util.number.NumberUtils;  
8 -import cn.iocoder.yudao.module.bpm.api.task.dto.BpmProcessInstanceCreateReqDTO;  
9 -import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance.*;  
10 -import cn.iocoder.yudao.module.bpm.convert.task.BpmProcessInstanceConvert;  
11 -import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmProcessDefinitionExtDO;  
12 -import cn.iocoder.yudao.module.bpm.dal.dataobject.task.BpmProcessInstanceExtDO;  
13 -import cn.iocoder.yudao.module.bpm.dal.mysql.task.BpmProcessInstanceExtMapper;  
14 -import cn.iocoder.yudao.module.bpm.enums.task.BpmProcessInstanceDeleteReasonEnum;  
15 -import cn.iocoder.yudao.module.bpm.enums.task.BpmProcessInstanceResultEnum;  
16 -import cn.iocoder.yudao.module.bpm.enums.task.BpmProcessInstanceStatusEnum;  
17 -import cn.iocoder.yudao.module.bpm.framework.bpm.core.event.BpmProcessInstanceResultEventPublisher;  
18 -import cn.iocoder.yudao.module.bpm.service.definition.BpmProcessDefinitionService;  
19 -import cn.iocoder.yudao.module.bpm.service.message.BpmMessageService;  
20 -import cn.iocoder.yudao.module.system.api.dept.DeptApi;  
21 -import cn.iocoder.yudao.module.system.api.dept.dto.DeptRespDTO;  
22 -import cn.iocoder.yudao.module.system.api.user.AdminUserApi;  
23 -import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;  
24 -import lombok.extern.slf4j.Slf4j;  
25 -import org.flowable.engine.HistoryService;  
26 -import org.flowable.engine.RuntimeService;  
27 -import org.flowable.engine.delegate.event.FlowableCancelledEvent;  
28 -import org.flowable.engine.history.HistoricProcessInstance;  
29 -import org.flowable.engine.repository.ProcessDefinition;  
30 -import org.flowable.engine.runtime.ProcessInstance;  
31 -import org.flowable.task.api.Task;  
32 -import org.springframework.context.annotation.Lazy;  
33 -import org.springframework.stereotype.Service;  
34 -import org.springframework.transaction.annotation.Transactional;  
35 -import org.springframework.validation.annotation.Validated;  
36 -  
37 -import javax.annotation.Resource;  
38 -import javax.validation.Valid;  
39 -import java.util.*;  
40 -  
41 -import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;  
42 -import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList;  
43 -import static cn.iocoder.yudao.module.bpm.enums.ErrorCodeConstants.*;  
44 -import static cn.iocoder.yudao.module.bpm.enums.ErrorCodeConstants.PROCESS_INSTANCE_CANCEL_FAIL_NOT_SELF;  
45 -  
46 -/**  
47 - * 流程实例 Service 实现类  
48 - *  
49 - * ProcessDefinition & ProcessInstance & Execution & Task 的关系:  
50 - * 1. https://blog.csdn.net/bobozai86/article/details/105210414  
51 - *  
52 - * HistoricProcessInstance & ProcessInstance 的关系:  
53 - * 1.https://my.oschina.net/843294669/blog/719024  
54 - * 简单来说,前者 = 历史 + 运行中的流程实例,后者仅是运行中的流程实例  
55 - *  
56 - * @author 芋道源码  
57 - */  
58 -@Service  
59 -@Validated  
60 -@Slf4j  
61 -public class BpmProcessInstanceServiceImpl implements BpmProcessInstanceService {  
62 -  
63 - @Resource  
64 - private RuntimeService runtimeService;  
65 - @Resource  
66 - private BpmProcessInstanceExtMapper processInstanceExtMapper;  
67 - @Resource  
68 - @Lazy // 解决循环依赖  
69 - private BpmTaskService taskService;  
70 - @Resource  
71 - private BpmProcessDefinitionService processDefinitionService;  
72 - @Resource  
73 - private HistoryService historyService;  
74 - @Resource  
75 - private AdminUserApi adminUserApi;  
76 - @Resource  
77 - private DeptApi deptApi;  
78 - @Resource  
79 - private BpmProcessInstanceResultEventPublisher processInstanceResultEventPublisher;  
80 - @Resource  
81 - private BpmMessageService messageService;  
82 - @Override  
83 - public ProcessInstance getProcessInstance(String id) {  
84 - return runtimeService.createProcessInstanceQuery().processInstanceId(id).singleResult();  
85 - }  
86 -  
87 - @Override  
88 - public List<ProcessInstance> getProcessInstances(Set<String> ids) {  
89 - return runtimeService.createProcessInstanceQuery().processInstanceIds(ids).list();  
90 - }  
91 -  
92 - @Override  
93 - public PageResult<BpmProcessInstancePageItemRespVO> getMyProcessInstancePage(Long userId,  
94 - BpmProcessInstanceMyPageReqVO pageReqVO) {  
95 - // 通过 BpmProcessInstanceExtDO 表,先查询到对应的分页  
96 - PageResult<BpmProcessInstanceExtDO> pageResult = processInstanceExtMapper.selectPage(userId, pageReqVO);  
97 - if (CollUtil.isEmpty(pageResult.getList())) {  
98 - return new PageResult<>(pageResult.getTotal());  
99 - }  
100 -  
101 - // 获得流程 Task Map  
102 - List<String> processInstanceIds = convertList(pageResult.getList(), BpmProcessInstanceExtDO::getProcessInstanceId);  
103 - Map<String, List<Task>> taskMap = taskService.getTaskMapByProcessInstanceIds(processInstanceIds);  
104 - // 转换返回  
105 - return BpmProcessInstanceConvert.INSTANCE.convertPage(pageResult, taskMap);  
106 - }  
107 -  
108 - @Override  
109 - @Transactional(rollbackFor = Exception.class)  
110 - public String createProcessInstance(Long userId, @Valid BpmProcessInstanceCreateReqVO createReqVO) {  
111 - // 获得流程定义  
112 - ProcessDefinition definition = processDefinitionService.getProcessDefinition(createReqVO.getProcessDefinitionId());  
113 - // 发起流程  
114 - return createProcessInstance0(userId, definition, createReqVO.getVariables(), null);  
115 - }  
116 -  
117 - @Override  
118 - public String createProcessInstance(Long userId, @Valid BpmProcessInstanceCreateReqDTO createReqDTO) {  
119 - // 获得流程定义  
120 - ProcessDefinition definition = processDefinitionService.getActiveProcessDefinition(createReqDTO.getProcessDefinitionKey());  
121 - // 发起流程  
122 - return createProcessInstance0(userId, definition, createReqDTO.getVariables(), createReqDTO.getBusinessKey());  
123 - }  
124 -  
125 - @Override  
126 - public BpmProcessInstanceRespVO getProcessInstanceVO(String id) {  
127 - // 获得流程实例  
128 - HistoricProcessInstance processInstance = getHistoricProcessInstance(id);  
129 - if (processInstance == null) {  
130 - return null;  
131 - }  
132 - BpmProcessInstanceExtDO processInstanceExt = processInstanceExtMapper.selectByProcessInstanceId(id);  
133 - Assert.notNull(processInstanceExt, "流程实例拓展({}) 不存在", id);  
134 -  
135 - // 获得流程定义  
136 - ProcessDefinition processDefinition = processDefinitionService  
137 - .getProcessDefinition(processInstance.getProcessDefinitionId());  
138 - Assert.notNull(processDefinition, "流程定义({}) 不存在", processInstance.getProcessDefinitionId());  
139 - BpmProcessDefinitionExtDO processDefinitionExt = processDefinitionService.getProcessDefinitionExt(  
140 - processInstance.getProcessDefinitionId());  
141 - Assert.notNull(processDefinitionExt, "流程定义拓展({}) 不存在", id);  
142 - String bpmnXml = processDefinitionService.getProcessDefinitionBpmnXML(processInstance.getProcessDefinitionId());  
143 -  
144 - // 获得 User  
145 - AdminUserRespDTO startUser = adminUserApi.getUser(NumberUtils.parseLong(processInstance.getStartUserId()));  
146 - DeptRespDTO dept = null;  
147 - if (startUser != null) {  
148 - dept = deptApi.getDept(startUser.getDeptId());  
149 - }  
150 -  
151 - // 拼接结果  
152 - return BpmProcessInstanceConvert.INSTANCE.convert2(processInstance, processInstanceExt,  
153 - processDefinition, processDefinitionExt, bpmnXml, startUser, dept);  
154 - }  
155 -  
156 - @Override  
157 - public void cancelProcessInstance(Long userId, @Valid BpmProcessInstanceCancelReqVO cancelReqVO) {  
158 - // 校验流程实例存在  
159 - ProcessInstance instance = getProcessInstance(cancelReqVO.getId());  
160 - if (instance == null) {  
161 - throw exception(PROCESS_INSTANCE_CANCEL_FAIL_NOT_EXISTS);  
162 - }  
163 - // 只能取消自己的  
164 - if (!Objects.equals(instance.getStartUserId(), String.valueOf(userId))) {  
165 - throw exception(PROCESS_INSTANCE_CANCEL_FAIL_NOT_SELF);  
166 - }  
167 -  
168 - // 通过删除流程实例,实现流程实例的取消,  
169 - // 删除流程实例,正则执行任务ACT_RU_TASK. 任务会被删除。通过历史表查询  
170 - deleteProcessInstance(cancelReqVO.getId(),  
171 - BpmProcessInstanceDeleteReasonEnum.CANCEL_TASK.format(cancelReqVO.getReason()));  
172 - }  
173 -  
174 - /**  
175 - * 获得历史的流程实例  
176 - *  
177 - * @param id 流程实例的编号  
178 - * @return 历史的流程实例  
179 - */  
180 - @Override  
181 - public HistoricProcessInstance getHistoricProcessInstance(String id) {  
182 - return historyService.createHistoricProcessInstanceQuery().processInstanceId(id).singleResult();  
183 - }  
184 -  
185 - @Override  
186 - public List<HistoricProcessInstance> getHistoricProcessInstances(Set<String> ids) {  
187 - return historyService.createHistoricProcessInstanceQuery().processInstanceIds(ids).list();  
188 - }  
189 -  
190 - @Override  
191 - public void createProcessInstanceExt(ProcessInstance instance) {  
192 - // 获得流程定义  
193 - ProcessDefinition definition = processDefinitionService.getProcessDefinition2(instance.getProcessDefinitionId());  
194 - // 插入 BpmProcessInstanceExtDO 对象  
195 - BpmProcessInstanceExtDO instanceExtDO = new BpmProcessInstanceExtDO()  
196 - .setProcessInstanceId(instance.getId())  
197 - .setProcessDefinitionId(definition.getId())  
198 - .setName(instance.getProcessDefinitionName())  
199 - .setStartUserId(Long.valueOf(instance.getStartUserId()))  
200 - .setCategory(definition.getCategory())  
201 - .setStatus(BpmProcessInstanceStatusEnum.RUNNING.getStatus())  
202 - .setResult(BpmProcessInstanceResultEnum.PROCESS.getResult());  
203 -  
204 - processInstanceExtMapper.insert(instanceExtDO);  
205 - }  
206 -  
207 - @Override  
208 - public void updateProcessInstanceExtCancel(FlowableCancelledEvent event) {  
209 - // 判断是否为 Reject 不通过。如果是,则不进行更新  
210 - if (BpmProcessInstanceDeleteReasonEnum.isRejectReason((String)event.getCause())) {  
211 - return;  
212 - }  
213 -  
214 - // 需要主动查询,因为 instance 只有 id 属性  
215 - // 另外,此时如果去查询 ProcessInstance 的话,字段是不全的,所以去查询了 HistoricProcessInstance  
216 - HistoricProcessInstance processInstance = getHistoricProcessInstance(event.getProcessInstanceId());  
217 - // 更新拓展表  
218 - BpmProcessInstanceExtDO instanceExtDO = new BpmProcessInstanceExtDO()  
219 - .setProcessInstanceId(event.getProcessInstanceId())  
220 - .setEndTime(new Date()) // 由于 ProcessInstance 里没有办法拿到 endTime,所以这里设置  
221 - .setStatus(BpmProcessInstanceStatusEnum.FINISH.getStatus())  
222 - .setResult(BpmProcessInstanceResultEnum.CANCEL.getResult());  
223 -  
224 - processInstanceExtMapper.updateByProcessInstanceId(instanceExtDO);  
225 -  
226 - // 发送流程实例的状态事件  
227 - processInstanceResultEventPublisher.sendProcessInstanceResultEvent(  
228 - BpmProcessInstanceConvert.INSTANCE.convert(this, processInstance, instanceExtDO.getResult()));  
229 - }  
230 -  
231 - @Override  
232 - public void updateProcessInstanceExtComplete(ProcessInstance instance) {  
233 - // 需要主动查询,因为 instance 只有 id 属性  
234 - // 另外,此时如果去查询 ProcessInstance 的话,字段是不全的,所以去查询了 HistoricProcessInstance  
235 - HistoricProcessInstance processInstance = getHistoricProcessInstance(instance.getId());  
236 - // 更新拓展表  
237 - BpmProcessInstanceExtDO instanceExtDO = new BpmProcessInstanceExtDO()  
238 - .setProcessInstanceId(instance.getProcessInstanceId())  
239 - .setEndTime(new Date()) // 由于 ProcessInstance 里没有办法拿到 endTime,所以这里设置  
240 - .setStatus(BpmProcessInstanceStatusEnum.FINISH.getStatus())  
241 - .setResult(BpmProcessInstanceResultEnum.APPROVE.getResult()); // 如果正常完全,说明审批通过  
242 - processInstanceExtMapper.updateByProcessInstanceId(instanceExtDO);  
243 -  
244 - // 发送流程被通过的消息  
245 - messageService.sendMessageWhenProcessInstanceApprove(BpmProcessInstanceConvert.INSTANCE.convert2ApprovedReq(instance));  
246 -  
247 - // 发送流程实例的状态事件  
248 - processInstanceResultEventPublisher.sendProcessInstanceResultEvent(  
249 - BpmProcessInstanceConvert.INSTANCE.convert(this, processInstance, instanceExtDO.getResult()));  
250 - }  
251 -  
252 - @Transactional(rollbackFor = Exception.class)  
253 - public void updateProcessInstanceExtReject(String id, String reason) {  
254 - // 需要主动查询,因为 instance 只有 id 属性  
255 - ProcessInstance processInstance = getProcessInstance(id);  
256 - // 删除流程实例,以实现驳回任务时,取消整个审批流程  
257 - deleteProcessInstance(id, StrUtil.format(BpmProcessInstanceDeleteReasonEnum.REJECT_TASK.format(reason)));  
258 -  
259 - // 更新 status + result  
260 - // 注意,不能和上面的逻辑更换位置。因为 deleteProcessInstance 会触发流程的取消,进而调用 updateProcessInstanceExtCancel 方法,  
261 - // 设置 result 为 BpmProcessInstanceStatusEnum.CANCEL,显然和 result 不一定是一致的  
262 - BpmProcessInstanceExtDO instanceExtDO = new BpmProcessInstanceExtDO().setProcessInstanceId(id)  
263 - .setStatus(BpmProcessInstanceStatusEnum.FINISH.getStatus())  
264 - .setResult(BpmProcessInstanceResultEnum.REJECT.getResult());  
265 - processInstanceExtMapper.updateByProcessInstanceId(instanceExtDO);  
266 -  
267 - // 发送流程被不通过的消息  
268 - messageService.sendMessageWhenProcessInstanceReject(BpmProcessInstanceConvert.INSTANCE.convert2RejectReq(processInstance, reason));  
269 -  
270 - // 发送流程实例的状态事件  
271 - processInstanceResultEventPublisher.sendProcessInstanceResultEvent(  
272 - BpmProcessInstanceConvert.INSTANCE.convert(this, processInstance, instanceExtDO.getResult()));  
273 - }  
274 -  
275 - private void deleteProcessInstance(String id, String reason) {  
276 - runtimeService.deleteProcessInstance(id, reason);  
277 - }  
278 -  
279 - private String createProcessInstance0(Long userId, ProcessDefinition definition,  
280 - Map<String, Object> variables, String businessKey) {  
281 - // 校验流程定义  
282 - if (definition == null) {  
283 - throw exception(PROCESS_DEFINITION_NOT_EXISTS);  
284 - }  
285 - if (definition.isSuspended()) {  
286 - throw exception(PROCESS_DEFINITION_IS_SUSPENDED);  
287 - }  
288 -  
289 - // 创建流程实例  
290 - ProcessInstance instance = runtimeService.startProcessInstanceById(definition.getId(), businessKey, variables);  
291 - // 设置流程名字  
292 - runtimeService.setProcessInstanceName(instance.getId(), definition.getName());  
293 -  
294 - // 补全流程实例的拓展表  
295 - processInstanceExtMapper.updateByProcessInstanceId(new BpmProcessInstanceExtDO().setProcessInstanceId(instance.getId())  
296 - .setFormVariables(variables));  
297 -  
298 - return instance.getId();  
299 - }  
300 -}  
yudao-module-bpm/yudao-module-bpm-base/pom.xml renamed to yudao-module-bpm/yudao-module-bpm-biz/pom.xml
@@ -8,7 +8,7 @@ @@ -8,7 +8,7 @@
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 - <artifactId>yudao-module-bpm-base</artifactId> 11 + <artifactId>yudao-module-bpm-biz</artifactId>
12 12
13 <name>${project.artifactId}</name> 13 <name>${project.artifactId}</name>
14 <description> 14 <description>
@@ -26,6 +26,11 @@ @@ -26,6 +26,11 @@
26 <artifactId>yudao-module-system-api</artifactId> 26 <artifactId>yudao-module-system-api</artifactId>
27 <version>${revision}</version> 27 <version>${revision}</version>
28 </dependency> 28 </dependency>
  29 + <dependency>
  30 + <groupId>cn.iocoder.boot</groupId>
  31 + <artifactId>yudao-module-system-biz</artifactId>
  32 + <version>${revision}</version>
  33 + </dependency>
29 34
30 <!-- 业务组件 --> 35 <!-- 业务组件 -->
31 <dependency> 36 <dependency>
@@ -36,6 +41,10 @@ @@ -36,6 +41,10 @@
36 <groupId>cn.iocoder.boot</groupId> 41 <groupId>cn.iocoder.boot</groupId>
37 <artifactId>yudao-spring-boot-starter-biz-data-permission</artifactId> 42 <artifactId>yudao-spring-boot-starter-biz-data-permission</artifactId>
38 </dependency> 43 </dependency>
  44 + <dependency>
  45 + <groupId>cn.iocoder.boot</groupId>
  46 + <artifactId>yudao-spring-boot-starter-biz-tenant</artifactId>
  47 + </dependency>
39 48
40 <!-- Web 相关 --> 49 <!-- Web 相关 -->
41 <dependency> 50 <dependency>
@@ -59,5 +68,10 @@ @@ -59,5 +68,10 @@
59 <groupId>cn.iocoder.boot</groupId> 68 <groupId>cn.iocoder.boot</groupId>
60 <artifactId>yudao-spring-boot-starter-test</artifactId> 69 <artifactId>yudao-spring-boot-starter-test</artifactId>
61 </dependency> 70 </dependency>
  71 + <!-- 工作流相关 -->
  72 + <dependency>
  73 + <groupId>cn.iocoder.boot</groupId>
  74 + <artifactId>yudao-spring-boot-starter-flowable</artifactId>
  75 + </dependency>
62 </dependencies> 76 </dependencies>
63 </project> 77 </project>
yudao-module-bpm/yudao-module-bpm-biz-activiti/src/main/java/cn/iocoder/yudao/module/bpm/api/package-info.java renamed to yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/api/package-info.java
yudao-module-bpm/yudao-module-bpm-biz-flowable/src/main/java/cn/iocoder/yudao/module/bpm/api/task/BpmProcessInstanceApiImpl.java renamed to yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/api/task/BpmProcessInstanceApiImpl.java
yudao-module-bpm/yudao-module-bpm-base/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/BpmFormController.java renamed to yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/BpmFormController.java
yudao-module-bpm/yudao-module-bpm-biz-flowable/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/BpmModelController.java renamed to yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/BpmModelController.java
yudao-module-bpm/yudao-module-bpm-biz-flowable/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/BpmProcessDefinitionController.java renamed to yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/BpmProcessDefinitionController.java
yudao-module-bpm/yudao-module-bpm-biz-activiti/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/BpmTaskAssignRuleController.java renamed to yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/BpmTaskAssignRuleController.java
@@ -55,5 +55,4 @@ public class BpmTaskAssignRuleController { @@ -55,5 +55,4 @@ public class BpmTaskAssignRuleController {
55 taskAssignRuleService.updateTaskAssignRule(reqVO); 55 taskAssignRuleService.updateTaskAssignRule(reqVO);
56 return success(true); 56 return success(true);
57 } 57 }
58 -  
59 } 58 }
yudao-module-bpm/yudao-module-bpm-base/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/BpmUserGroupController.java renamed to yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/BpmUserGroupController.java
yudao-module-bpm/yudao-module-bpm-base/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/form/BpmFormBaseVO.java renamed to yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/form/BpmFormBaseVO.java
yudao-module-bpm/yudao-module-bpm-base/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/form/BpmFormCreateReqVO.java renamed to yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/form/BpmFormCreateReqVO.java
yudao-module-bpm/yudao-module-bpm-base/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/form/BpmFormPageReqVO.java renamed to yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/form/BpmFormPageReqVO.java
yudao-module-bpm/yudao-module-bpm-base/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/form/BpmFormRespVO.java renamed to yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/form/BpmFormRespVO.java
yudao-module-bpm/yudao-module-bpm-base/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/form/BpmFormSimpleRespVO.java renamed to yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/form/BpmFormSimpleRespVO.java
yudao-module-bpm/yudao-module-bpm-base/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/form/BpmFormUpdateReqVO.java renamed to yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/form/BpmFormUpdateReqVO.java
yudao-module-bpm/yudao-module-bpm-base/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/group/BpmUserGroupBaseVO.java renamed to yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/group/BpmUserGroupBaseVO.java
yudao-module-bpm/yudao-module-bpm-base/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/group/BpmUserGroupCreateReqVO.java renamed to yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/group/BpmUserGroupCreateReqVO.java
yudao-module-bpm/yudao-module-bpm-base/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/group/BpmUserGroupPageReqVO.java renamed to yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/group/BpmUserGroupPageReqVO.java
yudao-module-bpm/yudao-module-bpm-base/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/group/BpmUserGroupRespVO.java renamed to yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/group/BpmUserGroupRespVO.java
yudao-module-bpm/yudao-module-bpm-base/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/group/BpmUserGroupSimpleRespVO.java renamed to yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/group/BpmUserGroupSimpleRespVO.java
yudao-module-bpm/yudao-module-bpm-base/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/group/BpmUserGroupUpdateReqVO.java renamed to yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/group/BpmUserGroupUpdateReqVO.java
yudao-module-bpm/yudao-module-bpm-base/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/model/BpmModeImportReqVO.java renamed to yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/model/BpmModeImportReqVO.java
yudao-module-bpm/yudao-module-bpm-base/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/model/BpmModelBaseVO.java renamed to yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/model/BpmModelBaseVO.java
yudao-module-bpm/yudao-module-bpm-base/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/model/BpmModelCreateReqVO.java renamed to yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/model/BpmModelCreateReqVO.java
yudao-module-bpm/yudao-module-bpm-base/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/model/BpmModelPageItemRespVO.java renamed to yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/model/BpmModelPageItemRespVO.java
yudao-module-bpm/yudao-module-bpm-base/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/model/BpmModelPageReqVO.java renamed to yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/model/BpmModelPageReqVO.java
yudao-module-bpm/yudao-module-bpm-base/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/model/BpmModelRespVO.java renamed to yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/model/BpmModelRespVO.java
yudao-module-bpm/yudao-module-bpm-base/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/model/BpmModelUpdateReqVO.java renamed to yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/model/BpmModelUpdateReqVO.java
yudao-module-bpm/yudao-module-bpm-base/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/model/BpmModelUpdateStateReqVO.java renamed to yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/model/BpmModelUpdateStateReqVO.java
yudao-module-bpm/yudao-module-bpm-base/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/process/BpmProcessDefinitionListReqVO.java renamed to yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/process/BpmProcessDefinitionListReqVO.java
yudao-module-bpm/yudao-module-bpm-base/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/process/BpmProcessDefinitionPageItemRespVO.java renamed to yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/process/BpmProcessDefinitionPageItemRespVO.java
yudao-module-bpm/yudao-module-bpm-base/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/process/BpmProcessDefinitionPageReqVO.java renamed to yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/process/BpmProcessDefinitionPageReqVO.java
yudao-module-bpm/yudao-module-bpm-base/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/process/BpmProcessDefinitionRespVO.java renamed to yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/process/BpmProcessDefinitionRespVO.java
yudao-module-bpm/yudao-module-bpm-base/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/rule/BpmTaskAssignRuleBaseVO.java renamed to yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/rule/BpmTaskAssignRuleBaseVO.java
yudao-module-bpm/yudao-module-bpm-base/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/rule/BpmTaskAssignRuleCreateReqVO.java renamed to yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/rule/BpmTaskAssignRuleCreateReqVO.java
yudao-module-bpm/yudao-module-bpm-base/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/rule/BpmTaskAssignRuleRespVO.java renamed to yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/rule/BpmTaskAssignRuleRespVO.java
yudao-module-bpm/yudao-module-bpm-base/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/rule/BpmTaskAssignRuleUpdateReqVO.java renamed to yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/rule/BpmTaskAssignRuleUpdateReqVO.java
yudao-module-bpm/yudao-module-bpm-base/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/oa/BpmOALeaveController.http renamed to yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/oa/BpmOALeaveController.http
yudao-module-bpm/yudao-module-bpm-base/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/oa/BpmOALeaveController.java renamed to yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/oa/BpmOALeaveController.java
yudao-module-bpm/yudao-module-bpm-base/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/oa/package-info.java renamed to yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/oa/package-info.java
yudao-module-bpm/yudao-module-bpm-base/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/oa/vo/BpmOALeaveBaseVO.java renamed to yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/oa/vo/BpmOALeaveBaseVO.java
yudao-module-bpm/yudao-module-bpm-base/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/oa/vo/BpmOALeaveCreateReqVO.java renamed to yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/oa/vo/BpmOALeaveCreateReqVO.java
yudao-module-bpm/yudao-module-bpm-base/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/oa/vo/BpmOALeavePageReqVO.java renamed to yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/oa/vo/BpmOALeavePageReqVO.java
yudao-module-bpm/yudao-module-bpm-base/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/oa/vo/BpmOALeaveRespVO.java renamed to yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/oa/vo/BpmOALeaveRespVO.java
yudao-module-bpm/yudao-module-bpm-biz-flowable/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/BpmActivityController.java renamed to yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/BpmActivityController.java
yudao-module-bpm/yudao-module-bpm-biz-activiti/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/BpmProcessInstanceController.java renamed to yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/BpmProcessInstanceController.java
1 package cn.iocoder.yudao.module.bpm.controller.admin.task; 1 package cn.iocoder.yudao.module.bpm.controller.admin.task;
2 2
3 -import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance.*;  
4 -import cn.iocoder.yudao.module.bpm.service.task.BpmProcessInstanceService;  
5 import cn.iocoder.yudao.framework.common.pojo.CommonResult; 3 import cn.iocoder.yudao.framework.common.pojo.CommonResult;
6 import cn.iocoder.yudao.framework.common.pojo.PageResult; 4 import cn.iocoder.yudao.framework.common.pojo.PageResult;
  5 +import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance.*;
  6 +import cn.iocoder.yudao.module.bpm.service.task.BpmProcessInstanceService;
7 import io.swagger.annotations.Api; 7 import io.swagger.annotations.Api;
8 import io.swagger.annotations.ApiImplicitParam; 8 import io.swagger.annotations.ApiImplicitParam;
9 import io.swagger.annotations.ApiOperation; 9 import io.swagger.annotations.ApiOperation;
@@ -22,25 +22,9 @@ import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUti @@ -22,25 +22,9 @@ import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUti
22 @RequestMapping("/bpm/process-instance") 22 @RequestMapping("/bpm/process-instance")
23 @Validated 23 @Validated
24 public class BpmProcessInstanceController { 24 public class BpmProcessInstanceController {
25 -  
26 @Resource 25 @Resource
27 private BpmProcessInstanceService processInstanceService; 26 private BpmProcessInstanceService processInstanceService;
28 27
29 - @PostMapping("/create")  
30 - @ApiOperation("新建流程实例")  
31 - @PreAuthorize("@ss.hasPermission('bpm:process-instance:query')")  
32 - public CommonResult<String> createProcessInstance(@Valid @RequestBody BpmProcessInstanceCreateReqVO createReqVO) {  
33 - return success(processInstanceService.createProcessInstance(getLoginUserId(), createReqVO));  
34 - }  
35 -  
36 - @DeleteMapping("/cancel")  
37 - @ApiOperation(value = "取消流程实例", notes = "撤回发起的流程")  
38 - @PreAuthorize("@ss.hasPermission('bpm:process-instance:cancel')")  
39 - public CommonResult<Boolean> cancelProcessInstance(@Valid @RequestBody BpmProcessInstanceCancelReqVO cancelReqVO) {  
40 - processInstanceService.cancelProcessInstance(getLoginUserId(), cancelReqVO);  
41 - return success(true);  
42 - }  
43 -  
44 @GetMapping("/my-page") 28 @GetMapping("/my-page")
45 @ApiOperation(value = "获得我的实例分页列表", notes = "在【我的流程】菜单中,进行调用") 29 @ApiOperation(value = "获得我的实例分页列表", notes = "在【我的流程】菜单中,进行调用")
46 @PreAuthorize("@ss.hasPermission('bpm:process-instance:query')") 30 @PreAuthorize("@ss.hasPermission('bpm:process-instance:query')")
@@ -49,6 +33,13 @@ public class BpmProcessInstanceController { @@ -49,6 +33,13 @@ public class BpmProcessInstanceController {
49 return success(processInstanceService.getMyProcessInstancePage(getLoginUserId(), pageReqVO)); 33 return success(processInstanceService.getMyProcessInstancePage(getLoginUserId(), pageReqVO));
50 } 34 }
51 35
  36 + @PostMapping("/create")
  37 + @ApiOperation("新建流程实例")
  38 + @PreAuthorize("@ss.hasPermission('bpm:process-instance:query')")
  39 + public CommonResult<String> createProcessInstance(@Valid @RequestBody BpmProcessInstanceCreateReqVO createReqVO) {
  40 + return success(processInstanceService.createProcessInstance(getLoginUserId(), createReqVO));
  41 + }
  42 +
52 @GetMapping("/get") 43 @GetMapping("/get")
53 @ApiOperation(value = "获得指定流程实例", notes = "在【流程详细】界面中,进行调用") 44 @ApiOperation(value = "获得指定流程实例", notes = "在【流程详细】界面中,进行调用")
54 @ApiImplicitParam(name = "id", value = "流程实例的编号", required = true, dataTypeClass = String.class) 45 @ApiImplicitParam(name = "id", value = "流程实例的编号", required = true, dataTypeClass = String.class)
@@ -57,4 +48,11 @@ public class BpmProcessInstanceController { @@ -57,4 +48,11 @@ public class BpmProcessInstanceController {
57 return success(processInstanceService.getProcessInstanceVO(id)); 48 return success(processInstanceService.getProcessInstanceVO(id));
58 } 49 }
59 50
  51 + @DeleteMapping("/cancel")
  52 + @ApiOperation(value = "取消流程实例", notes = "撤回发起的流程")
  53 + @PreAuthorize("@ss.hasPermission('bpm:process-instance:cancel')")
  54 + public CommonResult<Boolean> cancelProcessInstance(@Valid @RequestBody BpmProcessInstanceCancelReqVO cancelReqVO) {
  55 + processInstanceService.cancelProcessInstance(getLoginUserId(), cancelReqVO);
  56 + return success(true);
  57 + }
60 } 58 }
yudao-module-bpm/yudao-module-bpm-biz-activiti/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/BpmTaskController.java renamed to yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/BpmTaskController.java
1 package cn.iocoder.yudao.module.bpm.controller.admin.task; 1 package cn.iocoder.yudao.module.bpm.controller.admin.task;
2 2
3 -import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.task.*;  
4 -import cn.iocoder.yudao.module.bpm.service.task.BpmTaskService;  
5 import cn.iocoder.yudao.framework.common.pojo.CommonResult; 3 import cn.iocoder.yudao.framework.common.pojo.CommonResult;
6 import cn.iocoder.yudao.framework.common.pojo.PageResult; 4 import cn.iocoder.yudao.framework.common.pojo.PageResult;
  5 +import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.task.*;
  6 +import cn.iocoder.yudao.module.bpm.service.task.BpmTaskService;
7 import io.swagger.annotations.Api; 7 import io.swagger.annotations.Api;
8 import io.swagger.annotations.ApiImplicitParam; 8 import io.swagger.annotations.ApiImplicitParam;
9 import io.swagger.annotations.ApiOperation; 9 import io.swagger.annotations.ApiOperation;
@@ -13,6 +13,7 @@ import org.springframework.web.bind.annotation.*; @@ -13,6 +13,7 @@ import org.springframework.web.bind.annotation.*;
13 13
14 import javax.annotation.Resource; 14 import javax.annotation.Resource;
15 import javax.validation.Valid; 15 import javax.validation.Valid;
  16 +
16 import java.util.List; 17 import java.util.List;
17 18
18 import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; 19 import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
@@ -41,6 +42,15 @@ public class BpmTaskController { @@ -41,6 +42,15 @@ public class BpmTaskController {
41 return success(taskService.getDoneTaskPage(getLoginUserId(), pageVO)); 42 return success(taskService.getDoneTaskPage(getLoginUserId(), pageVO));
42 } 43 }
43 44
  45 + @GetMapping("/list-by-process-instance-id")
  46 + @ApiOperation(value = "获得指定流程实例的任务列表", notes = "包括完成的、未完成的")
  47 + @ApiImplicitParam(name = "processInstanceId", value = "流程实例的编号", required = true, dataTypeClass = String.class)
  48 + @PreAuthorize("@ss.hasPermission('bpm:task:query')")
  49 + public CommonResult<List<BpmTaskRespVO>> getTaskListByProcessInstanceId(
  50 + @RequestParam("processInstanceId") String processInstanceId) {
  51 + return success(taskService.getTaskListByProcessInstanceId(processInstanceId));
  52 + }
  53 +
44 @PutMapping("/approve") 54 @PutMapping("/approve")
45 @ApiOperation("通过任务") 55 @ApiOperation("通过任务")
46 @PreAuthorize("@ss.hasPermission('bpm:task:update')") 56 @PreAuthorize("@ss.hasPermission('bpm:task:update')")
@@ -65,13 +75,4 @@ public class BpmTaskController { @@ -65,13 +75,4 @@ public class BpmTaskController {
65 return success(true); 75 return success(true);
66 } 76 }
67 77
68 - @GetMapping("/list-by-process-instance-id")  
69 - @ApiOperation(value = "获得指定流程实例的任务列表", notes = "包括完成的、未完成的")  
70 - @ApiImplicitParam(name = "processInstanceId", value = "流程实例的编号", required = true, dataTypeClass = String.class)  
71 - @PreAuthorize("@ss.hasPermission('bpm:task:query')")  
72 - public CommonResult<List<BpmTaskRespVO>> getTaskListByProcessInstanceId(  
73 - @RequestParam("processInstanceId") String processInstanceId) {  
74 - return success(taskService.getTaskListByProcessInstanceId(processInstanceId));  
75 - }  
76 -  
77 } 78 }
yudao-module-bpm/yudao-module-bpm-base/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/activity/BpmActivityRespVO.java renamed to yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/activity/BpmActivityRespVO.java
yudao-module-bpm/yudao-module-bpm-base/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/instance/BpmProcessInstanceCancelReqVO.java renamed to yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/instance/BpmProcessInstanceCancelReqVO.java
yudao-module-bpm/yudao-module-bpm-base/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/instance/BpmProcessInstanceCreateReqVO.java renamed to yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/instance/BpmProcessInstanceCreateReqVO.java
yudao-module-bpm/yudao-module-bpm-base/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/instance/BpmProcessInstanceMyPageReqVO.java renamed to yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/instance/BpmProcessInstanceMyPageReqVO.java
yudao-module-bpm/yudao-module-bpm-base/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/instance/BpmProcessInstancePageItemRespVO.java renamed to yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/instance/BpmProcessInstancePageItemRespVO.java
yudao-module-bpm/yudao-module-bpm-base/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/instance/BpmProcessInstanceRespVO.java renamed to yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/instance/BpmProcessInstanceRespVO.java
yudao-module-bpm/yudao-module-bpm-base/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/task/BpmTaskApproveReqVO.java renamed to yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/task/BpmTaskApproveReqVO.java
yudao-module-bpm/yudao-module-bpm-base/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/task/BpmTaskDonePageItemRespVO.java renamed to yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/task/BpmTaskDonePageItemRespVO.java
yudao-module-bpm/yudao-module-bpm-base/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/task/BpmTaskDonePageReqVO.java renamed to yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/task/BpmTaskDonePageReqVO.java
yudao-module-bpm/yudao-module-bpm-base/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/task/BpmTaskRejectReqVO.java renamed to yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/task/BpmTaskRejectReqVO.java
yudao-module-bpm/yudao-module-bpm-base/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/task/BpmTaskRespVO.java renamed to yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/task/BpmTaskRespVO.java
@@ -35,5 +35,4 @@ public class BpmTaskRespVO extends BpmTaskDonePageItemRespVO { @@ -35,5 +35,4 @@ public class BpmTaskRespVO extends BpmTaskDonePageItemRespVO {
35 private String deptName; 35 private String deptName;
36 36
37 } 37 }
38 -  
39 } 38 }
yudao-module-bpm/yudao-module-bpm-base/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/task/BpmTaskTodoPageItemRespVO.java renamed to yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/task/BpmTaskTodoPageItemRespVO.java
yudao-module-bpm/yudao-module-bpm-base/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/task/BpmTaskTodoPageReqVO.java renamed to yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/task/BpmTaskTodoPageReqVO.java
yudao-module-bpm/yudao-module-bpm-base/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/task/BpmTaskUpdateAssigneeReqVO.java renamed to yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/task/BpmTaskUpdateAssigneeReqVO.java
yudao-module-bpm/yudao-module-bpm-base/src/main/java/cn/iocoder/yudao/module/bpm/controller/app/package-info.java renamed to yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/app/package-info.java
yudao-module-bpm/yudao-module-bpm-base/src/main/java/cn/iocoder/yudao/module/bpm/controller/package-info.java renamed to yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/package-info.java
yudao-module-bpm/yudao-module-bpm-base/src/main/java/cn/iocoder/yudao/module/bpm/convert/definition/BpmFormConvert.java renamed to yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/convert/definition/BpmFormConvert.java
yudao-module-bpm/yudao-module-bpm-biz-flowable/src/main/java/cn/iocoder/yudao/module/bpm/convert/definition/BpmModelConvert.java renamed to yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/convert/definition/BpmModelConvert.java
yudao-module-bpm/yudao-module-bpm-biz-flowable/src/main/java/cn/iocoder/yudao/module/bpm/convert/definition/BpmProcessDefinitionConvert.java renamed to yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/convert/definition/BpmProcessDefinitionConvert.java
yudao-module-bpm/yudao-module-bpm-biz-flowable/src/main/java/cn/iocoder/yudao/module/bpm/convert/definition/BpmTaskAssignRuleConvert.java renamed to yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/convert/definition/BpmTaskAssignRuleConvert.java
yudao-module-bpm/yudao-module-bpm-base/src/main/java/cn/iocoder/yudao/module/bpm/convert/definition/BpmUserGroupConvert.java renamed to yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/convert/definition/BpmUserGroupConvert.java
yudao-module-bpm/yudao-module-bpm-base/src/main/java/cn/iocoder/yudao/module/bpm/convert/message/BpmMessageConvert.java renamed to yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/convert/message/BpmMessageConvert.java
yudao-module-bpm/yudao-module-bpm-base/src/main/java/cn/iocoder/yudao/module/bpm/convert/oa/BpmOALeaveConvert.java renamed to yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/convert/oa/BpmOALeaveConvert.java
yudao-module-bpm/yudao-module-bpm-biz-activiti/src/main/java/cn/iocoder/yudao/module/bpm/convert/package-info.java renamed to yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/convert/package-info.java
yudao-module-bpm/yudao-module-bpm-biz-flowable/src/main/java/cn/iocoder/yudao/module/bpm/convert/task/BpmActivityConvert.java renamed to yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/convert/task/BpmActivityConvert.java
yudao-module-bpm/yudao-module-bpm-biz-flowable/src/main/java/cn/iocoder/yudao/module/bpm/convert/task/BpmProcessInstanceConvert.java renamed to yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/convert/task/BpmProcessInstanceConvert.java
yudao-module-bpm/yudao-module-bpm-biz-flowable/src/main/java/cn/iocoder/yudao/module/bpm/convert/task/BpmTaskConvert.java renamed to yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/convert/task/BpmTaskConvert.java
@@ -9,7 +9,6 @@ import cn.iocoder.yudao.module.bpm.dal.dataobject.task.BpmTaskExtDO; @@ -9,7 +9,6 @@ import cn.iocoder.yudao.module.bpm.dal.dataobject.task.BpmTaskExtDO;
9 import cn.iocoder.yudao.module.bpm.service.message.dto.BpmMessageSendWhenTaskCreatedReqDTO; 9 import cn.iocoder.yudao.module.bpm.service.message.dto.BpmMessageSendWhenTaskCreatedReqDTO;
10 import cn.iocoder.yudao.module.system.api.dept.dto.DeptRespDTO; 10 import cn.iocoder.yudao.module.system.api.dept.dto.DeptRespDTO;
11 import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO; 11 import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
12 -  
13 import org.flowable.common.engine.impl.db.SuspensionState; 12 import org.flowable.common.engine.impl.db.SuspensionState;
14 import org.flowable.engine.history.HistoricProcessInstance; 13 import org.flowable.engine.history.HistoricProcessInstance;
15 import org.flowable.engine.runtime.ProcessInstance; 14 import org.flowable.engine.runtime.ProcessInstance;
@@ -17,9 +16,12 @@ import org.flowable.task.api.Task; @@ -17,9 +16,12 @@ import org.flowable.task.api.Task;
17 import org.flowable.task.api.history.HistoricTaskInstance; 16 import org.flowable.task.api.history.HistoricTaskInstance;
18 import org.mapstruct.*; 17 import org.mapstruct.*;
19 import org.mapstruct.factory.Mappers; 18 import org.mapstruct.factory.Mappers;
  19 +import org.springframework.beans.BeanUtils;
20 20
  21 +import java.util.Collections;
21 import java.util.List; 22 import java.util.List;
22 import java.util.Map; 23 import java.util.Map;
  24 +import java.util.stream.Collectors;
23 25
24 /** 26 /**
25 * Bpm 任务 Convert 27 * Bpm 任务 Convert
@@ -31,8 +33,37 @@ public interface BpmTaskConvert { @@ -31,8 +33,37 @@ public interface BpmTaskConvert {
31 33
32 BpmTaskConvert INSTANCE = Mappers.getMapper(BpmTaskConvert.class); 34 BpmTaskConvert INSTANCE = Mappers.getMapper(BpmTaskConvert.class);
33 35
34 - default List<BpmTaskTodoPageItemRespVO> convertList1(List<Task> tasks, Map<String, ProcessInstance> processInstanceMap,  
35 - Map<Long, AdminUserRespDTO> userMap) { 36 + /**
  37 + * 复制对象
  38 + *
  39 + * @param source 源 要复制的对象
  40 + * @param target 目标 复制到此对象
  41 + * @param <T>
  42 + *
  43 + * @return
  44 + */
  45 + public static <T> T copy(Object source, Class<T> target) {
  46 + if (source == null || target == null) {
  47 + return null;
  48 + }
  49 + try {
  50 + T newInstance = target.newInstance();
  51 + BeanUtils.copyProperties(source, newInstance);
  52 + return newInstance;
  53 + } catch (Exception e) {
  54 + throw new RuntimeException(e);
  55 + }
  56 + }
  57 +
  58 + default <T, K> List<K> copyList(List<T> source, Class<K> target) {
  59 + if (null == source || source.isEmpty()) {
  60 + return Collections.emptyList();
  61 + }
  62 + return source.stream().map(e -> copy(e, target)).collect(Collectors.toList());
  63 + }
  64 +
  65 + default List<BpmTaskTodoPageItemRespVO> convertList1(List<Task> tasks,
  66 + Map<String, ProcessInstance> processInstanceMap, Map<Long, AdminUserRespDTO> userMap) {
36 return CollectionUtils.convertList(tasks, task -> { 67 return CollectionUtils.convertList(tasks, task -> {
37 BpmTaskTodoPageItemRespVO respVO = convert1(task); 68 BpmTaskTodoPageItemRespVO respVO = convert1(task);
38 ProcessInstance processInstance = processInstanceMap.get(task.getProcessInstanceId()); 69 ProcessInstance processInstance = processInstanceMap.get(task.getProcessInstanceId());
@@ -49,13 +80,12 @@ public interface BpmTaskConvert { @@ -49,13 +80,12 @@ public interface BpmTaskConvert {
49 80
50 @Named("convertSuspendedToSuspensionState") 81 @Named("convertSuspendedToSuspensionState")
51 default Integer convertSuspendedToSuspensionState(boolean suspended) { 82 default Integer convertSuspendedToSuspensionState(boolean suspended) {
52 - return suspended ? SuspensionState.SUSPENDED.getStateCode() :  
53 - SuspensionState.ACTIVE.getStateCode(); 83 + return suspended ? SuspensionState.SUSPENDED.getStateCode() : SuspensionState.ACTIVE.getStateCode();
54 } 84 }
55 85
56 - default List<BpmTaskDonePageItemRespVO> convertList2(List<HistoricTaskInstance> tasks, Map<String, BpmTaskExtDO> bpmTaskExtDOMap,  
57 - Map<String, HistoricProcessInstance> historicProcessInstanceMap,  
58 - Map<Long, AdminUserRespDTO> userMap) { 86 + default List<BpmTaskDonePageItemRespVO> convertList2(List<HistoricTaskInstance> tasks,
  87 + Map<String, BpmTaskExtDO> bpmTaskExtDOMap, Map<String, HistoricProcessInstance> historicProcessInstanceMap,
  88 + Map<Long, AdminUserRespDTO> userMap) {
59 return CollectionUtils.convertList(tasks, task -> { 89 return CollectionUtils.convertList(tasks, task -> {
60 BpmTaskDonePageItemRespVO respVO = convert2(task); 90 BpmTaskDonePageItemRespVO respVO = convert2(task);
61 BpmTaskExtDO taskExtDO = bpmTaskExtDOMap.get(task.getId()); 91 BpmTaskExtDO taskExtDO = bpmTaskExtDOMap.get(task.getId());
@@ -71,18 +101,16 @@ public interface BpmTaskConvert { @@ -71,18 +101,16 @@ public interface BpmTaskConvert {
71 101
72 BpmTaskDonePageItemRespVO convert2(HistoricTaskInstance bean); 102 BpmTaskDonePageItemRespVO convert2(HistoricTaskInstance bean);
73 103
74 - @Mappings({  
75 - @Mapping(source = "processInstance.id", target = "id"),  
76 - @Mapping(source = "processInstance.name", target = "name"),  
77 - @Mapping(source = "processInstance.startUserId", target = "startUserId"),  
78 - @Mapping(source = "processInstance.processDefinitionId", target = "processDefinitionId"),  
79 - @Mapping(source = "startUser.nickname", target = "startUserNickname")  
80 - }) 104 + @Mappings({@Mapping(source = "processInstance.id", target = "id"),
  105 + @Mapping(source = "processInstance.name", target = "name"),
  106 + @Mapping(source = "processInstance.startUserId", target = "startUserId"),
  107 + @Mapping(source = "processInstance.processDefinitionId", target = "processDefinitionId"),
  108 + @Mapping(source = "startUser.nickname", target = "startUserNickname")})
81 BpmTaskTodoPageItemRespVO.ProcessInstance convert(ProcessInstance processInstance, AdminUserRespDTO startUser); 109 BpmTaskTodoPageItemRespVO.ProcessInstance convert(ProcessInstance processInstance, AdminUserRespDTO startUser);
82 110
83 - default List<BpmTaskRespVO> convertList3(List<HistoricTaskInstance> tasks, Map<String, BpmTaskExtDO> bpmTaskExtDOMap,  
84 - HistoricProcessInstance processInstance, Map<Long, AdminUserRespDTO> userMap,  
85 - Map<Long, DeptRespDTO> deptMap) { 111 + default List<BpmTaskRespVO> convertList3(List<HistoricTaskInstance> tasks,
  112 + Map<String, BpmTaskExtDO> bpmTaskExtDOMap, HistoricProcessInstance processInstance,
  113 + Map<Long, AdminUserRespDTO> userMap, Map<Long, DeptRespDTO> deptMap) {
86 return CollectionUtils.convertList(tasks, task -> { 114 return CollectionUtils.convertList(tasks, task -> {
87 BpmTaskRespVO respVO = convert3(task); 115 BpmTaskRespVO respVO = convert3(task);
88 BpmTaskExtDO taskExtDO = bpmTaskExtDOMap.get(task.getId()); 116 BpmTaskExtDO taskExtDO = bpmTaskExtDOMap.get(task.getId());
@@ -111,37 +139,30 @@ public interface BpmTaskConvert { @@ -111,37 +139,30 @@ public interface BpmTaskConvert {
111 @Mapping(target = "id", ignore = true) 139 @Mapping(target = "id", ignore = true)
112 void copyTo(BpmTaskExtDO from, @MappingTarget BpmTaskDonePageItemRespVO to); 140 void copyTo(BpmTaskExtDO from, @MappingTarget BpmTaskDonePageItemRespVO to);
113 141
114 - @Mappings({  
115 - @Mapping(source = "processInstance.id", target = "id"),  
116 - @Mapping(source = "processInstance.name", target = "name"),  
117 - @Mapping(source = "processInstance.startUserId", target = "startUserId"),  
118 - @Mapping(source = "processInstance.processDefinitionId", target = "processDefinitionId"),  
119 - @Mapping(source = "startUser.nickname", target = "startUserNickname")  
120 - })  
121 - BpmTaskTodoPageItemRespVO.ProcessInstance convert(HistoricProcessInstance processInstance, AdminUserRespDTO startUser);  
122 -  
123 - default BpmTaskExtDO convert2TaskExt(Task task){  
124 - BpmTaskExtDO taskExtDO = new BpmTaskExtDO()  
125 - .setTaskId(task.getId())  
126 - .setAssigneeUserId(NumberUtils.parseLong(task.getAssignee()))  
127 - .setName(task.getName())  
128 - .setProcessDefinitionId(task.getProcessDefinitionId())  
129 - .setProcessInstanceId(task.getProcessInstanceId()); 142 + @Mappings({@Mapping(source = "processInstance.id", target = "id"),
  143 + @Mapping(source = "processInstance.name", target = "name"),
  144 + @Mapping(source = "processInstance.startUserId", target = "startUserId"),
  145 + @Mapping(source = "processInstance.processDefinitionId", target = "processDefinitionId"),
  146 + @Mapping(source = "startUser.nickname", target = "startUserNickname")})
  147 + BpmTaskTodoPageItemRespVO.ProcessInstance convert(HistoricProcessInstance processInstance,
  148 + AdminUserRespDTO startUser);
  149 +
  150 + default BpmTaskExtDO convert2TaskExt(Task task) {
  151 + BpmTaskExtDO taskExtDO = new BpmTaskExtDO().setTaskId(task.getId())
  152 + .setAssigneeUserId(NumberUtils.parseLong(task.getAssignee())).setName(task.getName())
  153 + .setProcessDefinitionId(task.getProcessDefinitionId()).setProcessInstanceId(task.getProcessInstanceId());
130 taskExtDO.setCreateTime(task.getCreateTime()); 154 taskExtDO.setCreateTime(task.getCreateTime());
131 return taskExtDO; 155 return taskExtDO;
132 } 156 }
133 157
134 - default BpmMessageSendWhenTaskCreatedReqDTO convert(ProcessInstance processInstance, AdminUserRespDTO startUser, Task task) { 158 + default BpmMessageSendWhenTaskCreatedReqDTO convert(ProcessInstance processInstance, AdminUserRespDTO startUser,
  159 + Task task) {
135 BpmMessageSendWhenTaskCreatedReqDTO reqDTO = new BpmMessageSendWhenTaskCreatedReqDTO(); 160 BpmMessageSendWhenTaskCreatedReqDTO reqDTO = new BpmMessageSendWhenTaskCreatedReqDTO();
136 reqDTO.setProcessInstanceId(processInstance.getProcessInstanceId()) 161 reqDTO.setProcessInstanceId(processInstance.getProcessInstanceId())
137 - .setProcessInstanceName(processInstance.getName())  
138 - .setStartUserId(startUser.getId())  
139 - .setStartUserNickname(startUser.getNickname())  
140 - .setTaskId(task.getId())  
141 - .setTaskName(task.getName())  
142 - .setAssigneeUserId(NumberUtils.parseLong(task.getAssignee())); 162 + .setProcessInstanceName(processInstance.getName()).setStartUserId(startUser.getId())
  163 + .setStartUserNickname(startUser.getNickname()).setTaskId(task.getId()).setTaskName(task.getName())
  164 + .setAssigneeUserId(NumberUtils.parseLong(task.getAssignee()));
143 return reqDTO; 165 return reqDTO;
144 } 166 }
145 -}  
146 -  
147 167
  168 +}
yudao-module-bpm/yudao-module-bpm-base/src/main/java/cn/iocoder/yudao/module/bpm/convert/task/package-info.java renamed to yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/convert/task/package-info.java
yudao-module-bpm/yudao-module-bpm-biz-activiti/src/main/java/cn/iocoder/yudao/module/bpm/convert/《芋道 Spring Boot 对象转换 MapStruct 入门》.md renamed to yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/convert/《芋道 Spring Boot 对象转换 MapStruct 入门》.md
yudao-module-bpm/yudao-module-bpm-base/src/main/java/cn/iocoder/yudao/module/bpm/dal/dataobject/definition/BpmFormDO.java renamed to yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/dal/dataobject/definition/BpmFormDO.java
1 package cn.iocoder.yudao.module.bpm.dal.dataobject.definition; 1 package cn.iocoder.yudao.module.bpm.dal.dataobject.definition;
2 2
3 import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; 3 import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
4 -import com.baomidou.mybatisplus.annotation.KeySequence;  
5 import com.baomidou.mybatisplus.annotation.TableField; 4 import com.baomidou.mybatisplus.annotation.TableField;
6 import com.baomidou.mybatisplus.annotation.TableId; 5 import com.baomidou.mybatisplus.annotation.TableId;
7 import com.baomidou.mybatisplus.annotation.TableName; 6 import com.baomidou.mybatisplus.annotation.TableName;
@@ -17,7 +16,6 @@ import java.util.List; @@ -17,7 +16,6 @@ import java.util.List;
17 * @author 芋道源码 16 * @author 芋道源码
18 */ 17 */
19 @TableName(value = "bpm_form", autoResultMap = true) 18 @TableName(value = "bpm_form", autoResultMap = true)
20 -@KeySequence("bpm_form_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。  
21 @Data 19 @Data
22 @EqualsAndHashCode(callSuper = true) 20 @EqualsAndHashCode(callSuper = true)
23 @ToString(callSuper = true) 21 @ToString(callSuper = true)
yudao-module-bpm/yudao-module-bpm-base/src/main/java/cn/iocoder/yudao/module/bpm/dal/dataobject/definition/BpmProcessDefinitionExtDO.java renamed to yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/dal/dataobject/definition/BpmProcessDefinitionExtDO.java
@@ -2,7 +2,6 @@ package cn.iocoder.yudao.module.bpm.dal.dataobject.definition; @@ -2,7 +2,6 @@ package cn.iocoder.yudao.module.bpm.dal.dataobject.definition;
2 2
3 import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; 3 import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
4 import cn.iocoder.yudao.module.bpm.enums.definition.BpmModelFormTypeEnum; 4 import cn.iocoder.yudao.module.bpm.enums.definition.BpmModelFormTypeEnum;
5 -import com.baomidou.mybatisplus.annotation.KeySequence;  
6 import com.baomidou.mybatisplus.annotation.TableField; 5 import com.baomidou.mybatisplus.annotation.TableField;
7 import com.baomidou.mybatisplus.annotation.TableId; 6 import com.baomidou.mybatisplus.annotation.TableId;
8 import com.baomidou.mybatisplus.annotation.TableName; 7 import com.baomidou.mybatisplus.annotation.TableName;
@@ -18,7 +17,6 @@ import java.util.List; @@ -18,7 +17,6 @@ import java.util.List;
18 * @author 芋道源码 17 * @author 芋道源码
19 */ 18 */
20 @TableName(value = "bpm_process_definition_ext", autoResultMap = true) 19 @TableName(value = "bpm_process_definition_ext", autoResultMap = true)
21 -@KeySequence("bpm_process_definition_ext_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。  
22 @Data 20 @Data
23 @EqualsAndHashCode(callSuper = true) 21 @EqualsAndHashCode(callSuper = true)
24 @ToString(callSuper = true) 22 @ToString(callSuper = true)
yudao-module-bpm/yudao-module-bpm-base/src/main/java/cn/iocoder/yudao/module/bpm/dal/dataobject/definition/BpmTaskAssignRuleDO.java renamed to yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/dal/dataobject/definition/BpmTaskAssignRuleDO.java
@@ -4,7 +4,6 @@ import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; @@ -4,7 +4,6 @@ import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
4 import cn.iocoder.yudao.framework.mybatis.core.type.JsonLongSetTypeHandler; 4 import cn.iocoder.yudao.framework.mybatis.core.type.JsonLongSetTypeHandler;
5 import cn.iocoder.yudao.module.bpm.enums.definition.BpmTaskAssignRuleTypeEnum; 5 import cn.iocoder.yudao.module.bpm.enums.definition.BpmTaskAssignRuleTypeEnum;
6 import cn.iocoder.yudao.module.bpm.enums.definition.BpmTaskRuleScriptEnum; 6 import cn.iocoder.yudao.module.bpm.enums.definition.BpmTaskRuleScriptEnum;
7 -import com.baomidou.mybatisplus.annotation.KeySequence;  
8 import com.baomidou.mybatisplus.annotation.TableField; 7 import com.baomidou.mybatisplus.annotation.TableField;
9 import com.baomidou.mybatisplus.annotation.TableId; 8 import com.baomidou.mybatisplus.annotation.TableId;
10 import com.baomidou.mybatisplus.annotation.TableName; 9 import com.baomidou.mybatisplus.annotation.TableName;
@@ -22,7 +21,6 @@ import java.util.Set; @@ -22,7 +21,6 @@ import java.util.Set;
22 * @author 芋道源码 21 * @author 芋道源码
23 */ 22 */
24 @TableName(value = "bpm_task_assign_rule", autoResultMap = true) 23 @TableName(value = "bpm_task_assign_rule", autoResultMap = true)
25 -@KeySequence("bpm_task_assign_rule_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。  
26 @Data 24 @Data
27 @EqualsAndHashCode(callSuper = true) 25 @EqualsAndHashCode(callSuper = true)
28 @ToString(callSuper = true) 26 @ToString(callSuper = true)
@@ -33,9 +31,8 @@ public class BpmTaskAssignRuleDO extends BaseDO { @@ -33,9 +31,8 @@ public class BpmTaskAssignRuleDO extends BaseDO {
33 31
34 /** 32 /**
35 * {@link #processDefinitionId} 空串,用于标识属于流程模型,而不属于流程定义 33 * {@link #processDefinitionId} 空串,用于标识属于流程模型,而不属于流程定义
36 - * 不使用空串的原因,Oracle 针对空串,会处理成 null,进而导致无法检索  
37 */ 34 */
38 - public static final String PROCESS_DEFINITION_ID_NULL = "DEFAULT"; 35 + public static final String PROCESS_DEFINITION_ID_NULL = "";
39 36
40 /** 37 /**
41 * 编号 38 * 编号
@@ -67,6 +64,7 @@ public class BpmTaskAssignRuleDO extends BaseDO { @@ -67,6 +64,7 @@ public class BpmTaskAssignRuleDO extends BaseDO {
67 * 64 *
68 * 枚举 {@link BpmTaskAssignRuleTypeEnum} 65 * 枚举 {@link BpmTaskAssignRuleTypeEnum}
69 */ 66 */
  67 + @TableField("`type`")
70 private Integer type; 68 private Integer type;
71 /** 69 /**
72 * 规则值数组,一般关联指定表的编号 70 * 规则值数组,一般关联指定表的编号
yudao-module-bpm/yudao-module-bpm-base/src/main/java/cn/iocoder/yudao/module/bpm/dal/dataobject/definition/BpmTaskMessageRuleDO.java renamed to yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/dal/dataobject/definition/BpmTaskMessageRuleDO.java
yudao-module-bpm/yudao-module-bpm-base/src/main/java/cn/iocoder/yudao/module/bpm/dal/dataobject/definition/BpmUserGroupDO.java renamed to yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/dal/dataobject/definition/BpmUserGroupDO.java
@@ -3,7 +3,6 @@ package cn.iocoder.yudao.module.bpm.dal.dataobject.definition; @@ -3,7 +3,6 @@ package cn.iocoder.yudao.module.bpm.dal.dataobject.definition;
3 import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; 3 import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
4 import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; 4 import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
5 import cn.iocoder.yudao.framework.mybatis.core.type.JsonLongSetTypeHandler; 5 import cn.iocoder.yudao.framework.mybatis.core.type.JsonLongSetTypeHandler;
6 -import com.baomidou.mybatisplus.annotation.KeySequence;  
7 import com.baomidou.mybatisplus.annotation.TableField; 6 import com.baomidou.mybatisplus.annotation.TableField;
8 import com.baomidou.mybatisplus.annotation.TableId; 7 import com.baomidou.mybatisplus.annotation.TableId;
9 import com.baomidou.mybatisplus.annotation.TableName; 8 import com.baomidou.mybatisplus.annotation.TableName;
@@ -17,7 +16,6 @@ import java.util.Set; @@ -17,7 +16,6 @@ import java.util.Set;
17 * @author 芋道源码 16 * @author 芋道源码
18 */ 17 */
19 @TableName(value = "bpm_user_group", autoResultMap = true) 18 @TableName(value = "bpm_user_group", autoResultMap = true)
20 -@KeySequence("bpm_user_group_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。  
21 @Data 19 @Data
22 @EqualsAndHashCode(callSuper = true) 20 @EqualsAndHashCode(callSuper = true)
23 @ToString(callSuper = true) 21 @ToString(callSuper = true)
yudao-module-bpm/yudao-module-bpm-base/src/main/java/cn/iocoder/yudao/module/bpm/dal/dataobject/oa/BpmOALeaveDO.java renamed to yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/dal/dataobject/oa/BpmOALeaveDO.java
1 package cn.iocoder.yudao.module.bpm.dal.dataobject.oa; 1 package cn.iocoder.yudao.module.bpm.dal.dataobject.oa;
2 2
3 -import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;  
4 import cn.iocoder.yudao.module.bpm.enums.task.BpmProcessInstanceResultEnum; 3 import cn.iocoder.yudao.module.bpm.enums.task.BpmProcessInstanceResultEnum;
5 -import com.baomidou.mybatisplus.annotation.KeySequence;  
6 -import com.baomidou.mybatisplus.annotation.TableId;  
7 -import com.baomidou.mybatisplus.annotation.TableName;  
8 import lombok.*; 4 import lombok.*;
9 -  
10 -import java.util.Date; 5 +import java.util.*;
  6 +import com.baomidou.mybatisplus.annotation.*;
  7 +import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
11 8
12 /** 9 /**
13 * OA 请假申请 DO 10 * OA 请假申请 DO
@@ -18,7 +15,6 @@ import java.util.Date; @@ -18,7 +15,6 @@ import java.util.Date;
18 * @author 芋道源码 15 * @author 芋道源码
19 */ 16 */
20 @TableName("bpm_oa_leave") 17 @TableName("bpm_oa_leave")
21 -@KeySequence("bpm_oa_leave_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。  
22 @Data 18 @Data
23 @EqualsAndHashCode(callSuper = true) 19 @EqualsAndHashCode(callSuper = true)
24 @ToString(callSuper = true) 20 @ToString(callSuper = true)
@@ -41,7 +37,8 @@ public class BpmOALeaveDO extends BaseDO { @@ -41,7 +37,8 @@ public class BpmOALeaveDO extends BaseDO {
41 /** 37 /**
42 * 请假类型 38 * 请假类型
43 */ 39 */
44 - private Integer type; 40 + @TableField("`type`")
  41 + private String type;
45 /** 42 /**
46 * 原因 43 * 原因
47 */ 44 */
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/dal/dataobject/task/BpmActivityDO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.bpm.dal.dataobject.task;
  2 +
  3 +import com.fasterxml.jackson.annotation.JsonFormat;
  4 +import lombok.*;
  5 +import org.springframework.format.annotation.DateTimeFormat;
  6 +
  7 +import java.util.Date;
  8 +
  9 +import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
  10 +import static cn.iocoder.yudao.framework.common.util.date.DateUtils.TIME_ZONE_DEFAULT;
  11 +
  12 +/**
  13 + * 任务流程关联表
  14 + *
  15 + * @author kemengkai
  16 + * @create 2022-05-09 10:33
  17 + */
  18 +@Data
  19 +@AllArgsConstructor
  20 +@NoArgsConstructor
  21 +public class BpmActivityDO {
  22 +
  23 + /**
  24 + * 任务流程关联id
  25 + */
  26 + private String id;
  27 +
  28 + /**
  29 + * 审批结果
  30 + */
  31 + private Integer rev;
  32 +
  33 + /**
  34 + * 任务流程部署id
  35 + */
  36 + private String procDefId;
  37 +
  38 + /**
  39 + * 任务流程id
  40 + */
  41 + private String processInstanceId;
  42 +
  43 + /**
  44 + * 任务执行id
  45 + */
  46 + private String executionId;
  47 +
  48 + /**
  49 + * 任务key
  50 + */
  51 + private String activityId;
  52 +
  53 + /**
  54 + * 任务id
  55 + */
  56 + private String taskId;
  57 +
  58 + /**
  59 + * 调用流程id
  60 + */
  61 + private String callProcInstId;
  62 +
  63 + /**
  64 + * 任务名称
  65 + */
  66 + private String activityName;
  67 +
  68 + /**
  69 + * 任务类型
  70 + */
  71 + private String activityType;
  72 +
  73 + /**
  74 + * 任务审批人id
  75 + */
  76 + private String assignee;
  77 +
  78 + /**
  79 + * 任务开始时间
  80 + */
  81 + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
  82 + @JsonFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND, timezone = TIME_ZONE_DEFAULT)
  83 + private Date startTime;
  84 +
  85 + /**
  86 + * 任务结束时间
  87 + */
  88 + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
  89 + @JsonFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND, timezone = TIME_ZONE_DEFAULT)
  90 + private Date endTime;
  91 +
  92 + private Integer transactionOrder;
  93 +
  94 + private Long duration;
  95 +
  96 + /**
  97 + * 删除结果
  98 + */
  99 + private String deleteReason;
  100 +
  101 + /**
  102 + * 租户id
  103 + */
  104 + private String tenantId;
  105 +}
yudao-module-bpm/yudao-module-bpm-base/src/main/java/cn/iocoder/yudao/module/bpm/dal/dataobject/task/BpmProcessInstanceExtDO.java renamed to yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/dal/dataobject/task/BpmProcessInstanceExtDO.java
@@ -3,7 +3,6 @@ package cn.iocoder.yudao.module.bpm.dal.dataobject.task; @@ -3,7 +3,6 @@ package cn.iocoder.yudao.module.bpm.dal.dataobject.task;
3 import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; 3 import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
4 import cn.iocoder.yudao.module.bpm.enums.task.BpmProcessInstanceResultEnum; 4 import cn.iocoder.yudao.module.bpm.enums.task.BpmProcessInstanceResultEnum;
5 import cn.iocoder.yudao.module.bpm.enums.task.BpmProcessInstanceStatusEnum; 5 import cn.iocoder.yudao.module.bpm.enums.task.BpmProcessInstanceStatusEnum;
6 -import com.baomidou.mybatisplus.annotation.KeySequence;  
7 import com.baomidou.mybatisplus.annotation.TableField; 6 import com.baomidou.mybatisplus.annotation.TableField;
8 import com.baomidou.mybatisplus.annotation.TableId; 7 import com.baomidou.mybatisplus.annotation.TableId;
9 import com.baomidou.mybatisplus.annotation.TableName; 8 import com.baomidou.mybatisplus.annotation.TableName;
@@ -22,7 +21,6 @@ import java.util.Map; @@ -22,7 +21,6 @@ import java.util.Map;
22 * @author 芋道源码 21 * @author 芋道源码
23 */ 22 */
24 @TableName(value = "bpm_process_instance_ext", autoResultMap = true) 23 @TableName(value = "bpm_process_instance_ext", autoResultMap = true)
25 -@KeySequence("bpm_process_instance_ext_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。  
26 @Data 24 @Data
27 @EqualsAndHashCode(callSuper = true) 25 @EqualsAndHashCode(callSuper = true)
28 @ToString(callSuper = true) 26 @ToString(callSuper = true)
yudao-module-bpm/yudao-module-bpm-base/src/main/java/cn/iocoder/yudao/module/bpm/dal/dataobject/task/BpmTaskExtDO.java renamed to yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/dal/dataobject/task/BpmTaskExtDO.java
@@ -2,8 +2,6 @@ package cn.iocoder.yudao.module.bpm.dal.dataobject.task; @@ -2,8 +2,6 @@ package cn.iocoder.yudao.module.bpm.dal.dataobject.task;
2 2
3 import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; 3 import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
4 import cn.iocoder.yudao.module.bpm.enums.task.BpmProcessInstanceResultEnum; 4 import cn.iocoder.yudao.module.bpm.enums.task.BpmProcessInstanceResultEnum;
5 -import com.baomidou.mybatisplus.annotation.KeySequence;  
6 -import com.baomidou.mybatisplus.annotation.TableField;  
7 import com.baomidou.mybatisplus.annotation.TableId; 5 import com.baomidou.mybatisplus.annotation.TableId;
8 import com.baomidou.mybatisplus.annotation.TableName; 6 import com.baomidou.mybatisplus.annotation.TableName;
9 import lombok.Data; 7 import lombok.Data;
@@ -19,7 +17,6 @@ import java.util.Date; @@ -19,7 +17,6 @@ import java.util.Date;
19 * @author 芋道源码 17 * @author 芋道源码
20 */ 18 */
21 @TableName(value = "bpm_task_ext", autoResultMap = true) 19 @TableName(value = "bpm_task_ext", autoResultMap = true)
22 -@KeySequence("bpm_task_ext_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。  
23 @Data 20 @Data
24 @EqualsAndHashCode(callSuper = true) 21 @EqualsAndHashCode(callSuper = true)
25 @ToString(callSuper = true) 22 @ToString(callSuper = true)
@@ -30,6 +27,7 @@ public class BpmTaskExtDO extends BaseDO { @@ -30,6 +27,7 @@ public class BpmTaskExtDO extends BaseDO {
30 */ 27 */
31 @TableId 28 @TableId
32 private Long id; 29 private Long id;
  30 +
33 /** 31 /**
34 * 任务的审批人 32 * 任务的审批人
35 * 33 *
yudao-module-bpm/yudao-module-bpm-base/src/main/java/cn/iocoder/yudao/module/bpm/dal/mysql/definition/BpmFormMapper.java renamed to yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/dal/mysql/definition/BpmFormMapper.java
1 package cn.iocoder.yudao.module.bpm.dal.mysql.definition; 1 package cn.iocoder.yudao.module.bpm.dal.mysql.definition;
2 2
3 3
4 -import cn.iocoder.yudao.framework.common.pojo.PageResult;  
5 -import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;  
6 -import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;  
7 import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.form.BpmFormPageReqVO; 4 import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.form.BpmFormPageReqVO;
8 import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmFormDO; 5 import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmFormDO;
  6 +import cn.iocoder.yudao.framework.common.pojo.PageResult;
  7 +import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
  8 +import cn.iocoder.yudao.framework.mybatis.core.query.QueryWrapperX;
9 import org.apache.ibatis.annotations.Mapper; 9 import org.apache.ibatis.annotations.Mapper;
10 10
11 /** 11 /**
@@ -17,9 +17,9 @@ import org.apache.ibatis.annotations.Mapper; @@ -17,9 +17,9 @@ import org.apache.ibatis.annotations.Mapper;
17 public interface BpmFormMapper extends BaseMapperX<BpmFormDO> { 17 public interface BpmFormMapper extends BaseMapperX<BpmFormDO> {
18 18
19 default PageResult<BpmFormDO> selectPage(BpmFormPageReqVO reqVO) { 19 default PageResult<BpmFormDO> selectPage(BpmFormPageReqVO reqVO) {
20 - return selectPage(reqVO, new LambdaQueryWrapperX<BpmFormDO>()  
21 - .likeIfPresent(BpmFormDO::getName, reqVO.getName())  
22 - .orderByDesc(BpmFormDO::getId)); 20 + return selectPage(reqVO, new QueryWrapperX<BpmFormDO>()
  21 + .likeIfPresent("name", reqVO.getName())
  22 + .orderByDesc("id"));
23 } 23 }
24 24
25 } 25 }
yudao-module-bpm/yudao-module-bpm-base/src/main/java/cn/iocoder/yudao/module/bpm/dal/mysql/definition/BpmProcessDefinitionExtMapper.java renamed to yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/dal/mysql/definition/BpmProcessDefinitionExtMapper.java
1 package cn.iocoder.yudao.module.bpm.dal.mysql.definition; 1 package cn.iocoder.yudao.module.bpm.dal.mysql.definition;
2 2
3 -import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; 3 +import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
4 import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmProcessDefinitionExtDO; 4 import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmProcessDefinitionExtDO;
  5 +import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
5 import org.apache.ibatis.annotations.Mapper; 6 import org.apache.ibatis.annotations.Mapper;
6 7
7 import java.util.Collection; 8 import java.util.Collection;
@@ -11,11 +12,11 @@ import java.util.List; @@ -11,11 +12,11 @@ import java.util.List;
11 public interface BpmProcessDefinitionExtMapper extends BaseMapperX<BpmProcessDefinitionExtDO> { 12 public interface BpmProcessDefinitionExtMapper extends BaseMapperX<BpmProcessDefinitionExtDO> {
12 13
13 default List<BpmProcessDefinitionExtDO> selectListByProcessDefinitionIds(Collection<String> processDefinitionIds) { 14 default List<BpmProcessDefinitionExtDO> selectListByProcessDefinitionIds(Collection<String> processDefinitionIds) {
14 - return selectList(BpmProcessDefinitionExtDO::getProcessDefinitionId, processDefinitionIds); 15 + return selectList("process_definition_id", processDefinitionIds);
15 } 16 }
16 17
17 default BpmProcessDefinitionExtDO selectByProcessDefinitionId(String processDefinitionId) { 18 default BpmProcessDefinitionExtDO selectByProcessDefinitionId(String processDefinitionId) {
18 - return selectOne(BpmProcessDefinitionExtDO::getProcessDefinitionId, processDefinitionId); 19 + return selectOne("process_definition_id", processDefinitionId);
19 } 20 }
20 21
21 } 22 }
yudao-module-bpm/yudao-module-bpm-base/src/main/java/cn/iocoder/yudao/module/bpm/dal/mysql/definition/BpmTaskAssignRuleMapper.java renamed to yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/dal/mysql/definition/BpmTaskAssignRuleMapper.java
1 package cn.iocoder.yudao.module.bpm.dal.mysql.definition; 1 package cn.iocoder.yudao.module.bpm.dal.mysql.definition;
2 2
3 -import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;  
4 -import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;  
5 import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmTaskAssignRuleDO; 3 import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmTaskAssignRuleDO;
  4 +import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
  5 +import cn.iocoder.yudao.framework.mybatis.core.query.QueryWrapperX;
6 import org.apache.ibatis.annotations.Mapper; 6 import org.apache.ibatis.annotations.Mapper;
7 import org.springframework.lang.Nullable; 7 import org.springframework.lang.Nullable;
8 8
@@ -13,23 +13,25 @@ public interface BpmTaskAssignRuleMapper extends BaseMapperX&lt;BpmTaskAssignRuleDO @@ -13,23 +13,25 @@ public interface BpmTaskAssignRuleMapper extends BaseMapperX&lt;BpmTaskAssignRuleDO
13 13
14 default List<BpmTaskAssignRuleDO> selectListByProcessDefinitionId(String processDefinitionId, 14 default List<BpmTaskAssignRuleDO> selectListByProcessDefinitionId(String processDefinitionId,
15 @Nullable String taskDefinitionKey) { 15 @Nullable String taskDefinitionKey) {
16 - return selectList(new LambdaQueryWrapperX<BpmTaskAssignRuleDO>()  
17 - .eq(BpmTaskAssignRuleDO::getProcessDefinitionId, processDefinitionId)  
18 - .eqIfPresent(BpmTaskAssignRuleDO::getTaskDefinitionKey, taskDefinitionKey)); 16 + return selectList(new QueryWrapperX<BpmTaskAssignRuleDO>()
  17 + .eq("process_definition_id", processDefinitionId)
  18 + .eqIfPresent("task_definition_key", taskDefinitionKey));
19 } 19 }
20 20
21 default List<BpmTaskAssignRuleDO> selectListByModelId(String modelId) { 21 default List<BpmTaskAssignRuleDO> selectListByModelId(String modelId) {
22 - return selectList(new LambdaQueryWrapperX<BpmTaskAssignRuleDO>()  
23 - .eq(BpmTaskAssignRuleDO::getModelId, modelId)  
24 - .eq(BpmTaskAssignRuleDO::getProcessDefinitionId, BpmTaskAssignRuleDO.PROCESS_DEFINITION_ID_NULL)); 22 + return selectList(new QueryWrapperX<BpmTaskAssignRuleDO>()
  23 + .eq("model_id", modelId)
  24 + .eq("process_definition_id", BpmTaskAssignRuleDO.PROCESS_DEFINITION_ID_NULL));
25 } 25 }
26 26
27 default BpmTaskAssignRuleDO selectListByModelIdAndTaskDefinitionKey(String modelId, 27 default BpmTaskAssignRuleDO selectListByModelIdAndTaskDefinitionKey(String modelId,
28 String taskDefinitionKey) { 28 String taskDefinitionKey) {
29 - return selectOne(new LambdaQueryWrapperX<BpmTaskAssignRuleDO>()  
30 - .eq(BpmTaskAssignRuleDO::getModelId, modelId)  
31 - .eq(BpmTaskAssignRuleDO::getProcessDefinitionId, BpmTaskAssignRuleDO.PROCESS_DEFINITION_ID_NULL)  
32 - .eq(BpmTaskAssignRuleDO::getTaskDefinitionKey, taskDefinitionKey)); 29 + return selectOne(new QueryWrapperX<BpmTaskAssignRuleDO>()
  30 + .eq("model_id", modelId)
  31 + .eq("process_definition_id", BpmTaskAssignRuleDO.PROCESS_DEFINITION_ID_NULL)
  32 + .eq("task_definition_key", taskDefinitionKey));
33 } 33 }
34 34
  35 +
  36 +
35 } 37 }
yudao-module-bpm/yudao-module-bpm-base/src/main/java/cn/iocoder/yudao/module/bpm/dal/mysql/definition/BpmUserGroupMapper.java renamed to yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/dal/mysql/definition/BpmUserGroupMapper.java
yudao-module-bpm/yudao-module-bpm-base/src/main/java/cn/iocoder/yudao/module/bpm/dal/mysql/oa/BpmOALeaveMapper.java renamed to yudao-module-bpm/yudao-module-bpm-biz/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/BpmActivityMapper.java 0 → 100644
  1 +package cn.iocoder.yudao.module.bpm.dal.mysql.task;
  2 +
  3 +import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
  4 +import cn.iocoder.yudao.module.bpm.dal.dataobject.task.BpmActivityDO;
  5 +import org.apache.ibatis.annotations.Mapper;
  6 +import org.apache.ibatis.annotations.Param;
  7 +
  8 +import java.util.List;
  9 +
  10 +@Mapper
  11 +public interface BpmActivityMapper extends BaseMapperX<BpmActivityDO> {
  12 +
  13 +
  14 + // TODO @ke:可以试试,把 activiti 的表,映射成对应的实体,然后读取下。我们尽量避免 xml 操作,因为要做多 db 类型的支持,例如说 oracle 等。通过 mybatis plus 帮助我们生成不同数据库的表操作
  15 + /**
  16 + * 获取指定流程的历史任务
  17 + *
  18 + * @param procInstId 流程id
  19 + *
  20 + * @return 返回历史任务
  21 + */
  22 + List<BpmActivityDO> listAllByProcInstIdAndDelete(@Param("procInstId") String procInstId);
  23 +
  24 + /**
  25 + * 逻辑删除hiActInst表任务
  26 + *
  27 + * @param taskIdList 任务列表
  28 + *
  29 + * @return 返回是否成功
  30 + */
  31 + Boolean delHiActInstByTaskId(@Param("taskIdList") List<String> taskIdList);
  32 +
  33 + /**
  34 + * 逻辑删除hiTaskInst任务
  35 + *
  36 + * @param taskIdList 任务列表
  37 + *
  38 + * @return 返回是否成功
  39 + */
  40 + Boolean delHiTaskInstByTaskId(@Param("taskIdList") List<String> taskIdList);
  41 +}
yudao-module-bpm/yudao-module-bpm-base/src/main/java/cn/iocoder/yudao/module/bpm/dal/mysql/task/BpmProcessInstanceExtMapper.java renamed to yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/dal/mysql/task/BpmProcessInstanceExtMapper.java
1 package cn.iocoder.yudao.module.bpm.dal.mysql.task; 1 package cn.iocoder.yudao.module.bpm.dal.mysql.task;
2 2
3 -import cn.iocoder.yudao.framework.common.pojo.PageResult;  
4 -import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;  
5 -import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;  
6 import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance.BpmProcessInstanceMyPageReqVO; 3 import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance.BpmProcessInstanceMyPageReqVO;
7 import cn.iocoder.yudao.module.bpm.dal.dataobject.task.BpmProcessInstanceExtDO; 4 import cn.iocoder.yudao.module.bpm.dal.dataobject.task.BpmProcessInstanceExtDO;
  5 +import cn.iocoder.yudao.framework.common.pojo.PageResult;
  6 +import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
  7 +import cn.iocoder.yudao.framework.mybatis.core.query.QueryWrapperX;
  8 +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
8 import org.apache.ibatis.annotations.Mapper; 9 import org.apache.ibatis.annotations.Mapper;
9 10
10 @Mapper 11 @Mapper
11 public interface BpmProcessInstanceExtMapper extends BaseMapperX<BpmProcessInstanceExtDO> { 12 public interface BpmProcessInstanceExtMapper extends BaseMapperX<BpmProcessInstanceExtDO> {
12 13
13 default PageResult<BpmProcessInstanceExtDO> selectPage(Long userId, BpmProcessInstanceMyPageReqVO reqVO) { 14 default PageResult<BpmProcessInstanceExtDO> selectPage(Long userId, BpmProcessInstanceMyPageReqVO reqVO) {
14 - return selectPage(reqVO, new LambdaQueryWrapperX<BpmProcessInstanceExtDO>()  
15 - .eqIfPresent(BpmProcessInstanceExtDO::getStartUserId, userId)  
16 - .likeIfPresent(BpmProcessInstanceExtDO::getName, reqVO.getName())  
17 - .eqIfPresent(BpmProcessInstanceExtDO::getProcessDefinitionId, reqVO.getProcessDefinitionId())  
18 - .eqIfPresent(BpmProcessInstanceExtDO::getCategory, reqVO.getCategory())  
19 - .eqIfPresent(BpmProcessInstanceExtDO::getStatus, reqVO.getStatus())  
20 - .eqIfPresent(BpmProcessInstanceExtDO::getResult, reqVO.getResult())  
21 - .betweenIfPresent(BpmProcessInstanceExtDO::getCreateTime, reqVO.getBeginCreateTime(), reqVO.getEndCreateTime())  
22 - .orderByDesc(BpmProcessInstanceExtDO::getId)); 15 + return selectPage(reqVO, new QueryWrapperX<BpmProcessInstanceExtDO>()
  16 + .eqIfPresent("start_user_id", userId)
  17 + .likeIfPresent("name", reqVO.getName())
  18 + .eqIfPresent("process_definition_id", reqVO.getProcessDefinitionId())
  19 + .eqIfPresent("category", reqVO.getCategory())
  20 + .eqIfPresent("status", reqVO.getStatus())
  21 + .eqIfPresent("result", reqVO.getResult())
  22 + .betweenIfPresent("create_time", reqVO.getBeginCreateTime(), reqVO.getEndCreateTime())
  23 + .orderByDesc("id"));
23 } 24 }
24 25
25 default BpmProcessInstanceExtDO selectByProcessInstanceId(String processDefinitionId) { 26 default BpmProcessInstanceExtDO selectByProcessInstanceId(String processDefinitionId) {
26 - return selectOne(BpmProcessInstanceExtDO::getProcessInstanceId, processDefinitionId); 27 + return selectOne("process_instance_id", processDefinitionId);
27 } 28 }
28 29
29 default void updateByProcessInstanceId(BpmProcessInstanceExtDO updateObj) { 30 default void updateByProcessInstanceId(BpmProcessInstanceExtDO updateObj) {
30 - update(updateObj, new LambdaQueryWrapperX<BpmProcessInstanceExtDO>()  
31 - .eq(BpmProcessInstanceExtDO::getProcessInstanceId, updateObj.getProcessInstanceId())); 31 + update(updateObj, new QueryWrapper<BpmProcessInstanceExtDO>()
  32 + .eq("process_instance_id", updateObj.getProcessInstanceId()));
32 } 33 }
33 34
34 } 35 }
yudao-module-bpm/yudao-module-bpm-base/src/main/java/cn/iocoder/yudao/module/bpm/dal/mysql/task/BpmTaskExtMapper.java renamed to yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/dal/mysql/task/BpmTaskExtMapper.java
@@ -19,7 +19,8 @@ public interface BpmTaskExtMapper extends BaseMapperX&lt;BpmTaskExtDO&gt; { @@ -19,7 +19,8 @@ public interface BpmTaskExtMapper extends BaseMapperX&lt;BpmTaskExtDO&gt; {
19 return selectList(BpmTaskExtDO::getTaskId, taskIds); 19 return selectList(BpmTaskExtDO::getTaskId, taskIds);
20 } 20 }
21 21
22 - default List<BpmTaskExtDO> selectListByProcessInstanceId(String processInstanceId) {  
23 - return selectList(BpmTaskExtDO::getProcessInstanceId, processInstanceId); 22 + default BpmTaskExtDO selectByTaskId(String taskId) {
  23 + return selectOne(BpmTaskExtDO::getTaskId, taskId);
24 } 24 }
  25 +
25 } 26 }
yudao-module-bpm/yudao-module-bpm-base/src/main/java/cn/iocoder/yudao/module/bpm/framework/bpm/config/BpmCommonConfiguration.java renamed to yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/bpm/config/BpmCommonConfiguration.java
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/bpm/config/BpmSecurityConfiguration.java 0 → 100644
  1 +package cn.iocoder.yudao.module.bpm.framework.bpm.config;
  2 +
  3 +import cn.iocoder.yudao.framework.security.config.AuthorizeRequestsCustomizer;
  4 +import org.springframework.context.annotation.Bean;
  5 +import org.springframework.context.annotation.Configuration;
  6 +import org.springframework.security.config.annotation.web.builders.HttpSecurity;
  7 +import org.springframework.security.config.annotation.web.configurers.ExpressionUrlAuthorizationConfigurer;
  8 +
  9 +/**
  10 + * @author kemengkai
  11 + * @create 2022-05-07 08:15
  12 + */
  13 +@Configuration("bpmSecurityConfiguration")
  14 +public class BpmSecurityConfiguration {
  15 +
  16 + @Bean("bpmAuthorizeRequestsCustomizer")
  17 + public AuthorizeRequestsCustomizer authorizeRequestsCustomizer() {
  18 + return new AuthorizeRequestsCustomizer() {
  19 +
  20 + @Override
  21 + public void customize(ExpressionUrlAuthorizationConfigurer<HttpSecurity>.ExpressionInterceptUrlRegistry registry) {
  22 + // 任务回退接口
  23 + registry.antMatchers(buildAdminApi("/bpm/task/back")).permitAll();
  24 + }
  25 +
  26 + };
  27 + }
  28 +}
yudao-module-bpm/yudao-module-bpm-base/src/main/java/cn/iocoder/yudao/module/bpm/framework/bpm/core/event/BpmProcessInstanceResultEvent.java renamed to yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/bpm/core/event/BpmProcessInstanceResultEvent.java
yudao-module-bpm/yudao-module-bpm-base/src/main/java/cn/iocoder/yudao/module/bpm/framework/bpm/core/event/BpmProcessInstanceResultEventListener.java renamed to yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/bpm/core/event/BpmProcessInstanceResultEventListener.java
yudao-module-bpm/yudao-module-bpm-base/src/main/java/cn/iocoder/yudao/module/bpm/framework/bpm/core/event/BpmProcessInstanceResultEventPublisher.java renamed to yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/bpm/core/event/BpmProcessInstanceResultEventPublisher.java
yudao-module-bpm/yudao-module-bpm-base/src/main/java/cn/iocoder/yudao/module/bpm/framework/bpm/core/event/package-info.java renamed to yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/bpm/core/event/package-info.java
yudao-module-bpm/yudao-module-bpm-base/src/main/java/cn/iocoder/yudao/module/bpm/framework/bpm/core/package-info.java renamed to yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/bpm/core/package-info.java
yudao-module-bpm/yudao-module-bpm-base/src/main/java/cn/iocoder/yudao/module/bpm/framework/bpm/package-info.java renamed to yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/bpm/package-info.java
yudao-module-bpm/yudao-module-bpm-biz-flowable/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/config/BpmFlowableConfiguration.java renamed to yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/config/BpmFlowableConfiguration.java
@@ -2,12 +2,7 @@ package cn.iocoder.yudao.module.bpm.framework.flowable.config; @@ -2,12 +2,7 @@ package cn.iocoder.yudao.module.bpm.framework.flowable.config;
2 2
3 import cn.hutool.core.collection.ListUtil; 3 import cn.hutool.core.collection.ListUtil;
4 import cn.iocoder.yudao.module.bpm.framework.flowable.core.behavior.BpmActivityBehaviorFactory; 4 import cn.iocoder.yudao.module.bpm.framework.flowable.core.behavior.BpmActivityBehaviorFactory;
5 -import cn.iocoder.yudao.module.bpm.framework.flowable.core.behavior.script.BpmTaskAssignScript;  
6 import cn.iocoder.yudao.module.bpm.service.definition.BpmTaskAssignRuleService; 5 import cn.iocoder.yudao.module.bpm.service.definition.BpmTaskAssignRuleService;
7 -import cn.iocoder.yudao.module.bpm.service.definition.BpmUserGroupService;  
8 -import cn.iocoder.yudao.module.system.api.dept.DeptApi;  
9 -import cn.iocoder.yudao.module.system.api.permission.PermissionApi;  
10 -import cn.iocoder.yudao.module.system.api.user.AdminUserApi;  
11 import org.flowable.common.engine.api.delegate.event.FlowableEventListener; 6 import org.flowable.common.engine.api.delegate.event.FlowableEventListener;
12 import org.flowable.spring.SpringProcessEngineConfiguration; 7 import org.flowable.spring.SpringProcessEngineConfiguration;
13 import org.flowable.spring.boot.EngineConfigurationConfigurer; 8 import org.flowable.spring.boot.EngineConfigurationConfigurer;
@@ -15,8 +10,6 @@ import org.springframework.beans.factory.ObjectProvider; @@ -15,8 +10,6 @@ import org.springframework.beans.factory.ObjectProvider;
15 import org.springframework.context.annotation.Bean; 10 import org.springframework.context.annotation.Bean;
16 import org.springframework.context.annotation.Configuration; 11 import org.springframework.context.annotation.Configuration;
17 12
18 -import java.util.List;  
19 -  
20 /** 13 /**
21 * BPM 模块的 Flowable 配置类 14 * BPM 模块的 Flowable 配置类
22 * 15 *
@@ -36,7 +29,7 @@ public class BpmFlowableConfiguration { @@ -36,7 +29,7 @@ public class BpmFlowableConfiguration {
36 ObjectProvider<FlowableEventListener> listeners, 29 ObjectProvider<FlowableEventListener> listeners,
37 BpmActivityBehaviorFactory bpmActivityBehaviorFactory) { 30 BpmActivityBehaviorFactory bpmActivityBehaviorFactory) {
38 return configuration -> { 31 return configuration -> {
39 - // 注册监听器,例如说 BpmActivitiEventListener 32 + // 注册监听器,例如说 BpmActivityEventListener
40 configuration.setEventListeners(ListUtil.toList(listeners.iterator())); 33 configuration.setEventListeners(ListUtil.toList(listeners.iterator()));
41 // 设置 ActivityBehaviorFactory 实现类,用于流程任务的审核人的自定义 34 // 设置 ActivityBehaviorFactory 实现类,用于流程任务的审核人的自定义
42 configuration.setActivityBehaviorFactory(bpmActivityBehaviorFactory); 35 configuration.setActivityBehaviorFactory(bpmActivityBehaviorFactory);
@@ -44,19 +37,10 @@ public class BpmFlowableConfiguration { @@ -44,19 +37,10 @@ public class BpmFlowableConfiguration {
44 } 37 }
45 38
46 @Bean 39 @Bean
47 - public BpmActivityBehaviorFactory bpmActivityBehaviorFactory(BpmTaskAssignRuleService taskRuleService,  
48 - BpmUserGroupService userGroupService,  
49 - PermissionApi permissionApi,  
50 - DeptApi deptApi,  
51 - AdminUserApi adminUserApi,  
52 - List<BpmTaskAssignScript> scripts) { 40 + public BpmActivityBehaviorFactory bpmActivityBehaviorFactory(BpmTaskAssignRuleService taskRuleService) {
53 BpmActivityBehaviorFactory bpmActivityBehaviorFactory = new BpmActivityBehaviorFactory(); 41 BpmActivityBehaviorFactory bpmActivityBehaviorFactory = new BpmActivityBehaviorFactory();
54 bpmActivityBehaviorFactory.setBpmTaskRuleService(taskRuleService); 42 bpmActivityBehaviorFactory.setBpmTaskRuleService(taskRuleService);
55 - bpmActivityBehaviorFactory.setUserGroupService(userGroupService);  
56 - bpmActivityBehaviorFactory.setAdminUserApi(adminUserApi);  
57 - bpmActivityBehaviorFactory.setPermissionApi(permissionApi);  
58 - bpmActivityBehaviorFactory.setDeptApi(deptApi);  
59 - bpmActivityBehaviorFactory.setScripts(scripts);  
60 return bpmActivityBehaviorFactory; 43 return bpmActivityBehaviorFactory;
61 } 44 }
  45 +
62 } 46 }
yudao-module-bpm/yudao-module-bpm-biz-flowable/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/behavior/BpmActivityBehaviorFactory.java renamed to yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/behavior/BpmActivityBehaviorFactory.java
1 package cn.iocoder.yudao.module.bpm.framework.flowable.core.behavior; 1 package cn.iocoder.yudao.module.bpm.framework.flowable.core.behavior;
2 2
3 -import cn.iocoder.yudao.module.bpm.framework.flowable.core.behavior.script.BpmTaskAssignScript;  
4 import cn.iocoder.yudao.module.bpm.service.definition.BpmTaskAssignRuleService; 3 import cn.iocoder.yudao.module.bpm.service.definition.BpmTaskAssignRuleService;
5 -import cn.iocoder.yudao.module.bpm.service.definition.BpmUserGroupService;  
6 -import cn.iocoder.yudao.module.system.api.dept.DeptApi;  
7 -import cn.iocoder.yudao.module.system.api.permission.PermissionApi;  
8 -import cn.iocoder.yudao.module.system.api.user.AdminUserApi;  
9 import lombok.Data; 4 import lombok.Data;
10 import lombok.EqualsAndHashCode; 5 import lombok.EqualsAndHashCode;
11 import lombok.Setter; 6 import lombok.Setter;
12 import lombok.ToString; 7 import lombok.ToString;
  8 +import org.flowable.bpmn.model.Activity;
13 import org.flowable.bpmn.model.UserTask; 9 import org.flowable.bpmn.model.UserTask;
  10 +import org.flowable.engine.impl.bpmn.behavior.AbstractBpmnActivityBehavior;
  11 +import org.flowable.engine.impl.bpmn.behavior.ParallelMultiInstanceBehavior;
14 import org.flowable.engine.impl.bpmn.behavior.UserTaskActivityBehavior; 12 import org.flowable.engine.impl.bpmn.behavior.UserTaskActivityBehavior;
15 import org.flowable.engine.impl.bpmn.parser.factory.DefaultActivityBehaviorFactory; 13 import org.flowable.engine.impl.bpmn.parser.factory.DefaultActivityBehaviorFactory;
16 14
17 -import java.util.List;  
18 -  
19 /** 15 /**
20 * 自定义的 ActivityBehaviorFactory 实现类,目的如下: 16 * 自定义的 ActivityBehaviorFactory 实现类,目的如下:
21 * 1. 自定义 {@link #createUserTaskActivityBehavior(UserTask)}:实现自定义的流程任务的 assignee 负责人的分配 17 * 1. 自定义 {@link #createUserTaskActivityBehavior(UserTask)}:实现自定义的流程任务的 assignee 负责人的分配
@@ -29,27 +25,20 @@ public class BpmActivityBehaviorFactory extends DefaultActivityBehaviorFactory { @@ -29,27 +25,20 @@ public class BpmActivityBehaviorFactory extends DefaultActivityBehaviorFactory {
29 25
30 @Setter 26 @Setter
31 private BpmTaskAssignRuleService bpmTaskRuleService; 27 private BpmTaskAssignRuleService bpmTaskRuleService;
32 - @Setter  
33 - private BpmUserGroupService userGroupService;  
34 -  
35 - @Setter  
36 - private PermissionApi permissionApi;  
37 - @Setter  
38 - private DeptApi deptApi;  
39 - @Setter  
40 - private AdminUserApi adminUserApi;  
41 - @Setter  
42 - private List<BpmTaskAssignScript> scripts;  
43 28
44 @Override 29 @Override
45 public UserTaskActivityBehavior createUserTaskActivityBehavior(UserTask userTask) { 30 public UserTaskActivityBehavior createUserTaskActivityBehavior(UserTask userTask) {
46 - BpmUserTaskActivityBehavior userTaskActivityBehavior = new BpmUserTaskActivityBehavior(userTask);  
47 - userTaskActivityBehavior.setBpmTaskRuleService(bpmTaskRuleService);  
48 - userTaskActivityBehavior.setPermissionApi(permissionApi);  
49 - userTaskActivityBehavior.setDeptApi(deptApi);  
50 - userTaskActivityBehavior.setUserGroupService(userGroupService);  
51 - userTaskActivityBehavior.setAdminUserApi(adminUserApi);  
52 - userTaskActivityBehavior.setScripts(scripts);  
53 - return userTaskActivityBehavior; 31 + return new BpmUserTaskActivityBehavior(userTask)
  32 + .setBpmTaskRuleService(bpmTaskRuleService);
  33 + }
  34 +
  35 + @Override
  36 + public ParallelMultiInstanceBehavior createParallelMultiInstanceBehavior(Activity activity,
  37 + AbstractBpmnActivityBehavior innerActivityBehavior) {
  38 + return new BpmParallelMultiInstanceBehavior(activity, innerActivityBehavior)
  39 + .setBpmTaskRuleService(bpmTaskRuleService);
54 } 40 }
  41 +
  42 + // TODO @ke:SequentialMultiInstanceBehavior 这个抽空也可以看看
  43 +
55 } 44 }
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/behavior/BpmParallelMultiInstanceBehavior.java 0 → 100644
  1 +package cn.iocoder.yudao.module.bpm.framework.flowable.core.behavior;
  2 +
  3 +import cn.iocoder.yudao.framework.flowable.core.util.FlowableUtils;
  4 +import cn.iocoder.yudao.module.bpm.service.definition.BpmTaskAssignRuleService;
  5 +import lombok.Setter;
  6 +import lombok.extern.slf4j.Slf4j;
  7 +import org.flowable.bpmn.model.Activity;
  8 +import org.flowable.engine.delegate.DelegateExecution;
  9 +import org.flowable.engine.impl.bpmn.behavior.AbstractBpmnActivityBehavior;
  10 +import org.flowable.engine.impl.bpmn.behavior.ParallelMultiInstanceBehavior;
  11 +
  12 +import java.util.Set;
  13 +
  14 +/**
  15 + * 自定义的【并行】的【多个】流程任务的 assignee 负责人的分配
  16 + * 第一步,基于分配规则,计算出分配任务的【多个】候选人们。
  17 + * 第二步,将【多个】任务候选人们,设置到 DelegateExecution 的 collectionVariable 变量中,以便 BpmUserTaskActivityBehavior 使用它
  18 + *
  19 + * @author kemengkai
  20 + * @date 2022-04-21 16:57
  21 + */
  22 +@Slf4j
  23 +public class BpmParallelMultiInstanceBehavior extends ParallelMultiInstanceBehavior {
  24 +
  25 + @Setter
  26 + private BpmTaskAssignRuleService bpmTaskRuleService;
  27 +
  28 + public BpmParallelMultiInstanceBehavior(Activity activity,
  29 + AbstractBpmnActivityBehavior innerActivityBehavior) {
  30 + super(activity, innerActivityBehavior);
  31 + }
  32 +
  33 + /**
  34 + * 重写该方法,主要实现两个功能:
  35 + * 1. 忽略原有的 collectionVariable、collectionElementVariable 表达式,而是采用自己定义的
  36 + * 2. 获得任务的处理人,并设置到 collectionVariable 中,用于 BpmUserTaskActivityBehavior 从中可以获取任务的处理人
  37 + *
  38 + * 注意,多个任务实例,每个任务实例对应一个处理人,所以返回的数量就是任务处理人的数量
  39 + *
  40 + * @param execution 执行任务
  41 + * @return 数量
  42 + */
  43 + @Override
  44 + protected int resolveNrOfInstances(DelegateExecution execution) {
  45 + // 第一步,设置 collectionVariable 和 CollectionVariable
  46 + // 从 execution.getVariable() 读取所有任务处理人的 key
  47 + super.collectionExpression = null; // collectionExpression 和 collectionVariable 是互斥的
  48 + super.collectionVariable = FlowableUtils.formatCollectionVariable(execution.getCurrentActivityId());
  49 + // 从 execution.getVariable() 读取当前所有任务处理的人的 key
  50 + super.collectionElementVariable = FlowableUtils.formatCollectionElementVariable(execution.getCurrentActivityId());
  51 +
  52 + // 第二步,获取任务的所有处理人
  53 + Set<Long> assigneeUserIds = bpmTaskRuleService.calculateTaskCandidateUsers(execution);
  54 + execution.setVariable(super.collectionVariable, assigneeUserIds);
  55 + return assigneeUserIds.size();
  56 + }
  57 +
  58 +}
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/behavior/BpmUserTaskActivityBehavior.java 0 → 100644
  1 +package cn.iocoder.yudao.module.bpm.framework.flowable.core.behavior;
  2 +
  3 +import cn.hutool.core.collection.CollUtil;
  4 +import cn.hutool.core.lang.Assert;
  5 +import cn.hutool.core.util.RandomUtil;
  6 +import cn.iocoder.yudao.module.bpm.service.definition.BpmTaskAssignRuleService;
  7 +import lombok.Setter;
  8 +import lombok.extern.slf4j.Slf4j;
  9 +import org.flowable.bpmn.model.UserTask;
  10 +import org.flowable.common.engine.impl.el.ExpressionManager;
  11 +import org.flowable.engine.delegate.DelegateExecution;
  12 +import org.flowable.engine.impl.bpmn.behavior.UserTaskActivityBehavior;
  13 +import org.flowable.engine.impl.cfg.ProcessEngineConfigurationImpl;
  14 +import org.flowable.engine.impl.util.TaskHelper;
  15 +import org.flowable.task.service.TaskService;
  16 +import org.flowable.task.service.impl.persistence.entity.TaskEntity;
  17 +
  18 +import java.util.List;
  19 +import java.util.Set;
  20 +
  21 +/**
  22 + * 自定义的【单个】流程任务的 assignee 负责人的分配
  23 + * 第一步,基于分配规则,计算出分配任务的【单个】候选人。如果找不到,则直接报业务异常,不继续执行后续的流程;
  24 + * 第二步,随机选择一个候选人,则选择作为 assignee 负责人。
  25 + *
  26 + * @author 芋道源码
  27 + */
  28 +@Slf4j
  29 +public class BpmUserTaskActivityBehavior extends UserTaskActivityBehavior {
  30 +
  31 + @Setter
  32 + private BpmTaskAssignRuleService bpmTaskRuleService;
  33 +
  34 + public BpmUserTaskActivityBehavior(UserTask userTask) {
  35 + super(userTask);
  36 + }
  37 +
  38 + @Override
  39 + protected void handleAssignments(TaskService taskService, String assignee, String owner,
  40 + List<String> candidateUsers, List<String> candidateGroups, TaskEntity task, ExpressionManager expressionManager,
  41 + DelegateExecution execution, ProcessEngineConfigurationImpl processEngineConfiguration) {
  42 + // 第一步,获得任务的候选用户
  43 + Long assigneeUserId = calculateTaskCandidateUsers(execution);
  44 + Assert.notNull(assigneeUserId, "任务处理人不能为空");
  45 + // 第二步,设置作为负责人
  46 + TaskHelper.changeTaskAssignee(task, String.valueOf(assigneeUserId));
  47 + }
  48 +
  49 + private Long calculateTaskCandidateUsers(DelegateExecution execution) {
  50 + // 情况一,如果是多实例的任务,例如说会签、或签等情况,则从 Variable 中获取。它的任务处理人在 BpmParallelMultiInstanceBehavior 中已经被分配了
  51 + if (super.multiInstanceActivityBehavior != null) {
  52 + return execution.getVariable(super.multiInstanceActivityBehavior.getCollectionElementVariable(), Long.class);
  53 + }
  54 +
  55 + // 情况二,如果非多实例的任务,则计算任务处理人
  56 + // 第一步,先计算可处理该任务的处理人们
  57 + Set<Long> candidateUserIds = bpmTaskRuleService.calculateTaskCandidateUsers(execution);
  58 + // 第二步,后随机选择一个任务的处理人
  59 + // 疑问:为什么一定要选择一个任务处理人?
  60 + // 解答:项目对 bpm 的任务是责任到人,所以每个任务有且仅有一个处理人。
  61 + // 如果希望一个任务可以同时被多个人处理,可以考虑使用 BpmParallelMultiInstanceBehavior 实现的会签 or 或签。
  62 + int index = RandomUtil.randomInt(candidateUserIds.size());
  63 + return CollUtil.get(candidateUserIds, index);
  64 + }
  65 +
  66 +}
yudao-module-bpm/yudao-module-bpm-biz-flowable/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/behavior/script/BpmTaskAssignScript.java renamed to yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/behavior/script/BpmTaskAssignScript.java
1 package cn.iocoder.yudao.module.bpm.framework.flowable.core.behavior.script; 1 package cn.iocoder.yudao.module.bpm.framework.flowable.core.behavior.script;
2 2
3 import cn.iocoder.yudao.module.bpm.enums.definition.BpmTaskRuleScriptEnum; 3 import cn.iocoder.yudao.module.bpm.enums.definition.BpmTaskRuleScriptEnum;
4 -import org.flowable.task.service.impl.persistence.entity.TaskEntity; 4 +import org.flowable.engine.delegate.DelegateExecution;
5 5
6 import java.util.Set; 6 import java.util.Set;
7 7
@@ -17,12 +17,12 @@ import java.util.Set; @@ -17,12 +17,12 @@ import java.util.Set;
17 public interface BpmTaskAssignScript { 17 public interface BpmTaskAssignScript {
18 18
19 /** 19 /**
20 - * 基于流程任务,获得任务的候选用户们 20 + * 基于执行任务,获得任务的候选用户们
21 * 21 *
22 - * @param task 任务 22 + * @param execution 执行任务
23 * @return 候选人用户的编号数组 23 * @return 候选人用户的编号数组
24 */ 24 */
25 - Set<Long> calculateTaskCandidateUsers(TaskEntity task); 25 + Set<Long> calculateTaskCandidateUsers(DelegateExecution execution);
26 26
27 /** 27 /**
28 * 获得枚举值 28 * 获得枚举值
yudao-module-bpm/yudao-module-bpm-biz-flowable/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/behavior/script/impl/BpmTaskAssignLeaderAbstractScript.java renamed to yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/behavior/script/impl/BpmTaskAssignLeaderAbstractScript.java
@@ -7,9 +7,8 @@ import cn.iocoder.yudao.module.system.api.dept.DeptApi; @@ -7,9 +7,8 @@ import cn.iocoder.yudao.module.system.api.dept.DeptApi;
7 import cn.iocoder.yudao.module.system.api.dept.dto.DeptRespDTO; 7 import cn.iocoder.yudao.module.system.api.dept.dto.DeptRespDTO;
8 import cn.iocoder.yudao.module.system.api.user.AdminUserApi; 8 import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
9 import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO; 9 import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
10 - 10 +import org.flowable.engine.delegate.DelegateExecution;
11 import org.flowable.engine.runtime.ProcessInstance; 11 import org.flowable.engine.runtime.ProcessInstance;
12 -import org.flowable.task.service.impl.persistence.entity.TaskEntity;  
13 import org.springframework.context.annotation.Lazy; 12 import org.springframework.context.annotation.Lazy;
14 import org.springframework.util.Assert; 13 import org.springframework.util.Assert;
15 14
@@ -35,10 +34,10 @@ public abstract class BpmTaskAssignLeaderAbstractScript implements BpmTaskAssign @@ -35,10 +34,10 @@ public abstract class BpmTaskAssignLeaderAbstractScript implements BpmTaskAssign
35 @Lazy // 解决循环依赖 34 @Lazy // 解决循环依赖
36 private BpmProcessInstanceService bpmProcessInstanceService; 35 private BpmProcessInstanceService bpmProcessInstanceService;
37 36
38 - protected Set<Long> calculateTaskCandidateUsers(TaskEntity task, int level) { 37 + protected Set<Long> calculateTaskCandidateUsers(DelegateExecution execution, int level) {
39 Assert.isTrue(level > 0, "level 必须大于 0"); 38 Assert.isTrue(level > 0, "level 必须大于 0");
40 // 获得发起人 39 // 获得发起人
41 - ProcessInstance processInstance = bpmProcessInstanceService.getProcessInstance(task.getProcessInstanceId()); 40 + ProcessInstance processInstance = bpmProcessInstanceService.getProcessInstance(execution.getProcessInstanceId());
42 Long startUserId = NumberUtils.parseLong(processInstance.getStartUserId()); 41 Long startUserId = NumberUtils.parseLong(processInstance.getStartUserId());
43 // 获得对应 leve 的部门 42 // 获得对应 leve 的部门
44 DeptRespDTO dept = null; 43 DeptRespDTO dept = null;
yudao-module-bpm/yudao-module-bpm-biz-flowable/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/behavior/script/impl/BpmTaskAssignLeaderX1Script.java renamed to yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/behavior/script/impl/BpmTaskAssignLeaderX1Script.java
1 package cn.iocoder.yudao.module.bpm.framework.flowable.core.behavior.script.impl; 1 package cn.iocoder.yudao.module.bpm.framework.flowable.core.behavior.script.impl;
2 2
3 -import cn.iocoder.yudao.framework.datapermission.core.annotation.DataPermission;  
4 import cn.iocoder.yudao.module.bpm.enums.definition.BpmTaskRuleScriptEnum; 3 import cn.iocoder.yudao.module.bpm.enums.definition.BpmTaskRuleScriptEnum;
5 -import org.flowable.task.service.impl.persistence.entity.TaskEntity; 4 +import org.flowable.engine.delegate.DelegateExecution;
6 import org.springframework.stereotype.Component; 5 import org.springframework.stereotype.Component;
7 6
8 import java.util.Set; 7 import java.util.Set;
@@ -16,9 +15,8 @@ import java.util.Set; @@ -16,9 +15,8 @@ import java.util.Set;
16 public class BpmTaskAssignLeaderX1Script extends BpmTaskAssignLeaderAbstractScript { 15 public class BpmTaskAssignLeaderX1Script extends BpmTaskAssignLeaderAbstractScript {
17 16
18 @Override 17 @Override
19 - @DataPermission(enable = false) // 不需要处理数据权限, 不然会有问题,查询不到数据  
20 - public Set<Long> calculateTaskCandidateUsers(TaskEntity task) {  
21 - return calculateTaskCandidateUsers(task, 1); 18 + public Set<Long> calculateTaskCandidateUsers(DelegateExecution execution) {
  19 + return calculateTaskCandidateUsers(execution, 1);
22 } 20 }
23 21
24 @Override 22 @Override
yudao-module-bpm/yudao-module-bpm-biz-flowable/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/behavior/script/impl/BpmTaskAssignLeaderX2Script.java renamed to yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/behavior/script/impl/BpmTaskAssignLeaderX2Script.java
1 package cn.iocoder.yudao.module.bpm.framework.flowable.core.behavior.script.impl; 1 package cn.iocoder.yudao.module.bpm.framework.flowable.core.behavior.script.impl;
2 2
3 -import cn.iocoder.yudao.framework.datapermission.core.annotation.DataPermission;  
4 import cn.iocoder.yudao.module.bpm.enums.definition.BpmTaskRuleScriptEnum; 3 import cn.iocoder.yudao.module.bpm.enums.definition.BpmTaskRuleScriptEnum;
5 -import org.flowable.task.service.impl.persistence.entity.TaskEntity; 4 +import org.flowable.engine.delegate.DelegateExecution;
6 import org.springframework.stereotype.Component; 5 import org.springframework.stereotype.Component;
7 6
8 import java.util.Set; 7 import java.util.Set;
@@ -16,9 +15,8 @@ import java.util.Set; @@ -16,9 +15,8 @@ import java.util.Set;
16 public class BpmTaskAssignLeaderX2Script extends BpmTaskAssignLeaderAbstractScript { 15 public class BpmTaskAssignLeaderX2Script extends BpmTaskAssignLeaderAbstractScript {
17 16
18 @Override 17 @Override
19 - @DataPermission(enable = false) // 不需要处理数据权限, 不然会有问题,查询不到数据  
20 - public Set<Long> calculateTaskCandidateUsers(TaskEntity task) {  
21 - return calculateTaskCandidateUsers(task, 2); 18 + public Set<Long> calculateTaskCandidateUsers(DelegateExecution execution) {
  19 + return calculateTaskCandidateUsers(execution, 2);
22 } 20 }
23 21
24 @Override 22 @Override
yudao-module-bpm/yudao-module-bpm-biz-flowable/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/behavior/script/impl/BpmTaskAssignStartUserScript.java renamed to yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/behavior/script/impl/BpmTaskAssignStartUserScript.java
@@ -3,11 +3,10 @@ package cn.iocoder.yudao.module.bpm.framework.flowable.core.behavior.script.impl @@ -3,11 +3,10 @@ package cn.iocoder.yudao.module.bpm.framework.flowable.core.behavior.script.impl
3 import cn.iocoder.yudao.framework.common.util.collection.SetUtils; 3 import cn.iocoder.yudao.framework.common.util.collection.SetUtils;
4 import cn.iocoder.yudao.framework.common.util.number.NumberUtils; 4 import cn.iocoder.yudao.framework.common.util.number.NumberUtils;
5 import cn.iocoder.yudao.module.bpm.enums.definition.BpmTaskRuleScriptEnum; 5 import cn.iocoder.yudao.module.bpm.enums.definition.BpmTaskRuleScriptEnum;
6 -  
7 import cn.iocoder.yudao.module.bpm.framework.flowable.core.behavior.script.BpmTaskAssignScript; 6 import cn.iocoder.yudao.module.bpm.framework.flowable.core.behavior.script.BpmTaskAssignScript;
8 import cn.iocoder.yudao.module.bpm.service.task.BpmProcessInstanceService; 7 import cn.iocoder.yudao.module.bpm.service.task.BpmProcessInstanceService;
  8 +import org.flowable.engine.delegate.DelegateExecution;
9 import org.flowable.engine.runtime.ProcessInstance; 9 import org.flowable.engine.runtime.ProcessInstance;
10 -import org.flowable.task.service.impl.persistence.entity.TaskEntity;  
11 import org.springframework.context.annotation.Lazy; 10 import org.springframework.context.annotation.Lazy;
12 import org.springframework.stereotype.Component; 11 import org.springframework.stereotype.Component;
13 12
@@ -27,8 +26,8 @@ public class BpmTaskAssignStartUserScript implements BpmTaskAssignScript { @@ -27,8 +26,8 @@ public class BpmTaskAssignStartUserScript implements BpmTaskAssignScript {
27 private BpmProcessInstanceService bpmProcessInstanceService; 26 private BpmProcessInstanceService bpmProcessInstanceService;
28 27
29 @Override 28 @Override
30 - public Set<Long> calculateTaskCandidateUsers(TaskEntity task) {  
31 - ProcessInstance processInstance = bpmProcessInstanceService.getProcessInstance(task.getProcessInstanceId()); 29 + public Set<Long> calculateTaskCandidateUsers(DelegateExecution execution) {
  30 + ProcessInstance processInstance = bpmProcessInstanceService.getProcessInstance(execution.getProcessInstanceId());
32 Long startUserId = NumberUtils.parseLong(processInstance.getStartUserId()); 31 Long startUserId = NumberUtils.parseLong(processInstance.getStartUserId());
33 return SetUtils.asSet(startUserId); 32 return SetUtils.asSet(startUserId);
34 } 33 }
yudao-module-bpm/yudao-module-bpm-biz-flowable/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/listener/BpmProcessInstanceEventListener.java renamed to yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/listener/BpmProcessInstanceEventListener.java
yudao-module-bpm/yudao-module-bpm-biz-flowable/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/listener/BpmTaskEventListener.java renamed to yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/listener/BpmTaskEventListener.java
1 package cn.iocoder.yudao.module.bpm.framework.flowable.core.listener; 1 package cn.iocoder.yudao.module.bpm.framework.flowable.core.listener;
2 2
  3 +import cn.hutool.core.util.StrUtil;
3 import cn.iocoder.yudao.module.bpm.dal.dataobject.task.BpmTaskExtDO; 4 import cn.iocoder.yudao.module.bpm.dal.dataobject.task.BpmTaskExtDO;
  5 +import cn.iocoder.yudao.module.bpm.service.task.BpmActivityService;
4 import cn.iocoder.yudao.module.bpm.service.task.BpmTaskService; 6 import cn.iocoder.yudao.module.bpm.service.task.BpmTaskService;
5 import com.google.common.collect.ImmutableSet; 7 import com.google.common.collect.ImmutableSet;
  8 +import lombok.extern.slf4j.Slf4j;
6 import org.flowable.common.engine.api.delegate.event.FlowableEngineEntityEvent; 9 import org.flowable.common.engine.api.delegate.event.FlowableEngineEntityEvent;
7 import org.flowable.common.engine.api.delegate.event.FlowableEngineEventType; 10 import org.flowable.common.engine.api.delegate.event.FlowableEngineEventType;
8 import org.flowable.engine.delegate.event.AbstractFlowableEngineEventListener; 11 import org.flowable.engine.delegate.event.AbstractFlowableEngineEventListener;
  12 +import org.flowable.engine.delegate.event.FlowableActivityCancelledEvent;
  13 +import org.flowable.engine.history.HistoricActivityInstance;
9 import org.flowable.task.api.Task; 14 import org.flowable.task.api.Task;
10 import org.springframework.context.annotation.Lazy; 15 import org.springframework.context.annotation.Lazy;
11 import org.springframework.stereotype.Component; 16 import org.springframework.stereotype.Component;
@@ -19,16 +24,22 @@ import java.util.Set; @@ -19,16 +24,22 @@ import java.util.Set;
19 * @author jason 24 * @author jason
20 */ 25 */
21 @Component 26 @Component
  27 +@Slf4j
22 public class BpmTaskEventListener extends AbstractFlowableEngineEventListener { 28 public class BpmTaskEventListener extends AbstractFlowableEngineEventListener {
23 29
24 @Resource 30 @Resource
25 @Lazy // 解决循环依赖 31 @Lazy // 解决循环依赖
26 private BpmTaskService taskService; 32 private BpmTaskService taskService;
27 33
  34 + @Resource
  35 + @Lazy // 解决循环依赖
  36 + private BpmActivityService activityService;
  37 +
28 public static final Set<FlowableEngineEventType> TASK_EVENTS = ImmutableSet.<FlowableEngineEventType>builder() 38 public static final Set<FlowableEngineEventType> TASK_EVENTS = ImmutableSet.<FlowableEngineEventType>builder()
29 .add(FlowableEngineEventType.TASK_CREATED) 39 .add(FlowableEngineEventType.TASK_CREATED)
30 .add(FlowableEngineEventType.TASK_ASSIGNED) 40 .add(FlowableEngineEventType.TASK_ASSIGNED)
31 .add(FlowableEngineEventType.TASK_COMPLETED) 41 .add(FlowableEngineEventType.TASK_COMPLETED)
  42 + .add(FlowableEngineEventType.ACTIVITY_CANCELLED)
32 .build(); 43 .build();
33 44
34 public BpmTaskEventListener(){ 45 public BpmTaskEventListener(){
@@ -49,4 +60,18 @@ public class BpmTaskEventListener extends AbstractFlowableEngineEventListener { @@ -49,4 +60,18 @@ public class BpmTaskEventListener extends AbstractFlowableEngineEventListener {
49 protected void taskAssigned(FlowableEngineEntityEvent event) { 60 protected void taskAssigned(FlowableEngineEntityEvent event) {
50 taskService.updateTaskExtAssign((Task)event.getEntity()); 61 taskService.updateTaskExtAssign((Task)event.getEntity());
51 } 62 }
  63 +
  64 + @Override
  65 + protected void activityCancelled(FlowableActivityCancelledEvent event) {
  66 + HistoricActivityInstance activity = activityService.getHistoricActivityByExecutionId(event.getExecutionId());
  67 + if (activity == null) {
  68 + log.error("[activityCancelled][使用 executionId({}) 查找不到对应的活动实例]", event.getExecutionId());
  69 + return;
  70 + }
  71 + if (StrUtil.isEmpty(activity.getTaskId())) {
  72 + return;
  73 + }
  74 + taskService.updateTaskExtCancel(activity.getTaskId());
  75 + }
  76 +
52 } 77 }
yudao-module-bpm/yudao-module-bpm-base/src/main/java/cn/iocoder/yudao/module/bpm/framework/package-info.java renamed to yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/package-info.java
yudao-module-bpm/yudao-module-bpm-biz-activiti/src/main/java/cn/iocoder/yudao/module/bpm/package-info.java renamed to yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/package-info.java
@@ -7,6 +7,6 @@ @@ -7,6 +7,6 @@
7 * 1. Controller URL:以 /bpm/ 开头,避免和其它 Module 冲突 7 * 1. Controller URL:以 /bpm/ 开头,避免和其它 Module 冲突
8 * 2. DataObject 表名:以 bpm_ 开头,方便在数据库中区分 8 * 2. DataObject 表名:以 bpm_ 开头,方便在数据库中区分
9 * 9 *
10 - * 注意,由于 Bpm 模块下,容易和其它模块重名,所以类名都加载 Pay 的前缀~ 10 + * 注意,由于 Bpm 模块下,容易和其它模块重名,所以类名都加载 Bpm 的前缀~
11 */ 11 */
12 package cn.iocoder.yudao.module.bpm; 12 package cn.iocoder.yudao.module.bpm;
yudao-module-bpm/yudao-module-bpm-base/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmFormService.java renamed to yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmFormService.java
yudao-module-bpm/yudao-module-bpm-base/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmFormServiceImpl.java renamed to yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmFormServiceImpl.java
yudao-module-bpm/yudao-module-bpm-biz-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmModelService.java renamed to yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmModelService.java
yudao-module-bpm/yudao-module-bpm-biz-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmModelServiceImpl.java renamed to yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmModelServiceImpl.java
yudao-module-bpm/yudao-module-bpm-biz-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmProcessDefinitionService.java renamed to yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmProcessDefinitionService.java
yudao-module-bpm/yudao-module-bpm-biz-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmProcessDefinitionServiceImpl.java renamed to yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmProcessDefinitionServiceImpl.java
yudao-module-bpm/yudao-module-bpm-biz-activiti/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmTaskAssignRuleService.java renamed to yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmTaskAssignRuleService.java
@@ -4,10 +4,12 @@ import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.rule.BpmTaskAs @@ -4,10 +4,12 @@ import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.rule.BpmTaskAs
4 import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.rule.BpmTaskAssignRuleRespVO; 4 import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.rule.BpmTaskAssignRuleRespVO;
5 import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.rule.BpmTaskAssignRuleUpdateReqVO; 5 import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.rule.BpmTaskAssignRuleUpdateReqVO;
6 import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmTaskAssignRuleDO; 6 import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmTaskAssignRuleDO;
  7 +import org.flowable.engine.delegate.DelegateExecution;
7 import org.springframework.lang.Nullable; 8 import org.springframework.lang.Nullable;
8 9
9 import javax.validation.Valid; 10 import javax.validation.Valid;
10 import java.util.List; 11 import java.util.List;
  12 +import java.util.Set;
11 13
12 /** 14 /**
13 * BPM 任务分配规则 Service 接口 15 * BPM 任务分配规则 Service 接口
@@ -84,4 +86,12 @@ public interface BpmTaskAssignRuleService { @@ -84,4 +86,12 @@ public interface BpmTaskAssignRuleService {
84 */ 86 */
85 void checkTaskAssignRuleAllConfig(String id); 87 void checkTaskAssignRuleAllConfig(String id);
86 88
  89 + /**
  90 + * 计算当前执行任务的处理人
  91 + *
  92 + * @param execution 执行任务
  93 + * @return 处理人的编号数组
  94 + */
  95 + Set<Long> calculateTaskCandidateUsers(DelegateExecution execution);
  96 +
87 } 97 }
yudao-module-bpm/yudao-module-bpm-biz-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmTaskAssignRuleServiceImpl.java renamed to yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmTaskAssignRuleServiceImpl.java
@@ -3,25 +3,35 @@ package cn.iocoder.yudao.module.bpm.service.definition; @@ -3,25 +3,35 @@ package cn.iocoder.yudao.module.bpm.service.definition;
3 import cn.hutool.core.collection.CollUtil; 3 import cn.hutool.core.collection.CollUtil;
4 import cn.hutool.core.util.ObjectUtil; 4 import cn.hutool.core.util.ObjectUtil;
5 import cn.hutool.core.util.StrUtil; 5 import cn.hutool.core.util.StrUtil;
  6 +import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
6 import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; 7 import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
7 import cn.iocoder.yudao.framework.common.util.object.ObjectUtils; 8 import cn.iocoder.yudao.framework.common.util.object.ObjectUtils;
  9 +import cn.iocoder.yudao.framework.datapermission.core.annotation.DataPermission;
8 import cn.iocoder.yudao.framework.flowable.core.util.FlowableUtils; 10 import cn.iocoder.yudao.framework.flowable.core.util.FlowableUtils;
9 import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.rule.BpmTaskAssignRuleCreateReqVO; 11 import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.rule.BpmTaskAssignRuleCreateReqVO;
10 import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.rule.BpmTaskAssignRuleRespVO; 12 import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.rule.BpmTaskAssignRuleRespVO;
11 import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.rule.BpmTaskAssignRuleUpdateReqVO; 13 import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.rule.BpmTaskAssignRuleUpdateReqVO;
12 import cn.iocoder.yudao.module.bpm.convert.definition.BpmTaskAssignRuleConvert; 14 import cn.iocoder.yudao.module.bpm.convert.definition.BpmTaskAssignRuleConvert;
13 import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmTaskAssignRuleDO; 15 import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmTaskAssignRuleDO;
  16 +import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmUserGroupDO;
14 import cn.iocoder.yudao.module.bpm.dal.mysql.definition.BpmTaskAssignRuleMapper; 17 import cn.iocoder.yudao.module.bpm.dal.mysql.definition.BpmTaskAssignRuleMapper;
15 -import cn.iocoder.yudao.module.bpm.enums.DictTypeConstants;  
16 import cn.iocoder.yudao.module.bpm.enums.definition.BpmTaskAssignRuleTypeEnum; 18 import cn.iocoder.yudao.module.bpm.enums.definition.BpmTaskAssignRuleTypeEnum;
  19 +import cn.iocoder.yudao.module.bpm.enums.DictTypeConstants;
  20 +import cn.iocoder.yudao.module.bpm.framework.flowable.core.behavior.script.BpmTaskAssignScript;
17 import cn.iocoder.yudao.module.system.api.dept.DeptApi; 21 import cn.iocoder.yudao.module.system.api.dept.DeptApi;
18 import cn.iocoder.yudao.module.system.api.dept.PostApi; 22 import cn.iocoder.yudao.module.system.api.dept.PostApi;
  23 +import cn.iocoder.yudao.module.system.api.dept.dto.DeptRespDTO;
19 import cn.iocoder.yudao.module.system.api.dict.DictDataApi; 24 import cn.iocoder.yudao.module.system.api.dict.DictDataApi;
  25 +import cn.iocoder.yudao.module.system.api.permission.PermissionApi;
20 import cn.iocoder.yudao.module.system.api.permission.RoleApi; 26 import cn.iocoder.yudao.module.system.api.permission.RoleApi;
21 import cn.iocoder.yudao.module.system.api.user.AdminUserApi; 27 import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
  28 +import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
  29 +import com.google.common.annotations.VisibleForTesting;
22 import lombok.extern.slf4j.Slf4j; 30 import lombok.extern.slf4j.Slf4j;
23 import org.flowable.bpmn.model.BpmnModel; 31 import org.flowable.bpmn.model.BpmnModel;
24 import org.flowable.bpmn.model.UserTask; 32 import org.flowable.bpmn.model.UserTask;
  33 +import org.flowable.common.engine.api.FlowableException;
  34 +import org.flowable.engine.delegate.DelegateExecution;
25 import org.springframework.context.annotation.Lazy; 35 import org.springframework.context.annotation.Lazy;
26 import org.springframework.stereotype.Service; 36 import org.springframework.stereotype.Service;
27 import org.springframework.validation.annotation.Validated; 37 import org.springframework.validation.annotation.Validated;
@@ -30,7 +40,11 @@ import javax.annotation.Resource; @@ -30,7 +40,11 @@ import javax.annotation.Resource;
30 import javax.validation.Valid; 40 import javax.validation.Valid;
31 import java.util.*; 41 import java.util.*;
32 42
  43 +import static cn.hutool.core.text.CharSequenceUtil.format;
33 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; 44 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
  45 +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap;
  46 +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
  47 +import static cn.iocoder.yudao.framework.common.util.json.JsonUtils.toJsonString;
34 import static cn.iocoder.yudao.module.bpm.enums.ErrorCodeConstants.*; 48 import static cn.iocoder.yudao.module.bpm.enums.ErrorCodeConstants.*;
35 49
36 /** 50 /**
@@ -39,7 +53,7 @@ import static cn.iocoder.yudao.module.bpm.enums.ErrorCodeConstants.*; @@ -39,7 +53,7 @@ import static cn.iocoder.yudao.module.bpm.enums.ErrorCodeConstants.*;
39 @Service 53 @Service
40 @Validated 54 @Validated
41 @Slf4j 55 @Slf4j
42 -public class BpmTaskAssignRuleServiceImpl implements BpmTaskAssignRuleService{ 56 +public class BpmTaskAssignRuleServiceImpl implements BpmTaskAssignRuleService {
43 57
44 @Resource 58 @Resource
45 private BpmTaskAssignRuleMapper taskRuleMapper; 59 private BpmTaskAssignRuleMapper taskRuleMapper;
@@ -61,9 +75,21 @@ public class BpmTaskAssignRuleServiceImpl implements BpmTaskAssignRuleService{ @@ -61,9 +75,21 @@ public class BpmTaskAssignRuleServiceImpl implements BpmTaskAssignRuleService{
61 private AdminUserApi adminUserApi; 75 private AdminUserApi adminUserApi;
62 @Resource 76 @Resource
63 private DictDataApi dictDataApi; 77 private DictDataApi dictDataApi;
  78 + @Resource
  79 + private PermissionApi permissionApi;
  80 + /**
  81 + * 任务分配脚本
  82 + */
  83 + private Map<Long, BpmTaskAssignScript> scriptMap = Collections.emptyMap();
  84 +
  85 + @Resource
  86 + public void setScripts(List<BpmTaskAssignScript> scripts) {
  87 + this.scriptMap = convertMap(scripts, script -> script.getEnum().getId());
  88 + }
64 89
65 @Override 90 @Override
66 - public List<BpmTaskAssignRuleDO> getTaskAssignRuleListByProcessDefinitionId(String processDefinitionId, String taskDefinitionKey) { 91 + public List<BpmTaskAssignRuleDO> getTaskAssignRuleListByProcessDefinitionId(String processDefinitionId,
  92 + String taskDefinitionKey) {
67 return taskRuleMapper.selectListByProcessDefinitionId(processDefinitionId, taskDefinitionKey); 93 return taskRuleMapper.selectListByProcessDefinitionId(processDefinitionId, taskDefinitionKey);
68 } 94 }
69 95
@@ -101,15 +127,15 @@ public class BpmTaskAssignRuleServiceImpl implements BpmTaskAssignRuleService{ @@ -101,15 +127,15 @@ public class BpmTaskAssignRuleServiceImpl implements BpmTaskAssignRuleService{
101 // 校验参数 127 // 校验参数
102 validTaskAssignRuleOptions(reqVO.getType(), reqVO.getOptions()); 128 validTaskAssignRuleOptions(reqVO.getType(), reqVO.getOptions());
103 // 校验是否已经配置 129 // 校验是否已经配置
104 - BpmTaskAssignRuleDO existRule = taskRuleMapper.selectListByModelIdAndTaskDefinitionKey(  
105 - reqVO.getModelId(), reqVO.getTaskDefinitionKey()); 130 + BpmTaskAssignRuleDO existRule =
  131 + taskRuleMapper.selectListByModelIdAndTaskDefinitionKey(reqVO.getModelId(), reqVO.getTaskDefinitionKey());
106 if (existRule != null) { 132 if (existRule != null) {
107 throw exception(TASK_ASSIGN_RULE_EXISTS, reqVO.getModelId(), reqVO.getTaskDefinitionKey()); 133 throw exception(TASK_ASSIGN_RULE_EXISTS, reqVO.getModelId(), reqVO.getTaskDefinitionKey());
108 } 134 }
109 135
110 // 存储 136 // 存储
111 BpmTaskAssignRuleDO rule = BpmTaskAssignRuleConvert.INSTANCE.convert(reqVO) 137 BpmTaskAssignRuleDO rule = BpmTaskAssignRuleConvert.INSTANCE.convert(reqVO)
112 - .setProcessDefinitionId(BpmTaskAssignRuleDO.PROCESS_DEFINITION_ID_NULL); // 只有流程模型,才允许新建 138 + .setProcessDefinitionId(BpmTaskAssignRuleDO.PROCESS_DEFINITION_ID_NULL); // 只有流程模型,才允许新建
113 taskRuleMapper.insert(rule); 139 taskRuleMapper.insert(rule);
114 return rule.getId(); 140 return rule.getId();
115 } 141 }
@@ -142,15 +168,15 @@ public class BpmTaskAssignRuleServiceImpl implements BpmTaskAssignRuleService{ @@ -142,15 +168,15 @@ public class BpmTaskAssignRuleServiceImpl implements BpmTaskAssignRuleService{
142 } 168 }
143 169
144 // 遍历,匹配对应的规则 170 // 遍历,匹配对应的规则
145 - Map<String, BpmTaskAssignRuleRespVO> processInstanceRuleMap = CollectionUtils.convertMap(processInstanceRules,  
146 - BpmTaskAssignRuleRespVO::getTaskDefinitionKey); 171 + Map<String, BpmTaskAssignRuleRespVO> processInstanceRuleMap =
  172 + CollectionUtils.convertMap(processInstanceRules, BpmTaskAssignRuleRespVO::getTaskDefinitionKey);
147 for (BpmTaskAssignRuleRespVO modelRule : modelRules) { 173 for (BpmTaskAssignRuleRespVO modelRule : modelRules) {
148 BpmTaskAssignRuleRespVO processInstanceRule = processInstanceRuleMap.get(modelRule.getTaskDefinitionKey()); 174 BpmTaskAssignRuleRespVO processInstanceRule = processInstanceRuleMap.get(modelRule.getTaskDefinitionKey());
149 if (processInstanceRule == null) { 175 if (processInstanceRule == null) {
150 return false; 176 return false;
151 } 177 }
152 - if (!ObjectUtil.equals(modelRule.getType(), processInstanceRule.getType())  
153 - || !ObjectUtil.equal(modelRule.getOptions(), processInstanceRule.getOptions())) { 178 + if (!ObjectUtil.equals(modelRule.getType(), processInstanceRule.getType()) || !ObjectUtil.equal(
  179 + modelRule.getOptions(), processInstanceRule.getOptions())) {
154 return false; 180 return false;
155 } 181 }
156 } 182 }
@@ -165,8 +191,8 @@ public class BpmTaskAssignRuleServiceImpl implements BpmTaskAssignRuleService{ @@ -165,8 +191,8 @@ public class BpmTaskAssignRuleServiceImpl implements BpmTaskAssignRuleService{
165 } 191 }
166 // 开始复制 192 // 开始复制
167 List<BpmTaskAssignRuleDO> newRules = BpmTaskAssignRuleConvert.INSTANCE.convertList2(rules); 193 List<BpmTaskAssignRuleDO> newRules = BpmTaskAssignRuleConvert.INSTANCE.convertList2(rules);
168 - newRules.forEach(rule -> rule.setProcessDefinitionId(toProcessDefinitionId).setId(null)  
169 - .setCreateTime(null).setUpdateTime(null)); 194 + newRules.forEach(rule -> rule.setProcessDefinitionId(toProcessDefinitionId).setId(null).setCreateTime(null)
  195 + .setUpdateTime(null));
170 taskRuleMapper.insertBatch(newRules); 196 taskRuleMapper.insertBatch(newRules);
171 } 197 }
172 198
@@ -189,7 +215,7 @@ public class BpmTaskAssignRuleServiceImpl implements BpmTaskAssignRuleService{ @@ -189,7 +215,7 @@ public class BpmTaskAssignRuleServiceImpl implements BpmTaskAssignRuleService{
189 if (Objects.equals(type, BpmTaskAssignRuleTypeEnum.ROLE.getType())) { 215 if (Objects.equals(type, BpmTaskAssignRuleTypeEnum.ROLE.getType())) {
190 roleApi.validRoles(options); 216 roleApi.validRoles(options);
191 } else if (ObjectUtils.equalsAny(type, BpmTaskAssignRuleTypeEnum.DEPT_MEMBER.getType(), 217 } else if (ObjectUtils.equalsAny(type, BpmTaskAssignRuleTypeEnum.DEPT_MEMBER.getType(),
192 - BpmTaskAssignRuleTypeEnum.DEPT_LEADER.getType())) { 218 + BpmTaskAssignRuleTypeEnum.DEPT_LEADER.getType())) {
193 deptApi.validDepts(options); 219 deptApi.validDepts(options);
194 } else if (Objects.equals(type, BpmTaskAssignRuleTypeEnum.POST.getType())) { 220 } else if (Objects.equals(type, BpmTaskAssignRuleTypeEnum.POST.getType())) {
195 postApi.validPosts(options); 221 postApi.validPosts(options);
@@ -199,9 +225,120 @@ public class BpmTaskAssignRuleServiceImpl implements BpmTaskAssignRuleService{ @@ -199,9 +225,120 @@ public class BpmTaskAssignRuleServiceImpl implements BpmTaskAssignRuleService{
199 userGroupService.validUserGroups(options); 225 userGroupService.validUserGroups(options);
200 } else if (Objects.equals(type, BpmTaskAssignRuleTypeEnum.SCRIPT.getType())) { 226 } else if (Objects.equals(type, BpmTaskAssignRuleTypeEnum.SCRIPT.getType())) {
201 dictDataApi.validDictDatas(DictTypeConstants.TASK_ASSIGN_SCRIPT, 227 dictDataApi.validDictDatas(DictTypeConstants.TASK_ASSIGN_SCRIPT,
202 - CollectionUtils.convertSet(options, String::valueOf)); 228 + CollectionUtils.convertSet(options, String::valueOf));
203 } else { 229 } else {
204 - throw new IllegalArgumentException(StrUtil.format("未知的规则类型({})", type)); 230 + throw new IllegalArgumentException(format("未知的规则类型({})", type));
  231 + }
  232 + }
  233 +
  234 + @Override
  235 + @DataPermission(enable = false) // 忽略数据权限,不然分配会存在问题
  236 + public Set<Long> calculateTaskCandidateUsers(DelegateExecution execution) {
  237 + BpmTaskAssignRuleDO rule = getTaskRule(execution);
  238 + return calculateTaskCandidateUsers(execution, rule);
  239 + }
  240 +
  241 + @VisibleForTesting
  242 + BpmTaskAssignRuleDO getTaskRule(DelegateExecution execution) {
  243 + List<BpmTaskAssignRuleDO> taskRules = getTaskAssignRuleListByProcessDefinitionId(
  244 + execution.getProcessDefinitionId(), execution.getCurrentActivityId());
  245 + if (CollUtil.isEmpty(taskRules)) {
  246 + throw new FlowableException(format("流程任务({}/{}/{}) 找不到符合的任务规则",
  247 + execution.getId(), execution.getProcessDefinitionId(), execution.getCurrentActivityId()));
  248 + }
  249 + if (taskRules.size() > 1) {
  250 + throw new FlowableException(format("流程任务({}/{}/{}) 找到过多任务规则({})",
  251 + execution.getId(), execution.getProcessDefinitionId(), execution.getCurrentActivityId()));
  252 + }
  253 + return taskRules.get(0);
  254 + }
  255 +
  256 + @VisibleForTesting
  257 + Set<Long> calculateTaskCandidateUsers(DelegateExecution execution, BpmTaskAssignRuleDO rule) {
  258 + Set<Long> assigneeUserIds = null;
  259 + if (Objects.equals(BpmTaskAssignRuleTypeEnum.ROLE.getType(), rule.getType())) {
  260 + assigneeUserIds = calculateTaskCandidateUsersByRole(rule);
  261 + } else if (Objects.equals(BpmTaskAssignRuleTypeEnum.DEPT_MEMBER.getType(), rule.getType())) {
  262 + assigneeUserIds = calculateTaskCandidateUsersByDeptMember(rule);
  263 + } else if (Objects.equals(BpmTaskAssignRuleTypeEnum.DEPT_LEADER.getType(), rule.getType())) {
  264 + assigneeUserIds = calculateTaskCandidateUsersByDeptLeader(rule);
  265 + } else if (Objects.equals(BpmTaskAssignRuleTypeEnum.POST.getType(), rule.getType())) {
  266 + assigneeUserIds = calculateTaskCandidateUsersByPost(rule);
  267 + } else if (Objects.equals(BpmTaskAssignRuleTypeEnum.USER.getType(), rule.getType())) {
  268 + assigneeUserIds = calculateTaskCandidateUsersByUser(rule);
  269 + } else if (Objects.equals(BpmTaskAssignRuleTypeEnum.USER_GROUP.getType(), rule.getType())) {
  270 + assigneeUserIds = calculateTaskCandidateUsersByUserGroup(rule);
  271 + } else if (Objects.equals(BpmTaskAssignRuleTypeEnum.SCRIPT.getType(), rule.getType())) {
  272 + assigneeUserIds = calculateTaskCandidateUsersByScript(execution, rule);
  273 + }
  274 +
  275 + // 移除被禁用的用户
  276 + removeDisableUsers(assigneeUserIds);
  277 + // 如果候选人为空,抛出异常
  278 + if (CollUtil.isEmpty(assigneeUserIds)) {
  279 + log.error("[calculateTaskCandidateUsers][流程任务({}/{}/{}) 任务规则({}) 找不到候选人]", execution.getId(),
  280 + execution.getProcessDefinitionId(), execution.getCurrentActivityId(), toJsonString(rule));
  281 + throw exception(TASK_CREATE_FAIL_NO_CANDIDATE_USER);
  282 + }
  283 + return assigneeUserIds;
  284 + }
  285 +
  286 + private Set<Long> calculateTaskCandidateUsersByRole(BpmTaskAssignRuleDO rule) {
  287 + return permissionApi.getUserRoleIdListByRoleIds(rule.getOptions());
  288 + }
  289 +
  290 + private Set<Long> calculateTaskCandidateUsersByDeptMember(BpmTaskAssignRuleDO rule) {
  291 + List<AdminUserRespDTO> users = adminUserApi.getUsersByDeptIds(rule.getOptions());
  292 + return convertSet(users, AdminUserRespDTO::getId);
  293 + }
  294 +
  295 + private Set<Long> calculateTaskCandidateUsersByDeptLeader(BpmTaskAssignRuleDO rule) {
  296 + List<DeptRespDTO> depts = deptApi.getDepts(rule.getOptions());
  297 + return convertSet(depts, DeptRespDTO::getLeaderUserId);
  298 + }
  299 +
  300 + private Set<Long> calculateTaskCandidateUsersByPost(BpmTaskAssignRuleDO rule) {
  301 + List<AdminUserRespDTO> users = adminUserApi.getUsersByPostIds(rule.getOptions());
  302 + return convertSet(users, AdminUserRespDTO::getId);
  303 + }
  304 +
  305 + private Set<Long> calculateTaskCandidateUsersByUser(BpmTaskAssignRuleDO rule) {
  306 + return rule.getOptions();
  307 + }
  308 +
  309 + private Set<Long> calculateTaskCandidateUsersByUserGroup(BpmTaskAssignRuleDO rule) {
  310 + List<BpmUserGroupDO> userGroups = userGroupService.getUserGroupList(rule.getOptions());
  311 + Set<Long> userIds = new HashSet<>();
  312 + userGroups.forEach(group -> userIds.addAll(group.getMemberUserIds()));
  313 + return userIds;
  314 + }
  315 +
  316 + private Set<Long> calculateTaskCandidateUsersByScript(DelegateExecution execution, BpmTaskAssignRuleDO rule) {
  317 + // 获得对应的脚本
  318 + List<BpmTaskAssignScript> scripts = new ArrayList<>(rule.getOptions().size());
  319 + rule.getOptions().forEach(id -> {
  320 + BpmTaskAssignScript script = scriptMap.get(id);
  321 + if (script == null) {
  322 + throw exception(TASK_ASSIGN_SCRIPT_NOT_EXISTS, id);
  323 + }
  324 + scripts.add(script);
  325 + });
  326 + // 逐个计算任务
  327 + Set<Long> userIds = new HashSet<>();
  328 + scripts.forEach(script -> CollUtil.addAll(userIds, script.calculateTaskCandidateUsers(execution)));
  329 + return userIds;
  330 + }
  331 +
  332 + @VisibleForTesting
  333 + void removeDisableUsers(Set<Long> assigneeUserIds) {
  334 + if (CollUtil.isEmpty(assigneeUserIds)) {
  335 + return;
205 } 336 }
  337 + Map<Long, AdminUserRespDTO> userMap = adminUserApi.getUserMap(assigneeUserIds);
  338 + assigneeUserIds.removeIf(id -> {
  339 + AdminUserRespDTO user = userMap.get(id);
  340 + return user == null || !CommonStatusEnum.ENABLE.getStatus().equals(user.getStatus());
  341 + });
206 } 342 }
  343 +
207 } 344 }
yudao-module-bpm/yudao-module-bpm-base/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmUserGroupService.java renamed to yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmUserGroupService.java
yudao-module-bpm/yudao-module-bpm-base/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmUserGroupServiceImpl.java renamed to yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmUserGroupServiceImpl.java
yudao-module-bpm/yudao-module-bpm-base/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/dto/BpmFormFieldRespDTO.java renamed to yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/dto/BpmFormFieldRespDTO.java
yudao-module-bpm/yudao-module-bpm-base/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/dto/BpmModelMetaInfoRespDTO.java renamed to yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/dto/BpmModelMetaInfoRespDTO.java
yudao-module-bpm/yudao-module-bpm-base/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/dto/BpmProcessDefinitionCreateReqDTO.java renamed to yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/dto/BpmProcessDefinitionCreateReqDTO.java
yudao-module-bpm/yudao-module-bpm-base/src/main/java/cn/iocoder/yudao/module/bpm/service/message/BpmMessageService.java renamed to yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/message/BpmMessageService.java
yudao-module-bpm/yudao-module-bpm-base/src/main/java/cn/iocoder/yudao/module/bpm/service/message/BpmMessageServiceImpl.java renamed to yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/message/BpmMessageServiceImpl.java
yudao-module-bpm/yudao-module-bpm-base/src/main/java/cn/iocoder/yudao/module/bpm/service/message/dto/BpmMessageSendWhenProcessInstanceApproveReqDTO.java renamed to yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/message/dto/BpmMessageSendWhenProcessInstanceApproveReqDTO.java
yudao-module-bpm/yudao-module-bpm-base/src/main/java/cn/iocoder/yudao/module/bpm/service/message/dto/BpmMessageSendWhenProcessInstanceRejectReqDTO.java renamed to yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/message/dto/BpmMessageSendWhenProcessInstanceRejectReqDTO.java
yudao-module-bpm/yudao-module-bpm-base/src/main/java/cn/iocoder/yudao/module/bpm/service/message/dto/BpmMessageSendWhenTaskCreatedReqDTO.java renamed to yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/message/dto/BpmMessageSendWhenTaskCreatedReqDTO.java
yudao-module-bpm/yudao-module-bpm-base/src/main/java/cn/iocoder/yudao/module/bpm/service/oa/BpmOALeaveService.java renamed to yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/oa/BpmOALeaveService.java
yudao-module-bpm/yudao-module-bpm-base/src/main/java/cn/iocoder/yudao/module/bpm/service/oa/BpmOALeaveServiceImpl.java renamed to yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/oa/BpmOALeaveServiceImpl.java
yudao-module-bpm/yudao-module-bpm-base/src/main/java/cn/iocoder/yudao/module/bpm/service/oa/listener/BpmOALeaveResultListener.java renamed to yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/oa/listener/BpmOALeaveResultListener.java
yudao-module-bpm/yudao-module-bpm-biz-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmActivityService.java renamed to yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmActivityService.java
1 package cn.iocoder.yudao.module.bpm.service.task; 1 package cn.iocoder.yudao.module.bpm.service.task;
2 2
3 import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.activity.BpmActivityRespVO; 3 import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.activity.BpmActivityRespVO;
  4 +import org.flowable.engine.history.HistoricActivityInstance;
4 5
5 import java.util.List; 6 import java.util.List;
6 7
@@ -19,4 +20,12 @@ public interface BpmActivityService { @@ -19,4 +20,12 @@ public interface BpmActivityService {
19 */ 20 */
20 List<BpmActivityRespVO> getActivityListByProcessInstanceId(String processInstanceId); 21 List<BpmActivityRespVO> getActivityListByProcessInstanceId(String processInstanceId);
21 22
  23 + /**
  24 + * 获得执行编号对应的活动实例
  25 + *
  26 + * @param executionId 执行编号
  27 + * @return 活动实例
  28 + */
  29 + HistoricActivityInstance getHistoricActivityByExecutionId(String executionId);
  30 +
22 } 31 }
yudao-module-bpm/yudao-module-bpm-biz-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmActivityServiceImpl.java renamed to yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmActivityServiceImpl.java
1 package cn.iocoder.yudao.module.bpm.service.task; 1 package cn.iocoder.yudao.module.bpm.service.task;
2 2
3 -import cn.hutool.core.io.IoUtil;  
4 -import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;  
5 import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.activity.BpmActivityRespVO; 3 import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.activity.BpmActivityRespVO;
6 import cn.iocoder.yudao.module.bpm.convert.task.BpmActivityConvert; 4 import cn.iocoder.yudao.module.bpm.convert.task.BpmActivityConvert;
7 -import cn.iocoder.yudao.module.bpm.service.definition.BpmProcessDefinitionService; 5 +import cn.iocoder.yudao.module.bpm.dal.mysql.task.BpmActivityMapper;
8 import lombok.extern.slf4j.Slf4j; 6 import lombok.extern.slf4j.Slf4j;
9 -  
10 -import org.flowable.bpmn.model.BpmnModel;  
11 import org.flowable.engine.HistoryService; 7 import org.flowable.engine.HistoryService;
12 import org.flowable.engine.history.HistoricActivityInstance; 8 import org.flowable.engine.history.HistoricActivityInstance;
13 -import org.flowable.engine.history.HistoricProcessInstance;  
14 -import org.flowable.image.ProcessDiagramGenerator;  
15 import org.springframework.stereotype.Service; 9 import org.springframework.stereotype.Service;
16 import org.springframework.validation.annotation.Validated; 10 import org.springframework.validation.annotation.Validated;
17 11
18 import javax.annotation.Resource; 12 import javax.annotation.Resource;
19 -import java.io.InputStream;  
20 -import java.util.Collections;  
21 import java.util.List; 13 import java.util.List;
22 14
23 -import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;  
24 -import static cn.iocoder.yudao.module.bpm.enums.ErrorCodeConstants.PROCESS_DEFINITION_BPMN_MODEL_NOT_EXISTS;  
25 -import static cn.iocoder.yudao.module.bpm.enums.ErrorCodeConstants.PROCESS_INSTANCE_NOT_EXISTS;  
26 15
27 /** 16 /**
28 * BPM 活动实例 Service 实现类 17 * BPM 活动实例 Service 实现类
@@ -36,6 +25,8 @@ public class BpmActivityServiceImpl implements BpmActivityService { @@ -36,6 +25,8 @@ public class BpmActivityServiceImpl implements BpmActivityService {
36 25
37 @Resource 26 @Resource
38 private HistoryService historyService; 27 private HistoryService historyService;
  28 + @Resource
  29 + private BpmActivityMapper bpmActivityMapper;
39 30
40 @Override 31 @Override
41 public List<BpmActivityRespVO> getActivityListByProcessInstanceId(String processInstanceId) { 32 public List<BpmActivityRespVO> getActivityListByProcessInstanceId(String processInstanceId) {
@@ -44,6 +35,9 @@ public class BpmActivityServiceImpl implements BpmActivityService { @@ -44,6 +35,9 @@ public class BpmActivityServiceImpl implements BpmActivityService {
44 return BpmActivityConvert.INSTANCE.convertList(activityList); 35 return BpmActivityConvert.INSTANCE.convertList(activityList);
45 } 36 }
46 37
47 - 38 + @Override
  39 + public HistoricActivityInstance getHistoricActivityByExecutionId(String executionId) {
  40 + return historyService.createHistoricActivityInstanceQuery().executionId(executionId).singleResult();
  41 + }
48 42
49 } 43 }
yudao-module-bpm/yudao-module-bpm-biz-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmProcessInstanceService.java renamed to yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmProcessInstanceService.java
@@ -4,7 +4,6 @@ import cn.iocoder.yudao.framework.common.pojo.PageResult; @@ -4,7 +4,6 @@ import cn.iocoder.yudao.framework.common.pojo.PageResult;
4 import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; 4 import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
5 import cn.iocoder.yudao.module.bpm.api.task.dto.BpmProcessInstanceCreateReqDTO; 5 import cn.iocoder.yudao.module.bpm.api.task.dto.BpmProcessInstanceCreateReqDTO;
6 import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance.*; 6 import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance.*;
7 -import org.flowable.common.engine.api.delegate.event.FlowableEngineEntityEvent;  
8 import org.flowable.engine.delegate.event.FlowableCancelledEvent; 7 import org.flowable.engine.delegate.event.FlowableCancelledEvent;
9 import org.flowable.engine.history.HistoricProcessInstance; 8 import org.flowable.engine.history.HistoricProcessInstance;
10 import org.flowable.engine.runtime.ProcessInstance; 9 import org.flowable.engine.runtime.ProcessInstance;
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmProcessInstanceServiceImpl.java 0 → 100644
  1 +package cn.iocoder.yudao.module.bpm.service.task; import cn.hutool.core.collection.CollUtil; import cn.hutool.core.lang.Assert; import cn.hutool.core.util.StrUtil; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.common.util.number.NumberUtils; import cn.iocoder.yudao.module.bpm.api.task.dto.BpmProcessInstanceCreateReqDTO; import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance.*; import cn.iocoder.yudao.module.bpm.convert.task.BpmProcessInstanceConvert; import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmProcessDefinitionExtDO; import cn.iocoder.yudao.module.bpm.dal.dataobject.task.BpmProcessInstanceExtDO; import cn.iocoder.yudao.module.bpm.dal.mysql.task.BpmProcessInstanceExtMapper; import cn.iocoder.yudao.module.bpm.enums.task.BpmProcessInstanceDeleteReasonEnum; import cn.iocoder.yudao.module.bpm.enums.task.BpmProcessInstanceResultEnum; import cn.iocoder.yudao.module.bpm.enums.task.BpmProcessInstanceStatusEnum; import cn.iocoder.yudao.module.bpm.framework.bpm.core.event.BpmProcessInstanceResultEventPublisher; import cn.iocoder.yudao.module.bpm.service.definition.BpmProcessDefinitionService; import cn.iocoder.yudao.module.bpm.service.message.BpmMessageService; import cn.iocoder.yudao.module.system.api.dept.DeptApi; import cn.iocoder.yudao.module.system.api.dept.dto.DeptRespDTO; import cn.iocoder.yudao.module.system.api.user.AdminUserApi; import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO; import lombok.extern.slf4j.Slf4j; import org.flowable.engine.HistoryService; import org.flowable.engine.RuntimeService; import org.flowable.engine.delegate.event.FlowableCancelledEvent; import org.flowable.engine.history.HistoricProcessInstance; import org.flowable.engine.repository.ProcessDefinition; import org.flowable.engine.runtime.ProcessInstance; import org.flowable.task.api.Task; import org.springframework.context.annotation.Lazy; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import org.springframework.validation.annotation.Validated; import javax.annotation.Resource; import javax.validation.Valid; import java.util.*; import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList; import static cn.iocoder.yudao.module.bpm.enums.ErrorCodeConstants.*; /** * 流程实例 Service 实现类 * * ProcessDefinition & ProcessInstance & Execution & Task 的关系: * 1. <a href="https://blog.csdn.net/bobozai86/article/details/105210414" /> * * HistoricProcessInstance & ProcessInstance 的关系: * 1. <a href=" https://my.oschina.net/843294669/blog/71902" /> * * 简单来说,前者 = 历史 + 运行中的流程实例,后者仅是运行中的流程实例 * * @author 芋道源码 */ @Service @Validated @Slf4j public class BpmProcessInstanceServiceImpl implements BpmProcessInstanceService { @Resource private RuntimeService runtimeService; @Resource private BpmProcessInstanceExtMapper processInstanceExtMapper; @Resource @Lazy // 解决循环依赖 private BpmTaskService taskService; @Resource private BpmProcessDefinitionService processDefinitionService; @Resource private HistoryService historyService; @Resource private AdminUserApi adminUserApi; @Resource private DeptApi deptApi; @Resource private BpmProcessInstanceResultEventPublisher processInstanceResultEventPublisher; @Resource private BpmMessageService messageService; @Override public ProcessInstance getProcessInstance(String id) { return runtimeService.createProcessInstanceQuery().processInstanceId(id).singleResult(); } @Override public List<ProcessInstance> getProcessInstances(Set<String> ids) { return runtimeService.createProcessInstanceQuery().processInstanceIds(ids).list(); } @Override public PageResult<BpmProcessInstancePageItemRespVO> getMyProcessInstancePage(Long userId, BpmProcessInstanceMyPageReqVO pageReqVO) { // 通过 BpmProcessInstanceExtDO 表,先查询到对应的分页 PageResult<BpmProcessInstanceExtDO> pageResult = processInstanceExtMapper.selectPage(userId, pageReqVO); if (CollUtil.isEmpty(pageResult.getList())) { return new PageResult<>(pageResult.getTotal()); } // 获得流程 Task Map List<String> processInstanceIds = convertList(pageResult.getList(), BpmProcessInstanceExtDO::getProcessInstanceId); Map<String, List<Task>> taskMap = taskService.getTaskMapByProcessInstanceIds(processInstanceIds); // 转换返回 return BpmProcessInstanceConvert.INSTANCE.convertPage(pageResult, taskMap); } @Override @Transactional(rollbackFor = Exception.class) public String createProcessInstance(Long userId, @Valid BpmProcessInstanceCreateReqVO createReqVO) { // 获得流程定义 ProcessDefinition definition = processDefinitionService.getProcessDefinition(createReqVO.getProcessDefinitionId()); // 发起流程 return createProcessInstance0(userId, definition, createReqVO.getVariables(), null); } @Override public String createProcessInstance(Long userId, @Valid BpmProcessInstanceCreateReqDTO createReqDTO) { // 获得流程定义 ProcessDefinition definition = processDefinitionService.getActiveProcessDefinition(createReqDTO.getProcessDefinitionKey()); // 发起流程 return createProcessInstance0(userId, definition, createReqDTO.getVariables(), createReqDTO.getBusinessKey()); } @Override public BpmProcessInstanceRespVO getProcessInstanceVO(String id) { // 获得流程实例 HistoricProcessInstance processInstance = getHistoricProcessInstance(id); if (processInstance == null) { return null; } BpmProcessInstanceExtDO processInstanceExt = processInstanceExtMapper.selectByProcessInstanceId(id); Assert.notNull(processInstanceExt, "流程实例拓展({}) 不存在", id); // 获得流程定义 ProcessDefinition processDefinition = processDefinitionService .getProcessDefinition(processInstance.getProcessDefinitionId()); Assert.notNull(processDefinition, "流程定义({}) 不存在", processInstance.getProcessDefinitionId()); BpmProcessDefinitionExtDO processDefinitionExt = processDefinitionService.getProcessDefinitionExt( processInstance.getProcessDefinitionId()); Assert.notNull(processDefinitionExt, "流程定义拓展({}) 不存在", id); String bpmnXml = processDefinitionService.getProcessDefinitionBpmnXML(processInstance.getProcessDefinitionId()); // 获得 User AdminUserRespDTO startUser = adminUserApi.getUser(NumberUtils.parseLong(processInstance.getStartUserId())); DeptRespDTO dept = null; if (startUser != null) { dept = deptApi.getDept(startUser.getDeptId()); } // 拼接结果 return BpmProcessInstanceConvert.INSTANCE.convert2(processInstance, processInstanceExt, processDefinition, processDefinitionExt, bpmnXml, startUser, dept); } @Override public void cancelProcessInstance(Long userId, @Valid BpmProcessInstanceCancelReqVO cancelReqVO) { // 校验流程实例存在 ProcessInstance instance = getProcessInstance(cancelReqVO.getId()); if (instance == null) { throw exception(PROCESS_INSTANCE_CANCEL_FAIL_NOT_EXISTS); } // 只能取消自己的 if (!Objects.equals(instance.getStartUserId(), String.valueOf(userId))) { throw exception(PROCESS_INSTANCE_CANCEL_FAIL_NOT_SELF); } // 通过删除流程实例,实现流程实例的取消, // 删除流程实例,正则执行任务 ACT_RU_TASK. 任务会被删除。通过历史表查询 deleteProcessInstance(cancelReqVO.getId(), BpmProcessInstanceDeleteReasonEnum.CANCEL_TASK.format(cancelReqVO.getReason())); } /** * 获得历史的流程实例 * * @param id 流程实例的编号 * @return 历史的流程实例 */ @Override public HistoricProcessInstance getHistoricProcessInstance(String id) { return historyService.createHistoricProcessInstanceQuery().processInstanceId(id).singleResult(); } @Override public List<HistoricProcessInstance> getHistoricProcessInstances(Set<String> ids) { return historyService.createHistoricProcessInstanceQuery().processInstanceIds(ids).list(); } @Override public void createProcessInstanceExt(ProcessInstance instance) { // 获得流程定义 ProcessDefinition definition = processDefinitionService.getProcessDefinition2(instance.getProcessDefinitionId()); // 插入 BpmProcessInstanceExtDO 对象 BpmProcessInstanceExtDO instanceExtDO = new BpmProcessInstanceExtDO() .setProcessInstanceId(instance.getId()) .setProcessDefinitionId(definition.getId()) .setName(instance.getProcessDefinitionName()) .setStartUserId(Long.valueOf(instance.getStartUserId())) .setCategory(definition.getCategory()) .setStatus(BpmProcessInstanceStatusEnum.RUNNING.getStatus()) .setResult(BpmProcessInstanceResultEnum.PROCESS.getResult()); processInstanceExtMapper.insert(instanceExtDO); } @Override public void updateProcessInstanceExtCancel(FlowableCancelledEvent event) { // 判断是否为 Reject 不通过。如果是,则不进行更新. // 因为,updateProcessInstanceExtReject 方法,已经进行更新了 if (BpmProcessInstanceDeleteReasonEnum.isRejectReason((String)event.getCause())) { return; } // 需要主动查询,因为 instance 只有 id 属性 // 另外,此时如果去查询 ProcessInstance 的话,字段是不全的,所以去查询了 HistoricProcessInstance HistoricProcessInstance processInstance = getHistoricProcessInstance(event.getProcessInstanceId()); // 更新拓展表 BpmProcessInstanceExtDO instanceExtDO = new BpmProcessInstanceExtDO() .setProcessInstanceId(event.getProcessInstanceId()) .setEndTime(new Date()) // 由于 ProcessInstance 里没有办法拿到 endTime,所以这里设置 .setStatus(BpmProcessInstanceStatusEnum.FINISH.getStatus()) .setResult(BpmProcessInstanceResultEnum.CANCEL.getResult()); processInstanceExtMapper.updateByProcessInstanceId(instanceExtDO); // 发送流程实例的状态事件 processInstanceResultEventPublisher.sendProcessInstanceResultEvent( BpmProcessInstanceConvert.INSTANCE.convert(this, processInstance, instanceExtDO.getResult())); } @Override public void updateProcessInstanceExtComplete(ProcessInstance instance) { // 需要主动查询,因为 instance 只有 id 属性 // 另外,此时如果去查询 ProcessInstance 的话,字段是不全的,所以去查询了 HistoricProcessInstance HistoricProcessInstance processInstance = getHistoricProcessInstance(instance.getId()); // 更新拓展表 BpmProcessInstanceExtDO instanceExtDO = new BpmProcessInstanceExtDO() .setProcessInstanceId(instance.getProcessInstanceId()) .setEndTime(new Date()) // 由于 ProcessInstance 里没有办法拿到 endTime,所以这里设置 .setStatus(BpmProcessInstanceStatusEnum.FINISH.getStatus()) .setResult(BpmProcessInstanceResultEnum.APPROVE.getResult()); // 如果正常完全,说明审批通过 processInstanceExtMapper.updateByProcessInstanceId(instanceExtDO); // 发送流程被通过的消息 messageService.sendMessageWhenProcessInstanceApprove(BpmProcessInstanceConvert.INSTANCE.convert2ApprovedReq(instance)); // 发送流程实例的状态事件 processInstanceResultEventPublisher.sendProcessInstanceResultEvent( BpmProcessInstanceConvert.INSTANCE.convert(this, processInstance, instanceExtDO.getResult())); } @Transactional(rollbackFor = Exception.class) public void updateProcessInstanceExtReject(String id, String reason) { // 需要主动查询,因为 instance 只有 id 属性 ProcessInstance processInstance = getProcessInstance(id); // 删除流程实例,以实现驳回任务时,取消整个审批流程 deleteProcessInstance(id, StrUtil.format(BpmProcessInstanceDeleteReasonEnum.REJECT_TASK.format(reason))); // 更新 status + result // 注意,不能和上面的逻辑更换位置。因为 deleteProcessInstance 会触发流程的取消,进而调用 updateProcessInstanceExtCancel 方法, // 设置 result 为 BpmProcessInstanceStatusEnum.CANCEL,显然和 result 不一定是一致的 BpmProcessInstanceExtDO instanceExtDO = new BpmProcessInstanceExtDO().setProcessInstanceId(id) .setStatus(BpmProcessInstanceStatusEnum.FINISH.getStatus()) .setResult(BpmProcessInstanceResultEnum.REJECT.getResult()); processInstanceExtMapper.updateByProcessInstanceId(instanceExtDO); // 发送流程被不通过的消息 messageService.sendMessageWhenProcessInstanceReject(BpmProcessInstanceConvert.INSTANCE.convert2RejectReq(processInstance, reason)); // 发送流程实例的状态事件 processInstanceResultEventPublisher.sendProcessInstanceResultEvent( BpmProcessInstanceConvert.INSTANCE.convert(this, processInstance, instanceExtDO.getResult())); } private void deleteProcessInstance(String id, String reason) { runtimeService.deleteProcessInstance(id, reason); } private String createProcessInstance0(Long userId, ProcessDefinition definition, Map<String, Object> variables, String businessKey) { // 校验流程定义 if (definition == null) { throw exception(PROCESS_DEFINITION_NOT_EXISTS); } if (definition.isSuspended()) { throw exception(PROCESS_DEFINITION_IS_SUSPENDED); } // 创建流程实例 ProcessInstance instance = runtimeService.startProcessInstanceById(definition.getId(), businessKey, variables); // 设置流程名字 runtimeService.setProcessInstanceName(instance.getId(), definition.getName()); // 补全流程实例的拓展表 processInstanceExtMapper.updateByProcessInstanceId(new BpmProcessInstanceExtDO().setProcessInstanceId(instance.getId()) .setFormVariables(variables)); return instance.getId(); } }
0 \ No newline at end of file 2 \ No newline at end of file
yudao-module-bpm/yudao-module-bpm-biz-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmTaskService.java renamed to yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmTaskService.java
1 package cn.iocoder.yudao.module.bpm.service.task; 1 package cn.iocoder.yudao.module.bpm.service.task;
2 2
  3 +import cn.iocoder.yudao.framework.common.pojo.CommonResult;
3 import cn.iocoder.yudao.framework.common.pojo.PageResult; 4 import cn.iocoder.yudao.framework.common.pojo.PageResult;
4 import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; 5 import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
5 import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.task.*; 6 import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.task.*;
6 import org.flowable.task.api.Task; 7 import org.flowable.task.api.Task;
7 8
8 -  
9 import javax.validation.Valid; 9 import javax.validation.Valid;
10 import java.util.List; 10 import java.util.List;
11 import java.util.Map; 11 import java.util.Map;
@@ -17,19 +17,23 @@ import java.util.Map; @@ -17,19 +17,23 @@ import java.util.Map;
17 * @author 芋道源码 17 * @author 芋道源码
18 */ 18 */
19 public interface BpmTaskService { 19 public interface BpmTaskService {
  20 +
20 /** 21 /**
21 * 获得待办的流程任务分页 22 * 获得待办的流程任务分页
22 * 23 *
23 - * @param userId 用户编号 24 + * @param userId 用户编号
24 * @param pageReqVO 分页请求 25 * @param pageReqVO 分页请求
  26 + *
25 * @return 流程任务分页 27 * @return 流程任务分页
26 */ 28 */
27 PageResult<BpmTaskTodoPageItemRespVO> getTodoTaskPage(Long userId, BpmTaskTodoPageReqVO pageReqVO); 29 PageResult<BpmTaskTodoPageItemRespVO> getTodoTaskPage(Long userId, BpmTaskTodoPageReqVO pageReqVO);
  30 +
28 /** 31 /**
29 * 获得已办的流程任务分页 32 * 获得已办的流程任务分页
30 * 33 *
31 - * @param userId 用户编号 34 + * @param userId 用户编号
32 * @param pageReqVO 分页请求 35 * @param pageReqVO 分页请求
  36 + *
33 * @return 流程任务分页 37 * @return 流程任务分页
34 */ 38 */
35 PageResult<BpmTaskDonePageItemRespVO> getDoneTaskPage(Long userId, BpmTaskDonePageReqVO pageReqVO); 39 PageResult<BpmTaskDonePageItemRespVO> getDoneTaskPage(Long userId, BpmTaskDonePageReqVO pageReqVO);
@@ -38,17 +42,19 @@ public interface BpmTaskService { @@ -38,17 +42,19 @@ public interface BpmTaskService {
38 * 获得流程任务 Map 42 * 获得流程任务 Map
39 * 43 *
40 * @param processInstanceIds 流程实例的编号数组 44 * @param processInstanceIds 流程实例的编号数组
  45 + *
41 * @return 流程任务 Map 46 * @return 流程任务 Map
42 */ 47 */
43 default Map<String, List<Task>> getTaskMapByProcessInstanceIds(List<String> processInstanceIds) { 48 default Map<String, List<Task>> getTaskMapByProcessInstanceIds(List<String> processInstanceIds) {
44 return CollectionUtils.convertMultiMap(getTasksByProcessInstanceIds(processInstanceIds), 49 return CollectionUtils.convertMultiMap(getTasksByProcessInstanceIds(processInstanceIds),
45 - Task::getProcessInstanceId); 50 + Task::getProcessInstanceId);
46 } 51 }
47 52
48 /** 53 /**
49 * 获得流程任务列表 54 * 获得流程任务列表
50 * 55 *
51 * @param processInstanceIds 流程实例的编号数组 56 * @param processInstanceIds 流程实例的编号数组
  57 + *
52 * @return 流程任务列表 58 * @return 流程任务列表
53 */ 59 */
54 List<Task> getTasksByProcessInstanceIds(List<String> processInstanceIds); 60 List<Task> getTasksByProcessInstanceIds(List<String> processInstanceIds);
@@ -57,6 +63,7 @@ public interface BpmTaskService { @@ -57,6 +63,7 @@ public interface BpmTaskService {
57 * 获得指令流程实例的流程任务列表,包括所有状态的 63 * 获得指令流程实例的流程任务列表,包括所有状态的
58 * 64 *
59 * @param processInstanceId 流程实例的编号 65 * @param processInstanceId 流程实例的编号
  66 + *
60 * @return 流程任务列表 67 * @return 流程任务列表
61 */ 68 */
62 List<BpmTaskRespVO> getTaskListByProcessInstanceId(String processInstanceId); 69 List<BpmTaskRespVO> getTaskListByProcessInstanceId(String processInstanceId);
@@ -65,7 +72,7 @@ public interface BpmTaskService { @@ -65,7 +72,7 @@ public interface BpmTaskService {
65 * 通过任务 72 * 通过任务
66 * 73 *
67 * @param userId 用户编号 74 * @param userId 用户编号
68 - * @param reqVO 通过请求 75 + * @param reqVO 通过请求
69 */ 76 */
70 void approveTask(Long userId, @Valid BpmTaskApproveReqVO reqVO); 77 void approveTask(Long userId, @Valid BpmTaskApproveReqVO reqVO);
71 78
@@ -73,7 +80,7 @@ public interface BpmTaskService { @@ -73,7 +80,7 @@ public interface BpmTaskService {
73 * 不通过任务 80 * 不通过任务
74 * 81 *
75 * @param userId 用户编号 82 * @param userId 用户编号
76 - * @param reqVO 不通过请求 83 + * @param reqVO 不通过请求
77 */ 84 */
78 void rejectTask(Long userId, @Valid BpmTaskRejectReqVO reqVO); 85 void rejectTask(Long userId, @Valid BpmTaskRejectReqVO reqVO);
79 86
@@ -81,14 +88,14 @@ public interface BpmTaskService { @@ -81,14 +88,14 @@ public interface BpmTaskService {
81 * 将流程任务分配给指定用户 88 * 将流程任务分配给指定用户
82 * 89 *
83 * @param userId 用户编号 90 * @param userId 用户编号
84 - * @param reqVO 分配请求 91 + * @param reqVO 分配请求
85 */ 92 */
86 void updateTaskAssignee(Long userId, BpmTaskUpdateAssigneeReqVO reqVO); 93 void updateTaskAssignee(Long userId, BpmTaskUpdateAssigneeReqVO reqVO);
87 94
88 /** 95 /**
89 * 将流程任务分配给指定用户 96 * 将流程任务分配给指定用户
90 * 97 *
91 - * @param id 流程任务编号 98 + * @param id 流程任务编号
92 * @param userId 用户编号 99 * @param userId 用户编号
93 */ 100 */
94 void updateTaskAssignee(String id, Long userId); 101 void updateTaskAssignee(String id, Long userId);
@@ -108,6 +115,13 @@ public interface BpmTaskService { @@ -108,6 +115,13 @@ public interface BpmTaskService {
108 void updateTaskExtComplete(Task task); 115 void updateTaskExtComplete(Task task);
109 116
110 /** 117 /**
  118 + * 更新 Task 拓展记录为已取消
  119 + *
  120 + * @param taskId 任务的编号
  121 + */
  122 + void updateTaskExtCancel(String taskId);
  123 +
  124 + /**
111 * 更新 Task 拓展记录,并发送通知 125 * 更新 Task 拓展记录,并发送通知
112 * 126 *
113 * @param task 任务实体 127 * @param task 任务实体
yudao-module-bpm/yudao-module-bpm-biz-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmTaskServiceImpl.java renamed to yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmTaskServiceImpl.java
@@ -7,8 +7,12 @@ import cn.iocoder.yudao.framework.common.util.number.NumberUtils; @@ -7,8 +7,12 @@ import cn.iocoder.yudao.framework.common.util.number.NumberUtils;
7 import cn.iocoder.yudao.framework.common.util.object.PageUtils; 7 import cn.iocoder.yudao.framework.common.util.object.PageUtils;
8 import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.task.*; 8 import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.task.*;
9 import cn.iocoder.yudao.module.bpm.convert.task.BpmTaskConvert; 9 import cn.iocoder.yudao.module.bpm.convert.task.BpmTaskConvert;
  10 +import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmTaskAssignRuleDO;
10 import cn.iocoder.yudao.module.bpm.dal.dataobject.task.BpmTaskExtDO; 11 import cn.iocoder.yudao.module.bpm.dal.dataobject.task.BpmTaskExtDO;
  12 +import cn.iocoder.yudao.module.bpm.dal.mysql.definition.BpmTaskAssignRuleMapper;
  13 +import cn.iocoder.yudao.module.bpm.dal.mysql.task.BpmActivityMapper;
11 import cn.iocoder.yudao.module.bpm.dal.mysql.task.BpmTaskExtMapper; 14 import cn.iocoder.yudao.module.bpm.dal.mysql.task.BpmTaskExtMapper;
  15 +import cn.iocoder.yudao.module.bpm.enums.task.BpmProcessInstanceDeleteReasonEnum;
12 import cn.iocoder.yudao.module.bpm.enums.task.BpmProcessInstanceResultEnum; 16 import cn.iocoder.yudao.module.bpm.enums.task.BpmProcessInstanceResultEnum;
13 import cn.iocoder.yudao.module.bpm.service.message.BpmMessageService; 17 import cn.iocoder.yudao.module.bpm.service.message.BpmMessageService;
14 import cn.iocoder.yudao.module.system.api.dept.DeptApi; 18 import cn.iocoder.yudao.module.system.api.dept.DeptApi;
@@ -46,7 +50,7 @@ import static cn.iocoder.yudao.module.bpm.enums.ErrorCodeConstants.*; @@ -46,7 +50,7 @@ import static cn.iocoder.yudao.module.bpm.enums.ErrorCodeConstants.*;
46 */ 50 */
47 @Slf4j 51 @Slf4j
48 @Service 52 @Service
49 -public class BpmTaskServiceImpl implements BpmTaskService{ 53 +public class BpmTaskServiceImpl implements BpmTaskService {
50 54
51 @Resource 55 @Resource
52 private TaskService taskService; 56 private TaskService taskService;
@@ -63,13 +67,16 @@ public class BpmTaskServiceImpl implements BpmTaskService{ @@ -63,13 +67,16 @@ public class BpmTaskServiceImpl implements BpmTaskService{
63 private BpmTaskExtMapper taskExtMapper; 67 private BpmTaskExtMapper taskExtMapper;
64 @Resource 68 @Resource
65 private BpmMessageService messageService; 69 private BpmMessageService messageService;
  70 + @Resource
  71 + private BpmTaskAssignRuleMapper taskAssignRuleMapper;
  72 + @Resource
  73 + private BpmActivityMapper bpmActivityMapper;
66 74
67 @Override 75 @Override
68 public PageResult<BpmTaskTodoPageItemRespVO> getTodoTaskPage(Long userId, BpmTaskTodoPageReqVO pageVO) { 76 public PageResult<BpmTaskTodoPageItemRespVO> getTodoTaskPage(Long userId, BpmTaskTodoPageReqVO pageVO) {
69 // 查询待办任务 77 // 查询待办任务
70 - TaskQuery taskQuery = taskService.createTaskQuery()  
71 - .taskAssignee(String.valueOf(userId)) // 分配给自己  
72 - .orderByTaskCreateTime().desc(); // 创建时间倒序 78 + TaskQuery taskQuery = taskService.createTaskQuery().taskAssignee(String.valueOf(userId)) // 分配给自己
  79 + .orderByTaskCreateTime().desc(); // 创建时间倒序
73 if (StrUtil.isNotBlank(pageVO.getName())) { 80 if (StrUtil.isNotBlank(pageVO.getName())) {
74 taskQuery.taskNameLike("%" + pageVO.getName() + "%"); 81 taskQuery.taskNameLike("%" + pageVO.getName() + "%");
75 } 82 }
@@ -86,23 +93,22 @@ public class BpmTaskServiceImpl implements BpmTaskService{ @@ -86,23 +93,22 @@ public class BpmTaskServiceImpl implements BpmTaskService{
86 } 93 }
87 94
88 // 获得 ProcessInstance Map 95 // 获得 ProcessInstance Map
89 - Map<String, ProcessInstance> processInstanceMap = processInstanceService.getProcessInstanceMap(  
90 - convertSet(tasks, Task::getProcessInstanceId)); 96 + Map<String, ProcessInstance> processInstanceMap =
  97 + processInstanceService.getProcessInstanceMap(convertSet(tasks, Task::getProcessInstanceId));
91 // 获得 User Map 98 // 获得 User Map
92 Map<Long, AdminUserRespDTO> userMap = adminUserApi.getUserMap( 99 Map<Long, AdminUserRespDTO> userMap = adminUserApi.getUserMap(
93 - convertSet(processInstanceMap.values(), instance -> Long.valueOf(instance.getStartUserId()))); 100 + convertSet(processInstanceMap.values(), instance -> Long.valueOf(instance.getStartUserId())));
94 // 拼接结果 101 // 拼接结果
95 return new PageResult<>(BpmTaskConvert.INSTANCE.convertList1(tasks, processInstanceMap, userMap), 102 return new PageResult<>(BpmTaskConvert.INSTANCE.convertList1(tasks, processInstanceMap, userMap),
96 - taskQuery.count()); 103 + taskQuery.count());
97 } 104 }
98 105
99 @Override 106 @Override
100 public PageResult<BpmTaskDonePageItemRespVO> getDoneTaskPage(Long userId, BpmTaskDonePageReqVO pageVO) { 107 public PageResult<BpmTaskDonePageItemRespVO> getDoneTaskPage(Long userId, BpmTaskDonePageReqVO pageVO) {
101 // 查询已办任务 108 // 查询已办任务
102 - HistoricTaskInstanceQuery taskQuery = historyService.createHistoricTaskInstanceQuery()  
103 - .finished() // 已完成  
104 - .taskAssignee(String.valueOf(userId)) // 分配给自己  
105 - .orderByHistoricTaskInstanceEndTime().desc(); // 审批时间倒序 109 + HistoricTaskInstanceQuery taskQuery = historyService.createHistoricTaskInstanceQuery().finished() // 已完成
  110 + .taskAssignee(String.valueOf(userId)) // 分配给自己
  111 + .orderByHistoricTaskInstanceEndTime().desc(); // 审批时间倒序
106 if (StrUtil.isNotBlank(pageVO.getName())) { 112 if (StrUtil.isNotBlank(pageVO.getName())) {
107 taskQuery.taskNameLike("%" + pageVO.getName() + "%"); 113 taskQuery.taskNameLike("%" + pageVO.getName() + "%");
108 } 114 }
@@ -119,17 +125,20 @@ public class BpmTaskServiceImpl implements BpmTaskService{ @@ -119,17 +125,20 @@ public class BpmTaskServiceImpl implements BpmTaskService{
119 } 125 }
120 126
121 // 获得 TaskExtDO Map 127 // 获得 TaskExtDO Map
122 - List<BpmTaskExtDO> bpmTaskExtDOs = taskExtMapper.selectListByTaskIds(convertSet(tasks, HistoricTaskInstance::getId)); 128 + List<BpmTaskExtDO> bpmTaskExtDOs =
  129 + taskExtMapper.selectListByTaskIds(convertSet(tasks, HistoricTaskInstance::getId));
123 Map<String, BpmTaskExtDO> bpmTaskExtDOMap = convertMap(bpmTaskExtDOs, BpmTaskExtDO::getTaskId); 130 Map<String, BpmTaskExtDO> bpmTaskExtDOMap = convertMap(bpmTaskExtDOs, BpmTaskExtDO::getTaskId);
124 // 获得 ProcessInstance Map 131 // 获得 ProcessInstance Map
125 - Map<String, HistoricProcessInstance> historicProcessInstanceMap = processInstanceService.getHistoricProcessInstanceMap( 132 + Map<String, HistoricProcessInstance> historicProcessInstanceMap =
  133 + processInstanceService.getHistoricProcessInstanceMap(
126 convertSet(tasks, HistoricTaskInstance::getProcessInstanceId)); 134 convertSet(tasks, HistoricTaskInstance::getProcessInstanceId));
127 // 获得 User Map 135 // 获得 User Map
128 Map<Long, AdminUserRespDTO> userMap = adminUserApi.getUserMap( 136 Map<Long, AdminUserRespDTO> userMap = adminUserApi.getUserMap(
129 - convertSet(historicProcessInstanceMap.values(), instance -> Long.valueOf(instance.getStartUserId()))); 137 + convertSet(historicProcessInstanceMap.values(), instance -> Long.valueOf(instance.getStartUserId())));
130 // 拼接结果 138 // 拼接结果
131 - return new PageResult<>(BpmTaskConvert.INSTANCE.convertList2(tasks, bpmTaskExtDOMap, historicProcessInstanceMap, userMap),  
132 - taskQuery.count()); 139 + return new PageResult<>(
  140 + BpmTaskConvert.INSTANCE.convertList2(tasks, bpmTaskExtDOMap, historicProcessInstanceMap, userMap),
  141 + taskQuery.count());
133 } 142 }
134 143
135 @Override 144 @Override
@@ -180,9 +189,15 @@ public class BpmTaskServiceImpl implements BpmTaskService{ @@ -180,9 +189,15 @@ public class BpmTaskServiceImpl implements BpmTaskService{
180 189
181 // 完成任务,审批通过 190 // 完成任务,审批通过
182 taskService.complete(task.getId(), instance.getProcessVariables()); 191 taskService.complete(task.getId(), instance.getProcessVariables());
  192 +
183 // 更新任务拓展表为通过 193 // 更新任务拓展表为通过
184 - taskExtMapper.updateByTaskId(new BpmTaskExtDO().setTaskId(task.getId())  
185 - .setResult(BpmProcessInstanceResultEnum.APPROVE.getResult()).setReason(reqVO.getReason())); 194 + taskExtMapper.updateByTaskId(
  195 + new BpmTaskExtDO().setTaskId(task.getId()).setResult(BpmProcessInstanceResultEnum.APPROVE.getResult())
  196 + .setReason(reqVO.getReason()));
  197 + // 判断任务是否为或签,或签时删除其余不用审批的任务
  198 + List<BpmTaskAssignRuleDO> bpmTaskAssignRuleList =
  199 + taskAssignRuleMapper.selectListByProcessDefinitionId(task.getProcessDefinitionId(),
  200 + task.getTaskDefinitionKey());
186 } 201 }
187 202
188 @Override 203 @Override
@@ -199,8 +214,9 @@ public class BpmTaskServiceImpl implements BpmTaskService{ @@ -199,8 +214,9 @@ public class BpmTaskServiceImpl implements BpmTaskService{
199 processInstanceService.updateProcessInstanceExtReject(instance.getProcessInstanceId(), reqVO.getReason()); 214 processInstanceService.updateProcessInstanceExtReject(instance.getProcessInstanceId(), reqVO.getReason());
200 215
201 // 更新任务拓展表为不通过 216 // 更新任务拓展表为不通过
202 - taskExtMapper.updateByTaskId(new BpmTaskExtDO().setTaskId(task.getId())  
203 - .setResult(BpmProcessInstanceResultEnum.REJECT.getResult()).setReason(reqVO.getReason())); 217 + taskExtMapper.updateByTaskId(
  218 + new BpmTaskExtDO().setTaskId(task.getId()).setResult(BpmProcessInstanceResultEnum.REJECT.getResult())
  219 + .setReason(reqVO.getReason()));
204 } 220 }
205 221
206 @Override 222 @Override
@@ -216,55 +232,95 @@ public class BpmTaskServiceImpl implements BpmTaskService{ @@ -216,55 +232,95 @@ public class BpmTaskServiceImpl implements BpmTaskService{
216 taskService.setAssignee(id, String.valueOf(userId)); 232 taskService.setAssignee(id, String.valueOf(userId));
217 } 233 }
218 234
  235 + /**
  236 + * 校验任务是否存在, 并且是否是分配给自己的任务
  237 + *
  238 + * @param userId 用户 id
  239 + * @param taskId task id
  240 + */
  241 + private Task checkTask(Long userId, String taskId) {
  242 + Task task = getTask(taskId);
  243 + if (task == null) {
  244 + throw exception(TASK_COMPLETE_FAIL_NOT_EXISTS);
  245 + }
  246 + if (!Objects.equals(userId, NumberUtils.parseLong(task.getAssignee()))) {
  247 + throw exception(TASK_COMPLETE_FAIL_ASSIGN_NOT_SELF);
  248 + }
  249 + return task;
  250 + }
219 251
220 @Override 252 @Override
221 public void createTaskExt(Task task) { 253 public void createTaskExt(Task task) {
222 - BpmTaskExtDO taskExtDO = BpmTaskConvert.INSTANCE.convert2TaskExt(task)  
223 - .setResult(BpmProcessInstanceResultEnum.PROCESS.getResult()); 254 + BpmTaskExtDO taskExtDO =
  255 + BpmTaskConvert.INSTANCE.convert2TaskExt(task).setResult(BpmProcessInstanceResultEnum.PROCESS.getResult());
224 taskExtMapper.insert(taskExtDO); 256 taskExtMapper.insert(taskExtDO);
225 } 257 }
226 258
227 @Override 259 @Override
228 public void updateTaskExtComplete(Task task) { 260 public void updateTaskExtComplete(Task task) {
229 BpmTaskExtDO taskExtDO = BpmTaskConvert.INSTANCE.convert2TaskExt(task) 261 BpmTaskExtDO taskExtDO = BpmTaskConvert.INSTANCE.convert2TaskExt(task)
  262 + .setResult(BpmProcessInstanceResultEnum.APPROVE.getResult()) // 不设置也问题不大,因为 Complete 一般是审核通过,已经设置
230 .setEndTime(new Date()); 263 .setEndTime(new Date());
231 taskExtMapper.updateByTaskId(taskExtDO); 264 taskExtMapper.updateByTaskId(taskExtDO);
232 } 265 }
233 266
234 @Override 267 @Override
  268 + public void updateTaskExtCancel(String taskId) {
  269 + // 需要在事务提交后,才进行查询。不然查询不到历史的原因
  270 + TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronization() {
  271 +
  272 + @Override
  273 + public void afterCommit() {
  274 + // 可能只是活动,不是任务,所以查询不到
  275 + HistoricTaskInstance task = getHistoricTask(taskId);
  276 + if (task == null) {
  277 + return;
  278 + }
  279 +
  280 + // 如果任务拓展表已经是完成的状态,则跳过
  281 + BpmTaskExtDO taskExt = taskExtMapper.selectByTaskId(taskId);
  282 + if (taskExt == null) {
  283 + log.error("[updateTaskExtCancel][taskId({}) 查找不到对应的记录,可能存在问题]", taskId);
  284 + return;
  285 + }
  286 + // 如果已经是最终的结果,则跳过
  287 + if (BpmProcessInstanceResultEnum.isEndResult(taskExt.getResult())) {
  288 + log.error("[updateTaskExtCancel][taskId({}) 处于结果({}),无需进行更新]", taskId, taskExt.getResult());
  289 + return;
  290 + }
  291 +
  292 + // 更新任务
  293 + taskExtMapper.updateById(new BpmTaskExtDO().setId(taskExt.getId()).setResult(BpmProcessInstanceResultEnum.CANCEL.getResult())
  294 + .setEndTime(new Date()).setReason(BpmProcessInstanceDeleteReasonEnum.translateReason(task.getDeleteReason())));
  295 + }
  296 +
  297 + });
  298 + }
  299 +
  300 + @Override
235 public void updateTaskExtAssign(Task task) { 301 public void updateTaskExtAssign(Task task) {
236 - BpmTaskExtDO taskExtDO = new BpmTaskExtDO()  
237 - .setAssigneeUserId(NumberUtils.parseLong(task.getAssignee()))  
238 - .setTaskId(task.getId()); 302 + BpmTaskExtDO taskExtDO =
  303 + new BpmTaskExtDO().setAssigneeUserId(NumberUtils.parseLong(task.getAssignee())).setTaskId(task.getId());
239 taskExtMapper.updateByTaskId(taskExtDO); 304 taskExtMapper.updateByTaskId(taskExtDO);
240 // 发送通知。在事务提交时,批量执行操作,所以直接查询会无法查询到 ProcessInstance,所以这里是通过监听事务的提交来实现。 305 // 发送通知。在事务提交时,批量执行操作,所以直接查询会无法查询到 ProcessInstance,所以这里是通过监听事务的提交来实现。
241 TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronization() { 306 TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronization() {
242 @Override 307 @Override
243 public void afterCommit() { 308 public void afterCommit() {
244 - ProcessInstance processInstance = processInstanceService.getProcessInstance(task.getProcessInstanceId()); 309 + ProcessInstance processInstance =
  310 + processInstanceService.getProcessInstance(task.getProcessInstanceId());
245 AdminUserRespDTO startUser = adminUserApi.getUser(Long.valueOf(processInstance.getStartUserId())); 311 AdminUserRespDTO startUser = adminUserApi.getUser(Long.valueOf(processInstance.getStartUserId()));
246 - messageService.sendMessageWhenTaskAssigned(BpmTaskConvert.INSTANCE.convert(processInstance, startUser, task)); 312 + messageService.sendMessageWhenTaskAssigned(
  313 + BpmTaskConvert.INSTANCE.convert(processInstance, startUser, task));
247 } 314 }
248 }); 315 });
249 } 316 }
250 317
251 - /**  
252 - * 校验任务是否存在, 并且是否是分配给自己的任务  
253 - * @param userId 用户 id  
254 - * @param taskId task id  
255 - */  
256 - private Task checkTask(Long userId, String taskId) {  
257 - Task task = getTask(taskId);  
258 - if (task == null) {  
259 - throw exception(TASK_COMPLETE_FAIL_NOT_EXISTS);  
260 - }  
261 - if (!Objects.equals(userId, NumberUtils.parseLong(task.getAssignee()))) {  
262 - throw exception(TASK_COMPLETE_FAIL_ASSIGN_NOT_SELF);  
263 - }  
264 - return task;  
265 - }  
266 -  
267 private Task getTask(String id) { 318 private Task getTask(String id) {
268 return taskService.createTaskQuery().taskId(id).singleResult(); 319 return taskService.createTaskQuery().taskId(id).singleResult();
269 } 320 }
  321 +
  322 + private HistoricTaskInstance getHistoricTask(String id) {
  323 + return historyService.createHistoricTaskInstanceQuery().taskId(id).singleResult();
  324 + }
  325 +
270 } 326 }
yudao-module-bpm/yudao-module-bpm-base/src/main/java/cn/iocoder/yudao/module/bpm/service/task/package-info.java renamed to yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/task/package-info.java
yudao-module-bpm/yudao-module-bpm-biz-activiti/src/test/java/cn/iocoder/yudao/module/bpm/framework/activiti/core/behavior/script/impl/BpmTaskAssignLeaderX2ScriptTest.java renamed to yudao-module-bpm/yudao-module-bpm-biz/src/test/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/behavior/script/impl/BpmTaskAssignLeaderX2ScriptTest.java
1 -package cn.iocoder.yudao.module.bpm.framework.activiti.core.behavior.script.impl; 1 +package cn.iocoder.yudao.module.bpm.framework.flowable.core.behavior.script.impl;
2 2
3 import cn.iocoder.yudao.framework.test.core.ut.BaseMockitoUnitTest; 3 import cn.iocoder.yudao.framework.test.core.ut.BaseMockitoUnitTest;
  4 +import cn.iocoder.yudao.module.bpm.service.task.BpmProcessInstanceService;
4 import cn.iocoder.yudao.module.system.api.dept.DeptApi; 5 import cn.iocoder.yudao.module.system.api.dept.DeptApi;
5 import cn.iocoder.yudao.module.system.api.dept.dto.DeptRespDTO; 6 import cn.iocoder.yudao.module.system.api.dept.dto.DeptRespDTO;
6 import cn.iocoder.yudao.module.system.api.user.AdminUserApi; 7 import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
7 import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO; 8 import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
8 -import org.activiti.engine.impl.persistence.entity.ExecutionEntityImpl;  
9 -import org.activiti.engine.impl.persistence.entity.TaskEntity;  
10 -import org.activiti.engine.impl.persistence.entity.TaskEntityImpl; 9 +import org.flowable.engine.delegate.DelegateExecution;
  10 +import org.flowable.engine.impl.persistence.entity.ExecutionEntityImpl;
11 import org.junit.jupiter.api.Test; 11 import org.junit.jupiter.api.Test;
12 import org.mockito.InjectMocks; 12 import org.mockito.InjectMocks;
13 import org.mockito.Mock; 13 import org.mockito.Mock;
14 -import org.springframework.boot.test.mock.mockito.MockBean;  
15 14
16 import java.util.Set; 15 import java.util.Set;
17 16
18 import static cn.iocoder.yudao.framework.common.util.collection.SetUtils.asSet; 17 import static cn.iocoder.yudao.framework.common.util.collection.SetUtils.asSet;
19 import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomPojo; 18 import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomPojo;
  19 +import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomString;
20 import static org.junit.jupiter.api.Assertions.assertEquals; 20 import static org.junit.jupiter.api.Assertions.assertEquals;
21 import static org.mockito.ArgumentMatchers.eq; 21 import static org.mockito.ArgumentMatchers.eq;
22 import static org.mockito.Mockito.when; 22 import static org.mockito.Mockito.when;
23 23
24 -class BpmTaskAssignLeaderX2ScriptTest extends BaseMockitoUnitTest { 24 +public class BpmTaskAssignLeaderX2ScriptTest extends BaseMockitoUnitTest {
25 25
26 @InjectMocks 26 @InjectMocks
27 private BpmTaskAssignLeaderX2Script script; 27 private BpmTaskAssignLeaderX2Script script;
@@ -30,17 +30,19 @@ class BpmTaskAssignLeaderX2ScriptTest extends BaseMockitoUnitTest { @@ -30,17 +30,19 @@ class BpmTaskAssignLeaderX2ScriptTest extends BaseMockitoUnitTest {
30 private AdminUserApi adminUserApi; 30 private AdminUserApi adminUserApi;
31 @Mock 31 @Mock
32 private DeptApi deptApi; 32 private DeptApi deptApi;
  33 + @Mock
  34 + private BpmProcessInstanceService bpmProcessInstanceService;
33 35
34 @Test 36 @Test
35 public void testCalculateTaskCandidateUsers_noDept() { 37 public void testCalculateTaskCandidateUsers_noDept() {
36 // 准备参数 38 // 准备参数
37 - TaskEntity task = buildTaskEntity(1L); 39 + DelegateExecution execution = mockDelegateExecution(1L);
38 // mock 方法(startUser) 40 // mock 方法(startUser)
39 AdminUserRespDTO startUser = randomPojo(AdminUserRespDTO.class, o -> o.setDeptId(10L)); 41 AdminUserRespDTO startUser = randomPojo(AdminUserRespDTO.class, o -> o.setDeptId(10L));
40 when(adminUserApi.getUser(eq(1L))).thenReturn(startUser); 42 when(adminUserApi.getUser(eq(1L))).thenReturn(startUser);
41 43
42 // 调用 44 // 调用
43 - Set<Long> result = script.calculateTaskCandidateUsers(task); 45 + Set<Long> result = script.calculateTaskCandidateUsers(execution);
44 // 断言 46 // 断言
45 assertEquals(0, result.size()); 47 assertEquals(0, result.size());
46 } 48 }
@@ -48,7 +50,7 @@ class BpmTaskAssignLeaderX2ScriptTest extends BaseMockitoUnitTest { @@ -48,7 +50,7 @@ class BpmTaskAssignLeaderX2ScriptTest extends BaseMockitoUnitTest {
48 @Test 50 @Test
49 public void testCalculateTaskCandidateUsers_noParentDept() { 51 public void testCalculateTaskCandidateUsers_noParentDept() {
50 // 准备参数 52 // 准备参数
51 - TaskEntity task = buildTaskEntity(1L); 53 + DelegateExecution execution = mockDelegateExecution(1L);
52 // mock 方法(startUser) 54 // mock 方法(startUser)
53 AdminUserRespDTO startUser = randomPojo(AdminUserRespDTO.class, o -> o.setDeptId(10L)); 55 AdminUserRespDTO startUser = randomPojo(AdminUserRespDTO.class, o -> o.setDeptId(10L));
54 when(adminUserApi.getUser(eq(1L))).thenReturn(startUser); 56 when(adminUserApi.getUser(eq(1L))).thenReturn(startUser);
@@ -57,7 +59,7 @@ class BpmTaskAssignLeaderX2ScriptTest extends BaseMockitoUnitTest { @@ -57,7 +59,7 @@ class BpmTaskAssignLeaderX2ScriptTest extends BaseMockitoUnitTest {
57 when(deptApi.getDept(eq(10L))).thenReturn(startUserDept); 59 when(deptApi.getDept(eq(10L))).thenReturn(startUserDept);
58 60
59 // 调用 61 // 调用
60 - Set<Long> result = script.calculateTaskCandidateUsers(task); 62 + Set<Long> result = script.calculateTaskCandidateUsers(execution);
61 // 断言 63 // 断言
62 assertEquals(asSet(20L), result); 64 assertEquals(asSet(20L), result);
63 } 65 }
@@ -65,7 +67,7 @@ class BpmTaskAssignLeaderX2ScriptTest extends BaseMockitoUnitTest { @@ -65,7 +67,7 @@ class BpmTaskAssignLeaderX2ScriptTest extends BaseMockitoUnitTest {
65 @Test 67 @Test
66 public void testCalculateTaskCandidateUsers_existParentDept() { 68 public void testCalculateTaskCandidateUsers_existParentDept() {
67 // 准备参数 69 // 准备参数
68 - TaskEntity task = buildTaskEntity(1L); 70 + DelegateExecution execution = mockDelegateExecution(1L);
69 // mock 方法(startUser) 71 // mock 方法(startUser)
70 AdminUserRespDTO startUser = randomPojo(AdminUserRespDTO.class, o -> o.setDeptId(10L)); 72 AdminUserRespDTO startUser = randomPojo(AdminUserRespDTO.class, o -> o.setDeptId(10L));
71 when(adminUserApi.getUser(eq(1L))).thenReturn(startUser); 73 when(adminUserApi.getUser(eq(1L))).thenReturn(startUser);
@@ -78,17 +80,21 @@ class BpmTaskAssignLeaderX2ScriptTest extends BaseMockitoUnitTest { @@ -78,17 +80,21 @@ class BpmTaskAssignLeaderX2ScriptTest extends BaseMockitoUnitTest {
78 when(deptApi.getDept(eq(100L))).thenReturn(parentDept); 80 when(deptApi.getDept(eq(100L))).thenReturn(parentDept);
79 81
80 // 调用 82 // 调用
81 - Set<Long> result = script.calculateTaskCandidateUsers(task); 83 + Set<Long> result = script.calculateTaskCandidateUsers(execution);
82 // 断言 84 // 断言
83 assertEquals(asSet(200L), result); 85 assertEquals(asSet(200L), result);
84 } 86 }
85 87
86 @SuppressWarnings("SameParameterValue") 88 @SuppressWarnings("SameParameterValue")
87 - private TaskEntity buildTaskEntity(Long startUserId) {  
88 - TaskEntityImpl task = new TaskEntityImpl();  
89 - task.setProcessInstance(new ExecutionEntityImpl());  
90 - task.getProcessInstance().setStartUserId(String.valueOf(startUserId));  
91 - return task; 89 + private DelegateExecution mockDelegateExecution(Long startUserId) {
  90 + ExecutionEntityImpl execution = new ExecutionEntityImpl();
  91 + execution.setProcessInstanceId(randomString());
  92 + // mock 返回 startUserId
  93 + ExecutionEntityImpl processInstance = new ExecutionEntityImpl();
  94 + processInstance.setStartUserId(String.valueOf(startUserId));
  95 + when(bpmProcessInstanceService.getProcessInstance(eq(execution.getProcessInstanceId())))
  96 + .thenReturn(processInstance);
  97 + return execution;
92 } 98 }
93 99
94 } 100 }
yudao-module-bpm/yudao-module-bpm-base/src/test/java/cn/iocoder/yudao/module/bpm/service/definition/BpmFormServiceTest.java renamed to yudao-module-bpm/yudao-module-bpm-biz/src/test/java/cn/iocoder/yudao/module/bpm/service/definition/BpmFormServiceTest.java
yudao-module-bpm/yudao-module-bpm-biz-activiti/src/test/java/cn/iocoder/yudao/module/bpm/framework/activiti/core/behavior/BpmUserTaskActivityBehaviorTest.java renamed to yudao-module-bpm/yudao-module-bpm-biz/src/test/java/cn/iocoder/yudao/module/bpm/service/definition/BpmTaskAssignRuleServiceImplTest.java
1 -package cn.iocoder.yudao.module.bpm.framework.activiti.core.behavior; 1 +package cn.iocoder.yudao.module.bpm.service.definition;
2 2
3 import cn.hutool.core.map.MapUtil; 3 import cn.hutool.core.map.MapUtil;
4 -import cn.iocoder.yudao.module.bpm.framework.activiti.core.behavior.script.BpmTaskAssignScript;  
5 -import cn.iocoder.yudao.module.bpm.service.definition.BpmTaskAssignRuleService;  
6 import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; 4 import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
7 import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; 5 import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
8 -import cn.iocoder.yudao.framework.test.core.ut.BaseMockitoUnitTest; 6 +import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest;
9 import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmTaskAssignRuleDO; 7 import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmTaskAssignRuleDO;
10 import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmUserGroupDO; 8 import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmUserGroupDO;
11 import cn.iocoder.yudao.module.bpm.enums.definition.BpmTaskAssignRuleTypeEnum; 9 import cn.iocoder.yudao.module.bpm.enums.definition.BpmTaskAssignRuleTypeEnum;
12 import cn.iocoder.yudao.module.bpm.enums.definition.BpmTaskRuleScriptEnum; 10 import cn.iocoder.yudao.module.bpm.enums.definition.BpmTaskRuleScriptEnum;
13 -import cn.iocoder.yudao.module.bpm.service.definition.BpmUserGroupService; 11 +import cn.iocoder.yudao.module.bpm.framework.flowable.core.behavior.script.BpmTaskAssignScript;
  12 +import cn.iocoder.yudao.module.bpm.framework.flowable.core.behavior.script.impl.BpmTaskAssignStartUserScript;
14 import cn.iocoder.yudao.module.system.api.dept.DeptApi; 13 import cn.iocoder.yudao.module.system.api.dept.DeptApi;
  14 +import cn.iocoder.yudao.module.system.api.dept.PostApi;
15 import cn.iocoder.yudao.module.system.api.dept.dto.DeptRespDTO; 15 import cn.iocoder.yudao.module.system.api.dept.dto.DeptRespDTO;
  16 +import cn.iocoder.yudao.module.system.api.dict.DictDataApi;
16 import cn.iocoder.yudao.module.system.api.permission.PermissionApi; 17 import cn.iocoder.yudao.module.system.api.permission.PermissionApi;
  18 +import cn.iocoder.yudao.module.system.api.permission.RoleApi;
17 import cn.iocoder.yudao.module.system.api.user.AdminUserApi; 19 import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
18 import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO; 20 import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
19 -import org.activiti.engine.impl.persistence.entity.TaskEntity; 21 +import org.flowable.engine.delegate.DelegateExecution;
20 import org.junit.jupiter.api.Test; 22 import org.junit.jupiter.api.Test;
21 -import org.mockito.InjectMocks;  
22 -import org.mockito.Mock; 23 +import org.springframework.boot.test.mock.mockito.MockBean;
  24 +import org.springframework.context.annotation.Import;
23 25
  26 +import javax.annotation.Resource;
24 import java.util.Arrays; 27 import java.util.Arrays;
25 import java.util.List; 28 import java.util.List;
26 import java.util.Map; 29 import java.util.Map;
@@ -33,21 +36,31 @@ import static org.junit.jupiter.api.Assertions.assertEquals; @@ -33,21 +36,31 @@ import static org.junit.jupiter.api.Assertions.assertEquals;
33 import static org.mockito.ArgumentMatchers.eq; 36 import static org.mockito.ArgumentMatchers.eq;
34 import static org.mockito.Mockito.when; 37 import static org.mockito.Mockito.when;
35 38
36 -public class BpmUserTaskActivityBehaviorTest extends BaseMockitoUnitTest { 39 +/**
  40 + * {@link BpmTaskAssignRuleService} 的单元测试
  41 + *
  42 + * @author 芋道源码
  43 + */
  44 +@Import({BpmTaskAssignRuleServiceImpl.class, BpmTaskAssignStartUserScript.class}) // Import 引入 BpmTaskAssignStartUserScript 目的是保证不报错
  45 +public class BpmTaskAssignRuleServiceImplTest extends BaseDbUnitTest {
37 46
38 - @InjectMocks  
39 - private BpmUserTaskActivityBehavior behavior;  
40 - @Mock  
41 - private BpmTaskAssignRuleService bpmTaskRuleService;  
42 - @Mock  
43 - private BpmUserGroupService userGroupService; 47 + @Resource
  48 + private BpmTaskAssignRuleServiceImpl bpmTaskRuleService;
44 49
45 - @Mock 50 + @MockBean
  51 + private BpmUserGroupService userGroupService;
  52 + @MockBean
46 private DeptApi deptApi; 53 private DeptApi deptApi;
47 - @Mock 54 + @MockBean
48 private AdminUserApi adminUserApi; 55 private AdminUserApi adminUserApi;
49 - @Mock 56 + @MockBean
50 private PermissionApi permissionApi; 57 private PermissionApi permissionApi;
  58 + @MockBean
  59 + private RoleApi roleApi;
  60 + @MockBean
  61 + private PostApi postApi;
  62 + @MockBean
  63 + private DictDataApi dictDataApi;
51 64
52 @Test 65 @Test
53 public void testCalculateTaskCandidateUsers_Role() { 66 public void testCalculateTaskCandidateUsers_Role() {
@@ -60,7 +73,7 @@ public class BpmUserTaskActivityBehaviorTest extends BaseMockitoUnitTest { @@ -60,7 +73,7 @@ public class BpmUserTaskActivityBehaviorTest extends BaseMockitoUnitTest {
60 mockGetUserMap(asSet(11L, 22L)); 73 mockGetUserMap(asSet(11L, 22L));
61 74
62 // 调用 75 // 调用
63 - Set<Long> results = behavior.calculateTaskCandidateUsers(null, rule); 76 + Set<Long> results = bpmTaskRuleService.calculateTaskCandidateUsers(null, rule);
64 // 断言 77 // 断言
65 assertEquals(asSet(11L, 22L), results); 78 assertEquals(asSet(11L, 22L), results);
66 } 79 }
@@ -77,7 +90,7 @@ public class BpmUserTaskActivityBehaviorTest extends BaseMockitoUnitTest { @@ -77,7 +90,7 @@ public class BpmUserTaskActivityBehaviorTest extends BaseMockitoUnitTest {
77 mockGetUserMap(asSet(11L, 22L)); 90 mockGetUserMap(asSet(11L, 22L));
78 91
79 // 调用 92 // 调用
80 - Set<Long> results = behavior.calculateTaskCandidateUsers(null, rule); 93 + Set<Long> results = bpmTaskRuleService.calculateTaskCandidateUsers(null, rule);
81 // 断言 94 // 断言
82 assertEquals(asSet(11L, 22L), results); 95 assertEquals(asSet(11L, 22L), results);
83 } 96 }
@@ -94,7 +107,7 @@ public class BpmUserTaskActivityBehaviorTest extends BaseMockitoUnitTest { @@ -94,7 +107,7 @@ public class BpmUserTaskActivityBehaviorTest extends BaseMockitoUnitTest {
94 mockGetUserMap(asSet(11L, 22L)); 107 mockGetUserMap(asSet(11L, 22L));
95 108
96 // 调用 109 // 调用
97 - Set<Long> results = behavior.calculateTaskCandidateUsers(null, rule); 110 + Set<Long> results = bpmTaskRuleService.calculateTaskCandidateUsers(null, rule);
98 // 断言 111 // 断言
99 assertEquals(asSet(11L, 22L), results); 112 assertEquals(asSet(11L, 22L), results);
100 } 113 }
@@ -111,7 +124,7 @@ public class BpmUserTaskActivityBehaviorTest extends BaseMockitoUnitTest { @@ -111,7 +124,7 @@ public class BpmUserTaskActivityBehaviorTest extends BaseMockitoUnitTest {
111 mockGetUserMap(asSet(11L, 22L)); 124 mockGetUserMap(asSet(11L, 22L));
112 125
113 // 调用 126 // 调用
114 - Set<Long> results = behavior.calculateTaskCandidateUsers(null, rule); 127 + Set<Long> results = bpmTaskRuleService.calculateTaskCandidateUsers(null, rule);
115 // 断言 128 // 断言
116 assertEquals(asSet(11L, 22L), results); 129 assertEquals(asSet(11L, 22L), results);
117 } 130 }
@@ -125,7 +138,7 @@ public class BpmUserTaskActivityBehaviorTest extends BaseMockitoUnitTest { @@ -125,7 +138,7 @@ public class BpmUserTaskActivityBehaviorTest extends BaseMockitoUnitTest {
125 mockGetUserMap(asSet(1L, 2L)); 138 mockGetUserMap(asSet(1L, 2L));
126 139
127 // 调用 140 // 调用
128 - Set<Long> results = behavior.calculateTaskCandidateUsers(null, rule); 141 + Set<Long> results = bpmTaskRuleService.calculateTaskCandidateUsers(null, rule);
129 // 断言 142 // 断言
130 assertEquals(asSet(1L, 2L), results); 143 assertEquals(asSet(1L, 2L), results);
131 } 144 }
@@ -142,7 +155,7 @@ public class BpmUserTaskActivityBehaviorTest extends BaseMockitoUnitTest { @@ -142,7 +155,7 @@ public class BpmUserTaskActivityBehaviorTest extends BaseMockitoUnitTest {
142 mockGetUserMap(asSet(11L, 12L, 21L, 22L)); 155 mockGetUserMap(asSet(11L, 12L, 21L, 22L));
143 156
144 // 调用 157 // 调用
145 - Set<Long> results = behavior.calculateTaskCandidateUsers(null, rule); 158 + Set<Long> results = bpmTaskRuleService.calculateTaskCandidateUsers(null, rule);
146 // 断言 159 // 断言
147 assertEquals(asSet(11L, 12L, 21L, 22L), results); 160 assertEquals(asSet(11L, 12L, 21L, 22L), results);
148 } 161 }
@@ -156,7 +169,7 @@ public class BpmUserTaskActivityBehaviorTest extends BaseMockitoUnitTest { @@ -156,7 +169,7 @@ public class BpmUserTaskActivityBehaviorTest extends BaseMockitoUnitTest {
156 BpmTaskAssignScript script1 = new BpmTaskAssignScript() { 169 BpmTaskAssignScript script1 = new BpmTaskAssignScript() {
157 170
158 @Override 171 @Override
159 - public Set<Long> calculateTaskCandidateUsers(TaskEntity task) { 172 + public Set<Long> calculateTaskCandidateUsers(DelegateExecution task) {
160 return singleton(11L); 173 return singleton(11L);
161 } 174 }
162 175
@@ -168,7 +181,7 @@ public class BpmUserTaskActivityBehaviorTest extends BaseMockitoUnitTest { @@ -168,7 +181,7 @@ public class BpmUserTaskActivityBehaviorTest extends BaseMockitoUnitTest {
168 BpmTaskAssignScript script2 = new BpmTaskAssignScript() { 181 BpmTaskAssignScript script2 = new BpmTaskAssignScript() {
169 182
170 @Override 183 @Override
171 - public Set<Long> calculateTaskCandidateUsers(TaskEntity task) { 184 + public Set<Long> calculateTaskCandidateUsers(DelegateExecution task) {
172 return singleton(22L); 185 return singleton(22L);
173 } 186 }
174 187
@@ -177,11 +190,11 @@ public class BpmUserTaskActivityBehaviorTest extends BaseMockitoUnitTest { @@ -177,11 +190,11 @@ public class BpmUserTaskActivityBehaviorTest extends BaseMockitoUnitTest {
177 return BpmTaskRuleScriptEnum.LEADER_X2; 190 return BpmTaskRuleScriptEnum.LEADER_X2;
178 } 191 }
179 }; 192 };
180 - behavior.setScripts(Arrays.asList(script1, script2)); 193 + bpmTaskRuleService.setScripts(Arrays.asList(script1, script2));
181 mockGetUserMap(asSet(11L, 22L)); 194 mockGetUserMap(asSet(11L, 22L));
182 195
183 // 调用 196 // 调用
184 - Set<Long> results = behavior.calculateTaskCandidateUsers(null, rule); 197 + Set<Long> results = bpmTaskRuleService.calculateTaskCandidateUsers(null, rule);
185 // 断言 198 // 断言
186 assertEquals(asSet(11L, 22L), results); 199 assertEquals(asSet(11L, 22L), results);
187 } 200 }
@@ -200,7 +213,7 @@ public class BpmUserTaskActivityBehaviorTest extends BaseMockitoUnitTest { @@ -200,7 +213,7 @@ public class BpmUserTaskActivityBehaviorTest extends BaseMockitoUnitTest {
200 when(adminUserApi.getUserMap(eq(assigneeUserIds))).thenReturn(userMap); 213 when(adminUserApi.getUserMap(eq(assigneeUserIds))).thenReturn(userMap);
201 214
202 // 调用 215 // 调用
203 - behavior.removeDisableUsers(assigneeUserIds); 216 + bpmTaskRuleService.removeDisableUsers(assigneeUserIds);
204 // 断言 217 // 断言
205 assertEquals(asSet(1L), assigneeUserIds); 218 assertEquals(asSet(1L), assigneeUserIds);
206 } 219 }
yudao-module-bpm/yudao-module-bpm-base/src/test/java/cn/iocoder/yudao/module/bpm/service/definition/BpmUserGroupServiceTest.java renamed to yudao-module-bpm/yudao-module-bpm-biz/src/test/java/cn/iocoder/yudao/module/bpm/service/definition/BpmUserGroupServiceTest.java
yudao-module-bpm/yudao-module-bpm-base/src/test/resources/application-unit-test.yaml renamed to yudao-module-bpm/yudao-module-bpm-biz/src/test/resources/application-unit-test.yaml
@@ -20,8 +20,9 @@ spring: @@ -20,8 +20,9 @@ spring:
20 init: 20 init:
21 schema-locations: classpath:/sql/create_tables.sql 21 schema-locations: classpath:/sql/create_tables.sql
22 22
23 -mybatis: 23 +mybatis-plus:
24 lazy-initialization: true # 单元测试,设置 MyBatis Mapper 延迟加载,加速每个单元测试 24 lazy-initialization: true # 单元测试,设置 MyBatis Mapper 延迟加载,加速每个单元测试
  25 + type-aliases-package: ${yudao.info.base-package}.module.*.dal.dataobject
25 26
26 --- #################### 定时任务相关配置 #################### 27 --- #################### 定时任务相关配置 ####################
27 28
yudao-module-bpm/yudao-module-bpm-base/src/test/resources/logback.xml renamed to yudao-module-bpm/yudao-module-bpm-biz/src/test/resources/logback.xml
yudao-module-bpm/yudao-module-bpm-base/src/test/resources/sql/clean.sql renamed to yudao-module-bpm/yudao-module-bpm-biz/src/test/resources/sql/clean.sql
yudao-module-bpm/yudao-module-bpm-base/src/test/resources/sql/create_tables.sql renamed to yudao-module-bpm/yudao-module-bpm-biz/src/test/resources/sql/create_tables.sql
yudao-server/pom.xml
@@ -54,7 +54,7 @@ @@ -54,7 +54,7 @@
54 <!-- 默认引入 yudao-module-bpm-biz-flowable 实现,可以替换为 yudao-module-bpm-biz-activiti 实现--> 54 <!-- 默认引入 yudao-module-bpm-biz-flowable 实现,可以替换为 yudao-module-bpm-biz-activiti 实现-->
55 <dependency> 55 <dependency>
56 <groupId>cn.iocoder.boot</groupId> 56 <groupId>cn.iocoder.boot</groupId>
57 - <artifactId>yudao-module-bpm-biz-flowable</artifactId> 57 + <artifactId>yudao-module-bpm-biz</artifactId>
58 <version>${revision}</version> 58 <version>${revision}</version>
59 </dependency> 59 </dependency>
60 <!-- <dependency>--> 60 <!-- <dependency>-->
yudao-server/src/main/resources/application.yaml
@@ -32,17 +32,6 @@ spring: @@ -32,17 +32,6 @@ spring:
32 redis: 32 redis:
33 time-to-live: 1h # 设置过期时间为 1 小时 33 time-to-live: 1h # 设置过期时间为 1 小时
34 34
35 - # 工作流 Activiti 配置  
36 - activiti:  
37 - # 1. false: 默认值,activiti启动时,对比数据库表中保存的版本,如果不匹配。将抛出异常  
38 - # 2. true: 启动时会对数据库中所有表进行更新操作,如果表存在,不做处理,反之,自动创建表  
39 - # 3. create_drop: 启动时自动创建表,关闭时自动删除表  
40 - # 4. drop_create: 启动时,删除旧表,再创建新表  
41 - database-schema-update: true # 设置为 false,可通过 sql/activiti.sql 初始化  
42 - db-history-used: true # activiti7 默认 false 不生成历史信息表,需手动设置开启  
43 - check-process-definitions: false # 设置为 false,禁用 /resources/processes 自动部署 BPMN XML 流程  
44 - history-level: full # full:保存历史数据的最高级别,可保存全部流程相关细节,包括流程流转各节点参数  
45 -  
46 # 工作流 Flowable 配置 35 # 工作流 Flowable 配置
47 flowable: 36 flowable:
48 # 1. false: 默认值,Flowable 启动时,对比数据库表中保存的版本,如果不匹配。将抛出异常 37 # 1. false: 默认值,Flowable 启动时,对比数据库表中保存的版本,如果不匹配。将抛出异常
yudao-ui-admin/src/api/bpm/task.js
@@ -39,6 +39,13 @@ export function rejectTask(data) { @@ -39,6 +39,13 @@ export function rejectTask(data) {
39 data: data 39 data: data
40 }) 40 })
41 } 41 }
  42 +export function backTask(data) {
  43 + return request({
  44 + url: '/bpm/task/back',
  45 + method: 'PUT',
  46 + data: data
  47 + })
  48 +}
42 49
43 export function updateTaskAssignee(data) { 50 export function updateTaskAssignee(data) {
44 return request({ 51 return request({
yudao-ui-admin/src/components/bpmnProcessDesigner/package/designer/ProcessDesigner.vue
@@ -118,6 +118,7 @@ export default { @@ -118,6 +118,7 @@ export default {
118 componentName: "MyProcessDesigner", 118 componentName: "MyProcessDesigner",
119 props: { 119 props: {
120 value: String, // xml 字符串 120 value: String, // xml 字符串
  121 + valueWatch: true, // xml 字符串的 watch 状态
121 processId: String, // 流程 key 标识 122 processId: String, // 流程 key 标识
122 processName: String, // 流程 name 名字 123 processName: String, // 流程 name 名字
123 formId: Number, // 流程 form 表单编号 124 formId: Number, // 流程 form 表单编号
@@ -252,11 +253,6 @@ export default { @@ -252,11 +253,6 @@ export default {
252 this.bpmnModeler = null; 253 this.bpmnModeler = null;
253 }); 254 });
254 }, 255 },
255 - watch: {  
256 - value: function (newValue) { // 在 xmlString 发生变化时,重新创建,从而绘制流程图  
257 - this.createNewDiagram(newValue);  
258 - }  
259 - },  
260 methods: { 256 methods: {
261 initBpmnModeler() { 257 initBpmnModeler() {
262 if (this.bpmnModeler) return; 258 if (this.bpmnModeler) return;
@@ -307,7 +303,7 @@ export default { @@ -307,7 +303,7 @@ export default {
307 let newName = this.processName || `业务流程_${new Date().getTime()}`; 303 let newName = this.processName || `业务流程_${new Date().getTime()}`;
308 let xmlString = xml || DefaultEmptyXML(newId, newName, this.prefix); 304 let xmlString = xml || DefaultEmptyXML(newId, newName, this.prefix);
309 try { 305 try {
310 - console.log(this.bpmnModeler.importXML); 306 + // console.log(this.bpmnModeler.importXML);
311 let { warnings } = await this.bpmnModeler.importXML(xmlString); 307 let { warnings } = await this.bpmnModeler.importXML(xmlString);
312 if (warnings && warnings.length) { 308 if (warnings && warnings.length) {
313 warnings.forEach(warn => console.warn(warn)); 309 warnings.forEach(warn => console.warn(warn));
yudao-ui-admin/src/components/bpmnProcessDesigner/package/designer/ProcessViewer.vue
@@ -116,10 +116,11 @@ export default { @@ -116,10 +116,11 @@ export default {
116 let todoActivity = activityList.find(m => !m.endTime) // 找到待办的任务 116 let todoActivity = activityList.find(m => !m.endTime) // 找到待办的任务
117 let endActivity = activityList[activityList.length - 1] // 获得最后一个任务 117 let endActivity = activityList[activityList.length - 1] // 获得最后一个任务
118 // debugger 118 // debugger
119 - console.log(this.bpmnModeler.getDefinitions().rootElements[0].flowElements); 119 + // console.log(this.bpmnModeler.getDefinitions().rootElements[0].flowElements);
120 this.bpmnModeler.getDefinitions().rootElements[0].flowElements?.forEach(n => { 120 this.bpmnModeler.getDefinitions().rootElements[0].flowElements?.forEach(n => {
121 let activity = activityList.find(m => m.key === n.id) // 找到对应的活动 121 let activity = activityList.find(m => m.key === n.id) // 找到对应的活动
122 if (n.$type === 'bpmn:UserTask') { // 用户任务 122 if (n.$type === 'bpmn:UserTask') { // 用户任务
  123 + debugger
123 if (!activity) { 124 if (!activity) {
124 return; 125 return;
125 } 126 }
yudao-ui-admin/src/components/bpmnProcessDesigner/package/penal/base/ElementBaseInfo.vue
@@ -2,6 +2,8 @@ @@ -2,6 +2,8 @@
2 <div class="panel-tab__content"> 2 <div class="panel-tab__content">
3 <el-form size="mini" label-width="90px" :model="model" :rules="rules" @submit.native.prevent> 3 <el-form size="mini" label-width="90px" :model="model" :rules="rules" @submit.native.prevent>
4 <div v-if="elementBaseInfo.$type === 'bpmn:Process'"> <!-- 如果是 Process 信息的时候,使用自定义表单 --> 4 <div v-if="elementBaseInfo.$type === 'bpmn:Process'"> <!-- 如果是 Process 信息的时候,使用自定义表单 -->
  5 + <el-link href="https://doc.iocoder.cn/bpm/#_3-%E6%B5%81%E7%A8%8B%E5%9B%BE%E7%A4%BA%E4%BE%8B"
  6 + type="danger" target="_blank">如何实现实现会签、或签?</el-link>
5 <el-form-item label="流程标识" prop="key"> 7 <el-form-item label="流程标识" prop="key">
6 <el-input v-model="model.key" placeholder="请输入流标标识" 8 <el-input v-model="model.key" placeholder="请输入流标标识"
7 :disabled="model.id !== undefined && model.id.length > 0" @change="handleKeyUpdate" /> 9 :disabled="model.id !== undefined && model.id.length > 0" @change="handleKeyUpdate" />
yudao-ui-admin/src/components/bpmnProcessDesigner/package/penal/flow-condition/FlowCondition.vue
@@ -15,7 +15,7 @@ @@ -15,7 +15,7 @@
15 </el-select> 15 </el-select>
16 </el-form-item> 16 </el-form-item>
17 <el-form-item label="表达式" v-if="flowConditionForm.conditionType && flowConditionForm.conditionType === 'expression'" key="express"> 17 <el-form-item label="表达式" v-if="flowConditionForm.conditionType && flowConditionForm.conditionType === 'expression'" key="express">
18 - <el-input v-model="flowConditionForm.body" clearable @change="updateFlowCondition" /> 18 + <el-input v-model="flowConditionForm.body" style="width:192px;" clearable @change="updateFlowCondition" />
19 </el-form-item> 19 </el-form-item>
20 <template v-if="flowConditionForm.conditionType && flowConditionForm.conditionType === 'script'"> 20 <template v-if="flowConditionForm.conditionType && flowConditionForm.conditionType === 'script'">
21 <el-form-item label="脚本语言" key="language"> 21 <el-form-item label="脚本语言" key="language">
yudao-ui-admin/src/components/bpmnProcessDesigner/package/penal/multi-instance/ElementMultiInstance.vue
@@ -15,7 +15,7 @@ @@ -15,7 +15,7 @@
15 <el-form-item label="循环基数" key="loopCardinality"> 15 <el-form-item label="循环基数" key="loopCardinality">
16 <el-input v-model="loopInstanceForm.loopCardinality" clearable @change="updateLoopCardinality" /> 16 <el-input v-model="loopInstanceForm.loopCardinality" clearable @change="updateLoopCardinality" />
17 </el-form-item> 17 </el-form-item>
18 - <el-form-item label="集合" key="collection"> 18 + <el-form-item label="集合" key="collection" v-show="false">
19 <el-input v-model="loopInstanceForm.collection" clearable @change="updateLoopBase" /> 19 <el-input v-model="loopInstanceForm.collection" clearable @change="updateLoopBase" />
20 </el-form-item> 20 </el-form-item>
21 <el-form-item label="元素变量" key="elementVariable"> 21 <el-form-item label="元素变量" key="elementVariable">
@@ -131,7 +131,7 @@ export default { @@ -131,7 +131,7 @@ export default {
131 if (type === "SequentialMultiInstance") { 131 if (type === "SequentialMultiInstance") {
132 this.multiLoopInstance = window.bpmnInstances.moddle.create("bpmn:MultiInstanceLoopCharacteristics", { isSequential: true }); 132 this.multiLoopInstance = window.bpmnInstances.moddle.create("bpmn:MultiInstanceLoopCharacteristics", { isSequential: true });
133 } else { 133 } else {
134 - this.multiLoopInstance = window.bpmnInstances.moddle.create("bpmn:MultiInstanceLoopCharacteristics"); 134 + this.multiLoopInstance = window.bpmnInstances.moddle.create("bpmn:MultiInstanceLoopCharacteristics", { collection: "${coll_userList}" });
135 } 135 }
136 window.bpmnInstances.modeling.updateProperties(this.bpmnElement, { 136 window.bpmnInstances.modeling.updateProperties(this.bpmnElement, {
137 loopCharacteristics: this.multiLoopInstance 137 loopCharacteristics: this.multiLoopInstance
yudao-ui-admin/src/views/bpm/model/modelEditor.vue
@@ -2,7 +2,7 @@ @@ -2,7 +2,7 @@
2 <div class="app-container"> 2 <div class="app-container">
3 3
4 <!-- 流程设计器,负责绘制流程等 --> 4 <!-- 流程设计器,负责绘制流程等 -->
5 - <my-process-designer :key="`designer-${reloadIndex}`" v-model="xmlString" v-bind="controlForm" 5 + <my-process-designer v-if="xmlString !== undefined" :key="`designer-${reloadIndex}`" v-model="xmlString" v-bind="controlForm"
6 keyboard ref="processDesigner" @init-finished="initModeler" 6 keyboard ref="processDesigner" @init-finished="initModeler"
7 @save="save"/> 7 @save="save"/>
8 8
@@ -30,7 +30,7 @@ export default { @@ -30,7 +30,7 @@ export default {
30 components: { MyProcessPalette }, 30 components: { MyProcessPalette },
31 data() { 31 data() {
32 return { 32 return {
33 - xmlString: "", // BPMN XML 33 + xmlString: undefined, // BPMN XML
34 modeler: null, 34 modeler: null,
35 reloadIndex: 0, 35 reloadIndex: 0,
36 controlDrawerVisible: false, 36 controlDrawerVisible: false,
@@ -72,21 +72,6 @@ export default { @@ -72,21 +72,6 @@ export default {
72 console.log(modeler); 72 console.log(modeler);
73 }, 10); 73 }, 10);
74 }, 74 },
75 - reloadProcessDesigner(deep) {  
76 - this.controlForm.additionalModel = [];  
77 - for (let key in this.addis) {  
78 - if (this.addis[key]) {  
79 - this.controlForm.additionalModel.push(this.addis[key]);  
80 - }  
81 - }  
82 - deep && (this.xmlString = undefined);  
83 - this.reloadIndex += 1;  
84 - this.modeler = null; // 避免 panel 异常  
85 - // if (deep) {  
86 - // this.xmlString = undefined;  
87 - // this.$refs.processDesigner.processRestart();  
88 - // }  
89 - },  
90 save(bpmnXml) { 75 save(bpmnXml) {
91 const data = { 76 const data = {
92 ...this.model, 77 ...this.model,
yudao-ui-admin/src/views/bpm/processInstance/detail.vue
@@ -60,7 +60,7 @@ @@ -60,7 +60,7 @@
60 审批人:{{ item.assigneeUser.nickname }} 60 审批人:{{ item.assigneeUser.nickname }}
61 <el-tag type="info" size="mini">{{ item.assigneeUser.deptName }}</el-tag> 61 <el-tag type="info" size="mini">{{ item.assigneeUser.deptName }}</el-tag>
62 </label> 62 </label>
63 - <label style="font-weight: normal">创建时间:</label> 63 + <label style="font-weight: normal" v-if="item.createTime">创建时间:</label>
64 <label style="color:#8a909c; font-weight: normal">{{ parseTime(item.createTime) }}</label> 64 <label style="color:#8a909c; font-weight: normal">{{ parseTime(item.createTime) }}</label>
65 <label v-if="item.endTime" style="margin-left: 30px;font-weight: normal">审批时间:</label> 65 <label v-if="item.endTime" style="margin-left: 30px;font-weight: normal">审批时间:</label>
66 <label v-if="item.endTime" style="color:#8a909c;font-weight: normal"> {{ parseTime(item.endTime) }}</label> 66 <label v-if="item.endTime" style="color:#8a909c;font-weight: normal"> {{ parseTime(item.endTime) }}</label>
@@ -109,7 +109,7 @@ import store from &quot;@/store&quot;; @@ -109,7 +109,7 @@ import store from &quot;@/store&quot;;
109 import {decodeFields} from "@/utils/formGenerator"; 109 import {decodeFields} from "@/utils/formGenerator";
110 import Parser from '@/components/parser/Parser' 110 import Parser from '@/components/parser/Parser'
111 import {createProcessInstance, getProcessInstance} from "@/api/bpm/processInstance"; 111 import {createProcessInstance, getProcessInstance} from "@/api/bpm/processInstance";
112 -import {approveTask, getTaskListByProcessInstanceId, rejectTask, updateTaskAssignee} from "@/api/bpm/task"; 112 +import {approveTask, getTaskListByProcessInstanceId, rejectTask, updateTaskAssignee,backTask} from "@/api/bpm/task";
113 import {getDate} from "@/utils/dateUtils"; 113 import {getDate} from "@/utils/dateUtils";
114 import {listSimpleUsers} from "@/api/system/user"; 114 import {listSimpleUsers} from "@/api/system/user";
115 import {getActivityList} from "@/api/bpm/activity"; 115 import {getActivityList} from "@/api/bpm/activity";
@@ -232,7 +232,13 @@ export default { @@ -232,7 +232,13 @@ export default {
232 this.auditForms = []; 232 this.auditForms = [];
233 getTaskListByProcessInstanceId(this.id).then(response => { 233 getTaskListByProcessInstanceId(this.id).then(response => {
234 // 审批记录 234 // 审批记录
235 - this.tasks = response.data; 235 + this.tasks = [];
  236 + // 移除已取消的审批
  237 + response.data.forEach(task => {
  238 + if (task.result !== 4) {
  239 + this.tasks.push(task);
  240 + }
  241 + });
236 // 排序,将未完成的排在前面,已完成的排在后面; 242 // 排序,将未完成的排在前面,已完成的排在后面;
237 this.tasks.sort((a, b) => { 243 this.tasks.sort((a, b) => {
238 // 有已完成的情况,按照完成时间倒序 244 // 有已完成的情况,按照完成时间倒序
@@ -407,6 +413,15 @@ export default { @@ -407,6 +413,15 @@ export default {
407 /** 处理审批退回的操作 */ 413 /** 处理审批退回的操作 */
408 handleBack(task) { 414 handleBack(task) {
409 this.$modal.msgError("暂不支持【退回】功能!"); 415 this.$modal.msgError("暂不支持【退回】功能!");
  416 + // 可参考 http://blog.wya1.com/article/636697030/details/7296
  417 + // const data = {
  418 + // id: task.id,
  419 + // assigneeUserId: 1
  420 + // }
  421 + // backTask(data).then(response => {
  422 + // this.$modal.msgSuccess("回退成功!");
  423 + // this.getDetail(); // 获得最新详情
  424 + // });
410 } 425 }
411 } 426 }
412 }; 427 };
yudao-ui-admin/src/views/bpm/taskAssignRule/taskAssignRuleDialog.vue
@@ -53,7 +53,7 @@ @@ -53,7 +53,7 @@
53 <el-option v-for="item in postOptions" :key="parseInt(item.id)" :label="item.name" :value="parseInt(item.id)" /> 53 <el-option v-for="item in postOptions" :key="parseInt(item.id)" :label="item.name" :value="parseInt(item.id)" />
54 </el-select> 54 </el-select>
55 </el-form-item> 55 </el-form-item>
56 - <el-form-item v-if="form.type === 30" label="指定用户" prop="userIds"> 56 + <el-form-item v-if="form.type === 30 || form.type === 31 || form.type === 32" label="指定用户" prop="userIds">
57 <el-select v-model="form.userIds" multiple clearable style="width: 100%"> 57 <el-select v-model="form.userIds" multiple clearable style="width: 100%">
58 <el-option v-for="item in userOptions" :key="parseInt(item.id)" :label="item.nickname" :value="parseInt(item.id)" /> 58 <el-option v-for="item in userOptions" :key="parseInt(item.id)" :label="item.nickname" :value="parseInt(item.id)" />
59 </el-select> 59 </el-select>
@@ -215,7 +215,7 @@ export default { @@ -215,7 +215,7 @@ export default {
215 this.form.deptIds.push(...row.options); 215 this.form.deptIds.push(...row.options);
216 } else if (row.type === 22) { 216 } else if (row.type === 22) {
217 this.form.postIds.push(...row.options); 217 this.form.postIds.push(...row.options);
218 - } else if (row.type === 30) { 218 + } else if (row.type === 30 || row.type === 31 || row.type === 32) {
219 this.form.userIds.push(...row.options); 219 this.form.userIds.push(...row.options);
220 } else if (row.type === 40) { 220 } else if (row.type === 40) {
221 this.form.userGroupIds.push(...row.options); 221 this.form.userGroupIds.push(...row.options);
@@ -240,7 +240,7 @@ export default { @@ -240,7 +240,7 @@ export default {
240 form.options = form.deptIds; 240 form.options = form.deptIds;
241 } else if (form.type === 22) { 241 } else if (form.type === 22) {
242 form.options = form.postIds; 242 form.options = form.postIds;
243 - } else if (form.type === 30) { 243 + } else if (form.type === 30 || form.type === 31 || form.type === 32) {
244 form.options = form.userIds; 244 form.options = form.userIds;
245 } else if (form.type === 40) { 245 } else if (form.type === 40) {
246 form.options = form.userGroupIds; 246 form.options = form.userGroupIds;
@@ -302,7 +302,7 @@ export default { @@ -302,7 +302,7 @@ export default {
302 return postOption.name; 302 return postOption.name;
303 } 303 }
304 } 304 }
305 - } else if (type === 30) { 305 + } else if (type === 30 || type === 31 || type === 32) {
306 for (const userOption of this.userOptions) { 306 for (const userOption of this.userOptions) {
307 if (userOption.id === option) { 307 if (userOption.id === option) {
308 return userOption.nickname; 308 return userOption.nickname;