Commit 073d860a78d6d6b565060de717d600f6a27dc7df

Authored by jason
1 parent c761f525

工作流 Flowable 发起流程 相关实现

Showing 17 changed files with 246 additions and 2 deletions
yudao-dependencies/pom.xml
@@ -400,6 +400,11 @@ @@ -400,6 +400,11 @@
400 </dependency> 400 </dependency>
401 <!-- 工作流相关 flowable --> 401 <!-- 工作流相关 flowable -->
402 <dependency> 402 <dependency>
  403 + <groupId>cn.iocoder.boot</groupId>
  404 + <artifactId>yudao-spring-boot-starter-flowable</artifactId>
  405 + <version>${revision}</version>
  406 + </dependency>
  407 + <dependency>
403 <groupId>org.flowable</groupId> 408 <groupId>org.flowable</groupId>
404 <artifactId>flowable-spring-boot-starter-basic</artifactId> 409 <artifactId>flowable-spring-boot-starter-basic</artifactId>
405 <version>${flowable.version}</version> 410 <version>${flowable.version}</version>
yudao-framework/pom.xml
@@ -35,6 +35,7 @@ @@ -35,6 +35,7 @@
35 <module>yudao-spring-boot-starter-biz-social</module> 35 <module>yudao-spring-boot-starter-biz-social</module>
36 <module>yudao-spring-boot-starter-biz-tenant</module> 36 <module>yudao-spring-boot-starter-biz-tenant</module>
37 <module>yudao-spring-boot-starter-biz-data-permission</module> 37 <module>yudao-spring-boot-starter-biz-data-permission</module>
  38 + <module>yudao-spring-boot-starter-flowable</module>
38 </modules> 39 </modules>
39 40
40 <artifactId>yudao-framework</artifactId> 41 <artifactId>yudao-framework</artifactId>
yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/enums/WebFilterOrderEnum.java
@@ -29,6 +29,8 @@ public interface WebFilterOrderEnum { @@ -29,6 +29,8 @@ public interface WebFilterOrderEnum {
29 29
30 int ACTIVITI_FILTER = -98; // 需要保证在 Spring Security 过滤后面 30 int ACTIVITI_FILTER = -98; // 需要保证在 Spring Security 过滤后面
31 31
  32 + int FLOWABLE_FILTER = -98; // 需要保证在 Spring Security 过滤后面
  33 +
32 int DEMO_FILTER = Integer.MAX_VALUE; 34 int DEMO_FILTER = Integer.MAX_VALUE;
33 35
34 } 36 }
yudao-framework/yudao-spring-boot-starter-flowable/pom.xml 0 → 100644
  1 +<?xml version="1.0" encoding="UTF-8"?>
  2 +<project xmlns="http://maven.apache.org/POM/4.0.0"
  3 + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4 + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  5 + <parent>
  6 + <artifactId>yudao-framework</artifactId>
  7 + <groupId>cn.iocoder.boot</groupId>
  8 + <version>${revision}</version>
  9 + </parent>
  10 + <modelVersion>4.0.0</modelVersion>
  11 +
  12 + <artifactId>yudao-spring-boot-starter-flowable</artifactId>
  13 +
  14 + <dependencies>
  15 + <dependency>
  16 + <groupId>cn.iocoder.boot</groupId>
  17 + <artifactId>yudao-common</artifactId>
  18 + </dependency>
  19 + <!-- Web 相关 -->
  20 + <dependency>
  21 + <groupId>cn.iocoder.boot</groupId>
  22 + <artifactId>yudao-spring-boot-starter-security</artifactId>
  23 + </dependency>
  24 + <!-- flowable 工作流相关 -->
  25 + <dependency>
  26 + <groupId>org.flowable</groupId>
  27 + <artifactId>flowable-spring-boot-starter-basic</artifactId>
  28 + </dependency>
  29 + </dependencies>
  30 +
  31 +</project>
