Commit 26ff75370115bf7edcbde1a497e9a050a213b22f

Authored by YunaiV
1 parent b37a535d

暂时去除回退功能,边界处理不够正确

Showing 38 changed files with 15 additions and 1306 deletions
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.16 | [文档](http://www.iocoder.cn/SpringMVC/MVC/?yudao) | 167 | [Spring MVC](https://github.com/spring-projects/spring-framework/tree/master/spring-webmvc) | MVC 框架 | 5.3.16 | [文档](http://www.iocoder.cn/SpringMVC/MVC/?yudao) |
168 | [Spring Security](https://github.com/spring-projects/spring-security) | Spring 安全框架 | 5.5.5 | [文档](http://www.iocoder.cn/Spring-Boot/Spring-Security/?yudao) | 168 | [Spring Security](https://github.com/spring-projects/spring-security) | Spring 安全框架 | 5.5.5 | [文档](http://www.iocoder.cn/Spring-Boot/Spring-Security/?yudao) |
169 | [Hibernate Validator](https://github.com/hibernate/hibernate-validator) | 参数校验组件 | 6.2.2 | [文档](http://www.iocoder.cn/Spring-Boot/Validation/?yudao) | 169 | [Hibernate Validator](https://github.com/hibernate/hibernate-validator) | 参数校验组件 | 6.2.2 | [文档](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.2 | [文档](http://www.iocoder.cn/Spring-Boot/Swagger/?yudao) | 172 | [Knife4j](https://gitee.com/xiaoym/knife4j) | Swagger 增强 UI 实现 | 3.0.2 | [文档](http://www.iocoder.cn/Spring-Boot/Swagger/?yudao) |
173 | [Resilience4j](https://github.com/resilience4j/resilience4j) | 服务保障组件 | 1.7.0 | [文档](http://www.iocoder.cn/Spring-Boot/Resilience4j/?yudao) | 173 | [Resilience4j](https://github.com/resilience4j/resilience4j) | 服务保障组件 | 1.7.0 | [文档](http://www.iocoder.cn/Spring-Boot/Resilience4j/?yudao) |
yudao-framework/pom.xml
@@ -25,7 +25,6 @@ @@ -25,7 +25,6 @@
25 25
26 <module>yudao-spring-boot-starter-excel</module> 26 <module>yudao-spring-boot-starter-excel</module>
27 <module>yudao-spring-boot-starter-test</module> 27 <module>yudao-spring-boot-starter-test</module>
28 - <module>yudao-spring-boot-starter-extension</module>  
29 28
30 <module>yudao-spring-boot-starter-biz-operatelog</module> 29 <module>yudao-spring-boot-starter-biz-operatelog</module>
31 <module>yudao-spring-boot-starter-biz-dict</module> 30 <module>yudao-spring-boot-starter-biz-dict</module>
yudao-framework/yudao-spring-boot-starter-extension/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 - <artifactId>yudao-framework</artifactId>  
7 - <groupId>cn.iocoder.boot</groupId>  
8 - <version>${revision}</version>  
9 - </parent>  
10 - <modelVersion>4.0.0</modelVersion>  
11 -  
12 - <artifactId>yudao-spring-boot-starter-extension</artifactId>  
13 - <packaging>jar</packaging>  
14 -  
15 - <name>${project.artifactId}</name>  
16 - <description>扩展点组件</description>  
17 - <url>https://github.com/YunaiV/ruoyi-vue-pro</url>  
18 -  
19 - <properties>  
20 -  
21 - </properties>  
22 -  
23 - <dependencies>  
24 - <dependency>  
25 - <groupId>cn.iocoder.boot</groupId>  
26 - <artifactId>yudao-common</artifactId>  
27 - </dependency>  
28 -  
29 - <!-- Spring 核心 -->  
30 - <dependency>  
31 - <groupId>org.springframework</groupId>  
32 - <artifactId>spring-context</artifactId>  
33 - <scope>provided</scope>  
34 - </dependency>  
35 -  
36 - <dependency>  
37 - <groupId>org.springframework</groupId>  
38 - <artifactId>spring-beans</artifactId>  
39 - <scope>provided</scope>  
40 - </dependency>  
41 -  
42 - <!-- Spring 核心 -->  
43 - <dependency>  
44 - <groupId>org.springframework.boot</groupId>  
45 - <artifactId>spring-boot-starter-aop</artifactId>  
46 - </dependency>  
47 -  
48 - <!-- 测试包 -->  
49 - <dependency>  
50 - <groupId>org.springframework.boot</groupId>  
51 - <artifactId>spring-boot-starter-test</artifactId>  
52 - <scope>test</scope>  
53 - </dependency>  
54 -  
55 - <!-- 测试包 -->  
56 - <dependency>  
57 - <groupId>junit</groupId>  
58 - <artifactId>junit</artifactId>  
59 - <scope>test</scope>  
60 - </dependency>  
61 -  
62 - <!-- 工具类相关 -->  
63 - <dependency>  
64 - <groupId>jakarta.validation</groupId>  
65 - <artifactId>jakarta.validation-api</artifactId>  
66 - </dependency>  
67 - </dependencies>  
68 -</project>  
69 \ No newline at end of file 0 \ No newline at end of file
yudao-framework/yudao-spring-boot-starter-extension/src/main/java/cn/iocoder/yudao/framework/extension/config/YudaoExtensionAutoConfiguration.java deleted
1 -package cn.iocoder.yudao.framework.extension.config;  
2 -  
3 -import cn.iocoder.yudao.framework.extension.core.ExtensionBootstrap;  
4 -import cn.iocoder.yudao.framework.extension.core.context.ExtensionContext;  
5 -import cn.iocoder.yudao.framework.extension.core.context.ExtensionContextHolder;  
6 -import cn.iocoder.yudao.framework.extension.core.context.ExtensionExecutor;  
7 -import cn.iocoder.yudao.framework.extension.core.factory.ExtensionFactory;  
8 -import cn.iocoder.yudao.framework.extension.core.factory.ExtensionRegisterFactory;  
9 -import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;  
10 -import org.springframework.context.annotation.Bean;  
11 -import org.springframework.context.annotation.Configuration;  
12 -  
13 -/**  
14 - * @description 扩展点组件自动装配  
15 - * @author Qingchen  
16 - * @version 1.0.0  
17 - * @date 2021-08-28 21:50  
18 - * @class cn.iocoder.yudao.framework.extension.config.YudaoExtensionAutoConfiguration.java  
19 - */  
20 -@Configuration  
21 -public class YudaoExtensionAutoConfiguration {  
22 -  
23 - /**  
24 - * 组件初始化  
25 - * @return  
26 - */  
27 - @Bean(initMethod = "init")  
28 - @ConditionalOnMissingBean(ExtensionBootstrap.class)  
29 - public ExtensionBootstrap bootstrap() {  
30 - return new ExtensionBootstrap();  
31 - }  
32 -  
33 - /**  
34 - * 扩展点工厂  
35 - * @return  
36 - */  
37 - @Bean  
38 - @ConditionalOnMissingBean({ExtensionRegisterFactory.class, ExtensionFactory.class})  
39 - public ExtensionRegisterFactory registerFactory() {  
40 - return new ExtensionRegisterFactory();  
41 - }  
42 -  
43 - /**  
44 - * 扩展组件上下文对象  
45 - * @return  
46 - */  
47 - @Bean  
48 - @ConditionalOnMissingBean({ExtensionContextHolder.class, ExtensionContext.class})  
49 - public ExtensionContextHolder context() {  
50 - return new ExtensionContextHolder();  
51 - }  
52 -  
53 - /**  
54 - * 扩展组件执行器  
55 - * @return  
56 - */  
57 - @Bean  
58 - @ConditionalOnMissingBean(ExtensionExecutor.class)  
59 - public ExtensionExecutor executor() {  
60 - return new ExtensionExecutor();  
61 - }  
62 -}  
yudao-framework/yudao-spring-boot-starter-extension/src/main/java/cn/iocoder/yudao/framework/extension/core/BusinessScenario.java deleted
1 -package cn.iocoder.yudao.framework.extension.core;  
2 -  
3 -import javax.validation.constraints.NotNull;  
4 -import java.io.Serializable;  
5 -import java.util.StringJoiner;  
6 -  
7 -/**  
8 - * @description 业务场景 = businessId + useCase + scenario, 用来标识系统中唯一的一个场景<br/>  
9 - * @author Qingchen  
10 - * @version 1.0.0  
11 - * @date 2021-08-28 22:19  
12 - * @class cn.iocoder.yudao.framework.extension.core.BusinessScenario.java  
13 - */  
14 -public class BusinessScenario implements Serializable {  
15 -  
16 - /**  
17 - * 默认业务id  
18 - */  
19 - public final static String DEFAULT_BUSINESS_ID = "#defaultBusinessId#";  
20 -  
21 - /**  
22 - * 默认用例  
23 - */  
24 - public final static String DEFAULT_USECASE = "#defaultUseCase#";  
25 -  
26 - /**  
27 - * 默认场景  
28 - */  
29 - public final static String DEFAULT_SCENARIO = "#defaultScenario#";  
30 -  
31 - /**  
32 - * 分隔符  
33 - */  
34 - private final static String DOT_SEPARATOR = ".";  
35 -  
36 - /**  
37 - * 业务Id  
38 - */  
39 - private String businessId;  
40 -  
41 - /**  
42 - * 用例  
43 - */  
44 - private String useCase;  
45 -  
46 - /**  
47 - * 场景  
48 - */  
49 - private String scenario;  
50 -  
51 - public BusinessScenario() {  
52 - this.businessId = DEFAULT_BUSINESS_ID;  
53 - this.useCase = DEFAULT_USECASE;  
54 - this.scenario = DEFAULT_SCENARIO;  
55 - }  
56 -  
57 - public BusinessScenario(@NotNull String businessId, @NotNull String useCase, @NotNull String scenario) {  
58 - this.businessId = businessId;  
59 - this.useCase = useCase;  
60 - this.scenario = scenario;  
61 - }  
62 -  
63 - public BusinessScenario(@NotNull String scenario) {  
64 - this();  
65 - this.scenario = scenario;  
66 - }  
67 -  
68 - public BusinessScenario(@NotNull String useCase, @NotNull String scenario) {  
69 - this(DEFAULT_BUSINESS_ID, useCase, scenario);  
70 - }  
71 -  
72 - public String getBusinessId() {  
73 - return businessId;  
74 - }  
75 -  
76 - public void setBusinessId(String businessId) {  
77 - this.businessId = businessId;  
78 - }  
79 -  
80 - public String getUseCase() {  
81 - return useCase;  
82 - }  
83 -  
84 - public void setUseCase(String useCase) {  
85 - this.useCase = useCase;  
86 - }  
87 -  
88 - public String getScenario() {  
89 - return scenario;  
90 - }  
91 -  
92 - public void setScenario(String scenario) {  
93 - this.scenario = scenario;  
94 - }  
95 -  
96 - /**  
97 - * 构建业务场景  
98 - * @param businessId  
99 - * @param useCase  
100 - * @param scenario  
101 - * @return  
102 - */  
103 - public static BusinessScenario valueOf(@NotNull String businessId, @NotNull String useCase, @NotNull String scenario) {  
104 - return new BusinessScenario(businessId, useCase, scenario);  
105 - }  
106 -  
107 - /**  
108 - * 构建业务场景  
109 - * @param useCase  
110 - * @param scenario  
111 - * @return  
112 - */  
113 - public static BusinessScenario valueOf(@NotNull String useCase, @NotNull String scenario) {  
114 - return new BusinessScenario(useCase, scenario);  
115 - }  
116 -  
117 - /**  
118 - * 构建业务场景  
119 - * @param scenario  
120 - * @return  
121 - */  
122 - public static BusinessScenario valueOf(@NotNull String scenario) {  
123 - return new BusinessScenario(scenario);  
124 - }  
125 -  
126 - /**  
127 - * 业务场景唯一标识  
128 - * @return  
129 - */  
130 - public String getUniqueIdentity(){  
131 - return new StringJoiner(DOT_SEPARATOR).add(businessId).add(useCase).add(scenario).toString();  
132 - }  
133 -  
134 - @Override  
135 - public String toString() {  
136 - return "BusinessScenario{" +  
137 - "businessId='" + businessId + '\'' +  
138 - ", useCase='" + useCase + '\'' +  
139 - ", scenario='" + scenario + '\'' +  
140 - '}';  
141 - }  
142 -}  
yudao-framework/yudao-spring-boot-starter-extension/src/main/java/cn/iocoder/yudao/framework/extension/core/ExtensionBootstrap.java deleted
1 -package cn.iocoder.yudao.framework.extension.core;  
2 -  
3 -import cn.iocoder.yudao.framework.extension.core.factory.ExtensionRegisterFactory;  
4 -import org.springframework.beans.BeansException;  
5 -import org.springframework.beans.factory.annotation.Autowired;  
6 -import org.springframework.context.ApplicationContext;  
7 -import org.springframework.context.ApplicationContextAware;  
8 -  
9 -import javax.annotation.PostConstruct;  
10 -  
11 -/**  
12 - * @description  
13 - * @author Qingchen  
14 - * @version 1.0.0  
15 - * @date 2021-08-29 00:18  
16 - * @class cn.iocoder.yudao.framework.extension.core.ExtensionBootstrap.java  
17 - */  
18 -public class ExtensionBootstrap implements ApplicationContextAware {  
19 -  
20 - /**  
21 - * spring 容器  
22 - */  
23 - private ApplicationContext applicationContext;  
24 -  
25 - @Autowired  
26 - private ExtensionRegisterFactory registerFactory;  
27 -  
28 - /**  
29 - * 初始化  
30 - */  
31 - @PostConstruct  
32 - public void init() {  
33 - registerFactory.setApplicationContext(applicationContext);  
34 - registerFactory.register(null);  
35 - }  
36 -  
37 - @Override  
38 - public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {  
39 - this.applicationContext = applicationContext;  
40 - }  
41 -}  
yudao-framework/yudao-spring-boot-starter-extension/src/main/java/cn/iocoder/yudao/framework/extension/core/context/AbstractComponentExecutor.java deleted
1 -package cn.iocoder.yudao.framework.extension.core.context;  
2 -  
3 -import cn.iocoder.yudao.framework.extension.core.BusinessScenario;  
4 -import cn.iocoder.yudao.framework.extension.core.point.ExtensionPoint;  
5 -  
6 -import java.util.function.Consumer;  
7 -import java.util.function.Function;  
8 -  
9 -/**  
10 - * @description 执行器通用方法  
11 - * @author Qingchen  
12 - * @version 1.0.0  
13 - * @date 2021-08-29 00:38  
14 - * @class cn.iocoder.yudao.framework.extension.core.context.AbstractComponentExecutor.java  
15 - */  
16 -public abstract class AbstractComponentExecutor {  
17 -  
18 - /**  
19 - * ("业务" + "用例" + "场景")执行扩展组件,并返回执行结果  
20 - * @param targetClazz  
21 - * @param businessId  
22 - * @param useCase  
23 - * @param scenario  
24 - * @param function  
25 - * @param <R>  
26 - * @param <T>  
27 - * @return  
28 - */  
29 - public <R, T extends ExtensionPoint> R execute(Class<T> targetClazz, String businessId, String useCase, String scenario, Function<T, R> function) {  
30 - return execute(targetClazz, BusinessScenario.valueOf(businessId, useCase, scenario), function);  
31 - }  
32 -  
33 -  
34 - /**  
35 - * ("用例" + "场景")执行扩展组件,并返回执行结果  
36 - * @param targetClazz  
37 - * @param useCase  
38 - * @param scenario  
39 - * @param function  
40 - * @param <R>  
41 - * @param <T>  
42 - * @return  
43 - */  
44 - public <R, T extends ExtensionPoint> R execute(Class<T> targetClazz, String useCase, String scenario, Function<T, R> function) {  
45 - return execute(targetClazz, BusinessScenario.valueOf(useCase, scenario), function);  
46 - }  
47 -  
48 - /**  
49 - * ("场景")执行扩展组件,并返回执行结果  
50 - * @param targetClazz  
51 - * @param scenario  
52 - * @param function  
53 - * @param <R>  
54 - * @param <T>  
55 - * @return  
56 - */  
57 - public <R, T extends ExtensionPoint> R execute(Class<T> targetClazz, String scenario, Function<T, R> function) {  
58 - return execute(targetClazz, BusinessScenario.valueOf(scenario), function);  
59 - }  
60 -  
61 - /**  
62 - * 执行扩展组件,并返回执行结果  
63 - * @param targetClazz  
64 - * @param businessScenario  
65 - * @param function  
66 - * @param <R> Response Type  
67 - * @param <T> Parameter Type  
68 - * @return  
69 - */  
70 - public <R, T extends ExtensionPoint> R execute(Class<T> targetClazz, BusinessScenario businessScenario, Function<T, R> function) {  
71 - T component = locateComponent(targetClazz, businessScenario);  
72 - return function.apply(component);  
73 - }  
74 -  
75 - /**  
76 - * ("业务" + "用例" + "场景")执行扩展组件,适用于无返回值的业务  
77 - * @param targetClazz  
78 - * @param businessId  
79 - * @param useCase  
80 - * @param scenario  
81 - * @param consumer  
82 - * @param <T>  
83 - */  
84 - public <T extends ExtensionPoint> void accept(Class<T> targetClazz, String businessId, String useCase, String scenario, Consumer<T> consumer) {  
85 - accept(targetClazz, BusinessScenario.valueOf(businessId, useCase, scenario), consumer);  
86 - }  
87 -  
88 - /**  
89 - * ("场景")执行扩展组件,适用于无返回值的业务  
90 - * @param targetClazz  
91 - * @param useCase  
92 - * @param scenario  
93 - * @param consumer  
94 - * @param <T>  
95 - */  
96 - public <T extends ExtensionPoint> void accept(Class<T> targetClazz, String useCase, String scenario, Consumer<T> consumer) {  
97 - accept(targetClazz, BusinessScenario.valueOf(useCase, scenario), consumer);  
98 - }  
99 -  
100 - /**  
101 - * ("场景")执行扩展组件,适用于无返回值的业务  
102 - * @param targetClazz  
103 - * @param scenario  
104 - * @param consumer  
105 - * @param <T>  
106 - */  
107 - public <T extends ExtensionPoint> void accept(Class<T> targetClazz, String scenario, Consumer<T> consumer) {  
108 - accept(targetClazz, BusinessScenario.valueOf(scenario), consumer);  
109 - }  
110 -  
111 - /**  
112 - * 执行扩展组件,适用于无返回值的业务  
113 - * @param targetClazz  
114 - * @param businessScenario  
115 - * @param consumer  
116 - * @param <T> Parameter Type  
117 - */  
118 - public <T extends ExtensionPoint> void accept(Class<T> targetClazz, BusinessScenario businessScenario, Consumer<T> consumer) {  
119 - T component = locateComponent(targetClazz, businessScenario);  
120 - consumer.accept(component);  
121 - }  
122 -  
123 - /**  
124 - * 获取/定位扩展点组件  
125 - * @param targetClazz  
126 - * @param businessScenario  
127 - * @param <C>  
128 - * @return  
129 - */  
130 - protected abstract <C extends ExtensionPoint> C locateComponent(Class<C> targetClazz, BusinessScenario businessScenario);  
131 -}  
yudao-framework/yudao-spring-boot-starter-extension/src/main/java/cn/iocoder/yudao/framework/extension/core/context/ExtensionContext.java deleted
1 -package cn.iocoder.yudao.framework.extension.core.context;  
2 -  
3 -import cn.iocoder.yudao.framework.extension.core.BusinessScenario;  
4 -import cn.iocoder.yudao.framework.extension.core.point.ExtensionPoint;  
5 -  
6 -/**  
7 - * @description 上下文,包含各个扩展点的相关操作  
8 - * @author Qingchen  
9 - * @version 1.0.0  
10 - * @date 2021-08-28 22:15  
11 - * @class cn.iocoder.yudao.framework.extension.core.context.ExtensionContext.java  
12 - */  
13 -public interface ExtensionContext {  
14 -  
15 - /**  
16 - * 根据业务场景唯一标识获取扩展点组件实现类  
17 - * @param businessId  
18 - * @param useCase  
19 - * @param scenario  
20 - * @param clazz  
21 - * @param <T>  
22 - * @return  
23 - */  
24 - <T extends ExtensionPoint> T getPoint(String businessId, String useCase, String scenario, Class<T> clazz);  
25 -  
26 - /**  
27 - * 根据("实例" + "场景")获取扩展点组件实现类,其中:业务id(businessId)= {@linkplain cn.iocoder.yudao.framework.extension.core.BusinessScenario.DEFAULT_BUSINESS_ID}  
28 - * @param useCase  
29 - * @param scenario  
30 - * @param clazz  
31 - * @param <T>  
32 - * @return  
33 - */  
34 - <T extends ExtensionPoint> T getPoint(String useCase, String scenario, Class<T> clazz);  
35 -  
36 - /**  
37 - * 根据("场景")获取扩展点组件实现类 <br/>  
38 - * 其中:  
39 - * 业务id(businessId)= {@linkplain cn.iocoder.yudao.framework.extension.core.BusinessScenario.DEFAULT_BUSINESS_ID}  
40 - * 实例(useCase)= {@linkplain cn.iocoder.yudao.framework.extension.core.BusinessScenario.DEFAULT_USECASE}  
41 - * @param scenario  
42 - * @param clazz  
43 - * @param <T>  
44 - * @return  
45 - */  
46 - <T extends ExtensionPoint> T getPoint(String scenario, Class<T> clazz);  
47 -  
48 - /**  
49 - * 根据业务场景唯一标识获取扩展点组件实现类  
50 - * @param businessScenario  
51 - * @param clazz  
52 - * @param <T>  
53 - * @return  
54 - */  
55 - <T extends ExtensionPoint> T getPoint(BusinessScenario businessScenario, Class<T> clazz);  
56 -}  
yudao-framework/yudao-spring-boot-starter-extension/src/main/java/cn/iocoder/yudao/framework/extension/core/context/ExtensionContextHolder.java deleted
1 -package cn.iocoder.yudao.framework.extension.core.context;  
2 -  
3 -import cn.iocoder.yudao.framework.extension.core.BusinessScenario;  
4 -import cn.iocoder.yudao.framework.extension.core.factory.ExtensionFactory;  
5 -import cn.iocoder.yudao.framework.extension.core.point.ExtensionPoint;  
6 -import lombok.extern.slf4j.Slf4j;  
7 -import org.springframework.beans.factory.annotation.Autowired;  
8 -import org.springframework.stereotype.Component;  
9 -  
10 -import javax.validation.constraints.NotNull;  
11 -  
12 -/**  
13 - * @description 上下文及扩展点组件工厂的持有类  
14 - * @author Qingchen  
15 - * @version 1.0.0  
16 - * @date 2021-08-29 00:29  
17 - * @class cn.iocoder.yudao.framework.extension.core.context.ExtensionContextHolder.java  
18 - */  
19 -@Component  
20 -@Slf4j  
21 -public class ExtensionContextHolder implements ExtensionContext{  
22 -  
23 - @Autowired  
24 - private ExtensionFactory factory;  
25 -  
26 - @Override  
27 - public <T extends ExtensionPoint> T getPoint(@NotNull String businessId, @NotNull String useCase, @NotNull String scenario, Class<T> clazz) {  
28 - return getPoint(BusinessScenario.valueOf(businessId, useCase, scenario), clazz);  
29 - }  
30 -  
31 - @Override  
32 - public <T extends ExtensionPoint> T getPoint(@NotNull String useCase, String scenario, Class<T> clazz) {  
33 - return getPoint(BusinessScenario.valueOf(useCase, scenario), clazz);  
34 - }  
35 -  
36 - @Override  
37 - public <T extends ExtensionPoint> T getPoint(@NotNull String scenario, Class<T> clazz) {  
38 - return getPoint(BusinessScenario.valueOf(scenario), clazz);  
39 - }  
40 -  
41 - @Override  
42 - public <T extends ExtensionPoint> T getPoint(@NotNull BusinessScenario businessScenario, Class<T> clazz) {  
43 - return factory.get(businessScenario, clazz);  
44 - }  
45 -}  
yudao-framework/yudao-spring-boot-starter-extension/src/main/java/cn/iocoder/yudao/framework/extension/core/context/ExtensionExecutor.java deleted
1 -package cn.iocoder.yudao.framework.extension.core.context;  
2 -  
3 -import cn.iocoder.yudao.framework.extension.core.BusinessScenario;  
4 -import cn.iocoder.yudao.framework.extension.core.point.ExtensionPoint;  
5 -import lombok.extern.slf4j.Slf4j;  
6 -import org.springframework.beans.factory.annotation.Autowired;  
7 -import org.springframework.stereotype.Component;  
8 -  
9 -/**  
10 - * @description 扩展组件执行器  
11 - * @author Qingchen  
12 - * @version 1.0.0  
13 - * @date 2021-08-29 00:32  
14 - * @class cn.iocoder.yudao.framework.extension.core.context.ExtensionExecutor.java  
15 - */  
16 -@Component  
17 -@Slf4j  
18 -public class ExtensionExecutor extends AbstractComponentExecutor{  
19 -  
20 - @Autowired  
21 - private ExtensionContextHolder contextHolder;  
22 -  
23 -  
24 - @Override  
25 - protected <C extends ExtensionPoint> C locateComponent(Class<C> targetClazz, BusinessScenario businessScenario) {  
26 - return contextHolder.getPoint(businessScenario, targetClazz);  
27 - }  
28 -}  
yudao-framework/yudao-spring-boot-starter-extension/src/main/java/cn/iocoder/yudao/framework/extension/core/factory/ExtensionDefinition.java deleted
1 -package cn.iocoder.yudao.framework.extension.core.factory;  
2 -  
3 -import cn.iocoder.yudao.framework.extension.core.BusinessScenario;  
4 -import cn.iocoder.yudao.framework.extension.core.point.ExtensionPoint;  
5 -import lombok.Getter;  
6 -import lombok.Setter;  
7 -  
8 -import javax.validation.constraints.NotNull;  
9 -import java.io.Serializable;  
10 -import java.util.Objects;  
11 -  
12 -/**  
13 - * @description 扩展定义(扩展坐标),标识唯一一个业务场景实现  
14 - * @author Qingchen  
15 - * @version 1.0.0  
16 - * @date 2021-08-28 23:14  
17 - * @class cn.iocoder.yudao.framework.extension.core.factory.ExtensionDefinition.java  
18 - */  
19 -@Setter  
20 -@Getter  
21 -public class ExtensionDefinition implements Serializable {  
22 -  
23 - /**  
24 - * 业务场景唯一标识(id)  
25 - */  
26 - private String uniqueIdentify;  
27 -  
28 - /**  
29 - * 扩展点实现类名称  
30 - */  
31 - private String extensionPointName;  
32 -  
33 - /**  
34 - * 业务场景  
35 - */  
36 - private BusinessScenario businessScenario;  
37 -  
38 - /**  
39 - * 扩展点实现类  
40 - */  
41 - private ExtensionPoint extensionPoint;  
42 -  
43 - /**  
44 - * class  
45 - */  
46 - private Class extensionPointClass;  
47 -  
48 - public ExtensionDefinition() {  
49 - }  
50 -  
51 - public ExtensionDefinition(@NotNull BusinessScenario businessScenario, @NotNull ExtensionPoint extensionPoint) {  
52 - this.businessScenario = businessScenario;  
53 - this.extensionPoint = extensionPoint;  
54 - this.uniqueIdentify = this.businessScenario.getUniqueIdentity();  
55 - this.extensionPointClass = this.extensionPoint.getClass();  
56 - }  
57 -  
58 - /**  
59 - * 构建definition  
60 - * @param businessScenario  
61 - * @param point  
62 - * @return  
63 - */  
64 - public static ExtensionDefinition valueOf(@NotNull BusinessScenario businessScenario, @NotNull ExtensionPoint point) {  
65 - return new ExtensionDefinition(businessScenario, point);  
66 - }  
67 -  
68 - @Override  
69 - public boolean equals(Object o) {  
70 - if (this == o) {  
71 - return true;  
72 - }  
73 - if (o == null || getClass() != o.getClass()) {  
74 - return false;  
75 - }  
76 - ExtensionDefinition that = (ExtensionDefinition) o;  
77 - return Objects.equals(uniqueIdentify, that.uniqueIdentify) && Objects.equals(extensionPointName, that.extensionPointName);  
78 - }  
79 -  
80 - @Override  
81 - public int hashCode() {  
82 - final int prime = 31;  
83 - int result = 1;  
84 - result = prime * result + ((uniqueIdentify == null) ? 0 : uniqueIdentify.hashCode());  
85 - result = prime * result + ((extensionPointName == null) ? 0 : extensionPointName.hashCode());  
86 - return result;  
87 - }  
88 -  
89 - @Override  
90 - public String toString() {  
91 - return "ExtensionDefinition{" +  
92 - "uniqueIdentify='" + uniqueIdentify + '\'' +  
93 - ", extensionPointName='" + extensionPointName + '\'' +  
94 - '}';  
95 - }  
96 -}  
yudao-framework/yudao-spring-boot-starter-extension/src/main/java/cn/iocoder/yudao/framework/extension/core/factory/ExtensionFactory.java deleted
1 -package cn.iocoder.yudao.framework.extension.core.factory;  
2 -  
3 -import cn.iocoder.yudao.framework.extension.core.BusinessScenario;  
4 -import cn.iocoder.yudao.framework.extension.core.point.ExtensionPoint;  
5 -  
6 -/**  
7 - * @description 扩展点工厂  
8 - * @author Qingchen  
9 - * @version 1.0.0  
10 - * @date 2021-08-28 23:04  
11 - * @class cn.iocoder.yudao.framework.extension.core.factory.ExtensionFactory.java  
12 - */  
13 -public interface ExtensionFactory {  
14 -  
15 - /**  
16 - * 注册所有扩展点实现类  
17 - * @param basePackage  
18 - */  
19 - void register(String basePackage);  
20 -  
21 - /**  
22 - * 根据业务场景获取指定类型的扩展点  
23 - * @param businessScenario  
24 - * @param clazz  
25 - * @param <T>  
26 - * @return  
27 - */  
28 - <T extends ExtensionPoint> T get(BusinessScenario businessScenario, Class<T> clazz);  
29 -}  
yudao-framework/yudao-spring-boot-starter-extension/src/main/java/cn/iocoder/yudao/framework/extension/core/factory/ExtensionRegisterFactory.java deleted
1 -package cn.iocoder.yudao.framework.extension.core.factory;  
2 -  
3 -import cn.iocoder.yudao.framework.extension.core.BusinessScenario;  
4 -import cn.iocoder.yudao.framework.extension.core.point.ExtensionPoint;  
5 -import cn.iocoder.yudao.framework.extension.core.stereotype.Extension;  
6 -import lombok.extern.slf4j.Slf4j;  
7 -import org.springframework.aop.support.AopUtils;  
8 -import org.springframework.context.ApplicationContext;  
9 -import org.springframework.core.annotation.AnnotationUtils;  
10 -import org.springframework.stereotype.Component;  
11 -import org.springframework.util.ClassUtils;  
12 -  
13 -import javax.validation.constraints.NotNull;  
14 -import java.util.Map;  
15 -import java.util.concurrent.ConcurrentHashMap;  
16 -  
17 -/**  
18 - * @description 注册工厂  
19 - * @author Qingchen  
20 - * @version 1.0.0  
21 - * @date 2021-08-28 23:07  
22 - * @class cn.iocoder.yudao.framework.extension.core.factory.ExtensionRegisterFactory.java  
23 - */  
24 -@Component  
25 -@Slf4j  
26 -public class ExtensionRegisterFactory implements ExtensionFactory {  
27 -  
28 - /**  
29 - * spring ApplicationContext  
30 - */  
31 - private ApplicationContext applicationContext;  
32 -  
33 - /**  
34 - * 扩展点实现类集合  
35 - */  
36 - private Map<String, ExtensionDefinition> registerExtensionBeans = new ConcurrentHashMap<>();  
37 -  
38 - @Override  
39 - public void register(String basePackage) {  
40 - final Map<String, Object> beans = applicationContext.getBeansWithAnnotation(Extension.class);  
41 - if(beans == null || beans.isEmpty()) {  
42 - return;  
43 - }  
44 -  
45 - beans.values().forEach(point -> doRegister((ExtensionPoint) point));  
46 - log.info("业务场景相关扩展点注册完成,注册数量: {}", registerExtensionBeans.size());  
47 - }  
48 -  
49 - @Override  
50 - public <T extends ExtensionPoint> T get(BusinessScenario businessScenario, Class<T> clazz) {  
51 -  
52 - final ExtensionDefinition definition = registerExtensionBeans.get(businessScenario.getUniqueIdentity());  
53 - if(definition == null) {  
54 - log.error("获取业务场景扩展点实现失败,失败原因:尚未定义该业务场景相关扩展点。{}", businessScenario);  
55 - throw new RuntimeException("尚未定义该业务场景相关扩展点 [" + businessScenario + "]");  
56 - }  
57 -  
58 - return (T) definition.getExtensionPoint();  
59 - }  
60 -  
61 - /**  
62 - * 注册扩展点  
63 - * @param point  
64 - */  
65 - private void doRegister(@NotNull ExtensionPoint point) {  
66 - Class<?> extensionClazz = point.getClass();  
67 -  
68 - if (AopUtils.isAopProxy(point)) {  
69 - extensionClazz = ClassUtils.getUserClass(point);  
70 - }  
71 -  
72 - Extension extension = AnnotationUtils.findAnnotation(extensionClazz, Extension.class);  
73 - final BusinessScenario businessScenario = BusinessScenario.valueOf(extension.businessId(), extension.useCase(), extension.scenario());  
74 - final ExtensionDefinition definition = ExtensionDefinition.valueOf(businessScenario, point);  
75 - final ExtensionDefinition exist = registerExtensionBeans.get(businessScenario.getUniqueIdentity());  
76 - if(exist != null && !exist.equals(definition)) {  
77 - throw new RuntimeException("相同的业务场景重复注册了不同类型的扩展点实现 :【" + definition + "】【" + exist + "】");  
78 - }  
79 -  
80 - registerExtensionBeans.put(businessScenario.getUniqueIdentity(), definition);  
81 - }  
82 -  
83 - public void setApplicationContext(ApplicationContext applicationContext) {  
84 - this.applicationContext = applicationContext;  
85 - }  
86 -}  
yudao-framework/yudao-spring-boot-starter-extension/src/main/java/cn/iocoder/yudao/framework/extension/core/package-info.java deleted
1 -/**  
2 - * @description core 核心  
3 - * @author Qingchen  
4 - * @version 1.0.0  
5 - * @date 2021-08-28 21:54  
6 - * @class cn.iocoder.yudao.framework.extension.core.package-info.java  
7 - */  
8 -package cn.iocoder.yudao.framework.extension.core;  
9 \ No newline at end of file 0 \ No newline at end of file
yudao-framework/yudao-spring-boot-starter-extension/src/main/java/cn/iocoder/yudao/framework/extension/core/point/ExtensionPoint.java deleted
1 -package cn.iocoder.yudao.framework.extension.core.point;  
2 -/**  
3 - * @description 扩展点 <br/>  
4 - * 表示一块逻辑在不同的业务有不同的实现,使用扩展点做接口申明,然后用{@linkplain cn.iocoder.yudao.framework.extension.core.stereotype.Extension}(扩展)去实现扩展点。  
5 - * @author Qingchen  
6 - * @version 1.0.0  
7 - * @date 2021-08-28 22:06  
8 - * @class cn.iocoder.yudao.framework.extension.core.point.ExtensionPoint.java  
9 - */  
10 -public interface ExtensionPoint {  
11 -}  
yudao-framework/yudao-spring-boot-starter-extension/src/main/java/cn/iocoder/yudao/framework/extension/core/stereotype/Extension.java deleted
1 -package cn.iocoder.yudao.framework.extension.core.stereotype;  
2 -  
3 -import cn.iocoder.yudao.framework.extension.core.BusinessScenario;  
4 -import org.springframework.stereotype.Component;  
5 -  
6 -import java.lang.annotation.*;  
7 -  
8 -/**  
9 - * @description 表示带注释的类是“扩展组件”  
10 - * @author Qingchen  
11 - * @version 1.0.0  
12 - * @date 2021-08-28 21:59  
13 - * @class cn.iocoder.yudao.framework.extension.core.stereotype.Extension.java  
14 - */  
15 -@Inherited  
16 -@Retention(RetentionPolicy.RUNTIME)  
17 -@Target({ElementType.TYPE})  
18 -@Component  
19 -public @interface Extension {  
20 -  
21 - /**  
22 - * 业务 <br/>  
23 - * 一个自负盈亏的财务主体,比如tmall、淘宝和零售通就是三个不同的业务  
24 - * @return  
25 - */  
26 - String businessId() default BusinessScenario.DEFAULT_BUSINESS_ID;  
27 -  
28 - /**  
29 - * 用例 <br/>  
30 - * 描述了用户和系统之间的互动,每个用例提供了一个或多个场景。比如,支付订单就是一个典型的用例。  
31 - * @return  
32 - */  
33 - String useCase() default BusinessScenario.DEFAULT_USECASE;  
34 -  
35 - /**  
36 - * 场景 <br/>  
37 - * 场景也被称为用例的实例(Instance),包括用例所有的可能情况(正常的和异常的)。比如对于"订单支付"这个用例,就有“支付宝支付”、“银行卡支付”、"微信支付"等多个场景  
38 - * @return  
39 - */  
40 - String scenario() default BusinessScenario.DEFAULT_SCENARIO;  
41 -}  
yudao-framework/yudao-spring-boot-starter-extension/src/main/java/cn/iocoder/yudao/framework/extension/package-info.java deleted
1 -/**  
2 - * @description 扩展点组件  
3 - * @author Qingchen  
4 - * @version 1.0.0  
5 - * @date 2021-08-28 14:35  
6 - * @class cn.iocoder.yudao.framework.extension.package-info.java  
7 - */  
8 -package cn.iocoder.yudao.framework.extension;  
9 \ No newline at end of file 0 \ No newline at end of file
yudao-framework/yudao-spring-boot-starter-extension/src/main/resources/META-INF/spring.factories deleted
1 -org.springframework.boot.autoconfigure.EnableAutoConfiguration=\  
2 - cn.iocoder.yudao.framework.extension.config.YudaoExtensionAutoConfiguration  
yudao-framework/yudao-spring-boot-starter-extension/src/test/java/cn/iocoder/yudao/framework/extension/Application.java deleted
1 -package cn.iocoder.yudao.framework.extension;  
2 -  
3 -import org.springframework.boot.SpringApplication;  
4 -import org.springframework.boot.autoconfigure.SpringBootApplication;  
5 -  
6 -/**  
7 - * @description Application  
8 - * @author Qingchen  
9 - * @version 1.0.0  
10 - * @date 2021-08-30 10:32  
11 - * @class cn.iocoder.yudao.framework.extension.Application.java  
12 - */  
13 -@SpringBootApplication  
14 -public class Application {  
15 -  
16 - public static void main(String[] args) {  
17 - SpringApplication.run(Application.class, args);  
18 - }  
19 -}  
yudao-framework/yudao-spring-boot-starter-extension/src/test/java/cn/iocoder/yudao/framework/extension/ExtensionTest.java deleted
1 -package cn.iocoder.yudao.framework.extension;  
2 -  
3 -import cn.hutool.core.util.IdUtil;  
4 -import cn.hutool.json.JSONUtil;  
5 -import cn.iocoder.yudao.framework.extension.core.BusinessScenario;  
6 -import cn.iocoder.yudao.framework.extension.core.context.ExtensionExecutor;  
7 -import cn.iocoder.yudao.framework.extension.pay.PayExtensionPoint;  
8 -import cn.iocoder.yudao.framework.extension.pay.command.TransactionsCommand;  
9 -import cn.iocoder.yudao.framework.extension.pay.domain.TransactionsResult;  
10 -import lombok.extern.slf4j.Slf4j;  
11 -import org.junit.Assert;  
12 -import org.junit.Test;  
13 -import org.junit.runner.RunWith;  
14 -import org.springframework.beans.factory.annotation.Autowired;  
15 -import org.springframework.boot.test.context.SpringBootTest;  
16 -import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;  
17 -  
18 -import java.math.BigDecimal;  
19 -  
20 -/**  
21 - * @description  
22 - * @author Qingchen  
23 - * @version 1.0.0  
24 - * @date 2021-08-30 10:30  
25 - * @class cn.iocoder.yudao.framework.extension.ExtensionTest.java  
26 - */  
27 -@RunWith(SpringJUnit4ClassRunner.class)  
28 -@SpringBootTest(classes = Application.class)  
29 -@Slf4j  
30 -public class ExtensionTest {  
31 -  
32 - @Autowired  
33 - private ExtensionExecutor extensionExecutor;  
34 -  
35 - @Test  
36 - public void unifiedOrder() {  
37 - final BusinessScenario scenario = BusinessScenario.valueOf("pay", "jsapi", "wechat");  
38 - final TransactionsCommand command = new TransactionsCommand(IdUtil.objectId(), new BigDecimal(105), "Image形象店-深圳腾大-QQ公仔", "https://www.weixin.qq.com/wxpay/pay.php");  
39 - final TransactionsResult result = extensionExecutor.execute(PayExtensionPoint.class, scenario, extension -> extension.unifiedOrder(command));  
40 - log.info("result is: {}", JSONUtil.toJsonStr(result));  
41 - Assert.assertSame("wechat", result.getChannel());  
42 - }  
43 -}  
yudao-framework/yudao-spring-boot-starter-extension/src/test/java/cn/iocoder/yudao/framework/extension/package-info.java deleted
1 -/**  
2 - * @description  
3 - * @author Qingchen  
4 - * @version 1.0.0  
5 - * @date 2021-08-30 10:25  
6 - * @class cn.iocoder.yudao.framework.extension.package-info.java  
7 - */  
8 -package cn.iocoder.yudao.framework.extension;  
9 \ No newline at end of file 0 \ No newline at end of file
yudao-framework/yudao-spring-boot-starter-extension/src/test/java/cn/iocoder/yudao/framework/extension/pay/PayExtensionPoint.java deleted
1 -package cn.iocoder.yudao.framework.extension.pay;  
2 -  
3 -import cn.iocoder.yudao.framework.extension.core.point.ExtensionPoint;  
4 -import cn.iocoder.yudao.framework.extension.pay.command.TransactionsCommand;  
5 -import cn.iocoder.yudao.framework.extension.pay.domain.TransactionsResult;  
6 -  
7 -/**  
8 - * @description 支付操作接口  
9 - * @author Qingchen  
10 - * @version 1.0.0  
11 - * @date 2021-08-30 10:35  
12 - * @class cn.iocoder.yudao.framework.extension.pay.PayExtensionPoint.java  
13 - */  
14 -public interface PayExtensionPoint extends ExtensionPoint {  
15 -  
16 - /**  
17 - * 统一下单:获取"预支付交易会话标识"  
18 - * @param command  
19 - * @return  
20 - */  
21 - TransactionsResult unifiedOrder(TransactionsCommand command);  
22 -}  
yudao-framework/yudao-spring-boot-starter-extension/src/test/java/cn/iocoder/yudao/framework/extension/pay/command/TransactionsCommand.java deleted
1 -package cn.iocoder.yudao.framework.extension.pay.command;  
2 -  
3 -import lombok.AllArgsConstructor;  
4 -import lombok.Data;  
5 -import lombok.NoArgsConstructor;  
6 -  
7 -import java.io.Serializable;  
8 -import java.math.BigDecimal;  
9 -  
10 -/**  
11 - * @description 下单请求  
12 - * @author Qingchen  
13 - * @version 1.0.0  
14 - * @date 2021-08-30 10:48  
15 - * @class cn.iocoder.yudao.framework.extension.pay.command.TransactionsCommand.java  
16 - */  
17 -@Data  
18 -@NoArgsConstructor  
19 -@AllArgsConstructor  
20 -public class TransactionsCommand implements Serializable {  
21 - /**  
22 - * 订单编号  
23 - */  
24 - private String orderNo;  
25 -  
26 - /**  
27 - * 支付金额  
28 - */  
29 - private BigDecimal amount;  
30 -  
31 - /**  
32 - * 商品描述  
33 - */  
34 - private String productDescription;  
35 -  
36 - /**  
37 - * 通知地址  
38 - */  
39 - private String notifyUrl;  
40 -}  
yudao-framework/yudao-spring-boot-starter-extension/src/test/java/cn/iocoder/yudao/framework/extension/pay/domain/TransactionsResult.java deleted
1 -package cn.iocoder.yudao.framework.extension.pay.domain;  
2 -  
3 -import lombok.*;  
4 -  
5 -import java.io.Serializable;  
6 -  
7 -/**  
8 - * @description 下单: 预支付交易单返回结果  
9 - * @author Qingchen  
10 - * @version 1.0.0  
11 - * @date 2021-08-30 10:43  
12 - * @class cn.iocoder.yudao.framework.extension.pay.domain.TransactionsResult.java  
13 - */  
14 -@Data  
15 -@AllArgsConstructor  
16 -public class TransactionsResult implements Serializable {  
17 -  
18 - /**  
19 - * 预支付交易会话标识  
20 - */  
21 - private String prepayId;  
22 -  
23 - /**  
24 - * 订单编号  
25 - */  
26 - private String orderNo;  
27 -  
28 - /**  
29 - * 系统内部支付单号  
30 - */  
31 - private String paymentNo;  
32 -  
33 - /**  
34 - * 支付渠道:微信 or 支付宝  
35 - */  
36 - private String channel;  
37 -  
38 -  
39 -}  
yudao-framework/yudao-spring-boot-starter-extension/src/test/java/cn/iocoder/yudao/framework/extension/pay/impl/AlipayService.java deleted
1 -package cn.iocoder.yudao.framework.extension.pay.impl;  
2 -  
3 -import cn.hutool.core.util.IdUtil;  
4 -import cn.hutool.json.JSONUtil;  
5 -import cn.iocoder.yudao.framework.extension.core.stereotype.Extension;  
6 -import cn.iocoder.yudao.framework.extension.pay.PayExtensionPoint;  
7 -import cn.iocoder.yudao.framework.extension.pay.command.TransactionsCommand;  
8 -import cn.iocoder.yudao.framework.extension.pay.domain.TransactionsResult;  
9 -import lombok.extern.slf4j.Slf4j;  
10 -  
11 -/**  
12 - * @description 微信 JSAPI 支付  
13 - * @author Qingchen  
14 - * @version 1.0.0  
15 - * @date 2021-08-30 10:38  
16 - * @class cn.iocoder.yudao.framework.extension.pay.impl.AlipayService.java  
17 - */  
18 -@Extension(businessId = "pay", useCase = "jsapi", scenario = "alipay")  
19 -@Slf4j  
20 -public class AlipayService implements PayExtensionPoint {  
21 - @Override  
22 - public TransactionsResult unifiedOrder(TransactionsCommand command) {  
23 - log.info("微信 JSAPI 支付:{}", JSONUtil.toJsonStr(command));  
24 - return new TransactionsResult("alipay26112221580621e9b071c00d9e093b0000", command.getOrderNo(), IdUtil.objectId(), "alipay");  
25 - }  
26 -}  
yudao-framework/yudao-spring-boot-starter-extension/src/test/java/cn/iocoder/yudao/framework/extension/pay/impl/WechatPayService.java deleted
1 -package cn.iocoder.yudao.framework.extension.pay.impl;  
2 -  
3 -import cn.hutool.core.util.IdUtil;  
4 -import cn.hutool.json.JSONUtil;  
5 -import cn.iocoder.yudao.framework.extension.core.stereotype.Extension;  
6 -import cn.iocoder.yudao.framework.extension.pay.PayExtensionPoint;  
7 -import cn.iocoder.yudao.framework.extension.pay.command.TransactionsCommand;  
8 -import cn.iocoder.yudao.framework.extension.pay.domain.TransactionsResult;  
9 -import lombok.extern.slf4j.Slf4j;  
10 -  
11 -/**  
12 - * @description 微信 JSAPI 支付  
13 - * @author Qingchen  
14 - * @version 1.0.0  
15 - * @date 2021-08-30 10:37  
16 - * @class cn.iocoder.yudao.framework.extension.pay.impl.WechatPayService.java  
17 - */  
18 -@Extension(businessId = "pay", useCase = "jsapi", scenario = "wechat")  
19 -@Slf4j  
20 -public class WechatPayService implements PayExtensionPoint {  
21 - @Override  
22 - public TransactionsResult unifiedOrder(TransactionsCommand command) {  
23 - log.info("微信 JSAPI 支付:{}", JSONUtil.toJsonStr(command));  
24 - return new TransactionsResult("wx26112221580621e9b071c00d9e093b0000", command.getOrderNo(), IdUtil.objectId(), "wechat");  
25 - }  
26 -}  
yudao-framework/yudao-spring-boot-starter-extension/《芋道 Spring Boot 扩展点组件》.md deleted
1 -### 作用  
2 -  
3 -​ 为了解决同一个流程不同业务有不同处理逻辑而产生,减少代码中 if else 逻辑,降低代码的耦合性,通过统一的扩展形式来支撑业务的变化。  
4 -  
5 -### 原理  
6 -  
7 -​ https://blog.csdn.net/significantfrank/article/details/100074716  
8 -  
9 -  
10 -  
11 -### 使用介绍  
12 -  
13 -参考测试代码 `cn.iocoder.yudao.framework.extension.ExtensionTest`  
14 -  
15 -  
16 -  
17 -  
18 -  
19 -  
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/BpmTaskController.java
@@ -75,13 +75,4 @@ public class BpmTaskController { @@ -75,13 +75,4 @@ public class BpmTaskController {
75 return success(true); 75 return success(true);
76 } 76 }
77 77
78 - @PutMapping("/back")  
79 - @ApiOperation(value = "回退")  
80 - // @PreAuthorize("@ss.hasPermission('bpm:task:back')")  
81 - public CommonResult<Boolean> backTask(@Valid @RequestBody BpmTaskBackReqVO reqVO) {  
82 - //先硬编码到 回退到第一个审批节点  
83 - // String destinationTaskDefKey = "task01";  
84 - return taskService.backTask(reqVO);  
85 -  
86 - }  
87 } 78 }
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/task/BpmTaskBackReqVO.java deleted
1 -package cn.iocoder.yudao.module.bpm.controller.admin.task.vo.task;  
2 -  
3 -import io.swagger.annotations.ApiModelProperty;  
4 -import lombok.AllArgsConstructor;  
5 -import lombok.Data;  
6 -import lombok.NoArgsConstructor;  
7 -  
8 -import javax.validation.constraints.NotEmpty;  
9 -import javax.validation.constraints.NotNull;  
10 -  
11 -/**  
12 - * @author kemengkai  
13 - * @create 2022-05-07 08:05 TODO ke:vo 类,使用 swagger 注解即可  
14 - */  
15 -@Data  
16 -@AllArgsConstructor  
17 -@NoArgsConstructor  
18 -public class BpmTaskBackReqVO {  
19 -  
20 - // TODO ke:userId 应该使用后端的,不能前端传递,不然就越权了  
21 - @ApiModelProperty(value = "用户id", required = true, example = "1")  
22 - @NotEmpty(message = "用户id不能为空")  
23 - private String userId;  
24 -  
25 - // TODO ke:procInstId、taskId、oldTaskDefKey 三个,是不是只要传递一个 taskId?字段不要存在推导关系  
26 - @ApiModelProperty(value = "流程编号id", required = true, example = "730da750-cc4f-11ec-b58e-1e429355e4a0")  
27 - @NotEmpty(message = "流程编号id不能为空")  
28 - private String procInstId;  
29 -  
30 - @ApiModelProperty(value = "当前任务id", required = true, example = "730da750-cc4f-11ec-b58e-1e429355e4a0")  
31 - @NotEmpty(message = "当前任务id不能为空")  
32 - private String taskId;  
33 -  
34 - @ApiModelProperty(value = "当前流程任务id", required = true, example = "Activity_1jlembv")  
35 - @NotNull(message = "当前流程任务id不能为空")  
36 - private String oldTaskDefKey;  
37 -  
38 - @ApiModelProperty(value = "准备回退的流程任务id", required = true, example = "task01")  
39 - @NotNull(message = "准备回退流程任务id不能为空")  
40 - private String newTaskDefKey;  
41 -  
42 - @ApiModelProperty(value = "审批结果", required = true, example = "任务驳回")  
43 - @NotNull(message = "审批结果")  
44 - private String reason;  
45 -}  
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/dal/mysql/task/BpmTaskExtMapper.java
@@ -4,7 +4,6 @@ import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; @@ -4,7 +4,6 @@ import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
4 import cn.iocoder.yudao.module.bpm.dal.dataobject.task.BpmTaskExtDO; 4 import cn.iocoder.yudao.module.bpm.dal.dataobject.task.BpmTaskExtDO;
5 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; 5 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
6 import org.apache.ibatis.annotations.Mapper; 6 import org.apache.ibatis.annotations.Mapper;
7 -import org.apache.ibatis.annotations.Param;  
8 7
9 import java.util.Collection; 8 import java.util.Collection;
10 import java.util.List; 9 import java.util.List;
@@ -24,28 +23,4 @@ public interface BpmTaskExtMapper extends BaseMapperX&lt;BpmTaskExtDO&gt; { @@ -24,28 +23,4 @@ public interface BpmTaskExtMapper extends BaseMapperX&lt;BpmTaskExtDO&gt; {
24 return selectOne(BpmTaskExtDO::getTaskId, taskId); 23 return selectOne(BpmTaskExtDO::getTaskId, taskId);
25 } 24 }
26 25
27 - default List<BpmTaskExtDO> selectListByProcessInstanceId(String processInstanceId) {  
28 - return selectList(BpmTaskExtDO::getProcessInstanceId, processInstanceId);  
29 - }  
30 -  
31 - // TODO @ke:可以使用类上上面的 default 方法实现。然后,方法的命名上,要保持和 db 一样。因为 mapper 是数据层,不关注业务。例如说,这里,其实复用 updateByTaskId 方法即可  
32 - /**  
33 - * 任务驳回  
34 - *  
35 - * @param taskId 任务列表  
36 - * @param reason 驳回理由  
37 - *  
38 - * @return 返回驳回结果,是否成功  
39 - */  
40 - Boolean backByTaskId(@Param("taskId") String taskId, @Param("reason") String reason);  
41 -  
42 - // TODO @ke:tong上哈  
43 - /**  
44 - * 逻辑删除任务  
45 - *  
46 - * @param taskIdList 任务id列表  
47 - *  
48 - * @return 返回是否成功  
49 - */  
50 - Boolean delByTaskIds(@Param("taskIdList") List<String> taskIdList);  
51 } 26 }
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/behavior/script/BpmTaskAssignScript.java
@@ -5,7 +5,6 @@ import org.flowable.engine.delegate.DelegateExecution; @@ -5,7 +5,6 @@ import org.flowable.engine.delegate.DelegateExecution;
5 5
6 import java.util.Set; 6 import java.util.Set;
7 7
8 -// TODO @芋艿:迁移到 bpm 的 core 下  
9 /** 8 /**
10 * Bpm 任务分配的自定义 Script 脚本 9 * Bpm 任务分配的自定义 Script 脚本
11 * 使用场景: 10 * 使用场景:
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmProcessInstanceServiceImpl.java
1 -package cn.iocoder.yudao.module.bpm.service.task; import cn.hutool.core.collection.CollUtil; import cn.hutool.core.lang.Assert; import cn.hutool.core.util.StrUtil; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.common.util.number.NumberUtils; import cn.iocoder.yudao.module.bpm.api.task.dto.BpmProcessInstanceCreateReqDTO; import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance.*; import cn.iocoder.yudao.module.bpm.convert.task.BpmProcessInstanceConvert; import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmProcessDefinitionExtDO; import cn.iocoder.yudao.module.bpm.dal.dataobject.task.BpmProcessInstanceExtDO; import cn.iocoder.yudao.module.bpm.dal.mysql.task.BpmProcessInstanceExtMapper; import cn.iocoder.yudao.module.bpm.enums.task.BpmProcessInstanceDeleteReasonEnum; import cn.iocoder.yudao.module.bpm.enums.task.BpmProcessInstanceResultEnum; import cn.iocoder.yudao.module.bpm.enums.task.BpmProcessInstanceStatusEnum; import cn.iocoder.yudao.module.bpm.framework.bpm.core.event.BpmProcessInstanceResultEventPublisher; import cn.iocoder.yudao.module.bpm.service.definition.BpmProcessDefinitionService; import cn.iocoder.yudao.module.bpm.service.message.BpmMessageService; import cn.iocoder.yudao.module.system.api.dept.DeptApi; import cn.iocoder.yudao.module.system.api.dept.dto.DeptRespDTO; import cn.iocoder.yudao.module.system.api.user.AdminUserApi; import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO; import lombok.extern.slf4j.Slf4j; import org.flowable.engine.HistoryService; import org.flowable.engine.RuntimeService; import org.flowable.engine.delegate.event.FlowableCancelledEvent; import org.flowable.engine.history.HistoricProcessInstance; import org.flowable.engine.repository.ProcessDefinition; import org.flowable.engine.runtime.ProcessInstance; import org.flowable.task.api.Task; import org.springframework.context.annotation.Lazy; import org.springframework.scheduling.annotation.Async; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import org.springframework.validation.annotation.Validated; import javax.annotation.Resource; import javax.validation.Valid; import java.util.*; import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList; import static cn.iocoder.yudao.module.bpm.enums.ErrorCodeConstants.*; import static cn.iocoder.yudao.module.bpm.enums.ErrorCodeConstants.PROCESS_INSTANCE_CANCEL_FAIL_NOT_SELF; /** * 流程实例 Service 实现类 * * ProcessDefinition & ProcessInstance & Execution & Task 的关系: * 1. <a href="https://blog.csdn.net/bobozai86/article/details/105210414" /> * * HistoricProcessInstance & ProcessInstance 的关系: * 1. <a href=" https://my.oschina.net/843294669/blog/71902" /> * * 简单来说,前者 = 历史 + 运行中的流程实例,后者仅是运行中的流程实例 * * @author 芋道源码 */ @Service @Validated @Slf4j public class BpmProcessInstanceServiceImpl implements BpmProcessInstanceService { @Resource private RuntimeService runtimeService; @Resource private BpmProcessInstanceExtMapper processInstanceExtMapper; @Resource @Lazy // 解决循环依赖 private BpmTaskService taskService; @Resource private BpmProcessDefinitionService processDefinitionService; @Resource private HistoryService historyService; @Resource private AdminUserApi adminUserApi; @Resource private DeptApi deptApi; @Resource private BpmProcessInstanceResultEventPublisher processInstanceResultEventPublisher; @Resource private BpmMessageService messageService; @Override public ProcessInstance getProcessInstance(String id) { return runtimeService.createProcessInstanceQuery().processInstanceId(id).singleResult(); } @Override public List<ProcessInstance> getProcessInstances(Set<String> ids) { return runtimeService.createProcessInstanceQuery().processInstanceIds(ids).list(); } @Override public PageResult<BpmProcessInstancePageItemRespVO> getMyProcessInstancePage(Long userId, BpmProcessInstanceMyPageReqVO pageReqVO) { // 通过 BpmProcessInstanceExtDO 表,先查询到对应的分页 PageResult<BpmProcessInstanceExtDO> pageResult = processInstanceExtMapper.selectPage(userId, pageReqVO); if (CollUtil.isEmpty(pageResult.getList())) { return new PageResult<>(pageResult.getTotal()); } // 获得流程 Task Map List<String> processInstanceIds = convertList(pageResult.getList(), BpmProcessInstanceExtDO::getProcessInstanceId); Map<String, List<Task>> taskMap = taskService.getTaskMapByProcessInstanceIds(processInstanceIds); // 转换返回 return BpmProcessInstanceConvert.INSTANCE.convertPage(pageResult, taskMap); } @Override @Transactional(rollbackFor = Exception.class) public String createProcessInstance(Long userId, @Valid BpmProcessInstanceCreateReqVO createReqVO) { // 获得流程定义 ProcessDefinition definition = processDefinitionService.getProcessDefinition(createReqVO.getProcessDefinitionId()); // 发起流程 return createProcessInstance0(userId, definition, createReqVO.getVariables(), null); } @Override public String createProcessInstance(Long userId, @Valid BpmProcessInstanceCreateReqDTO createReqDTO) { // 获得流程定义 ProcessDefinition definition = processDefinitionService.getActiveProcessDefinition(createReqDTO.getProcessDefinitionKey()); // 发起流程 return createProcessInstance0(userId, definition, createReqDTO.getVariables(), createReqDTO.getBusinessKey()); } @Override public BpmProcessInstanceRespVO getProcessInstanceVO(String id) { // 获得流程实例 HistoricProcessInstance processInstance = getHistoricProcessInstance(id); if (processInstance == null) { return null; } BpmProcessInstanceExtDO processInstanceExt = processInstanceExtMapper.selectByProcessInstanceId(id); Assert.notNull(processInstanceExt, "流程实例拓展({}) 不存在", id); // 获得流程定义 ProcessDefinition processDefinition = processDefinitionService .getProcessDefinition(processInstance.getProcessDefinitionId()); Assert.notNull(processDefinition, "流程定义({}) 不存在", processInstance.getProcessDefinitionId()); BpmProcessDefinitionExtDO processDefinitionExt = processDefinitionService.getProcessDefinitionExt( processInstance.getProcessDefinitionId()); Assert.notNull(processDefinitionExt, "流程定义拓展({}) 不存在", id); String bpmnXml = processDefinitionService.getProcessDefinitionBpmnXML(processInstance.getProcessDefinitionId()); // 获得 User AdminUserRespDTO startUser = adminUserApi.getUser(NumberUtils.parseLong(processInstance.getStartUserId())); DeptRespDTO dept = null; if (startUser != null) { dept = deptApi.getDept(startUser.getDeptId()); } // 拼接结果 return BpmProcessInstanceConvert.INSTANCE.convert2(processInstance, processInstanceExt, processDefinition, processDefinitionExt, bpmnXml, startUser, dept); } @Override public void cancelProcessInstance(Long userId, @Valid BpmProcessInstanceCancelReqVO cancelReqVO) { // 校验流程实例存在 ProcessInstance instance = getProcessInstance(cancelReqVO.getId()); if (instance == null) { throw exception(PROCESS_INSTANCE_CANCEL_FAIL_NOT_EXISTS); } // 只能取消自己的 if (!Objects.equals(instance.getStartUserId(), String.valueOf(userId))) { throw exception(PROCESS_INSTANCE_CANCEL_FAIL_NOT_SELF); } // 通过删除流程实例,实现流程实例的取消, // 删除流程实例,正则执行任务 ACT_RU_TASK. 任务会被删除。通过历史表查询 deleteProcessInstance(cancelReqVO.getId(), BpmProcessInstanceDeleteReasonEnum.CANCEL_TASK.format(cancelReqVO.getReason())); } /** * 获得历史的流程实例 * * @param id 流程实例的编号 * @return 历史的流程实例 */ @Override public HistoricProcessInstance getHistoricProcessInstance(String id) { return historyService.createHistoricProcessInstanceQuery().processInstanceId(id).singleResult(); } @Override public List<HistoricProcessInstance> getHistoricProcessInstances(Set<String> ids) { return historyService.createHistoricProcessInstanceQuery().processInstanceIds(ids).list(); } @Override public void createProcessInstanceExt(ProcessInstance instance) { // 获得流程定义 ProcessDefinition definition = processDefinitionService.getProcessDefinition2(instance.getProcessDefinitionId()); // 插入 BpmProcessInstanceExtDO 对象 BpmProcessInstanceExtDO instanceExtDO = new BpmProcessInstanceExtDO() .setProcessInstanceId(instance.getId()) .setProcessDefinitionId(definition.getId()) .setName(instance.getProcessDefinitionName()) .setStartUserId(Long.valueOf(instance.getStartUserId())) .setCategory(definition.getCategory()) .setStatus(BpmProcessInstanceStatusEnum.RUNNING.getStatus()) .setResult(BpmProcessInstanceResultEnum.PROCESS.getResult()); processInstanceExtMapper.insert(instanceExtDO); } @Override public void updateProcessInstanceExtCancel(FlowableCancelledEvent event) { // 判断是否为 Reject 不通过。如果是,则不进行更新. // 因为,updateProcessInstanceExtReject 方法,已经进行更新了 if (BpmProcessInstanceDeleteReasonEnum.isRejectReason((String)event.getCause())) { return; } // 需要主动查询,因为 instance 只有 id 属性 // 另外,此时如果去查询 ProcessInstance 的话,字段是不全的,所以去查询了 HistoricProcessInstance HistoricProcessInstance processInstance = getHistoricProcessInstance(event.getProcessInstanceId()); // 更新拓展表 BpmProcessInstanceExtDO instanceExtDO = new BpmProcessInstanceExtDO() .setProcessInstanceId(event.getProcessInstanceId()) .setEndTime(new Date()) // 由于 ProcessInstance 里没有办法拿到 endTime,所以这里设置 .setStatus(BpmProcessInstanceStatusEnum.FINISH.getStatus()) .setResult(BpmProcessInstanceResultEnum.CANCEL.getResult()); processInstanceExtMapper.updateByProcessInstanceId(instanceExtDO); // 发送流程实例的状态事件 processInstanceResultEventPublisher.sendProcessInstanceResultEvent( BpmProcessInstanceConvert.INSTANCE.convert(this, processInstance, instanceExtDO.getResult())); } @Override public void updateProcessInstanceExtComplete(ProcessInstance instance) { // 需要主动查询,因为 instance 只有 id 属性 // 另外,此时如果去查询 ProcessInstance 的话,字段是不全的,所以去查询了 HistoricProcessInstance HistoricProcessInstance processInstance = getHistoricProcessInstance(instance.getId()); // 更新拓展表 BpmProcessInstanceExtDO instanceExtDO = new BpmProcessInstanceExtDO() .setProcessInstanceId(instance.getProcessInstanceId()) .setEndTime(new Date()) // 由于 ProcessInstance 里没有办法拿到 endTime,所以这里设置 .setStatus(BpmProcessInstanceStatusEnum.FINISH.getStatus()) .setResult(BpmProcessInstanceResultEnum.APPROVE.getResult()); // 如果正常完全,说明审批通过 processInstanceExtMapper.updateByProcessInstanceId(instanceExtDO); // 发送流程被通过的消息 messageService.sendMessageWhenProcessInstanceApprove(BpmProcessInstanceConvert.INSTANCE.convert2ApprovedReq(instance)); // 发送流程实例的状态事件 processInstanceResultEventPublisher.sendProcessInstanceResultEvent( BpmProcessInstanceConvert.INSTANCE.convert(this, processInstance, instanceExtDO.getResult())); } @Transactional(rollbackFor = Exception.class) public void updateProcessInstanceExtReject(String id, String reason) { // 需要主动查询,因为 instance 只有 id 属性 ProcessInstance processInstance = getProcessInstance(id); // 删除流程实例,以实现驳回任务时,取消整个审批流程 deleteProcessInstance(id, StrUtil.format(BpmProcessInstanceDeleteReasonEnum.REJECT_TASK.format(reason))); // 更新 status + result // 注意,不能和上面的逻辑更换位置。因为 deleteProcessInstance 会触发流程的取消,进而调用 updateProcessInstanceExtCancel 方法, // 设置 result 为 BpmProcessInstanceStatusEnum.CANCEL,显然和 result 不一定是一致的 BpmProcessInstanceExtDO instanceExtDO = new BpmProcessInstanceExtDO().setProcessInstanceId(id) .setStatus(BpmProcessInstanceStatusEnum.FINISH.getStatus()) .setResult(BpmProcessInstanceResultEnum.REJECT.getResult()); processInstanceExtMapper.updateByProcessInstanceId(instanceExtDO); // 发送流程被不通过的消息 messageService.sendMessageWhenProcessInstanceReject(BpmProcessInstanceConvert.INSTANCE.convert2RejectReq(processInstance, reason)); // 发送流程实例的状态事件 processInstanceResultEventPublisher.sendProcessInstanceResultEvent( BpmProcessInstanceConvert.INSTANCE.convert(this, processInstance, instanceExtDO.getResult())); } private void deleteProcessInstance(String id, String reason) { runtimeService.deleteProcessInstance(id, reason); } private String createProcessInstance0(Long userId, ProcessDefinition definition, Map<String, Object> variables, String businessKey) { // 校验流程定义 if (definition == null) { throw exception(PROCESS_DEFINITION_NOT_EXISTS); } if (definition.isSuspended()) { throw exception(PROCESS_DEFINITION_IS_SUSPENDED); } // 创建流程实例 ProcessInstance instance = runtimeService.startProcessInstanceById(definition.getId(), businessKey, variables); // 设置流程名字 runtimeService.setProcessInstanceName(instance.getId(), definition.getName()); // 补全流程实例的拓展表 //TODO startProcessInstance流程里面修改了 BpmProcessInstanceExt,没有提交,和下面的更新 锁持有冲突了,异步更新这个表 // processInstanceExtMapper.updateByProcessInstanceId(new BpmProcessInstanceExtDO().setProcessInstanceId(instance.getId()).setFormVariables(variables)); BpmProcessInstanceExtDO bpmProcessInstanceExtDO = new BpmProcessInstanceExtDO().setProcessInstanceId(instance.getId()).setFormVariables(variables); asyncUpdateProcesInstance(bpmProcessInstanceExtDO); return instance.getId(); } @Async public void asyncUpdateProcesInstance(BpmProcessInstanceExtDO bpmProcessInstanceExtDO){ log.info("asyncUpdateProcesInstance ,cause MySQL Dead Lock"); processInstanceExtMapper.updateByProcessInstanceId(bpmProcessInstanceExtDO); } }  
2 \ No newline at end of file 1 \ No newline at end of file
  2 +package cn.iocoder.yudao.module.bpm.service.task; import cn.hutool.core.collection.CollUtil; import cn.hutool.core.lang.Assert; import cn.hutool.core.util.StrUtil; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.common.util.number.NumberUtils; import cn.iocoder.yudao.module.bpm.api.task.dto.BpmProcessInstanceCreateReqDTO; import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance.*; import cn.iocoder.yudao.module.bpm.convert.task.BpmProcessInstanceConvert; import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmProcessDefinitionExtDO; import cn.iocoder.yudao.module.bpm.dal.dataobject.task.BpmProcessInstanceExtDO; import cn.iocoder.yudao.module.bpm.dal.mysql.task.BpmProcessInstanceExtMapper; import cn.iocoder.yudao.module.bpm.enums.task.BpmProcessInstanceDeleteReasonEnum; import cn.iocoder.yudao.module.bpm.enums.task.BpmProcessInstanceResultEnum; import cn.iocoder.yudao.module.bpm.enums.task.BpmProcessInstanceStatusEnum; import cn.iocoder.yudao.module.bpm.framework.bpm.core.event.BpmProcessInstanceResultEventPublisher; import cn.iocoder.yudao.module.bpm.service.definition.BpmProcessDefinitionService; import cn.iocoder.yudao.module.bpm.service.message.BpmMessageService; import cn.iocoder.yudao.module.system.api.dept.DeptApi; import cn.iocoder.yudao.module.system.api.dept.dto.DeptRespDTO; import cn.iocoder.yudao.module.system.api.user.AdminUserApi; import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO; import lombok.extern.slf4j.Slf4j; import org.flowable.engine.HistoryService; import org.flowable.engine.RuntimeService; import org.flowable.engine.delegate.event.FlowableCancelledEvent; import org.flowable.engine.history.HistoricProcessInstance; import org.flowable.engine.repository.ProcessDefinition; import org.flowable.engine.runtime.ProcessInstance; import org.flowable.task.api.Task; import org.springframework.context.annotation.Lazy; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import org.springframework.validation.annotation.Validated; import javax.annotation.Resource; import javax.validation.Valid; import java.util.*; import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList; import static cn.iocoder.yudao.module.bpm.enums.ErrorCodeConstants.*; /** * 流程实例 Service 实现类 * * ProcessDefinition & ProcessInstance & Execution & Task 的关系: * 1. <a href="https://blog.csdn.net/bobozai86/article/details/105210414" /> * * HistoricProcessInstance & ProcessInstance 的关系: * 1. <a href=" https://my.oschina.net/843294669/blog/71902" /> * * 简单来说,前者 = 历史 + 运行中的流程实例,后者仅是运行中的流程实例 * * @author 芋道源码 */ @Service @Validated @Slf4j public class BpmProcessInstanceServiceImpl implements BpmProcessInstanceService { @Resource private RuntimeService runtimeService; @Resource private BpmProcessInstanceExtMapper processInstanceExtMapper; @Resource @Lazy // 解决循环依赖 private BpmTaskService taskService; @Resource private BpmProcessDefinitionService processDefinitionService; @Resource private HistoryService historyService; @Resource private AdminUserApi adminUserApi; @Resource private DeptApi deptApi; @Resource private BpmProcessInstanceResultEventPublisher processInstanceResultEventPublisher; @Resource private BpmMessageService messageService; @Override public ProcessInstance getProcessInstance(String id) { return runtimeService.createProcessInstanceQuery().processInstanceId(id).singleResult(); } @Override public List<ProcessInstance> getProcessInstances(Set<String> ids) { return runtimeService.createProcessInstanceQuery().processInstanceIds(ids).list(); } @Override public PageResult<BpmProcessInstancePageItemRespVO> getMyProcessInstancePage(Long userId, BpmProcessInstanceMyPageReqVO pageReqVO) { // 通过 BpmProcessInstanceExtDO 表,先查询到对应的分页 PageResult<BpmProcessInstanceExtDO> pageResult = processInstanceExtMapper.selectPage(userId, pageReqVO); if (CollUtil.isEmpty(pageResult.getList())) { return new PageResult<>(pageResult.getTotal()); } // 获得流程 Task Map List<String> processInstanceIds = convertList(pageResult.getList(), BpmProcessInstanceExtDO::getProcessInstanceId); Map<String, List<Task>> taskMap = taskService.getTaskMapByProcessInstanceIds(processInstanceIds); // 转换返回 return BpmProcessInstanceConvert.INSTANCE.convertPage(pageResult, taskMap); } @Override @Transactional(rollbackFor = Exception.class) public String createProcessInstance(Long userId, @Valid BpmProcessInstanceCreateReqVO createReqVO) { // 获得流程定义 ProcessDefinition definition = processDefinitionService.getProcessDefinition(createReqVO.getProcessDefinitionId()); // 发起流程 return createProcessInstance0(userId, definition, createReqVO.getVariables(), null); } @Override public String createProcessInstance(Long userId, @Valid BpmProcessInstanceCreateReqDTO createReqDTO) { // 获得流程定义 ProcessDefinition definition = processDefinitionService.getActiveProcessDefinition(createReqDTO.getProcessDefinitionKey()); // 发起流程 return createProcessInstance0(userId, definition, createReqDTO.getVariables(), createReqDTO.getBusinessKey()); } @Override public BpmProcessInstanceRespVO getProcessInstanceVO(String id) { // 获得流程实例 HistoricProcessInstance processInstance = getHistoricProcessInstance(id); if (processInstance == null) { return null; } BpmProcessInstanceExtDO processInstanceExt = processInstanceExtMapper.selectByProcessInstanceId(id); Assert.notNull(processInstanceExt, "流程实例拓展({}) 不存在", id); // 获得流程定义 ProcessDefinition processDefinition = processDefinitionService .getProcessDefinition(processInstance.getProcessDefinitionId()); Assert.notNull(processDefinition, "流程定义({}) 不存在", processInstance.getProcessDefinitionId()); BpmProcessDefinitionExtDO processDefinitionExt = processDefinitionService.getProcessDefinitionExt( processInstance.getProcessDefinitionId()); Assert.notNull(processDefinitionExt, "流程定义拓展({}) 不存在", id); String bpmnXml = processDefinitionService.getProcessDefinitionBpmnXML(processInstance.getProcessDefinitionId()); // 获得 User AdminUserRespDTO startUser = adminUserApi.getUser(NumberUtils.parseLong(processInstance.getStartUserId())); DeptRespDTO dept = null; if (startUser != null) { dept = deptApi.getDept(startUser.getDeptId()); } // 拼接结果 return BpmProcessInstanceConvert.INSTANCE.convert2(processInstance, processInstanceExt, processDefinition, processDefinitionExt, bpmnXml, startUser, dept); } @Override public void cancelProcessInstance(Long userId, @Valid BpmProcessInstanceCancelReqVO cancelReqVO) { // 校验流程实例存在 ProcessInstance instance = getProcessInstance(cancelReqVO.getId()); if (instance == null) { throw exception(PROCESS_INSTANCE_CANCEL_FAIL_NOT_EXISTS); } // 只能取消自己的 if (!Objects.equals(instance.getStartUserId(), String.valueOf(userId))) { throw exception(PROCESS_INSTANCE_CANCEL_FAIL_NOT_SELF); } // 通过删除流程实例,实现流程实例的取消, // 删除流程实例,正则执行任务 ACT_RU_TASK. 任务会被删除。通过历史表查询 deleteProcessInstance(cancelReqVO.getId(), BpmProcessInstanceDeleteReasonEnum.CANCEL_TASK.format(cancelReqVO.getReason())); } /** * 获得历史的流程实例 * * @param id 流程实例的编号 * @return 历史的流程实例 */ @Override public HistoricProcessInstance getHistoricProcessInstance(String id) { return historyService.createHistoricProcessInstanceQuery().processInstanceId(id).singleResult(); } @Override public List<HistoricProcessInstance> getHistoricProcessInstances(Set<String> ids) { return historyService.createHistoricProcessInstanceQuery().processInstanceIds(ids).list(); } @Override public void createProcessInstanceExt(ProcessInstance instance) { // 获得流程定义 ProcessDefinition definition = processDefinitionService.getProcessDefinition2(instance.getProcessDefinitionId()); // 插入 BpmProcessInstanceExtDO 对象 BpmProcessInstanceExtDO instanceExtDO = new BpmProcessInstanceExtDO() .setProcessInstanceId(instance.getId()) .setProcessDefinitionId(definition.getId()) .setName(instance.getProcessDefinitionName()) .setStartUserId(Long.valueOf(instance.getStartUserId())) .setCategory(definition.getCategory()) .setStatus(BpmProcessInstanceStatusEnum.RUNNING.getStatus()) .setResult(BpmProcessInstanceResultEnum.PROCESS.getResult()); processInstanceExtMapper.insert(instanceExtDO); } @Override public void updateProcessInstanceExtCancel(FlowableCancelledEvent event) { // 判断是否为 Reject 不通过。如果是,则不进行更新. // 因为,updateProcessInstanceExtReject 方法,已经进行更新了 if (BpmProcessInstanceDeleteReasonEnum.isRejectReason((String)event.getCause())) { return; } // 需要主动查询,因为 instance 只有 id 属性 // 另外,此时如果去查询 ProcessInstance 的话,字段是不全的,所以去查询了 HistoricProcessInstance HistoricProcessInstance processInstance = getHistoricProcessInstance(event.getProcessInstanceId()); // 更新拓展表 BpmProcessInstanceExtDO instanceExtDO = new BpmProcessInstanceExtDO() .setProcessInstanceId(event.getProcessInstanceId()) .setEndTime(new Date()) // 由于 ProcessInstance 里没有办法拿到 endTime,所以这里设置 .setStatus(BpmProcessInstanceStatusEnum.FINISH.getStatus()) .setResult(BpmProcessInstanceResultEnum.CANCEL.getResult()); processInstanceExtMapper.updateByProcessInstanceId(instanceExtDO); // 发送流程实例的状态事件 processInstanceResultEventPublisher.sendProcessInstanceResultEvent( BpmProcessInstanceConvert.INSTANCE.convert(this, processInstance, instanceExtDO.getResult())); } @Override public void updateProcessInstanceExtComplete(ProcessInstance instance) { // 需要主动查询,因为 instance 只有 id 属性 // 另外,此时如果去查询 ProcessInstance 的话,字段是不全的,所以去查询了 HistoricProcessInstance HistoricProcessInstance processInstance = getHistoricProcessInstance(instance.getId()); // 更新拓展表 BpmProcessInstanceExtDO instanceExtDO = new BpmProcessInstanceExtDO() .setProcessInstanceId(instance.getProcessInstanceId()) .setEndTime(new Date()) // 由于 ProcessInstance 里没有办法拿到 endTime,所以这里设置 .setStatus(BpmProcessInstanceStatusEnum.FINISH.getStatus()) .setResult(BpmProcessInstanceResultEnum.APPROVE.getResult()); // 如果正常完全,说明审批通过 processInstanceExtMapper.updateByProcessInstanceId(instanceExtDO); // 发送流程被通过的消息 messageService.sendMessageWhenProcessInstanceApprove(BpmProcessInstanceConvert.INSTANCE.convert2ApprovedReq(instance)); // 发送流程实例的状态事件 processInstanceResultEventPublisher.sendProcessInstanceResultEvent( BpmProcessInstanceConvert.INSTANCE.convert(this, processInstance, instanceExtDO.getResult())); } @Transactional(rollbackFor = Exception.class) public void updateProcessInstanceExtReject(String id, String reason) { // 需要主动查询,因为 instance 只有 id 属性 ProcessInstance processInstance = getProcessInstance(id); // 删除流程实例,以实现驳回任务时,取消整个审批流程 deleteProcessInstance(id, StrUtil.format(BpmProcessInstanceDeleteReasonEnum.REJECT_TASK.format(reason))); // 更新 status + result // 注意,不能和上面的逻辑更换位置。因为 deleteProcessInstance 会触发流程的取消,进而调用 updateProcessInstanceExtCancel 方法, // 设置 result 为 BpmProcessInstanceStatusEnum.CANCEL,显然和 result 不一定是一致的 BpmProcessInstanceExtDO instanceExtDO = new BpmProcessInstanceExtDO().setProcessInstanceId(id) .setStatus(BpmProcessInstanceStatusEnum.FINISH.getStatus()) .setResult(BpmProcessInstanceResultEnum.REJECT.getResult()); processInstanceExtMapper.updateByProcessInstanceId(instanceExtDO); // 发送流程被不通过的消息 messageService.sendMessageWhenProcessInstanceReject(BpmProcessInstanceConvert.INSTANCE.convert2RejectReq(processInstance, reason)); // 发送流程实例的状态事件 processInstanceResultEventPublisher.sendProcessInstanceResultEvent( BpmProcessInstanceConvert.INSTANCE.convert(this, processInstance, instanceExtDO.getResult())); } private void deleteProcessInstance(String id, String reason) { runtimeService.deleteProcessInstance(id, reason); } private String createProcessInstance0(Long userId, ProcessDefinition definition, Map<String, Object> variables, String businessKey) { // 校验流程定义 if (definition == null) { throw exception(PROCESS_DEFINITION_NOT_EXISTS); } if (definition.isSuspended()) { throw exception(PROCESS_DEFINITION_IS_SUSPENDED); } // 创建流程实例 ProcessInstance instance = runtimeService.startProcessInstanceById(definition.getId(), businessKey, variables); // 设置流程名字 runtimeService.setProcessInstanceName(instance.getId(), definition.getName()); // 补全流程实例的拓展表 processInstanceExtMapper.updateByProcessInstanceId(new BpmProcessInstanceExtDO().setProcessInstanceId(instance.getId()) .setFormVariables(variables)); return instance.getId(); } }
3 \ No newline at end of file 3 \ No newline at end of file
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmTaskService.java
@@ -85,13 +85,6 @@ public interface BpmTaskService { @@ -85,13 +85,6 @@ public interface BpmTaskService {
85 void rejectTask(Long userId, @Valid BpmTaskRejectReqVO reqVO); 85 void rejectTask(Long userId, @Valid BpmTaskRejectReqVO reqVO);
86 86
87 /** 87 /**
88 - * 回退任务  
89 - *  
90 - * @param reqVO 回退任务信息  
91 - */  
92 - CommonResult<Boolean> backTask(BpmTaskBackReqVO reqVO);  
93 -  
94 - /**  
95 * 将流程任务分配给指定用户 88 * 将流程任务分配给指定用户
96 * 89 *
97 * @param userId 用户编号 90 * @param userId 用户编号
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmTaskServiceImpl.java
@@ -2,15 +2,12 @@ package cn.iocoder.yudao.module.bpm.service.task; @@ -2,15 +2,12 @@ package cn.iocoder.yudao.module.bpm.service.task;
2 2
3 import cn.hutool.core.collection.CollUtil; 3 import cn.hutool.core.collection.CollUtil;
4 import cn.hutool.core.util.StrUtil; 4 import cn.hutool.core.util.StrUtil;
5 -import cn.iocoder.yudao.framework.common.pojo.CommonResult;  
6 import cn.iocoder.yudao.framework.common.pojo.PageResult; 5 import cn.iocoder.yudao.framework.common.pojo.PageResult;
7 import cn.iocoder.yudao.framework.common.util.number.NumberUtils; 6 import cn.iocoder.yudao.framework.common.util.number.NumberUtils;
8 import cn.iocoder.yudao.framework.common.util.object.PageUtils; 7 import cn.iocoder.yudao.framework.common.util.object.PageUtils;
9 -import cn.iocoder.yudao.framework.tenant.core.aop.TenantIgnore;  
10 import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.task.*; 8 import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.task.*;
11 import cn.iocoder.yudao.module.bpm.convert.task.BpmTaskConvert; 9 import cn.iocoder.yudao.module.bpm.convert.task.BpmTaskConvert;
12 import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmTaskAssignRuleDO; 10 import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmTaskAssignRuleDO;
13 -import cn.iocoder.yudao.module.bpm.dal.dataobject.task.BpmActivityDO;  
14 import cn.iocoder.yudao.module.bpm.dal.dataobject.task.BpmTaskExtDO; 11 import cn.iocoder.yudao.module.bpm.dal.dataobject.task.BpmTaskExtDO;
15 import cn.iocoder.yudao.module.bpm.dal.mysql.definition.BpmTaskAssignRuleMapper; 12 import cn.iocoder.yudao.module.bpm.dal.mysql.definition.BpmTaskAssignRuleMapper;
16 import cn.iocoder.yudao.module.bpm.dal.mysql.task.BpmActivityMapper; 13 import cn.iocoder.yudao.module.bpm.dal.mysql.task.BpmActivityMapper;
@@ -24,7 +21,6 @@ import cn.iocoder.yudao.module.system.api.user.AdminUserApi; @@ -24,7 +21,6 @@ import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
24 import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO; 21 import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
25 import lombok.extern.slf4j.Slf4j; 22 import lombok.extern.slf4j.Slf4j;
26 import org.flowable.engine.HistoryService; 23 import org.flowable.engine.HistoryService;
27 -import org.flowable.engine.RuntimeService;  
28 import org.flowable.engine.TaskService; 24 import org.flowable.engine.TaskService;
29 import org.flowable.engine.history.HistoricProcessInstance; 25 import org.flowable.engine.history.HistoricProcessInstance;
30 import org.flowable.engine.runtime.ProcessInstance; 26 import org.flowable.engine.runtime.ProcessInstance;
@@ -40,7 +36,6 @@ import org.springframework.transaction.support.TransactionSynchronizationManager @@ -40,7 +36,6 @@ import org.springframework.transaction.support.TransactionSynchronizationManager
40 import javax.annotation.Resource; 36 import javax.annotation.Resource;
41 import javax.validation.Valid; 37 import javax.validation.Valid;
42 import java.util.*; 38 import java.util.*;
43 -import java.util.stream.Collectors;  
44 39
45 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; 40 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
46 import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap; 41 import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap;
@@ -60,8 +55,6 @@ public class BpmTaskServiceImpl implements BpmTaskService { @@ -60,8 +55,6 @@ public class BpmTaskServiceImpl implements BpmTaskService {
60 @Resource 55 @Resource
61 private TaskService taskService; 56 private TaskService taskService;
62 @Resource 57 @Resource
63 - private RuntimeService runtimeService;  
64 - @Resource  
65 private HistoryService historyService; 58 private HistoryService historyService;
66 59
67 @Resource 60 @Resource
@@ -227,44 +220,6 @@ public class BpmTaskServiceImpl implements BpmTaskService { @@ -227,44 +220,6 @@ public class BpmTaskServiceImpl implements BpmTaskService {
227 } 220 }
228 221
229 @Override 222 @Override
230 - @Transactional(rollbackFor = Exception.class)  
231 - @TenantIgnore  
232 - public CommonResult<Boolean> backTask(BpmTaskBackReqVO reqVO) {  
233 - Long userId = Long.valueOf(reqVO.getUserId());  
234 - // 校验任务存在  
235 - Task task = checkTask(userId, reqVO.getTaskId());  
236 - ArrayList<String> oldTaskDefKeyList = CollUtil.newArrayList(reqVO.getOldTaskDefKey());  
237 -  
238 - // List<HistoricActivityInstance> hisActInstList =  
239 - // historyService.createHistoricActivityInstanceQuery().processInstanceId(reqVO.getProcInstId()).list();  
240 - // TODO @ke:使用 historyService.createHistoricActivityInstanceQuery().processInstanceId(reqVO.getProcInstId()).list() 读取,会存在啥问题呀?  
241 - List<BpmActivityDO> bpmActivityDOList = bpmActivityMapper.listAllByProcInstIdAndDelete(reqVO.getProcInstId());  
242 - // List<BpmActivityDO> bpmActivityDOList = BpmTaskConvert.INSTANCE.copyList(hisActInstList, BpmActivityDO.class);  
243 - // bpmActivityDOList.forEach(bpmActivityDO -> log.info("bpmActivityDO = " + bpmActivityDO));  
244 - // TODO @ke:如果 开始->a->b->c->d->结束,从 d 驳回到 b 的话,这样会不会导致 a 也被删除呀?http://blog.wya1.com/article/636697030/details/7296 可以看看这篇文章哈。  
245 - List<String> taskIdList = bpmActivityDOList.stream().filter(  
246 - bpmActivityDO -> bpmActivityDO.getActivityId().equals(reqVO.getOldTaskDefKey())  
247 - && !bpmActivityDO.getTaskId().equals(reqVO.getTaskId())).map(BpmActivityDO::getTaskId)  
248 - .collect(Collectors.toList());  
249 -  
250 - // 使用flowable更改任务节点  
251 - runtimeService.createChangeActivityStateBuilder().processInstanceId(reqVO.getProcInstId())  
252 - .moveActivityIdsToSingleActivityId(oldTaskDefKeyList, reqVO.getNewTaskDefKey()).changeState();  
253 -  
254 - // 逻辑删除hiActInst表任务  
255 - Boolean delHiActInstResult = bpmActivityMapper.delHiActInstByTaskId(taskIdList);  
256 - // 逻辑删除hiTaskInst表任务  
257 - Boolean delHiTaskInstResult = bpmActivityMapper.delHiTaskInstByTaskId(taskIdList);  
258 - // 更新任务拓展表  
259 - Boolean backResult = taskExtMapper.backByTaskId(reqVO.getTaskId(), reqVO.getReason());  
260 - Boolean delTaskResult = taskExtMapper.delByTaskIds(taskIdList);  
261 - if (!delHiActInstResult && !delHiTaskInstResult && !backResult && !delTaskResult) {  
262 - throw new RuntimeException("任务驳回失败!!!");  
263 - }  
264 - return CommonResult.success(true);  
265 - }  
266 -  
267 - @Override  
268 public void updateTaskAssignee(Long userId, BpmTaskUpdateAssigneeReqVO reqVO) { 223 public void updateTaskAssignee(Long userId, BpmTaskUpdateAssigneeReqVO reqVO) {
269 // 校验任务存在 224 // 校验任务存在
270 Task task = checkTask(userId, reqVO.getId()); 225 Task task = checkTask(userId, reqVO.getId());
yudao-module-bpm/yudao-module-bpm-biz/src/main/resources/mapper/BpmActivityMapper.xml deleted
1 -<?xml version="1.0" encoding="UTF-8"?>  
2 -<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">  
3 -<mapper namespace="cn.iocoder.yudao.module.bpm.dal.mysql.task.BpmActivityMapper">  
4 -  
5 - <update id="delHiActInstByTaskId">  
6 - UPDATE act_hi_actinst  
7 - SET delete_reason_ = 'delete task' WHERE task_id_ IN  
8 - <foreach collection="taskIdList" item="item" open="(" separator="," close=")">  
9 - #{item}  
10 - </foreach>  
11 - </update>  
12 - <delete id="delHiTaskInstByTaskId">  
13 - UPDATE act_hi_taskinst  
14 - SET delete_reason_ = 'delete task' WHERE id_ IN  
15 - <foreach collection="taskIdList" item="item" open="(" separator="," close=")">  
16 - #{item}  
17 - </foreach>  
18 - </delete>  
19 -  
20 - <select id="listAllByProcInstIdAndDelete"  
21 - resultType="cn.iocoder.yudao.module.bpm.dal.dataobject.task.BpmActivityDO">  
22 - SELECT id_ AS `id`,  
23 - rev_ AS `rev`,  
24 - proc_def_id_ AS `proc_def_id`,  
25 - proc_inst_id_ AS `process_instance_id`,  
26 - execution_id_ AS `execution_id`,  
27 - act_id_ AS `activity_id`,  
28 - task_id_ AS `task_id`,  
29 - call_proc_inst_id_ AS `call_proc_inst_id`,  
30 - act_name_ AS `activity_name`,  
31 - act_type_ AS `activity_type`,  
32 - assignee_ AS `assignee`,  
33 - start_time_ AS `start_time`,  
34 - end_time_ AS `end_time`,  
35 - transaction_order_ AS `transaction_order`,  
36 - duration_ AS `duration`,  
37 - delete_reason_ AS `delete_reason`,  
38 - tenant_id_ AS `tenant_id`  
39 - FROM act_hi_actinst aha  
40 - WHERE aha.proc_inst_id_ = #{procInstId}  
41 - AND aha.act_type_ != 'sequenceFlow'  
42 - LIMIT 500;  
43 - </select>  
44 -</mapper>  
yudao-module-bpm/yudao-module-bpm-biz/src/main/resources/mapper/BpmTaskExtMapper.xml deleted
1 -<?xml version="1.0" encoding="UTF-8"?>  
2 -<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">  
3 -<mapper namespace="cn.iocoder.yudao.module.bpm.dal.mysql.task.BpmTaskExtMapper">  
4 -  
5 - <update id="backByTaskId">  
6 - UPDATE bpm_task_ext  
7 - SET result=2,  
8 - `reason`=#{reason}  
9 - WHERE task_id = #{taskId}  
10 - </update>  
11 - <update id="delByTaskIds">  
12 - UPDATE bpm_task_ext  
13 - SET result=1,  
14 - `deleted`= true  
15 - WHERE `task_id` IN  
16 - <foreach collection="taskIdList" item="item" open="(" separator="," close=")">  
17 - #{item}  
18 - </foreach>  
19 - </update>  
20 -  
21 -</mapper>  
yudao-ui-admin/src/components/bpmnProcessDesigner/package/penal/base/ElementBaseInfo.vue
@@ -2,6 +2,8 @@ @@ -2,6 +2,8 @@
2 <div class="panel-tab__content"> 2 <div class="panel-tab__content">
3 <el-form size="mini" label-width="90px" :model="model" :rules="rules" @submit.native.prevent> 3 <el-form size="mini" label-width="90px" :model="model" :rules="rules" @submit.native.prevent>
4 <div v-if="elementBaseInfo.$type === 'bpmn:Process'"> <!-- 如果是 Process 信息的时候,使用自定义表单 --> 4 <div v-if="elementBaseInfo.$type === 'bpmn:Process'"> <!-- 如果是 Process 信息的时候,使用自定义表单 -->
  5 + <el-link href="https://doc.iocoder.cn/bpm/#_3-%E4%BC%9A%E7%AD%BE-%E6%88%96%E7%AD%BE"
  6 + type="danger" target="_blank">如何实现实现会签、或签?</el-link>
5 <el-form-item label="流程标识" prop="key"> 7 <el-form-item label="流程标识" prop="key">
6 <el-input v-model="model.key" placeholder="请输入流标标识" 8 <el-input v-model="model.key" placeholder="请输入流标标识"
7 :disabled="model.id !== undefined && model.id.length > 0" @change="handleKeyUpdate" /> 9 :disabled="model.id !== undefined && model.id.length > 0" @change="handleKeyUpdate" />
yudao-ui-admin/src/views/bpm/processInstance/detail.vue
@@ -412,15 +412,16 @@ export default { @@ -412,15 +412,16 @@ export default {
412 }, 412 },
413 /** 处理审批退回的操作 */ 413 /** 处理审批退回的操作 */
414 handleBack(task) { 414 handleBack(task) {
415 - const data = {  
416 - id: task.id,  
417 - assigneeUserId: 1  
418 - }  
419 - // this.$modal.msgError("暂不支持【--退回】功能!");  
420 - backTask(data).then(response => {  
421 - this.$modal.msgSuccess("回退成功!");  
422 - this.getDetail(); // 获得最新详情  
423 - }); 415 + this.$modal.msgError("暂不支持【退回】功能!");
  416 + // 可参考 http://blog.wya1.com/article/636697030/details/7296
  417 + // const data = {
  418 + // id: task.id,
  419 + // assigneeUserId: 1
  420 + // }
  421 + // backTask(data).then(response => {
  422 + // this.$modal.msgSuccess("回退成功!");
  423 + // this.getDetail(); // 获得最新详情
  424 + // });
424 } 425 }
425 } 426 }
426 }; 427 };