Browse Source

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

jason 3 years ago
parent
commit
073d860a78
17 changed files with 246 additions and 2 deletions
  1. 5 0
      yudao-dependencies/pom.xml
  2. 1 0
      yudao-framework/pom.xml
  3. 2 0
      yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/enums/WebFilterOrderEnum.java
  4. 31 0
      yudao-framework/yudao-spring-boot-starter-flowable/pom.xml
  5. 22 0
      yudao-framework/yudao-spring-boot-starter-flowable/src/main/java/cn/iocoder/yudao/framework/flowable/config/YudaoFlowableConfiguration.java
  6. 1 0
      yudao-framework/yudao-spring-boot-starter-flowable/src/main/java/cn/iocoder/yudao/framework/flowable/core/package-info.java
  7. 14 0
      yudao-framework/yudao-spring-boot-starter-flowable/src/main/java/cn/iocoder/yudao/framework/flowable/core/util/FlowableUtils.java
  8. 35 0
      yudao-framework/yudao-spring-boot-starter-flowable/src/main/java/cn/iocoder/yudao/framework/flowable/core/web/FlowableWebFilter.java
  9. 1 0
      yudao-framework/yudao-spring-boot-starter-flowable/src/main/java/cn/iocoder/yudao/framework/flowable/package-info.java
  10. 2 0
      yudao-framework/yudao-spring-boot-starter-flowable/src/main/resources/META-INF/spring.factories
  11. 2 2
      yudao-module-bpm/yudao-module-bpm-impl-flowable/pom.xml
  12. 33 0
      yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/config/BpmFlowableConfiguration.java
  13. 54 0
      yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/listener/BpmProcessInstanceEventListener.java
  14. 10 0
      yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmProcessDefinitionService.java
  15. 5 0
      yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmProcessDefinitionServiceImpl.java
  16. 8 0
      yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmProcessInstanceService.java
  17. 20 0
      yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmProcessInstanceServiceImpl.java

+ 5 - 0
yudao-dependencies/pom.xml

@@ -399,6 +399,11 @@
                 <version>${revision}</version>
             </dependency>
             <!-- 工作流相关 flowable -->
+            <dependency>
+                <groupId>cn.iocoder.boot</groupId>
+                <artifactId>yudao-spring-boot-starter-flowable</artifactId>
+                <version>${revision}</version>
+            </dependency>
             <dependency>
                 <groupId>org.flowable</groupId>
                 <artifactId>flowable-spring-boot-starter-basic</artifactId>

+ 1 - 0
yudao-framework/pom.xml

@@ -35,6 +35,7 @@
         <module>yudao-spring-boot-starter-biz-social</module>
         <module>yudao-spring-boot-starter-biz-tenant</module>
         <module>yudao-spring-boot-starter-biz-data-permission</module>
+        <module>yudao-spring-boot-starter-flowable</module>
     </modules>
 
     <artifactId>yudao-framework</artifactId>

+ 2 - 0
yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/enums/WebFilterOrderEnum.java

@@ -29,6 +29,8 @@ public interface WebFilterOrderEnum {
 
     int ACTIVITI_FILTER = -98; // 需要保证在 Spring Security 过滤后面
 
+    int FLOWABLE_FILTER = -98; // 需要保证在 Spring Security 过滤后面
+
     int DEMO_FILTER = Integer.MAX_VALUE;
 
 }

+ 31 - 0
yudao-framework/yudao-spring-boot-starter-flowable/pom.xml

@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
+        <artifactId>yudao-framework</artifactId>
+        <groupId>cn.iocoder.boot</groupId>
+        <version>${revision}</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>yudao-spring-boot-starter-flowable</artifactId>
+
+    <dependencies>
+        <dependency>
+            <groupId>cn.iocoder.boot</groupId>
+            <artifactId>yudao-common</artifactId>
+        </dependency>
+        <!-- Web 相关 -->
+        <dependency>
+            <groupId>cn.iocoder.boot</groupId>
+            <artifactId>yudao-spring-boot-starter-security</artifactId>
+        </dependency>
+        <!-- flowable 工作流相关 -->
+        <dependency>
+            <groupId>org.flowable</groupId>
+            <artifactId>flowable-spring-boot-starter-basic</artifactId>
+        </dependency>
+    </dependencies>
+
+</project>

