From f55b21d5ab052212d6a1539a5b0c4687c09bcc8f Mon Sep 17 00:00:00 2001 From: asp_ly Date: Fri, 13 Dec 2024 20:04:52 +0800 Subject: [PATCH] 1 --- .../workflow/dto/graph/WorkflowNodeGraph.java | 33 ++ .../backend/workflow/enums/NodeTypeEnums.java | 12 +- .../util/WorkflowDefinitionGraph.java | 184 +------- .../db/migration/V1.0.1__init_data.sql | 398 +++++++++++++++++- 4 files changed, 439 insertions(+), 188 deletions(-) diff --git a/backend/src/main/java/com/qqchen/deploy/backend/workflow/dto/graph/WorkflowNodeGraph.java b/backend/src/main/java/com/qqchen/deploy/backend/workflow/dto/graph/WorkflowNodeGraph.java index 7481bd9a..15f71d74 100644 --- a/backend/src/main/java/com/qqchen/deploy/backend/workflow/dto/graph/WorkflowNodeGraph.java +++ b/backend/src/main/java/com/qqchen/deploy/backend/workflow/dto/graph/WorkflowNodeGraph.java @@ -24,6 +24,8 @@ public class WorkflowNodeGraph { private Ports ports; + private Position position; + public WorkflowNodeGraph setSize(int width, int height) { this.size = new Size(width, height); return this; @@ -34,6 +36,11 @@ public class WorkflowNodeGraph { return this; } + public WorkflowNodeGraph setPosition(int x, int y) { + this.position = new Position(x, y); + return this; + } + public WorkflowNodeGraph configPorts(List types) { this.ports = new Ports(); Map 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 public static class Style { + private String fill; // 填充颜色 private String stroke; // 边框颜色 @@ -118,6 +146,7 @@ public class WorkflowNodeGraph { /** * 获取端口类型列表 + * * @return 端口类型列表("in"/"out") */ public List getTypes() { @@ -131,6 +160,7 @@ public class WorkflowNodeGraph { @Data public static class PortGroup { private String position; + private PortAttrs attrs; public PortGroup() { @@ -149,8 +179,11 @@ public class WorkflowNodeGraph { @Data public static class PortCircle { + private int r; + private String fill; + private String stroke; public PortCircle() { diff --git a/backend/src/main/java/com/qqchen/deploy/backend/workflow/enums/NodeTypeEnums.java b/backend/src/main/java/com/qqchen/deploy/backend/workflow/enums/NodeTypeEnums.java index 4e2d5726..21c1fc4e 100644 --- a/backend/src/main/java/com/qqchen/deploy/backend/workflow/enums/NodeTypeEnums.java +++ b/backend/src/main/java/com/qqchen/deploy/backend/workflow/enums/NodeTypeEnums.java @@ -52,14 +52,14 @@ public enum NodeTypeEnums { ), SCRIPT_TASK( "SCRIPT_TASK", - "结束节点", + "脚本任务", NodeCategoryEnums.TASK, - "工作流的终点", + "脚本执行任务", new WorkflowNodeGraph() - .setShape("circle") - .setSize(40, 40) - .setStyle("#fff1f0", "#ff4d4f", "stop") - .configPorts(Arrays.asList("in")) + .setShape("rect") + .setSize(120, 60) + .setStyle("#ffffff", "#1890ff", "code") + .configPorts(Arrays.asList("in", "out")) ); // // /** diff --git a/backend/src/main/java/com/qqchen/deploy/backend/workflow/util/WorkflowDefinitionGraph.java b/backend/src/main/java/com/qqchen/deploy/backend/workflow/util/WorkflowDefinitionGraph.java index 8353e406..78d621a6 100644 --- a/backend/src/main/java/com/qqchen/deploy/backend/workflow/util/WorkflowDefinitionGraph.java +++ b/backend/src/main/java/com/qqchen/deploy/backend/workflow/util/WorkflowDefinitionGraph.java @@ -18,8 +18,7 @@ import java.util.Map; * 工作流定义图形生成工具类 * 用于生成示例工作流定义,包括: * 1. 简单工作流:开始 -> 脚本任务 -> 结束 - * 2. 复杂工作流:开始 -> 服务任务 -> 用户任务 -> 脚本任务 -> 结束 - * 3. 网关工作流:开始 -> 服务任务 -> 排他网关 -> (用户任务A/用户任务B) -> 并行网关 -> (脚本任务A/脚本任务B) -> 结束 + * 2. 复杂工作流:开始 -> 脚本任务A -> 脚本任务B -> 结束 */ @Data @Slf4j @@ -90,7 +89,7 @@ public class WorkflowDefinitionGraph { /** * 生成复杂工作流 - * 开始 -> 服务任务 -> 用户任务 -> 脚本任务 -> 结束 + * 开始 -> 脚本任务A -> 脚本任务B -> 结束 */ public static WorkflowDefinitionGraph generateComplexWorkflow() { WorkflowDefinitionGraph graph = new WorkflowDefinitionGraph(); @@ -107,171 +106,30 @@ public class WorkflowDefinitionGraph { ); nodes.add(startNode); - // 服务任务节点 - Map 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 userConfig = createNodeConfig("用户任务", "人工审批"); - userConfig.put("assignee", "admin"); - -// WorkflowDefinitionNode userNode = createNode( -// "userTask1", -// NodeTypeEnums.USER_TASK, -// "人工审批", -// 500, 100, -// userConfig -// ); -// nodes.add(userNode); - - // 脚本任务节点 - Map 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 nodes = new ArrayList<>(); - List edges = new ArrayList<>(); - - // 开始节点 - WorkflowDefinitionNode startNode = createNode( - "startEvent1", - NodeTypeEnums.START_EVENT, - "开始", - 100, 150, - createNodeConfig("开始节点", "启动流程") - ); - nodes.add(startNode); - - // 服务任务节点 - Map 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 userConfigA = createNodeConfig("用户任务A", "人工处理"); - userConfigA.put("assignee", "expert"); - -// WorkflowDefinitionNode userNodeA = createNode( -// "userTask1", -// NodeTypeEnums.USER_TASK, -// "人工处理", -// 550, 50, -// userConfigA -// ); -// nodes.add(userNodeA); - - // 用户任务B(小数据量) - Map 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 - Map scriptConfigA = createNodeConfig("脚本任务A", "数据分析"); - scriptConfigA.put("script", "analyze_data.py"); - scriptConfigA.put("language", "python"); + Map scriptConfigA = createNodeConfig("脚本任务A", "数据处理"); + scriptConfigA.put("script", "process_data.sh"); + scriptConfigA.put("language", "shell"); WorkflowDefinitionNode scriptNodeA = createNode( "scriptTask1", NodeTypeEnums.SCRIPT_TASK, - "数据分析", - 850, 50, + "数据处理", + 300, 100, scriptConfigA ); nodes.add(scriptNodeA); // 脚本任务B Map scriptConfigB = createNodeConfig("脚本任务B", "生成报告"); - scriptConfigB.put("script", "generate_report.py"); - scriptConfigB.put("language", "python"); + scriptConfigB.put("script", "generate_report.sh"); + scriptConfigB.put("language", "shell"); WorkflowDefinitionNode scriptNodeB = createNode( "scriptTask2", NodeTypeEnums.SCRIPT_TASK, "生成报告", - 850, 250, + 500, 100, scriptConfigB ); nodes.add(scriptNodeB); @@ -281,22 +139,15 @@ public class WorkflowDefinitionGraph { "endEvent1", NodeTypeEnums.END_EVENT, "结束", - 1000, 150, + 700, 100, createNodeConfig("结束节点", "流程结束") ); nodes.add(endNode); // 添加连线 - edges.add(createEdge("flow1", "startEvent1", "serviceTask1", "开始到服务")); - edges.add(createEdge("flow2", "serviceTask1", "exclusiveGateway1", "服务到网关")); - edges.add(createEdge("flow3", "exclusiveGateway1", "userTask1", "大数据量处理", "#{dataSize > 1000}")); - 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", "报告完成")); + edges.add(createEdge("flow1", "startEvent1", "scriptTask1", "开始到处理")); + edges.add(createEdge("flow2", "scriptTask1", "scriptTask2", "处理到报告")); + edges.add(createEdge("flow3", "scriptTask2", "endEvent1", "报告到结束")); graph.setNodes(nodes); 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 config) { WorkflowDefinitionNode node = new WorkflowDefinitionNode(); node.setId(id); - node.setCode(type.getCode()); // 直接使用枚举的code + node.setCode(type.getCode()); node.setType(type); node.setName(name); node.setConfig(config); @@ -322,7 +173,8 @@ public class WorkflowDefinitionGraph { .setStyle(originalConfig.getStyle().getFill(), originalConfig.getStyle().getStroke(), originalConfig.getStyle().getIcon()) - .configPorts(originalConfig.getPorts().getTypes()); + .configPorts(originalConfig.getPorts().getTypes()) + .setPosition(x, y); node.setGraph(nodeGraph); return node; @@ -373,8 +225,6 @@ public class WorkflowDefinitionGraph { System.out.println(mapper.writerWithDefaultPrettyPrinter().writeValueAsString(generateSimpleWorkflow())); System.out.println("\n=== 复杂工作流 ==="); System.out.println(mapper.writerWithDefaultPrettyPrinter().writeValueAsString(generateComplexWorkflow())); - System.out.println("\n=== 网关工作流 ==="); - System.out.println(mapper.writerWithDefaultPrettyPrinter().writeValueAsString(generateGatewayWorkflow())); } catch (Exception e) { log.error("生成工作流定义失败", e); } diff --git a/backend/src/main/resources/db/migration/V1.0.1__init_data.sql b/backend/src/main/resources/db/migration/V1.0.1__init_data.sql index 8abfca78..db8f5ccf 100644 --- a/backend/src/main/resources/db/migration/V1.0.1__init_data.sql +++ b/backend/src/main/resources/db/migration/V1.0.1__init_data.sql @@ -170,33 +170,401 @@ INSERT INTO workflow_definition ( ( '简单脚本流程', 'simple_script_flow', 1, '一个包含脚本任务的简单流程', 'test', '{ - "nodes": [{"id":"startEvent1","code":"START_EVENT","type":"START_EVENT","name":"开始","graph":{"shape":"circle","size":{"width":40,"height":40},"style":{"fill":"#e8f7ff","stroke":"#1890ff","icon":"play-circle","iconColor":"#1890ff","strokeWidth":2},"ports":{"groups":{"out":{"position":"right","attrs":{"circle":{"r":4,"fill":"#ffffff","stroke":"#1890ff"}}}},"types":["out"]}},"config":{"name":"开始节点","description":"启动流程"}},{"id":"scriptTask1","code":"SCRIPT_TASK","type":"SCRIPT_TASK","name":"执行脚本","graph":{"shape":"rect","size":{"width":120,"height":60},"style":{"fill":"#ffffff","stroke":"#1890ff","icon":"code","iconColor":"#1890ff","strokeWidth":2},"ports":{"groups":{"in":{"position":"left","attrs":{"circle":{"r":4,"fill":"#ffffff","stroke":"#1890ff"}}},"out":{"position":"right","attrs":{"circle":{"r":4,"fill":"#ffffff","stroke":"#1890ff"}}}},"types":["in","out"]}},"config":{"name":"脚本任务","description":"执行一个简单的Shell脚本","language":"shell","script":"echo ''Hello World''"}},{"id":"endEvent1","code":"END_EVENT","type":"END_EVENT","name":"结束","graph":{"shape":"circle","size":{"width":40,"height":40},"style":{"fill":"#fff1f0","stroke":"#ff4d4f","icon":"stop","iconColor":"#ff4d4f","strokeWidth":2},"ports":{"groups":{"in":{"position":"left","attrs":{"circle":{"r":4,"fill":"#ffffff","stroke":"#1890ff"}}}},"types":["in"]}},"config":{"name":"结束节点","description":"流程结束"}}],"edges":[{"id":"flow1","from":"startEvent1","to":"scriptTask1","name":"开始到脚本","config":{"type":"sequence"},"properties":null},{"id":"flow2","from":"scriptTask1","to":"endEvent1","name":"脚本到结束","config":{"type":"sequence"},"properties":null}]}', + "nodes" : [ { + "id" : "startEvent1", + "code" : "START_EVENT", + "type" : "START_EVENT", + "name" : "开始", + "graph" : { + "shape" : "circle", + "size" : { + "width" : 40, + "height" : 40 + }, + "style" : { + "fill" : "#e8f7ff", + "stroke" : "#1890ff", + "icon" : "play-circle", + "iconColor" : "#1890ff", + "strokeWidth" : 2 + }, + "ports" : { + "groups" : { + "out" : { + "position" : "right", + "attrs" : { + "circle" : { + "r" : 4, + "fill" : "#ffffff", + "stroke" : "#1890ff" + } + } + } + }, + "types" : [ "out" ] + }, + "position" : { + "x" : 100, + "y" : 100 + } + }, + "config" : { + "name" : "开始节点", + "description" : "启动流程" + } + }, { + "id" : "scriptTask1", + "code" : "SCRIPT_TASK", + "type" : "SCRIPT_TASK", + "name" : "执行脚本", + "graph" : { + "shape" : "rect", + "size" : { + "width" : 40, + "height" : 40 + }, + "style" : { + "fill" : "#fff1f0", + "stroke" : "#ff4d4f", + "icon" : "code", + "iconColor" : "#ff4d4f", + "strokeWidth" : 2 + }, + "ports" : { + "groups" : { + "in" : { + "position" : "left", + "attrs" : { + "circle" : { + "r" : 4, + "fill" : "#ffffff", + "stroke" : "#1890ff" + } + } + }, + "out" : { + "position" : "right", + "attrs" : { + "circle" : { + "r" : 4, + "fill" : "#ffffff", + "stroke" : "#1890ff" + } + } + } + }, + "types" : [ "in", "out" ] + }, + "position" : { + "x" : 300, + "y" : 100 + } + }, + "config" : { + "name" : "脚本任务", + "description" : "执行一个简单的Shell脚本", + "language" : "shell", + "script" : "echo ''Hello World''" + } + }, { + "id" : "endEvent1", + "code" : "END_EVENT", + "type" : "END_EVENT", + "name" : "结束", + "graph" : { + "shape" : "circle", + "size" : { + "width" : 40, + "height" : 40 + }, + "style" : { + "fill" : "#fff1f0", + "stroke" : "#ff4d4f", + "icon" : "stop", + "iconColor" : "#ff4d4f", + "strokeWidth" : 2 + }, + "ports" : { + "groups" : { + "in" : { + "position" : "left", + "attrs" : { + "circle" : { + "r" : 4, + "fill" : "#ffffff", + "stroke" : "#1890ff" + } + } + } + }, + "types" : [ "in" ] + }, + "position" : { + "x" : 500, + "y" : 100 + } + }, + "config" : { + "name" : "结束节点", + "description" : "流程结束" + } + } ], + "edges" : [ { + "id" : "flow1", + "from" : "startEvent1", + "to" : "scriptTask1", + "name" : "开始到脚本", + "config" : { + "type" : "sequence" + }, + "properties" : null + }, { + "id" : "flow2", + "from" : "scriptTask1", + "to" : "endEvent1", + "name" : "脚本到结束", + "config" : { + "type" : "sequence" + }, + "properties" : null + } ] +}', '{"formItems":[]}', '["simple","script","test"]', 'DRAFT', TRUE, 'http://www.flowable.org/test', NOW(), NOW(), 1, 1, FALSE ), --- 复杂业务流程:开始 -> 服务任务 -> 用户任务 -> 脚本任务 -> 结束 +-- 复杂业务流程:开始 -> 脚本任务A -> 脚本任务B -> 结束 ( - '复杂业务流程', 'complex_business_flow', 1, '包含多种任务节点的复杂业务流程', 'business', + '复杂业务流程', 'complex_business_flow', 1, '包含多个脚本任务节点的业务流程', 'business', '{ - "nodes": [{"id":"startEvent1","code":"START_EVENT","type":"START_EVENT","name":"开始","graph":{"shape":"circle","size":{"width":40,"height":40},"style":{"fill":"#e8f7ff","stroke":"#1890ff","icon":"play-circle","iconColor":"#1890ff","strokeWidth":2},"ports":{"groups":{"out":{"position":"right","attrs":{"circle":{"r":4,"fill":"#ffffff","stroke":"#1890ff"}}}},"types":["out"]}},"config":{"name":"开始节点","description":"启动流程"}},{"id":"serviceTask1","code":"SERVICE_TASK","type":"SERVICE_TASK","name":"调用服务","graph":{"shape":"rect","size":{"width":120,"height":60},"style":{"fill":"#ffffff","stroke":"#1890ff","icon":"api","iconColor":"#1890ff","strokeWidth":2},"ports":{"groups":{"in":{"position":"left","attrs":{"circle":{"r":4,"fill":"#ffffff","stroke":"#1890ff"}}},"out":{"position":"right","attrs":{"circle":{"r":4,"fill":"#ffffff","stroke":"#1890ff"}}}},"types":["in","out"]}},"config":{"method":"POST","name":"服务任务","description":"调用外部服务","url":"http://api.example.com/service"}},{"id":"userTask1","code":"USER_TASK","type":"USER_TASK","name":"人工审批","graph":{"shape":"rect","size":{"width":120,"height":60},"style":{"fill":"#ffffff","stroke":"#1890ff","icon":"user","iconColor":"#1890ff","strokeWidth":2},"ports":{"groups":{"in":{"position":"left","attrs":{"circle":{"r":4,"fill":"#ffffff","stroke":"#1890ff"}}},"out":{"position":"right","attrs":{"circle":{"r":4,"fill":"#ffffff","stroke":"#1890ff"}}}},"types":["in","out"]}},"config":{"name":"用户任务","description":"人工审批","assignee":"admin"}},{"id":"scriptTask1","code":"SCRIPT_TASK","type":"SCRIPT_TASK","name":"执行脚本","graph":{"shape":"rect","size":{"width":120,"height":60},"style":{"fill":"#ffffff","stroke":"#1890ff","icon":"code","iconColor":"#1890ff","strokeWidth":2},"ports":{"groups":{"in":{"position":"left","attrs":{"circle":{"r":4,"fill":"#ffffff","stroke":"#1890ff"}}},"out":{"position":"right","attrs":{"circle":{"r":4,"fill":"#ffffff","stroke":"#1890ff"}}}},"types":["in","out"]}},"config":{"name":"脚本任务","description":"执行脚本","language":"shell","script":"process_data.sh"}},{"id":"endEvent1","code":"END_EVENT","type":"END_EVENT","name":"结束","graph":{"shape":"circle","size":{"width":40,"height":40},"style":{"fill":"#fff1f0","stroke":"#ff4d4f","icon":"stop","iconColor":"#ff4d4f","strokeWidth":2},"ports":{"groups":{"in":{"position":"left","attrs":{"circle":{"r":4,"fill":"#ffffff","stroke":"#1890ff"}}}},"types":["in"]}},"config":{"name":"结束节点","description":"流程结束"}}],"edges":[{"id":"flow1","from":"startEvent1","to":"serviceTask1","name":"开始到服务","config":{"type":"sequence"},"properties":null},{"id":"flow2","from":"serviceTask1","to":"userTask1","name":"服务到用户","config":{"type":"sequence"},"properties":null},{"id":"flow3","from":"userTask1","to":"scriptTask1","name":"用户到脚本","config":{"type":"sequence"},"properties":null},{"id":"flow4","from":"scriptTask1","to":"endEvent1","name":"脚本到结束","config":{"type":"sequence"},"properties":null}]}', + "nodes" : [ { + "id" : "startEvent1", + "code" : "START_EVENT", + "type" : "START_EVENT", + "name" : "开始", + "graph" : { + "shape" : "circle", + "size" : { + "width" : 40, + "height" : 40 + }, + "style" : { + "fill" : "#e8f7ff", + "stroke" : "#1890ff", + "icon" : "play-circle", + "iconColor" : "#1890ff", + "strokeWidth" : 2 + }, + "ports" : { + "groups" : { + "out" : { + "position" : "right", + "attrs" : { + "circle" : { + "r" : 4, + "fill" : "#ffffff", + "stroke" : "#1890ff" + } + } + } + }, + "types" : [ "out" ] + }, + "position" : { + "x" : 100, + "y" : 100 + } + }, + "config" : { + "name" : "开始节点", + "description" : "启动流程" + } + }, { + "id" : "scriptTask1", + "code" : "SCRIPT_TASK", + "type" : "SCRIPT_TASK", + "name" : "数据处理", + "graph" : { + "shape" : "rect", + "size" : { + "width" : 40, + "height" : 40 + }, + "style" : { + "fill" : "#fff1f0", + "stroke" : "#ff4d4f", + "icon" : "code", + "iconColor" : "#ff4d4f", + "strokeWidth" : 2 + }, + "ports" : { + "groups" : { + "in" : { + "position" : "left", + "attrs" : { + "circle" : { + "r" : 4, + "fill" : "#ffffff", + "stroke" : "#1890ff" + } + } + }, + "out" : { + "position" : "right", + "attrs" : { + "circle" : { + "r" : 4, + "fill" : "#ffffff", + "stroke" : "#1890ff" + } + } + } + }, + "types" : [ "in", "out" ] + }, + "position" : { + "x" : 300, + "y" : 100 + } + }, + "config" : { + "name" : "脚本任务A", + "description" : "数据处理", + "language" : "shell", + "script" : "process_data.sh" + } + }, { + "id" : "scriptTask2", + "code" : "SCRIPT_TASK", + "type" : "SCRIPT_TASK", + "name" : "生成报告", + "graph" : { + "shape" : "rect", + "size" : { + "width" : 40, + "height" : 40 + }, + "style" : { + "fill" : "#fff1f0", + "stroke" : "#ff4d4f", + "icon" : "code", + "iconColor" : "#ff4d4f", + "strokeWidth" : 2 + }, + "ports" : { + "groups" : { + "in" : { + "position" : "left", + "attrs" : { + "circle" : { + "r" : 4, + "fill" : "#ffffff", + "stroke" : "#1890ff" + } + } + }, + "out" : { + "position" : "right", + "attrs" : { + "circle" : { + "r" : 4, + "fill" : "#ffffff", + "stroke" : "#1890ff" + } + } + } + }, + "types" : [ "in", "out" ] + }, + "position" : { + "x" : 500, + "y" : 100 + } + }, + "config" : { + "name" : "脚本任务B", + "description" : "生成报告", + "language" : "shell", + "script" : "generate_report.sh" + } + }, { + "id" : "endEvent1", + "code" : "END_EVENT", + "type" : "END_EVENT", + "name" : "结束", + "graph" : { + "shape" : "circle", + "size" : { + "width" : 40, + "height" : 40 + }, + "style" : { + "fill" : "#fff1f0", + "stroke" : "#ff4d4f", + "icon" : "stop", + "iconColor" : "#ff4d4f", + "strokeWidth" : 2 + }, + "ports" : { + "groups" : { + "in" : { + "position" : "left", + "attrs" : { + "circle" : { + "r" : 4, + "fill" : "#ffffff", + "stroke" : "#1890ff" + } + } + } + }, + "types" : [ "in" ] + }, + "position" : { + "x" : 700, + "y" : 100 + } + }, + "config" : { + "name" : "结束节点", + "description" : "流程结束" + } + } ], + "edges" : [ { + "id" : "flow1", + "from" : "startEvent1", + "to" : "scriptTask1", + "name" : "开始到处理", + "config" : { + "type" : "sequence" + }, + "properties" : null + }, { + "id" : "flow2", + "from" : "scriptTask1", + "to" : "scriptTask2", + "name" : "处理到报告", + "config" : { + "type" : "sequence" + }, + "properties" : null + }, { + "id" : "flow3", + "from" : "scriptTask2", + "to" : "endEvent1", + "name" : "报告到结束", + "config" : { + "type" : "sequence" + }, + "properties" : null + } ] +}', '{"formItems":[{"type":"input","label":"业务参数","name":"businessParam","required":true}]}', '["complex","business","multi-task"]', 'DRAFT', TRUE, 'http://www.flowable.org/test', NOW(), NOW(), 1, 1, FALSE -), - --- 网关工作流:包含排他网关和并行网关的复杂流程 -( - '网关处理流程', 'gateway_process_flow', 1, '包含排他网关和并行网关的数据处理流程', 'gateway', - '{ - "nodes": [{"id":"startEvent1","code":"START_EVENT","type":"START_EVENT","name":"开始","graph":{"shape":"circle","size":{"width":40,"height":40},"style":{"fill":"#e8f7ff","stroke":"#1890ff","icon":"play-circle","iconColor":"#1890ff","strokeWidth":2},"ports":{"groups":{"out":{"position":"right","attrs":{"circle":{"r":4,"fill":"#ffffff","stroke":"#1890ff"}}}},"types":["out"]}},"config":{"name":"开始节点","description":"启动流程"}},{"id":"serviceTask1","code":"SERVICE_TASK","type":"SERVICE_TASK","name":"获取数据","graph":{"shape":"rect","size":{"width":120,"height":60},"style":{"fill":"#ffffff","stroke":"#1890ff","icon":"api","iconColor":"#1890ff","strokeWidth":2},"ports":{"groups":{"in":{"position":"left","attrs":{"circle":{"r":4,"fill":"#ffffff","stroke":"#1890ff"}}},"out":{"position":"right","attrs":{"circle":{"r":4,"fill":"#ffffff","stroke":"#1890ff"}}}},"types":["in","out"]}},"config":{"method":"GET","name":"服务任务","description":"获取数据","url":"http://api.example.com/data"}},{"id":"exclusiveGateway1","code":"EXCLUSIVE_GATEWAY","type":"EXCLUSIVE_GATEWAY","name":"数据路由","graph":{"shape":"diamond","size":{"width":50,"height":50},"style":{"fill":"#fff7e6","stroke":"#faad14","icon":"fork","iconColor":"#faad14","strokeWidth":2},"ports":{"groups":{"in":{"position":"left","attrs":{"circle":{"r":4,"fill":"#ffffff","stroke":"#1890ff"}}},"out":{"position":"right","attrs":{"circle":{"r":4,"fill":"#ffffff","stroke":"#1890ff"}}}},"types":["in","out"]}},"config":{"name":"排他网关","description":"根据数据量选择处理方式"}},{"id":"userTask1","code":"USER_TASK","type":"USER_TASK","name":"人工处理","graph":{"shape":"rect","size":{"width":120,"height":60},"style":{"fill":"#ffffff","stroke":"#1890ff","icon":"user","iconColor":"#1890ff","strokeWidth":2},"ports":{"groups":{"in":{"position":"left","attrs":{"circle":{"r":4,"fill":"#ffffff","stroke":"#1890ff"}}},"out":{"position":"right","attrs":{"circle":{"r":4,"fill":"#ffffff","stroke":"#1890ff"}}}},"types":["in","out"]}},"config":{"name":"用户任务A","description":"人工处理","assignee":"expert"}},{"id":"userTask2","code":"USER_TASK","type":"USER_TASK","name":"快速处理","graph":{"shape":"rect","size":{"width":120,"height":60},"style":{"fill":"#ffffff","stroke":"#1890ff","icon":"user","iconColor":"#1890ff","strokeWidth":2},"ports":{"groups":{"in":{"position":"left","attrs":{"circle":{"r":4,"fill":"#ffffff","stroke":"#1890ff"}}},"out":{"position":"right","attrs":{"circle":{"r":4,"fill":"#ffffff","stroke":"#1890ff"}}}},"types":["in","out"]}},"config":{"name":"用户任务B","description":"快速处理","assignee":"operator"}},{"id":"parallelGateway1","code":"PARALLEL_GATEWAY","type":"PARALLEL_GATEWAY","name":"并行处理","graph":{"shape":"diamond","size":{"width":50,"height":50},"style":{"fill":"#fff7e6","stroke":"#faad14","icon":"branches","iconColor":"#faad14","strokeWidth":2},"ports":{"groups":{"in":{"position":"left","attrs":{"circle":{"r":4,"fill":"#ffffff","stroke":"#1890ff"}}},"out":{"position":"right","attrs":{"circle":{"r":4,"fill":"#ffffff","stroke":"#1890ff"}}}},"types":["in","out"]}},"config":{"name":"并行网关","description":"并行处理数据"}},{"id":"scriptTask1","code":"SCRIPT_TASK","type":"SCRIPT_TASK","name":"数据分析","graph":{"shape":"rect","size":{"width":120,"height":60},"style":{"fill":"#ffffff","stroke":"#1890ff","icon":"code","iconColor":"#1890ff","strokeWidth":2},"ports":{"groups":{"in":{"position":"left","attrs":{"circle":{"r":4,"fill":"#ffffff","stroke":"#1890ff"}}},"out":{"position":"right","attrs":{"circle":{"r":4,"fill":"#ffffff","stroke":"#1890ff"}}}},"types":["in","out"]}},"config":{"name":"脚本任务A","description":"数据分析","language":"python","script":"analyze_data.py"}},{"id":"scriptTask2","code":"SCRIPT_TASK","type":"SCRIPT_TASK","name":"生成报告","graph":{"shape":"rect","size":{"width":120,"height":60},"style":{"fill":"#ffffff","stroke":"#1890ff","icon":"code","iconColor":"#1890ff","strokeWidth":2},"ports":{"groups":{"in":{"position":"left","attrs":{"circle":{"r":4,"fill":"#ffffff","stroke":"#1890ff"}}},"out":{"position":"right","attrs":{"circle":{"r":4,"fill":"#ffffff","stroke":"#1890ff"}}}},"types":["in","out"]}},"config":{"name":"脚本任务B","description":"生成报告","language":"python","script":"generate_report.py"}},{"id":"endEvent1","code":"END_EVENT","type":"END_EVENT","name":"结束","graph":{"shape":"circle","size":{"width":40,"height":40},"style":{"fill":"#fff1f0","stroke":"#ff4d4f","icon":"stop","iconColor":"#ff4d4f","strokeWidth":2},"ports":{"groups":{"in":{"position":"left","attrs":{"circle":{"r":4,"fill":"#ffffff","stroke":"#1890ff"}}}},"types":["in"]}},"config":{"name":"结束节点","description":"流程结束"}}],"edges":[{"id":"flow1","from":"startEvent1","to":"serviceTask1","name":"开始到服务","config":{"type":"sequence"},"properties":null},{"id":"flow2","from":"serviceTask1","to":"exclusiveGateway1","name":"服务到网关","config":{"type":"sequence"},"properties":null},{"id":"flow3","from":"exclusiveGateway1","to":"userTask1","name":"大数据量处理","config":{"condition":"#{dataSize > 1000}","conditionExpression":"#{dataSize > 1000}","type":"sequence"},"properties":null},{"id":"flow4","from":"exclusiveGateway1","to":"userTask2","name":"小数据量处理","config":{"condition":"#{dataSize <= 1000}","conditionExpression":"#{dataSize <= 1000}","type":"sequence"},"properties":null},{"id":"flow5","from":"userTask1","to":"parallelGateway1","name":"处理完成","config":{"type":"sequence"},"properties":null},{"id":"flow6","from":"userTask2","to":"parallelGateway1","name":"处理完成","config":{"type":"sequence"},"properties":null},{"id":"flow7","from":"parallelGateway1","to":"scriptTask1","name":"执行分析","config":{"type":"sequence"},"properties":null},{"id":"flow8","from":"parallelGateway1","to":"scriptTask2","name":"生成报告","config":{"type":"sequence"},"properties":null},{"id":"flow9","from":"scriptTask1","to":"endEvent1","name":"分析完成","config":{"type":"sequence"},"properties":null},{"id":"flow10","from":"scriptTask2","to":"endEvent1","name":"报告完成","config":{"type":"sequence"},"properties":null}]}', - '{"formItems":[{"type":"input","label":"数据大小","name":"dataSize","required":true}]}', - '["gateway","parallel","exclusive"]', - 'DRAFT', TRUE, 'http://www.flowable.org/test', - NOW(), NOW(), 1, 1, FALSE );