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