+ 22 - 0
yudao-framework/yudao-spring-boot-starter-flowable/src/main/java/cn/iocoder/yudao/framework/flowable/config/YudaoFlowableConfiguration.java

@@ -0,0 +1,22 @@
+package cn.iocoder.yudao.framework.flowable.config;
+
+import cn.iocoder.yudao.framework.common.enums.WebFilterOrderEnum;
+import cn.iocoder.yudao.framework.flowable.core.web.FlowableWebFilter;
+import org.springframework.boot.web.servlet.FilterRegistrationBean;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+@Configuration
+public class YudaoFlowableConfiguration {
+
+    /**
+     * 配置 flowable Web 过滤器
+     */
+    @Bean
+    public FilterRegistrationBean<FlowableWebFilter> flowableWebFilter() {
+        FilterRegistrationBean<FlowableWebFilter> registrationBean = new FilterRegistrationBean<>();
+        registrationBean.setFilter(new FlowableWebFilter());
+        registrationBean.setOrder(WebFilterOrderEnum.FLOWABLE_FILTER);
+        return registrationBean;
+    }
+}

+ 1 - 0
yudao-framework/yudao-spring-boot-starter-flowable/src/main/java/cn/iocoder/yudao/framework/flowable/core/package-info.java

@@ -0,0 +1 @@
+package cn.iocoder.yudao.framework.flowable.core;

+ 14 - 0
yudao-framework/yudao-spring-boot-starter-flowable/src/main/java/cn/iocoder/yudao/framework/flowable/core/util/FlowableUtils.java

@@ -0,0 +1,14 @@
+package cn.iocoder.yudao.framework.flowable.core.util;
+
+import org.flowable.common.engine.impl.identity.Authentication;
+
+public class FlowableUtils {
+
+    public static void setAuthenticatedUserId(Long userId) {
+        Authentication.setAuthenticatedUserId(String.valueOf(userId));
+    }
+
+    public static void clearAuthenticatedUserId() {
+        Authentication.setAuthenticatedUserId(null);
+    }
+}

+ 35 - 0
yudao-framework/yudao-spring-boot-starter-flowable/src/main/java/cn/iocoder/yudao/framework/flowable/core/web/FlowableWebFilter.java

@@ -0,0 +1,35 @@
+package cn.iocoder.yudao.framework.flowable.core.web;
+
+import cn.iocoder.yudao.framework.flowable.core.util.FlowableUtils;
+import cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils;
+import org.springframework.web.filter.OncePerRequestFilter;
+
+import javax.servlet.FilterChain;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+/**
+ * flowable Web 过滤器,将 userId 设置到 {@link org.flowable.common.engine.impl.identity.Authentication} 中
+ *
+ * @author jason
+ */
+public class FlowableWebFilter extends OncePerRequestFilter {
+
+    @Override
+    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain)
+            throws ServletException, IOException {
+        try {
+            // 设置工作流的用户
+            Long userId = SecurityFrameworkUtils.getLoginUserId();
+            if (userId != null) {
+                FlowableUtils.setAuthenticatedUserId(userId);
+            }
+            // 过滤
+            chain.doFilter(request, response);
+        } finally {
+            // 清理
+            FlowableUtils.clearAuthenticatedUserId();
+        }
+    }
+}

+ 1 - 0
yudao-framework/yudao-spring-boot-starter-flowable/src/main/java/cn/iocoder/yudao/framework/flowable/package-info.java

@@ -0,0 +1 @@
+package cn.iocoder.yudao.framework.flowable;

