Commit 559bab571ae6a1d80febdaee675bb24fa54e44b3
1 parent
29a0fbfc
BPM:移除 flowable starter 模块,融合到 bpm 模块中
Showing
25 changed files
with
147 additions
and
159 deletions
yudao-module-bpm/pom.xml
| @@ -11,7 +11,6 @@ | @@ -11,7 +11,6 @@ | ||
| 11 | <modules> | 11 | <modules> |
| 12 | <module>yudao-module-bpm-api</module> | 12 | <module>yudao-module-bpm-api</module> |
| 13 | <module>yudao-module-bpm-biz</module> | 13 | <module>yudao-module-bpm-biz</module> |
| 14 | - <module>yudao-spring-boot-starter-flowable</module> | ||
| 15 | </modules> | 14 | </modules> |
| 16 | <artifactId>yudao-module-bpm</artifactId> | 15 | <artifactId>yudao-module-bpm</artifactId> |
| 17 | <packaging>pom</packaging> | 16 | <packaging>pom</packaging> |
yudao-module-bpm/yudao-module-bpm-biz/pom.xml
| @@ -64,15 +64,19 @@ | @@ -64,15 +64,19 @@ | ||
| 64 | <artifactId>yudao-spring-boot-starter-test</artifactId> | 64 | <artifactId>yudao-spring-boot-starter-test</artifactId> |
| 65 | </dependency> | 65 | </dependency> |
| 66 | 66 | ||
| 67 | - <!-- 工作流相关 --> | 67 | + <!-- 工具类相关 --> |
| 68 | <dependency> | 68 | <dependency> |
| 69 | <groupId>cn.iocoder.boot</groupId> | 69 | <groupId>cn.iocoder.boot</groupId> |
| 70 | - <artifactId>yudao-spring-boot-starter-flowable</artifactId> | ||
| 71 | - <version>${revision}</version> | 70 | + <artifactId>yudao-spring-boot-starter-excel</artifactId> |
| 72 | </dependency> | 71 | </dependency> |
| 72 | + <!-- Flowable 工作流相关 --> | ||
| 73 | <dependency> | 73 | <dependency> |
| 74 | - <groupId>cn.iocoder.boot</groupId> | ||
| 75 | - <artifactId>yudao-spring-boot-starter-excel</artifactId> | 74 | + <groupId>org.flowable</groupId> |
| 75 | + <artifactId>flowable-spring-boot-starter-process</artifactId> | ||
| 76 | + </dependency> | ||
| 77 | + <dependency> | ||
| 78 | + <groupId>org.flowable</groupId> | ||
| 79 | + <artifactId>flowable-spring-boot-starter-actuator</artifactId> | ||
| 76 | </dependency> | 80 | </dependency> |
| 77 | </dependencies> | 81 | </dependencies> |
| 78 | </project> | 82 | </project> |
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/convert/task/BpmProcessInstanceConvert.java
| @@ -4,7 +4,7 @@ import cn.iocoder.yudao.framework.common.pojo.PageResult; | @@ -4,7 +4,7 @@ import cn.iocoder.yudao.framework.common.pojo.PageResult; | ||
| 4 | import cn.iocoder.yudao.framework.common.util.collection.MapUtils; | 4 | import cn.iocoder.yudao.framework.common.util.collection.MapUtils; |
| 5 | import cn.iocoder.yudao.framework.common.util.number.NumberUtils; | 5 | import cn.iocoder.yudao.framework.common.util.number.NumberUtils; |
| 6 | import cn.iocoder.yudao.framework.common.util.object.BeanUtils; | 6 | import cn.iocoder.yudao.framework.common.util.object.BeanUtils; |
| 7 | -import cn.iocoder.yudao.framework.flowable.core.util.FlowableUtils; | 7 | +import cn.iocoder.yudao.module.bpm.framework.flowable.core.util.FlowableUtils; |
| 8 | import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance.BpmProcessInstancePageItemRespVO; | 8 | import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance.BpmProcessInstancePageItemRespVO; |
| 9 | import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance.BpmProcessInstanceRespVO; | 9 | import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance.BpmProcessInstanceRespVO; |
| 10 | import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmCategoryDO; | 10 | import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmCategoryDO; |
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/convert/task/BpmTaskConvert.java
| @@ -6,7 +6,7 @@ import cn.iocoder.yudao.framework.common.pojo.PageResult; | @@ -6,7 +6,7 @@ import cn.iocoder.yudao.framework.common.pojo.PageResult; | ||
| 6 | import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; | 6 | import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; |
| 7 | import cn.iocoder.yudao.framework.common.util.number.NumberUtils; | 7 | import cn.iocoder.yudao.framework.common.util.number.NumberUtils; |
| 8 | import cn.iocoder.yudao.framework.common.util.object.BeanUtils; | 8 | import cn.iocoder.yudao.framework.common.util.object.BeanUtils; |
| 9 | -import cn.iocoder.yudao.framework.flowable.core.util.FlowableUtils; | 9 | +import cn.iocoder.yudao.module.bpm.framework.flowable.core.util.FlowableUtils; |
| 10 | import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance.BpmProcessInstanceRespVO; | 10 | import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance.BpmProcessInstanceRespVO; |
| 11 | import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.task.BpmTaskRespVO; | 11 | import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.task.BpmTaskRespVO; |
| 12 | import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmFormDO; | 12 | import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmFormDO; |
yudao-module-bpm/yudao-spring-boot-starter-flowable/src/main/java/cn/iocoder/yudao/framework/flowable/core/context/FlowableContextHolder.java renamed to yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/FlowableContextHolder.java
| 1 | -package cn.iocoder.yudao.framework.flowable.core.context; | 1 | +package cn.iocoder.yudao.module.bpm.framework; |
| 2 | 2 | ||
| 3 | import cn.hutool.core.collection.CollUtil; | 3 | import cn.hutool.core.collection.CollUtil; |
| 4 | import com.alibaba.ttl.TransmittableThreadLocal; | 4 | import com.alibaba.ttl.TransmittableThreadLocal; |
| @@ -10,6 +10,7 @@ import java.util.Map; | @@ -10,6 +10,7 @@ import java.util.Map; | ||
| 10 | /** | 10 | /** |
| 11 | * 工作流--用户用到的上下文相关信息 | 11 | * 工作流--用户用到的上下文相关信息 |
| 12 | */ | 12 | */ |
| 13 | +@Deprecated // TODO 芋艿:找个方式,去掉这个上下文 | ||
| 13 | public class FlowableContextHolder { | 14 | public class FlowableContextHolder { |
| 14 | 15 | ||
| 15 | private static final ThreadLocal<Map<String, List<Long>>> ASSIGNEE = new TransmittableThreadLocal<>(); | 16 | private static final ThreadLocal<Map<String, List<Long>>> ASSIGNEE = new TransmittableThreadLocal<>(); |
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/bpm/config/BpmCommonConfiguration.java deleted
| 1 | -package cn.iocoder.yudao.module.bpm.framework.bpm.config; | ||
| 2 | - | ||
| 3 | -import cn.iocoder.yudao.module.bpm.framework.bpm.core.event.BpmProcessInstanceResultEventPublisher; | ||
| 4 | -import org.springframework.context.ApplicationEventPublisher; | ||
| 5 | -import org.springframework.context.annotation.Bean; | ||
| 6 | -import org.springframework.context.annotation.Configuration; | ||
| 7 | - | ||
| 8 | -/** | ||
| 9 | - * BPM 通用的 Configuration 配置类,提供给 Activiti 和 Flowable | ||
| 10 | - */ | ||
| 11 | -@Configuration(proxyBeanMethods = false) | ||
| 12 | -public class BpmCommonConfiguration { | ||
| 13 | - | ||
| 14 | - @Bean | ||
| 15 | - public BpmProcessInstanceResultEventPublisher processInstanceResultEventPublisher(ApplicationEventPublisher publisher) { | ||
| 16 | - return new BpmProcessInstanceResultEventPublisher(publisher); | ||
| 17 | - } | ||
| 18 | - | ||
| 19 | -} |
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/bpm/core/event/package-info.java deleted
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/bpm/core/package-info.java deleted
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/bpm/package-info.java deleted
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/config/BpmFlowableConfiguration.java
| @@ -4,13 +4,18 @@ import cn.hutool.core.collection.ListUtil; | @@ -4,13 +4,18 @@ 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.candidate.BpmTaskCandidateInvoker; | 5 | import cn.iocoder.yudao.module.bpm.framework.flowable.core.candidate.BpmTaskCandidateInvoker; |
| 6 | import cn.iocoder.yudao.module.bpm.framework.flowable.core.candidate.BpmTaskCandidateStrategy; | 6 | import cn.iocoder.yudao.module.bpm.framework.flowable.core.candidate.BpmTaskCandidateStrategy; |
| 7 | +import cn.iocoder.yudao.module.bpm.framework.flowable.core.event.BpmProcessInstanceResultEventPublisher; | ||
| 7 | import cn.iocoder.yudao.module.system.api.user.AdminUserApi; | 8 | import cn.iocoder.yudao.module.system.api.user.AdminUserApi; |
| 8 | import org.flowable.common.engine.api.delegate.event.FlowableEventListener; | 9 | import org.flowable.common.engine.api.delegate.event.FlowableEventListener; |
| 9 | import org.flowable.spring.SpringProcessEngineConfiguration; | 10 | import org.flowable.spring.SpringProcessEngineConfiguration; |
| 10 | import org.flowable.spring.boot.EngineConfigurationConfigurer; | 11 | import org.flowable.spring.boot.EngineConfigurationConfigurer; |
| 11 | import org.springframework.beans.factory.ObjectProvider; | 12 | import org.springframework.beans.factory.ObjectProvider; |
| 13 | +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; | ||
| 14 | +import org.springframework.context.ApplicationEventPublisher; | ||
| 12 | import org.springframework.context.annotation.Bean; | 15 | import org.springframework.context.annotation.Bean; |
| 13 | import org.springframework.context.annotation.Configuration; | 16 | import org.springframework.context.annotation.Configuration; |
| 17 | +import org.springframework.core.task.AsyncListenableTaskExecutor; | ||
| 18 | +import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; | ||
| 14 | 19 | ||
| 15 | import java.util.List; | 20 | import java.util.List; |
| 16 | 21 | ||
| @@ -23,6 +28,26 @@ import java.util.List; | @@ -23,6 +28,26 @@ import java.util.List; | ||
| 23 | public class BpmFlowableConfiguration { | 28 | public class BpmFlowableConfiguration { |
| 24 | 29 | ||
| 25 | /** | 30 | /** |
| 31 | + * 参考 {@link org.flowable.spring.boot.FlowableJobConfiguration} 类,创建对应的 AsyncListenableTaskExecutor Bean | ||
| 32 | + * | ||
| 33 | + * 如果不创建,会导致项目启动时,Flowable 报错的问题 | ||
| 34 | + */ | ||
| 35 | + @Bean(name = "applicationTaskExecutor") | ||
| 36 | + @ConditionalOnMissingBean(name = "applicationTaskExecutor") | ||
| 37 | + public AsyncListenableTaskExecutor taskExecutor() { | ||
| 38 | + ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor(); | ||
| 39 | + executor.setCorePoolSize(8); | ||
| 40 | + executor.setMaxPoolSize(8); | ||
| 41 | + executor.setQueueCapacity(100); | ||
| 42 | + executor.setThreadNamePrefix("flowable-task-Executor-"); | ||
| 43 | + executor.setAwaitTerminationSeconds(30); | ||
| 44 | + executor.setWaitForTasksToCompleteOnShutdown(true); | ||
| 45 | + executor.setAllowCoreThreadTimeOut(true); | ||
| 46 | + executor.initialize(); | ||
| 47 | + return executor; | ||
| 48 | + } | ||
| 49 | + | ||
| 50 | + /** | ||
| 26 | * BPM 模块的 ProcessEngineConfigurationConfigurer 实现类: | 51 | * BPM 模块的 ProcessEngineConfigurationConfigurer 实现类: |
| 27 | * | 52 | * |
| 28 | * 1. 设置各种监听器 | 53 | * 1. 设置各种监听器 |
| @@ -56,4 +81,11 @@ public class BpmFlowableConfiguration { | @@ -56,4 +81,11 @@ public class BpmFlowableConfiguration { | ||
| 56 | return new BpmTaskCandidateInvoker(strategyList, adminUserApi); | 81 | return new BpmTaskCandidateInvoker(strategyList, adminUserApi); |
| 57 | } | 82 | } |
| 58 | 83 | ||
| 84 | + // =========== 自己拓展的 Bean ========== | ||
| 85 | + | ||
| 86 | + @Bean | ||
| 87 | + public BpmProcessInstanceResultEventPublisher processInstanceResultEventPublisher(ApplicationEventPublisher publisher) { | ||
| 88 | + return new BpmProcessInstanceResultEventPublisher(publisher); | ||
| 89 | + } | ||
| 90 | + | ||
| 59 | } | 91 | } |
| 60 | \ No newline at end of file | 92 | \ No newline at end of file |
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/behavior/BpmParallelMultiInstanceBehavior.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.framework.flowable.core.util.FlowableUtils; | 3 | +import cn.iocoder.yudao.module.bpm.framework.flowable.core.util.FlowableUtils; |
| 4 | import cn.iocoder.yudao.module.bpm.framework.flowable.core.candidate.BpmTaskCandidateInvoker; | 4 | import cn.iocoder.yudao.module.bpm.framework.flowable.core.candidate.BpmTaskCandidateInvoker; |
| 5 | import lombok.Setter; | 5 | import lombok.Setter; |
| 6 | import org.flowable.bpmn.model.Activity; | 6 | import org.flowable.bpmn.model.Activity; |
| @@ -43,9 +43,9 @@ public class BpmParallelMultiInstanceBehavior extends ParallelMultiInstanceBehav | @@ -43,9 +43,9 @@ public class BpmParallelMultiInstanceBehavior extends ParallelMultiInstanceBehav | ||
| 43 | // 第一步,设置 collectionVariable 和 CollectionVariable | 43 | // 第一步,设置 collectionVariable 和 CollectionVariable |
| 44 | // 从 execution.getVariable() 读取所有任务处理人的 key | 44 | // 从 execution.getVariable() 读取所有任务处理人的 key |
| 45 | super.collectionExpression = null; // collectionExpression 和 collectionVariable 是互斥的 | 45 | super.collectionExpression = null; // collectionExpression 和 collectionVariable 是互斥的 |
| 46 | - super.collectionVariable = FlowableUtils.formatCollectionVariable(execution.getCurrentActivityId()); | 46 | + super.collectionVariable = FlowableUtils.formatExecutionCollectionVariable(execution.getCurrentActivityId()); |
| 47 | // 从 execution.getVariable() 读取当前所有任务处理的人的 key | 47 | // 从 execution.getVariable() 读取当前所有任务处理的人的 key |
| 48 | - super.collectionElementVariable = FlowableUtils.formatCollectionElementVariable(execution.getCurrentActivityId()); | 48 | + super.collectionElementVariable = FlowableUtils.formatExecutionCollectionElementVariable(execution.getCurrentActivityId()); |
| 49 | 49 | ||
| 50 | // 第二步,获取任务的所有处理人 | 50 | // 第二步,获取任务的所有处理人 |
| 51 | Set<Long> assigneeUserIds = taskCandidateInvoker.calculateUsers(execution); | 51 | Set<Long> assigneeUserIds = taskCandidateInvoker.calculateUsers(execution); |
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/behavior/BpmSequentialMultiInstanceBehavior.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.framework.flowable.core.util.FlowableUtils; | 3 | +import cn.iocoder.yudao.module.bpm.framework.flowable.core.util.FlowableUtils; |
| 4 | import cn.iocoder.yudao.module.bpm.framework.flowable.core.candidate.BpmTaskCandidateInvoker; | 4 | import cn.iocoder.yudao.module.bpm.framework.flowable.core.candidate.BpmTaskCandidateInvoker; |
| 5 | import lombok.Setter; | 5 | import lombok.Setter; |
| 6 | import org.flowable.bpmn.model.Activity; | 6 | import org.flowable.bpmn.model.Activity; |
| @@ -37,9 +37,9 @@ public class BpmSequentialMultiInstanceBehavior extends SequentialMultiInstanceB | @@ -37,9 +37,9 @@ public class BpmSequentialMultiInstanceBehavior extends SequentialMultiInstanceB | ||
| 37 | // 第一步,设置 collectionVariable 和 CollectionVariable | 37 | // 第一步,设置 collectionVariable 和 CollectionVariable |
| 38 | // 从 execution.getVariable() 读取所有任务处理人的 key | 38 | // 从 execution.getVariable() 读取所有任务处理人的 key |
| 39 | super.collectionExpression = null; // collectionExpression 和 collectionVariable 是互斥的 | 39 | super.collectionExpression = null; // collectionExpression 和 collectionVariable 是互斥的 |
| 40 | - super.collectionVariable = FlowableUtils.formatCollectionVariable(execution.getCurrentActivityId()); | 40 | + super.collectionVariable = FlowableUtils.formatExecutionCollectionVariable(execution.getCurrentActivityId()); |
| 41 | // 从 execution.getVariable() 读取当前所有任务处理的人的 key | 41 | // 从 execution.getVariable() 读取当前所有任务处理的人的 key |
| 42 | - super.collectionElementVariable = FlowableUtils.formatCollectionElementVariable(execution.getCurrentActivityId()); | 42 | + super.collectionElementVariable = FlowableUtils.formatExecutionCollectionElementVariable(execution.getCurrentActivityId()); |
| 43 | 43 | ||
| 44 | // 第二步,获取任务的所有处理人 | 44 | // 第二步,获取任务的所有处理人 |
| 45 | Set<Long> assigneeUserIds = new LinkedHashSet<>(taskCandidateInvoker.calculateUsers(execution)); // 保证有序!!! | 45 | Set<Long> assigneeUserIds = new LinkedHashSet<>(taskCandidateInvoker.calculateUsers(execution)); // 保证有序!!! |
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/candidate/BpmTaskCandidateInvoker.java
| @@ -5,7 +5,7 @@ import cn.hutool.core.lang.Assert; | @@ -5,7 +5,7 @@ import cn.hutool.core.lang.Assert; | ||
| 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.enums.CommonStatusEnum; |
| 7 | import cn.iocoder.yudao.framework.common.util.number.NumberUtils; | 7 | import cn.iocoder.yudao.framework.common.util.number.NumberUtils; |
| 8 | -import cn.iocoder.yudao.framework.flowable.core.util.BpmnModelUtils; | 8 | +import cn.iocoder.yudao.module.bpm.framework.flowable.core.util.BpmnModelUtils; |
| 9 | import cn.iocoder.yudao.module.bpm.framework.flowable.core.enums.BpmTaskCandidateStrategyEnum; | 9 | import cn.iocoder.yudao.module.bpm.framework.flowable.core.enums.BpmTaskCandidateStrategyEnum; |
| 10 | import cn.iocoder.yudao.module.bpm.framework.flowable.core.enums.BpmnModelConstants; | 10 | import cn.iocoder.yudao.module.bpm.framework.flowable.core.enums.BpmnModelConstants; |
| 11 | import cn.iocoder.yudao.module.system.api.user.AdminUserApi; | 11 | import cn.iocoder.yudao.module.system.api.user.AdminUserApi; |
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/candidate/strategy/BpmTaskCandidateExpressionStrategy.java
| 1 | package cn.iocoder.yudao.module.bpm.framework.flowable.core.candidate.strategy; | 1 | package cn.iocoder.yudao.module.bpm.framework.flowable.core.candidate.strategy; |
| 2 | 2 | ||
| 3 | -import cn.iocoder.yudao.framework.flowable.core.util.FlowableUtils; | 3 | +import cn.iocoder.yudao.module.bpm.framework.flowable.core.util.FlowableUtils; |
| 4 | import cn.iocoder.yudao.module.bpm.framework.flowable.core.candidate.BpmTaskCandidateStrategy; | 4 | import cn.iocoder.yudao.module.bpm.framework.flowable.core.candidate.BpmTaskCandidateStrategy; |
| 5 | import cn.iocoder.yudao.module.bpm.framework.flowable.core.enums.BpmTaskCandidateStrategyEnum; | 5 | import cn.iocoder.yudao.module.bpm.framework.flowable.core.enums.BpmTaskCandidateStrategyEnum; |
| 6 | import org.dromara.hutool.core.convert.Convert; | 6 | import org.dromara.hutool.core.convert.Convert; |
yudao-module-bpm/yudao-module-bpm-biz/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/flowable/core/event/BpmProcessInstanceResultEventPublisher.java
| 1 | -package cn.iocoder.yudao.module.bpm.framework.bpm.core.event; | 1 | +package cn.iocoder.yudao.module.bpm.framework.flowable.core.event; |
| 2 | 2 | ||
| 3 | import cn.iocoder.yudao.module.bpm.event.BpmProcessInstanceResultEvent; | 3 | import cn.iocoder.yudao.module.bpm.event.BpmProcessInstanceResultEvent; |
| 4 | import lombok.AllArgsConstructor; | 4 | import lombok.AllArgsConstructor; |
yudao-module-bpm/yudao-spring-boot-starter-flowable/src/main/java/cn/iocoder/yudao/framework/flowable/core/util/BpmnModelUtils.java renamed to yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/util/BpmnModelUtils.java
| 1 | -package cn.iocoder.yudao.framework.flowable.core.util; | 1 | +package cn.iocoder.yudao.module.bpm.framework.flowable.core.util; |
| 2 | 2 | ||
| 3 | import cn.hutool.core.collection.CollUtil; | 3 | import cn.hutool.core.collection.CollUtil; |
| 4 | import cn.hutool.core.util.ArrayUtil; | 4 | import cn.hutool.core.util.ArrayUtil; |
yudao-module-bpm/yudao-spring-boot-starter-flowable/src/main/java/cn/iocoder/yudao/framework/flowable/core/util/FlowableUtils.java renamed to yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/util/FlowableUtils.java
| 1 | -package cn.iocoder.yudao.framework.flowable.core.util; | 1 | +package cn.iocoder.yudao.module.bpm.framework.flowable.core.util; |
| 2 | 2 | ||
| 3 | +import cn.iocoder.yudao.module.bpm.framework.flowable.core.enums.BpmConstants; | ||
| 3 | import org.flowable.common.engine.api.delegate.Expression; | 4 | import org.flowable.common.engine.api.delegate.Expression; |
| 4 | import org.flowable.common.engine.api.variable.VariableContainer; | 5 | import org.flowable.common.engine.api.variable.VariableContainer; |
| 5 | import org.flowable.common.engine.impl.el.ExpressionManager; | 6 | import org.flowable.common.engine.impl.el.ExpressionManager; |
| @@ -32,11 +33,23 @@ public class FlowableUtils { | @@ -32,11 +33,23 @@ public class FlowableUtils { | ||
| 32 | 33 | ||
| 33 | // ========== Execution 相关的工具方法 ========== | 34 | // ========== Execution 相关的工具方法 ========== |
| 34 | 35 | ||
| 35 | - public static String formatCollectionVariable(String activityId) { | 36 | + /** |
| 37 | + * 格式化多实例(并签、或签)的 collectionVariable 变量(多实例对应的多审批人列表) | ||
| 38 | + * | ||
| 39 | + * @param activityId 活动编号 | ||
| 40 | + * @return collectionVariable 变量 | ||
| 41 | + */ | ||
| 42 | + public static String formatExecutionCollectionVariable(String activityId) { | ||
| 36 | return activityId + "_assignees"; | 43 | return activityId + "_assignees"; |
| 37 | } | 44 | } |
| 38 | 45 | ||
| 39 | - public static String formatCollectionElementVariable(String activityId) { | 46 | + /** |
| 47 | + * 格式化多实例(并签、或签)的 collectionElementVariable 变量(当前实例对应的一个审批人) | ||
| 48 | + * | ||
| 49 | + * @param activityId 活动编号 | ||
| 50 | + * @return collectionElementVariable 变量 | ||
| 51 | + */ | ||
| 52 | + public static String formatExecutionCollectionElementVariable(String activityId) { | ||
| 40 | return activityId + "_assignee"; | 53 | return activityId + "_assignee"; |
| 41 | } | 54 | } |
| 42 | 55 | ||
| @@ -50,43 +63,86 @@ public class FlowableUtils { | @@ -50,43 +63,86 @@ public class FlowableUtils { | ||
| 50 | return getProcessInstanceStatus(processInstance.getProcessVariables()); | 63 | return getProcessInstanceStatus(processInstance.getProcessVariables()); |
| 51 | } | 64 | } |
| 52 | 65 | ||
| 53 | - // TODO 芋艿:需要再搞搞 | 66 | + /** |
| 67 | + * 获得流程实例的状态 | ||
| 68 | + * | ||
| 69 | + * @param processVariables 流程实例的 variables | ||
| 70 | + * @return 状态 | ||
| 71 | + */ | ||
| 54 | private static Integer getProcessInstanceStatus(Map<String, Object> processVariables) { | 72 | private static Integer getProcessInstanceStatus(Map<String, Object> processVariables) { |
| 55 | - return (Integer) processVariables.get("PROCESS_STATUS"); | 73 | + return (Integer) processVariables.get(BpmConstants.PROCESS_INSTANCE_VARIABLE_STATUS); |
| 56 | } | 74 | } |
| 57 | 75 | ||
| 76 | + /** | ||
| 77 | + * 获得流程实例的表单 | ||
| 78 | + * | ||
| 79 | + * @param processInstance 流程实例 | ||
| 80 | + * @return 表单 | ||
| 81 | + */ | ||
| 58 | public static Map<String, Object> getProcessInstanceFormVariable(ProcessInstance processInstance) { | 82 | public static Map<String, Object> getProcessInstanceFormVariable(ProcessInstance processInstance) { |
| 59 | Map<String, Object> formVariables = new HashMap<>(processInstance.getProcessVariables()); | 83 | Map<String, Object> formVariables = new HashMap<>(processInstance.getProcessVariables()); |
| 60 | filterProcessInstanceFormVariable(formVariables); | 84 | filterProcessInstanceFormVariable(formVariables); |
| 61 | return formVariables; | 85 | return formVariables; |
| 62 | } | 86 | } |
| 63 | 87 | ||
| 88 | + /** | ||
| 89 | + * 过滤流程实例的表单 | ||
| 90 | + * | ||
| 91 | + * 为什么要过滤?目前使用 processVariables 存储所有流程实例的拓展字段,需要过滤掉一部分的系统字段,从而实现表单的展示 | ||
| 92 | + * | ||
| 93 | + * @param processVariables 流程实例的 variables | ||
| 94 | + * @return 过滤后的表单 | ||
| 95 | + */ | ||
| 64 | public static Map<String, Object> filterProcessInstanceFormVariable(Map<String, Object> processVariables) { | 96 | public static Map<String, Object> filterProcessInstanceFormVariable(Map<String, Object> processVariables) { |
| 65 | - processVariables.remove("PROCESS_STATUS"); | 97 | + processVariables.remove(BpmConstants.PROCESS_INSTANCE_VARIABLE_STATUS); |
| 66 | return processVariables; | 98 | return processVariables; |
| 67 | } | 99 | } |
| 68 | 100 | ||
| 69 | // ========== Task 相关的工具方法 ========== | 101 | // ========== Task 相关的工具方法 ========== |
| 70 | 102 | ||
| 71 | - // TODO 芋艿:需要再搞搞 | ||
| 72 | - | 103 | + /** |
| 104 | + * 获得任务的状态 | ||
| 105 | + * | ||
| 106 | + * @param task 任务 | ||
| 107 | + * @return 状态 | ||
| 108 | + */ | ||
| 73 | public static Integer getTaskStatus(TaskInfo task) { | 109 | public static Integer getTaskStatus(TaskInfo task) { |
| 74 | - return (Integer) task.getTaskLocalVariables().get("TASK_STATUS"); | 110 | + return (Integer) task.getTaskLocalVariables().get(BpmConstants.TASK_VARIABLE_STATUS); |
| 75 | } | 111 | } |
| 76 | 112 | ||
| 113 | + /** | ||
| 114 | + * 获得任务的审批原因 | ||
| 115 | + * | ||
| 116 | + * @param task 任务 | ||
| 117 | + * @return 审批原因 | ||
| 118 | + */ | ||
| 77 | public static String getTaskReason(TaskInfo task) { | 119 | public static String getTaskReason(TaskInfo task) { |
| 78 | - return (String) task.getTaskLocalVariables().get("TASK_REASON"); | 120 | + return (String) task.getTaskLocalVariables().get(BpmConstants.TASK_VARIABLE_REASON); |
| 79 | } | 121 | } |
| 80 | 122 | ||
| 123 | + /** | ||
| 124 | + * 获得任务的表单 | ||
| 125 | + * | ||
| 126 | + * @param task 任务 | ||
| 127 | + * @return 表单 | ||
| 128 | + */ | ||
| 81 | public static Map<String, Object> getTaskFormVariable(TaskInfo task) { | 129 | public static Map<String, Object> getTaskFormVariable(TaskInfo task) { |
| 82 | Map<String, Object> formVariables = new HashMap<>(task.getTaskLocalVariables()); | 130 | Map<String, Object> formVariables = new HashMap<>(task.getTaskLocalVariables()); |
| 83 | filterTaskFormVariable(formVariables); | 131 | filterTaskFormVariable(formVariables); |
| 84 | return formVariables; | 132 | return formVariables; |
| 85 | } | 133 | } |
| 86 | 134 | ||
| 135 | + /** | ||
| 136 | + * 过滤任务的表单 | ||
| 137 | + * | ||
| 138 | + * 为什么要过滤?目前使用 taskLocalVariables 存储所有任务的拓展字段,需要过滤掉一部分的系统字段,从而实现表单的展示 | ||
| 139 | + * | ||
| 140 | + * @param taskLocalVariables 任务的 taskLocalVariables | ||
| 141 | + * @return 过滤后的表单 | ||
| 142 | + */ | ||
| 87 | public static Map<String, Object> filterTaskFormVariable(Map<String, Object> taskLocalVariables) { | 143 | public static Map<String, Object> filterTaskFormVariable(Map<String, Object> taskLocalVariables) { |
| 88 | - taskLocalVariables.remove("TASK_STATUS"); | ||
| 89 | - taskLocalVariables.remove("TASK_REASON"); | 144 | + taskLocalVariables.remove(BpmConstants.TASK_VARIABLE_STATUS); |
| 145 | + taskLocalVariables.remove(BpmConstants.TASK_VARIABLE_REASON); | ||
| 90 | return taskLocalVariables; | 146 | return taskLocalVariables; |
| 91 | } | 147 | } |
| 92 | 148 |
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/web/config/BpmWebConfiguration.java
| 1 | package cn.iocoder.yudao.module.bpm.framework.web.config; | 1 | package cn.iocoder.yudao.module.bpm.framework.web.config; |
| 2 | 2 | ||
| 3 | +import cn.iocoder.yudao.framework.common.enums.WebFilterOrderEnum; | ||
| 3 | import cn.iocoder.yudao.framework.swagger.config.YudaoSwaggerAutoConfiguration; | 4 | import cn.iocoder.yudao.framework.swagger.config.YudaoSwaggerAutoConfiguration; |
| 5 | +import cn.iocoder.yudao.module.bpm.framework.web.core.FlowableWebFilter; | ||
| 4 | import org.springdoc.core.models.GroupedOpenApi; | 6 | import org.springdoc.core.models.GroupedOpenApi; |
| 7 | +import org.springframework.boot.web.servlet.FilterRegistrationBean; | ||
| 5 | import org.springframework.context.annotation.Bean; | 8 | import org.springframework.context.annotation.Bean; |
| 6 | import org.springframework.context.annotation.Configuration; | 9 | import org.springframework.context.annotation.Configuration; |
| 7 | 10 | ||
| @@ -21,4 +24,15 @@ public class BpmWebConfiguration { | @@ -21,4 +24,15 @@ public class BpmWebConfiguration { | ||
| 21 | return YudaoSwaggerAutoConfiguration.buildGroupedOpenApi("bpm"); | 24 | return YudaoSwaggerAutoConfiguration.buildGroupedOpenApi("bpm"); |
| 22 | } | 25 | } |
| 23 | 26 | ||
| 27 | + /** | ||
| 28 | + * 配置 Flowable Web 过滤器 | ||
| 29 | + */ | ||
| 30 | + @Bean | ||
| 31 | + public FilterRegistrationBean<FlowableWebFilter> flowableWebFilter() { | ||
| 32 | + FilterRegistrationBean<FlowableWebFilter> registrationBean = new FilterRegistrationBean<>(); | ||
| 33 | + registrationBean.setFilter(new FlowableWebFilter()); | ||
| 34 | + registrationBean.setOrder(WebFilterOrderEnum.FLOWABLE_FILTER); | ||
| 35 | + return registrationBean; | ||
| 36 | + } | ||
| 37 | + | ||
| 24 | } | 38 | } |
yudao-module-bpm/yudao-spring-boot-starter-flowable/src/main/java/cn/iocoder/yudao/framework/flowable/core/web/FlowableWebFilter.java renamed to yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/web/core/FlowableWebFilter.java
| 1 | -package cn.iocoder.yudao.framework.flowable.core.web; | 1 | +package cn.iocoder.yudao.module.bpm.framework.web.core; |
| 2 | 2 | ||
| 3 | -import cn.iocoder.yudao.framework.flowable.core.util.FlowableUtils; | ||
| 4 | import cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils; | 3 | import cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils; |
| 5 | -import org.springframework.web.filter.OncePerRequestFilter; | ||
| 6 | - | 4 | +import cn.iocoder.yudao.module.bpm.framework.flowable.core.util.FlowableUtils; |
| 7 | import jakarta.servlet.FilterChain; | 5 | import jakarta.servlet.FilterChain; |
| 8 | import jakarta.servlet.ServletException; | 6 | import jakarta.servlet.ServletException; |
| 9 | import jakarta.servlet.http.HttpServletRequest; | 7 | import jakarta.servlet.http.HttpServletRequest; |
| 10 | import jakarta.servlet.http.HttpServletResponse; | 8 | import jakarta.servlet.http.HttpServletResponse; |
| 9 | +import org.springframework.web.filter.OncePerRequestFilter; | ||
| 10 | + | ||
| 11 | import java.io.IOException; | 11 | import java.io.IOException; |
| 12 | + | ||
| 12 | /** | 13 | /** |
| 13 | - * flowable Web 过滤器,将 userId 设置到 {@link org.flowable.common.engine.impl.identity.Authentication} 中 | 14 | + * Flowable Web 过滤器,将 userId 设置到 {@link org.flowable.common.engine.impl.identity.Authentication} 中 |
| 14 | * | 15 | * |
| 15 | * @author jason | 16 | * @author jason |
| 16 | */ | 17 | */ |
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmProcessInstanceServiceImpl.java
| 1 | -package cn.iocoder.yudao.module.bpm.service.task; import cn.hutool.core.collection.CollUtil; import cn.hutool.core.lang.Assert; import cn.hutool.core.util.ArrayUtil; import cn.hutool.core.util.StrUtil; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.common.util.date.DateUtils; import cn.iocoder.yudao.framework.common.util.number.NumberUtils; import cn.iocoder.yudao.framework.common.util.object.PageUtils; import cn.iocoder.yudao.framework.flowable.core.context.FlowableContextHolder; import cn.iocoder.yudao.framework.flowable.core.util.FlowableUtils; import cn.iocoder.yudao.module.bpm.api.task.dto.BpmProcessInstanceCreateReqDTO; import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance.BpmProcessInstanceCancelReqVO; import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance.BpmProcessInstanceCreateReqVO; import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance.BpmProcessInstanceMyPageReqVO; import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance.BpmProcessInstanceRespVO; import cn.iocoder.yudao.module.bpm.convert.task.BpmProcessInstanceConvert; import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmProcessDefinitionInfoDO; import cn.iocoder.yudao.module.bpm.enums.task.BpmDeleteReasonEnum; 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.framework.flowable.core.enums.BpmConstants; 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 jakarta.annotation.Resource; import jakarta.validation.Valid; 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.history.HistoricProcessInstanceQuery; import org.flowable.engine.repository.ProcessDefinition; import org.flowable.engine.runtime.ProcessInstance; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import org.springframework.validation.annotation.Validated; import java.util.*; import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; 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 HistoryService historyService; @Resource private BpmProcessDefinitionService processDefinitionService; @Resource private BpmMessageService messageService; @Resource private BpmProcessInstanceResultEventPublisher processInstanceResultEventPublisher; @Resource private AdminUserApi adminUserApi; @Resource private DeptApi deptApi; @Override public ProcessInstance getProcessInstance(String id) { return runtimeService.createProcessInstanceQuery() .includeProcessVariables() .processInstanceId(id) .singleResult(); } @Override public List<ProcessInstance> getProcessInstances(Set<String> ids) { return runtimeService.createProcessInstanceQuery().processInstanceIds(ids).list(); } @Override public HistoricProcessInstance getHistoricProcessInstance(String id) { return historyService.createHistoricProcessInstanceQuery().processInstanceId(id).includeProcessVariables().singleResult(); } @Override public List<HistoricProcessInstance> getHistoricProcessInstances(Set<String> ids) { return historyService.createHistoricProcessInstanceQuery().processInstanceIds(ids).list(); } @Override public PageResult<HistoricProcessInstance> getMyProcessInstancePage(Long userId, BpmProcessInstanceMyPageReqVO pageReqVO) { // 通过 BpmProcessInstanceExtDO 表,先查询到对应的分页 HistoricProcessInstanceQuery processInstanceQuery = historyService.createHistoricProcessInstanceQuery().includeProcessVariables() .startedBy(String.valueOf(userId)) .orderByProcessInstanceStartTime().desc(); if (StrUtil.isNotEmpty(pageReqVO.getName())) { processInstanceQuery.processInstanceNameLike("%" + pageReqVO.getName() + "%"); } if (StrUtil.isNotEmpty(pageReqVO.getProcessDefinitionId())) { processInstanceQuery.processDefinitionId("%" + pageReqVO.getProcessDefinitionId() + "%"); } if (StrUtil.isNotEmpty(pageReqVO.getCategory())) { processInstanceQuery.processDefinitionCategory(pageReqVO.getCategory()); } if (pageReqVO.getStatus() != null) { processInstanceQuery.variableValueEquals(BpmConstants.PROCESS_INSTANCE_VARIABLE_STATUS, pageReqVO.getStatus()); } if (ArrayUtil.isNotEmpty(pageReqVO.getCreateTime())) { processInstanceQuery.startedAfter(DateUtils.of(pageReqVO.getCreateTime()[0])); processInstanceQuery.startedBefore(DateUtils.of(pageReqVO.getCreateTime()[1])); } // 查询数量 long processInstanceCount = processInstanceQuery.count(); if (processInstanceCount == 0) { return PageResult.empty(processInstanceCount); } // 查询列表 List<HistoricProcessInstance> processInstanceList = processInstanceQuery.listPage(PageUtils.getStart(pageReqVO), pageReqVO.getPageSize()); return new PageResult<>(processInstanceList, processInstanceCount); } @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, createReqVO.getAssignee()); } @Override public String createProcessInstance(Long userId, @Valid BpmProcessInstanceCreateReqDTO createReqDTO) { // 获得流程定义 ProcessDefinition definition = processDefinitionService.getActiveProcessDefinition(createReqDTO.getProcessDefinitionKey()); // 发起流程 return createProcessInstance0(userId, definition, createReqDTO.getVariables(), createReqDTO.getBusinessKey(), createReqDTO.getAssignee()); } private String createProcessInstance0(Long userId, ProcessDefinition definition, Map<String, Object> variables, String businessKey, Map<String, List<Long>> assignee) { // 校验流程定义 if (definition == null) { throw exception(PROCESS_DEFINITION_NOT_EXISTS); } if (definition.isSuspended()) { throw exception(PROCESS_DEFINITION_IS_SUSPENDED); } // 设置上下文信息 // TODO @hai:要不往 variables 存到一个全局固定 key 里,减少对上下文的依赖 FlowableContextHolder.setAssignee(assignee); // 创建流程实例 FlowableUtils.filterProcessInstanceFormVariable(variables); // 过滤一下,避免 ProcessInstance 系统级的变量被占用 variables.put(BpmConstants.PROCESS_INSTANCE_VARIABLE_STATUS, // 流程实例状态:审批中 BpmProcessInstanceStatusEnum.RUNNING.getStatus()); ProcessInstance instance = runtimeService.createProcessInstanceBuilder() .processDefinitionId(definition.getId()) .businessKey(businessKey) .name(definition.getName().trim()) .variables(variables) .start(); return instance.getId(); } @Override public BpmProcessInstanceRespVO getProcessInstanceVO(String id) { // 获得流程实例 HistoricProcessInstance processInstance = getHistoricProcessInstance(id); if (processInstance == null) { return null; } // 获得流程定义 ProcessDefinition processDefinition = processDefinitionService .getProcessDefinition(processInstance.getProcessDefinitionId()); Assert.notNull(processDefinition, "流程定义({}) 不存在", processInstance.getProcessDefinitionId()); BpmProcessDefinitionInfoDO processDefinitionExt = processDefinitionService.getProcessDefinitionInfo( 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, processDefinition, processDefinitionExt, bpmnXml, startUser, dept); } @Override public void cancelProcessInstance(Long userId, @Valid BpmProcessInstanceCancelReqVO cancelReqVO) { // 1.1 校验流程实例存在 ProcessInstance instance = getProcessInstance(cancelReqVO.getId()); if (instance == null) { throw exception(PROCESS_INSTANCE_CANCEL_FAIL_NOT_EXISTS); } // 1.2 只能取消自己的 if (!Objects.equals(instance.getStartUserId(), String.valueOf(userId))) { throw exception(PROCESS_INSTANCE_CANCEL_FAIL_NOT_SELF); } // 2. 通过删除流程实例,实现流程实例的取消, // 删除流程实例,正则执行任务 ACT_RU_TASK. 任务会被删除。通过历史表查询 deleteProcessInstance(cancelReqVO.getId(), BpmDeleteReasonEnum.CANCEL_PROCESS_INSTANCE.format(cancelReqVO.getReason())); // 3. 进一步的处理,交给 updateProcessInstanceCancel 方法 } @Override public void updateProcessInstanceWhenCancel(FlowableCancelledEvent event) { // 1. 判断是否为 Reject 不通过。如果是,则不进行更新. // 因为,updateProcessInstanceReject 方法(审批不通过),已经进行更新了 if (BpmDeleteReasonEnum.isRejectReason((String) event.getCause())) { return; } // 2. 更新流程实例 status runtimeService.setVariable(event.getProcessInstanceId(), BpmConstants.PROCESS_INSTANCE_VARIABLE_STATUS, BpmProcessInstanceStatusEnum.CANCEL.getStatus()); // 3. 发送流程实例的状态事件 // 注意:此时如果去查询 ProcessInstance 的话,字段是不全的,所以去查询了 HistoricProcessInstance HistoricProcessInstance processInstance = getHistoricProcessInstance(event.getProcessInstanceId()); // 发送流程实例的状态事件 processInstanceResultEventPublisher.sendProcessInstanceResultEvent( BpmProcessInstanceConvert.INSTANCE.convert(this, processInstance, BpmProcessInstanceStatusEnum.CANCEL.getStatus())); } @Override public void updateProcessInstanceWhenApprove(ProcessInstance instance) { // 1. 更新流程实例 status runtimeService.setVariable(instance.getId(), BpmConstants.PROCESS_INSTANCE_VARIABLE_STATUS, BpmProcessInstanceStatusEnum.APPROVE.getStatus()); // 2. 发送流程被【通过】的消息 messageService.sendMessageWhenProcessInstanceApprove(BpmProcessInstanceConvert.INSTANCE.convert2ApprovedReq(instance)); // 3. 发送流程实例的状态事件 // 注意:此时如果去查询 ProcessInstance 的话,字段是不全的,所以去查询了 HistoricProcessInstance HistoricProcessInstance processInstance = getHistoricProcessInstance(instance.getId()); processInstanceResultEventPublisher.sendProcessInstanceResultEvent( BpmProcessInstanceConvert.INSTANCE.convert(this, processInstance, BpmProcessInstanceStatusEnum.APPROVE.getStatus())); } @Override @Transactional(rollbackFor = Exception.class) public void updateProcessInstanceReject(String id, String reason) { // 1. 更新流程实例 status runtimeService.setVariable(id, BpmConstants.PROCESS_INSTANCE_VARIABLE_STATUS, BpmProcessInstanceStatusEnum.REJECT.getStatus()); // 2. 删除流程实例,以实现驳回任务时,取消整个审批流程 ProcessInstance processInstance = getProcessInstance(id); deleteProcessInstance(id, StrUtil.format(BpmDeleteReasonEnum.REJECT_TASK.format(reason))); // 3. 发送流程被【不通过】的消息 messageService.sendMessageWhenProcessInstanceReject(BpmProcessInstanceConvert.INSTANCE.convert2RejectReq(processInstance, reason)); // 4. 发送流程实例的状态事件 processInstanceResultEventPublisher.sendProcessInstanceResultEvent( BpmProcessInstanceConvert.INSTANCE.convert(this, processInstance, BpmProcessInstanceStatusEnum.REJECT.getStatus())); } private void deleteProcessInstance(String id, String reason) { runtimeService.deleteProcessInstance(id, reason); } @Override public List<Long> getAssigneeByProcessInstanceIdAndTaskDefinitionKey(String processInstanceId, String taskDefinitionKey) { // 1. 先从上下文获取,首次提交数据库中查询不到 List<Long> result = FlowableContextHolder.getAssigneeByTaskDefinitionKey(taskDefinitionKey); if (CollUtil.isNotEmpty(result)) { return result; } // 2. 从数据库中获取 // TODO @芋艿:指定审批人,这里的存储方案有问题,后续优化下 // BpmProcessInstanceExtDO instance = processInstanceExtMapper.selectByProcessInstanceId(processInstanceId); // if (instance == null) { // throw exception(PROCESS_INSTANCE_CANCEL_FAIL_NOT_EXISTS); // } // if (CollUtil.isNotEmpty(instance.getAssignee())) { // return instance.getAssignee().get(taskDefinitionKey); // } return Collections.emptyList(); } } | ||
| 2 | \ No newline at end of file | 1 | \ No newline at end of file |
| 2 | +package cn.iocoder.yudao.module.bpm.service.task; import cn.hutool.core.collection.CollUtil; import cn.hutool.core.lang.Assert; import cn.hutool.core.util.ArrayUtil; import cn.hutool.core.util.StrUtil; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.common.util.date.DateUtils; import cn.iocoder.yudao.framework.common.util.number.NumberUtils; import cn.iocoder.yudao.framework.common.util.object.PageUtils; import cn.iocoder.yudao.module.bpm.framework.FlowableContextHolder; import cn.iocoder.yudao.module.bpm.framework.flowable.core.util.FlowableUtils; import cn.iocoder.yudao.module.bpm.api.task.dto.BpmProcessInstanceCreateReqDTO; import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance.BpmProcessInstanceCancelReqVO; import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance.BpmProcessInstanceCreateReqVO; import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance.BpmProcessInstanceMyPageReqVO; import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance.BpmProcessInstanceRespVO; import cn.iocoder.yudao.module.bpm.convert.task.BpmProcessInstanceConvert; import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmProcessDefinitionInfoDO; import cn.iocoder.yudao.module.bpm.enums.task.BpmDeleteReasonEnum; import cn.iocoder.yudao.module.bpm.enums.task.BpmProcessInstanceStatusEnum; import cn.iocoder.yudao.module.bpm.framework.flowable.core.event.BpmProcessInstanceResultEventPublisher; import cn.iocoder.yudao.module.bpm.framework.flowable.core.enums.BpmConstants; 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 jakarta.annotation.Resource; import jakarta.validation.Valid; 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.history.HistoricProcessInstanceQuery; import org.flowable.engine.repository.ProcessDefinition; import org.flowable.engine.runtime.ProcessInstance; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import org.springframework.validation.annotation.Validated; import java.util.*; import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; 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 HistoryService historyService; @Resource private BpmProcessDefinitionService processDefinitionService; @Resource private BpmMessageService messageService; @Resource private BpmProcessInstanceResultEventPublisher processInstanceResultEventPublisher; @Resource private AdminUserApi adminUserApi; @Resource private DeptApi deptApi; @Override public ProcessInstance getProcessInstance(String id) { return runtimeService.createProcessInstanceQuery() .includeProcessVariables() .processInstanceId(id) .singleResult(); } @Override public List<ProcessInstance> getProcessInstances(Set<String> ids) { return runtimeService.createProcessInstanceQuery().processInstanceIds(ids).list(); } @Override public HistoricProcessInstance getHistoricProcessInstance(String id) { return historyService.createHistoricProcessInstanceQuery().processInstanceId(id).includeProcessVariables().singleResult(); } @Override public List<HistoricProcessInstance> getHistoricProcessInstances(Set<String> ids) { return historyService.createHistoricProcessInstanceQuery().processInstanceIds(ids).list(); } @Override public PageResult<HistoricProcessInstance> getMyProcessInstancePage(Long userId, BpmProcessInstanceMyPageReqVO pageReqVO) { // 通过 BpmProcessInstanceExtDO 表,先查询到对应的分页 HistoricProcessInstanceQuery processInstanceQuery = historyService.createHistoricProcessInstanceQuery().includeProcessVariables() .startedBy(String.valueOf(userId)) .orderByProcessInstanceStartTime().desc(); if (StrUtil.isNotEmpty(pageReqVO.getName())) { processInstanceQuery.processInstanceNameLike("%" + pageReqVO.getName() + "%"); } if (StrUtil.isNotEmpty(pageReqVO.getProcessDefinitionId())) { processInstanceQuery.processDefinitionId("%" + pageReqVO.getProcessDefinitionId() + "%"); } if (StrUtil.isNotEmpty(pageReqVO.getCategory())) { processInstanceQuery.processDefinitionCategory(pageReqVO.getCategory()); } if (pageReqVO.getStatus() != null) { processInstanceQuery.variableValueEquals(BpmConstants.PROCESS_INSTANCE_VARIABLE_STATUS, pageReqVO.getStatus()); } if (ArrayUtil.isNotEmpty(pageReqVO.getCreateTime())) { processInstanceQuery.startedAfter(DateUtils.of(pageReqVO.getCreateTime()[0])); processInstanceQuery.startedBefore(DateUtils.of(pageReqVO.getCreateTime()[1])); } // 查询数量 long processInstanceCount = processInstanceQuery.count(); if (processInstanceCount == 0) { return PageResult.empty(processInstanceCount); } // 查询列表 List<HistoricProcessInstance> processInstanceList = processInstanceQuery.listPage(PageUtils.getStart(pageReqVO), pageReqVO.getPageSize()); return new PageResult<>(processInstanceList, processInstanceCount); } @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, createReqVO.getAssignee()); } @Override public String createProcessInstance(Long userId, @Valid BpmProcessInstanceCreateReqDTO createReqDTO) { // 获得流程定义 ProcessDefinition definition = processDefinitionService.getActiveProcessDefinition(createReqDTO.getProcessDefinitionKey()); // 发起流程 return createProcessInstance0(userId, definition, createReqDTO.getVariables(), createReqDTO.getBusinessKey(), createReqDTO.getAssignee()); } private String createProcessInstance0(Long userId, ProcessDefinition definition, Map<String, Object> variables, String businessKey, Map<String, List<Long>> assignee) { // 校验流程定义 if (definition == null) { throw exception(PROCESS_DEFINITION_NOT_EXISTS); } if (definition.isSuspended()) { throw exception(PROCESS_DEFINITION_IS_SUSPENDED); } // 设置上下文信息 // TODO @hai:要不往 variables 存到一个全局固定 key 里,减少对上下文的依赖 FlowableContextHolder.setAssignee(assignee); // 创建流程实例 FlowableUtils.filterProcessInstanceFormVariable(variables); // 过滤一下,避免 ProcessInstance 系统级的变量被占用 variables.put(BpmConstants.PROCESS_INSTANCE_VARIABLE_STATUS, // 流程实例状态:审批中 BpmProcessInstanceStatusEnum.RUNNING.getStatus()); ProcessInstance instance = runtimeService.createProcessInstanceBuilder() .processDefinitionId(definition.getId()) .businessKey(businessKey) .name(definition.getName().trim()) .variables(variables) .start(); return instance.getId(); } @Override public BpmProcessInstanceRespVO getProcessInstanceVO(String id) { // 获得流程实例 HistoricProcessInstance processInstance = getHistoricProcessInstance(id); if (processInstance == null) { return null; } // 获得流程定义 ProcessDefinition processDefinition = processDefinitionService .getProcessDefinition(processInstance.getProcessDefinitionId()); Assert.notNull(processDefinition, "流程定义({}) 不存在", processInstance.getProcessDefinitionId()); BpmProcessDefinitionInfoDO processDefinitionExt = processDefinitionService.getProcessDefinitionInfo( 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, processDefinition, processDefinitionExt, bpmnXml, startUser, dept); } @Override public void cancelProcessInstance(Long userId, @Valid BpmProcessInstanceCancelReqVO cancelReqVO) { // 1.1 校验流程实例存在 ProcessInstance instance = getProcessInstance(cancelReqVO.getId()); if (instance == null) { throw exception(PROCESS_INSTANCE_CANCEL_FAIL_NOT_EXISTS); } // 1.2 只能取消自己的 if (!Objects.equals(instance.getStartUserId(), String.valueOf(userId))) { throw exception(PROCESS_INSTANCE_CANCEL_FAIL_NOT_SELF); } // 2. 通过删除流程实例,实现流程实例的取消, // 删除流程实例,正则执行任务 ACT_RU_TASK. 任务会被删除。通过历史表查询 deleteProcessInstance(cancelReqVO.getId(), BpmDeleteReasonEnum.CANCEL_PROCESS_INSTANCE.format(cancelReqVO.getReason())); // 3. 进一步的处理,交给 updateProcessInstanceCancel 方法 } @Override public void updateProcessInstanceWhenCancel(FlowableCancelledEvent event) { // 1. 判断是否为 Reject 不通过。如果是,则不进行更新. // 因为,updateProcessInstanceReject 方法(审批不通过),已经进行更新了 if (BpmDeleteReasonEnum.isRejectReason((String) event.getCause())) { return; } // 2. 更新流程实例 status runtimeService.setVariable(event.getProcessInstanceId(), BpmConstants.PROCESS_INSTANCE_VARIABLE_STATUS, BpmProcessInstanceStatusEnum.CANCEL.getStatus()); // 3. 发送流程实例的状态事件 // 注意:此时如果去查询 ProcessInstance 的话,字段是不全的,所以去查询了 HistoricProcessInstance HistoricProcessInstance processInstance = getHistoricProcessInstance(event.getProcessInstanceId()); // 发送流程实例的状态事件 processInstanceResultEventPublisher.sendProcessInstanceResultEvent( BpmProcessInstanceConvert.INSTANCE.convert(this, processInstance, BpmProcessInstanceStatusEnum.CANCEL.getStatus())); } @Override public void updateProcessInstanceWhenApprove(ProcessInstance instance) { // 1. 更新流程实例 status runtimeService.setVariable(instance.getId(), BpmConstants.PROCESS_INSTANCE_VARIABLE_STATUS, BpmProcessInstanceStatusEnum.APPROVE.getStatus()); // 2. 发送流程被【通过】的消息 messageService.sendMessageWhenProcessInstanceApprove(BpmProcessInstanceConvert.INSTANCE.convert2ApprovedReq(instance)); // 3. 发送流程实例的状态事件 // 注意:此时如果去查询 ProcessInstance 的话,字段是不全的,所以去查询了 HistoricProcessInstance HistoricProcessInstance processInstance = getHistoricProcessInstance(instance.getId()); processInstanceResultEventPublisher.sendProcessInstanceResultEvent( BpmProcessInstanceConvert.INSTANCE.convert(this, processInstance, BpmProcessInstanceStatusEnum.APPROVE.getStatus())); } @Override @Transactional(rollbackFor = Exception.class) public void updateProcessInstanceReject(String id, String reason) { // 1. 更新流程实例 status runtimeService.setVariable(id, BpmConstants.PROCESS_INSTANCE_VARIABLE_STATUS, BpmProcessInstanceStatusEnum.REJECT.getStatus()); // 2. 删除流程实例,以实现驳回任务时,取消整个审批流程 ProcessInstance processInstance = getProcessInstance(id); deleteProcessInstance(id, StrUtil.format(BpmDeleteReasonEnum.REJECT_TASK.format(reason))); // 3. 发送流程被【不通过】的消息 messageService.sendMessageWhenProcessInstanceReject(BpmProcessInstanceConvert.INSTANCE.convert2RejectReq(processInstance, reason)); // 4. 发送流程实例的状态事件 processInstanceResultEventPublisher.sendProcessInstanceResultEvent( BpmProcessInstanceConvert.INSTANCE.convert(this, processInstance, BpmProcessInstanceStatusEnum.REJECT.getStatus())); } private void deleteProcessInstance(String id, String reason) { runtimeService.deleteProcessInstance(id, reason); } @Override public List<Long> getAssigneeByProcessInstanceIdAndTaskDefinitionKey(String processInstanceId, String taskDefinitionKey) { // 1. 先从上下文获取,首次提交数据库中查询不到 List<Long> result = FlowableContextHolder.getAssigneeByTaskDefinitionKey(taskDefinitionKey); if (CollUtil.isNotEmpty(result)) { return result; } // 2. 从数据库中获取 // TODO @芋艿:指定审批人,这里的存储方案有问题,后续优化下 // BpmProcessInstanceExtDO instance = processInstanceExtMapper.selectByProcessInstanceId(processInstanceId); // if (instance == null) { // throw exception(PROCESS_INSTANCE_CANCEL_FAIL_NOT_EXISTS); // } // if (CollUtil.isNotEmpty(instance.getAssignee())) { // return instance.getAssignee().get(taskDefinitionKey); // } return Collections.emptyList(); } } | ||
| 3 | \ No newline at end of file | 3 | \ No newline at end of file |
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmTaskServiceImpl.java
| @@ -9,8 +9,8 @@ import cn.iocoder.yudao.framework.common.pojo.PageResult; | @@ -9,8 +9,8 @@ import cn.iocoder.yudao.framework.common.pojo.PageResult; | ||
| 9 | import cn.iocoder.yudao.framework.common.util.date.DateUtils; | 9 | import cn.iocoder.yudao.framework.common.util.date.DateUtils; |
| 10 | import cn.iocoder.yudao.framework.common.util.number.NumberUtils; | 10 | import cn.iocoder.yudao.framework.common.util.number.NumberUtils; |
| 11 | import cn.iocoder.yudao.framework.common.util.object.PageUtils; | 11 | import cn.iocoder.yudao.framework.common.util.object.PageUtils; |
| 12 | -import cn.iocoder.yudao.framework.flowable.core.util.BpmnModelUtils; | ||
| 13 | -import cn.iocoder.yudao.framework.flowable.core.util.FlowableUtils; | 12 | +import cn.iocoder.yudao.module.bpm.framework.flowable.core.util.BpmnModelUtils; |
| 13 | +import cn.iocoder.yudao.module.bpm.framework.flowable.core.util.FlowableUtils; | ||
| 14 | import cn.iocoder.yudao.framework.web.core.util.WebFrameworkUtils; | 14 | import cn.iocoder.yudao.framework.web.core.util.WebFrameworkUtils; |
| 15 | import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.task.*; | 15 | import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.task.*; |
| 16 | import cn.iocoder.yudao.module.bpm.convert.task.BpmTaskConvert; | 16 | import cn.iocoder.yudao.module.bpm.convert.task.BpmTaskConvert; |
yudao-module-bpm/yudao-module-bpm-biz/src/test/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/candidate/strategy/BpmTaskCandidateExpressionStrategyTest.java
| 1 | package cn.iocoder.yudao.module.bpm.framework.flowable.core.candidate.strategy; | 1 | package cn.iocoder.yudao.module.bpm.framework.flowable.core.candidate.strategy; |
| 2 | 2 | ||
| 3 | -import cn.iocoder.yudao.framework.flowable.core.util.FlowableUtils; | 3 | +import cn.iocoder.yudao.module.bpm.framework.flowable.core.util.FlowableUtils; |
| 4 | import cn.iocoder.yudao.framework.test.core.ut.BaseMockitoUnitTest; | 4 | import cn.iocoder.yudao.framework.test.core.ut.BaseMockitoUnitTest; |
| 5 | import org.flowable.engine.delegate.DelegateExecution; | 5 | import org.flowable.engine.delegate.DelegateExecution; |
| 6 | import org.junit.jupiter.api.Test; | 6 | import org.junit.jupiter.api.Test; |
yudao-module-bpm/yudao-spring-boot-starter-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 | - | ||
| 12 | - <artifactId>yudao-spring-boot-starter-flowable</artifactId> | ||
| 13 | - | ||
| 14 | - <dependencies> | ||
| 15 | - <dependency> | ||
| 16 | - <groupId>cn.iocoder.boot</groupId> | ||
| 17 | - <artifactId>yudao-common</artifactId> | ||
| 18 | - </dependency> | ||
| 19 | - | ||
| 20 | - <!-- Web 相关 --> | ||
| 21 | - <dependency> | ||
| 22 | - <groupId>cn.iocoder.boot</groupId> | ||
| 23 | - <artifactId>yudao-spring-boot-starter-security</artifactId> | ||
| 24 | - </dependency> | ||
| 25 | - | ||
| 26 | - <!-- flowable 工作流相关 --> | ||
| 27 | - <dependency> | ||
| 28 | - <groupId>org.flowable</groupId> | ||
| 29 | - <artifactId>flowable-spring-boot-starter-process</artifactId> | ||
| 30 | - </dependency> | ||
| 31 | - <dependency> | ||
| 32 | - <groupId>org.flowable</groupId> | ||
| 33 | - <artifactId>flowable-spring-boot-starter-actuator</artifactId> | ||
| 34 | - </dependency> | ||
| 35 | - </dependencies> | ||
| 36 | - | ||
| 37 | -</project> |
yudao-module-bpm/yudao-spring-boot-starter-flowable/src/main/java/cn/iocoder/yudao/framework/flowable/config/YudaoFlowableConfiguration.java deleted
| 1 | -package cn.iocoder.yudao.framework.flowable.config; | ||
| 2 | - | ||
| 3 | -import cn.iocoder.yudao.framework.common.enums.WebFilterOrderEnum; | ||
| 4 | -import cn.iocoder.yudao.framework.flowable.core.web.FlowableWebFilter; | ||
| 5 | -import org.springframework.boot.autoconfigure.AutoConfiguration; | ||
| 6 | -import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; | ||
| 7 | -import org.springframework.boot.web.servlet.FilterRegistrationBean; | ||
| 8 | -import org.springframework.context.annotation.Bean; | ||
| 9 | -import org.springframework.core.task.AsyncListenableTaskExecutor; | ||
| 10 | -import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; | ||
| 11 | - | ||
| 12 | -@AutoConfiguration | ||
| 13 | -public class YudaoFlowableConfiguration { | ||
| 14 | - | ||
| 15 | - /** | ||
| 16 | - * 参考 {@link org.flowable.spring.boot.FlowableJobConfiguration} 类,创建对应的 AsyncListenableTaskExecutor Bean | ||
| 17 | - * | ||
| 18 | - * 如果不创建,会导致项目启动时,Flowable 报错的问题 | ||
| 19 | - */ | ||
| 20 | - @Bean(name = "applicationTaskExecutor") | ||
| 21 | - @ConditionalOnMissingBean(name = "applicationTaskExecutor") | ||
| 22 | - public AsyncListenableTaskExecutor taskExecutor() { | ||
| 23 | - ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor(); | ||
| 24 | - executor.setCorePoolSize(8); | ||
| 25 | - executor.setMaxPoolSize(8); | ||
| 26 | - executor.setQueueCapacity(100); | ||
| 27 | - executor.setThreadNamePrefix("flowable-task-Executor-"); | ||
| 28 | - executor.setAwaitTerminationSeconds(30); | ||
| 29 | - executor.setWaitForTasksToCompleteOnShutdown(true); | ||
| 30 | - executor.setAllowCoreThreadTimeOut(true); | ||
| 31 | - executor.initialize(); | ||
| 32 | - return executor; | ||
| 33 | - } | ||
| 34 | - | ||
| 35 | - /** | ||
| 36 | - * 配置 flowable Web 过滤器 | ||
| 37 | - */ | ||
| 38 | - @Bean | ||
| 39 | - public FilterRegistrationBean<FlowableWebFilter> flowableWebFilter() { | ||
| 40 | - FilterRegistrationBean<FlowableWebFilter> registrationBean = new FilterRegistrationBean<>(); | ||
| 41 | - registrationBean.setFilter(new FlowableWebFilter()); | ||
| 42 | - registrationBean.setOrder(WebFilterOrderEnum.FLOWABLE_FILTER); | ||
| 43 | - return registrationBean; | ||
| 44 | - } | ||
| 45 | - | ||
| 46 | -} |
yudao-module-bpm/yudao-spring-boot-starter-flowable/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports deleted