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 45  
46 46 ### JRebel ###
47 47 rebel.xml
  48 +
  49 +application-my.yaml
... ...
README.md
... ... @@ -23,7 +23,7 @@
23 23 * 权限认证使用 Spring Security & Token & Redis,支持多终端、多种用户的认证系统。
24 24 * 支持加载动态权限菜单,按钮级别权限控制,本地缓存提升性能。
25 25 * 支持 SaaS 多租户系统,可自定义每个租户的权限,提供透明化的多租户底层封装。
26   -* 工作流使用 Activiti + Flowable,支持动态表单、在线设计流程、多种任务分配方式。
  26 +* 工作流使用 Flowable,支持动态表单、在线设计流程、会签 / 或签、多种任务分配方式。
27 27 * 高效率开发,使用代码生成器可以一键生成前后端代码 + 单元测试 + Swagger 接口文档 + Validator 参数校验。
28 28 * 集成微信小程序、微信公众号、企业微信、钉钉等三方登陆,集成支付宝、微信等支付与退款。
29 29 * 集成阿里云、腾讯云、云片等短信渠道,集成 MinIO、阿里云、腾讯云、七牛云等云存储服务。
... ... @@ -167,7 +167,7 @@ ps:核心功能已经实现,正在对接微信小程序中...
167 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 168 | [Spring Security](https://github.com/spring-projects/spring-security) | Spring 安全框架 | 5.6.5 | [文档](http://www.iocoder.cn/Spring-Boot/Spring-Security/?yudao) |
169 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 171 | [Quartz](https://github.com/quartz-scheduler) | 任务调度组件 | 2.3.2 | [文档](http://www.iocoder.cn/Spring-Boot/Job/?yudao) |
172 172 | [Knife4j](https://gitee.com/xiaoym/knife4j) | Swagger 增强 UI 实现 | 3.0.3 | [文档](http://www.iocoder.cn/Spring-Boot/Swagger/?yudao) |
173 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 587 <artifactId>justauth-spring-boot-starter</artifactId> <!-- 社交登陆(例如说,个人微信、企业微信等等) -->
588 588 <version>${justauth.version}</version>
589 589 </dependency>
590   -
591 590 </dependencies>
592 591 </dependencyManagement>
593 592  
... ...
yudao-framework/pom.xml
... ... @@ -38,7 +38,6 @@
38 38 <module>yudao-spring-boot-starter-biz-data-permission</module>
39 39 <module>yudao-spring-boot-starter-biz-error-code</module>
40 40  
41   - <module>yudao-spring-boot-starter-activiti</module>
42 41 <module>yudao-spring-boot-starter-flowable</module>
43 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 9 import java.util.Arrays;
10 10 import java.util.List;
11 11  
  12 +/**
  13 + * Flowable 相关的工具方法
  14 + *
  15 + * @author 芋道源码
  16 + */
12 17 public class FlowableUtils {
13 18  
  19 + // ========== User 相关的工具方法 ==========
  20 +
14 21 public static void setAuthenticatedUserId(Long userId) {
15 22 Authentication.setAuthenticatedUserId(String.valueOf(userId));
16 23 }
... ... @@ -19,6 +26,8 @@ public class FlowableUtils {
19 26 Authentication.setAuthenticatedUserId(null);
20 27 }
21 28  
  29 + // ========== BPMN 相关的工具方法 ==========
  30 +
22 31 /**
23 32 * 获得 BPMN 流程中,指定的元素们
24 33 *
... ... @@ -59,4 +68,15 @@ public class FlowableUtils {
59 68 BpmnXMLConverter converter = new BpmnXMLConverter();
60 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 10 <modelVersion>4.0.0</modelVersion>
11 11 <modules>
12 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 14 </modules>
17 15 <artifactId>yudao-module-bpm</artifactId>
18 16 <packaging>pom</packaging>
... ... @@ -23,10 +21,7 @@
23 21 例如说:流程定义、表单配置、审核中心(我的申请、我的待办、我的已办)等等
24 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 25 </description>
31 26  
32 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 13 public enum BpmTaskAssignRuleTypeEnum {
14 14  
15 15 ROLE(10, "角色"),
16   -
17 16 DEPT_MEMBER(20, "部门的成员"), // 包括负责人
18 17 DEPT_LEADER(21, "部门的负责人"),
19 18 POST(22, "岗位"),
20   -
21 19 USER(30, "用户"),
22   -
23 20 USER_GROUP(40, "用户组"),
24   -
25 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 14 public enum BpmProcessInstanceDeleteReasonEnum {
15 15  
16 16 REJECT_TASK("不通过任务,原因:{}"), // 修改文案时,需要注意 isRejectReason 方法
17   - CANCEL_TASK("主动取消任务,原因:{}");
  17 + CANCEL_TASK("主动取消任务,原因:{}"),
  18 +
  19 + // ========== 流程任务的独有原因 ==========
  20 + MULTI_TASK_END("系统自动取消,原因:多任务审批已经满足条件,无需审批该任务"), // 多实例满足 condition 而结束时,其它任务实例任务会被取消,对应的删除原因是 MI_END
  21 +
  22 + ;
18 23  
19 24 private final String reason;
20 25  
... ... @@ -34,4 +39,20 @@ public enum BpmProcessInstanceDeleteReasonEnum {
34 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 1 package cn.iocoder.yudao.module.bpm.enums.task;
2 2  
  3 +import cn.iocoder.yudao.framework.common.util.object.ObjectUtils;
3 4 import lombok.AllArgsConstructor;
4 5 import lombok.Getter;
5 6  
... ... @@ -15,10 +16,16 @@ public enum BpmProcessInstanceResultEnum {
15 16 PROCESS(1, "处理中"),
16 17 APPROVE(2, "通过"),
17 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 30 private final Integer result;
24 31 /**
... ... @@ -26,4 +33,16 @@ public enum BpmProcessInstanceResultEnum {
26 33 */
27 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 8 <version>${revision}</version>
9 9 </parent>
10 10 <modelVersion>4.0.0</modelVersion>
11   - <artifactId>yudao-module-bpm-base</artifactId>
  11 + <artifactId>yudao-module-bpm-biz</artifactId>
12 12  
13 13 <name>${project.artifactId}</name>
14 14 <description>
... ... @@ -26,6 +26,11 @@
26 26 <artifactId>yudao-module-system-api</artifactId>
27 27 <version>${revision}</version>
28 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 36 <dependency>
... ... @@ -36,6 +41,10 @@
36 41 <groupId>cn.iocoder.boot</groupId>
37 42 <artifactId>yudao-spring-boot-starter-biz-data-permission</artifactId>
38 43 </dependency>
  44 + <dependency>
  45 + <groupId>cn.iocoder.boot</groupId>
  46 + <artifactId>yudao-spring-boot-starter-biz-tenant</artifactId>
  47 + </dependency>
39 48  
40 49 <!-- Web 相关 -->
41 50 <dependency>
... ... @@ -59,5 +68,10 @@
59 68 <groupId>cn.iocoder.boot</groupId>
60 69 <artifactId>yudao-spring-boot-starter-test</artifactId>
61 70 </dependency>
  71 + <!-- 工作流相关 -->
  72 + <dependency>
  73 + <groupId>cn.iocoder.boot</groupId>
  74 + <artifactId>yudao-spring-boot-starter-flowable</artifactId>
  75 + </dependency>
62 76 </dependencies>
63 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 55 taskAssignRuleService.updateTaskAssignRule(reqVO);
56 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