+ 2 - 0
yudao-framework/yudao-spring-boot-starter-flowable/src/main/resources/META-INF/spring.factories

@@ -0,0 +1,2 @@
+org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
+  cn.iocoder.yudao.framework.flowable.config.YudaoFlowableConfiguration

+ 2 - 2
yudao-module-bpm/yudao-module-bpm-impl-flowable/pom.xml

@@ -23,8 +23,8 @@
         </dependency>
         <!-- 工作流相关 -->
         <dependency>
-            <groupId>org.flowable</groupId>
-            <artifactId>flowable-spring-boot-starter-basic</artifactId>
+            <groupId>cn.iocoder.boot</groupId>
+            <artifactId>yudao-spring-boot-starter-flowable</artifactId>
         </dependency>
         <dependency>
             <groupId>org.flowable</groupId>

+ 33 - 0
yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/config/BpmFlowableConfiguration.java

@@ -0,0 +1,33 @@
+package cn.iocoder.yudao.module.bpm.framework.flowable.config;
+
+import cn.iocoder.yudao.module.bpm.framework.flowable.core.listener.BpmProcessInstanceEventListener;
+import org.flowable.common.engine.api.delegate.event.FlowableEventListener;
+import org.flowable.engine.runtime.ProcessInstance;
+import org.flowable.spring.SpringProcessEngineConfiguration;
+import org.flowable.spring.boot.EngineConfigurationConfigurer;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+import java.util.ArrayList;
+import java.util.List;
+/**
+ * BPM 模块的 Flowable 配置类
+ *
+ * @author jason
+ */
+@Configuration
+public class BpmFlowableConfiguration {
+
+    /**
+     *将自定义 listener 加入全局listener
+     * @param processInstanceListener 自定义监听 {@link ProcessInstance}
+     */
+    @Bean
+    public EngineConfigurationConfigurer<SpringProcessEngineConfiguration> addCustomerListenerConfigurer (BpmProcessInstanceEventListener processInstanceListener) {
+        return engineConfiguration -> {
+            List<FlowableEventListener> eventListeners = new ArrayList<>();
+            eventListeners.add(processInstanceListener);
+            engineConfiguration.setEventListeners(eventListeners);
+        };
+    }
+}

+ 54 - 0
yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/listener/BpmProcessInstanceEventListener.java

@@ -0,0 +1,54 @@
+package cn.iocoder.yudao.module.bpm.framework.flowable.core.listener;
+
+import cn.iocoder.yudao.module.bpm.dal.dataobject.task.BpmProcessInstanceExtDO;
+import cn.iocoder.yudao.module.bpm.service.task.BpmProcessInstanceService;
+import com.google.common.collect.ImmutableSet;
+import org.flowable.common.engine.api.delegate.event.FlowableEngineEntityEvent;
+import org.flowable.common.engine.api.delegate.event.FlowableEngineEventType;
+import org.flowable.engine.delegate.event.AbstractFlowableEngineEventListener;
+import org.flowable.engine.delegate.event.FlowableCancelledEvent;
+import org.flowable.engine.delegate.event.FlowableProcessStartedEvent;
+import org.flowable.engine.runtime.ProcessInstance;
+import org.springframework.context.annotation.Lazy;
+import org.springframework.stereotype.Component;
+
+import javax.annotation.Resource;
+import java.util.Set;
+/**
+ * 监听 {@link ProcessInstance} 的开始与完成,创建与更新对应的 {@link BpmProcessInstanceExtDO} 记录
+ *
+ * @author jason
+ */
+@Component
+public class BpmProcessInstanceEventListener extends AbstractFlowableEngineEventListener {
+
+    @Resource
+    @Lazy
+    private BpmProcessInstanceService processInstanceService;
+
+    public static final Set<FlowableEngineEventType> PROCESS_INSTANCE_EVENTS = ImmutableSet.<FlowableEngineEventType>builder()
+                     .add(FlowableEngineEventType.PROCESS_CREATED)
+                     .add(FlowableEngineEventType.PROCESS_STARTED)
+                     .add(FlowableEngineEventType.PROCESS_CANCELLED)
+                     .build();
+
+    public BpmProcessInstanceEventListener(){
+        super(PROCESS_INSTANCE_EVENTS);
+    }
+
+    @Override
+    protected void processCreated(FlowableEngineEntityEvent event) {
+        processInstanceService.createProcessInstanceExt((ProcessInstance)event.getEntity());
+    }
+
+    @Override
+    protected void processStarted(FlowableProcessStartedEvent event) {
+        super.processStarted(event);
+    }
+
+
+    @Override
+    protected void processCancelled(FlowableCancelledEvent event) {
+        super.processCancelled(event);
+    }
+}

