Kaynağa Gözat

ifelse逻辑开发

lichunlei 4 ay önce
ebeveyn
işleme
e761c9a137
6 değiştirilmiş dosya ile 2500 ekleme ve 5 silme
  1. 1 1
      Model/Custom/EdgeList.cs
  2. 1 0
      OmegaLogic.csproj
  3. 1 1
      Util/LogicHelper.cs
  4. 166 2
      Util/LogicNodeHelper.cs
  5. 120 1
      Util/Utils.cs
  6. 2211 0
      工作流文档.md

+ 1 - 1
Model/Custom/EdgeList.cs

@@ -66,6 +66,6 @@ namespace Model.Custom
         /// <summary>
         /// 参数值
         /// </summary>
-        public object paramValue { get; set; } = null;
+        public string paramValue { get; set; } = string.Empty;
     }
 }

+ 1 - 0
OmegaLogic.csproj

@@ -38,6 +38,7 @@
     <PackageReference Include="nacos-sdk-csharp.Extensions.Configuration" Version="1.3.10" />
     <PackageReference Include="nacos-sdk-csharp.IniParser" Version="1.3.10" />
     <PackageReference Include="nacos-sdk-csharp.YamlParser" Version="1.3.10" />
+    <PackageReference Include="NCalc" Version="1.3.8" />
     <PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
     <PackageReference Include="NLog" Version="5.2.8" />
     <PackageReference Include="Npgsql" Version="8.0.3" />

+ 1 - 1
Util/LogicHelper.cs

@@ -63,7 +63,7 @@ namespace Util
                 JsonData item = input[i];
                 string paramName = item["label"].ToString();
                 string paramType = item["type"][0].ToString();
-                object paramValue = item["value"];
+                string paramValue = item["value"].ToString();
                 ParamList paramListObj = new ParamList();
                 paramListObj.paramName = paramName;
                 paramListObj.paramType = paramType;

+ 166 - 2
Util/LogicNodeHelper.cs

@@ -15,17 +15,181 @@ namespace Util
         {
             JsonData nodeData = node.nodeData;
             JsonData ifCondition = nodeData["data"]["formData"]["ifelse"]["value"]; // 如果条件
-            foreach(JsonData item in ifCondition)
+            foreach (JsonData item in ifCondition)
             {
+                string conditionExpression = ""; // 条件表达式
+                string logicTag = item["logic"].ToString(); // 逻辑
                 JsonData conditions = item["conditions"]; // 条件
-                foreach(JsonData condition in conditions)
+                foreach (JsonData condition in conditions)
                 {
                     string oper = condition["operator"].ToString(); // 运算符
                     string value = condition["value"].ToString(); // 值
                     string variable = condition["variable"].ToString(); // 变量
+                    if (variable.Contains(".") && variable.Contains("output"))
+                    {
+                        variable = variable.Substring(variable.LastIndexOf(".") + 1);
+                        var param = paramList.FirstOrDefault(x => x.paramName == variable);
+                        if (param != null)
+                        {
+                            string paramValue = param.paramValue;
+                            string paramType = param.paramType;
+                            conditionExpression += operatorTransfer(param, oper, paramValue);
+                            if (logicTag == "and")
+                            {
+                                conditionExpression += " && ";
+                            }
+                            else if (logicTag == "or")
+                            {
+                                conditionExpression += " || ";
+                            }
+                        }
+                    }
                 }
             }
         }
 
+        /// <summary>
+        /// 运算符转换
+        /// </summary>
+        /// <param name="oper">运算符</param>
+        /// <returns>转换后的运算符</returns>
+        public static string operatorTransfer(ParamList param, string oper, string paramValue)
+        {
+            if (oper == "equal") //等于
+            { 
+                if(param.paramType == "string" || param.paramType == "time")
+                {
+                    return "'" + param.paramValue + "' == '" + paramValue + "'";
+                }
+                return param.paramValue + " == " + paramValue;
+            }
+            else if (oper == "not_equal") //不等于
+            {
+                if(param.paramType == "string" || param.paramType == "time")
+                {
+                    return "'" + param.paramValue + "' != '" + paramValue + "'";
+                }
+                return param.paramValue + " != " + paramValue;
+            }
+            else if (oper == "greater") //大于
+            {
+                return param.paramValue + " > " + paramValue;
+            }
+            else if (oper == "greater_equal") //大于等于
+            {
+                return param.paramValue + " >= " + paramValue;
+            }
+            else if (oper == "less") //小于
+            {
+                return param.paramValue + " < " + paramValue;
+            }
+            else if (oper == "less_equal") //小于等于
+            {
+                return param.paramValue + " <= " + paramValue;
+            }
+            else if (oper == "between") //在之间
+            {
+                string[] betweenValues = paramValue.Split(',');
+                return param.paramValue + " >= " + betweenValues[0] + " && " + param.paramValue + " <= " + betweenValues[1];
+            }
+            else if (oper == "not_between") //不在之间
+            {
+                string[] betweenValues = paramValue.Split(',');
+                return "(" + param.paramValue + " < " + betweenValues[0] + " || " + param.paramValue + " > " + betweenValues[1] + ")";
+            }
+            else if (oper == "contains") //包含
+            {
+                return "'" + param.paramValue + "'.Contains('" + paramValue + "')";
+            }
+            else if (oper == "not_contains") //不包含
+            {
+                return "!'" + param.paramValue + "'.Contains('" + paramValue + "')";
+            }
+            else if (oper == "starts_with") //以...开头
+            {
+                return "'" + param.paramValue + "'.StartsWith('" + paramValue + "')";
+            }
+            else if (oper == "ends_with") //以...结尾
+            {
+                return "'" + param.paramValue + "'.EndsWith('" + paramValue + "')";
+            }
+            else if (oper == "matches_regex") //匹配正则表达式
+            {
+                return "'" + param.paramValue + "'.Match('" + paramValue + "')";
+            }
+            else if (oper == "not_matches_regex") //不匹配正则表达式
+            {
+                return "!" + "'" + param.paramValue + "'.Match('" + paramValue + "')";
+            }
+            else if (oper == "is_empty")
+            {
+                return "IsNullOrEmpty('" + param.paramValue + "')";
+            }
+            else if (oper == "is_not_empty") //不为空
+            {
+                return "!" + "IsNullOrEmpty('" + param.paramValue + "')";
+            }
+            else if (oper == "is_null") //为空
+            {
+                return "('" + param.paramValue + "'=='{}' || '" + param.paramValue + "'=='[]')";
+            }
+            else if (oper == "is_not_null") //不为空
+            {
+                return "('" + param.paramValue + "'!='{}' || '" + param.paramValue + "'!='[]')";
+            }
+            else if (oper == "in") //在...中
+            {
+                return "'" + param.paramValue + "' in '" + paramValue + "'";
+            }
+            else if (oper == "not_in") //不在...中
+            {
+                return "'" + param.paramValue + "' not in '" + paramValue + "'";
+            }
+            else if (oper == "array_contains") //数组包含
+            {
+                return "'" + param.paramValue + "' array_contains '" + paramValue + "'";
+            }
+            else if (oper == "array_not_contains") //数组不包含 
+            {
+                return "'" + param.paramValue + "' array_not_contains '" + paramValue + "'";
+            }
+            else if (oper == "array_length_equal") //数组长度等于
+            {
+                return "'" + param.paramValue + "' array_length_equal " + paramValue;
+            }
+            else if (oper == "array_length_greater")
+            {
+                return "'" + param.paramValue + "' array_length_greater " + paramValue;
+            }
+            else if (oper == "array_length_less") //数组长度小于
+            {
+                return "'" + param.paramValue + "' array_length_less " + paramValue;
+            }
+            else if (oper == "is_true") //为真
+            {
+                return "'" + param.paramValue + "' is true";
+            }
+            else if (oper == "is_false") //为假
+            {
+                return "'" + param.paramValue + "' is false";
+            }
+            else if (oper == "date_equal") //日期等于
+            {
+                return "'" + param.paramValue + "' date_equal '" + paramValue + "'";
+            }
+            else if (oper == "date_before") //日期之前
+            {
+                return "'" + param.paramValue + "' date_before '" + paramValue + "'";
+            }
+            else if (oper == "date_after") //日期之后
+            {
+                return "'" + param.paramValue + "' date_after '" + paramValue + "'";
+            }
+            else if (oper == "date_between") //日期之间
+            {
+                return "'" + param.paramValue + "' date_between '" + paramValue + "'";
+            }
+            return "";
+        }
     }
 }

+ 120 - 1
Util/Utils.cs