0 \ No newline at end of file 32 \ No newline at end of file
yudao-framework/yudao-spring-boot-starter-flowable/src/main/java/cn/iocoder/yudao/framework/flowable/config/YudaoFlowableConfiguration.java 0 → 100644
  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.web.servlet.FilterRegistrationBean;
  6 +import org.springframework.context.annotation.Bean;
  7 +import org.springframework.context.annotation.Configuration;
  8 +
  9 +@Configuration
  10 +public class YudaoFlowableConfiguration {
  11 +
  12 + /**
  13 + * 配置 flowable Web 过滤器
  14 + */
  15 + @Bean
  16 + public FilterRegistrationBean<FlowableWebFilter> flowableWebFilter() {
  17 + FilterRegistrationBean<FlowableWebFilter> registrationBean = new FilterRegistrationBean<>();
  18 + registrationBean.setFilter(new FlowableWebFilter());
  19 + registrationBean.setOrder(WebFilterOrderEnum.FLOWABLE_FILTER);
  20 + return registrationBean;
  21 + }
  22 +}
yudao-framework/yudao-spring-boot-starter-flowable/src/main/java/cn/iocoder/yudao/framework/flowable/core/package-info.java 0 → 100644
  1 +package cn.iocoder.yudao.framework.flowable.core;
yudao-framework/yudao-spring-boot-starter-flowable/src/main/java/cn/iocoder/yudao/framework/flowable/core/util/FlowableUtils.java 0 → 100644
  1 +package cn.iocoder.yudao.framework.flowable.core.util;
  2 +
  3 +import org.flowable.common.engine.impl.identity.Authentication;
  4 +
  5 +public class FlowableUtils {
  6 +
  7 + public static void setAuthenticatedUserId(Long userId) {
  8 + Authentication.setAuthenticatedUserId(String.valueOf(userId));
  9 + }
  10 +
  11 + public static void clearAuthenticatedUserId() {
  12 + Authentication.setAuthenticatedUserId(null);
  13 + }
  14 +}
yudao-framework/yudao-spring-boot-starter-flowable/src/main/java/cn/iocoder/yudao/framework/flowable/core/web/FlowableWebFilter.java 0 → 100644
  1 +package cn.iocoder.yudao.framework.flowable.core.web;
  2 +
  3 +import cn.iocoder.yudao.framework.flowable.core.util.FlowableUtils;
  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 + * flowable Web 过滤器,将 userId 设置到 {@link org.flowable.common.engine.impl.identity.Authentication} 中
  14 + *
  15 + * @author jason
  16 + */
  17 +public class FlowableWebFilter extends OncePerRequestFilter {
  18 +
  19 + @Override
  20 + protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain)
  21 + throws ServletException, IOException {
  22 + try {
  23 + // 设置工作流的用户
  24 + Long userId = SecurityFrameworkUtils.getLoginUserId();
  25 + if (userId != null) {
  26 + FlowableUtils.setAuthenticatedUserId(userId);
  27 + }
  28 + // 过滤
  29 + chain.doFilter(request, response);
  30 + } finally {
  31 + // 清理
  32 + FlowableUtils.clearAuthenticatedUserId();
  33 + }
  34 + }
  35 +}
yudao-framework/yudao-spring-boot-starter-flowable/src/main/java/cn/iocoder/yudao/framework/flowable/package-info.java 0 → 100644
  1 +package cn.iocoder.yudao.framework.flowable;
yudao-framework/yudao-spring-boot-starter-flowable/src/main/resources/META-INF/spring.factories 0 → 100644
  1 +org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
  2 + cn.iocoder.yudao.framework.flowable.config.YudaoFlowableConfiguration
yudao-module-bpm/yudao-module-bpm-impl-flowable/pom.xml
@@ -23,8 +23,8 @@ @@ -23,8 +23,8 @@
23 </dependency> 23 </dependency>
24 <!-- 工作流相关 --> 24 <!-- 工作流相关 -->
25 <dependency> 25 <dependency>
26 - <groupId>org.flowable</groupId>  
27 - <artifactId>flowable-spring-boot-starter-basic</artifactId> 26 + <groupId>cn.iocoder.boot</groupId>
  27 + <artifactId>yudao-spring-boot-starter-flowable</artifactId>
