Commit 6d30d56633d22960a227ebdd1a3bf2fbd1c4fe11

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

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

Merge pull request !212 from 芋道源码/feature/bpm-back
Showing 244 changed files with 993 additions and 5313 deletions
.gitignore
... ... @@ -45,3 +45,5 @@ nbdist/
45 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
yudao-module-bpm/yudao-module-bpm-base/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/group/BpmUserGroupPageReqVO.java renamed to yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/group/BpmUserGroupPageReqVO.java
yudao-module-bpm/yudao-module-bpm-base/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/group/BpmUserGroupRespVO.java renamed to yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/group/BpmUserGroupRespVO.java
yudao-module-bpm/yudao-module-bpm-base/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/group/BpmUserGroupSimpleRespVO.java renamed to yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/group/BpmUserGroupSimpleRespVO.java
yudao-module-bpm/yudao-module-bpm-base/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/group/BpmUserGroupUpdateReqVO.java renamed to yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/group/BpmUserGroupUpdateReqVO.java
yudao-module-bpm/yudao-module-bpm-base/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/model/BpmModeImportReqVO.java renamed to yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/model/BpmModeImportReqVO.java
yudao-module-bpm/yudao-module-bpm-base/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/model/BpmModelBaseVO.java renamed to yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/model/BpmModelBaseVO.java
yudao-module-bpm/yudao-module-bpm-base/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/model/BpmModelCreateReqVO.java renamed to yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/model/BpmModelCreateReqVO.java
yudao-module-bpm/yudao-module-bpm-base/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/model/BpmModelPageItemRespVO.java renamed to yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/model/BpmModelPageItemRespVO.java
yudao-module-bpm/yudao-module-bpm-base/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/model/BpmModelPageReqVO.java renamed to yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/model/BpmModelPageReqVO.java
yudao-module-bpm/yudao-module-bpm-base/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/model/BpmModelRespVO.java renamed to yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/model/BpmModelRespVO.java
yudao-module-bpm/yudao-module-bpm-base/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/model/BpmModelUpdateReqVO.java renamed to yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/model/BpmModelUpdateReqVO.java
yudao-module-bpm/yudao-module-bpm-base/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/model/BpmModelUpdateStateReqVO.java renamed to yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/model/BpmModelUpdateStateReqVO.java
yudao-module-bpm/yudao-module-bpm-base/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/process/BpmProcessDefinitionListReqVO.java renamed to yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/process/BpmProcessDefinitionListReqVO.java
yudao-module-bpm/yudao-module-bpm-base/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/process/BpmProcessDefinitionPageItemRespVO.java renamed to yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/process/BpmProcessDefinitionPageItemRespVO.java
yudao-module-bpm/yudao-module-bpm-base/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/process/BpmProcessDefinitionPageReqVO.java renamed to yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/process/BpmProcessDefinitionPageReqVO.java
yudao-module-bpm/yudao-module-bpm-base/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/process/BpmProcessDefinitionRespVO.java renamed to yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/process/BpmProcessDefinitionRespVO.java
yudao-module-bpm/yudao-module-bpm-base/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/rule/BpmTaskAssignRuleBaseVO.java renamed to yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/rule/BpmTaskAssignRuleBaseVO.java
yudao-module-bpm/yudao-module-bpm-base/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/rule/BpmTaskAssignRuleCreateReqVO.java renamed to yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/rule/BpmTaskAssignRuleCreateReqVO.java
yudao-module-bpm/yudao-module-bpm-base/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/rule/BpmTaskAssignRuleRespVO.java renamed to yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/rule/BpmTaskAssignRuleRespVO.java
yudao-module-bpm/yudao-module-bpm-base/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/rule/BpmTaskAssignRuleUpdateReqVO.java renamed to yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/rule/BpmTaskAssignRuleUpdateReqVO.java
yudao-module-bpm/yudao-module-bpm-base/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/oa/BpmOALeaveController.http renamed to yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/oa/BpmOALeaveController.http
yudao-module-bpm/yudao-module-bpm-base/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/oa/BpmOALeaveController.java renamed to yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/oa/BpmOALeaveController.java
yudao-module-bpm/yudao-module-bpm-base/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/oa/package-info.java renamed to yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/oa/package-info.java
yudao-module-bpm/yudao-module-bpm-base/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/oa/vo/BpmOALeaveBaseVO.java renamed to yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/oa/vo/BpmOALeaveBaseVO.java
yudao-module-bpm/yudao-module-bpm-base/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/oa/vo/BpmOALeaveCreateReqVO.java renamed to yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/oa/vo/BpmOALeaveCreateReqVO.java
yudao-module-bpm/yudao-module-bpm-base/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/oa/vo/BpmOALeavePageReqVO.java renamed to yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/oa/vo/BpmOALeavePageReqVO.java
yudao-module-bpm/yudao-module-bpm-base/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/oa/vo/BpmOALeaveRespVO.java renamed to yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/oa/vo/BpmOALeaveRespVO.java
yudao-module-bpm/yudao-module-bpm-biz-flowable/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/BpmActivityController.java renamed to yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/BpmActivityController.java
yudao-module-bpm/yudao-module-bpm-biz-activiti/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/BpmProcessInstanceController.java renamed to yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/BpmProcessInstanceController.java
1 1 package cn.iocoder.yudao.module.bpm.controller.admin.task;
2 2  
3   -import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance.*;
4   -import cn.iocoder.yudao.module.bpm.service.task.BpmProcessInstanceService;
5 3 import cn.iocoder.yudao.framework.common.pojo.CommonResult;
6 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 7 import io.swagger.annotations.Api;
8 8 import io.swagger.annotations.ApiImplicitParam;
9 9 import io.swagger.annotations.ApiOperation;
... ... @@ -22,25 +22,9 @@ import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUti
22 22 @RequestMapping("/bpm/process-instance")
23 23 @Validated
24 24 public class BpmProcessInstanceController {
25   -
26 25 @Resource
27 26 private BpmProcessInstanceService processInstanceService;
28 27  
29   - @PostMapping("/create")
30   - @ApiOperation("新建流程实例")
31   - @PreAuthorize("@ss.hasPermission('bpm:process-instance:query')")
32   - public CommonResult<String> createProcessInstance(@Valid @RequestBody BpmProcessInstanceCreateReqVO createReqVO) {
33   - return success(processInstanceService.createProcessInstance(getLoginUserId(), createReqVO));
34   - }
35   -
36   - @DeleteMapping("/cancel")
37   - @ApiOperation(value = "取消流程实例", notes = "撤回发起的流程")
38   - @PreAuthorize("@ss.hasPermission('bpm:process-instance:cancel')")
39   - public CommonResult<Boolean> cancelProcessInstance(@Valid @RequestBody BpmProcessInstanceCancelReqVO cancelReqVO) {
40   - processInstanceService.cancelProcessInstance(getLoginUserId(), cancelReqVO);
41   - return success(true);
42   - }
43   -
44 28 @GetMapping("/my-page")
45 29 @ApiOperation(value = "获得我的实例分页列表", notes = "在【我的流程】菜单中,进行调用")
46 30 @PreAuthorize("@ss.hasPermission('bpm:process-instance:query')")
... ... @@ -49,6 +33,13 @@ public class BpmProcessInstanceController {
49 33 return success(processInstanceService.getMyProcessInstancePage(getLoginUserId(), pageReqVO));
50 34 }
51 35  
  36 + @PostMapping("/create")
  37 + @ApiOperation("新建流程实例")
  38 + @PreAuthorize("@ss.hasPermission('bpm:process-instance:query')")
  39 + public CommonResult<String> createProcessInstance(@Valid @RequestBody BpmProcessInstanceCreateReqVO createReqVO) {
  40 + return success(processInstanceService.createProcessInstance(getLoginUserId(), createReqVO));
  41 + }
  42 +
52 43 @GetMapping("/get")
53 44 @ApiOperation(value = "获得指定流程实例", notes = "在【流程详细】界面中,进行调用")
54 45 @ApiImplicitParam(name = "id", value = "流程实例的编号", required = true, dataTypeClass = String.class)
... ... @@ -57,4 +48,11 @@ public class BpmProcessInstanceController {
57 48 return success(processInstanceService.getProcessInstanceVO(id));
58 49 }
59 50  
  51 + @DeleteMapping("/cancel")
  52 + @ApiOperation(value = "取消流程实例", notes = "撤回发起的流程")
  53 + @PreAuthorize("@ss.hasPermission('bpm:process-instance:cancel')")
  54 + public CommonResult<Boolean> cancelProcessInstance(@Valid @RequestBody BpmProcessInstanceCancelReqVO cancelReqVO) {
  55 + processInstanceService.cancelProcessInstance(getLoginUserId(), cancelReqVO);
  56 + return success(true);
  57 + }
60 58 }
... ...
yudao-module-bpm/yudao-module-bpm-biz-activiti/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/BpmTaskController.java renamed to yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/BpmTaskController.java
1 1 package cn.iocoder.yudao.module.bpm.controller.admin.task;
2 2  
3   -import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.task.*;
4   -import cn.iocoder.yudao.module.bpm.service.task.BpmTaskService;
5 3 import cn.iocoder.yudao.framework.common.pojo.CommonResult;
6 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 7 import io.swagger.annotations.Api;
8 8 import io.swagger.annotations.ApiImplicitParam;
9 9 import io.swagger.annotations.ApiOperation;
... ... @@ -13,6 +13,7 @@ import org.springframework.web.bind.annotation.*;
13 13  
14 14 import javax.annotation.Resource;
15 15 import javax.validation.Valid;
  16 +
16 17 import java.util.List;
17 18  
18 19 import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
... ... @@ -41,6 +42,15 @@ public class BpmTaskController {
41 42 return success(taskService.getDoneTaskPage(getLoginUserId(), pageVO));
42 43 }
43 44  
  45 + @GetMapping("/list-by-process-instance-id")
  46 + @ApiOperation(value = "获得指定流程实例的任务列表", notes = "包括完成的、未完成的")
  47 + @ApiImplicitParam(name = "processInstanceId", value = "流程实例的编号", required = true, dataTypeClass = String.class)
  48 + @PreAuthorize("@ss.hasPermission('bpm:task:query')")
  49 + public CommonResult<List<BpmTaskRespVO>> getTaskListByProcessInstanceId(
  50 + @RequestParam("processInstanceId") String processInstanceId) {
  51 + return success(taskService.getTaskListByProcessInstanceId(processInstanceId));
  52 + }
  53 +
44 54 @PutMapping("/approve")
45 55 @ApiOperation("通过任务")
46 56 @PreAuthorize("@ss.hasPermission('bpm:task:update')")
... ... @@ -65,13 +75,4 @@ public class BpmTaskController {
65 75 return success(true);
66 76 }
67 77  
68   - @GetMapping("/list-by-process-instance-id")
69   - @ApiOperation(value = "获得指定流程实例的任务列表", notes = "包括完成的、未完成的")
70   - @ApiImplicitParam(name = "processInstanceId", value = "流程实例的编号", required = true, dataTypeClass = String.class)
71   - @PreAuthorize("@ss.hasPermission('bpm:task:query')")
72   - public CommonResult<List<BpmTaskRespVO>> getTaskListByProcessInstanceId(
73   - @RequestParam("processInstanceId") String processInstanceId) {
74   - return success(taskService.getTaskListByProcessInstanceId(processInstanceId));
75   - }
76   -
77 78 }
... ...
yudao-module-bpm/yudao-module-bpm-base/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/activity/BpmActivityRespVO.java renamed to yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/activity/BpmActivityRespVO.java
yudao-module-bpm/yudao-module-bpm-base/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/instance/BpmProcessInstanceCancelReqVO.java renamed to yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/instance/BpmProcessInstanceCancelReqVO.java
yudao-module-bpm/yudao-module-bpm-base/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/instance/BpmProcessInstanceCreateReqVO.java renamed to yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/instance/BpmProcessInstanceCreateReqVO.java
yudao-module-bpm/yudao-module-bpm-base/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/instance/BpmProcessInstanceMyPageReqVO.java renamed to yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/instance/BpmProcessInstanceMyPageReqVO.java
yudao-module-bpm/yudao-module-bpm-base/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/instance/BpmProcessInstancePageItemRespVO.java renamed to yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/instance/BpmProcessInstancePageItemRespVO.java
yudao-module-bpm/yudao-module-bpm-base/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/instance/BpmProcessInstanceRespVO.java renamed to yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/instance/BpmProcessInstanceRespVO.java
yudao-module-bpm/yudao-module-bpm-base/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/task/BpmTaskApproveReqVO.java renamed to yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/task/BpmTaskApproveReqVO.java
yudao-module-bpm/yudao-module-bpm-base/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/task/BpmTaskDonePageItemRespVO.java renamed to yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/task/BpmTaskDonePageItemRespVO.java
yudao-module-bpm/yudao-module-bpm-base/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/task/BpmTaskDonePageReqVO.java renamed to yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/task/BpmTaskDonePageReqVO.java
yudao-module-bpm/yudao-module-bpm-base/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/task/BpmTaskRejectReqVO.java renamed to yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/task/BpmTaskRejectReqVO.java
yudao-module-bpm/yudao-module-bpm-base/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/task/BpmTaskRespVO.java renamed to yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/task/BpmTaskRespVO.java
... ... @@ -35,5 +35,4 @@ public class BpmTaskRespVO extends BpmTaskDonePageItemRespVO {
35 35 private String deptName;
36 36  
37 37 }
38   -
39 38 }
... ...
yudao-module-bpm/yudao-module-bpm-base/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/task/BpmTaskTodoPageItemRespVO.java renamed to yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/task/BpmTaskTodoPageItemRespVO.java
yudao-module-bpm/yudao-module-bpm-base/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/task/BpmTaskTodoPageReqVO.java renamed to yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/task/BpmTaskTodoPageReqVO.java
yudao-module-bpm/yudao-module-bpm-base/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/task/BpmTaskUpdateAssigneeReqVO.java renamed to yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/task/BpmTaskUpdateAssigneeReqVO.java
yudao-module-bpm/yudao-module-bpm-base/src/main/java/cn/iocoder/yudao/module/bpm/controller/app/package-info.java renamed to yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/app/package-info.java
yudao-module-bpm/yudao-module-bpm-base/src/main/java/cn/iocoder/yudao/module/bpm/controller/package-info.java renamed to yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/package-info.java
yudao-module-bpm/yudao-module-bpm-base/src/main/java/cn/iocoder/yudao/module/bpm/convert/definition/BpmFormConvert.java renamed to yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/convert/definition/BpmFormConvert.java
yudao-module-bpm/yudao-module-bpm-biz-flowable/src/main/java/cn/iocoder/yudao/module/bpm/convert/definition/BpmModelConvert.java renamed to yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/convert/definition/BpmModelConvert.java
yudao-module-bpm/yudao-module-bpm-biz-flowable/src/main/java/cn/iocoder/yudao/module/bpm/convert/definition/BpmProcessDefinitionConvert.java renamed to yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/convert/definition/BpmProcessDefinitionConvert.java
yudao-module-bpm/yudao-module-bpm-biz-flowable/src/main/java/cn/iocoder/yudao/module/bpm/convert/definition/BpmTaskAssignRuleConvert.java renamed to yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/convert/definition/BpmTaskAssignRuleConvert.java
yudao-module-bpm/yudao-module-bpm-base/src/main/java/cn/iocoder/yudao/module/bpm/convert/definition/BpmUserGroupConvert.java renamed to yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/convert/definition/BpmUserGroupConvert.java
yudao-module-bpm/yudao-module-bpm-base/src/main/java/cn/iocoder/yudao/module/bpm/convert/message/BpmMessageConvert.java renamed to yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/convert/message/BpmMessageConvert.java
yudao-module-bpm/yudao-module-bpm-base/src/main/java/cn/iocoder/yudao/module/bpm/convert/oa/BpmOALeaveConvert.java renamed to yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/convert/oa/BpmOALeaveConvert.java
yudao-module-bpm/yudao-module-bpm-biz-activiti/src/main/java/cn/iocoder/yudao/module/bpm/convert/package-info.java renamed to yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/convert/package-info.java
yudao-module-bpm/yudao-module-bpm-biz-flowable/src/main/java/cn/iocoder/yudao/module/bpm/convert/task/BpmActivityConvert.java renamed to yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/convert/task/BpmActivityConvert.java
yudao-module-bpm/yudao-module-bpm-biz-flowable/src/main/java/cn/iocoder/yudao/module/bpm/convert/task/BpmProcessInstanceConvert.java renamed to yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/convert/task/BpmProcessInstanceConvert.java
yudao-module-bpm/yudao-module-bpm-biz-flowable/src/main/java/cn/iocoder/yudao/module/bpm/convert/task/BpmTaskConvert.java renamed to yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/convert/task/BpmTaskConvert.java
... ... @@ -9,7 +9,6 @@ import cn.iocoder.yudao.module.bpm.dal.dataobject.task.BpmTaskExtDO;
9 9 import cn.iocoder.yudao.module.bpm.service.message.dto.BpmMessageSendWhenTaskCreatedReqDTO;
10 10 import cn.iocoder.yudao.module.system.api.dept.dto.DeptRespDTO;
11 11 import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
12   -
13 12 import org.flowable.common.engine.impl.db.SuspensionState;
14 13 import org.flowable.engine.history.HistoricProcessInstance;
15 14 import org.flowable.engine.runtime.ProcessInstance;
... ... @@ -17,9 +16,12 @@ import org.flowable.task.api.Task;
17 16 import org.flowable.task.api.history.HistoricTaskInstance;
18 17 import org.mapstruct.*;
19 18 import org.mapstruct.factory.Mappers;
  19 +import org.springframework.beans.BeanUtils;
20 20  
  21 +import java.util.Collections;
21 22 import java.util.List;
22 23 import java.util.Map;
  24 +import java.util.stream.Collectors;