@@ -1,4 +1,7 @@
-public class Utils
+using System.Text.RegularExpressions;
+using NCalc;
+
+public class Utils
 {
     
     #region 打控制台日志
@@ -10,5 +13,121 @@
 
     #endregion
 
+    /// <summary>
+    /// 解析布尔表达式,返回 true/false
+    /// 支持的表达式示例:"10 > 5", "a == b", "(1+2) < 10 && 3 != 4", "true || false"
+    /// </summary>
+    /// <param name="booleanExpression">布尔表达式字符串</param>
+    /// <param name="parameters">可选:表达式中的变量参数(如 a=10, b=5)</param>
+    /// <returns>表达式的布尔结果</returns>
+    public static bool EvaluateBoolean(string booleanExpression, Dictionary<string, object> parameters = null)
+    {
+        try
+        {
+            // 创建表达式对象
+            var expr = new Expression(booleanExpression);
+
+            // 2. 【强制绑定】直接绑定函数事件(不抽离,避免绑定失效)
+            expr.EvaluateFunction += OnEvaluateFunction;
+
+            // 注入变量参数(如果有)
+            if (parameters != null && parameters.Count > 0)
+            {
+                foreach (var param in parameters)
+                {
+                    expr.Parameters[param.Key] = param.Value;
+                }
+            }
+
+            // 执行表达式并转换为布尔值
+            var result = expr.Evaluate();
+            return Convert.ToBoolean(result);
+        }
+        catch (Exception ex)
+        {
+            throw new ArgumentException($"布尔表达式解析失败:{booleanExpression},错误:{ex.Message}", ex);
+        }
+    }
+
+    /// <summary>
+    /// 核心函数处理逻辑(直接写,避免任何匹配误差)
+    /// </summary>
+    private static void OnEvaluateFunction(string funcName, FunctionArgs args)
+    {
+        // 注册 Contains 函数(核心新增)
+        if (funcName == "Contains")
+        {
+            if (args.Parameters.Length != 2)
+            {
+                throw new ArgumentException("Contains 必须传入 2 个参数:字符串、子串");
+            }
+            // 安全获取参数(避免 null/空字符串解析问题)
+            var str = args.Parameters[0].Evaluate()?.ToString() ?? string.Empty;
+            var subStr = args.Parameters[1].Evaluate()?.ToString() ?? string.Empty;
+            args.Result = str.Contains(subStr);
+            return;
+        }
+        
+        // 方案1:精准匹配(表达式写 StartsWith 就匹配 StartsWith)
+        if (funcName == "StartsWith")
+        {
+            // 严格校验参数数量
+            if (args.Parameters.Length != 2)
+            {
+                throw new ArgumentException("StartsWith 必须传入 2 个参数:字符串、前缀");
+            }
+            // 安全获取参数值(避免 null)
+            var str = args.Parameters[0].Evaluate()?.ToString() ?? string.Empty;
+            var prefix = args.Parameters[1].Evaluate()?.ToString() ?? string.Empty;
+            // 执行原生 StartsWith
+            args.Result = str.StartsWith(prefix);
+            return;
+        }
+        if (funcName == "EndsWith")
+        {
+            // 严格校验参数数量
+            if (args.Parameters.Length != 2)
+            {
+                throw new ArgumentException("EndsWith 必须传入 2 个参数:字符串、前缀");
+            }
+            // 安全获取参数值(避免 null)
+            var str = args.Parameters[0].Evaluate()?.ToString() ?? string.Empty;
+            var prefix = args.Parameters[1].Evaluate()?.ToString() ?? string.Empty;
+            // 执行原生 EndsWith
+            args.Result = str.EndsWith(prefix);
+            return;
+        }
+
+        // 方案1:精准匹配 IsNullOrEmpty
+        if (funcName == "IsNullOrEmpty")
+        {
+            if (args.Parameters.Length != 1)
+            {
+                throw new ArgumentException("IsNullOrEmpty 必须传入 1 个参数:字符串");
+            }
+            var value = args.Parameters[0].Evaluate()?.ToString();
+            args.Result = string.IsNullOrEmpty(value);
+            return;
+        }
+        
+        if (funcName == "Match")
+        {
+            // 严格校验参数数量
+            if (args.Parameters.Length != 2)
+            {
+                throw new ArgumentException("StartsWith 必须传入 2 个参数:字符串、前缀");
+            }
+            // 安全获取参数值(避免 null)
+            var str = args.Parameters[0].Evaluate()?.ToString() ?? string.Empty;
+            var prefix = args.Parameters[1].Evaluate()?.ToString() ?? string.Empty;
+            // 执行原生 StartsWith
+            args.Result = Regex.IsMatch(str, prefix);
+            return;
+        }
+
+        // 未找到函数时明确报错
+        throw new ArgumentException($"未定义函数:{funcName}");
+    }
+
 
 }

+ 2211 - 0
工作流文档.md