+ 10 - 0
yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmProcessDefinitionService.java

@@ -89,6 +89,16 @@ public interface BpmProcessDefinitionService {
      */
     ProcessDefinition getProcessDefinition(String id);
 
+    /**
+     * 获得编号对应的 ProcessDefinition
+     *
+     * 相比 {@link #getProcessDefinition(String)} 方法,category 的取值是正确
+     *
+     * @param id 编号
+     * @return 流程定义
+     */
+    ProcessDefinition getProcessDefinition2(String id);
+
     /**
      * 获得 deploymentId 对应的 ProcessDefinition
      *

+ 5 - 0
yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmProcessDefinitionServiceImpl.java

@@ -66,6 +66,11 @@ public class BpmProcessDefinitionServiceImpl implements BpmProcessDefinitionServ
         return repositoryService.getProcessDefinition(id);
     }
 
+    @Override
+    public ProcessDefinition getProcessDefinition2(String id) {
+        return repositoryService.createProcessDefinitionQuery().processDefinitionId(id).singleResult();
+    }
+
     @Override
     public ProcessDefinition getProcessDefinitionByDeploymentId(String deploymentId) {
         if (StrUtil.isEmpty(deploymentId)) {

+ 8 - 0
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
 import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance.BpmProcessInstanceMyPageReqVO;
 import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance.BpmProcessInstancePageItemRespVO;
 import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance.BpmProcessInstanceRespVO;
+import org.flowable.common.engine.api.delegate.event.FlowableEngineEntityEvent;
 import org.flowable.engine.history.HistoricProcessInstance;
 import org.flowable.engine.runtime.ProcessInstance;
 
@@ -73,4 +74,11 @@ public interface BpmProcessInstanceService {
      * @return 历史的流程实例
      */
     HistoricProcessInstance getHistoricProcessInstance(String id);
+
+    /**
+     * 创建 ProcessInstance 拓展记录
+     *
+     * @param instance 流程任务
+     */
+    void createProcessInstanceExt(ProcessInstance instance);
 }

+ 20 - 0
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;
 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.BpmProcessInstanceResultEnum;
+import cn.iocoder.yudao.module.bpm.enums.task.BpmProcessInstanceStatusEnum;
 import cn.iocoder.yudao.module.bpm.service.definition.BpmProcessDefinitionService;
 import cn.iocoder.yudao.module.system.api.dept.DeptApi;
 import cn.iocoder.yudao.module.system.api.dept.dto.DeptRespDTO;
@@ -32,6 +34,7 @@ import javax.annotation.Resource;
 import javax.validation.Valid;
 import java.util.List;
 import java.util.Map;
+import java.util.Optional;
 import java.util.Set;
 
 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
@@ -142,6 +145,23 @@ public class BpmProcessInstanceServiceImpl implements BpmProcessInstanceService
         return historyService.createHistoricProcessInstanceQuery().processInstanceId(id).singleResult();
     }
 
+    @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);
+    }
+
     private String createProcessInstance0(Long userId, ProcessDefinition definition,
                                           Map<String, Object> variables, String businessKey) {
         // 校验流程定义