初始代码

This commit is contained in:
wangmingwei
2026-04-21 17:15:37 +08:00
parent 321382cac0
commit 349295e4c4
48 changed files with 5660 additions and 0 deletions

View File

@@ -0,0 +1,32 @@
<?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">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.yunzhupaas</groupId>
<artifactId>yunzhupaas-workflow-core</artifactId>
<version>1.0.0-RELEASE</version>
</parent>
<artifactId>yunzhupaas-workflow-activiti</artifactId>
<dependencies>
<dependency>
<groupId>org.activiti</groupId>
<artifactId>activiti-spring-boot-starter</artifactId>
<version>${activiti.version}</version>
<exclusions>
<exclusion>
<artifactId>mybatis</artifactId>
<groupId>org.mybatis</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.yunzhupaas</groupId>
<artifactId>yunzhupaas-workflow-common</artifactId>
<version>${project.version}</version>
</dependency>
</dependencies>
</project>

View File

@@ -0,0 +1,144 @@
package com.yunzhupaas.workflow.activiti.cmd;
import cn.hutool.core.collection.CollectionUtil;
import org.activiti.bpmn.model.BpmnModel;
import org.activiti.bpmn.model.UserTask;
import org.activiti.engine.RuntimeService;
import org.activiti.engine.history.HistoricActivityInstance;
import org.activiti.engine.history.HistoricTaskInstance;
import org.activiti.engine.impl.HistoricActivityInstanceQueryImpl;
import org.activiti.engine.impl.HistoricTaskInstanceQueryImpl;
import org.activiti.engine.impl.Page;
import org.activiti.engine.impl.interceptor.Command;
import org.activiti.engine.impl.interceptor.CommandContext;
import org.activiti.engine.impl.persistence.entity.*;
import org.activiti.engine.runtime.Execution;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
/**
* 跳转命令类
*
* @author yanghuixing
* @author YMPaaS CloudYUNZHUPAAS开发组
* @version 0.2.0
* @since 2023/8/22 17:56
*/
public class JumpCmd implements Command<Void> {
private final String processInstanceId;
private List<String> sourceTaskDefIdList;
private List<String> targetFlowNodeIdList;
private String deleteReason;
private final BpmnModel bpmnModel;
private final RuntimeService runtimeService;
/**
* 保存撤回节点的变量map
*/
private Map<String, List<VariableInstanceEntity>> varMap = new ConcurrentHashMap<>();
public JumpCmd(String processInstanceId, List<String> sourceTaskDefIdList, List<String> targetFlowNodeIdList,
String deleteReason, BpmnModel bpmnModel, RuntimeService runtimeService) {
this.processInstanceId = processInstanceId;
this.sourceTaskDefIdList = sourceTaskDefIdList;
this.deleteReason = deleteReason;
this.targetFlowNodeIdList = targetFlowNodeIdList;
this.bpmnModel = bpmnModel;
this.runtimeService = runtimeService;
}
@Override
public Void execute(CommandContext commandContext) {
ExecutionEntityManager executionEntityManager = commandContext.getExecutionEntityManager();
// 处理act_ru_execution
handleExecution(commandContext);
// 处理act_hi_actinst
handleActInst(commandContext);
targetFlowNodeIdList.forEach(targetId -> {
UserTask userTask = (UserTask) bpmnModel.getFlowElement(targetId);
// 创建子执行流,开启任务
ExecutionEntity processExecution = executionEntityManager.findById(processInstanceId);
ExecutionEntity childExecution = executionEntityManager.createChildExecution(processExecution);
childExecution.setCurrentFlowElement(userTask);
// 设置执行变量
VariableInstanceEntityManager variableManage = commandContext.getVariableInstanceEntityManager();
List<VariableInstanceEntity> variableInstanceEntities = varMap.get(userTask.getId());
if (CollectionUtil.isNotEmpty(variableInstanceEntities)) {
variableInstanceEntities.forEach(var -> {
var.setExecutionId(childExecution.getId());
variableManage.insert(var);
});
}
executionEntityManager.insert(childExecution);
// 交给引擎流转
commandContext.getAgenda().planContinueProcessOperation(childExecution);
});
return null;
}
private void handleActInst(CommandContext commandContext) {
for (String str : sourceTaskDefIdList) {
HistoricActivityInstanceQueryImpl query = new HistoricActivityInstanceQueryImpl().activityId(str)
.processInstanceId(processInstanceId).unfinished();
List<HistoricActivityInstance> activityInstances = commandContext.getHistoricActivityInstanceEntityManager()
.findHistoricActivityInstancesByQueryCriteria(query, new Page(0, Integer.MAX_VALUE));
for (HistoricActivityInstance activity : activityInstances) {
HistoricActivityInstanceEntity activityEntity = (HistoricActivityInstanceEntity) activity;
// 修改act_hi_actinst表
activityEntity.setDeleted(true);
activityEntity.setDeleteReason(deleteReason);
commandContext.getHistoricActivityInstanceEntityManager().update(activityEntity);
}
}
}
private void handleExecution(CommandContext commandContext) {
ExecutionEntityManager executionEntityManager = commandContext.getExecutionEntityManager();
HistoricTaskInstanceEntityManager historicTaskManager = commandContext.getHistoricTaskInstanceEntityManager();
VariableInstanceEntityManager variableManager = commandContext.getVariableInstanceEntityManager();
for (String str : sourceTaskDefIdList) {
List<Execution> executionEntities = runtimeService.createExecutionQuery()
.processInstanceId(processInstanceId).activityId(str).list();
for (Execution parentExecution : executionEntities) {
// 关闭未完成的任务执行流
// 获取子级Executions如子流程节点等需要处理
List<ExecutionEntity> childExecutions = executionEntityManager
.findChildExecutionsByParentExecutionId(parentExecution.getId());
for (ExecutionEntity childExecution : childExecutions) {
// 因为外键约束,首先要删除variable表中的execution相关数据
List<VariableInstanceEntity> variableInstances = variableManager
.findVariableInstancesByExecutionId(childExecution.getId());
varMap.put(parentExecution.getActivityId(), variableInstances);
variableInstances.forEach(variableManager::delete);
executionEntityManager.deleteExecutionAndRelatedData(childExecution, deleteReason, false);
// 修改历史实例
HistoricTaskInstanceQueryImpl query = new HistoricTaskInstanceQueryImpl()
.executionId(childExecution.getId()).processInstanceId(processInstanceId);
List<HistoricTaskInstance> HistoricTaskInstances = historicTaskManager
.findHistoricTaskInstancesByQueryCriteria(query);
if (CollectionUtil.isNotEmpty(HistoricTaskInstances)) {
for (HistoricTaskInstance HistoricTaskInstance : HistoricTaskInstances) {
HistoricTaskInstanceEntity entity = (HistoricTaskInstanceEntity) HistoricTaskInstance;
entity.setDeleteReason(deleteReason);
commandContext.getHistoricTaskInstanceEntityManager().update(entity);
}
}
}
// 父执行流关闭
List<VariableInstanceEntity> variableInstances = variableManager
.findVariableInstancesByExecutionId(parentExecution.getId());
varMap.put(parentExecution.getActivityId(), variableInstances);
variableInstances.forEach(variableManager::delete);
ExecutionEntity parentExecution1 = (ExecutionEntity) parentExecution;
executionEntityManager.deleteExecutionAndRelatedData(parentExecution1, deleteReason, false);
}
}
}
}

