工作流 Flowable 发起流程 相关实现
This commit is contained in:
parent
c761f5258a
commit
073d860a78
@ -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>
|
||||
|
@ -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>
|
||||
|
@ -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
yudao-framework/yudao-spring-boot-starter-flowable/pom.xml
Normal file
31
yudao-framework/yudao-spring-boot-starter-flowable/pom.xml
Normal file
@ -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>
|
@ -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;
|
||||
}
|
||||
}
|
@ -0,0 +1 @@
|
||||
package cn.iocoder.yudao.framework.flowable.core;
|
@ -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);
|
||||
}
|
||||
}
|
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1 @@
|
||||
package cn.iocoder.yudao.framework.flowable;
|
@ -0,0 +1,2 @@
|
||||
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
|
||||
cn.iocoder.yudao.framework.flowable.config.YudaoFlowableConfiguration
|
@ -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>
|
||||
|
@ -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);
|
||||
};
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
@ -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
|
||||
*
|
||||
|
@ -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)) {
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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) {
|
||||
// 校验流程定义
|
||||
|
Loading…
Reference in New Issue
Block a user