@@ -0,0 +1,2211 @@
+# 工作流数据格式文档
+
+## 1. 概述
+
+本文档说明工作流编辑器导出的 JSON 数据结构,供后端开发人员解析、存储和执行工作流数据时参考。
+
+## 2. 节点分类 (category)
+
+| 值        | 说明       |
+| --------- | ---------- |
+| basic     | 基础节点   |
+| logic     | 逻辑节点   |
+| database  | 数据库节点 |
+| transform | 转换节点   |
+| tool      | 工具节点   |
+
+## 3. 节点菜单的结构
+
+节点菜单用于定义前端可添加的节点列表,供前端渲染节点选择面板使用。
+
+### 3.1 节点分类列表 (categories)
+
+```json
+[
+  { "label": "基础节点", "value": "basic" },
+  { "label": "逻辑节点", "value": "logic" },
+  { "label": "数据库节点", "value": "database" },
+  { "label": "转换节点", "value": "transform" },
+  { "label": "工具节点", "value": "tool" }
+]
+```
+
+### 3.2 添加节点的菜单项结构
+
+每个节点菜单项包含三部分:`node`(节点基础信息)、`handle`(连接点)、`form`(表单配置)。
+
+```json
+{
+  "node": {
+    "type": "节点类型",
+    "data": {
+      "nodeMeta": {
+        "category": "节点分类",
+        "label": "节点显示名称",
+        "icon": "图标URL",
+        "iconColor": "图标背景色",
+        "showEditBtn": true,
+        "showRunBtn": true
+      }
+    }
+  },
+  "handle": [
+    { "type": "source", "position": "right" },
+    { "type": "target", "position": "left" }
+  ],
+  "form": {
+    "fieldName": {
+      "label": "字段标签",
+      "type": "表单类型",
+      "showNodeLabel": true
+    }
+  }
+}
+```
+
+### 3.3 字段说明
+
+#### node 字段
+
+| 字段                      | 类型    | 说明                              |
+| ------------------------- | ------- | --------------------------------- |
+| type                      | string  | 节点类型标识                      |
+| data.nodeMeta.category    | string  | 节点分类                          |
+| data.nodeMeta.label       | string  | 节点显示名称                      |
+| data.nodeMeta.icon        | string  | 图标 URL(建议使用 iconify 格式) |
+| data.nodeMeta.iconColor   | string  | 图标背景色(十六进制)            |
+| data.nodeMeta.showEditBtn | boolean | 是否显示编辑按钮                  |
+| data.nodeMeta.showRunBtn  | boolean | 是否显示运行按钮                  |
+
+#### handle 字段
+
+| 字段     | 类型   | 说明                                            |
+| -------- | ------ | ----------------------------------------------- |
+| type     | string | 连接点类型:`source`(输出)/ `target`(输入)  |
+| position | string | 连接点位置:`left` / `right` / `top` / `bottom` |
+
+#### form 字段
+
+| 字段          | 类型    | 说明                         |
+| ------------- | ------- | ---------------------------- |
+| label         | string  | 表单字段标签                 |
+| type          | string  | 表单类型,见「表单类型列表」 |
+| showNodeLabel | boolean | 是否在节点上显示该字段标签   |
+
+### 3.4 完整节点菜单示例
+
+```json
+{
+  "node": {
+    "type": "http-request",
+    "data": {
+      "nodeMeta": {
+        "category": "tool",
+        "label": "HTTP请求",
+        "icon": "https://api.iconify.design/tabler/world-www.svg?color=white",
+        "iconColor": "#722ED1",
+        "showEditBtn": true,
+        "showRunBtn": true
+      }
+    }
+  },
+  "handle": [
+    { "type": "target", "position": "left" },
+    { "type": "source", "position": "right" }
+  ],
+  "form": {
+    "api": {
+      "label": "请求配置",
+      "type": "api",
+      "showNodeLabel": false
+    },
+    "token": {
+      "label": "认证",
+      "type": "token",
+      "showNodeLabel": false
+    },
+    "body": {
+      "label": "请求体",
+      "type": "requestBody",
+      "showNodeLabel": false
+    },
+    "output": {
+      "label": "输出变量",
+      "type": "outputVar",
+      "showNodeLabel": true
+    }
+  }
+}
+```
+
+---
+
+## 4. 工作流导出数据结构
+
+### 2.1 顶层 JSON 结构
+
+```json
+{
+  "nodes": [], // 节点数组
+  "edges": [], // 边(连线)数组
+  "position": [0, 0], // 视口位置 [x, y]
+  "zoom": 1, // 缩放级别
+  "viewport": {
+    // 视口信息
+    "x": 0,
+    "y": 0,
+    "zoom": 1
+  }
+}
+```
+
+---
+
+## 3. 节点 (nodes)
+
+### 3.1 节点字段说明
+
+| 字段       | 类型    | 必填 | 说明                                          |
+| ---------- | ------- | ---- | --------------------------------------------- |
+| id         | string  | ✅   | 节点唯一标识                                  |
+| type       | string  | ✅   | 节点类型,见「节点类型列表」                  |
+| position   | object  | ✅   | 节点位置 `{ x: number, y: number }`           |
+| data       | object  | ✅   | 节点数据,包含 nodeMeta 和 formData           |
+| parentNode | string  | ❌   | 父节点ID,用于嵌套节点(循环/迭代内的子节点) |
+| deletable  | boolean | ❌   | 是否可删除,默认 true                         |
+| draggable  | boolean | ❌   | 是否可拖动,默认 true                         |
+
+### 3.2 字段 data 的节点元信息 (data.nodeMeta)
+
+| 字段        | 类型    | 必填 | 说明                                          |
+| ----------- | ------- | ---- | --------------------------------------------- |
+| label       | string  | ✅   | 节点显示名称                                  |
+| icon        | string  | ✅   | 图标 URL                                      |
+| iconColor   | string  | ✅   | 图标背景色(十六进制)                        |
+| category    | string  | ✅   | 节点分类:basic/logic/database/transform/tool |
+| showEditBtn | boolean | ❌   | 是否显示编辑按钮                              |
+| showRunBtn  | boolean | ❌   | 是否显示运行按钮                              |
+
+### 3.3 表单数据 (data.formData)
+
+表单数据是一个对象,键的字段名是创建节点时传入的form中的字段名,值为字段配置:
+
+```json
+{
+  "fieldName": {
+    "value": "实际的表单值",
+    "type": "表单类型",
+    "label": "字段标签(可选)"
+  }
+}
+```
+
+### 3.4 节点完整示例
+
+```json
+{
+  "id": "start",
+  "type": "start",
+  "position": { "x": 250, "y": 50 },
+  "deletable": false,
+  "data": {
+    "nodeMeta": {
+      "label": "开始节点",
+      "icon": "https://api.iconify.design/tabler/circle-check.svg?color=white",
+      "iconColor": "#52C41A",
+      "category": "basic",
+      "showEditBtn": false,
+      "showRunBtn": false
+    },
+    "formData": {
+      "input": {
+        "type": "defineVar",
+        "label": "输入变量",
+        "value": [
+          {
+            "label": "userName",
+            "type": ["string"],
+            "required": true,
+            "desc": "用户名",
+            "defaultVal": ""
+          }
+        ]
+      }
+    }
+  }
+}
+```
+
+---
+
+## 4. 边 (edges)
+
+### 4.1 边字段说明
+
+| 字段         | 类型   | 必填 | 说明                     |
+| ------------ | ------ | ---- | ------------------------ |
+| id           | string | ✅   | 边唯一标识               |
+| source       | string | ✅   | 源节点 ID                |
+| target       | string | ✅   | 目标节点 ID              |
+| type         | string | ❌   | 边类型,默认 "base-edge" |
+| sourceHandle | string | ❌   | 源节点连接点 ID          |
+| targetHandle | string | ❌   | 目标节点连接点 ID        |
+
+### 4.2 边完整示例
+
+```json
+{
+  "id": "e-start-end",
+  "source": "start", // 源节点ID
+  "target": "end", // 目标节点ID
+  "type": "base-edge"
+}
+```
+
+---
+
+## 5. 节点类型列表
+
+### 5.1 基础节点
+
+| 类型值      | 说明           |
+| ----------- | -------------- |
+| start       | 开始节点       |
+| end         | 结束节点       |
+| break       | 跳出循环       |
+| comment     | 注释节点       |
+| child_start | 子流程开始节点 |
+| child_end   | 子流程结束节点 |
+
+### 5.2 逻辑节点
+
+| 类型值       | 说明     |
+| ------------ | -------- |
+| ifelse       | 条件分支 |
+| iteration    | 迭代     |
+| loop         | 循环     |
+| code-execute | 代码执行 |
+
+### 5.3 数据库节点
+
+| 类型值      | 说明     |
+| ----------- | -------- |
+| sql-execute | SQL 执行 |
+| insert-data | 插入数据 |
+| update-data | 更新数据 |
+| query-data  | 查询数据 |
+| delete-data | 删除数据 |
+
+### 5.4 转换节点
+
+| 类型值             | 说明     |
+| ------------------ | -------- |
+| template-transform | 模板转换 |
+| document-extractor | 文档提取 |
+
+### 5.5 工具节点
+
+| 类型值         | 说明      |
+| -------------- | --------- |
+| http-request   | HTTP 请求 |
+| list-operation | 列表操作  |
+
+---
+
+## 6. 表单类型与数据格式
+
+### 6.1 可用的表单类型列表
+
+| 类型值       | 说明           |
+| ------------ | -------------- |
+| defineVar    | 定义变量       |
+| declareVar   | 声明变量       |
+| selectVar    | 选择变量       |
+| selectOutput | 选择变量后输出 |
+| outputVar    | 输出变量       |
+| inputTagVar  | 输入标签变量   |
+| selectType   | 选择类型       |
+| ifelse       | 条件分支       |
+| code         | 代码           |
+| token        | 认证令牌       |
+| requestBody  | 请求体         |
+| database     | 数据库         |
+| sort         | 排序           |
+
+### 6.2 表单组件可用的 Props 参数
+
+每个表单组件除了基础的 `label`、`type`、`showNodeLabel` 外,还可以通过 `disposition` 字段传入特定的 props 参数。
+
+#### 6.2.1 defineVar(定义变量)
+
+无额外 props。
+
+#### 6.2.2 declareVar(声明变量)
+
+| Props 参数       | 类型   | 说明                                    |
+| ---------------- | ------ | --------------------------------------- |
+| selectVarOptions | object | 变量选择器的配置,见 selectVar 的 Props |
+
+**示例:**
+
+```json
+{
+  "type": "declareVar",
+  "label": "变量声明",
+  "disposition": {
+    "selectVarOptions": {
+      "allowChildNodeVar": true
+    }
+  }
+}
+```
+
+#### 6.2.3 selectVar(选择变量)
+
+| Props 参数        | 类型             | 说明                             | 默认值 |
+| ----------------- | ---------------- | -------------------------------- | ------ |
+| varTypes          | VariableType[][] | 过滤的变量类型,过滤下拉框的选项 | -      |
+|                   |                  |                                  |        |
+| allowChildNodeVar | boolean          | 是否可以获取子节点导出的变量     | false  |
+
+**示例:**
+
+```json
+{
+  "type": "selectVar",
+  "label": "选择变量",
+  "disposition": {
+    "varTypes": ["array", "object"], // 数组 对象类型
+    "allowChildNodeVar": true
+  }
+}
+```
+
+#### 6.2.4 selectOutput(选择变量后输出)
+
+| Props 参数       | 类型   | 说明                                    |
+| ---------------- | ------ | --------------------------------------- |
+| selectVarOptions | object | 变量选择器的配置,见 selectVar 的 Props |
+
+**示例:**
+
+```json
+{
+  "type": "selectOutput",
+  "label": "输出变量",
+  "disposition": {
+    "selectVarOptions": {
+      "allowChildNodeVar": true
+    }
+  }
+}
+```
+
+#### 6.2.5 outputVar(输出变量)
+
+| Props 参数 | 类型            | 说明         |
+| ---------- | --------------- | ------------ |
+| outputData | VariableModel[] | 输出数据数组 |
+
+#### 6.2.6 inputTagVar(输入标签变量)
+
+| Props 参数       | 类型                 | 说明                                    | 默认值  |
+| ---------------- | -------------------- | --------------------------------------- | ------- |
+| inputType        | 'input'\| 'textarea' | 模式:input 单行,textarea 多行         | 'input' |
+| disabled         | boolean              | 是否禁用                                | false   |
+| placeholder      | string               | 占位符                                  | -       |
+| varTypes         | VariableType[][]     | 过滤的变量类型(继承自 selectVar)      | -       |
+| selectVarOptions | object               | 变量选择器的配置,见 selectVar 的 Props |         |
+
+**示例:**
+
+```json
+{
+  "type": "inputTagVar",
+  "label": "变量标签输入",
+  "disposition": {
+    "inputType": "textarea",
+    "placeholder": "请输入内容,使用 {{变量}} 引用变量",
+    "allowChildNodeVar": true
+  }
+}
+```
+
+#### 6.2.7 selectType(选择类型)
+
+无额外 props(用于选择变量类型的下拉框)。
+
+#### 6.2.8 ifelse(条件分支)
+
+| Props 参数       | 类型   | 说明                                    |
+| ---------------- | ------ | --------------------------------------- |
+| selectVarOptions | object | 变量选择器的配置,见 selectVar 的 Props |
+
+**示例:**
+
+```json
+{
+  "type": "ifelse",
+  "label": "条件分支",
+  "disposition": {
+    "selectVarOptions": {
+      "allowChildNodeVar": true
+    }
+  }
+}
+```
+
+#### 6.2.9 code(代码执行)
+
+| Props 参数      | 类型                                                | 说明                  |
+| --------------- | --------------------------------------------------- | --------------------- |
+| monacoOptions   | editor.IStandaloneEditorConstructionOptions         | Monaco 编辑器配置选项 |
+| languageOptions | Array<'javascript'\| 'python' \| 'jinja2' \| 'sql'> | 可选择的编程语言列表  |
+
+**示例:**
+
+```json
+{
+  "type": "code",
+  "label": "代码",
+  "disposition": {
+    "languageOptions": ["javascript", "python"],
+    "monacoOptions": {
+      "theme": "vs-dark",
+      "minimap": { "enabled": false }
+    }
+  }
+}
+```
+
+#### 6.2.11 token(认证令牌)
+
+无额外 props。
+
+#### 6.2.12 requestBody(请求体)
+
+无额外 props。
+
+#### 6.2.13 database(数据库)
+
+无额外 props。
+
+#### 6.2.14 sort(排序)
+
+无额外 props。
+
+---
+
+### 6.3 各类型表单值的数据格式
+
+表单值的类型是固定为, 其中的label是可选的,label是根据创建节点时的form中的label来的:
+
+```js
+{
+        "label": "输入变量",
+	"type": "defineVar",
+        "value": xxx
+}
+```
+
+#### defineVar / declareVar(变量定义)
+
+表单值的结构:
+
+```json
+{
+  "type": "defineVar", // 表单的类型
+  "label": "输入变量",
+  "value": [
+    {
+      "label": "userName", // 变量名
+      "type": ["string"], // 变量类型
+      "required": true, // 是否必填
+      "desc": "用户名", // 描述
+      "defaultVal": "张三", // 默认值
+      "value": "", // 表单值
+      "isRef": false, // 当前值是否是引用的其他节点的变量
+      "children": [] // 子变量
+    }
+  ]
+}
+```
+
+#### selectVar(变量选择)
+
+表单值的结构:
+
+```json
+{
+  "type": "selectVar",
+  "label": "选择变量",
+  "value": "start::input.userName"
+}
+```
+
+值为变量路径字符串,格式:`节点ID::字段名.变量名.子变量名`
+
+#### ifelse(条件分支)
+
+表单值的结构:
+
+```json
+{
+  "type": "ifelse",
+  "label": "条件",
+  "value": {...}
+}
+```
+
+值为条件组:
+
+```json
+[
+  {
+    "logic": "and", // 且(and))/或(or))
+    "conditions": [
+      {
+        "variable": "start::input.age", // 引用的变量
+        "operator": "greater", //比较符
+        "value": "18", // 比较的值
+        "isRef": false // 比较的值是否是引用的变量
+      },
+      {
+        "variable": "start::input.status",
+        "operator": "equal",
+        "value": "active",
+        "isRef": false
+      }
+    ]
+  }
+]
+```
+
+**条件操作符 (operator) 可选值:**
+
+| 操作符               | 说明             | 适用类型              |
+| -------------------- | ---------------- | --------------------- |
+| equal                | 等于             | 所有类型              |
+| not_equal            | 不等于           | 所有类型              |
+| greater              | 大于             | number                |
+| greater_equal        | 大于等于         | number                |
+| less                 | 小于             | number                |
+| less_equal           | 小于等于         | number                |
+| between              | 介于两值之间     | number                |
+| not_between          | 不在两值之间     | number                |
+| contains             | 包含             | string                |
+| not_contains         | 不包含           | string                |
+| starts_with          | 以...开头        | string                |
+| ends_with            | 以...结尾        | string                |
+| matches_regex        | 正则匹配         | string                |
+| not_matches_regex    | 正则不匹配       | string                |
+| is_empty             | 为空             | string, array, object |
+| is_not_empty         | 不为空           | string, array, object |
+| is_null              | 为 null          | 所有类型              |
+| is_not_null          | 不为 null        | 所有类型              |
+| in                   | 在列表中         | string, number        |
+| not_in               | 不在列表中       | string, number        |
+| array_contains       | 数组包含某元素   | array                 |
+| array_not_contains   | 数组不包含某元素 | array                 |
+| array_length_equal   | 数组长度等于     | array                 |
+| array_length_greater | 数组长度大于     | array                 |
+| array_length_less    | 数组长度小于     | array                 |
+| is_true              | 为真             | boolean               |
+| is_false             | 为假             | boolean               |
+| date_equal           | 日期相等         | time                  |
+| date_before          | 日期早于         | time                  |
+| date_after           | 日期晚于         | time                  |
+| date_between         | 日期介于         | time                  |
+
+**逻辑运算符 (logic) 可选值:**
+
+- `and` - 并且
+- `or` - 或者
+
+#### code(代码执行)
+
+表单值的结构:
+
+```json
+{
+  "type": "code",
+  "label": "代码",
+  "value": {...}
+}
+```
+
+值包含输入变量和代码内容:
+
+```json
+{
+  // 变量类型
+  "inputVar": [
+    {
+      "label": "userName",
+      "type": ["string"],
+      "required": true,
+      "desc": "用户名",
+      "defaultVal": "张三",
+      "value": "",
+      "isRef": false,
+      "children": []
+    }
+  ],
+  "code": {
+    "language": "javascript", // 代码语言
+    "content": "return data.name.toUpperCase();" // 代码
+  }
+}
+```
+
+**支持的语言:** javascript, python, jinja2, sql
+
+#### token(认证令牌)
+
+表单值的结构:
+
+```json
+{
+  "type": "token",
+  "label": "认证",
+  "value": {...}
+}
+```
+
+值包含认证类型和认证数据:
+
+```json
+{
+  "authType": "bearer_token", // 鉴权的类型
+  "authOpen": true, // 是否开启鉴权
+  "authData": {
+    "apiKey": "your-api-key",
+    "header": "Authorization" // 仅自定义类型时可见
+  }
+}
+```
+
+**authType 可选值:**
+
+- `bearer_token` - Bearer Token
+- `custom` - 自定义
+
+#### requestBody(请求体)
+
+表单值的结构:
+
+```json
+{
+  "type": "requestBody",
+  "label": "请求体",
+  "value": {...}
+}
+```
+
+值包含请求体类型和数据:
+
+```json
+{
+  "bodyType": "json",
+  "bodyData": {
+    "json": "{\"name\": \"张三\", \"age\": 25}"
+  }
+}
+```
+
+**bodyType 可选值:**
+
+- `none` - 无
+- `json` - JSON
+- `raw` - 原始文本
+- `formData` - Form Data
+- `xWwwFormUrlencoded` - x-www-form-urlencoded
+- `binary` - 二进制
+
+#### database(数据库)
+
+表单值的结构:
+
+```json
+{
+  "type": "database",
+  "label": "数据库",
+  "value": {...}
+}
+```
+
+值包含数据库和数据表 ID:
+
+```json
+{
+  "dbId": 1, // 数据库ID
+  "dbTableId": 10 // 数据表ID
+}
+```
+
+#### sort(排序)
+
+表单值的结构:{
+
+```json
+{
+  "type": "sort",
+  "label": "排序",
+  "value": [
+    {
+      "variable": "start::input.list",
+      "sort": "asc"
+    }
+  ]
+}
+```
+
+**sort 可选值:**
+
+- `asc` - 升序
+- `desc` - 降序
+
+---
+
+## 7. 变量数据格式
+
+### 7.1 变量字段说明
+
+| 字段       | 类型     | 必填 | 说明                                                                                      |
+| ---------- | -------- | ---- | ----------------------------------------------------------------------------------------- |
+| label      | string   | ✅   | 变量名                                                                                    |
+| type       | string[] | ✅   | 变量类型数组,支持嵌套如 ["array", "string"]                                              |
+| required   | boolean  | ✅   | 是否必填                                                                                  |
+| value      | string   | ❌   | 变量值                                                                                    |
+| isRef      | boolean  | ❌   | 是否引用的其他变量,如果为是则value的值就是这种格式的:“`节点ID::字段名.变量名.子变量名`“ |
+| defaultVal | any      | ❌   | 默认值                                                                                    |
+| desc       | string   | ❌   | 变量描述                                                                                  |
+| children   | array    | ❌   | 子变量(type 为 object或者array 时使用)                                                  |
+
+### 7.2 变量类型枚举值
+
+| 类型值  | 说明   |
+| ------- | ------ |
+| string  | 字符串 |
+| number  | 数字   |
+| boolean | 布尔值 |
+| time    | 时间   |
+| object  | 对象   |
+| array   | 数组   |
+| file    | 文件   |
+
+### 7.3 嵌套变量示例
+
+```json
+{
+  "label": "userList",
+  "type": ["array", "object"], // 数组对象类型
+  "required": true,
+  "desc": "用户列表",
+  "children": [
+    {
+      "label": "name",
+      "type": ["string"],
+      "required": true
+    },
+    {
+      "label": "age",
+      "type": ["number"],
+      "required": false
+    }
+  ]
+}
+```
+
+---
+
+## 8. 示例
+
+### 8.1 简单工作流示例(开始→结束)
+
+```json
+{
+  "nodes": [
+    {
+      "id": "start",
+      "type": "start",
+      "position": { "x": 250, "y": 50 },
+      "deletable": false,
+      "data": {
+        "nodeMeta": {
+          "label": "开始节点",
+          "icon": "https://api.iconify.design/tabler/circle-check.svg?color=white",
+          "iconColor": "#52C41A",
+          "category": "basic"
+        },
+        "formData": {
+          "input": {
+            "type": "defineVar",
+            "label": "输入变量",
+            "value": [
+              {
+                "label": "userId",
+                "type": ["number"],
+                "required": true,
+                "desc": "用户ID"
+              }
+            ]
+          }
+        }
+      }
+    },
+    {
+      "id": "end",
+      "type": "end",
+      "position": { "x": 700, "y": 50 },
+      "deletable": false,
+      "data": {
+        "nodeMeta": {
+          "label": "结束节点",
+          "icon": "https://api.iconify.design/tabler/square-rounded-arrow-down.svg?color=white",
+          "iconColor": "#FA8C16",
+          "category": "basic"
+        },
+        "formData": {
+          "output": {
+            "type": "declareVar",
+            "label": "输出",
+            "value": [
+              {
+                "label": "result",
+                "type": ["string"],
+                "required": true,
+                "value": "start::input.userId",
+                "isRef": true
+              }
+            ]
+          }
+        }
+      }
+    }
+  ],
+  "edges": [
+    {
+      "id": "e-start-end",
+      "source": "start",
+      "target": "end",
+      "type": "base-edge"
+    }
+  ],
+  "position": [0, 0],
+  "zoom": 1,
+  "viewport": { "x": 0, "y": 0, "zoom": 1 }
+}
+```
+
+### 8.2 条件分支工作流示例
+
+```json
+{
+  "nodes": [
+    {
+      "id": "start",
+      "type": "start",
+      "position": { "x": 100, "y": 150 },
+      "data": {
+        "nodeMeta": {
+          "label": "开始",
+          "icon": "https://api.iconify.design/tabler/circle-check.svg?color=white",
+          "iconColor": "#52C41A",
+          "category": "basic"
+        },
+        "formData": {
+          "input": {
+            "type": "defineVar",
+            "value": [
+              {
+                "label": "age",
+                "type": ["number"],
+                "required": true,
+                "desc": "年龄"
+              }
+            ]
+          }
+        }
+      }
+    },
+    {
+      "id": "ifelse_1",
+      "type": "ifelse",
+      "position": { "x": 350, "y": 150 },
+      "data": {
+        "nodeMeta": {
+          "label": "条件分支",
+          "icon": "https://api.iconify.design/tabler/git-branch.svg?color=white",
+          "iconColor": "#1890FF",
+          "category": "logic"
+        },
+        "formData": {
+          "condition": {
+            "type": "ifelse",
+            "value": [
+              {
+                "logic": "and",
+                "conditions": [
+                  {
+                    "variable": "start::input.age",
+                    "operator": "greater_equal",
+                    "value": "18",
+                    "isRef": false
+                  }
+                ]
+              }
+            ]
+          }
+        }
+      }
+    },
+    {
+      "id": "end_adult",
+      "type": "end",
+      "position": { "x": 600, "y": 50 },
+      "data": {
+        "nodeMeta": {
+          "label": "成年人出口",
+          "iconColor": "#FA8C16",
+          "category": "basic"
+        },
+        "formData": {
+          "output": {
+            "type": "declareVar",
+            "value": [
+              { "label": "message", "type": ["string"], "value": "成年人" }
+            ]
+          }
+        }
+      }
+    },
+    {
+      "id": "end_minor",
+      "type": "end",
+      "position": { "x": 600, "y": 250 },
+      "data": {
+        "nodeMeta": {
+          "label": "未成年出口",
+          "iconColor": "#FA8C16",
+          "category": "basic"
+        },
+        "formData": {
+          "output": {
+            "type": "declareVar",
+            "value": [
+              { "label": "message", "type": ["string"], "value": "未成年" }
+            ]
+          }
+        }
+      }
+    }
+  ],
+  "edges": [
+    { "id": "e1", "source": "start", "target": "ifelse_1" },
+    {
+      "id": "e2",
+      "source": "ifelse_1",
+      "target": "end_adult",
+      "sourceHandle": "if"
+    },
+    {
+      "id": "e3",
+      "source": "ifelse_1",
+      "target": "end_minor",
+      "sourceHandle": "else"
+    }
+  ]
+}
+```
+
+### 8.3 HTTP请求工作流示例
+
+```json
+{
+  "nodes": [
+    {
+      "id": "start",
+      "type": "start",
+      "position": { "x": 100, "y": 100 },
+      "data": {
+        "nodeMeta": {
+          "label": "开始",
+          "iconColor": "#52C41A",
+          "category": "basic"
+        },
+        "formData": {
+          "input": {
+            "type": "defineVar",
+            "value": [
+              { "label": "apiUrl", "type": ["string"], "required": true },
+              { "label": "requestData", "type": ["object"], "required": true }
+            ]
+          }
+        }
+      }
+    },
+    {
+      "id": "http_1",
+      "type": "http-request",
+      "position": { "x": 350, "y": 100 },
+      "data": {
+        "nodeMeta": {
+          "label": "发送请求",
+          "iconColor": "#722ED1",
+          "category": "tool"
+        },
+        "formData": {
+          "api": {
+            "type": "api",
+            "value": {
+              "method": "POST",
+              "url": "start::input.apiUrl"
+            }
+          },
+          "token": {
+            "type": "token",
+            "value": {
+              "authType": "bearer_token",
+              "authOpen": true,
+              "authData": {
+                "apiKey": "your-token",
+                "header": "Authorization"
+              }
+            }
+          },
+          "body": {
+            "type": "requestBody",
+            "value": {
+              "bodyType": "json",
+              "bodyData": {
+                "json": "{\"data\": \"{{start::input.requestData}}\"}"
+              }
+            }
+          }
+        }
+      }
+    },
+    {
+      "id": "end",
+      "type": "end",
+      "position": { "x": 600, "y": 100 },
+      "data": {
+        "nodeMeta": {
+          "label": "结束",
+          "iconColor": "#FA8C16",
+          "category": "basic"
+        },
+        "formData": {
+          "output": {
+            "type": "declareVar",
+            "value": [
+              {
+                "label": "response",
+                "type": ["object"],
+                "value": "http_1::output.response",
+                "isRef": true
+              }
+            ]
+          }
+        }
+      }
+    }
+  ],
+  "edges": [
+    { "id": "e1", "source": "start", "target": "http_1" },
+    { "id": "e2", "source": "http_1", "target": "end" }
+  ]
+}
+```
+
+### 8.4 循环工作流示例
+
+```json
+{
+  "nodes": [
+    {
+      "id": "start",
+      "type": "start",
+      "position": { "x": 100, "y": 150 },
+      "data": {
+        "nodeMeta": {
+          "label": "开始",
+          "iconColor": "#52C41A",
+          "category": "basic"
+        },
+        "formData": {
+          "input": {
+            "type": "defineVar",
+            "value": [
+              {
+                "label": "userList",
+                "type": ["array", "object"],
+                "required": true,
+                "children": [
+                  { "label": "id", "type": ["number"] },
+                  { "label": "name", "type": ["string"] }
+                ]
+              }
+            ]
+          }
+        }
+      }
+    },
+    {
+      "id": "loop_1",
+      "type": "loop",
+      "position": { "x": 350, "y": 100 },
+      "data": {
+        "nodeMeta": {
+          "label": "遍历用户",
+          "iconColor": "#13C2C2",
+          "category": "logic"
+        },
+        "formData": {
+          "iterateVar": {
+            "type": "declareVar",
+            "value": {
+              "label": "userList",
+              "type": ["array", "object"],
+              "value": "start::input.userList",
+              "isRef": true
+            }
+          }
+        }
+      }
+    },
+    {
+      "id": "loop_1-child-start-node",
+      "type": "child_start",
+      "position": { "x": 20, "y": 55 },
+      "parentNode": "loop_1",
+      "draggable": false,
+      "deletable": false,
+      "data": {
+        "nodeMeta": {
+          "label": "迭代",
+          "category": "basic"
+        },
+        "formData": {
+          "loop_1-child-start-node": {
+            "type": "defineVar",
+            "value": [
+              { "label": "item", "type": ["object"] },
+              { "label": "index", "type": ["number"] }
+            ]
+          }
+        }
+      }
+    },
+    {
+      "id": "end",
+      "type": "end",
+      "position": { "x": 700, "y": 150 },
+      "data": {
+        "nodeMeta": {
+          "label": "结束",
+          "iconColor": "#FA8C16",
+          "category": "basic"
+        }
+      }
+    }
+  ],
+  "edges": [
+    { "id": "e1", "source": "start", "target": "loop_1" },
+    { "id": "e2", "source": "loop_1", "target": "end" }
+  ]
+}
+```
+
+完整示例
+
+```js
+{
+    "nodes": [
+        {
+            "id": "start",
+            "type": "start",
+            "initialized": false,
+            "position": {
+                "x": 0,
+                "y": 24.5
+            },
+            "data": {
+                "nodeMeta": {
+                    "label": "开始节点",
+                    "icon": "https://api.iconify.design/tabler/circle-check.svg?color=white",
+                    "iconColor": "#52C41A",
+                    "category": "basic",
+                    "showEditBtn": false,
+                    "showRunBtn": false
+                },
+                "formData": {
+                    "input": {
+                        "value": [
+                            {
+                                "label": "userId",
+                                "type": [
+                                    "number"
+                                ],
+                                "required": true,
+                                "desc": "用户ID",
+                                "defaultVal": 1001,
+                                "value": "",
+                                "isRef": false,
+                                "children": [],
+                                "_id": "mkw0kmjt-6d1ny361v57392y"
+                            },
+                            {
+                                "label": "userName",
+                                "type": [
+                                    "string"
+                                ],
+                                "required": true,
+                                "desc": "用户名",
+                                "defaultVal": "张三",
+                                "value": "",
+                                "isRef": false,
+                                "children": [],
+                                "_id": "mkw2nqte-2un14135a51l1p"
+                            },
+                            {
+                                "label": "userList",
+                                "type": [
+                                    "array",
+                                    "object"
+                                ],
+                                "required": true,
+                                "desc": "用户列表",
+                                "defaultVal": null,
+                                "value": "",
+                                "isRef": false,
+                                "children": [
+                                    {
+                                        "label": "id",
+                                        "type": [
+                                            "number"
+                                        ],
+                                        "required": true
+                                    },
+                                    {
+                                        "label": "name",
+                                        "type": [
+                                            "string"
+                                        ],
+                                        "required": true
+                                    },
+                                    {
+                                        "label": "age",
+                                        "type": [
+                                            "number"
+                                        ],
+                                        "required": false
+                                    }
+                                ]
+                            }
+                        ],
+                        "type": "defineVar",
+                        "label": "输入变量"
+                    }
+                }
+            },
+            "deletable": false,
+            "targetPosition": "left",
+            "sourcePosition": "right"
+        },
+        {
+            "id": "end",
+            "type": "end",
+            "initialized": false,
+            "position": {
+                "x": 3296.532495563284,
+                "y": -45.14859031424661
+            },
+            "data": {
+                "nodeMeta": {
+                    "label": "结束节点",
+                    "icon": "https://api.iconify.design/tabler/square-rounded-arrow-down.svg?color=white",
+                    "iconColor": "#FA8C16",
+                    "category": "basic",
+                    "showEditBtn": false,
+                    "showRunBtn": false
+                },
+                "formData": {
+                    "output": {
+                        "value": [
+                            {
+                                "label": "success",
+                                "type": [
+                                    "boolean"
+                                ],
+                                "required": true,
+                                "value": "true",
+                                "isRef": false
+                            },
+                            {
+                                "label": "report",
+                                "type": [
+                                    "string"
+                                ],
+                                "required": true,
+                                "value": "template_1::output.report",
+                                "isRef": true
+                            },
+                            {
+                                "label": "sortedOrders",
+                                "type": [
+                                    "array",
+                                    "object"
+                                ],
+                                "required": true,
+                                "value": "n_mkw0jnaj-635k14z2h1j443::output.orderList",
+                                "isRef": true
+                            }
+                        ],
+                        "type": "declareVar",
+                        "label": "输出"
+                    }
+                }
+            },
+            "deletable": false,
+            "targetPosition": "left",
+            "sourcePosition": "right"
+        },
+        {
+            "id": "n_mkvzyfv9-5x34711p443kx6y",
+            "type": "http-request",
+            "initialized": false,
+            "position": {
+                "x": 370,
+                "y": 24.5
+            },
+            "data": {
+                "nodeMeta": {
+                    "category": "tool",
+                    "label": "HTTP请求-获取用户详情",
+                    "icon": "https://api.iconify.design/tabler/world.svg?color=white",
+                    "iconColor": "#1890FF",
+                    "showEditBtn": true,
+                    "showRunBtn": true
+                },
+                "formData": {
+                    "requestMethod": {
+                        "value": "GET",
+                        "type": "select",
+                        "label": "请求方法"
+                    },
+                    "requestApi": {
+                        "value": "https://api.example.com/users/{{start::input.userId}}\n",
+                        "type": "inputTagVar",
+                        "label": "请求路径"
+                    },
+                    "requestParams": {
+                        "value": [],
+                        "type": "declareVar",
+                        "label": "请求参数"
+                    },
+                    "requestHeaders": {
+                        "value": [],
+                        "type": "declareVar",
+                        "label": "请求头"
+                    },
+                    "token": {
+                        "value": {
+                            "authOpen": true,
+                            "authType": "bearer_token",
+                            "authData": {
+                                "apiKey": "api-key-dwdwaaaa",
+                                "header": ""
+                            }
+                        },
+                        "type": "token",
+                        "label": "鉴权"
+                    },
+                    "requestBody": {
+                        "value": {
+                            "bodyType": "none",
+                            "bodyData": {}
+                        },
+                        "type": "requestBody",
+                        "label": "请求体"
+                    },
+                    "requestTimeout": {
+                        "value": 120,
+                        "type": "number",
+                        "label": "超时时间(秒)"
+                    },
+                    "retryCount": {
+                        "value": 3,
+                        "type": "number",
+                        "label": "重试次数"
+                    },
+                    "output": {
+                        "value": [
+                            {
+                                "label": "statusCode",
+                                "type": [
+                                    "number"
+                                ],
+                                "desc": "状态码",
+                                "isRef": false,
+                                "_id": "mkw08ny4-3k6c3ra3x4s46w"
+                            },
+                            {
+                                "label": "headers",
+                                "type": [
+                                    "string"
+                                ],
+                                "desc": "响应头",
+                                "isRef": false
+                            },
+                            {
+                                "label": "body",
+                                "type": [
+                                    "string"
+                                ],
+                                "desc": "响应体",
+                                "isRef": false,
+                                "_id": "mkw0afak-675vd652g2r622x"
+                            }
+                        ],
+                        "type": "outputVar",
+                        "label": "响应结果"
+                    }
+                }
+            },
+            "zIndex": 0,
+            "targetPosition": "left",
+            "sourcePosition": "right"
+        },
+        {
+            "id": "n_mkw08g7h-4l2x2w3k72k1736",
+            "type": "ifelse",
+            "initialized": false,
+            "position": {
+                "x": 1110,
+                "y": 0
+            },
+            "data": {
+                "nodeMeta": {
+                    "category": "logic",
+                    "label": "条件分支",
+                    "icon": "https://api.iconify.design/tabler/git-branch.svg?color=white",
+                    "iconColor": "#1890FF",
+                    "showEditBtn": true,
+                    "showRunBtn": true
+                },
+                "formData": {
+                    "ifelse": {
+                        "value": [
+                            {
+                                "conditions": [
+                                    {
+                                        "operator": "equal",
+                                        "value": "0",
+                                        "variable": "n_mkvzyfv9-5x34711p443kx6y::output.statusCode",
+                                        "isRef": false
+                                    },
+                                    {
+                                        "operator": "greater_equal",
+                                        "value": "18",
+                                        "variable": "n_mkw0b7xq-6r234k155867484l::output.userAge",
+                                        "isRef": false
+                                    }
+                                ],
+                                "logic": "and",
+                                "_id": "item-1769483756014-0.6851916864427338"
+                            }
+                        ],
+                        "type": "ifelse",
+                        "label": "条件分支"
+                    }
+                }
+            },
+            "zIndex": 0,
+            "targetPosition": "left",
+            "sourcePosition": "right"
+        },
+        {
+            "id": "n_mkw0b7xq-6r234k155867484l",
+            "type": "code-execute",
+            "initialized": false,
+            "position": {
+                "x": 740,
+                "y": 24.5
+            },
+            "data": {
+                "nodeMeta": {
+                    "category": "logic",
+                    "label": "请求结果提取",
+                    "icon": "https://api.iconify.design/tabler/code.svg?color=white",
+                    "iconColor": "#722ED1",
+                    "showEditBtn": true,
+                    "showRunBtn": true
+                },
+                "formData": {
+                    "code": {
+                        "value": {
+                            "code": {
+                                "language": "javascript",
+                                "content": "function main({httpRes}) {\n    return {\n        userAge: JSON.parse(httpRes).age\n    }\n}"
+                            },
+                            "inputVar": [
+                                {
+                                    "label": "httpRes",
+                                    "required": false,
+                                    "value": "n_mkvzyfv9-5x34711p443kx6y::output.body",
+                                    "type": [
+                                        "string"
+                                    ],
+                                    "desc": "",
+                                    "defaultVal": null,
+                                    "children": [],
+                                    "isRef": true
+                                }
+                            ]
+                        },
+                        "type": "code",
+                        "label": "代码"
+                    },
+                    "output": {
+                        "value": [
+                            {
+                                "label": "userAge",
+                                "required": false,
+                                "type": [
+                                    "number"
+                                ],
+                                "desc": "",
+                                "children": [],
+                                "_id": "mkw0cxxp-27b3u1o1j1v106v"
+                            }
+                        ],
+                        "type": "defineVar",
+                        "label": "输出变量"
+                    }
+                }
+            },
+            "zIndex": 0,
+            "targetPosition": "left",
+            "sourcePosition": "right"
+        },
+        {
+            "id": "n_mkw0jnaj-635k14z2h1j443",
+            "type": "query-data",
+            "initialized": false,
+            "position": {
+                "x": 1480,
+                "y": 24.5
+            },
+            "data": {
+                "nodeMeta": {
+                    "category": "database",
+                    "label": "查询数据",
+                    "icon": "https://api.iconify.design/tabler/search.svg?color=white",
+                    "iconColor": "#1890FF",
+                    "showEditBtn": true,
+                    "showRunBtn": true
+                },
+                "formData": {
+                    "dbLabel": {
+                        "value": {
+                            "dbTableId": 3,
+                            "dbId": 2
+                        },
+                        "type": "database",
+                        "label": "数据表"
+                    },
+                    "queryField": {
+                        "value": "n_mkw0jnaj-635k14z2h1j443::injected.field1",
+                        "type": "selectVar",
+                        "label": "查询字段"
+                    },
+                    "ifelse": {
+                        "value": [
+                            {
+                                "conditions": [
+                                    {
+                                        "operator": "equal",
+                                        "value": "start::input.userId",
+                                        "variable": "n_mkw0jnaj-635k14z2h1j443::injected.field1",
+                                        "isRef": true
+                                    }
+                                ],
+                                "logic": "or",
+                                "_id": "item-1769483109616-0.7693237549834577"
+                            }
+                        ],
+                        "type": "ifelse",
+                        "label": "查询条件"
+                    },
+                    "sort": {
+                        "value": [
+                            {
+                                "variable": "n_mkw0jnaj-635k14z2h1j443::injected.field1",
+                                "sort": "asc"
+                            }
+                        ],
+                        "type": "sort",
+                        "label": "排序"
+                    },
+                    "queryLimit": {
+                        "value": 100,
+                        "type": "number",
+                        "label": "查询上限"
+                    },
+                    "output": {
+                        "value": [
+                            {
+                                "label": "orderList",
+                                "required": true,
+                                "type": [
+                                    "array",
+                                    "object"
+                                ],
+                                "desc": "",
+                                "children": [],
+                                "_isExpanded": false,
+                                "_id": "mkw15c3o-512o714f6m2x524o"
+                            }
+                        ],
+                        "type": "defineVar",
+                        "label": "输出"
+                    }
+                }
+            },
+            "zIndex": 0,
+            "targetPosition": "left",
+            "sourcePosition": "right"
+        },
+        {
+            "id": "n_mkw25bhd-4a2x2k4u3s42ed",
+            "type": "code-execute",
+            "initialized": false,
+            "position": {
+                "x": 1850,
+                "y": 24.5
+            },
+            "data": {
+                "nodeMeta": {
+                    "category": "logic",
+                    "label": "代码执行-计算总价",
+                    "icon": "https://api.iconify.design/tabler/code.svg?color=white",
+                    "iconColor": "#722ED1",
+                    "showEditBtn": true,
+                    "showRunBtn": true
+                },
+                "formData": {
+                    "code": {
+                        "value": {
+                            "code": {
+                                "language": "javascript",
+                                "content": "function main({orderList}) {\n  // 计算订单总价\n  const total = orderList.items.reduce((sum, item) => {\n    return sum + item.price * item.quantity\n  }, 0)\n\n  return { calculation: { total, discount: total * 0.1 } }\n}"
+                            },
+                            "inputVar": [
+                                {
+                                    "label": "orderList",
+                                    "required": false,
+                                    "value": "n_mkw0jnaj-635k14z2h1j443::output.orderList",
+                                    "type": [
+                                        "array",
+                                        "object"
+                                    ],
+                                    "desc": "",
+                                    "defaultVal": null,
+                                    "children": [],
+                                    "isRef": true
+                                }
+                            ]
+                        },
+                        "type": "code",
+                        "label": "代码"
+                    },
+                    "output": {
+                        "value": [
+                            {
+                                "label": "calculation",
+                                "required": false,
+                                "type": [
+                                    "array",
+                                    "object"
+                                ],
+                                "desc": "",
+                                "children": [
+                                    {
+                                        "label": "total",
+                                        "required": false,
+                                        "type": [
+                                            "number"
+                                        ],
+                                        "desc": "",
+                                        "children": [],
+                                        "_id": "mkw29459-u3s586lc684043"
+                                    },
+                                    {
+                                        "label": "discount",
+                                        "required": false,
+                                        "type": [
+                                            "number"
+                                        ],
+                                        "desc": "",
+                                        "children": []
+                                    }
+                                ],
+                                "_id": "mkw2oly2-5c2f213d1v93d1t"
+                            }
+                        ],
+                        "type": "defineVar",
+                        "label": "输出变量"
+                    }
+                }
+            },
+            "extent": {
+                "range": "parent",
+                "padding": [
+                    55,
+                    20,
+                    20
+                ]
+            },
+            "zIndex": 0,
+            "targetPosition": "left",
+            "sourcePosition": "right"
+        },
+        {
+            "id": "n_mkw26i1v-4d421nvg3s126y",
+            "type": "update-data",
+            "initialized": false,
+            "position": {
+                "x": 2220,
+                "y": 24.5
+            },
+            "data": {
+                "nodeMeta": {
+                    "category": "database",
+                    "label": "更新数据",
+                    "icon": "https://api.iconify.design/tabler/edit.svg?color=white",
+                    "iconColor": "#1890FF",
+                    "showEditBtn": true,
+                    "showRunBtn": true
+                },
+                "formData": {
+                    "dbLabel": {
+                        "value": {
+                            "dbTableId": 3,
+                            "dbId": 2
+                        },
+                        "type": "database",
+                        "label": "数据表"
+                    },
+                    "ifelse": {
+                        "value": [
+                            {
+                                "conditions": [
+                                    {
+                                        "operator": "equal",
+                                        "value": "start::input.userId",
+                                        "variable": "n_mkw26i1v-4d421nvg3s126y::injected.field1",
+                                        "isRef": true
+                                    }
+                                ],
+                                "logic": "or",
+                                "_id": "item-1769485843409-0.9807798298960236"
+                            }
+                        ],
+                        "type": "ifelse",
+                        "label": "更新条件"
+                    },
+                    "setField": {
+                        "value": [
+                            {
+                                "label": "field2",
+                                "required": false,
+                                "value": "n_mkw25bhd-4a2x2k4u3s42ed::output.calculation.total",
+                                "type": [
+                                    "number"
+                                ],
+                                "desc": "",
+                                "defaultVal": null,
+                                "children": [],
+                                "isRef": true
+                            }
+                        ],
+                        "type": "declareVar",
+                        "label": "设置字段"
+                    },
+                    "output": {
+                        "value": [],
+                        "type": "defineVar",
+                        "label": "输出"
+                    }
+                }
+            },
+            "zIndex": 0,
+            "targetPosition": "left",
+            "sourcePosition": "right"
+        },
+        {
+            "id": "n_mkw2alma-276u484o2j2yy4z",
+            "type": "http-request",
+            "initialized": false,
+            "position": {
+                "x": 2590,
+                "y": 24.5
+            },
+            "data": {
+                "nodeMeta": {
+                    "category": "tool",
+                    "label": "HTTP请求-发送通知",
+                    "icon": "https://api.iconify.design/tabler/world.svg?color=white",
+                    "iconColor": "#1890FF",
+                    "showEditBtn": true,
+                    "showRunBtn": true
+                },
+                "formData": {
+                    "requestMethod": {
+                        "value": "POST",
+                        "type": "select",
+                        "label": "请求方法"
+                    },
+                    "requestApi": {
+                        "value": "https://api.example.com/notify",
+                        "type": "inputTagVar",
+                        "label": "请求路径"
+                    },
+                    "requestParams": {
+                        "value": [],
+                        "type": "declareVar",
+                        "label": "请求参数"
+                    },
+                    "requestHeaders": {
+                        "value": [],
+                        "type": "declareVar",
+                        "label": "请求头"
+                    },
+                    "token": {
+                        "value": {
+                            "authOpen": true,
+                            "authType": "custom",
+                            "authData": {
+                                "apiKey": "custom-token",
+                                "header": "X-API-Key"
+                            }
+                        },
+                        "type": "token",
+                        "label": "鉴权"
+                    },
+                    "requestBody": {
+                        "value": {
+                            "bodyType": "json",
+                            "bodyData": {
+                                "json": "{  \"userId\":\" {{start::input.userId}}\", \"message\": \"你好,{{start::input.userName}}\"}"
+                            }
+                        },
+                        "type": "requestBody",
+                        "label": "请求体"
+                    },
+                    "requestTimeout": {
+                        "value": 120,
+                        "type": "number",
+                        "label": "超时时间(秒)"
+                    },
+                    "retryCount": {
+                        "value": 3,
+                        "type": "number",
+                        "label": "重试次数"
+                    },
+                    "output": {
+                        "value": [
+                            {
+                                "label": "statusCode",
+                                "type": [
+                                    "number"
+                                ],
+                                "desc": "状态码",
+                                "isRef": false
+                            },
+                            {
+                                "label": "headers",
+                                "type": [
+                                    "string"
+                                ],
+                                "desc": "响应头",
+                                "isRef": false
+                            },
+                            {
+                                "label": "body",
+                                "type": [
+                                    "string"
+                                ],
+                                "desc": "响应体",
+                                "isRef": false
+                            }
+                        ],
+                        "type": "outputVar",
+                        "label": "响应结果"
+                    }
+                }
+            },
+            "zIndex": 0,
+            "targetPosition": "left",
+            "sourcePosition": "right"
+        },
+        {
+            "id": "n_mkw2m3r6-15f5c4p19391p54",
+            "type": "template-transform",
+            "initialized": false,
+            "position": {
+                "x": 2938.2913484734813,
+                "y": -55.09838893056755
+            },
+            "data": {
+                "nodeMeta": {
+                    "category": "transform",
+                    "label": "模板转换-生成报告",
+                    "icon": "https://api.iconify.design/tabler/transform.svg?color=white",
+                    "iconColor": "#FA8C16",
+                    "showEditBtn": true,
+                    "showRunBtn": true
+                },
+                "formData": {
+                    "code": {
+                        "value": {
+                            "code": {
+                                "language": "jinja2",
+                                "content": "{% macro main(userName, total) %}\n尊敬的 {{ userName }}:\\n\\n您的订单统计如下: 总金额:{{ total }}\\n\\n感谢您的支持!\n{% endmacro %}"
+                            },
+                            "inputVar": [
+                                {
+                                    "label": "userName",
+                                    "required": false,
+                                    "value": "start::input.userName",
+                                    "type": [
+                                        "string"
+                                    ],
+                                    "desc": "",
+                                    "defaultVal": null,
+                                    "children": [],
+                                    "isRef": true
+                                },
+                                {
+                                    "label": "total",
+                                    "required": false,
+                                    "value": "n_mkw25bhd-4a2x2k4u3s42ed::output.calculation.total",
+                                    "type": [
+                                        "number"
+                                    ],
+                                    "desc": "",
+                                    "defaultVal": null,
+                                    "children": [],
+                                    "isRef": true
+                                }
+                            ]
+                        },
+                        "type": "code",
+                        "label": "代码"
+                    },
+                    "output": {
+                        "value": [
+                            {
+                                "label": "output",
+                                "type": [
+                                    "string"
+                                ],
+                                "desc": "转换结果",
+                                "isRef": false
+                            }
+                        ],
+                        "type": "outputVar",
+                        "label": "输出变量"
+                    }
+                }
+            },
+            "zIndex": 0,
+            "targetPosition": "left",
+            "sourcePosition": "right"
+        }
+    ],
+    "edges": [
+        {
+            "id": "vueflow__edge-start-n_mkvzyfv9-5x34711p443kx6y",
+            "type": "base-edge",
+            "source": "start",
+            "target": "n_mkvzyfv9-5x34711p443kx6y",
+            "data": {},
+            "label": "",
+            "zIndex": 0,
+            "sourceX": 322.5,
+            "sourceY": 79.5,
+            "targetX": 367.5,
+            "targetY": 79.5,
+            "animated": false,
+            "style": {
+                "stroke": "",
+                "strokeWidth": ""
+            }
+        },
+        {
+            "id": "vueflow__edge-n_mkvzyfv9-5x34711p443kx6y-n_mkw0b7xq-6r234k155867484l",
+            "type": "base-edge",
+            "source": "n_mkvzyfv9-5x34711p443kx6y",
+            "target": "n_mkw0b7xq-6r234k155867484l",
+            "data": {},
+            "label": "",
+            "zIndex": 0,
+            "sourceX": 692.5,
+            "sourceY": 79.5,
+            "targetX": 737.5,
+            "targetY": 79.5,
+            "animated": false,
+            "style": {
+                "stroke": "",
+                "strokeWidth": ""
+            }
+        },
+        {
+            "id": "vueflow__edge-n_mkw0b7xq-6r234k155867484l-n_mkw08g7h-4l2x2w3k72k1736",
+            "type": "base-edge",
+            "source": "n_mkw0b7xq-6r234k155867484l",
+            "target": "n_mkw08g7h-4l2x2w3k72k1736",
+            "data": {},
+            "label": "",
+            "zIndex": 0,
+            "sourceX": 1062.5,
+            "sourceY": 79.5,
+            "targetX": 1107.5,
+            "targetY": 79.5,
+            "animated": false,
+            "style": {
+                "stroke": "",
+                "strokeWidth": ""
+            }
+        },
+        {
+            "id": "vueflow__edge-n_mkw08g7h-4l2x2w3k72k1736condition-0-n_mkw0jnaj-635k14z2h1j443",
+            "type": "base-edge",
+            "source": "n_mkw08g7h-4l2x2w3k72k1736",
+            "target": "n_mkw0jnaj-635k14z2h1j443",
+            "sourceHandle": "condition-0",
+            "data": {},
+            "label": "",
+            "zIndex": 0,
+            "sourceX": 1432.5,
+            "sourceY": 74.5,
+            "targetX": 1477.5,
+            "targetY": 79.5,
+            "animated": false,
+            "style": {
+                "stroke": "",
+                "strokeWidth": ""
+            }
+        },
+        {
+            "id": "vueflow__edge-n_mkw0jnaj-635k14z2h1j443-n_mkw25bhd-4a2x2k4u3s42ed",
+            "type": "base-edge",
+            "source": "n_mkw0jnaj-635k14z2h1j443",
+            "target": "n_mkw25bhd-4a2x2k4u3s42ed",
+            "sourceHandle": null,
+            "targetHandle": null,
+            "data": {},
+            "label": "",
+            "zIndex": 0,
+            "sourceX": 1802.5,
+            "sourceY": 79.5,
+            "targetX": 1847.5,
+            "targetY": 79.5,
+            "animated": false,
+            "style": {
+                "stroke": "",
+                "strokeWidth": ""
+            }
+        },
+        {
+            "id": "vueflow__edge-n_mkw25bhd-4a2x2k4u3s42ed-n_mkw26i1v-4d421nvg3s126y",
+            "type": "base-edge",
+            "source": "n_mkw25bhd-4a2x2k4u3s42ed",
+            "target": "n_mkw26i1v-4d421nvg3s126y",
+            "data": {},
+            "label": "",
+            "zIndex": 0,
+            "sourceX": 2172.5,
+            "sourceY": 79.5,
+            "targetX": 2217.5,
+            "targetY": 79.5,
+            "animated": false,
+            "style": {
+                "stroke": "",
+                "strokeWidth": ""
+            }
+        },
+        {
+            "id": "vueflow__edge-n_mkw26i1v-4d421nvg3s126y-n_mkw2alma-276u484o2j2yy4z",
+            "type": "base-edge",
+            "source": "n_mkw26i1v-4d421nvg3s126y",
+            "target": "n_mkw2alma-276u484o2j2yy4z",
+            "data": {},
+            "label": "",
+            "zIndex": 0,
+            "sourceX": 2542.5,
+            "sourceY": 79.5,
+            "targetX": 2587.5,
+            "targetY": 79.5,
+            "animated": false,
+            "style": {
+                "stroke": "",
+                "strokeWidth": ""
+            }
+        },
+        {
+            "id": "vueflow__edge-n_mkw2alma-276u484o2j2yy4z-n_mkw2m3r6-15f5c4p19391p54",
+            "type": "base-edge",
+            "source": "n_mkw2alma-276u484o2j2yy4z",
+            "target": "n_mkw2m3r6-15f5c4p19391p54",
+            "data": {},
+            "label": "",
+            "zIndex": 0,
+            "sourceX": 2912.5,
+            "sourceY": 79.5,
+            "targetX": 2935.7913484734813,
+            "targetY": -0.09838893056755182,
+            "animated": false,
+            "style": {
+                "stroke": "",
+                "strokeWidth": ""
+            }
+        },
+        {
+            "id": "vueflow__edge-n_mkw2m3r6-15f5c4p19391p54-end",
+            "type": "base-edge",
+            "source": "n_mkw2m3r6-15f5c4p19391p54",
+            "target": "end",
+            "sourceHandle": null,
+            "targetHandle": null,
+            "data": {},
+            "label": "",
+            "zIndex": 0,
+            "sourceX": 3260.7913484734813,
+            "sourceY": -0.09838893056755182,
+            "targetX": 3294.032495563284,
+            "targetY": 9.851409685753389,
+            "animated": false,
+            "style": {
+                "stroke": "",
+                "strokeWidth": ""
+            }
+        }
+    ],
+    "position": [
+        -1428.4298232803233,
+        645.310789176316
+    ],
+    "zoom": 0.6906716468595293,
+    "viewport": {
+        "x": -1428.4298232803233,
+        "y": 645.310789176316,
+        "zoom": 0.6906716468595293
+    }
+}
+```
+
+---