28 </dependency> 28 </dependency>
29 <dependency> 29 <dependency>
30 <groupId>org.flowable</groupId> 30 <groupId>org.flowable</groupId>
yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/config/BpmFlowableConfiguration.java 0 → 100644
  1 +package cn.iocoder.yudao.module.bpm.framework.flowable.config;
  2 +
  3 +import cn.iocoder.yudao.module.bpm.framework.flowable.core.listener.BpmProcessInstanceEventListener;
  4 +import org.flowable.common.engine.api.delegate.event.FlowableEventListener;
  5 +import org.flowable.engine.runtime.ProcessInstance;
  6 +import org.flowable.spring.SpringProcessEngineConfiguration;
  7 +import org.flowable.spring.boot.EngineConfigurationConfigurer;
  8 +import org.springframework.context.annotation.Bean;
  9 +import org.springframework.context.annotation.Configuration;
  10 +
  11 +import java.util.ArrayList;
  12 +import java.util.List;
  13 +/**
  14 + * BPM 模块的 Flowable 配置类
  15 + *
  16 + * @author jason
  17 + */
  18 +@Configuration
  19 +public class BpmFlowableConfiguration {
  20 +
  21 + /**
  22 + *将自定义 listener 加入全局listener
  23 + * @param processInstanceListener 自定义监听 {@link ProcessInstance}
  24 + */
  25 + @Bean
  26 + public EngineConfigurationConfigurer<SpringProcessEngineConfiguration> addCustomerListenerConfigurer (BpmProcessInstanceEventListener processInstanceListener) {
  27 + return engineConfiguration -> {
  28 + List<FlowableEventListener> eventListeners = new ArrayList<>();
  29 + eventListeners.add(processInstanceListener);
  30 + engineConfiguration.setEventListeners(eventListeners);
  31 + };
  32 + }
  33 +}
yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/listener/BpmProcessInstanceEventListener.java 0 → 100644
  1 +package cn.iocoder.yudao.module.bpm.framework.flowable.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 com.google.common.collect.ImmutableSet;
  6 +import org.flowable.common.engine.api.delegate.event.FlowableEngineEntityEvent;
  7 +import org.flowable.common.engine.api.delegate.event.FlowableEngineEventType;
  8 +import org.flowable.engine.delegate.event.AbstractFlowableEngineEventListener;
  9 +import org.flowable.engine.delegate.event.FlowableCancelledEvent;
  10 +import org.flowable.engine.delegate.event.FlowableProcessStartedEvent;
  11 +import org.flowable.engine.runtime.ProcessInstance;
  12 +import org.springframework.context.annotation.Lazy;
  13 +import org.springframework.stereotype.Component;
  14 +
  15 +import javax.annotation.Resource;
  16 +import java.util.Set;
  17 +/**
  18 + * 监听 {@link ProcessInstance} 的开始与完成,创建与更新对应的 {@link BpmProcessInstanceExtDO} 记录
  19 + *
  20 + * @author jason
  21 + */
  22 +@Component
  23 +public class BpmProcessInstanceEventListener extends AbstractFlowableEngineEventListener {
  24 +
  25 + @Resource
  26 + @Lazy
  27 + private BpmProcessInstanceService processInstanceService;
  28 +
  29 + public static final Set<FlowableEngineEventType> PROCESS_INSTANCE_EVENTS = ImmutableSet.<FlowableEngineEventType>builder()
  30 + .add(FlowableEngineEventType.PROCESS_CREATED)
  31 + .add(FlowableEngineEventType.PROCESS_STARTED)
  32 + .add(FlowableEngineEventType.PROCESS_CANCELLED)
  33 + .build();
  34 +
  35 + public BpmProcessInstanceEventListener(){
  36 + super(PROCESS_INSTANCE_EVENTS);
  37 + }
  38 +
  39 + @Override
  40 + protected void processCreated(FlowableEngineEntityEvent event) {
  41 + processInstanceService.createProcessInstanceExt((ProcessInstance)event.getEntity());
  42 + }
  43 +
  44 + @Override
  45 + protected void processStarted(FlowableProcessStartedEvent event) {
  46 + super.processStarted(event);
  47 + }
  48 +
  49 +
  50 + @Override
  51 + protected void processCancelled(FlowableCancelledEvent event) {
  52 + super.processCancelled(event);
  53 + }
  54 +}
yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmProcessDefinitionService.java
@@ -90,6 +90,16 @@ public interface BpmProcessDefinitionService { @@ -90,6 +90,16 @@ public interface BpmProcessDefinitionService {
90 ProcessDefinition getProcessDefinition(String id); 90 ProcessDefinition getProcessDefinition(String id);
91 91
92 /** 92 /**
  93 + * 获得编号对应的 ProcessDefinition
  94 + *
  95 + * 相比 {@link #getProcessDefinition(String)} 方法,category 的取值是正确
  96 + *
  97 + * @param id 编号
  98 + * @return 流程定义
  99 + */
  100 + ProcessDefinition getProcessDefinition2(String id);
  101 +
  102 + /**
93 * 获得 deploymentId 对应的 ProcessDefinition 103 * 获得 deploymentId 对应的 ProcessDefinition
94 * 104 *
95 * @param deploymentId 部署编号 105 * @param deploymentId 部署编号
yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmProcessDefinitionServiceImpl.java
@@ -67,6 +67,11 @@ public class BpmProcessDefinitionServiceImpl implements BpmProcessDefinitionServ @@ -67,6 +67,11 @@ public class BpmProcessDefinitionServiceImpl implements BpmProcessDefinitionServ
67 } 67 }
68 68
69 @Override 69 @Override
  70 + public ProcessDefinition getProcessDefinition2(String id) {
  71 + return repositoryService.createProcessDefinitionQuery().processDefinitionId(id).singleResult();
  72 + }
  73 +
  74 + @Override
70 public ProcessDefinition getProcessDefinitionByDeploymentId(String deploymentId) { 75 public ProcessDefinition getProcessDefinitionByDeploymentId(String deploymentId) {
71 if (StrUtil.isEmpty(deploymentId)) { 76 if (StrUtil.isEmpty(deploymentId)) {
72 return null; 77 return null;
yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmProcessInstanceService.java
@@ -6,6 +6,7 @@ import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance.BpmProcessI @@ -6,6 +6,7 @@ import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance.BpmProcessI
6 import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance.BpmProcessInstanceMyPageReqVO; 6 import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance.BpmProcessInstanceMyPageReqVO;
7 import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance.BpmProcessInstancePageItemRespVO; 7 import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance.BpmProcessInstancePageItemRespVO;
8 import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance.BpmProcessInstanceRespVO; 8 import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance.BpmProcessInstanceRespVO;
  9 +import org.flowable.common.engine.api.delegate.event.FlowableEngineEntityEvent;
9 import org.flowable.engine.history.HistoricProcessInstance; 10 import org.flowable.engine.history.HistoricProcessInstance;
10 import org.flowable.engine.runtime.ProcessInstance; 11 import org.flowable.engine.runtime.ProcessInstance;
11 12
@@ -73,4 +74,11 @@ public interface BpmProcessInstanceService { @@ -73,4 +74,11 @@ public interface BpmProcessInstanceService {
73 * @return 历史的流程实例 74 * @return 历史的流程实例
74 */ 75 */
75 HistoricProcessInstance getHistoricProcessInstance(String id); 76 HistoricProcessInstance getHistoricProcessInstance(String id);
  77 +
  78 + /**
  79 + * 创建 ProcessInstance 拓展记录
  80 + *
  81 + * @param instance 流程任务
  82 + */
  83 + void createProcessInstanceExt(ProcessInstance instance);
76 } 84 }
yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmProcessInstanceServiceImpl.java
@@ -12,6 +12,8 @@ import cn.iocoder.yudao.module.bpm.convert.task.BpmProcessInstanceConvert; @@ -12,6 +12,8 @@ import cn.iocoder.yudao.module.bpm.convert.task.BpmProcessInstanceConvert;
12 import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmProcessDefinitionExtDO; 12 import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmProcessDefinitionExtDO;
13 import cn.iocoder.yudao.module.bpm.dal.dataobject.task.BpmProcessInstanceExtDO; 13 import cn.iocoder.yudao.module.bpm.dal.dataobject.task.BpmProcessInstanceExtDO;
14 import cn.iocoder.yudao.module.bpm.dal.mysql.task.BpmProcessInstanceExtMapper; 14 import cn.iocoder.yudao.module.bpm.dal.mysql.task.BpmProcessInstanceExtMapper;
  15 +import cn.iocoder.yudao.module.bpm.enums.task.BpmProcessInstanceResultEnum;
  16 +import cn.iocoder.yudao.module.bpm.enums.task.BpmProcessInstanceStatusEnum;
