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

Too many changes.

To preserve performance only 100 of 244 files are displayed.

.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