23 25  
24 26 /**
25 27 * Bpm 任务 Convert
... ... @@ -31,8 +33,37 @@ public interface BpmTaskConvert {
31 33  
32 34 BpmTaskConvert INSTANCE = Mappers.getMapper(BpmTaskConvert.class);
33 35  
34   - default List<BpmTaskTodoPageItemRespVO> convertList1(List<Task> tasks, Map<String, ProcessInstance> processInstanceMap,
35   - Map<Long, AdminUserRespDTO> userMap) {
  36 + /**
  37 + * 复制对象
  38 + *
  39 + * @param source 源 要复制的对象
  40 + * @param target 目标 复制到此对象
  41 + * @param <T>
  42 + *
  43 + * @return
  44 + */
  45 + public static <T> T copy(Object source, Class<T> target) {
  46 + if (source == null || target == null) {
  47 + return null;
  48 + }
  49 + try {
  50 + T newInstance = target.newInstance();
  51 + BeanUtils.copyProperties(source, newInstance);
  52 + return newInstance;
  53 + } catch (Exception e) {
  54 + throw new RuntimeException(e);
  55 + }
  56 + }
  57 +
  58 + default <T, K> List<K> copyList(List<T> source, Class<K> target) {
  59 + if (null == source || source.isEmpty()) {
  60 + return Collections.emptyList();
  61 + }
  62 + return source.stream().map(e -> copy(e, target)).collect(Collectors.toList());
  63 + }
  64 +
  65 + default List<BpmTaskTodoPageItemRespVO> convertList1(List<Task> tasks,
  66 + Map<String, ProcessInstance> processInstanceMap, Map<Long, AdminUserRespDTO> userMap) {
36 67 return CollectionUtils.convertList(tasks, task -> {
37 68 BpmTaskTodoPageItemRespVO respVO = convert1(task);
38 69 ProcessInstance processInstance = processInstanceMap.get(task.getProcessInstanceId());
... ... @@ -49,13 +80,12 @@ public interface BpmTaskConvert {
49 80  
50 81 @Named("convertSuspendedToSuspensionState")
51 82 default Integer convertSuspendedToSuspensionState(boolean suspended) {
52   - return suspended ? SuspensionState.SUSPENDED.getStateCode() :
53   - SuspensionState.ACTIVE.getStateCode();
  83 + return suspended ? SuspensionState.SUSPENDED.getStateCode() : SuspensionState.ACTIVE.getStateCode();
54 84 }
55 85  
56   - default List<BpmTaskDonePageItemRespVO> convertList2(List<HistoricTaskInstance> tasks, Map<String, BpmTaskExtDO> bpmTaskExtDOMap,
57   - Map<String, HistoricProcessInstance> historicProcessInstanceMap,
58   - Map<Long, AdminUserRespDTO> userMap) {
  86 + default List<BpmTaskDonePageItemRespVO> convertList2(List<HistoricTaskInstance> tasks,
  87 + Map<String, BpmTaskExtDO> bpmTaskExtDOMap, Map<String, HistoricProcessInstance> historicProcessInstanceMap,
  88 + Map<Long, AdminUserRespDTO> userMap) {
59 89 return CollectionUtils.convertList(tasks, task -> {
60 90 BpmTaskDonePageItemRespVO respVO = convert2(task);
61 91 BpmTaskExtDO taskExtDO = bpmTaskExtDOMap.get(task.getId());
... ... @@ -71,18 +101,16 @@ public interface BpmTaskConvert {
71 101  
72 102 BpmTaskDonePageItemRespVO convert2(HistoricTaskInstance bean);
73 103  
74   - @Mappings({
75   - @Mapping(source = "processInstance.id", target = "id"),
76   - @Mapping(source = "processInstance.name", target = "name"),
77   - @Mapping(source = "processInstance.startUserId", target = "startUserId"),
78   - @Mapping(source = "processInstance.processDefinitionId", target = "processDefinitionId"),
79   - @Mapping(source = "startUser.nickname", target = "startUserNickname")
80   - })
  104 + @Mappings({@Mapping(source = "processInstance.id", target = "id"),
  105 + @Mapping(source = "processInstance.name", target = "name"),
  106 + @Mapping(source = "processInstance.startUserId", target = "startUserId"),
  107 + @Mapping(source = "processInstance.processDefinitionId", target = "processDefinitionId"),
  108 + @Mapping(source = "startUser.nickname", target = "startUserNickname")})
81 109 BpmTaskTodoPageItemRespVO.ProcessInstance convert(ProcessInstance processInstance, AdminUserRespDTO startUser);
82 110  
83   - default List<BpmTaskRespVO> convertList3(List<HistoricTaskInstance> tasks, Map<String, BpmTaskExtDO> bpmTaskExtDOMap,
84   - HistoricProcessInstance processInstance, Map<Long, AdminUserRespDTO> userMap,
85   - Map<Long, DeptRespDTO> deptMap) {
  111 + default List<BpmTaskRespVO> convertList3(List<HistoricTaskInstance> tasks,
  112 + Map<String, BpmTaskExtDO> bpmTaskExtDOMap, HistoricProcessInstance processInstance,
  113 + Map<Long, AdminUserRespDTO> userMap, Map<Long, DeptRespDTO> deptMap) {
86 114 return CollectionUtils.convertList(tasks, task -> {
87 115 BpmTaskRespVO respVO = convert3(task);
88 116 BpmTaskExtDO taskExtDO = bpmTaskExtDOMap.get(task.getId());
... ... @@ -111,37 +139,30 @@ public interface BpmTaskConvert {
111 139 @Mapping(target = "id", ignore = true)
112 140 void copyTo(BpmTaskExtDO from, @MappingTarget BpmTaskDonePageItemRespVO to);
113 141  
114   - @Mappings({
115   - @Mapping(source = "processInstance.id", target = "id"),
116   - @Mapping(source = "processInstance.name", target = "name"),
117   - @Mapping(source = "processInstance.startUserId", target = "startUserId"),
118   - @Mapping(source = "processInstance.processDefinitionId", target = "processDefinitionId"),
119   - @Mapping(source = "startUser.nickname", target = "startUserNickname")
120   - })
121   - BpmTaskTodoPageItemRespVO.ProcessInstance convert(HistoricProcessInstance processInstance, AdminUserRespDTO startUser);
122   -
123   - default BpmTaskExtDO convert2TaskExt(Task task){
124   - BpmTaskExtDO taskExtDO = new BpmTaskExtDO()
125   - .setTaskId(task.getId())
126   - .setAssigneeUserId(NumberUtils.parseLong(task.getAssignee()))
127   - .setName(task.getName())
128   - .setProcessDefinitionId(task.getProcessDefinitionId())
129   - .setProcessInstanceId(task.getProcessInstanceId());
  142 + @Mappings({@Mapping(source = "processInstance.id", target = "id"),
  143 + @Mapping(source = "processInstance.name", target = "name"),
  144 + @Mapping(source = "processInstance.startUserId", target = "startUserId"),
  145 + @Mapping(source = "processInstance.processDefinitionId", target = "processDefinitionId"),
  146 + @Mapping(source = "startUser.nickname", target = "startUserNickname")})
  147 + BpmTaskTodoPageItemRespVO.ProcessInstance convert(HistoricProcessInstance processInstance,
  148 + AdminUserRespDTO startUser);
  149 +
  150 + default BpmTaskExtDO convert2TaskExt(Task task) {
  151 + BpmTaskExtDO taskExtDO = new BpmTaskExtDO().setTaskId(task.getId())
  152 + .setAssigneeUserId(NumberUtils.parseLong(task.getAssignee())).setName(task.getName())
  153 + .setProcessDefinitionId(task.getProcessDefinitionId()).setProcessInstanceId(task.getProcessInstanceId());
130 154 taskExtDO.setCreateTime(task.getCreateTime());
131 155 return taskExtDO;
132 156 }
133 157  
134   - default BpmMessageSendWhenTaskCreatedReqDTO convert(ProcessInstance processInstance, AdminUserRespDTO startUser, Task task) {
  158 + default BpmMessageSendWhenTaskCreatedReqDTO convert(ProcessInstance processInstance, AdminUserRespDTO startUser,
  159 + Task task) {
135 160 BpmMessageSendWhenTaskCreatedReqDTO reqDTO = new BpmMessageSendWhenTaskCreatedReqDTO();
136 161 reqDTO.setProcessInstanceId(processInstance.getProcessInstanceId())
137   - .setProcessInstanceName(processInstance.getName())
138   - .setStartUserId(startUser.getId())
139   - .setStartUserNickname(startUser.getNickname())
140   - .setTaskId(task.getId())
141   - .setTaskName(task.getName())
142   - .setAssigneeUserId(NumberUtils.parseLong(task.getAssignee()));
  162 + .setProcessInstanceName(processInstance.getName()).setStartUserId(startUser.getId())
  163 + .setStartUserNickname(startUser.getNickname()).setTaskId(task.getId()).setTaskName(task.getName())
  164 + .setAssigneeUserId(NumberUtils.parseLong(task.getAssignee()));
143 165 return reqDTO;
144 166 }
145   -}
146   -
147 167  
  168 +}
... ...
yudao-module-bpm/yudao-module-bpm-base/src/main/java/cn/iocoder/yudao/module/bpm/convert/task/package-info.java renamed to yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/convert/task/package-info.java
yudao-module-bpm/yudao-module-bpm-biz-activiti/src/main/java/cn/iocoder/yudao/module/bpm/convert/《芋道 Spring Boot 对象转换 MapStruct 入门》.md renamed to yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/convert/《芋道 Spring Boot 对象转换 MapStruct 入门》.md
yudao-module-bpm/yudao-module-bpm-base/src/main/java/cn/iocoder/yudao/module/bpm/dal/dataobject/definition/BpmFormDO.java renamed to yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/dal/dataobject/definition/BpmFormDO.java
1 1 package cn.iocoder.yudao.module.bpm.dal.dataobject.definition;
2 2  
3 3 import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
4   -import com.baomidou.mybatisplus.annotation.KeySequence;
5 4 import com.baomidou.mybatisplus.annotation.TableField;
6 5 import com.baomidou.mybatisplus.annotation.TableId;
7 6 import com.baomidou.mybatisplus.annotation.TableName;
... ... @@ -17,7 +16,6 @@ import java.util.List;
17 16 * @author 芋道源码
18 17 */
19 18 @TableName(value = "bpm_form", autoResultMap = true)
20   -@KeySequence("bpm_form_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
21 19 @Data
22 20 @EqualsAndHashCode(callSuper = true)
23 21 @ToString(callSuper = true)
... ...
yudao-module-bpm/yudao-module-bpm-base/src/main/java/cn/iocoder/yudao/module/bpm/dal/dataobject/definition/BpmProcessDefinitionExtDO.java renamed to yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/dal/dataobject/definition/BpmProcessDefinitionExtDO.java
... ... @@ -2,7 +2,6 @@ package cn.iocoder.yudao.module.bpm.dal.dataobject.definition;
2 2  
3 3 import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
4 4 import cn.iocoder.yudao.module.bpm.enums.definition.BpmModelFormTypeEnum;
5   -import com.baomidou.mybatisplus.annotation.KeySequence;
6 5 import com.baomidou.mybatisplus.annotation.TableField;
7 6 import com.baomidou.mybatisplus.annotation.TableId;
8 7 import com.baomidou.mybatisplus.annotation.TableName;
... ... @@ -18,7 +17,6 @@ import java.util.List;
18 17 * @author 芋道源码
19 18 */
20 19 @TableName(value = "bpm_process_definition_ext", autoResultMap = true)
21   -@KeySequence("bpm_process_definition_ext_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
22 20 @Data
23 21 @EqualsAndHashCode(callSuper = true)
24 22 @ToString(callSuper = true)
... ...
yudao-module-bpm/yudao-module-bpm-base/src/main/java/cn/iocoder/yudao/module/bpm/dal/dataobject/definition/BpmTaskAssignRuleDO.java renamed to yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/dal/dataobject/definition/BpmTaskAssignRuleDO.java
... ... @@ -4,7 +4,6 @@ import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
4 4 import cn.iocoder.yudao.framework.mybatis.core.type.JsonLongSetTypeHandler;
5 5 import cn.iocoder.yudao.module.bpm.enums.definition.BpmTaskAssignRuleTypeEnum;
6 6 import cn.iocoder.yudao.module.bpm.enums.definition.BpmTaskRuleScriptEnum;
7   -import com.baomidou.mybatisplus.annotation.KeySequence;
8 7 import com.baomidou.mybatisplus.annotation.TableField;
9 8 import com.baomidou.mybatisplus.annotation.TableId;
10 9 import com.baomidou.mybatisplus.annotation.TableName;
... ... @@ -22,7 +21,6 @@ import java.util.Set;
22 21 * @author 芋道源码
23 22 */
24 23 @TableName(value = "bpm_task_assign_rule", autoResultMap = true)
25   -@KeySequence("bpm_task_assign_rule_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
26 24 @Data
27 25 @EqualsAndHashCode(callSuper = true)
28 26 @ToString(callSuper = true)
... ... @@ -33,9 +31,8 @@ public class BpmTaskAssignRuleDO extends BaseDO {
33 31  
34 32 /**
35 33 * {@link #processDefinitionId} 空串,用于标识属于流程模型,而不属于流程定义
36   - * 不使用空串的原因,Oracle 针对空串,会处理成 null,进而导致无法检索
37 34 */
38   - public static final String PROCESS_DEFINITION_ID_NULL = "DEFAULT";
  35 + public static final String PROCESS_DEFINITION_ID_NULL = "";
39 36  
40 37 /**
41 38 * 编号
... ... @@ -67,6 +64,7 @@ public class BpmTaskAssignRuleDO extends BaseDO {
67 64 *
68 65 * 枚举 {@link BpmTaskAssignRuleTypeEnum}
69 66 */
  67 + @TableField("`type`")
70 68 private Integer type;
71 69 /**
72 70 * 规则值数组,一般关联指定表的编号
... ...
yudao-module-bpm/yudao-module-bpm-base/src/main/java/cn/iocoder/yudao/module/bpm/dal/dataobject/definition/BpmTaskMessageRuleDO.java renamed to yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/dal/dataobject/definition/BpmTaskMessageRuleDO.java
yudao-module-bpm/yudao-module-bpm-base/src/main/java/cn/iocoder/yudao/module/bpm/dal/dataobject/definition/BpmUserGroupDO.java renamed to yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/dal/dataobject/definition/BpmUserGroupDO.java
... ... @@ -3,7 +3,6 @@ package cn.iocoder.yudao.module.bpm.dal.dataobject.definition;
3 3 import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
4 4 import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
5 5 import cn.iocoder.yudao.framework.mybatis.core.type.JsonLongSetTypeHandler;
6   -import com.baomidou.mybatisplus.annotation.KeySequence;
7 6 import com.baomidou.mybatisplus.annotation.TableField;
8 7 import com.baomidou.mybatisplus.annotation.TableId;
9 8 import com.baomidou.mybatisplus.annotation.TableName;
... ... @@ -17,7 +16,6 @@ import java.util.Set;
17 16 * @author 芋道源码
18 17 */
19 18 @TableName(value = "bpm_user_group", autoResultMap = true)
20   -@KeySequence("bpm_user_group_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
21 19 @Data
22 20 @EqualsAndHashCode(callSuper = true)
23 21 @ToString(callSuper = true)
... ...
yudao-module-bpm/yudao-module-bpm-base/src/main/java/cn/iocoder/yudao/module/bpm/dal/dataobject/oa/BpmOALeaveDO.java renamed to yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/dal/dataobject/oa/BpmOALeaveDO.java
1 1 package cn.iocoder.yudao.module.bpm.dal.dataobject.oa;
2 2  
3   -import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
4 3 import cn.iocoder.yudao.module.bpm.enums.task.BpmProcessInstanceResultEnum;
5   -import com.baomidou.mybatisplus.annotation.KeySequence;
6   -import com.baomidou.mybatisplus.annotation.TableId;
7   -import com.baomidou.mybatisplus.annotation.TableName;
8 4 import lombok.*;
9   -
10   -import java.util.Date;
  5 +import java.util.*;
  6 +import com.baomidou.mybatisplus.annotation.*;
  7 +import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
11 8  
12 9 /**
13 10 * OA 请假申请 DO
... ... @@ -18,7 +15,6 @@ import java.util.Date;
18 15 * @author 芋道源码
19 16 */
20 17 @TableName("bpm_oa_leave")
21   -@KeySequence("bpm_oa_leave_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
22 18 @Data
23 19 @EqualsAndHashCode(callSuper = true)
24 20 @ToString(callSuper = true)
... ... @@ -41,7 +37,8 @@ public class BpmOALeaveDO extends BaseDO {
41 37 /**
42 38 * 请假类型
43 39 */
44   - private Integer type;
  40 + @TableField("`type`")
  41 + private String type;
45 42 /**
46 43 * 原因
47 44 */
... ...
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/dal/dataobject/task/BpmActivityDO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.bpm.dal.dataobject.task;
  2 +
  3 +import com.fasterxml.jackson.annotation.JsonFormat;
  4 +import lombok.*;
  5 +import org.springframework.format.annotation.DateTimeFormat;
  6 +
  7 +import java.util.Date;
  8 +
  9 +import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
  10 +import static cn.iocoder.yudao.framework.common.util.date.DateUtils.TIME_ZONE_DEFAULT;
  11 +
  12 +/**
  13 + * 任务流程关联表
  14 + *
  15 + * @author kemengkai
  16 + * @create 2022-05-09 10:33
  17 + */
  18 +@Data
  19 +@AllArgsConstructor
  20 +@NoArgsConstructor
  21 +public class BpmActivityDO {
  22 +
  23 + /**
  24 + * 任务流程关联id
  25 + */
  26 + private String id;
  27 +
  28 + /**
  29 + * 审批结果
  30 + */
  31 + private Integer rev;
  32 +
  33 + /**
  34 + * 任务流程部署id
  35 + */
  36 + private String procDefId;
  37 +
  38 + /**
  39 + * 任务流程id
  40 + */
  41 + private String processInstanceId;
  42 +
  43 + /**
  44 + * 任务执行id
  45 + */
  46 + private String executionId;
  47 +
  48 + /**
  49 + * 任务key
  50 + */
  51 + private String activityId;
  52 +
  53 + /**
  54 + * 任务id
  55 + */
  56 + private String taskId;
  57 +
  58 + /**
  59 + * 调用流程id
  60 + */
  61 + private String callProcInstId;
  62 +
  63 + /**
  64 + * 任务名称
  65 + */
  66 + private String activityName;
  67 +
  68 + /**
  69 + * 任务类型
  70 + */
  71 + private String activityType;
  72 +
  73 + /**
  74 + * 任务审批人id
  75 + */
  76 + private String assignee;
  77 +
  78 + /**
  79 + * 任务开始时间
  80 + */
  81 + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
  82 + @JsonFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND, timezone = TIME_ZONE_DEFAULT)
  83 + private Date startTime;
  84 +
  85 + /**
  86 + * 任务结束时间
  87 + */
  88 + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
  89 + @JsonFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND, timezone = TIME_ZONE_DEFAULT)
  90 + private Date endTime;
  91 +
  92 + private Integer transactionOrder;
  93 +
  94 + private Long duration;
  95 +
  96 + /**
  97 + * 删除结果
  98 + */
  99 + private String deleteReason;
  100 +
  101 + /**
  102 + * 租户id
  103 + */
  104 + private String tenantId;
  105 +}
... ...
yudao-module-bpm/yudao-module-bpm-base/src/main/java/cn/iocoder/yudao/module/bpm/dal/dataobject/task/BpmProcessInstanceExtDO.java renamed to yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/dal/dataobject/task/BpmProcessInstanceExtDO.java
... ... @@ -3,7 +3,6 @@ package cn.iocoder.yudao.module.bpm.dal.dataobject.task;
3 3 import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
4 4 import cn.iocoder.yudao.module.bpm.enums.task.BpmProcessInstanceResultEnum;
5 5 import cn.iocoder.yudao.module.bpm.enums.task.BpmProcessInstanceStatusEnum;
6   -import com.baomidou.mybatisplus.annotation.KeySequence;
7 6 import com.baomidou.mybatisplus.annotation.TableField;
8 7 import com.baomidou.mybatisplus.annotation.TableId;
9 8 import com.baomidou.mybatisplus.annotation.TableName;
... ... @@ -22,7 +21,6 @@ import java.util.Map;
22 21 * @author 芋道源码
23 22 */
24 23 @TableName(value = "bpm_process_instance_ext", autoResultMap = true)
25   -@KeySequence("bpm_process_instance_ext_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
26 24 @Data
27 25 @EqualsAndHashCode(callSuper = true)
28 26 @ToString(callSuper = true)
... ...
yudao-module-bpm/yudao-module-bpm-base/src/main/java/cn/iocoder/yudao/module/bpm/dal/dataobject/task/BpmTaskExtDO.java renamed to yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/dal/dataobject/task/BpmTaskExtDO.java
... ... @@ -2,8 +2,6 @@ package cn.iocoder.yudao.module.bpm.dal.dataobject.task;
2 2  
3 3 import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
4 4 import cn.iocoder.yudao.module.bpm.enums.task.BpmProcessInstanceResultEnum;
5   -import com.baomidou.mybatisplus.annotation.KeySequence;
6   -import com.baomidou.mybatisplus.annotation.TableField;
7 5 import com.baomidou.mybatisplus.annotation.TableId;
8 6 import com.baomidou.mybatisplus.annotation.TableName;
9 7 import lombok.Data;
... ... @@ -19,7 +17,6 @@ import java.util.Date;
19 17 * @author 芋道源码
20 18 */
21 19 @TableName(value = "bpm_task_ext", autoResultMap = true)
22   -@KeySequence("bpm_task_ext_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
23 20 @Data
24 21 @EqualsAndHashCode(callSuper = true)
25 22 @ToString(callSuper = true)
... ... @@ -30,6 +27,7 @@ public class BpmTaskExtDO extends BaseDO {
30 27 */
31 28 @TableId
32 29 private Long id;
  30 +
33 31 /**
34 32 * 任务的审批人
35 33 *
... ...
yudao-module-bpm/yudao-module-bpm-base/src/main/java/cn/iocoder/yudao/module/bpm/dal/mysql/definition/BpmFormMapper.java renamed to yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/dal/mysql/definition/BpmFormMapper.java
1 1 package cn.iocoder.yudao.module.bpm.dal.mysql.definition;
2 2  
3 3  
4   -import cn.iocoder.yudao.framework.common.pojo.PageResult;
5   -import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
6   -import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
7 4 import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.form.BpmFormPageReqVO;
8 5 import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmFormDO;
  6 +import cn.iocoder.yudao.framework.common.pojo.PageResult;
  7 +import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
  8 +import cn.iocoder.yudao.framework.mybatis.core.query.QueryWrapperX;
9 9 import org.apache.ibatis.annotations.Mapper;
10 10  
11 11 /**
... ... @@ -17,9 +17,9 @@ import org.apache.ibatis.annotations.Mapper;
17 17 public interface BpmFormMapper extends BaseMapperX<BpmFormDO> {
18 18  
19 19 default PageResult<BpmFormDO> selectPage(BpmFormPageReqVO reqVO) {
20   - return selectPage(reqVO, new LambdaQueryWrapperX<BpmFormDO>()
21   - .likeIfPresent(BpmFormDO::getName, reqVO.getName())
22   - .orderByDesc(BpmFormDO::getId));
  20 + return selectPage(reqVO, new QueryWrapperX<BpmFormDO>()
  21 + .likeIfPresent("name", reqVO.getName())
  22 + .orderByDesc("id"));
23 23 }
24 24  
25 25 }
... ...
yudao-module-bpm/yudao-module-bpm-base/src/main/java/cn/iocoder/yudao/module/bpm/dal/mysql/definition/BpmProcessDefinitionExtMapper.java renamed to yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/dal/mysql/definition/BpmProcessDefinitionExtMapper.java
1 1 package cn.iocoder.yudao.module.bpm.dal.mysql.definition;
2 2  
3   -import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
  3 +import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
4 4 import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmProcessDefinitionExtDO;
  5 +import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
5 6 import org.apache.ibatis.annotations.Mapper;
6 7  
7 8 import java.util.Collection;
... ... @@ -11,11 +12,11 @@ import java.util.List;
11 12 public interface BpmProcessDefinitionExtMapper extends BaseMapperX<BpmProcessDefinitionExtDO> {
12 13  
13 14 default List<BpmProcessDefinitionExtDO> selectListByProcessDefinitionIds(Collection<String> processDefinitionIds) {
14   - return selectList(BpmProcessDefinitionExtDO::getProcessDefinitionId, processDefinitionIds);
  15 + return selectList("process_definition_id", processDefinitionIds);
15 16 }
16 17  
17 18 default BpmProcessDefinitionExtDO selectByProcessDefinitionId(String processDefinitionId) {
18   - return selectOne(BpmProcessDefinitionExtDO::getProcessDefinitionId, processDefinitionId);
  19 + return selectOne("process_definition_id", processDefinitionId);
19 20 }
20 21  
21 22 }
... ...
yudao-module-bpm/yudao-module-bpm-base/src/main/java/cn/iocoder/yudao/module/bpm/dal/mysql/definition/BpmTaskAssignRuleMapper.java renamed to yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/dal/mysql/definition/BpmTaskAssignRuleMapper.java
1 1 package cn.iocoder.yudao.module.bpm.dal.mysql.definition;
2 2  
3   -import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
4   -import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
5 3 import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmTaskAssignRuleDO;
  4 +import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
  5 +import cn.iocoder.yudao.framework.mybatis.core.query.QueryWrapperX;
6 6 import org.apache.ibatis.annotations.Mapper;
7 7 import org.springframework.lang.Nullable;
8 8  
... ... @@ -13,23 +13,25 @@ public interface BpmTaskAssignRuleMapper extends BaseMapperX&lt;BpmTaskAssignRuleDO
13 13  
14 14 default List<BpmTaskAssignRuleDO> selectListByProcessDefinitionId(String processDefinitionId,
15 15 @Nullable String taskDefinitionKey) {
16   - return selectList(new LambdaQueryWrapperX<BpmTaskAssignRuleDO>()
17   - .eq(BpmTaskAssignRuleDO::getProcessDefinitionId, processDefinitionId)
18   - .eqIfPresent(BpmTaskAssignRuleDO::getTaskDefinitionKey, taskDefinitionKey));
  16 + return selectList(new QueryWrapperX<BpmTaskAssignRuleDO>()
  17 + .eq("process_definition_id", processDefinitionId)
  18 + .eqIfPresent("task_definition_key", taskDefinitionKey));
19 19 }
20 20  
21 21 default List<BpmTaskAssignRuleDO> selectListByModelId(String modelId) {
22   - return selectList(new LambdaQueryWrapperX<BpmTaskAssignRuleDO>()
23   - .eq(BpmTaskAssignRuleDO::getModelId, modelId)
24   - .eq(BpmTaskAssignRuleDO::getProcessDefinitionId, BpmTaskAssignRuleDO.PROCESS_DEFINITION_ID_NULL));
  22 + return selectList(new QueryWrapperX<BpmTaskAssignRuleDO>()
  23 + .eq("model_id", modelId)
  24 + .eq("process_definition_id", BpmTaskAssignRuleDO.PROCESS_DEFINITION_ID_NULL));
25 25 }
26 26  
27 27 default BpmTaskAssignRuleDO selectListByModelIdAndTaskDefinitionKey(String modelId,
28 28 String taskDefinitionKey) {
29   - return selectOne(new LambdaQueryWrapperX<BpmTaskAssignRuleDO>()
30   - .eq(BpmTaskAssignRuleDO::getModelId, modelId)
31   - .eq(BpmTaskAssignRuleDO::getProcessDefinitionId, BpmTaskAssignRuleDO.PROCESS_DEFINITION_ID_NULL)
32   - .eq(BpmTaskAssignRuleDO::getTaskDefinitionKey, taskDefinitionKey));
  29 + return selectOne(new QueryWrapperX<BpmTaskAssignRuleDO>()
  30 + .eq("model_id", modelId)
  31 + .eq("process_definition_id", BpmTaskAssignRuleDO.PROCESS_DEFINITION_ID_NULL)
  32 + .eq("task_definition_key", taskDefinitionKey));
33 33 }
34 34  
  35 +
  36 +
35 37 }
... ...
yudao-module-bpm/yudao-module-bpm-base/src/main/java/cn/iocoder/yudao/module/bpm/dal/mysql/definition/BpmUserGroupMapper.java renamed to yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/dal/mysql/definition/BpmUserGroupMapper.java
yudao-module-bpm/yudao-module-bpm-base/src/main/java/cn/iocoder/yudao/module/bpm/dal/mysql/oa/BpmOALeaveMapper.java renamed to yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/dal/mysql/oa/BpmOALeaveMapper.java
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/dal/mysql/task/BpmActivityMapper.java 0 → 100644
  1 +package cn.iocoder.yudao.module.bpm.dal.mysql.task;
  2 +
  3 +import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
  4 +import cn.iocoder.yudao.module.bpm.dal.dataobject.task.BpmActivityDO;
  5 +import org.apache.ibatis.annotations.Mapper;
  6 +import org.apache.ibatis.annotations.Param;
  7 +
  8 +import java.util.List;
  9 +
  10 +@Mapper
  11 +public interface BpmActivityMapper extends BaseMapperX<BpmActivityDO> {
  12 +
  13 +
  14 + // TODO @ke:可以试试,把 activiti 的表,映射成对应的实体,然后读取下。我们尽量避免 xml 操作,因为要做多 db 类型的支持,例如说 oracle 等。通过 mybatis plus 帮助我们生成不同数据库的表操作
  15 + /**
  16 + * 获取指定流程的历史任务
  17 + *
  18 + * @param procInstId 流程id
  19 + *
  20 + * @return 返回历史任务
  21 + */
  22 + List<BpmActivityDO> listAllByProcInstIdAndDelete(@Param("procInstId") String procInstId);
  23 +
  24 + /**
  25 + * 逻辑删除hiActInst表任务
  26 + *
  27 + * @param taskIdList 任务列表
  28 + *
  29 + * @return 返回是否成功
  30 + */
  31 + Boolean delHiActInstByTaskId(@Param("taskIdList") List<String> taskIdList);
  32 +
  33 + /**
  34 + * 逻辑删除hiTaskInst任务
  35 + *
  36 + * @param taskIdList 任务列表
  37 + *
  38 + * @return 返回是否成功
  39 + */
  40 + Boolean delHiTaskInstByTaskId(@Param("taskIdList") List<String> taskIdList);
  41 +}
... ...
yudao-module-bpm/yudao-module-bpm-base/src/main/java/cn/iocoder/yudao/module/bpm/dal/mysql/task/BpmProcessInstanceExtMapper.java renamed to yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/dal/mysql/task/BpmProcessInstanceExtMapper.java
1 1 package cn.iocoder.yudao.module.bpm.dal.mysql.task;
2 2  
3   -import cn.iocoder.yudao.framework.common.pojo.PageResult;
4   -import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
5   -import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
6 3 import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance.BpmProcessInstanceMyPageReqVO;
7 4 import cn.iocoder.yudao.module.bpm.dal.dataobject.task.BpmProcessInstanceExtDO;
  5 +import cn.iocoder.yudao.framework.common.pojo.PageResult;
  6 +import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
  7 +import cn.iocoder.yudao.framework.mybatis.core.query.QueryWrapperX;
  8 +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
8 9 import org.apache.ibatis.annotations.Mapper;
9 10  
10 11 @Mapper
11 12 public interface BpmProcessInstanceExtMapper extends BaseMapperX<BpmProcessInstanceExtDO> {
12 13  
13 14 default PageResult<BpmProcessInstanceExtDO> selectPage(Long userId, BpmProcessInstanceMyPageReqVO reqVO) {
14   - return selectPage(reqVO, new LambdaQueryWrapperX<BpmProcessInstanceExtDO>()
15   - .eqIfPresent(BpmProcessInstanceExtDO::getStartUserId, userId)
16   - .likeIfPresent(BpmProcessInstanceExtDO::getName, reqVO.getName())
17   - .eqIfPresent(BpmProcessInstanceExtDO::getProcessDefinitionId, reqVO.getProcessDefinitionId())
18   - .eqIfPresent(BpmProcessInstanceExtDO::getCategory, reqVO.getCategory())
19   - .eqIfPresent(BpmProcessInstanceExtDO::getStatus, reqVO.getStatus())
20   - .eqIfPresent(BpmProcessInstanceExtDO::getResult, reqVO.getResult())
21   - .betweenIfPresent(BpmProcessInstanceExtDO::getCreateTime, reqVO.getBeginCreateTime(), reqVO.getEndCreateTime())
22   - .orderByDesc(BpmProcessInstanceExtDO::getId));
  15 + return selectPage(reqVO, new QueryWrapperX<BpmProcessInstanceExtDO>()
  16 + .eqIfPresent("start_user_id", userId)
  17 + .likeIfPresent("name", reqVO.getName())
  18 + .eqIfPresent("process_definition_id", reqVO.getProcessDefinitionId())
  19 + .eqIfPresent("category", reqVO.getCategory())
  20 + .eqIfPresent("status", reqVO.getStatus())
  21 + .eqIfPresent("result", reqVO.getResult())
  22 + .betweenIfPresent("create_time", reqVO.getBeginCreateTime(), reqVO.getEndCreateTime())
  23 + .orderByDesc("id"));
23 24 }
24 25  
25 26 default BpmProcessInstanceExtDO selectByProcessInstanceId(String processDefinitionId) {
26   - return selectOne(BpmProcessInstanceExtDO::getProcessInstanceId, processDefinitionId);
  27 + return selectOne("process_instance_id", processDefinitionId);
27 28 }
28 29  
29 30 default void updateByProcessInstanceId(BpmProcessInstanceExtDO updateObj) {
30   - update(updateObj, new LambdaQueryWrapperX<BpmProcessInstanceExtDO>()
31   - .eq(BpmProcessInstanceExtDO::getProcessInstanceId, updateObj.getProcessInstanceId()));
  31 + update(updateObj, new QueryWrapper<BpmProcessInstanceExtDO>()
  32 + .eq("process_instance_id", updateObj.getProcessInstanceId()));
32 33 }
33 34  
34 35 }
... ...
yudao-module-bpm/yudao-module-bpm-base/src/main/java/cn/iocoder/yudao/module/bpm/dal/mysql/task/BpmTaskExtMapper.java renamed to yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/dal/mysql/task/BpmTaskExtMapper.java
... ... @@ -19,7 +19,8 @@ public interface BpmTaskExtMapper extends BaseMapperX&lt;BpmTaskExtDO&gt; {
19 19 return selectList(BpmTaskExtDO::getTaskId, taskIds);
20 20 }
21 21  
22   - default List<BpmTaskExtDO> selectListByProcessInstanceId(String processInstanceId) {
23   - return selectList(BpmTaskExtDO::getProcessInstanceId, processInstanceId);
  22 + default BpmTaskExtDO selectByTaskId(String taskId) {
  23 + return selectOne(BpmTaskExtDO::getTaskId, taskId);
24 24 }
  25 +
25 26 }
... ...
yudao-module-bpm/yudao-module-bpm-base/src/main/java/cn/iocoder/yudao/module/bpm/framework/bpm/config/BpmCommonConfiguration.java renamed to yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/bpm/config/BpmCommonConfiguration.java
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/bpm/config/BpmSecurityConfiguration.java 0 → 100644
  1 +package cn.iocoder.yudao.module.bpm.framework.bpm.config;
  2 +
  3 +import cn.iocoder.yudao.framework.security.config.AuthorizeRequestsCustomizer;
  4 +import org.springframework.context.annotation.Bean;
  5 +import org.springframework.context.annotation.Configuration;
  6 +import org.springframework.security.config.annotation.web.builders.HttpSecurity;
  7 +import org.springframework.security.config.annotation.web.configurers.ExpressionUrlAuthorizationConfigurer;
  8 +
  9 +/**
  10 + * @author kemengkai
  11 + * @create 2022-05-07 08:15
  12 + */
  13 +@Configuration("bpmSecurityConfiguration")
  14 +public class BpmSecurityConfiguration {
  15 +
  16 + @Bean("bpmAuthorizeRequestsCustomizer")
  17 + public AuthorizeRequestsCustomizer authorizeRequestsCustomizer() {
  18 + return new AuthorizeRequestsCustomizer() {
  19 +
  20 + @Override
  21 + public void customize(ExpressionUrlAuthorizationConfigurer<HttpSecurity>.ExpressionInterceptUrlRegistry registry) {
  22 + // 任务回退接口
  23 + registry.antMatchers(buildAdminApi("/bpm/task/back")).permitAll();
  24 + }
  25 +
  26 + };
  27 + }
  28 +}
... ...
yudao-module-bpm/yudao-module-bpm-base/src/main/java/cn/iocoder/yudao/module/bpm/framework/bpm/core/event/BpmProcessInstanceResultEvent.java renamed to yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/bpm/core/event/BpmProcessInstanceResultEvent.java
yudao-module-bpm/yudao-module-bpm-base/src/main/java/cn/iocoder/yudao/module/bpm/framework/bpm/core/event/BpmProcessInstanceResultEventListener.java renamed to yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/bpm/core/event/BpmProcessInstanceResultEventListener.java
yudao-module-bpm/yudao-module-bpm-base/src/main/java/cn/iocoder/yudao/module/bpm/framework/bpm/core/event/BpmProcessInstanceResultEventPublisher.java renamed to yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/bpm/core/event/BpmProcessInstanceResultEventPublisher.java
yudao-module-bpm/yudao-module-bpm-base/src/main/java/cn/iocoder/yudao/module/bpm/framework/bpm/core/event/package-info.java renamed to yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/bpm/core/event/package-info.java
yudao-module-bpm/yudao-module-bpm-base/src/main/java/cn/iocoder/yudao/module/bpm/framework/bpm/core/package-info.java renamed to yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/bpm/core/package-info.java
yudao-module-bpm/yudao-module-bpm-base/src/main/java/cn/iocoder/yudao/module/bpm/framework/bpm/package-info.java renamed to yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/bpm/package-info.java
yudao-module-bpm/yudao-module-bpm-biz-flowable/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/config/BpmFlowableConfiguration.java renamed to yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/config/BpmFlowableConfiguration.java
... ... @@ -2,12 +2,7 @@ package cn.iocoder.yudao.module.bpm.framework.flowable.config;
2 2  
3 3 import cn.hutool.core.collection.ListUtil;
4 4 import cn.iocoder.yudao.module.bpm.framework.flowable.core.behavior.BpmActivityBehaviorFactory;
5   -import cn.iocoder.yudao.module.bpm.framework.flowable.core.behavior.script.BpmTaskAssignScript;
6 5 import cn.iocoder.yudao.module.bpm.service.definition.BpmTaskAssignRuleService;
7   -import cn.iocoder.yudao.module.bpm.service.definition.BpmUserGroupService;
8   -import cn.iocoder.yudao.module.system.api.dept.DeptApi;
9   -import cn.iocoder.yudao.module.system.api.permission.PermissionApi;
10   -import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
11 6 import org.flowable.common.engine.api.delegate.event.FlowableEventListener;
12 7 import org.flowable.spring.SpringProcessEngineConfiguration;
13 8 import org.flowable.spring.boot.EngineConfigurationConfigurer;
... ... @@ -15,8 +10,6 @@ import org.springframework.beans.factory.ObjectProvider;
15 10 import org.springframework.context.annotation.Bean;
16 11 import org.springframework.context.annotation.Configuration;
17 12  
18   -import java.util.List;
19   -
20 13 /**
21 14 * BPM 模块的 Flowable 配置类
22 15 *
... ... @@ -36,7 +29,7 @@ public class BpmFlowableConfiguration {
36 29 ObjectProvider<FlowableEventListener> listeners,
37 30 BpmActivityBehaviorFactory bpmActivityBehaviorFactory) {
38 31 return configuration -> {
39   - // 注册监听器,例如说 BpmActivitiEventListener
  32 + // 注册监听器,例如说 BpmActivityEventListener
40 33 configuration.setEventListeners(ListUtil.toList(listeners.iterator()));
41 34 // 设置 ActivityBehaviorFactory 实现类,用于流程任务的审核人的自定义
42 35 configuration.setActivityBehaviorFactory(bpmActivityBehaviorFactory);
... ... @@ -44,19 +37,10 @@ public class BpmFlowableConfiguration {
44 37 }
45 38  
46 39 @Bean
47   - public BpmActivityBehaviorFactory bpmActivityBehaviorFactory(BpmTaskAssignRuleService taskRuleService,
48   - BpmUserGroupService userGroupService,
49   - PermissionApi permissionApi,
50   - DeptApi deptApi,
51   - AdminUserApi adminUserApi,
52   - List<BpmTaskAssignScript> scripts) {
  40 + public BpmActivityBehaviorFactory bpmActivityBehaviorFactory(BpmTaskAssignRuleService taskRuleService) {
53 41 BpmActivityBehaviorFactory bpmActivityBehaviorFactory = new BpmActivityBehaviorFactory();
54 42 bpmActivityBehaviorFactory.setBpmTaskRuleService(taskRuleService);
55   - bpmActivityBehaviorFactory.setUserGroupService(userGroupService);
56   - bpmActivityBehaviorFactory.setAdminUserApi(adminUserApi);
57   - bpmActivityBehaviorFactory.setPermissionApi(permissionApi);
58   - bpmActivityBehaviorFactory.setDeptApi(deptApi);
59   - bpmActivityBehaviorFactory.setScripts(scripts);
60 43 return bpmActivityBehaviorFactory;
61 44 }
  45 +
62 46 }
... ...
yudao-module-bpm/yudao-module-bpm-biz-flowable/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/behavior/BpmActivityBehaviorFactory.java renamed to yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/behavior/BpmActivityBehaviorFactory.java
1 1 package cn.iocoder.yudao.module.bpm.framework.flowable.core.behavior;
2 2  
3   -import cn.iocoder.yudao.module.bpm.framework.flowable.core.behavior.script.BpmTaskAssignScript;
4 3 import cn.iocoder.yudao.module.bpm.service.definition.BpmTaskAssignRuleService;
5   -import cn.iocoder.yudao.module.bpm.service.definition.BpmUserGroupService;
6   -import cn.iocoder.yudao.module.system.api.dept.DeptApi;
7   -import cn.iocoder.yudao.module.system.api.permission.PermissionApi;
8   -import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
9 4 import lombok.Data;
10 5 import lombok.EqualsAndHashCode;
11 6 import lombok.Setter;
12 7 import lombok.ToString;
  8 +import org.flowable.bpmn.model.Activity;
13 9 import org.flowable.bpmn.model.UserTask;
  10 +import org.flowable.engine.impl.bpmn.behavior.AbstractBpmnActivityBehavior;
  11 +import org.flowable.engine.impl.bpmn.behavior.ParallelMultiInstanceBehavior;
14 12 import org.flowable.engine.impl.bpmn.behavior.UserTaskActivityBehavior;
15 13 import org.flowable.engine.impl.bpmn.parser.factory.DefaultActivityBehaviorFactory;
16 14  
17   -import java.util.List;
18   -
19 15 /**
20 16 * 自定义的 ActivityBehaviorFactory 实现类,目的如下:
21 17 * 1. 自定义 {@link #createUserTaskActivityBehavior(UserTask)}:实现自定义的流程任务的 assignee 负责人的分配
... ... @@ -29,27 +25,20 @@ public class BpmActivityBehaviorFactory extends DefaultActivityBehaviorFactory {
29 25  
30 26 @Setter
31 27 private BpmTaskAssignRuleService bpmTaskRuleService;
32   - @Setter
33   - private BpmUserGroupService userGroupService;
34   -
35   - @Setter
36   - private PermissionApi permissionApi;
37   - @Setter
38   - private DeptApi deptApi;
39   - @Setter
40   - private AdminUserApi adminUserApi;
41   - @Setter
42   - private List<BpmTaskAssignScript> scripts;
43 28  
44 29 @Override
45 30 public UserTaskActivityBehavior createUserTaskActivityBehavior(UserTask userTask) {
46   - BpmUserTaskActivityBehavior userTaskActivityBehavior = new BpmUserTaskActivityBehavior(userTask);
47   - userTaskActivityBehavior.setBpmTaskRuleService(bpmTaskRuleService);
48   - userTaskActivityBehavior.setPermissionApi(permissionApi);
49   - userTaskActivityBehavior.setDeptApi(deptApi);
50   - userTaskActivityBehavior.setUserGroupService(userGroupService);
51   - userTaskActivityBehavior.setAdminUserApi(adminUserApi);
52   - userTaskActivityBehavior.setScripts(scripts);
53   - return userTaskActivityBehavior;
  31 + return new BpmUserTaskActivityBehavior(userTask)
  32 + .setBpmTaskRuleService(bpmTaskRuleService);
  33 + }
  34 +
  35 + @Override
  36 + public ParallelMultiInstanceBehavior createParallelMultiInstanceBehavior(Activity activity,
  37 + AbstractBpmnActivityBehavior innerActivityBehavior) {
  38 + return new BpmParallelMultiInstanceBehavior(activity, innerActivityBehavior)
  39 + .setBpmTaskRuleService(bpmTaskRuleService);
54 40 }
  41 +
  42 + // TODO @ke:SequentialMultiInstanceBehavior 这个抽空也可以看看
  43 +
55 44 }
... ...
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/behavior/BpmParallelMultiInstanceBehavior.java 0 → 100644
  1 +package cn.iocoder.yudao.module.bpm.framework.flowable.core.behavior;
  2 +
  3 +import cn.iocoder.yudao.framework.flowable.core.util.FlowableUtils;
  4 +import cn.iocoder.yudao.module.bpm.service.definition.BpmTaskAssignRuleService;
  5 +import lombok.Setter;
  6 +import lombok.extern.slf4j.Slf4j;
  7 +import org.flowable.bpmn.model.Activity;
  8 +import org.flowable.engine.delegate.DelegateExecution;
  9 +import org.flowable.engine.impl.bpmn.behavior.AbstractBpmnActivityBehavior;
  10 +import org.flowable.engine.impl.bpmn.behavior.ParallelMultiInstanceBehavior;
  11 +
  12 +import java.util.Set;
  13 +
  14 +/**
  15 + * 自定义的【并行】的【多个】流程任务的 assignee 负责人的分配
  16 + * 第一步,基于分配规则,计算出分配任务的【多个】候选人们。
  17 + * 第二步,将【多个】任务候选人们,设置到 DelegateExecution 的 collectionVariable 变量中,以便 BpmUserTaskActivityBehavior 使用它
  18 + *
  19 + * @author kemengkai
  20 + * @date 2022-04-21 16:57
  21 + */
  22 +@Slf4j
  23 +public class BpmParallelMultiInstanceBehavior extends ParallelMultiInstanceBehavior {
  24 +
  25 + @Setter
  26 + private BpmTaskAssignRuleService bpmTaskRuleService;
  27 +
  28 + public BpmParallelMultiInstanceBehavior(Activity activity,
  29 + AbstractBpmnActivityBehavior innerActivityBehavior) {
  30 + super(activity, innerActivityBehavior);
  31 + }
  32 +
  33 + /**
  34 + * 重写该方法,主要实现两个功能:
  35 + * 1. 忽略原有的 collectionVariable、collectionElementVariable 表达式,而是采用自己定义的
  36 + * 2. 获得任务的处理人,并设置到 collectionVariable 中,用于 BpmUserTaskActivityBehavior 从中可以获取任务的处理人
  37 + *
  38 + * 注意,多个任务实例,每个任务实例对应一个处理人,所以返回的数量就是任务处理人的数量
  39 + *
  40 + * @param execution 执行任务
  41 + * @return 数量
  42 + */
  43 + @Override
  44 + protected int resolveNrOfInstances(DelegateExecution execution) {
  45 + // 第一步,设置 collectionVariable 和 CollectionVariable
  46 + // 从 execution.getVariable() 读取所有任务处理人的 key
  47 + super.collectionExpression = null; // collectionExpression 和 collectionVariable 是互斥的
  48 + super.collectionVariable = FlowableUtils.formatCollectionVariable(execution.getCurrentActivityId());
  49 + // 从 execution.getVariable() 读取当前所有任务处理的人的 key
  50 + super.collectionElementVariable = FlowableUtils.formatCollectionElementVariable(execution.getCurrentActivityId());
  51 +
  52 + // 第二步,获取任务的所有处理人
  53 + Set<Long> assigneeUserIds = bpmTaskRuleService.calculateTaskCandidateUsers(execution);
  54 + execution.setVariable(super.collectionVariable, assigneeUserIds);
  55 + return assigneeUserIds.size();
  56 + }
  57 +
  58 +}
... ...
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/behavior/BpmUserTaskActivityBehavior.java 0 → 100644
  1 +package cn.iocoder.yudao.module.bpm.framework.flowable.core.behavior;
  2 +
  3 +import cn.hutool.core.collection.CollUtil;
  4 +import cn.hutool.core.lang.Assert;
  5 +import cn.hutool.core.util.RandomUtil;
  6 +import cn.iocoder.yudao.module.bpm.service.definition.BpmTaskAssignRuleService;
  7 +import lombok.Setter;
  8 +import lombok.extern.slf4j.Slf4j;
  9 +import org.flowable.bpmn.model.UserTask;
  10 +import org.flowable.common.engine.impl.el.ExpressionManager;
  11 +import org.flowable.engine.delegate.DelegateExecution;
  12 +import org.flowable.engine.impl.bpmn.behavior.UserTaskActivityBehavior;
  13 +import org.flowable.engine.impl.cfg.ProcessEngineConfigurationImpl;
  14 +import org.flowable.engine.impl.util.TaskHelper;
  15 +import org.flowable.task.service.TaskService;
  16 +import org.flowable.task.service.impl.persistence.entity.TaskEntity;
  17 +
  18 +import java.util.List;
  19 +import java.util.Set;
  20 +
  21 +/**
  22 + * 自定义的【单个】流程任务的 assignee 负责人的分配
  23 + * 第一步,基于分配规则,计算出分配任务的【单个】候选人。如果找不到,则直接报业务异常,不继续执行后续的流程;
  24 + * 第二步,随机选择一个候选人,则选择作为 assignee 负责人。
  25 + *
  26 + * @author 芋道源码
  27 + */
  28 +@Slf4j
  29 +public class BpmUserTaskActivityBehavior extends UserTaskActivityBehavior {
  30 +
  31 + @Setter
  32 + private BpmTaskAssignRuleService bpmTaskRuleService;
  33 +
  34 + public BpmUserTaskActivityBehavior(UserTask userTask) {
  35 + super(userTask);
  36 + }
  37 +
  38 + @Override
  39 + protected void handleAssignments(TaskService taskService, String assignee, String owner,
  40 + List<String> candidateUsers, List<String> candidateGroups, TaskEntity task, ExpressionManager expressionManager,
  41 + DelegateExecution execution, ProcessEngineConfigurationImpl processEngineConfiguration) {
  42 + // 第一步,获得任务的候选用户
  43 + Long assigneeUserId = calculateTaskCandidateUsers(execution);
  44 + Assert.notNull(assigneeUserId, "任务处理人不能为空");
  45 + // 第二步,设置作为负责人
  46 + TaskHelper.changeTaskAssignee(task, String.valueOf(assigneeUserId));
  47 + }
  48 +
  49 + private Long calculateTaskCandidateUsers(DelegateExecution execution) {
  50 + // 情况一,如果是多实例的任务,例如说会签、或签等情况,则从 Variable 中获取。它的任务处理人在 BpmParallelMultiInstanceBehavior 中已经被分配了
  51 + if (super.multiInstanceActivityBehavior != null) {
  52 + return execution.getVariable(super.multiInstanceActivityBehavior.getCollectionElementVariable(), Long.class);
  53 + }
  54 +
  55 + // 情况二,如果非多实例的任务,则计算任务处理人
  56 + // 第一步,先计算可处理该任务的处理人们
  57 + Set<Long> candidateUserIds = bpmTaskRuleService.calculateTaskCandidateUsers(execution);
  58 + // 第二步,后随机选择一个任务的处理人
  59 + // 疑问:为什么一定要选择一个任务处理人?
  60 + // 解答:项目对 bpm 的任务是责任到人,所以每个任务有且仅有一个处理人。
  61 + // 如果希望一个任务可以同时被多个人处理,可以考虑使用 BpmParallelMultiInstanceBehavior 实现的会签 or 或签。
  62 + int index = RandomUtil.randomInt(candidateUserIds.size());
  63 + return CollUtil.get(candidateUserIds, index);
  64 + }
  65 +
  66 +}
... ...
yudao-module-bpm/yudao-module-bpm-biz-flowable/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/behavior/script/BpmTaskAssignScript.java renamed to yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/behavior/script/BpmTaskAssignScript.java
1 1 package cn.iocoder.yudao.module.bpm.framework.flowable.core.behavior.script;
2 2  
3 3 import cn.iocoder.yudao.module.bpm.enums.definition.BpmTaskRuleScriptEnum;
4   -import org.flowable.task.service.impl.persistence.entity.TaskEntity;
  4 +import org.flowable.engine.delegate.DelegateExecution;
5 5  
6 6 import java.util.Set;
7 7  
... ... @@ -17,12 +17,12 @@ import java.util.Set;
17 17 public interface BpmTaskAssignScript {
18 18  
19 19 /**
20   - * 基于流程任务,获得任务的候选用户们
  20 + * 基于执行任务,获得任务的候选用户们
21 21 *
22   - * @param task 任务
  22 + * @param execution 执行任务
23 23 * @return 候选人用户的编号数组
24 24 */
25   - Set<Long> calculateTaskCandidateUsers(TaskEntity task);
  25 + Set<Long> calculateTaskCandidateUsers(DelegateExecution execution);
26 26  
27 27 /**
28 28 * 获得枚举值
... ...
yudao-module-bpm/yudao-module-bpm-biz-flowable/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/behavior/script/impl/BpmTaskAssignLeaderAbstractScript.java renamed to yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/behavior/script/impl/BpmTaskAssignLeaderAbstractScript.java
... ... @@ -7,9 +7,8 @@ import cn.iocoder.yudao.module.system.api.dept.DeptApi;
7 7 import cn.iocoder.yudao.module.system.api.dept.dto.DeptRespDTO;
8 8 import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
9 9 import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
10   -
  10 +import org.flowable.engine.delegate.DelegateExecution;
11 11 import org.flowable.engine.runtime.ProcessInstance;
12   -import org.flowable.task.service.impl.persistence.entity.TaskEntity;
13 12 import org.springframework.context.annotation.Lazy;
14 13 import org.springframework.util.Assert;
15 14  
... ... @@ -35,10 +34,10 @@ public abstract class BpmTaskAssignLeaderAbstractScript implements BpmTaskAssign
35 34 @Lazy // 解决循环依赖
36 35 private BpmProcessInstanceService bpmProcessInstanceService;
37 36  
38   - protected Set<Long> calculateTaskCandidateUsers(TaskEntity task, int level) {
  37 + protected Set<Long> calculateTaskCandidateUsers(DelegateExecution execution, int level) {
39 38 Assert.isTrue(level > 0, "level 必须大于 0");
40 39 // 获得发起人
41   - ProcessInstance processInstance = bpmProcessInstanceService.getProcessInstance(task.getProcessInstanceId());
  40 + ProcessInstance processInstance = bpmProcessInstanceService.getProcessInstance(execution.getProcessInstanceId());
42 41 Long startUserId = NumberUtils.parseLong(processInstance.getStartUserId());
43 42 // 获得对应 leve 的部门
44 43 DeptRespDTO dept = null;
... ...
yudao-module-bpm/yudao-module-bpm-biz-flowable/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/behavior/script/impl/BpmTaskAssignLeaderX1Script.java renamed to yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/behavior/script/impl/BpmTaskAssignLeaderX1Script.java
1 1 package cn.iocoder.yudao.module.bpm.framework.flowable.core.behavior.script.impl;
2 2  
3   -import cn.iocoder.yudao.framework.datapermission.core.annotation.DataPermission;
4 3 import cn.iocoder.yudao.module.bpm.enums.definition.BpmTaskRuleScriptEnum;
5   -import org.flowable.task.service.impl.persistence.entity.TaskEntity;
  4 +import org.flowable.engine.delegate.DelegateExecution;
6 5 import org.springframework.stereotype.Component;
7 6  
8 7 import java.util.Set;
... ... @@ -16,9 +15,8 @@ import java.util.Set;
16 15 public class BpmTaskAssignLeaderX1Script extends BpmTaskAssignLeaderAbstractScript {
17 16  
18 17 @Override
19   - @DataPermission(enable = false) // 不需要处理数据权限, 不然会有问题,查询不到数据
20   - public Set<Long> calculateTaskCandidateUsers(TaskEntity task) {
21   - return calculateTaskCandidateUsers(task, 1);
  18 + public Set<Long> calculateTaskCandidateUsers(DelegateExecution execution) {
  19 + return calculateTaskCandidateUsers(execution, 1);
22 20 }
23 21  
24 22 @Override
... ...
yudao-module-bpm/yudao-module-bpm-biz-flowable/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/behavior/script/impl/BpmTaskAssignLeaderX2Script.java renamed to yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/behavior/script/impl/BpmTaskAssignLeaderX2Script.java
1 1 package cn.iocoder.yudao.module.bpm.framework.flowable.core.behavior.script.impl;
2 2  
3   -import cn.iocoder.yudao.framework.datapermission.core.annotation.DataPermission;
4 3 import cn.iocoder.yudao.module.bpm.enums.definition.BpmTaskRuleScriptEnum;
5   -import org.flowable.task.service.impl.persistence.entity.TaskEntity;
  4 +import org.flowable.engine.delegate.DelegateExecution;
6 5 import org.springframework.stereotype.Component;
7 6  
8 7 import java.util.Set;
... ... @@ -16,9 +15,8 @@ import java.util.Set;
16 15 public class BpmTaskAssignLeaderX2Script extends BpmTaskAssignLeaderAbstractScript {
17 16  
18 17 @Override
19   - @DataPermission(enable = false) // 不需要处理数据权限, 不然会有问题,查询不到数据
20   - public Set<Long> calculateTaskCandidateUsers(TaskEntity task) {
21   - return calculateTaskCandidateUsers(task, 2);
  18 + public Set<Long> calculateTaskCandidateUsers(DelegateExecution execution) {
  19 + return calculateTaskCandidateUsers(execution, 2);
22 20 }
23 21  
24 22 @Override
... ...
yudao-module-bpm/yudao-module-bpm-biz-flowable/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/behavior/script/impl/BpmTaskAssignStartUserScript.java renamed to yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/behavior/script/impl/BpmTaskAssignStartUserScript.java
... ... @@ -3,11 +3,10 @@ package cn.iocoder.yudao.module.bpm.framework.flowable.core.behavior.script.impl
3 3 import cn.iocoder.yudao.framework.common.util.collection.SetUtils;
4 4 import cn.iocoder.yudao.framework.common.util.number.NumberUtils;
5 5 import cn.iocoder.yudao.module.bpm.enums.definition.BpmTaskRuleScriptEnum;
6   -
7 6 import cn.iocoder.yudao.module.bpm.framework.flowable.core.behavior.script.BpmTaskAssignScript;
8 7 import cn.iocoder.yudao.module.bpm.service.task.BpmProcessInstanceService;
  8 +import org.flowable.engine.delegate.DelegateExecution;
9 9 import org.flowable.engine.runtime.ProcessInstance;
10   -import org.flowable.task.service.impl.persistence.entity.TaskEntity;
11 10 import org.springframework.context.annotation.Lazy;
12 11 import org.springframework.stereotype.Component;
13 12  
... ... @@ -27,8 +26,8 @@ public class BpmTaskAssignStartUserScript implements BpmTaskAssignScript {
27 26 private BpmProcessInstanceService bpmProcessInstanceService;
28 27  
29 28 @Override
30   - public Set<Long> calculateTaskCandidateUsers(TaskEntity task) {
31   - ProcessInstance processInstance = bpmProcessInstanceService.getProcessInstance(task.getProcessInstanceId());
  29 + public Set<Long> calculateTaskCandidateUsers(DelegateExecution execution) {
  30 + ProcessInstance processInstance = bpmProcessInstanceService.getProcessInstance(execution.getProcessInstanceId());
32 31 Long startUserId = NumberUtils.parseLong(processInstance.getStartUserId());
33 32 return SetUtils.asSet(startUserId);
34 33 }
... ...
yudao-module-bpm/yudao-module-bpm-biz-flowable/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/listener/BpmProcessInstanceEventListener.java renamed to yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/listener/BpmProcessInstanceEventListener.java
yudao-module-bpm/yudao-module-bpm-biz-flowable/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/listener/BpmTaskEventListener.java renamed to yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/listener/BpmTaskEventListener.java
1 1 package cn.iocoder.yudao.module.bpm.framework.flowable.core.listener;
2 2  
  3 +import cn.hutool.core.util.StrUtil;
3 4 import cn.iocoder.yudao.module.bpm.dal.dataobject.task.BpmTaskExtDO;
  5 +import cn.iocoder.yudao.module.bpm.service.task.BpmActivityService;
4 6 import cn.iocoder.yudao.module.bpm.service.task.BpmTaskService;
5 7 import com.google.common.collect.ImmutableSet;
  8 +import lombok.extern.slf4j.Slf4j;
6 9 import org.flowable.common.engine.api.delegate.event.FlowableEngineEntityEvent;
7 10 import org.flowable.common.engine.api.delegate.event.FlowableEngineEventType;
8 11 import org.flowable.engine.delegate.event.AbstractFlowableEngineEventListener;
  12 +import org.flowable.engine.delegate.event.FlowableActivityCancelledEvent;
  13 +import org.flowable.engine.history.HistoricActivityInstance;
9 14 import org.flowable.task.api.Task;
10 15 import org.springframework.context.annotation.Lazy;
11 16 import org.springframework.stereotype.Component;
... ... @@ -19,16 +24,22 @@ import java.util.Set;
19 24 * @author jason
20 25 */
21 26 @Component
  27 +@Slf4j
22 28 public class BpmTaskEventListener extends AbstractFlowableEngineEventListener {
23 29  
24 30 @Resource
25 31 @Lazy // 解决循环依赖
26 32 private BpmTaskService taskService;
27 33  
  34 + @Resource
  35 + @Lazy // 解决循环依赖
  36 + private BpmActivityService activityService;
  37 +
28 38 public static final Set<FlowableEngineEventType> TASK_EVENTS = ImmutableSet.<FlowableEngineEventType>builder()
29 39 .add(FlowableEngineEventType.TASK_CREATED)
30 40 .add(FlowableEngineEventType.TASK_ASSIGNED)
31 41 .add(FlowableEngineEventType.TASK_COMPLETED)
  42 + .add(FlowableEngineEventType.ACTIVITY_CANCELLED)
32 43 .build();
33 44  
34 45 public BpmTaskEventListener(){
... ... @@ -49,4 +60,18 @@ public class BpmTaskEventListener extends AbstractFlowableEngineEventListener {
49 60 protected void taskAssigned(FlowableEngineEntityEvent event) {
50 61 taskService.updateTaskExtAssign((Task)event.getEntity());
51 62 }
  63 +
  64 + @Override
  65 + protected void activityCancelled(FlowableActivityCancelledEvent event) {
  66 + HistoricActivityInstance activity = activityService.getHistoricActivityByExecutionId(event.getExecutionId());
  67 + if (activity == null) {
  68 + log.error("[activityCancelled][使用 executionId({}) 查找不到对应的活动实例]", event.getExecutionId());
  69 + return;
  70 + }
  71 + if (StrUtil.isEmpty(activity.getTaskId())) {
  72 + return;
  73 + }
  74 + taskService.updateTaskExtCancel(activity.getTaskId());
  75 + }
  76 +
52 77 }
... ...
yudao-module-bpm/yudao-module-bpm-base/src/main/java/cn/iocoder/yudao/module/bpm/framework/package-info.java renamed to yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/package-info.java
yudao-module-bpm/yudao-module-bpm-biz-activiti/src/main/java/cn/iocoder/yudao/module/bpm/package-info.java renamed to yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/package-info.java
... ... @@ -7,6 +7,6 @@
7 7 * 1. Controller URL:以 /bpm/ 开头,避免和其它 Module 冲突
8 8 * 2. DataObject 表名:以 bpm_ 开头,方便在数据库中区分
9 9 *
10   - * 注意,由于 Bpm 模块下,容易和其它模块重名,所以类名都加载 Pay 的前缀~
  10 + * 注意,由于 Bpm 模块下,容易和其它模块重名,所以类名都加载 Bpm 的前缀~
11 11 */
12 12 package cn.iocoder.yudao.module.bpm;
... ...
yudao-module-bpm/yudao-module-bpm-base/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmFormService.java renamed to yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmFormService.java
yudao-module-bpm/yudao-module-bpm-base/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmFormServiceImpl.java renamed to yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmFormServiceImpl.java
yudao-module-bpm/yudao-module-bpm-biz-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmModelService.java renamed to yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmModelService.java
yudao-module-bpm/yudao-module-bpm-biz-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmModelServiceImpl.java renamed to yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmModelServiceImpl.java
yudao-module-bpm/yudao-module-bpm-biz-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmProcessDefinitionService.java renamed to yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmProcessDefinitionService.java
yudao-module-bpm/yudao-module-bpm-biz-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmProcessDefinitionServiceImpl.java renamed to yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmProcessDefinitionServiceImpl.java
yudao-module-bpm/yudao-module-bpm-biz-activiti/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmTaskAssignRuleService.java renamed to yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmTaskAssignRuleService.java
... ... @@ -4,10 +4,12 @@ import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.rule.BpmTaskAs
4 4 import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.rule.BpmTaskAssignRuleRespVO;
5 5 import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.rule.BpmTaskAssignRuleUpdateReqVO;
6 6 import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmTaskAssignRuleDO;
  7 +import org.flowable.engine.delegate.DelegateExecution;
7 8 import org.springframework.lang.Nullable;
8 9  
9 10 import javax.validation.Valid;
10 11 import java.util.List;
  12 +import java.util.Set;
11 13  
12 14 /**
13 15 * BPM 任务分配规则 Service 接口
... ... @@ -84,4 +86,12 @@ public interface BpmTaskAssignRuleService {
84 86 */
85 87 void checkTaskAssignRuleAllConfig(String id);
86 88  
  89 + /**
  90 + * 计算当前执行任务的处理人
  91 + *
  92 + * @param execution 执行任务
  93 + * @return 处理人的编号数组
  94 + */
  95 + Set<Long> calculateTaskCandidateUsers(DelegateExecution execution);
  96 +
87 97 }
... ...
yudao-module-bpm/yudao-module-bpm-biz-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmTaskAssignRuleServiceImpl.java renamed to yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmTaskAssignRuleServiceImpl.java
... ... @@ -3,25 +3,35 @@ package cn.iocoder.yudao.module.bpm.service.definition;
3 3 import cn.hutool.core.collection.CollUtil;
4 4 import cn.hutool.core.util.ObjectUtil;
5 5 import cn.hutool.core.util.StrUtil;
  6 +import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
6 7 import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
7 8 import cn.iocoder.yudao.framework.common.util.object.ObjectUtils;
  9 +import cn.iocoder.yudao.framework.datapermission.core.annotation.DataPermission;
8 10 import cn.iocoder.yudao.framework.flowable.core.util.FlowableUtils;
9 11 import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.rule.BpmTaskAssignRuleCreateReqVO;
10 12 import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.rule.BpmTaskAssignRuleRespVO;
11 13 import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.rule.BpmTaskAssignRuleUpdateReqVO;
12 14 import cn.iocoder.yudao.module.bpm.convert.definition.BpmTaskAssignRuleConvert;
13 15 import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmTaskAssignRuleDO;
  16 +import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmUserGroupDO;
14 17 import cn.iocoder.yudao.module.bpm.dal.mysql.definition.BpmTaskAssignRuleMapper;
15   -import cn.iocoder.yudao.module.bpm.enums.DictTypeConstants;
16 18 import cn.iocoder.yudao.module.bpm.enums.definition.BpmTaskAssignRuleTypeEnum;
  19 +import cn.iocoder.yudao.module.bpm.enums.DictTypeConstants;
  20 +import cn.iocoder.yudao.module.bpm.framework.flowable.core.behavior.script.BpmTaskAssignScript;
17 21 import cn.iocoder.yudao.module.system.api.dept.DeptApi;
18 22 import cn.iocoder.yudao.module.system.api.dept.PostApi;
  23 +import cn.iocoder.yudao.module.system.api.dept.dto.DeptRespDTO;
19 24 import cn.iocoder.yudao.module.system.api.dict.DictDataApi;
  25 +import cn.iocoder.yudao.module.system.api.permission.PermissionApi;
20 26 import cn.iocoder.yudao.module.system.api.permission.RoleApi;
21 27 import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
  28 +import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
  29 +import com.google.common.annotations.VisibleForTesting;
22 30 import lombok.extern.slf4j.Slf4j;
23 31 import org.flowable.bpmn.model.BpmnModel;
24 32 import org.flowable.bpmn.model.UserTask;
  33 +import org.flowable.common.engine.api.FlowableException;
  34 +import org.flowable.engine.delegate.DelegateExecution;
25 35 import org.springframework.context.annotation.Lazy;
26 36 import org.springframework.stereotype.Service;
27 37 import org.springframework.validation.annotation.Validated;
... ... @@ -30,7 +40,11 @@ import javax.annotation.Resource;
30 40 import javax.validation.Valid;
31 41 import java.util.*;
32 42  
  43 +import static cn.hutool.core.text.CharSequenceUtil.format;
33 44 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
  45 +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap;
  46 +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
  47 +import static cn.iocoder.yudao.framework.common.util.json.JsonUtils.toJsonString;
34 48 import static cn.iocoder.yudao.module.bpm.enums.ErrorCodeConstants.*;
35 49  
36 50 /**
... ... @@ -39,7 +53,7 @@ import static cn.iocoder.yudao.module.bpm.enums.ErrorCodeConstants.*;
39 53 @Service
40 54 @Validated
41 55 @Slf4j
42   -public class BpmTaskAssignRuleServiceImpl implements BpmTaskAssignRuleService{
  56 +public class BpmTaskAssignRuleServiceImpl implements BpmTaskAssignRuleService {
43 57  
44 58 @Resource
45 59 private BpmTaskAssignRuleMapper taskRuleMapper;
... ... @@ -61,9 +75,21 @@ public class BpmTaskAssignRuleServiceImpl implements BpmTaskAssignRuleService{
61 75 private AdminUserApi adminUserApi;
62 76 @Resource
63 77 private DictDataApi dictDataApi;
  78 + @Resource
  79 + private PermissionApi permissionApi;
  80 + /**
  81 + * 任务分配脚本
  82 + */
  83 + private Map<Long, BpmTaskAssignScript> scriptMap = Collections.emptyMap();
  84 +
  85 + @Resource
  86 + public void setScripts(List<BpmTaskAssignScript> scripts) {
  87 + this.scriptMap = convertMap(scripts, script -> script.getEnum().getId());
  88 + }
64 89  
65 90 @Override
66   - public List<BpmTaskAssignRuleDO> getTaskAssignRuleListByProcessDefinitionId(String processDefinitionId, String taskDefinitionKey) {
  91 + public List<BpmTaskAssignRuleDO> getTaskAssignRuleListByProcessDefinitionId(String processDefinitionId,
  92 + String taskDefinitionKey) {
67 93 return taskRuleMapper.selectListByProcessDefinitionId(processDefinitionId, taskDefinitionKey);
68 94 }
69 95  
... ... @@ -101,15 +127,15 @@ public class BpmTaskAssignRuleServiceImpl implements BpmTaskAssignRuleService{
101 127 // 校验参数
102 128 validTaskAssignRuleOptions(reqVO.getType(), reqVO.getOptions());
103 129 // 校验是否已经配置
104   - BpmTaskAssignRuleDO existRule = taskRuleMapper.selectListByModelIdAndTaskDefinitionKey(
105   - reqVO.getModelId(), reqVO.getTaskDefinitionKey());
  130 + BpmTaskAssignRuleDO existRule =
  131 + taskRuleMapper.selectListByModelIdAndTaskDefinitionKey(reqVO.getModelId(), reqVO.getTaskDefinitionKey());
106 132 if (existRule != null) {
107 133 throw exception(TASK_ASSIGN_RULE_EXISTS, reqVO.getModelId(), reqVO.getTaskDefinitionKey());
108 134 }
109 135  
110 136 // 存储
111 137 BpmTaskAssignRuleDO rule = BpmTaskAssignRuleConvert.INSTANCE.convert(reqVO)
112   - .setProcessDefinitionId(BpmTaskAssignRuleDO.PROCESS_DEFINITION_ID_NULL); // 只有流程模型,才允许新建
  138 + .setProcessDefinitionId(BpmTaskAssignRuleDO.PROCESS_DEFINITION_ID_NULL); // 只有流程模型,才允许新建
113 139 taskRuleMapper.insert(rule);
114 140 return rule.getId();
115 141 }
... ... @@ -142,15 +168,15 @@ public class BpmTaskAssignRuleServiceImpl implements BpmTaskAssignRuleService{
142 168 }
143 169  
144 170 // 遍历,匹配对应的规则
145   - Map<String, BpmTaskAssignRuleRespVO> processInstanceRuleMap = CollectionUtils.convertMap(processInstanceRules,
146   - BpmTaskAssignRuleRespVO::getTaskDefinitionKey);
  171 + Map<String, BpmTaskAssignRuleRespVO> processInstanceRuleMap =
  172 + CollectionUtils.convertMap(processInstanceRules, BpmTaskAssignRuleRespVO::getTaskDefinitionKey);
147 173 for (BpmTaskAssignRuleRespVO modelRule : modelRules) {
148 174 BpmTaskAssignRuleRespVO processInstanceRule = processInstanceRuleMap.get(modelRule.getTaskDefinitionKey());
149 175 if (processInstanceRule == null) {
150 176 return false;
151 177 }
152   - if (!ObjectUtil.equals(modelRule.getType(), processInstanceRule.getType())
153   - || !ObjectUtil.equal(modelRule.getOptions(), processInstanceRule.getOptions())) {
  178 + if (!ObjectUtil.equals(modelRule.getType(), processInstanceRule.getType()) || !ObjectUtil.equal(
  179 + modelRule.getOptions(), processInstanceRule.getOptions())) {
154 180 return false;
155 181 }
156 182 }
... ... @@ -165,8 +191,8 @@ public class BpmTaskAssignRuleServiceImpl implements BpmTaskAssignRuleService{
165 191 }
166 192 // 开始复制
167 193 List<BpmTaskAssignRuleDO> newRules = BpmTaskAssignRuleConvert.INSTANCE.convertList2(rules);
168   - newRules.forEach(rule -> rule.setProcessDefinitionId(toProcessDefinitionId).setId(null)
169   - .setCreateTime(null).setUpdateTime(null));
  194 + newRules.forEach(rule -> rule.setProcessDefinitionId(toProcessDefinitionId).setId(null).setCreateTime(null)
  195 + .setUpdateTime(null));
170 196 taskRuleMapper.insertBatch(newRules);
171 197 }
172 198  
... ... @@ -189,7 +215,7 @@ public class BpmTaskAssignRuleServiceImpl implements BpmTaskAssignRuleService{
189 215 if (Objects.equals(type, BpmTaskAssignRuleTypeEnum.ROLE.getType())) {
190 216 roleApi.validRoles(options);
191 217 } else if (ObjectUtils.equalsAny(type, BpmTaskAssignRuleTypeEnum.DEPT_MEMBER.getType(),
192   - BpmTaskAssignRuleTypeEnum.DEPT_LEADER.getType())) {
  218 + BpmTaskAssignRuleTypeEnum.DEPT_LEADER.getType())) {
193 219 deptApi.validDepts(options);
194 220 } else if (Objects.equals(type, BpmTaskAssignRuleTypeEnum.POST.getType())) {
195 221 postApi.validPosts(options);
... ... @@ -199,9 +225,120 @@ public class BpmTaskAssignRuleServiceImpl implements BpmTaskAssignRuleService{
199 225 userGroupService.validUserGroups(options);
200 226 } else if (Objects.equals(type, BpmTaskAssignRuleTypeEnum.SCRIPT.getType())) {
201 227 dictDataApi.validDictDatas(DictTypeConstants.TASK_ASSIGN_SCRIPT,
202   - CollectionUtils.convertSet(options, String::valueOf));
  228 + CollectionUtils.convertSet(options, String::valueOf));
203 229 } else {
204   - throw new IllegalArgumentException(StrUtil.format("未知的规则类型({})", type));
  230 + throw new IllegalArgumentException(format("未知的规则类型({})", type));
  231 + }
  232 + }
  233 +
  234 + @Override
  235 + @DataPermission(enable = false) // 忽略数据权限,不然分配会存在问题
  236 + public Set<Long> calculateTaskCandidateUsers(DelegateExecution execution) {
  237 + BpmTaskAssignRuleDO rule = getTaskRule(execution);
  238 + return calculateTaskCandidateUsers(execution, rule);
  239 + }
  240 +
  241 + @VisibleForTesting
  242 + BpmTaskAssignRuleDO getTaskRule(DelegateExecution execution) {
  243 + List<BpmTaskAssignRuleDO> taskRules = getTaskAssignRuleListByProcessDefinitionId(
  244 + execution.getProcessDefinitionId(), execution.getCurrentActivityId());
  245 + if (CollUtil.isEmpty(taskRules)) {
  246 + throw new FlowableException(format("流程任务({}/{}/{}) 找不到符合的任务规则",
  247 + execution.getId(), execution.getProcessDefinitionId(), execution.getCurrentActivityId()));
  248 + }
  249 + if (taskRules.size() > 1) {
  250 + throw new FlowableException(format("流程任务({}/{}/{}) 找到过多任务规则({})",
  251 + execution.getId(), execution.getProcessDefinitionId(), execution.getCurrentActivityId()));
  252 + }
  253 + return taskRules.get(0);
  254 + }
  255 +
  256 + @VisibleForTesting
  257 + Set<Long> calculateTaskCandidateUsers(DelegateExecution execution, BpmTaskAssignRuleDO rule) {
  258 + Set<Long> assigneeUserIds = null;
  259 + if (Objects.equals(BpmTaskAssignRuleTypeEnum.ROLE.getType(), rule.getType())) {
  260 + assigneeUserIds = calculateTaskCandidateUsersByRole(rule);
  261 + } else if (Objects.equals(BpmTaskAssignRuleTypeEnum.DEPT_MEMBER.getType(), rule.getType())) {
  262 + assigneeUserIds = calculateTaskCandidateUsersByDeptMember(rule);
  263 + } else if (Objects.equals(BpmTaskAssignRuleTypeEnum.DEPT_LEADER.getType(), rule.getType())) {
  264 + assigneeUserIds = calculateTaskCandidateUsersByDeptLeader(rule);
  265 + } else if (Objects.equals(BpmTaskAssignRuleTypeEnum.POST.getType(), rule.getType())) {
  266 + assigneeUserIds = calculateTaskCandidateUsersByPost(rule);
  267 + } else if (Objects.equals(BpmTaskAssignRuleTypeEnum.USER.getType(), rule.getType())) {
  268 + assigneeUserIds = calculateTaskCandidateUsersByUser(rule);
  269 + } else if (Objects.equals(BpmTaskAssignRuleTypeEnum.USER_GROUP.getType(), rule.getType())) {
  270 + assigneeUserIds = calculateTaskCandidateUsersByUserGroup(rule);
  271 + } else if (Objects.equals(BpmTaskAssignRuleTypeEnum.SCRIPT.getType(), rule.getType())) {
  272 + assigneeUserIds = calculateTaskCandidateUsersByScript(execution, rule);
  273 + }
  274 +
  275 + // 移除被禁用的用户
  276 + removeDisableUsers(assigneeUserIds);
  277 + // 如果候选人为空,抛出异常
  278 + if (CollUtil.isEmpty(assigneeUserIds)) {
  279 + log.error("[calculateTaskCandidateUsers][流程任务({}/{}/{}) 任务规则({}) 找不到候选人]", execution.getId(),
  280 + execution.getProcessDefinitionId(), execution.getCurrentActivityId(), toJsonString(rule));
  281 + throw exception(TASK_CREATE_FAIL_NO_CANDIDATE_USER);
  282 + }
  283 + return assigneeUserIds;
  284 + }
  285 +
  286 + private Set<Long> calculateTaskCandidateUsersByRole(BpmTaskAssignRuleDO rule) {
  287 + return permissionApi.getUserRoleIdListByRoleIds(rule.getOptions());
  288 + }
  289 +
  290 + private Set<Long> calculateTaskCandidateUsersByDeptMember(BpmTaskAssignRuleDO rule) {
  291 + List<AdminUserRespDTO> users = adminUserApi.getUsersByDeptIds(rule.getOptions());
  292 + return convertSet(users, AdminUserRespDTO::getId);
  293 + }
  294 +
  295 + private Set<Long> calculateTaskCandidateUsersByDeptLeader(BpmTaskAssignRuleDO rule) {
  296 + List<DeptRespDTO> depts = deptApi.getDepts(rule.getOptions());
  297 + return convertSet(depts, DeptRespDTO::getLeaderUserId);
  298 + }
  299 +
  300 + private Set<Long> calculateTaskCandidateUsersByPost(BpmTaskAssignRuleDO rule) {
  301 + List<AdminUserRespDTO> users = adminUserApi.getUsersByPostIds(rule.getOptions());
  302 + return convertSet(users, AdminUserRespDTO::getId);
  303 + }
  304 +
  305 + private Set<Long> calculateTaskCandidateUsersByUser(BpmTaskAssignRuleDO rule) {
  306 + return rule.getOptions();
  307 + }
  308 +
  309 + private Set<Long> calculateTaskCandidateUsersByUserGroup(BpmTaskAssignRuleDO rule) {
  310 + List<BpmUserGroupDO> userGroups = userGroupService.getUserGroupList(rule.getOptions());
  311 + Set<Long> userIds = new HashSet<>();
  312 + userGroups.forEach(group -> userIds.addAll(group.getMemberUserIds()));
  313 + return userIds;
  314 + }
  315 +
  316 + private Set<Long> calculateTaskCandidateUsersByScript(DelegateExecution execution, BpmTaskAssignRuleDO rule) {
  317 + // 获得对应的脚本
  318 + List<BpmTaskAssignScript> scripts = new ArrayList<>(rule.getOptions().size());
  319 + rule.getOptions().forEach(id -> {
  320 + BpmTaskAssignScript script = scriptMap.get(id);
  321 + if (script == null) {
  322 + throw exception(TASK_ASSIGN_SCRIPT_NOT_EXISTS, id);
  323 + }
  324 + scripts.add(script);
  325 + });
  326 + // 逐个计算任务
  327 + Set<Long> userIds = new HashSet<>();
  328 + scripts.forEach(script -> CollUtil.addAll(userIds, script.calculateTaskCandidateUsers(execution)));
  329 + return userIds;
  330 + }
  331 +
  332 + @VisibleForTesting
  333 + void removeDisableUsers(Set<Long> assigneeUserIds) {
  334 + if (CollUtil.isEmpty(assigneeUserIds)) {
  335 + return;
205 336 }
  337 + Map<Long, AdminUserRespDTO> userMap = adminUserApi.getUserMap(assigneeUserIds);
  338 + assigneeUserIds.removeIf(id -> {
  339 + AdminUserRespDTO user = userMap.get(id);
  340 + return user == null || !CommonStatusEnum.ENABLE.getStatus().equals(user.getStatus());
  341 + });
206 342 }
  343 +
207 344 }
... ...
yudao-module-bpm/yudao-module-bpm-base/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmUserGroupService.java renamed to yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmUserGroupService.java
yudao-module-bpm/yudao-module-bpm-base/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmUserGroupServiceImpl.java renamed to yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmUserGroupServiceImpl.java
yudao-module-bpm/yudao-module-bpm-base/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/dto/BpmFormFieldRespDTO.java renamed to yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/dto/BpmFormFieldRespDTO.java
yudao-module-bpm/yudao-module-bpm-base/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/dto/BpmModelMetaInfoRespDTO.java renamed to yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/dto/BpmModelMetaInfoRespDTO.java
yudao-module-bpm/yudao-module-bpm-base/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/dto/BpmProcessDefinitionCreateReqDTO.java renamed to yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/dto/BpmProcessDefinitionCreateReqDTO.java
yudao-module-bpm/yudao-module-bpm-base/src/main/java/cn/iocoder/yudao/module/bpm/service/message/BpmMessageService.java renamed to yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/message/BpmMessageService.java
yudao-module-bpm/yudao-module-bpm-base/src/main/java/cn/iocoder/yudao/module/bpm/service/message/BpmMessageServiceImpl.java renamed to yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/message/BpmMessageServiceImpl.java
yudao-module-bpm/yudao-module-bpm-base/src/main/java/cn/iocoder/yudao/module/bpm/service/message/dto/BpmMessageSendWhenProcessInstanceApproveReqDTO.java renamed to yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/message/dto/BpmMessageSendWhenProcessInstanceApproveReqDTO.java
yudao-module-bpm/yudao-module-bpm-base/src/main/java/cn/iocoder/yudao/module/bpm/service/message/dto/BpmMessageSendWhenProcessInstanceRejectReqDTO.java renamed to yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/message/dto/BpmMessageSendWhenProcessInstanceRejectReqDTO.java
yudao-module-bpm/yudao-module-bpm-base/src/main/java/cn/iocoder/yudao/module/bpm/service/message/dto/BpmMessageSendWhenTaskCreatedReqDTO.java renamed to yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/message/dto/BpmMessageSendWhenTaskCreatedReqDTO.java
yudao-module-bpm/yudao-module-bpm-base/src/main/java/cn/iocoder/yudao/module/bpm/service/oa/BpmOALeaveService.java renamed to yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/oa/BpmOALeaveService.java
yudao-module-bpm/yudao-module-bpm-base/src/main/java/cn/iocoder/yudao/module/bpm/service/oa/BpmOALeaveServiceImpl.java renamed to yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/oa/BpmOALeaveServiceImpl.java
yudao-module-bpm/yudao-module-bpm-base/src/main/java/cn/iocoder/yudao/module/bpm/service/oa/listener/BpmOALeaveResultListener.java renamed to yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/oa/listener/BpmOALeaveResultListener.java
yudao-module-bpm/yudao-module-bpm-biz-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmActivityService.java renamed to yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmActivityService.java
1 1 package cn.iocoder.yudao.module.bpm.service.task;
2 2  
3 3 import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.activity.BpmActivityRespVO;
  4 +import org.flowable.engine.history.HistoricActivityInstance;
4 5  
5 6 import java.util.List;
6 7  
... ... @@ -19,4 +20,12 @@ public interface BpmActivityService {
19 20 */
20 21 List<BpmActivityRespVO> getActivityListByProcessInstanceId(String processInstanceId);
21 22  
  23 + /**
  24 + * 获得执行编号对应的活动实例
  25 + *
  26 + * @param executionId 执行编号
  27 + * @return 活动实例
  28 + */
  29 + HistoricActivityInstance getHistoricActivityByExecutionId(String executionId);
  30 +
22 31 }
... ...
yudao-module-bpm/yudao-module-bpm-biz-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmActivityServiceImpl.java renamed to yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmActivityServiceImpl.java
1 1 package cn.iocoder.yudao.module.bpm.service.task;
2 2  
3   -import cn.hutool.core.io.IoUtil;
4   -import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
5 3 import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.activity.BpmActivityRespVO;
6 4 import cn.iocoder.yudao.module.bpm.convert.task.BpmActivityConvert;
7   -import cn.iocoder.yudao.module.bpm.service.definition.BpmProcessDefinitionService;
  5 +import cn.iocoder.yudao.module.bpm.dal.mysql.task.BpmActivityMapper;
8 6 import lombok.extern.slf4j.Slf4j;
9   -
10   -import org.flowable.bpmn.model.BpmnModel;
11 7 import org.flowable.engine.HistoryService;
12 8 import org.flowable.engine.history.HistoricActivityInstance;
13   -import org.flowable.engine.history.HistoricProcessInstance;
14   -import org.flowable.image.ProcessDiagramGenerator;
15 9 import org.springframework.stereotype.Service;
16 10 import org.springframework.validation.annotation.Validated;
17 11  
18 12 import javax.annotation.Resource;
19   -import java.io.InputStream;
20   -import java.util.Collections;
21 13 import java.util.List;
22 14  
23   -import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
24   -import static cn.iocoder.yudao.module.bpm.enums.ErrorCodeConstants.PROCESS_DEFINITION_BPMN_MODEL_NOT_EXISTS;
25   -import static cn.iocoder.yudao.module.bpm.enums.ErrorCodeConstants.PROCESS_INSTANCE_NOT_EXISTS;
26 15  
27 16 /**
28 17 * BPM 活动实例 Service 实现类
... ... @@ -36,6 +25,8 @@ public class BpmActivityServiceImpl implements BpmActivityService {
36 25  
37 26 @Resource
38 27 private HistoryService historyService;
  28 + @Resource
  29 + private BpmActivityMapper bpmActivityMapper;
39 30  
40 31 @Override
41 32 public List<BpmActivityRespVO> getActivityListByProcessInstanceId(String processInstanceId) {
... ... @@ -44,6 +35,9 @@ public class BpmActivityServiceImpl implements BpmActivityService {
44 35 return BpmActivityConvert.INSTANCE.convertList(activityList);
45 36 }
46 37  
47   -
  38 + @Override
  39 + public HistoricActivityInstance getHistoricActivityByExecutionId(String executionId) {
  40 + return historyService.createHistoricActivityInstanceQuery().executionId(executionId).singleResult();
  41 + }
48 42  
49 43 }
... ...
yudao-module-bpm/yudao-module-bpm-biz-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmProcessInstanceService.java renamed to yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmProcessInstanceService.java
... ... @@ -4,7 +4,6 @@ import cn.iocoder.yudao.framework.common.pojo.PageResult;
4 4 import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
5 5 import cn.iocoder.yudao.module.bpm.api.task.dto.BpmProcessInstanceCreateReqDTO;
6 6 import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance.*;
7   -import org.flowable.common.engine.api.delegate.event.FlowableEngineEntityEvent;
8 7 import org.flowable.engine.delegate.event.FlowableCancelledEvent;
9 8 import org.flowable.engine.history.HistoricProcessInstance;
10 9 import org.flowable.engine.runtime.ProcessInstance;
... ...
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmProcessInstanceServiceImpl.java 0 → 100644
  1 +package cn.iocoder.yudao.module.bpm.service.task; import cn.hutool.core.collection.CollUtil; import cn.hutool.core.lang.Assert; import cn.hutool.core.util.StrUtil; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.common.util.number.NumberUtils; import cn.iocoder.yudao.module.bpm.api.task.dto.BpmProcessInstanceCreateReqDTO; import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance.*; import cn.iocoder.yudao.module.bpm.convert.task.BpmProcessInstanceConvert; import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmProcessDefinitionExtDO; import cn.iocoder.yudao.module.bpm.dal.dataobject.task.BpmProcessInstanceExtDO; import cn.iocoder.yudao.module.bpm.dal.mysql.task.BpmProcessInstanceExtMapper; import cn.iocoder.yudao.module.bpm.enums.task.BpmProcessInstanceDeleteReasonEnum; import cn.iocoder.yudao.module.bpm.enums.task.BpmProcessInstanceResultEnum; import cn.iocoder.yudao.module.bpm.enums.task.BpmProcessInstanceStatusEnum; import cn.iocoder.yudao.module.bpm.framework.bpm.core.event.BpmProcessInstanceResultEventPublisher; import cn.iocoder.yudao.module.bpm.service.definition.BpmProcessDefinitionService; import cn.iocoder.yudao.module.bpm.service.message.BpmMessageService; import cn.iocoder.yudao.module.system.api.dept.DeptApi; import cn.iocoder.yudao.module.system.api.dept.dto.DeptRespDTO; import cn.iocoder.yudao.module.system.api.user.AdminUserApi; import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO; import lombok.extern.slf4j.Slf4j; import org.flowable.engine.HistoryService; import org.flowable.engine.RuntimeService; import org.flowable.engine.delegate.event.FlowableCancelledEvent; import org.flowable.engine.history.HistoricProcessInstance; import org.flowable.engine.repository.ProcessDefinition; import org.flowable.engine.runtime.ProcessInstance; import org.flowable.task.api.Task; import org.springframework.context.annotation.Lazy; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import org.springframework.validation.annotation.Validated; import javax.annotation.Resource; import javax.validation.Valid; import java.util.*; import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList; import static cn.iocoder.yudao.module.bpm.enums.ErrorCodeConstants.*; /** * 流程实例 Service 实现类 * * ProcessDefinition & ProcessInstance & Execution & Task 的关系: * 1. <a href="https://blog.csdn.net/bobozai86/article/details/105210414" /> * * HistoricProcessInstance & ProcessInstance 的关系: * 1. <a href=" https://my.oschina.net/843294669/blog/71902" /> * * 简单来说,前者 = 历史 + 运行中的流程实例,后者仅是运行中的流程实例 * * @author 芋道源码 */ @Service @Validated @Slf4j public class BpmProcessInstanceServiceImpl implements BpmProcessInstanceService { @Resource private RuntimeService runtimeService; @Resource private BpmProcessInstanceExtMapper processInstanceExtMapper; @Resource @Lazy // 解决循环依赖 private BpmTaskService taskService; @Resource private BpmProcessDefinitionService processDefinitionService; @Resource private HistoryService historyService; @Resource private AdminUserApi adminUserApi; @Resource private DeptApi deptApi; @Resource private BpmProcessInstanceResultEventPublisher processInstanceResultEventPublisher; @Resource private BpmMessageService messageService; @Override public ProcessInstance getProcessInstance(String id) { return runtimeService.createProcessInstanceQuery().processInstanceId(id).singleResult(); } @Override public List<ProcessInstance> getProcessInstances(Set<String> ids) { return runtimeService.createProcessInstanceQuery().processInstanceIds(ids).list(); } @Override public PageResult<BpmProcessInstancePageItemRespVO> getMyProcessInstancePage(Long userId, BpmProcessInstanceMyPageReqVO pageReqVO) { // 通过 BpmProcessInstanceExtDO 表,先查询到对应的分页 PageResult<BpmProcessInstanceExtDO> pageResult = processInstanceExtMapper.selectPage(userId, pageReqVO); if (CollUtil.isEmpty(pageResult.getList())) { return new PageResult<>(pageResult.getTotal()); } // 获得流程 Task Map List<String> processInstanceIds = convertList(pageResult.getList(), BpmProcessInstanceExtDO::getProcessInstanceId); Map<String, List<Task>> taskMap = taskService.getTaskMapByProcessInstanceIds(processInstanceIds); // 转换返回 return BpmProcessInstanceConvert.INSTANCE.convertPage(pageResult, taskMap); } @Override @Transactional(rollbackFor = Exception.class) public String createProcessInstance(Long userId, @Valid BpmProcessInstanceCreateReqVO createReqVO) { // 获得流程定义 ProcessDefinition definition = processDefinitionService.getProcessDefinition(createReqVO.getProcessDefinitionId()); // 发起流程 return createProcessInstance0(userId, definition, createReqVO.getVariables(), null); } @Override public String createProcessInstance(Long userId, @Valid BpmProcessInstanceCreateReqDTO createReqDTO) { // 获得流程定义 ProcessDefinition definition = processDefinitionService.getActiveProcessDefinition(createReqDTO.getProcessDefinitionKey()); // 发起流程 return createProcessInstance0(userId, definition, createReqDTO.getVariables(), createReqDTO.getBusinessKey()); } @Override public BpmProcessInstanceRespVO getProcessInstanceVO(String id) { // 获得流程实例 HistoricProcessInstance processInstance = getHistoricProcessInstance(id); if (processInstance == null) { return null; } BpmProcessInstanceExtDO processInstanceExt = processInstanceExtMapper.selectByProcessInstanceId(id); Assert.notNull(processInstanceExt, "流程实例拓展({}) 不存在", id); // 获得流程定义 ProcessDefinition processDefinition = processDefinitionService .getProcessDefinition(processInstance.getProcessDefinitionId()); Assert.notNull(processDefinition, "流程定义({}) 不存在", processInstance.getProcessDefinitionId()); BpmProcessDefinitionExtDO processDefinitionExt = processDefinitionService.getProcessDefinitionExt( processInstance.getProcessDefinitionId()); Assert.notNull(processDefinitionExt, "流程定义拓展({}) 不存在", id); String bpmnXml = processDefinitionService.getProcessDefinitionBpmnXML(processInstance.getProcessDefinitionId()); // 获得 User AdminUserRespDTO startUser = adminUserApi.getUser(NumberUtils.parseLong(processInstance.getStartUserId())); DeptRespDTO dept = null; if (startUser != null) { dept = deptApi.getDept(startUser.getDeptId()); } // 拼接结果 return BpmProcessInstanceConvert.INSTANCE.convert2(processInstance, processInstanceExt, processDefinition, processDefinitionExt, bpmnXml, startUser, dept); } @Override public void cancelProcessInstance(Long userId, @Valid BpmProcessInstanceCancelReqVO cancelReqVO) { // 校验流程实例存在 ProcessInstance instance = getProcessInstance(cancelReqVO.getId()); if (instance == null) { throw exception(PROCESS_INSTANCE_CANCEL_FAIL_NOT_EXISTS); } // 只能取消自己的 if (!Objects.equals(instance.getStartUserId(), String.valueOf(userId))) { throw exception(PROCESS_INSTANCE_CANCEL_FAIL_NOT_SELF); } // 通过删除流程实例,实现流程实例的取消, // 删除流程实例,正则执行任务 ACT_RU_TASK. 任务会被删除。通过历史表查询 deleteProcessInstance(cancelReqVO.getId(), BpmProcessInstanceDeleteReasonEnum.CANCEL_TASK.format(cancelReqVO.getReason())); } /** * 获得历史的流程实例 * * @param id 流程实例的编号 * @return 历史的流程实例 */ @Override public HistoricProcessInstance getHistoricProcessInstance(String id) { return historyService.createHistoricProcessInstanceQuery().processInstanceId(id).singleResult(); } @Override public List<HistoricProcessInstance> getHistoricProcessInstances(Set<String> ids) { return historyService.createHistoricProcessInstanceQuery().processInstanceIds(ids).list(); } @Override public void createProcessInstanceExt(ProcessInstance instance) { // 获得流程定义 ProcessDefinition definition = processDefinitionService.getProcessDefinition2(instance.getProcessDefinitionId()); // 插入 BpmProcessInstanceExtDO 对象 BpmProcessInstanceExtDO instanceExtDO = new BpmProcessInstanceExtDO() .setProcessInstanceId(instance.getId()) .setProcessDefinitionId(definition.getId()) .setName(instance.getProcessDefinitionName()) .setStartUserId(Long.valueOf(instance.getStartUserId())) .setCategory(definition.getCategory()) .setStatus(BpmProcessInstanceStatusEnum.RUNNING.getStatus()) .setResult(BpmProcessInstanceResultEnum.PROCESS.getResult()); processInstanceExtMapper.insert(instanceExtDO); } @Override public void updateProcessInstanceExtCancel(FlowableCancelledEvent event) { // 判断是否为 Reject 不通过。如果是,则不进行更新. // 因为,updateProcessInstanceExtReject 方法,已经进行更新了 if (BpmProcessInstanceDeleteReasonEnum.isRejectReason((String)event.getCause())) { return; } // 需要主动查询,因为 instance 只有 id 属性 // 另外,此时如果去查询 ProcessInstance 的话,字段是不全的,所以去查询了 HistoricProcessInstance HistoricProcessInstance processInstance = getHistoricProcessInstance(event.getProcessInstanceId()); // 更新拓展表 BpmProcessInstanceExtDO instanceExtDO = new BpmProcessInstanceExtDO() .setProcessInstanceId(event.getProcessInstanceId()) .setEndTime(new Date()) // 由于 ProcessInstance 里没有办法拿到 endTime,所以这里设置 .setStatus(BpmProcessInstanceStatusEnum.FINISH.getStatus()) .setResult(BpmProcessInstanceResultEnum.CANCEL.getResult()); processInstanceExtMapper.updateByProcessInstanceId(instanceExtDO); // 发送流程实例的状态事件 processInstanceResultEventPublisher.sendProcessInstanceResultEvent( BpmProcessInstanceConvert.INSTANCE.convert(this, processInstance, instanceExtDO.getResult())); } @Override public void updateProcessInstanceExtComplete(ProcessInstance instance) { // 需要主动查询,因为 instance 只有 id 属性 // 另外,此时如果去查询 ProcessInstance 的话,字段是不全的,所以去查询了 HistoricProcessInstance HistoricProcessInstance processInstance = getHistoricProcessInstance(instance.getId()); // 更新拓展表 BpmProcessInstanceExtDO instanceExtDO = new BpmProcessInstanceExtDO() .setProcessInstanceId(instance.getProcessInstanceId()) .setEndTime(new Date()) // 由于 ProcessInstance 里没有办法拿到 endTime,所以这里设置 .setStatus(BpmProcessInstanceStatusEnum.FINISH.getStatus()) .setResult(BpmProcessInstanceResultEnum.APPROVE.getResult()); // 如果正常完全,说明审批通过 processInstanceExtMapper.updateByProcessInstanceId(instanceExtDO); // 发送流程被通过的消息 messageService.sendMessageWhenProcessInstanceApprove(BpmProcessInstanceConvert.INSTANCE.convert2ApprovedReq(instance)); // 发送流程实例的状态事件 processInstanceResultEventPublisher.sendProcessInstanceResultEvent( BpmProcessInstanceConvert.INSTANCE.convert(this, processInstance, instanceExtDO.getResult())); } @Transactional(rollbackFor = Exception.class) public void updateProcessInstanceExtReject(String id, String reason) { // 需要主动查询,因为 instance 只有 id 属性 ProcessInstance processInstance = getProcessInstance(id); // 删除流程实例,以实现驳回任务时,取消整个审批流程 deleteProcessInstance(id, StrUtil.format(BpmProcessInstanceDeleteReasonEnum.REJECT_TASK.format(reason))); // 更新 status + result // 注意,不能和上面的逻辑更换位置。因为 deleteProcessInstance 会触发流程的取消,进而调用 updateProcessInstanceExtCancel 方法, // 设置 result 为 BpmProcessInstanceStatusEnum.CANCEL,显然和 result 不一定是一致的 BpmProcessInstanceExtDO instanceExtDO = new BpmProcessInstanceExtDO().setProcessInstanceId(id) .setStatus(BpmProcessInstanceStatusEnum.FINISH.getStatus()) .setResult(BpmProcessInstanceResultEnum.REJECT.getResult()); processInstanceExtMapper.updateByProcessInstanceId(instanceExtDO); // 发送流程被不通过的消息 messageService.sendMessageWhenProcessInstanceReject(BpmProcessInstanceConvert.INSTANCE.convert2RejectReq(processInstance, reason)); // 发送流程实例的状态事件 processInstanceResultEventPublisher.sendProcessInstanceResultEvent( BpmProcessInstanceConvert.INSTANCE.convert(this, processInstance, instanceExtDO.getResult())); } private void deleteProcessInstance(String id, String reason) { runtimeService.deleteProcessInstance(id, reason); } private String createProcessInstance0(Long userId, ProcessDefinition definition, Map<String, Object> variables, String businessKey) { // 校验流程定义 if (definition == null) { throw exception(PROCESS_DEFINITION_NOT_EXISTS); } if (definition.isSuspended()) { throw exception(PROCESS_DEFINITION_IS_SUSPENDED); } // 创建流程实例 ProcessInstance instance = runtimeService.startProcessInstanceById(definition.getId(), businessKey, variables); // 设置流程名字 runtimeService.setProcessInstanceName(instance.getId(), definition.getName()); // 补全流程实例的拓展表 processInstanceExtMapper.updateByProcessInstanceId(new BpmProcessInstanceExtDO().setProcessInstanceId(instance.getId()) .setFormVariables(variables)); return instance.getId(); } }
0 2 \ No newline at end of file
... ...
yudao-module-bpm/yudao-module-bpm-biz-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmTaskService.java renamed to yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmTaskService.java
1 1 package cn.iocoder.yudao.module.bpm.service.task;
2 2  
  3 +import cn.iocoder.yudao.framework.common.pojo.CommonResult;
3 4 import cn.iocoder.yudao.framework.common.pojo.PageResult;
4 5 import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
5 6 import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.task.*;
6 7 import org.flowable.task.api.Task;
7 8  
8   -
9 9 import javax.validation.Valid;
10 10 import java.util.List;
11 11 import java.util.Map;
... ... @@ -17,19 +17,23 @@ import java.util.Map;
17 17 * @author 芋道源码
18 18 */
19 19 public interface BpmTaskService {
  20 +
20 21 /**
21 22 * 获得待办的流程任务分页
22 23 *
23   - * @param userId 用户编号
  24 + * @param userId 用户编号
24 25 * @param pageReqVO 分页请求
  26 + *
25 27 * @return 流程任务分页
26 28 */
27 29 PageResult<BpmTaskTodoPageItemRespVO> getTodoTaskPage(Long userId, BpmTaskTodoPageReqVO pageReqVO);
  30 +
28 31 /**
29 32 * 获得已办的流程任务分页
30 33 *
31   - * @param userId 用户编号
  34 + * @param userId 用户编号
32 35 * @param pageReqVO 分页请求
  36 + *
33 37 * @return 流程任务分页
34 38 */
35 39 PageResult<BpmTaskDonePageItemRespVO> getDoneTaskPage(Long userId, BpmTaskDonePageReqVO pageReqVO);
... ... @@ -38,17 +42,19 @@ public interface BpmTaskService {
38 42 * 获得流程任务 Map
39 43 *
40 44 * @param processInstanceIds 流程实例的编号数组
  45 + *
41 46 * @return 流程任务 Map
42 47 */
43 48 default Map<String, List<Task>> getTaskMapByProcessInstanceIds(List<String> processInstanceIds) {
44 49 return CollectionUtils.convertMultiMap(getTasksByProcessInstanceIds(processInstanceIds),
45   - Task::getProcessInstanceId);
  50 + Task::getProcessInstanceId);
46 51 }
47 52  
48 53 /**
49 54 * 获得流程任务列表
50 55 *
51 56 * @param processInstanceIds 流程实例的编号数组
  57 + *
52 58 * @return 流程任务列表
53 59 */
54 60 List<Task> getTasksByProcessInstanceIds(List<String> processInstanceIds);
... ... @@ -57,6 +63,7 @@ public interface BpmTaskService {
57 63 * 获得指令流程实例的流程任务列表,包括所有状态的
58 64 *
59 65 * @param processInstanceId 流程实例的编号
  66 + *
60 67 * @return 流程任务列表
61 68 */
62 69 List<BpmTaskRespVO> getTaskListByProcessInstanceId(String processInstanceId);
... ... @@ -65,7 +72,7 @@ public interface BpmTaskService {
65 72 * 通过任务
66 73 *
67 74 * @param userId 用户编号
68   - * @param reqVO 通过请求
  75 + * @param reqVO 通过请求
69 76 */
70 77 void approveTask(Long userId, @Valid BpmTaskApproveReqVO reqVO);
71 78  
... ... @@ -73,7 +80,7 @@ public interface BpmTaskService {
73 80 * 不通过任务
74 81 *
75 82 * @param userId 用户编号
76   - * @param reqVO 不通过请求
  83 + * @param reqVO 不通过请求
77 84 */
78 85 void rejectTask(Long userId, @Valid BpmTaskRejectReqVO reqVO);
79 86  
... ... @@ -81,14 +88,14 @@ public interface BpmTaskService {
81 88 * 将流程任务分配给指定用户
82 89 *
83 90 * @param userId 用户编号
84   - * @param reqVO 分配请求
  91 + * @param reqVO 分配请求
85 92 */
86 93 void updateTaskAssignee(Long userId, BpmTaskUpdateAssigneeReqVO reqVO);
87 94  
88 95 /**
89 96 * 将流程任务分配给指定用户
90 97 *
91   - * @param id 流程任务编号
  98 + * @param id 流程任务编号
92 99 * @param userId 用户编号
93 100 */
94 101 void updateTaskAssignee(String id, Long userId);
... ... @@ -108,6 +115,13 @@ public interface BpmTaskService {
108 115 void updateTaskExtComplete(Task task);
109 116  
110 117 /**
  118 + * 更新 Task 拓展记录为已取消
  119 + *
  120 + * @param taskId 任务的编号
  121 + */
  122 + void updateTaskExtCancel(String taskId);
  123 +
  124 + /**
111 125 * 更新 Task 拓展记录,并发送通知
112 126 *
113 127 * @param task 任务实体
... ...
yudao-module-bpm/yudao-module-bpm-biz-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmTaskServiceImpl.java renamed to yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmTaskServiceImpl.java
... ... @@ -7,8 +7,12 @@ import cn.iocoder.yudao.framework.common.util.number.NumberUtils;
7 7 import cn.iocoder.yudao.framework.common.util.object.PageUtils;
8 8 import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.task.*;
9 9 import cn.iocoder.yudao.module.bpm.convert.task.BpmTaskConvert;
  10 +import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmTaskAssignRuleDO;
10 11 import cn.iocoder.yudao.module.bpm.dal.dataobject.task.BpmTaskExtDO;
  12 +import cn.iocoder.yudao.module.bpm.dal.mysql.definition.BpmTaskAssignRuleMapper;
  13 +import cn.iocoder.yudao.module.bpm.dal.mysql.task.BpmActivityMapper;
11 14 import cn.iocoder.yudao.module.bpm.dal.mysql.task.BpmTaskExtMapper;
  15 +import cn.iocoder.yudao.module.bpm.enums.task.BpmProcessInstanceDeleteReasonEnum;
12 16 import cn.iocoder.yudao.module.bpm.enums.task.BpmProcessInstanceResultEnum;
13 17 import cn.iocoder.yudao.module.bpm.service.message.BpmMessageService;
14 18 import cn.iocoder.yudao.module.system.api.dept.DeptApi;
... ... @@ -46,7 +50,7 @@ import static cn.iocoder.yudao.module.bpm.enums.ErrorCodeConstants.*;
46 50 */
47 51 @Slf4j
48 52 @Service
49   -public class BpmTaskServiceImpl implements BpmTaskService{
  53 +public class BpmTaskServiceImpl implements BpmTaskService {
50 54  
51 55 @Resource
52 56 private TaskService taskService;
... ... @@ -63,13 +67,16 @@ public class BpmTaskServiceImpl implements BpmTaskService{
63 67 private BpmTaskExtMapper taskExtMapper;
64 68 @Resource
65 69 private BpmMessageService messageService;
  70 + @Resource
  71 + private BpmTaskAssignRuleMapper taskAssignRuleMapper;
  72 + @Resource
  73 + private BpmActivityMapper bpmActivityMapper;
66 74  
67 75 @Override
68 76 public PageResult<BpmTaskTodoPageItemRespVO> getTodoTaskPage(Long userId, BpmTaskTodoPageReqVO pageVO) {
69 77 // 查询待办任务
70   - TaskQuery taskQuery = taskService.createTaskQuery()
71   - .taskAssignee(String.valueOf(userId)) // 分配给自己
72   - .orderByTaskCreateTime().desc(); // 创建时间倒序
  78 + TaskQuery taskQuery = taskService.createTaskQuery().taskAssignee(String.valueOf(userId)) // 分配给自己
  79 + .orderByTaskCreateTime().desc(); // 创建时间倒序
73 80 if (StrUtil.isNotBlank(pageVO.getName())) {
74 81 taskQuery.taskNameLike("%" + pageVO.getName() + "%");
75 82 }
... ... @@ -86,23 +93,22 @@ public class BpmTaskServiceImpl implements BpmTaskService{
86 93 }
87 94  
88 95 // 获得 ProcessInstance Map
89   - Map<String, ProcessInstance> processInstanceMap = processInstanceService.getProcessInstanceMap(
90   - convertSet(tasks, Task::getProcessInstanceId));
  96 + Map<String, ProcessInstance> processInstanceMap =
  97 + processInstanceService.getProcessInstanceMap(convertSet(tasks, Task::getProcessInstanceId));
91 98 // 获得 User Map
92 99 Map<Long, AdminUserRespDTO> userMap = adminUserApi.getUserMap(
93   - convertSet(processInstanceMap.values(), instance -> Long.valueOf(instance.getStartUserId())));
  100 + convertSet(processInstanceMap.values(), instance -> Long.valueOf(instance.getStartUserId())));
94 101 // 拼接结果
95 102 return new PageResult<>(BpmTaskConvert.INSTANCE.convertList1(tasks, processInstanceMap, userMap),
96   - taskQuery.count());
  103 + taskQuery.count());
97 104 }
98 105  
99 106 @Override
100 107 public PageResult<BpmTaskDonePageItemRespVO> getDoneTaskPage(Long userId, BpmTaskDonePageReqVO pageVO) {
101 108 // 查询已办任务
102   - HistoricTaskInstanceQuery taskQuery = historyService.createHistoricTaskInstanceQuery()
103   - .finished() // 已完成
104   - .taskAssignee(String.valueOf(userId)) // 分配给自己
105   - .orderByHistoricTaskInstanceEndTime().desc(); // 审批时间倒序
  109 + HistoricTaskInstanceQuery taskQuery = historyService.createHistoricTaskInstanceQuery().finished() // 已完成
  110 + .taskAssignee(String.valueOf(userId)) // 分配给自己
  111 + .orderByHistoricTaskInstanceEndTime().desc(); // 审批时间倒序
106 112 if (StrUtil.isNotBlank(pageVO.getName())) {
107 113 taskQuery.taskNameLike("%" + pageVO.getName() + "%");
108 114 }
... ... @@ -119,17 +125,20 @@ public class BpmTaskServiceImpl implements BpmTaskService{
119 125 }
120 126  
121 127 // 获得 TaskExtDO Map
122   - List<BpmTaskExtDO> bpmTaskExtDOs = taskExtMapper.selectListByTaskIds(convertSet(tasks, HistoricTaskInstance::getId));
  128 + List<BpmTaskExtDO> bpmTaskExtDOs =
  129 + taskExtMapper.selectListByTaskIds(convertSet(tasks, HistoricTaskInstance::getId));
123 130 Map<String, BpmTaskExtDO> bpmTaskExtDOMap = convertMap(bpmTaskExtDOs, BpmTaskExtDO::getTaskId);
124 131 // 获得 ProcessInstance Map
125   - Map<String, HistoricProcessInstance> historicProcessInstanceMap = processInstanceService.getHistoricProcessInstanceMap(
  132 + Map<String, HistoricProcessInstance> historicProcessInstanceMap =
  133 + processInstanceService.getHistoricProcessInstanceMap(
126 134 convertSet(tasks, HistoricTaskInstance::getProcessInstanceId));
127 135 // 获得 User Map
128 136 Map<Long, AdminUserRespDTO> userMap = adminUserApi.getUserMap(
129   - convertSet(historicProcessInstanceMap.values(), instance -> Long.valueOf(instance.getStartUserId())));
  137 + convertSet(historicProcessInstanceMap.values(), instance -> Long.valueOf(instance.getStartUserId())));
130 138 // 拼接结果
131   - return new PageResult<>(BpmTaskConvert.INSTANCE.convertList2(tasks, bpmTaskExtDOMap, historicProcessInstanceMap, userMap),
132   - taskQuery.count());
  139 + return new PageResult<>(
  140 + BpmTaskConvert.INSTANCE.convertList2(tasks, bpmTaskExtDOMap, historicProcessInstanceMap, userMap),
  141 + taskQuery.count());
133 142 }
134 143  
135 144 @Override
... ... @@ -180,9 +189,15 @@ public class BpmTaskServiceImpl implements BpmTaskService{
180 189  
181 190 // 完成任务,审批通过
182 191 taskService.complete(task.getId(), instance.getProcessVariables());
  192 +
183 193 // 更新任务拓展表为通过
184   - taskExtMapper.updateByTaskId(new BpmTaskExtDO().setTaskId(task.getId())
185   - .setResult(BpmProcessInstanceResultEnum.APPROVE.getResult()).setReason(reqVO.getReason()));
  194 + taskExtMapper.updateByTaskId(
  195 + new BpmTaskExtDO().setTaskId(task.getId()).setResult(BpmProcessInstanceResultEnum.APPROVE.getResult())
  196 + .setReason(reqVO.getReason()));
  197 + // 判断任务是否为或签,或签时删除其余不用审批的任务
  198 + List<BpmTaskAssignRuleDO> bpmTaskAssignRuleList =
  199 + taskAssignRuleMapper.selectListByProcessDefinitionId(task.getProcessDefinitionId(),
  200 + task.getTaskDefinitionKey());
186 201 }
187 202  
188 203 @Override
... ... @@ -199,8 +214,9 @@ public class BpmTaskServiceImpl implements BpmTaskService{
199 214 processInstanceService.updateProcessInstanceExtReject(instance.getProcessInstanceId(), reqVO.getReason());
200 215  
201 216 // 更新任务拓展表为不通过
202   - taskExtMapper.updateByTaskId(new BpmTaskExtDO().setTaskId(task.getId())
203   - .setResult(BpmProcessInstanceResultEnum.REJECT.getResult()).setReason(reqVO.getReason()));
  217 + taskExtMapper.updateByTaskId(
  218 + new BpmTaskExtDO().setTaskId(task.getId()).setResult(BpmProcessInstanceResultEnum.REJECT.getResult())
  219 + .setReason(reqVO.getReason()));
204 220 }
205 221  
206 222 @Override
... ... @@ -216,55 +232,95 @@ public class BpmTaskServiceImpl implements BpmTaskService{
216 232 taskService.setAssignee(id, String.valueOf(userId));
217 233 }
218 234  
  235 + /**
  236 + * 校验任务是否存在, 并且是否是分配给自己的任务
  237 + *
  238 + * @param userId 用户 id
  239 + * @param taskId task id
  240 + */
  241 + private Task checkTask(Long userId, String taskId) {
  242 + Task task = getTask(taskId);
  243 + if (task == null) {
  244 + throw exception(TASK_COMPLETE_FAIL_NOT_EXISTS);
  245 + }
  246 + if (!Objects.equals(userId, NumberUtils.parseLong(task.getAssignee()))) {
  247 + throw exception(TASK_COMPLETE_FAIL_ASSIGN_NOT_SELF);
  248 + }
  249 + return task;
  250 + }
219 251  
220 252 @Override
221 253 public void createTaskExt(Task task) {
222   - BpmTaskExtDO taskExtDO = BpmTaskConvert.INSTANCE.convert2TaskExt(task)
223   - .setResult(BpmProcessInstanceResultEnum.PROCESS.getResult());
  254 + BpmTaskExtDO taskExtDO =
  255 + BpmTaskConvert.INSTANCE.convert2TaskExt(task).setResult(BpmProcessInstanceResultEnum.PROCESS.getResult());
224 256 taskExtMapper.insert(taskExtDO);
225 257 }
226 258  
227 259 @Override
228 260 public void updateTaskExtComplete(Task task) {
229 261 BpmTaskExtDO taskExtDO = BpmTaskConvert.INSTANCE.convert2TaskExt(task)
  262 + .setResult(BpmProcessInstanceResultEnum.APPROVE.getResult()) // 不设置也问题不大,因为 Complete 一般是审核通过,已经设置
230 263 .setEndTime(new Date());
231 264 taskExtMapper.updateByTaskId(taskExtDO);
232 265 }
233 266  
234 267 @Override
  268 + public void updateTaskExtCancel(String taskId) {
  269 + // 需要在事务提交后,才进行查询。不然查询不到历史的原因
  270 + TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronization() {
  271 +
  272 + @Override
  273 + public void afterCommit() {
  274 + // 可能只是活动,不是任务,所以查询不到
  275 + HistoricTaskInstance task = getHistoricTask(taskId);
  276 + if (task == null) {
  277 + return;
  278 + }
  279 +
  280 + // 如果任务拓展表已经是完成的状态,则跳过
  281 + BpmTaskExtDO taskExt = taskExtMapper.selectByTaskId(taskId);
  282 + if (taskExt == null) {
  283 + log.error("[updateTaskExtCancel][taskId({}) 查找不到对应的记录,可能存在问题]", taskId);
  284 + return;
  285 + }
  286 + // 如果已经是最终的结果,则跳过
  287 + if (BpmProcessInstanceResultEnum.isEndResult(taskExt.getResult())) {
  288 + log.error("[updateTaskExtCancel][taskId({}) 处于结果({}),无需进行更新]", taskId, taskExt.getResult());
  289 + return;
  290 + }
  291 +
  292 + // 更新任务
  293 + taskExtMapper.updateById(new BpmTaskExtDO().setId(taskExt.getId()).setResult(BpmProcessInstanceResultEnum.CANCEL.getResult())
  294 + .setEndTime(new Date()).setReason(BpmProcessInstanceDeleteReasonEnum.translateReason(task.getDeleteReason())));
  295 + }
  296 +
  297 + });
  298 + }
  299 +
  300 + @Override
235 301 public void updateTaskExtAssign(Task task) {
236   - BpmTaskExtDO taskExtDO = new BpmTaskExtDO()
237   - .setAssigneeUserId(NumberUtils.parseLong(task.getAssignee()))
238   - .setTaskId(task.getId());
  302 + BpmTaskExtDO taskExtDO =
  303 + new BpmTaskExtDO().setAssigneeUserId(NumberUtils.parseLong(task.getAssignee())).setTaskId(task.getId());
239 304 taskExtMapper.updateByTaskId(taskExtDO);
240 305 // 发送通知。在事务提交时,批量执行操作,所以直接查询会无法查询到 ProcessInstance,所以这里是通过监听事务的提交来实现。
241 306 TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronization() {
242 307 @Override
243 308 public void afterCommit() {
244   - ProcessInstance processInstance = processInstanceService.getProcessInstance(task.getProcessInstanceId());
  309 + ProcessInstance processInstance =
  310 + processInstanceService.getProcessInstance(task.getProcessInstanceId());
245 311 AdminUserRespDTO startUser = adminUserApi.getUser(Long.valueOf(processInstance.getStartUserId()));
246   - messageService.sendMessageWhenTaskAssigned(BpmTaskConvert.INSTANCE.convert(processInstance, startUser, task));
  312 + messageService.sendMessageWhenTaskAssigned(
  313 + BpmTaskConvert.INSTANCE.convert(processInstance, startUser, task));
247 314 }
248 315 });
249 316 }
250 317  
251   - /**
252   - * 校验任务是否存在, 并且是否是分配给自己的任务
253   - * @param userId 用户 id
254   - * @param taskId task id
255   - */
256   - private Task checkTask(Long userId, String taskId) {
257   - Task task = getTask(taskId);
258   - if (task == null) {
259   - throw exception(TASK_COMPLETE_FAIL_NOT_EXISTS);
260   - }
261   - if (!Objects.equals(userId, NumberUtils.parseLong(task.getAssignee()))) {
262   - throw exception(TASK_COMPLETE_FAIL_ASSIGN_NOT_SELF);
263   - }
264   - return task;
265   - }
266   -
267 318 private Task getTask(String id) {
268 319 return taskService.createTaskQuery().taskId(id).singleResult();
269 320 }
  321 +
  322 + private HistoricTaskInstance getHistoricTask(String id) {
  323 + return historyService.createHistoricTaskInstanceQuery().taskId(id).singleResult();
  324 + }
  325 +
270 326 }
... ...
yudao-module-bpm/yudao-module-bpm-base/src/main/java/cn/iocoder/yudao/module/bpm/service/task/package-info.java renamed to yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/task/package-info.java
yudao-module-bpm/yudao-module-bpm-biz-activiti/src/test/java/cn/iocoder/yudao/module/bpm/framework/activiti/core/behavior/script/impl/BpmTaskAssignLeaderX2ScriptTest.java renamed to yudao-module-bpm/yudao-module-bpm-biz/src/test/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/behavior/script/impl/BpmTaskAssignLeaderX2ScriptTest.java
1   -package cn.iocoder.yudao.module.bpm.framework.activiti.core.behavior.script.impl;
  1 +package cn.iocoder.yudao.module.bpm.framework.flowable.core.behavior.script.impl;
2 2  
3 3 import cn.iocoder.yudao.framework.test.core.ut.BaseMockitoUnitTest;
  4 +import cn.iocoder.yudao.module.bpm.service.task.BpmProcessInstanceService;
4 5 import cn.iocoder.yudao.module.system.api.dept.DeptApi;
5 6 import cn.iocoder.yudao.module.system.api.dept.dto.DeptRespDTO;
6 7 import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
7 8 import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
8   -import org.activiti.engine.impl.persistence.entity.ExecutionEntityImpl;
9   -import org.activiti.engine.impl.persistence.entity.TaskEntity;
10   -import org.activiti.engine.impl.persistence.entity.TaskEntityImpl;
  9 +import org.flowable.engine.delegate.DelegateExecution;
  10 +import org.flowable.engine.impl.persistence.entity.ExecutionEntityImpl;
11 11 import org.junit.jupiter.api.Test;
12 12 import org.mockito.InjectMocks;
13 13 import org.mockito.Mock;
14   -import org.springframework.boot.test.mock.mockito.MockBean;
15 14  
16 15 import java.util.Set;
17 16  
18 17 import static cn.iocoder.yudao.framework.common.util.collection.SetUtils.asSet;
19 18 import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomPojo;
  19 +import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomString;
20 20 import static org.junit.jupiter.api.Assertions.assertEquals;
21 21 import static org.mockito.ArgumentMatchers.eq;
22 22 import static org.mockito.Mockito.when;
23 23  
24   -class BpmTaskAssignLeaderX2ScriptTest extends BaseMockitoUnitTest {
  24 +public class BpmTaskAssignLeaderX2ScriptTest extends BaseMockitoUnitTest {
25 25  
26 26 @InjectMocks
27 27 private BpmTaskAssignLeaderX2Script script;
... ... @@ -30,17 +30,19 @@ class BpmTaskAssignLeaderX2ScriptTest extends BaseMockitoUnitTest {
30 30 private AdminUserApi adminUserApi;
31 31 @Mock
32 32 private DeptApi deptApi;
  33 + @Mock
  34 + private BpmProcessInstanceService bpmProcessInstanceService;
33 35  
34 36 @Test
35 37 public void testCalculateTaskCandidateUsers_noDept() {
36 38 // 准备参数
37   - TaskEntity task = buildTaskEntity(1L);
  39 + DelegateExecution execution = mockDelegateExecution(1L);
38 40 // mock 方法(startUser)
39 41 AdminUserRespDTO startUser = randomPojo(AdminUserRespDTO.class, o -> o.setDeptId(10L));
40 42 when(adminUserApi.getUser(eq(1L))).thenReturn(startUser);
41 43  
42 44 // 调用
43   - Set<Long> result = script.calculateTaskCandidateUsers(task);
  45 + Set<Long> result = script.calculateTaskCandidateUsers(execution);
44 46 // 断言
45 47 assertEquals(0, result.size());
46 48 }
... ... @@ -48,7 +50,7 @@ class BpmTaskAssignLeaderX2ScriptTest extends BaseMockitoUnitTest {
48 50 @Test
49 51 public void testCalculateTaskCandidateUsers_noParentDept() {
50 52 // 准备参数
51   - TaskEntity task = buildTaskEntity(1L);
  53 + DelegateExecution execution = mockDelegateExecution(1L);
52 54 // mock 方法(startUser)
53 55 AdminUserRespDTO startUser = randomPojo(AdminUserRespDTO.class, o -> o.setDeptId(10L));
54 56 when(adminUserApi.getUser(eq(1L))).thenReturn(startUser);
... ... @@ -57,7 +59,7 @@ class BpmTaskAssignLeaderX2ScriptTest extends BaseMockitoUnitTest {
57 59 when(deptApi.getDept(eq(10L))).thenReturn(startUserDept);
58 60  
59 61 // 调用
60   - Set<Long> result = script.calculateTaskCandidateUsers(task);
  62 + Set<Long> result = script.calculateTaskCandidateUsers(execution);
61 63 // 断言
62 64 assertEquals(asSet(20L), result);
63 65 }
... ... @@ -65,7 +67,7 @@ class BpmTaskAssignLeaderX2ScriptTest extends BaseMockitoUnitTest {
65 67 @Test
66 68 public void testCalculateTaskCandidateUsers_existParentDept() {
67 69 // 准备参数
68   - TaskEntity task = buildTaskEntity(1L);
  70 + DelegateExecution execution = mockDelegateExecution(1L);
69 71 // mock 方法(startUser)
70 72 AdminUserRespDTO startUser = randomPojo(AdminUserRespDTO.class, o -> o.setDeptId(10L));
71 73 when(adminUserApi.getUser(eq(1L))).thenReturn(startUser);
... ... @@ -78,17 +80,21 @@ class BpmTaskAssignLeaderX2ScriptTest extends BaseMockitoUnitTest {
78 80 when(deptApi.getDept(eq(100L))).thenReturn(parentDept);
79 81  
80 82 // 调用
81   - Set<Long> result = script.calculateTaskCandidateUsers(task);
  83 + Set<Long> result = script.calculateTaskCandidateUsers(execution);
82 84 // 断言
83 85 assertEquals(asSet(200L), result);
84 86 }
85 87  
86 88 @SuppressWarnings("SameParameterValue")
87   - private TaskEntity buildTaskEntity(Long startUserId) {
88   - TaskEntityImpl task = new TaskEntityImpl();
89   - task.setProcessInstance(new ExecutionEntityImpl());
90   - task.getProcessInstance().setStartUserId(String.valueOf(startUserId));
91   - return task;
  89 + private DelegateExecution mockDelegateExecution(Long startUserId) {
  90 + ExecutionEntityImpl execution = new ExecutionEntityImpl();
  91 + execution.setProcessInstanceId(randomString());
  92 + // mock 返回 startUserId
  93 + ExecutionEntityImpl processInstance = new ExecutionEntityImpl();
  94 + processInstance.setStartUserId(String.valueOf(startUserId));
  95 + when(bpmProcessInstanceService.getProcessInstance(eq(execution.getProcessInstanceId())))
  96 + .thenReturn(processInstance);
  97 + return execution;
92 98 }
93 99  
94 100 }
... ...
yudao-module-bpm/yudao-module-bpm-base/src/test/java/cn/iocoder/yudao/module/bpm/service/definition/BpmFormServiceTest.java renamed to yudao-module-bpm/yudao-module-bpm-biz/src/test/java/cn/iocoder/yudao/module/bpm/service/definition/BpmFormServiceTest.java
yudao-module-bpm/yudao-module-bpm-biz-activiti/src/test/java/cn/iocoder/yudao/module/bpm/framework/activiti/core/behavior/BpmUserTaskActivityBehaviorTest.java renamed to yudao-module-bpm/yudao-module-bpm-biz/src/test/java/cn/iocoder/yudao/module/bpm/service/definition/BpmTaskAssignRuleServiceImplTest.java
1   -package cn.iocoder.yudao.module.bpm.framework.activiti.core.behavior;
  1 +package cn.iocoder.yudao.module.bpm.service.definition;
2 2  
3 3 import cn.hutool.core.map.MapUtil;
4   -import cn.iocoder.yudao.module.bpm.framework.activiti.core.behavior.script.BpmTaskAssignScript;
5   -import cn.iocoder.yudao.module.bpm.service.definition.BpmTaskAssignRuleService;
6 4 import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
7 5 import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
8   -import cn.iocoder.yudao.framework.test.core.ut.BaseMockitoUnitTest;
  6 +import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest;
9 7 import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmTaskAssignRuleDO;
10 8 import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmUserGroupDO;
11 9 import cn.iocoder.yudao.module.bpm.enums.definition.BpmTaskAssignRuleTypeEnum;
12 10 import cn.iocoder.yudao.module.bpm.enums.definition.BpmTaskRuleScriptEnum;
13   -import cn.iocoder.yudao.module.bpm.service.definition.BpmUserGroupService;
  11 +import cn.iocoder.yudao.module.bpm.framework.flowable.core.behavior.script.BpmTaskAssignScript;
  12 +import cn.iocoder.yudao.module.bpm.framework.flowable.core.behavior.script.impl.BpmTaskAssignStartUserScript;
14 13 import cn.iocoder.yudao.module.system.api.dept.DeptApi;
  14 +import cn.iocoder.yudao.module.system.api.dept.PostApi;
15 15 import cn.iocoder.yudao.module.system.api.dept.dto.DeptRespDTO;
  16 +import cn.iocoder.yudao.module.system.api.dict.DictDataApi;
16 17 import cn.iocoder.yudao.module.system.api.permission.PermissionApi;
  18 +import cn.iocoder.yudao.module.system.api.permission.RoleApi;
17 19 import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
18 20 import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
19   -import org.activiti.engine.impl.persistence.entity.TaskEntity;
  21 +import org.flowable.engine.delegate.DelegateExecution;
20 22 import org.junit.jupiter.api.Test;
21   -import org.mockito.InjectMocks;
22   -import org.mockito.Mock;
  23 +import org.springframework.boot.test.mock.mockito.MockBean;
  24 +import org.springframework.context.annotation.Import;
23 25  
  26 +import javax.annotation.Resource;
24 27 import java.util.Arrays;
25 28 import java.util.List;
26 29 import java.util.Map;
... ... @@ -33,21 +36,31 @@ import static org.junit.jupiter.api.Assertions.assertEquals;
33 36 import static org.mockito.ArgumentMatchers.eq;
34 37 import static org.mockito.Mockito.when;
35 38  
36   -public class BpmUserTaskActivityBehaviorTest extends BaseMockitoUnitTest {
  39 +/**
  40 + * {@link BpmTaskAssignRuleService} 的单元测试
  41 + *
  42 + * @author 芋道源码
  43 + */
  44 +@Import({BpmTaskAssignRuleServiceImpl.class, BpmTaskAssignStartUserScript.class}) // Import 引入 BpmTaskAssignStartUserScript 目的是保证不报错
  45 +public class BpmTaskAssignRuleServiceImplTest extends BaseDbUnitTest {
37 46  
38   - @InjectMocks
39   - private BpmUserTaskActivityBehavior behavior;
40   - @Mock
41   - private BpmTaskAssignRuleService bpmTaskRuleService;
42   - @Mock
43   - private BpmUserGroupService userGroupService;
  47 + @Resource
  48 + private BpmTaskAssignRuleServiceImpl bpmTaskRuleService;
44 49  
45   - @Mock
  50 + @MockBean
  51 + private BpmUserGroupService userGroupService;
  52 + @MockBean
46 53 private DeptApi deptApi;
47   - @Mock
  54 + @MockBean
48 55 private AdminUserApi adminUserApi;
49   - @Mock
  56 + @MockBean
50 57 private PermissionApi permissionApi;
  58 + @MockBean
  59 + private RoleApi roleApi;
  60 + @MockBean
  61 + private PostApi postApi;
  62 + @MockBean
  63 + private DictDataApi dictDataApi;
51 64  
52 65 @Test
53 66 public void testCalculateTaskCandidateUsers_Role() {
... ... @@ -60,7 +73,7 @@ public class BpmUserTaskActivityBehaviorTest extends BaseMockitoUnitTest {
60 73 mockGetUserMap(asSet(11L, 22L));
61 74  
62 75 // 调用
63   - Set<Long> results = behavior.calculateTaskCandidateUsers(null, rule);
  76 + Set<Long> results = bpmTaskRuleService.calculateTaskCandidateUsers(null, rule);
64 77 // 断言
65 78 assertEquals(asSet(11L, 22L), results);
66 79 }
... ... @@ -77,7 +90,7 @@ public class BpmUserTaskActivityBehaviorTest extends BaseMockitoUnitTest {
77 90 mockGetUserMap(asSet(11L, 22L));
78 91  
79 92 // 调用
80   - Set<Long> results = behavior.calculateTaskCandidateUsers(null, rule);
  93 + Set<Long> results = bpmTaskRuleService.calculateTaskCandidateUsers(null, rule);
81 94 // 断言
82 95 assertEquals(asSet(11L, 22L), results);
83 96 }
... ... @@ -94,7 +107,7 @@ public class BpmUserTaskActivityBehaviorTest extends BaseMockitoUnitTest {
94 107 mockGetUserMap(asSet(11L, 22L));
95 108  
96 109 // 调用
97   - Set<Long> results = behavior.calculateTaskCandidateUsers(null, rule);
  110 + Set<Long> results = bpmTaskRuleService.calculateTaskCandidateUsers(null, rule);
98 111 // 断言
99 112 assertEquals(asSet(11L, 22L), results);
100 113 }
... ... @@ -111,7 +124,7 @@ public class BpmUserTaskActivityBehaviorTest extends BaseMockitoUnitTest {
111 124 mockGetUserMap(asSet(11L, 22L));
112 125  
113 126 // 调用
114   - Set<Long> results = behavior.calculateTaskCandidateUsers(null, rule);
  127 + Set<Long> results = bpmTaskRuleService.calculateTaskCandidateUsers(null, rule);
115 128 // 断言
116 129 assertEquals(asSet(11L, 22L), results);
117 130 }
... ... @@ -125,7 +138,7 @@ public class BpmUserTaskActivityBehaviorTest extends BaseMockitoUnitTest {
125 138 mockGetUserMap(asSet(1L, 2L));
126 139  
127 140 // 调用
128   - Set<Long> results = behavior.calculateTaskCandidateUsers(null, rule);
  141 + Set<Long> results = bpmTaskRuleService.calculateTaskCandidateUsers(null, rule);
129 142 // 断言
130 143 assertEquals(asSet(1L, 2L), results);
131 144 }
... ... @@ -142,7 +155,7 @@ public class BpmUserTaskActivityBehaviorTest extends BaseMockitoUnitTest {
142 155 mockGetUserMap(asSet(11L, 12L, 21L, 22L));
143 156  
144 157 // 调用
145   - Set<Long> results = behavior.calculateTaskCandidateUsers(null, rule);
  158 + Set<Long> results = bpmTaskRuleService.calculateTaskCandidateUsers(null, rule);
146 159 // 断言
147 160 assertEquals(asSet(11L, 12L, 21L, 22L), results);
148 161 }
... ... @@ -156,7 +169,7 @@ public class BpmUserTaskActivityBehaviorTest extends BaseMockitoUnitTest {
156 169 BpmTaskAssignScript script1 = new BpmTaskAssignScript() {
157 170  
158 171 @Override
159   - public Set<Long> calculateTaskCandidateUsers(TaskEntity task) {
  172 + public Set<Long> calculateTaskCandidateUsers(DelegateExecution task) {
160 173 return singleton(11L);
161 174 }
162 175  
... ... @@ -168,7 +181,7 @@ public class BpmUserTaskActivityBehaviorTest extends BaseMockitoUnitTest {
168 181 BpmTaskAssignScript script2 = new BpmTaskAssignScript() {
169 182  
170 183 @Override
171   - public Set<Long> calculateTaskCandidateUsers(TaskEntity task) {
  184 + public Set<Long> calculateTaskCandidateUsers(DelegateExecution task) {
172 185 return singleton(22L);
173 186 }
174 187  
... ... @@ -177,11 +190,11 @@ public class BpmUserTaskActivityBehaviorTest extends BaseMockitoUnitTest {
177 190 return BpmTaskRuleScriptEnum.LEADER_X2;
178 191 }
179 192 };
180   - behavior.setScripts(Arrays.asList(script1, script2));
  193 + bpmTaskRuleService.setScripts(Arrays.asList(script1, script2));
181 194 mockGetUserMap(asSet(11L, 22L));
182 195  
183 196 // 调用
184   - Set<Long> results = behavior.calculateTaskCandidateUsers(null, rule);
  197 + Set<Long> results = bpmTaskRuleService.calculateTaskCandidateUsers(null, rule);
185 198 // 断言
186 199 assertEquals(asSet(11L, 22L), results);
187 200 }
... ... @@ -200,7 +213,7 @@ public class BpmUserTaskActivityBehaviorTest extends BaseMockitoUnitTest {
200 213 when(adminUserApi.getUserMap(eq(assigneeUserIds))).thenReturn(userMap);
201 214  
202 215 // 调用
203   - behavior.removeDisableUsers(assigneeUserIds);
  216 + bpmTaskRuleService.removeDisableUsers(assigneeUserIds);
204 217 // 断言
205 218 assertEquals(asSet(1L), assigneeUserIds);
206 219 }
... ...
yudao-module-bpm/yudao-module-bpm-base/src/test/java/cn/iocoder/yudao/module/bpm/service/definition/BpmUserGroupServiceTest.java renamed to yudao-module-bpm/yudao-module-bpm-biz/src/test/java/cn/iocoder/yudao/module/bpm/service/definition/BpmUserGroupServiceTest.java
yudao-module-bpm/yudao-module-bpm-base/src/test/resources/application-unit-test.yaml renamed to yudao-module-bpm/yudao-module-bpm-biz/src/test/resources/application-unit-test.yaml
... ... @@ -20,8 +20,9 @@ spring:
20 20 init:
21 21 schema-locations: classpath:/sql/create_tables.sql
22 22  
23   -mybatis:
  23 +mybatis-plus:
24 24 lazy-initialization: true # 单元测试,设置 MyBatis Mapper 延迟加载,加速每个单元测试
  25 + type-aliases-package: ${yudao.info.base-package}.module.*.dal.dataobject
25 26  
26 27 --- #################### 定时任务相关配置 ####################
27 28  
... ...
yudao-module-bpm/yudao-module-bpm-base/src/test/resources/logback.xml renamed to yudao-module-bpm/yudao-module-bpm-biz/src/test/resources/logback.xml
yudao-module-bpm/yudao-module-bpm-base/src/test/resources/sql/clean.sql renamed to yudao-module-bpm/yudao-module-bpm-biz/src/test/resources/sql/clean.sql
yudao-module-bpm/yudao-module-bpm-base/src/test/resources/sql/create_tables.sql renamed to yudao-module-bpm/yudao-module-bpm-biz/src/test/resources/sql/create_tables.sql
yudao-server/pom.xml
... ... @@ -54,7 +54,7 @@
54 54 <!-- 默认引入 yudao-module-bpm-biz-flowable 实现,可以替换为 yudao-module-bpm-biz-activiti 实现-->
55 55 <dependency>
56 56 <groupId>cn.iocoder.boot</groupId>
57   - <artifactId>yudao-module-bpm-biz-flowable</artifactId>
  57 + <artifactId>yudao-module-bpm-biz</artifactId>
58 58 <version>${revision}</version>
59 59 </dependency>
60 60 <!-- <dependency>-->
... ...
yudao-server/src/main/resources/application.yaml
... ... @@ -32,17 +32,6 @@ spring:
32 32 redis:
33 33 time-to-live: 1h # 设置过期时间为 1 小时
34 34  
35   - # 工作流 Activiti 配置
36   - activiti:
37   - # 1. false: 默认值,activiti启动时,对比数据库表中保存的版本,如果不匹配。将抛出异常
38   - # 2. true: 启动时会对数据库中所有表进行更新操作,如果表存在,不做处理,反之,自动创建表
39   - # 3. create_drop: 启动时自动创建表,关闭时自动删除表
40   - # 4. drop_create: 启动时,删除旧表,再创建新表
41   - database-schema-update: true # 设置为 false,可通过 sql/activiti.sql 初始化
42   - db-history-used: true # activiti7 默认 false 不生成历史信息表,需手动设置开启
43   - check-process-definitions: false # 设置为 false,禁用 /resources/processes 自动部署 BPMN XML 流程
44   - history-level: full # full:保存历史数据的最高级别,可保存全部流程相关细节,包括流程流转各节点参数
45   -
46 35 # 工作流 Flowable 配置
47 36 flowable:
48 37 # 1. false: 默认值,Flowable 启动时,对比数据库表中保存的版本,如果不匹配。将抛出异常
... ...
yudao-ui-admin/src/api/bpm/task.js
... ... @@ -39,6 +39,13 @@ export function rejectTask(data) {
39 39 data: data
40 40 })
41 41 }
  42 +export function backTask(data) {
  43 + return request({
  44 + url: '/bpm/task/back',
  45 + method: 'PUT',
  46 + data: data
  47 + })
  48 +}
42 49  
43 50 export function updateTaskAssignee(data) {
44 51 return request({
... ...
yudao-ui-admin/src/components/bpmnProcessDesigner/package/designer/ProcessDesigner.vue
... ... @@ -118,6 +118,7 @@ export default {
118 118 componentName: "MyProcessDesigner",
119 119 props: {
120 120 value: String, // xml 字符串
  121 + valueWatch: true, // xml 字符串的 watch 状态
121 122 processId: String, // 流程 key 标识
122 123 processName: String, // 流程 name 名字
123 124 formId: Number, // 流程 form 表单编号
... ... @@ -252,11 +253,6 @@ export default {
252 253 this.bpmnModeler = null;
253 254 });
254 255 },
255   - watch: {
256   - value: function (newValue) { // 在 xmlString 发生变化时,重新创建,从而绘制流程图
257   - this.createNewDiagram(newValue);
258   - }
259   - },
260 256 methods: {
261 257 initBpmnModeler() {
262 258 if (this.bpmnModeler) return;
... ... @@ -307,7 +303,7 @@ export default {
307 303 let newName = this.processName || `业务流程_${new Date().getTime()}`;
308 304 let xmlString = xml || DefaultEmptyXML(newId, newName, this.prefix);
309 305 try {
310   - console.log(this.bpmnModeler.importXML);
  306 + // console.log(this.bpmnModeler.importXML);
311 307 let { warnings } = await this.bpmnModeler.importXML(xmlString);
312 308 if (warnings && warnings.length) {
313 309 warnings.forEach(warn => console.warn(warn));
... ...
yudao-ui-admin/src/components/bpmnProcessDesigner/package/designer/ProcessViewer.vue
... ... @@ -116,10 +116,11 @@ export default {
116 116 let todoActivity = activityList.find(m => !m.endTime) // 找到待办的任务
117 117 let endActivity = activityList[activityList.length - 1] // 获得最后一个任务
118 118 // debugger
119   - console.log(this.bpmnModeler.getDefinitions().rootElements[0].flowElements);
  119 + // console.log(this.bpmnModeler.getDefinitions().rootElements[0].flowElements);
120 120 this.bpmnModeler.getDefinitions().rootElements[0].flowElements?.forEach(n => {
121 121 let activity = activityList.find(m => m.key === n.id) // 找到对应的活动
122 122 if (n.$type === 'bpmn:UserTask') { // 用户任务
  123 + debugger
123 124 if (!activity) {
124 125 return;
125 126 }
... ...
yudao-ui-admin/src/components/bpmnProcessDesigner/package/penal/base/ElementBaseInfo.vue
... ... @@ -2,6 +2,8 @@
2 2 <div class="panel-tab__content">
3 3 <el-form size="mini" label-width="90px" :model="model" :rules="rules" @submit.native.prevent>
4 4 <div v-if="elementBaseInfo.$type === 'bpmn:Process'"> <!-- 如果是 Process 信息的时候,使用自定义表单 -->
  5 + <el-link href="https://doc.iocoder.cn/bpm/#_3-%E6%B5%81%E7%A8%8B%E5%9B%BE%E7%A4%BA%E4%BE%8B"
  6 + type="danger" target="_blank">如何实现实现会签、或签?</el-link>
5 7 <el-form-item label="流程标识" prop="key">
6 8 <el-input v-model="model.key" placeholder="请输入流标标识"
7 9 :disabled="model.id !== undefined && model.id.length > 0" @change="handleKeyUpdate" />
... ...
yudao-ui-admin/src/components/bpmnProcessDesigner/package/penal/flow-condition/FlowCondition.vue
... ... @@ -15,7 +15,7 @@
15 15 </el-select>
16 16 </el-form-item>
17 17 <el-form-item label="表达式" v-if="flowConditionForm.conditionType && flowConditionForm.conditionType === 'expression'" key="express">
18   - <el-input v-model="flowConditionForm.body" clearable @change="updateFlowCondition" />
  18 + <el-input v-model="flowConditionForm.body" style="width:192px;" clearable @change="updateFlowCondition" />
19 19 </el-form-item>
20 20 <template v-if="flowConditionForm.conditionType && flowConditionForm.conditionType === 'script'">
21 21 <el-form-item label="脚本语言" key="language">
... ...
yudao-ui-admin/src/components/bpmnProcessDesigner/package/penal/multi-instance/ElementMultiInstance.vue
... ... @@ -15,7 +15,7 @@
15 15 <el-form-item label="循环基数" key="loopCardinality">
16 16 <el-input v-model="loopInstanceForm.loopCardinality" clearable @change="updateLoopCardinality" />
17 17 </el-form-item>
18   - <el-form-item label="集合" key="collection">
  18 + <el-form-item label="集合" key="collection" v-show="false">
19 19 <el-input v-model="loopInstanceForm.collection" clearable @change="updateLoopBase" />
20 20 </el-form-item>
21 21 <el-form-item label="元素变量" key="elementVariable">
... ... @@ -131,7 +131,7 @@ export default {
131 131 if (type === "SequentialMultiInstance") {
132 132 this.multiLoopInstance = window.bpmnInstances.moddle.create("bpmn:MultiInstanceLoopCharacteristics", { isSequential: true });
133 133 } else {
134   - this.multiLoopInstance = window.bpmnInstances.moddle.create("bpmn:MultiInstanceLoopCharacteristics");
  134 + this.multiLoopInstance = window.bpmnInstances.moddle.create("bpmn:MultiInstanceLoopCharacteristics", { collection: "${coll_userList}" });
135 135 }
136 136 window.bpmnInstances.modeling.updateProperties(this.bpmnElement, {
137 137 loopCharacteristics: this.multiLoopInstance
... ...
yudao-ui-admin/src/views/bpm/model/modelEditor.vue
... ... @@ -2,7 +2,7 @@
2 2 <div class="app-container">
3 3  
4 4 <!-- 流程设计器,负责绘制流程等 -->
5   - <my-process-designer :key="`designer-${reloadIndex}`" v-model="xmlString" v-bind="controlForm"
  5 + <my-process-designer v-if="xmlString !== undefined" :key="`designer-${reloadIndex}`" v-model="xmlString" v-bind="controlForm"
6 6 keyboard ref="processDesigner" @init-finished="initModeler"
7 7 @save="save"/>
8 8  
... ... @@ -30,7 +30,7 @@ export default {
30 30 components: { MyProcessPalette },
31 31 data() {
32 32 return {
33   - xmlString: "", // BPMN XML
  33 + xmlString: undefined, // BPMN XML
34 34 modeler: null,
35 35 reloadIndex: 0,
36 36 controlDrawerVisible: false,
... ... @@ -72,21 +72,6 @@ export default {
72 72 console.log(modeler);
73 73 }, 10);
74 74 },
75   - reloadProcessDesigner(deep) {
76   - this.controlForm.additionalModel = [];
77   - for (let key in this.addis) {
78   - if (this.addis[key]) {
79   - this.controlForm.additionalModel.push(this.addis[key]);
80   - }
81   - }
82   - deep && (this.xmlString = undefined);
83   - this.reloadIndex += 1;
84   - this.modeler = null; // 避免 panel 异常
85   - // if (deep) {
86   - // this.xmlString = undefined;
87   - // this.$refs.processDesigner.processRestart();
88   - // }
89   - },
90 75 save(bpmnXml) {
91 76 const data = {
92 77 ...this.model,
... ...
yudao-ui-admin/src/views/bpm/processInstance/detail.vue
... ... @@ -60,7 +60,7 @@
60 60 审批人:{{ item.assigneeUser.nickname }}
61 61 <el-tag type="info" size="mini">{{ item.assigneeUser.deptName }}</el-tag>
62 62 </label>
63   - <label style="font-weight: normal">创建时间:</label>
  63 + <label style="font-weight: normal" v-if="item.createTime">创建时间:</label>
64 64 <label style="color:#8a909c; font-weight: normal">{{ parseTime(item.createTime) }}</label>
65 65 <label v-if="item.endTime" style="margin-left: 30px;font-weight: normal">审批时间:</label>
66 66 <label v-if="item.endTime" style="color:#8a909c;font-weight: normal"> {{ parseTime(item.endTime) }}</label>
... ... @@ -109,7 +109,7 @@ import store from &quot;@/store&quot;;
109 109 import {decodeFields} from "@/utils/formGenerator";
110 110 import Parser from '@/components/parser/Parser'
111 111 import {createProcessInstance, getProcessInstance} from "@/api/bpm/processInstance";
112   -import {approveTask, getTaskListByProcessInstanceId, rejectTask, updateTaskAssignee} from "@/api/bpm/task";
  112 +import {approveTask, getTaskListByProcessInstanceId, rejectTask, updateTaskAssignee,backTask} from "@/api/bpm/task";
113 113 import {getDate} from "@/utils/dateUtils";
114 114 import {listSimpleUsers} from "@/api/system/user";
115 115 import {getActivityList} from "@/api/bpm/activity";
... ... @@ -232,7 +232,13 @@ export default {
232 232 this.auditForms = [];
233 233 getTaskListByProcessInstanceId(this.id).then(response => {
234 234 // 审批记录
235   - this.tasks = response.data;
  235 + this.tasks = [];
  236 + // 移除已取消的审批
  237 + response.data.forEach(task => {
  238 + if (task.result !== 4) {
  239 + this.tasks.push(task);
  240 + }
  241 + });
236 242 // 排序,将未完成的排在前面,已完成的排在后面;
237 243 this.tasks.sort((a, b) => {
238 244 // 有已完成的情况,按照完成时间倒序
... ... @@ -407,6 +413,15 @@ export default {
407 413 /** 处理审批退回的操作 */
408 414 handleBack(task) {
409 415 this.$modal.msgError("暂不支持【退回】功能!");
  416 + // 可参考 http://blog.wya1.com/article/636697030/details/7296
  417 + // const data = {
  418 + // id: task.id,
  419 + // assigneeUserId: 1
  420 + // }
  421 + // backTask(data).then(response => {
  422 + // this.$modal.msgSuccess("回退成功!");
  423 + // this.getDetail(); // 获得最新详情
  424 + // });
410 425 }
411 426 }
412 427 };
... ...
yudao-ui-admin/src/views/bpm/taskAssignRule/taskAssignRuleDialog.vue
... ... @@ -53,7 +53,7 @@
53 53 <el-option v-for="item in postOptions" :key="parseInt(item.id)" :label="item.name" :value="parseInt(item.id)" />
54 54 </el-select>
55 55 </el-form-item>
56   - <el-form-item v-if="form.type === 30" label="指定用户" prop="userIds">
  56 + <el-form-item v-if="form.type === 30 || form.type === 31 || form.type === 32" label="指定用户" prop="userIds">
57 57 <el-select v-model="form.userIds" multiple clearable style="width: 100%">
58 58 <el-option v-for="item in userOptions" :key="parseInt(item.id)" :label="item.nickname" :value="parseInt(item.id)" />
59 59 </el-select>
... ... @@ -215,7 +215,7 @@ export default {
215 215 this.form.deptIds.push(...row.options);
216 216 } else if (row.type === 22) {
217 217 this.form.postIds.push(...row.options);
218   - } else if (row.type === 30) {
  218 + } else if (row.type === 30 || row.type === 31 || row.type === 32) {
219 219 this.form.userIds.push(...row.options);
220 220 } else if (row.type === 40) {
221 221 this.form.userGroupIds.push(...row.options);
... ... @@ -240,7 +240,7 @@ export default {
240 240 form.options = form.deptIds;
241 241 } else if (form.type === 22) {
242 242 form.options = form.postIds;
243   - } else if (form.type === 30) {
  243 + } else if (form.type === 30 || form.type === 31 || form.type === 32) {
244 244 form.options = form.userIds;
245 245 } else if (form.type === 40) {
246 246 form.options = form.userGroupIds;
... ... @@ -302,7 +302,7 @@ export default {
302 302 return postOption.name;
303 303 }
304 304 }
305   - } else if (type === 30) {
  305 + } else if (type === 30 || type === 31 || type === 32) {
306 306 for (const userOption of this.userOptions) {
307 307 if (userOption.id === option) {
308 308 return userOption.nickname;
... ...