15 import cn.iocoder.yudao.module.bpm.service.definition.BpmProcessDefinitionService; 17 import cn.iocoder.yudao.module.bpm.service.definition.BpmProcessDefinitionService;
16 import cn.iocoder.yudao.module.system.api.dept.DeptApi; 18 import cn.iocoder.yudao.module.system.api.dept.DeptApi;
17 import cn.iocoder.yudao.module.system.api.dept.dto.DeptRespDTO; 19 import cn.iocoder.yudao.module.system.api.dept.dto.DeptRespDTO;
@@ -32,6 +34,7 @@ import javax.annotation.Resource; @@ -32,6 +34,7 @@ import javax.annotation.Resource;
32 import javax.validation.Valid; 34 import javax.validation.Valid;
33 import java.util.List; 35 import java.util.List;
34 import java.util.Map; 36 import java.util.Map;
  37 +import java.util.Optional;
35 import java.util.Set; 38 import java.util.Set;
36 39
37 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; 40 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
@@ -142,6 +145,23 @@ public class BpmProcessInstanceServiceImpl implements BpmProcessInstanceService @@ -142,6 +145,23 @@ public class BpmProcessInstanceServiceImpl implements BpmProcessInstanceService
142 return historyService.createHistoricProcessInstanceQuery().processInstanceId(id).singleResult(); 145 return historyService.createHistoricProcessInstanceQuery().processInstanceId(id).singleResult();
143 } 146 }
144 147
  148 + @Override
  149 + public void createProcessInstanceExt(ProcessInstance instance) {
  150 + // 获得流程定义
  151 + ProcessDefinition definition = processDefinitionService.getProcessDefinition2(instance.getProcessDefinitionId());
  152 + // 插入 BpmProcessInstanceExtDO 对象
  153 + BpmProcessInstanceExtDO instanceExtDO = new BpmProcessInstanceExtDO()
  154 + .setProcessInstanceId(instance.getId())
  155 + .setProcessDefinitionId(definition.getId())
  156 + .setName(instance.getProcessDefinitionName())
  157 + .setStartUserId(Long.valueOf(instance.getStartUserId()))
  158 + .setCategory(definition.getCategory())
  159 + .setStatus(BpmProcessInstanceStatusEnum.RUNNING.getStatus())
  160 + .setResult(BpmProcessInstanceResultEnum.PROCESS.getResult());
  161 +
  162 + processInstanceExtMapper.insert(instanceExtDO);
  163 + }
  164 +
145 private String createProcessInstance0(Long userId, ProcessDefinition definition, 165 private String createProcessInstance0(Long userId, ProcessDefinition definition,
146 Map<String, Object> variables, String businessKey) { 166 Map<String, Object> variables, String businessKey) {
147 // 校验流程定义 167 // 校验流程定义