This commit is contained in:
那些花儿
2025-07-31 10:36:02 +08:00
parent 73974dbdd3
commit 8118ea9687
21 changed files with 472 additions and 333 deletions
@@ -13,8 +13,8 @@ import java.util.List;
import java.util.stream.Collectors;
/**
*
* 流程模型
*
* @author mldong
* @date 2023/4/25
*/
@@ -24,6 +24,8 @@ public class ProcessModel extends BaseModel {
private String type; // 流程定义分类
private String icon; // 流程定义图标
private String category; // 流程定义分类
private String remark; // 流程备注
private String description; // 流程说明
private String instanceUrl; // 启动实例要填写的表单key
private String h5InstanceUrl; // 启动实例要填写的手机端表单key
private String instanceViewUrl;
@@ -39,13 +41,14 @@ public class ProcessModel extends BaseModel {
/**
* 获取开始节点
*
* @return
*/
public StartModel getStart() {
StartModel startModel = null;
for (int i = 0; i < nodes.size(); i++) {
NodeModel nodeModel = nodes.get(i);
if(nodeModel instanceof StartModel) {
if (nodeModel instanceof StartModel) {
startModel = (StartModel) nodeModel;
break;
}
@@ -55,12 +58,13 @@ public class ProcessModel extends BaseModel {
/**
* 获取process定义的指定节点名称的节点模型
*
* @param nodeName 节点名称
* @return
*/
public NodeModel getNode(String nodeName) {
for(NodeModel node : nodes) {
if(node.getName().equals(nodeName)) {
for (NodeModel node : nodes) {
if (node.getName().equals(nodeName)) {
return node;
}
}
@@ -69,23 +73,24 @@ public class ProcessModel extends BaseModel {
/**
* 获取下一个任务节点模型集合
*
* @param nodeName
* @return
*/
public List<TaskModel> getNextTaskModels(String nodeName) {
List<TaskModel> res = new ArrayList<>();
NodeModel nodeModel = getNode(nodeName);
if(nodeModel == null) return res;
if (nodeModel == null) return res;
// 获取所有输出边的目标节点
List<NodeModel> nextNodeModelList = nodeModel.getOutputs().stream().map(TransitionModel::getTarget).toList();
nextNodeModelList.forEach(item->{
if(item instanceof TaskModel) {
nextNodeModelList.forEach(item -> {
if (item instanceof TaskModel) {
res.add((TaskModel) item);
}
});
if(res.isEmpty()) {
if (res.isEmpty()) {
// 如果下一个节点不存在任务节点,递归往下找
nextNodeModelList.forEach(item->{
nextNodeModelList.forEach(item -> {
List<TaskModel> taskModelList = getNextTaskModels(item.getName());
res.addAll(taskModelList);
});
@@ -95,19 +100,22 @@ public class ProcessModel extends BaseModel {
/**
* 获取下一个任务节点的候选人
*
* @param nodeName
* @return
*/
public List<Candidate> getNextTaskModelCandidates(String nodeName) {
List<Candidate> res = new ArrayList<>();
List<TaskModel> nextTaskModels = getNextTaskModels(nodeName);
nextTaskModels.forEach(item->{
nextTaskModels.forEach(item -> {
res.addAll(getCandidates(item));
});
return res;
}
/**
* 根据任务模型获取候选人
*
* @param taskModel
* @return
*/
@@ -115,29 +123,31 @@ public class ProcessModel extends BaseModel {
List<Candidate> res = new ArrayList<>();
// 从上下文中查找候选人处理人
List<CandidateHandler> handlerList = ServiceContext.findList(CandidateHandler.class);
handlerList.forEach(handler->{
handlerList.forEach(handler -> {
// 通过候选从处理类获取候选人集合
List<Candidate> candidateList = handler.handle(taskModel);
if(candidateList!=null) {
if (candidateList != null) {
res.addAll(candidateList);
}
});
// 通过候选人处理类获取修选人
String candidateHandler = taskModel.getCandidateHandler();
if(StrUtil.isNotEmpty(candidateHandler)) {
if (StrUtil.isNotEmpty(candidateHandler)) {
CandidateHandler candidateHandlerClass = ReflectUtil.newInstance(candidateHandler);
List<Candidate> candidateList = candidateHandlerClass.handle(taskModel);
if(candidateList!=null) {
if (candidateList != null) {
res.addAll(candidateList);
}
}
// 去重
return res.stream().distinct().collect(Collectors.toList());
}
/**
* 根据指定的节点类型返回流程定义中所有模型对象
*
* @param clazz 节点类型
* @param <T> 泛型
* @param <T> 泛型
* @return 节点列表
*/
public <T> List<T> getModels(Class<T> clazz) {
@@ -147,10 +157,10 @@ public class ProcessModel extends BaseModel {
}
private <T> void buildModels(List<T> models, List<T> nextModels, Class<T> clazz) {
for(T nextModel : nextModels) {
if(!models.contains(nextModel)) {
for (T nextModel : nextModels) {
if (!models.contains(nextModel)) {
models.add(nextModel);
buildModels(models, ((NodeModel)nextModel).getNextModels(clazz), clazz);
buildModels(models, ((NodeModel) nextModel).getNextModels(clazz), clazz);
}
}
}
@@ -15,6 +15,7 @@ import java.util.List;
public class LfModel extends BaseModel {
private String type; // 流程定义分类
private String category;
private String description; // 流程描述
private String expireTime;// 过期时间(常量或变量)
private String instanceUrl; // 启动实例的url,前后端分离后,定义为路由名或或路由地址
private String h5InstanceUrl;
@@ -1,20 +1,21 @@
package com.budwk.app.flow.engine.parser;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.io.IoUtil;
import cn.hutool.json.JSONUtil;
import com.budwk.app.flow.engine.core.ServiceContext;
import com.budwk.app.flow.engine.model.NodeModel;
import com.budwk.app.flow.engine.model.ProcessModel;
import com.budwk.app.flow.engine.model.TaskModel;
import com.budwk.app.flow.engine.model.TransitionModel;
import com.budwk.app.flow.engine.model.logicflow.*;
import com.budwk.app.flow.engine.model.logicflow.LfEdge;
import com.budwk.app.flow.engine.model.logicflow.LfModel;
import com.budwk.app.flow.engine.model.logicflow.LfNode;
import java.io.ByteArrayInputStream;
import java.util.List;
public class ModelParser {
private ModelParser(){}
private ModelParser() {
}
// /**
// * 将json定义文件解析成流程模型对象
@@ -71,7 +72,7 @@ public class ModelParser {
ProcessModel processModel = new ProcessModel();
List<LfNode> nodes = lfModel.getNodes();
List<LfEdge> edges = lfModel.getEdges();
if(CollectionUtil.isEmpty(nodes) || CollectionUtil.isEmpty(edges) ) {
if (CollectionUtil.isEmpty(nodes) || CollectionUtil.isEmpty(edges)) {
return processModel;
}
// 流程定义基本信息
@@ -79,6 +80,7 @@ public class ModelParser {
processModel.setDisplayName(lfModel.getDisplayName());
processModel.setType(lfModel.getType());
processModel.setCategory(lfModel.getCategory());
processModel.setDescription(lfModel.getDescription());
processModel.setInstanceUrl(lfModel.getInstanceUrl());
processModel.setH5InstanceUrl(lfModel.getH5InstanceUrl());
processModel.setInstanceViewUrl(lfModel.getInstanceViewUrl());
@@ -87,10 +89,10 @@ public class ModelParser {
processModel.setPostInterceptors(lfModel.getPostInterceptors());
processModel.setPreInterceptors(lfModel.getPreInterceptors());
// 流程节点信息
nodes.forEach(node->{
String type = node.getType().replace(NodeParser.NODE_NAME_PREFIX,"");
NodeParser nodeParser = ServiceContext.findByName(type,NodeParser.class);
if(nodeParser!=null) {
nodes.forEach(node -> {
String type = node.getType().replace(NodeParser.NODE_NAME_PREFIX, "");
NodeParser nodeParser = ServiceContext.findByName(type, NodeParser.class);
if (nodeParser != null) {
nodeParser.parse(node, edges);
NodeModel nodeModel = nodeParser.getModel();
processModel.getNodes().add(nodeParser.getModel());
@@ -100,11 +102,11 @@ public class ModelParser {
}
});
// 循环节点模型,构造输入边、输出边的source、target
for(NodeModel node : processModel.getNodes()) {
for(TransitionModel transition : node.getOutputs()) {
for (NodeModel node : processModel.getNodes()) {
for (TransitionModel transition : node.getOutputs()) {
String to = transition.getTo();
for(NodeModel node2 : processModel.getNodes()) {
if(to.equalsIgnoreCase(node2.getName())) {
for (NodeModel node2 : processModel.getNodes()) {
if (to.equalsIgnoreCase(node2.getName())) {
node2.getInputs().add(transition);
transition.setTarget(node2);
}