This commit is contained in:
asp_ly 2024-12-13 20:04:52 +08:00
parent ee3978ae34
commit f55b21d5ab
4 changed files with 439 additions and 188 deletions

View File

@ -24,6 +24,8 @@ public class WorkflowNodeGraph {
private Ports ports; private Ports ports;
private Position position;
public WorkflowNodeGraph setSize(int width, int height) { public WorkflowNodeGraph setSize(int width, int height) {
this.size = new Size(width, height); this.size = new Size(width, height);
return this; return this;
@ -34,6 +36,11 @@ public class WorkflowNodeGraph {
return this; return this;
} }
public WorkflowNodeGraph setPosition(int x, int y) {
this.position = new Position(x, y);
return this;
}
public WorkflowNodeGraph configPorts(List<String> types) { public WorkflowNodeGraph configPorts(List<String> types) {
this.ports = new Ports(); this.ports = new Ports();
Map<String, PortGroup> groups = new HashMap<>(); Map<String, PortGroup> groups = new HashMap<>();
@ -77,11 +84,32 @@ public class WorkflowNodeGraph {
} }
} }
/**
* 节点位置配置
*/
@Data
public static class Position {
private int x;
private int y;
public Position() {
// 默认构造函数
}
public Position(int x, int y) {
this.x = x;
this.y = y;
}
}
/** /**
* 节点样式配置 * 节点样式配置
*/ */
@Data @Data
public static class Style { public static class Style {
private String fill; // 填充颜色 private String fill; // 填充颜色
private String stroke; // 边框颜色 private String stroke; // 边框颜色
@ -118,6 +146,7 @@ public class WorkflowNodeGraph {
/** /**
* 获取端口类型列表 * 获取端口类型列表
*
* @return 端口类型列表"in"/"out" * @return 端口类型列表"in"/"out"
*/ */
public List<String> getTypes() { public List<String> getTypes() {
@ -131,6 +160,7 @@ public class WorkflowNodeGraph {
@Data @Data
public static class PortGroup { public static class PortGroup {
private String position; private String position;
private PortAttrs attrs; private PortAttrs attrs;
public PortGroup() { public PortGroup() {
@ -149,8 +179,11 @@ public class WorkflowNodeGraph {
@Data @Data
public static class PortCircle { public static class PortCircle {
private int r; private int r;
private String fill; private String fill;
private String stroke; private String stroke;
public PortCircle() { public PortCircle() {

View File

@ -52,14 +52,14 @@ public enum NodeTypeEnums {
), ),
SCRIPT_TASK( SCRIPT_TASK(
"SCRIPT_TASK", "SCRIPT_TASK",
"结束节点", "脚本任务",
NodeCategoryEnums.TASK, NodeCategoryEnums.TASK,
"工作流的终点", "脚本执行任务",
new WorkflowNodeGraph() new WorkflowNodeGraph()
.setShape("circle") .setShape("rect")
.setSize(40, 40) .setSize(120, 60)
.setStyle("#fff1f0", "#ff4d4f", "stop") .setStyle("#ffffff", "#1890ff", "code")
.configPorts(Arrays.asList("in")) .configPorts(Arrays.asList("in", "out"))
); );
// //
// /** // /**

View File

@ -18,8 +18,7 @@ import java.util.Map;
* 工作流定义图形生成工具类 * 工作流定义图形生成工具类
* 用于生成示例工作流定义包括 * 用于生成示例工作流定义包括
* 1. 简单工作流开始 -> 脚本任务 -> 结束 * 1. 简单工作流开始 -> 脚本任务 -> 结束
* 2. 复杂工作流开始 -> 服务任务 -> 用户任务 -> 脚本任务 -> 结束 * 2. 复杂工作流开始 -> 脚本任务A -> 脚本任务B -> 结束
* 3. 网关工作流开始 -> 服务任务 -> 排他网关 -> (用户任务A/用户任务B) -> 并行网关 -> (脚本任务A/脚本任务B) -> 结束
*/ */
@Data @Data
@Slf4j @Slf4j
@ -90,7 +89,7 @@ public class WorkflowDefinitionGraph {
/** /**
* 生成复杂工作流 * 生成复杂工作流
* 开始 -> 服务任务 -> 用户任务 -> 脚本任务 -> 结束 * 开始 -> 脚本任务A -> 脚本任务B -> 结束
*/ */
public static WorkflowDefinitionGraph generateComplexWorkflow() { public static WorkflowDefinitionGraph generateComplexWorkflow() {
WorkflowDefinitionGraph graph = new WorkflowDefinitionGraph(); WorkflowDefinitionGraph graph = new WorkflowDefinitionGraph();
@ -107,171 +106,30 @@ public class WorkflowDefinitionGraph {
); );
nodes.add(startNode); nodes.add(startNode);
// 服务任务节点
Map<String, Object> serviceConfig = createNodeConfig("服务任务", "调用外部服务");
serviceConfig.put("url", "http://api.example.com/service");
serviceConfig.put("method", "POST");
// WorkflowDefinitionNode serviceNode = createNode(
// "serviceTask1",
// NodeTypeEnums.SERVICE_TASK,
// "调用服务",
// 300, 100,
// serviceConfig
// );
// nodes.add(serviceNode);
// 用户任务节点
Map<String, Object> userConfig = createNodeConfig("用户任务", "人工审批");
userConfig.put("assignee", "admin");
// WorkflowDefinitionNode userNode = createNode(
// "userTask1",
// NodeTypeEnums.USER_TASK,
// "人工审批",
// 500, 100,
// userConfig
// );
// nodes.add(userNode);
// 脚本任务节点
Map<String, Object> scriptConfig = createNodeConfig("脚本任务", "执行脚本");
scriptConfig.put("script", "process_data.sh");
scriptConfig.put("language", "shell");
WorkflowDefinitionNode scriptNode = createNode(
"scriptTask1",
NodeTypeEnums.SCRIPT_TASK,
"执行脚本",
700, 100,
scriptConfig
);
nodes.add(scriptNode);
// 结束节点
WorkflowDefinitionNode endNode = createNode(
"endEvent1",
NodeTypeEnums.END_EVENT,
"结束",
900, 100,
createNodeConfig("结束节点", "流程结束")
);
nodes.add(endNode);
// 添加连线
edges.add(createEdge("flow1", "startEvent1", "serviceTask1", "开始到服务"));
edges.add(createEdge("flow2", "serviceTask1", "userTask1", "服务到用户"));
edges.add(createEdge("flow3", "userTask1", "scriptTask1", "用户到脚本"));
edges.add(createEdge("flow4", "scriptTask1", "endEvent1", "脚本到结束"));
graph.setNodes(nodes);
graph.setEdges(edges);
return graph;
}
/**
* 生成网关工作流
* 开始 -> 服务任务 -> 排他网关 -> (用户任务A/用户任务B) -> 并行网关 -> (脚本任务A/脚本任务B) -> 结束
*/
public static WorkflowDefinitionGraph generateGatewayWorkflow() {
WorkflowDefinitionGraph graph = new WorkflowDefinitionGraph();
List<WorkflowDefinitionNode> nodes = new ArrayList<>();
List<WorkflowDefinitionEdge> edges = new ArrayList<>();
// 开始节点
WorkflowDefinitionNode startNode = createNode(
"startEvent1",
NodeTypeEnums.START_EVENT,
"开始",
100, 150,
createNodeConfig("开始节点", "启动流程")
);
nodes.add(startNode);
// 服务任务节点
Map<String, Object> serviceConfig = createNodeConfig("服务任务", "获取数据");
serviceConfig.put("url", "http://api.example.com/data");
serviceConfig.put("method", "GET");
// WorkflowDefinitionNode serviceNode = createNode(
// "serviceTask1",
// NodeTypeEnums.SERVICE_TASK,
// "获取数据",
// 250, 150,
// serviceConfig
// );
// nodes.add(serviceNode);
// 排他网关
// WorkflowDefinitionNode exclusiveGateway = createNode(
// "exclusiveGateway1",
// NodeTypeEnums.EXCLUSIVE_GATEWAY,
// "数据路由",
// 400, 150,
// createNodeConfig("排他网关", "根据数据量选择处理方式")
// );
// nodes.add(exclusiveGateway);
// 用户任务A大数据量
Map<String, Object> userConfigA = createNodeConfig("用户任务A", "人工处理");
userConfigA.put("assignee", "expert");
// WorkflowDefinitionNode userNodeA = createNode(
// "userTask1",
// NodeTypeEnums.USER_TASK,
// "人工处理",
// 550, 50,
// userConfigA
// );
// nodes.add(userNodeA);
// 用户任务B小数据量
Map<String, Object> userConfigB = createNodeConfig("用户任务B", "快速处理");
userConfigB.put("assignee", "operator");
// WorkflowDefinitionNode userNodeB = createNode(
// "userTask2",
// NodeTypeEnums.USER_TASK,
// "快速处理",
// 550, 250,
// userConfigB
// );
// nodes.add(userNodeB);
// 并行网关合并
// WorkflowDefinitionNode parallelGateway = createNode(
// "parallelGateway1",
// NodeTypeEnums.PARALLEL_GATEWAY,
// "并行处理",
// 700, 150,
// createNodeConfig("并行网关", "并行处理数据")
// );
// nodes.add(parallelGateway);
// 脚本任务A // 脚本任务A
Map<String, Object> scriptConfigA = createNodeConfig("脚本任务A", "数据分析"); Map<String, Object> scriptConfigA = createNodeConfig("脚本任务A", "数据处理");
scriptConfigA.put("script", "analyze_data.py"); scriptConfigA.put("script", "process_data.sh");
scriptConfigA.put("language", "python"); scriptConfigA.put("language", "shell");
WorkflowDefinitionNode scriptNodeA = createNode( WorkflowDefinitionNode scriptNodeA = createNode(
"scriptTask1", "scriptTask1",
NodeTypeEnums.SCRIPT_TASK, NodeTypeEnums.SCRIPT_TASK,
"数据分析", "数据处理",
850, 50, 300, 100,
scriptConfigA scriptConfigA
); );
nodes.add(scriptNodeA); nodes.add(scriptNodeA);
// 脚本任务B // 脚本任务B
Map<String, Object> scriptConfigB = createNodeConfig("脚本任务B", "生成报告"); Map<String, Object> scriptConfigB = createNodeConfig("脚本任务B", "生成报告");
scriptConfigB.put("script", "generate_report.py"); scriptConfigB.put("script", "generate_report.sh");
scriptConfigB.put("language", "python"); scriptConfigB.put("language", "shell");
WorkflowDefinitionNode scriptNodeB = createNode( WorkflowDefinitionNode scriptNodeB = createNode(
"scriptTask2", "scriptTask2",
NodeTypeEnums.SCRIPT_TASK, NodeTypeEnums.SCRIPT_TASK,
"生成报告", "生成报告",
850, 250, 500, 100,
scriptConfigB scriptConfigB
); );
nodes.add(scriptNodeB); nodes.add(scriptNodeB);
@ -281,22 +139,15 @@ public class WorkflowDefinitionGraph {
"endEvent1", "endEvent1",
NodeTypeEnums.END_EVENT, NodeTypeEnums.END_EVENT,
"结束", "结束",
1000, 150, 700, 100,
createNodeConfig("结束节点", "流程结束") createNodeConfig("结束节点", "流程结束")
); );
nodes.add(endNode); nodes.add(endNode);
// 添加连线 // 添加连线
edges.add(createEdge("flow1", "startEvent1", "serviceTask1", "开始到服务")); edges.add(createEdge("flow1", "startEvent1", "scriptTask1", "开始到处理"));
edges.add(createEdge("flow2", "serviceTask1", "exclusiveGateway1", "服务到网关")); edges.add(createEdge("flow2", "scriptTask1", "scriptTask2", "处理到报告"));
edges.add(createEdge("flow3", "exclusiveGateway1", "userTask1", "大数据量处理", "#{dataSize > 1000}")); edges.add(createEdge("flow3", "scriptTask2", "endEvent1", "报告到结束"));
edges.add(createEdge("flow4", "exclusiveGateway1", "userTask2", "小数据量处理", "#{dataSize <= 1000}"));
edges.add(createEdge("flow5", "userTask1", "parallelGateway1", "处理完成"));
edges.add(createEdge("flow6", "userTask2", "parallelGateway1", "处理完成"));
edges.add(createEdge("flow7", "parallelGateway1", "scriptTask1", "执行分析"));
edges.add(createEdge("flow8", "parallelGateway1", "scriptTask2", "生成报告"));
edges.add(createEdge("flow9", "scriptTask1", "endEvent1", "分析完成"));
edges.add(createEdge("flow10", "scriptTask2", "endEvent1", "报告完成"));
graph.setNodes(nodes); graph.setNodes(nodes);
graph.setEdges(edges); graph.setEdges(edges);
@ -309,7 +160,7 @@ public class WorkflowDefinitionGraph {
private static WorkflowDefinitionNode createNode(String id, NodeTypeEnums type, String name, int x, int y, Map<String, Object> config) { private static WorkflowDefinitionNode createNode(String id, NodeTypeEnums type, String name, int x, int y, Map<String, Object> config) {
WorkflowDefinitionNode node = new WorkflowDefinitionNode(); WorkflowDefinitionNode node = new WorkflowDefinitionNode();
node.setId(id); node.setId(id);
node.setCode(type.getCode()); // 直接使用枚举的code node.setCode(type.getCode());
node.setType(type); node.setType(type);
node.setName(name); node.setName(name);
node.setConfig(config); node.setConfig(config);
@ -322,7 +173,8 @@ public class WorkflowDefinitionGraph {
.setStyle(originalConfig.getStyle().getFill(), .setStyle(originalConfig.getStyle().getFill(),
originalConfig.getStyle().getStroke(), originalConfig.getStyle().getStroke(),
originalConfig.getStyle().getIcon()) originalConfig.getStyle().getIcon())
.configPorts(originalConfig.getPorts().getTypes()); .configPorts(originalConfig.getPorts().getTypes())
.setPosition(x, y);
node.setGraph(nodeGraph); node.setGraph(nodeGraph);
return node; return node;
@ -373,8 +225,6 @@ public class WorkflowDefinitionGraph {
System.out.println(mapper.writerWithDefaultPrettyPrinter().writeValueAsString(generateSimpleWorkflow())); System.out.println(mapper.writerWithDefaultPrettyPrinter().writeValueAsString(generateSimpleWorkflow()));
System.out.println("\n=== 复杂工作流 ==="); System.out.println("\n=== 复杂工作流 ===");
System.out.println(mapper.writerWithDefaultPrettyPrinter().writeValueAsString(generateComplexWorkflow())); System.out.println(mapper.writerWithDefaultPrettyPrinter().writeValueAsString(generateComplexWorkflow()));
System.out.println("\n=== 网关工作流 ===");
System.out.println(mapper.writerWithDefaultPrettyPrinter().writeValueAsString(generateGatewayWorkflow()));
} catch (Exception e) { } catch (Exception e) {
log.error("生成工作流定义失败", e); log.error("生成工作流定义失败", e);
} }

File diff suppressed because one or more lines are too long