View File

@@ -0,0 +1,289 @@
package com.yunzhupaas.workflow.activiti.util;
import org.activiti.bpmn.model.*;
import java.util.*;
/**
* activiti工具类
*
* @author yanghuixing
* @author YMPaaS CloudYUNZHUPAAS开发组
* @version 0.2.0
* @since 2023/8/22 14:12
*/
public class ActivitiUtil {
/**
* 获取全部节点元素
*
* @param flowElements {@link Collection<FlowElement>}
* @param allElements {@link Collection<FlowElement>}
* @return {@link Collection<FlowElement>}
* @author yanghuixing
* @since 2023/8/22 16:08
**/
public static Collection<FlowElement> getAllElements(Collection<FlowElement> flowElements,
Collection<FlowElement> allElements) {
allElements = allElements == null ? new ArrayList<>() : allElements;
for (FlowElement flowElement : flowElements) {
allElements.add(flowElement);
if (flowElement instanceof SubProcess) {
// 获取子流程元素
allElements = getAllElements(((SubProcess) flowElement).getFlowElements(), allElements);
}
}
return allElements;
}
/**
* 获取节点的入口连线
*
* @param element {@link FlowElement}
* @return {@link List<SequenceFlow>}
* @author yanghuixing
* @since 2023/8/22 16:09
**/
public static List<SequenceFlow> getElementIncomingFlows(FlowElement element) {
List<SequenceFlow> sequenceFlows = null;
if (element instanceof FlowNode) {
sequenceFlows = ((FlowNode) element).getIncomingFlows();
}
return sequenceFlows;
}
/**
* 获取节点的入口连线
*
* @param element {@link FlowElement}
* @return {@link List<SequenceFlow>}
* @author yanghuixing
* @since 2023/8/22 16:10
**/
public static List<SequenceFlow> getElementOutgoingFlows(FlowElement element) {
List<SequenceFlow> sequenceFlows = null;
if (element instanceof FlowNode) {
sequenceFlows = ((FlowNode) element).getOutgoingFlows();
}
return sequenceFlows;
}
/**
* 获取可回退的节点(用户任务、子流程)
*
* @param source {@link FlowElement}
* @param passFlows {@link Set<String>}
* @param passActs {@link List<Activity>}
* @return {@link List<Activity>}
* @author yanghuixing
* @since 2023/8/22 16:11
**/
public static List<Activity> getPassActs(FlowElement source, Set<String> passFlows, List<Activity> passActs) {
passFlows = passFlows == null ? new HashSet<>() : passFlows;
passActs = passActs == null ? new ArrayList<>() : passActs;
List<SequenceFlow> sequenceFlows = getElementIncomingFlows(source);
if (null != sequenceFlows && sequenceFlows.size() > 0) {
for (SequenceFlow sequenceFlow : sequenceFlows) {
// 连线重复
if (passFlows.contains(sequenceFlow.getId())) {
continue;
}
// 添加经过的连线
passFlows.add(sequenceFlow.getId());
// 添加经过的用户任务、子流程
if (sequenceFlow.getSourceFlowElement() instanceof UserTask) {
passActs.add((UserTask) sequenceFlow.getSourceFlowElement());
}
if (sequenceFlow.getSourceFlowElement() instanceof SubProcess) {
passActs.add((SubProcess) sequenceFlow.getSourceFlowElement());
}
// 迭代
getPassActs(sequenceFlow.getSourceFlowElement(), passFlows, passActs);
}
}
return passActs;
}
/**
* 获取上一级节点(用户任务、子流程)
*
* @param source {@link FlowElement}
* @param passFlows {@link Set<String>}
* @param parentActs {@link List<Activity>}
* @return {@link List<Activity>}
* @author yanghuixing
* @since 2023/8/22 16:13
**/
public static List<Activity> getParentActs(FlowElement source, Set<String> passFlows, List<Activity> parentActs) {
passFlows = passFlows == null ? new HashSet<>() : passFlows;
parentActs = parentActs == null ? new ArrayList<>() : parentActs;
List<SequenceFlow> sequenceFlows = getElementIncomingFlows(source);
if (null != sequenceFlows && sequenceFlows.size() > 0) {
for (SequenceFlow sequenceFlow : sequenceFlows) {
// 连线重复
if (passFlows.contains(sequenceFlow.getId())) {
continue;
}
// 添加经过的连线
passFlows.add(sequenceFlow.getId());
// 添加用户任务、子流程
if (sequenceFlow.getSourceFlowElement() instanceof UserTask) {
parentActs.add((UserTask) sequenceFlow.getSourceFlowElement());
continue;
}
if (sequenceFlow.getSourceFlowElement() instanceof SubProcess) {
parentActs.add((SubProcess) sequenceFlow.getSourceFlowElement());
continue;
}
// 迭代
getParentActs(sequenceFlow.getSourceFlowElement(), passFlows, parentActs);
}
}
return parentActs;
}
/**
* 获取需要撤回的节点
*
* @param source {@link FlowElement}
* @param runTaskKeyList {@link List<String>}
* @param passFlows {@link Set<String>}
* @param userTasks {@link List<UserTask>}
* @return {@link List<UserTask>}
* @author yanghuixing
* @since 2023/8/22 16:13
**/
public static List<UserTask> getChildUserTasks(FlowElement source, List<String> runTaskKeyList,
Set<String> passFlows, List<UserTask> userTasks) {
passFlows = passFlows == null ? new HashSet<>() : passFlows;
userTasks = userTasks == null ? new ArrayList<>() : userTasks;
List<SequenceFlow> sequenceFlows = getElementOutgoingFlows(source);
if (null != sequenceFlows && sequenceFlows.size() > 0) {
for (SequenceFlow sequenceFlow : sequenceFlows) {
// 连线重复
if (passFlows.contains(sequenceFlow.getId())) {
continue;
}
// 添加经过的连线
passFlows.add(sequenceFlow.getId());
// 用户任务
if (sequenceFlow.getTargetFlowElement() instanceof UserTask
&& runTaskKeyList.contains(sequenceFlow.getTargetFlowElement().getId())) {
userTasks.add((UserTask) sequenceFlow.getTargetFlowElement());
continue;
}
// 子流程,从第一个节点开始获取
if (sequenceFlow.getTargetFlowElement() instanceof SubProcess) {
FlowElement flowElement = (FlowElement) ((SubProcess) sequenceFlow.getTargetFlowElement())
.getFlowElements().toArray()[0];
List<UserTask> tasks = getChildUserTasks(flowElement, runTaskKeyList, passFlows, null);
// 找到用户任务,不继续向下找
if (tasks.size() > 0) {
userTasks.addAll(tasks);
continue;
}
}
// 迭代
getChildUserTasks(sequenceFlow.getTargetFlowElement(), runTaskKeyList, passFlows, userTasks);
}
}
return userTasks;
}
/**
* 获取下一级的用户任务
*
* @param source {@link FlowElement}
* @param hasSequenceFlow {@link Set<String>}
* @param userTaskList {@link List<UserTask>}
* @return {@link List<UserTask>}
* @author yanghuixing
* @since 2023/8/22 16:15
**/
public static List<UserTask> getNextUserTasks(FlowElement source, Set<String> hasSequenceFlow,
List<UserTask> userTaskList) {
hasSequenceFlow = Optional.ofNullable(hasSequenceFlow).orElse(new HashSet<>());
userTaskList = Optional.ofNullable(userTaskList).orElse(new ArrayList<>());
// 获取出口连线
List<SequenceFlow> sequenceFlows = getElementOutgoingFlows(source);
if (null != sequenceFlows) {
for (SequenceFlow sequenceFlow : sequenceFlows) {
// 如果发现连线重复,说明循环了,跳过这个循环
if (hasSequenceFlow.contains(sequenceFlow.getId())) {
continue;
}
// 添加已经走过的连线
hasSequenceFlow.add(sequenceFlow.getId());
FlowElement targetFlowElement = sequenceFlow.getTargetFlowElement();
if (targetFlowElement instanceof UserTask) {
// 若节点为用户任务,加入到结果列表中
userTaskList.add((UserTask) targetFlowElement);
} else {
// 若节点非用户任务,继续递归查找下一个节点
getNextUserTasks(targetFlowElement, hasSequenceFlow, userTaskList);
}
}
}
return userTaskList;
}
/**
* 判断某个节点的出口是否是网关,获取网关的出口连线
*
* @param source {@link FlowElement}
* @return {@link List<SequenceFlow>}
* @author yanghuixing
* @since 2023/8/22 16:15
**/
public static List<SequenceFlow> getOutFlowsOfGateway(FlowElement source) {
List<SequenceFlow> flows = new ArrayList<>();
// 获取出口连线
List<SequenceFlow> sequenceFlows = getElementOutgoingFlows(source);
if (null != sequenceFlows) {
for (SequenceFlow sequenceFlow : sequenceFlows) {
FlowElement targetFlowElement = sequenceFlow.getTargetFlowElement();
if (targetFlowElement instanceof Gateway) {
List<SequenceFlow> outgoingFlows = ((Gateway) targetFlowElement).getOutgoingFlows();
flows.addAll(outgoingFlows);
}
}
return flows;
}
return null;
}
/**
* 获取之前的节点
*
* @param source {@link FlowElement}
* @param passFlows {@link Set<String>}
* @param keys {@link List<String>}
* @return {@link List<String>}
* @author yanghuixing
* @since 2023/8/22 16:16
**/
public static List<String> getBefore(FlowElement source, Set<String> passFlows, List<String> keys) {
passFlows = passFlows == null ? new HashSet<>() : passFlows;
keys = keys == null ? new ArrayList<>() : keys;
List<SequenceFlow> sequenceFlows = getElementIncomingFlows(source);
if (null != sequenceFlows && sequenceFlows.size() > 0) {
for (SequenceFlow sequenceFlow : sequenceFlows) {
// 连线重复
if (passFlows.contains(sequenceFlow.getId())) {
continue;
}
// 添加经过的连线
passFlows.add(sequenceFlow.getId());
// 添加节点Key
keys.add(sequenceFlow.getSourceFlowElement().getId());
if (sequenceFlow.getSourceFlowElement() instanceof StartEvent) {
continue;
}
// 迭代
getBefore(sequenceFlow.getSourceFlowElement(), passFlows, keys);
}
}
return keys;
}
}