Эх сурвалжийг харах

完善迭代节点,读取节点,http节点,代码执行节点

lichunlei 3 сар өмнө
parent
commit
4f8accee93

+ 2 - 2
Common/Function.cs

@@ -949,7 +949,7 @@ namespace Common
             return new string(c);
         }
 
-        public static string PostWebRequest(string postUrl, string paramData, string ContentType = "application/x-www-form-urlencoded")
+        public static string PostWebRequest(string postUrl, string paramData, string Method, string ContentType = "application/x-www-form-urlencoded")
         {
             //return PostWebRequest(postUrl, paramData, new Dictionary<string, string>());
             string ret = string.Empty;
@@ -959,7 +959,7 @@ namespace Common
                 // 设置提交的相关参数 
                 HttpWebRequest request = WebRequest.Create(postUrl) as HttpWebRequest;
                 Encoding myEncoding = Encoding.UTF8;
-                request.Method = "POST";
+                request.Method = Method;
                 request.KeepAlive = false;
                 request.AllowAutoRedirect = true;
                 request.ContentType = ContentType;

+ 33 - 0
Feign/ISource.cs

@@ -0,0 +1,33 @@
+using Common;
+using LitJson;
+using Model.Source;
+
+namespace Feign
+{
+    public class ISource
+    {
+        public static List<DatabaseInfo> getDatabaseInfoListByIds(string dbIdList)
+        {
+            string url = Utils.FeignUrl["omega_source"] + "/v1/omega_source/DatabaseInfo/getDatabaseInfoListByIds?dbIdList=" + dbIdList;
+            string content = Function.GetWebRequest(url);
+            JsonData jsonObj = JsonMapper.ToObject(content);
+            if(jsonObj["status"].ToString() == "1")
+            {
+                return Newtonsoft.Json.JsonConvert.DeserializeObject<List<DatabaseInfo>>(jsonObj["data"].ToJson()) ?? new List<DatabaseInfo>();
+            }
+            return new List<DatabaseInfo>();
+        }
+
+        public static List<DatabaseTable> getDatabaseTableListByIds(string dbTableIdList)
+        {
+            string url = Utils.FeignUrl["omega_source"] + "/v1/omega_source/DatabaseTable/getTableListByIds?ids=" + dbTableIdList;
+            string content = Function.GetWebRequest(url);
+            JsonData jsonObj = JsonMapper.ToObject(content);
+            if(jsonObj["status"].ToString() == "1")
+            {
+                return Newtonsoft.Json.JsonConvert.DeserializeObject<List<DatabaseTable>>(jsonObj["data"].ToJson()) ?? new List<DatabaseTable>();
+            }
+            return new List<DatabaseTable>();
+        }
+    }
+}

+ 0 - 13
Feign/SysDeptFeign.cs

@@ -1,13 +0,0 @@
-using Microsoft.AspNetCore.Mvc;
-using SummerBoot.Feign.Attributes;
-using Vo;
-
-namespace Feign
-{
-    // [FeignClient(Url = "http://localhost:5296")]
-    // public interface SysDeptFeign
-    // {
-    //     [GetMapping("/feign/dept/query")]
-    //     Task<DeptFeignVo> GetDeptInfo([Query] long id);
-    // }
-}

+ 5 - 0
Model/Custom/EdgeList.cs

@@ -58,6 +58,11 @@ namespace Model.Custom
         /// </summary>
         public string nodeId { get; set; } = string.Empty;
 
+        /// <summary>
+        /// 参数属性
+        /// </summary>
+        public string paramAttribute { get; set; } = string.Empty;
+
         /// <summary>
         /// 参数名称
         /// </summary>

+ 1 - 0
OmegaLogic.csproj

@@ -18,6 +18,7 @@
     <PackageReference Include="CSRedisCore" Version="3.8.802" />
     <PackageReference Include="DotNettySocket" Version="1.2.0" />
     <PackageReference Include="IPTools.China" Version="1.6.0" />
+    <PackageReference Include="Jint" Version="4.7.0" />
     <PackageReference Include="LitJson" Version="0.19.0" />
     <PackageReference Include="Mapster" Version="7.4.0" />
     <PackageReference Include="Microsoft.AspNetCore.OpenApi" Version="7.0.15" />

+ 52 - 219
Util/LogicNodeHelper.cs → Util/Logic/LogicDatabaseNodeHelper.cs

@@ -4,67 +4,19 @@ using Model;
 using Model.Custom;
 using Model.Source;
 
-namespace Util
+namespace Util.Logic
 {
-    public class LogicNodeHelper
+    public class LogicDatabaseNodeHelper
     {
-        /// <summary>
-        /// 如果-否则节点
-        /// </summary>
-        /// <param name="node">节点数据</param>
-        /// <param name="paramList">参数列表</param>
-        public static List<bool> ifElse(NodeList node, List<ParamList> paramList)
-        {
-            List<bool> ifElseResult = new List<bool>(); // 如果-否则节点结果
-            JsonData nodeData = node.nodeData;
-            JsonData ifCondition = nodeData["data"]["formData"]["ifelse"]["value"]; // 如果条件
-            int ifIndex = 0; // 如果条件索引
-            foreach (JsonData item in ifCondition)
-            {
-                string conditionExpression = ""; // 条件表达式
-                string logicTag = item["logic"].ToString(); // 逻辑
-                JsonData conditions = item["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 += " || ";
-                            }
-                        }
-                    }
-                }
-                if (conditionExpression.EndsWith(" && ") || conditionExpression.EndsWith(" || "))
-                {
-                    conditionExpression = conditionExpression.Substring(0, conditionExpression.Length - 4);
-                }
-                ifElseResult.Add(Utils.EvaluateBoolean(conditionExpression));
-                ifIndex += 1;
-            }
-            return ifElseResult;
-        }
-
         /// <summary>
         /// 数据库查询节点
         /// </summary>
         /// <param name="node">节点数据</param>
+        /// <param name="dbData">数据库信息</param>
+        /// <param name="tables">数据库表列表</param>
         /// <param name="paramList">参数列表</param>
-        public static void dbQuery(NodeList node, DatabaseInfo dbData, List<DatabaseTable> tables, List<ParamList> paramList)
+        /// <param name="parentNodeParamList">父节点参数列表</param>
+        public static void dbQuery(NodeList node, List<DatabaseInfo> databaseInfos, List<DatabaseTable> tables, List<ParamList> paramList)
         { 
             JsonData nodeData = node.nodeData;
             JsonData dbInfo = nodeData["data"]["formData"]["dbLabel"]["value"]; // 数据库查询信息
@@ -80,11 +32,12 @@ namespace Util
                 queryFieldString += fieldName + ",";
             }
             if(string.IsNullOrEmpty(queryFieldString)) queryFieldString = "*";
+            int dbId = int.Parse(dbInfo["dbId"].ToString()); // 数据库ID
             int dbTableId = int.Parse(dbInfo["dbTableId"].ToString()); // 数据库表ID
             var queryTable = tables.FirstOrDefault(x => x.id == dbTableId);
             if (queryTable != null)
             {
-                string tableName = queryTable.tableName; // 数据库表名
+                string tableName = queryTable.tableName ?? string.Empty; // 数据库表名
                 string sql = "select " + queryFieldString.TrimEnd(',') + " from " + tableName;
                 if (conditions.Count > 0)
                 {
@@ -127,20 +80,31 @@ namespace Util
                 {
                     sql += " limit " + queryLimit;
                 }
-                SqlSugarClient db = initDb(dbData);
+                SqlSugarClient db = initDb(databaseInfos.FirstOrDefault(x => x.id == dbId) ?? new DatabaseInfo());
                 var items = db.Ado.GetDataTable(sql);
                 if (items.Rows.Count > 0)
                 { 
                     foreach (JsonData field in queryField)
                     {
                         string fieldName = field["label"].ToString(); // 字段名
-                        paramList.Add(new ParamList()
+                        if (nodeData.ToJson().Contains("\"parentNode\""))
+                        { 
+                            var parentParam = paramList.FirstOrDefault(x => x.paramName == fieldName && x.paramAttribute == "iterationInputField");
+                            if(parentParam != null)
+                            {
+                                parentParam.paramValue = items.Rows[0][fieldName]?.ToString() ?? string.Empty;
+                            }
+                        }
+                        else
                         {
-                            nodeId = node.nodeId,
-                            paramName = fieldName,
-                            paramValue = items.Rows[0][fieldName].ToString(),
-                            paramType = field["type"][0].ToString(),
-                        });
+                            paramList.Add(new ParamList()
+                            {
+                                nodeId = node.nodeId,
+                                paramName = fieldName,
+                                paramValue = items.Rows[0][fieldName]?.ToString() ?? string.Empty,
+                                paramType = field["type"][0].ToString(),
+                            });
+                        }
                     }
                 }
             }
@@ -150,38 +114,52 @@ namespace Util
         /// 数据库SQL查询节点
         /// </summary>
         /// <param name="node">节点数据</param>
+        /// <param name="dbData">数据库信息</param>
         /// <param name="paramList">参数列表</param>
-        public static void dbSqlQuery(NodeList node, DatabaseInfo dbData, List<ParamList> paramList)
+        /// <param name="parentNodeParamList">父节点参数列表</param>
+        public static void dbSqlQuery(NodeList node, List<DatabaseInfo> databaseInfos, List<ParamList> paramList)
         { 
             JsonData nodeData = node.nodeData;
             JsonData dbInfo = nodeData["data"]["formData"]["dbLabel"]["value"]; // 数据库查询信息
             JsonData queryField = nodeData["data"]["formData"]["output"]["value"]; // 查询字段
             string sql = nodeData["data"]["formData"]["sql"]["value"]["code"]["content"].ToString(); // SQL查询语句
-            SqlSugarClient db = initDb(dbData);
+            int dbId = int.Parse(dbInfo["dbId"].ToString()); // 数据库ID
+            SqlSugarClient db = initDb(databaseInfos.FirstOrDefault(x => x.id == dbId) ?? new DatabaseInfo());
             var items = db.Ado.GetDataTable(sql);
             if (items.Rows.Count > 0)
             {  
                 foreach (JsonData field in queryField)
                 {
                     string fieldName = field["label"].ToString(); // 字段名
-                    paramList.Add(new ParamList()
+                    if (nodeData.ToJson().Contains("\"parentNode\""))
+                    { 
+                        var parentParam = paramList.FirstOrDefault(x => x.paramName == fieldName && x.paramAttribute == "iterationInputField");
+                        if(parentParam != null)
+                        {
+                            parentParam.paramValue = items.Rows[0][fieldName]?.ToString() ?? string.Empty;
+                        }
+                    }
+                    else
                     {
-                        nodeId = node.nodeId,
-                        paramName = fieldName,
-                        paramValue = items.Rows[0][fieldName].ToString(),
-                        paramType = field["type"][0].ToString(),
-                    });
+                        paramList.Add(new ParamList()
+                        {
+                            nodeId = node.nodeId,
+                            paramName = fieldName,
+                            paramValue = items.Rows[0][fieldName]?.ToString() ?? string.Empty,
+                            paramType = field["type"][0].ToString(),
+                        });
+                    }
                 }
             }
         }
 
         public static SqlSugarClient initDb(DatabaseInfo dbInfo)
         {
-            string server = dbInfo.hostAddress;
+            string server = dbInfo.hostAddress ?? string.Empty;
             int port = dbInfo.port;
-            string user = dbInfo.username;
-            string password = dbInfo.pwd;
-            string database = dbInfo.dbName;
+            string user = dbInfo.username ?? string.Empty;
+            string password = dbInfo.pwd ?? string.Empty;
+            string database = dbInfo.dbName ?? string.Empty;
             DbType dbType = DbType.MySql;
             var db = new SqlSugarClient(new ConnectionConfig()
             {
@@ -192,151 +170,6 @@ namespace Util
             return db;
         }
 
-        /// <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 "Contains('" + param.paramValue + "', '" + paramValue + "')";
-            }
-            else if (oper == "not_contains") //不包含
-            {
-                return "!Contains('" + param.paramValue + "', '" + paramValue + "')";
-            }
-            else if (oper == "starts_with") //以...开头
-            {
-                return "StartsWith('" + param.paramValue + "', '" + paramValue + "')";
-            }
-            else if (oper == "ends_with") //以...结尾
-            {
-                return "EndsWith('" + param.paramValue + "', '" + paramValue + "')";
-            }
-            else if (oper == "matches_regex") //匹配正则表达式
-            {
-                return "Match('" + param.paramValue + "', '" + paramValue + "')";
-            }
-            else if (oper == "not_matches_regex") //不匹配正则表达式
-            {
-                return "!Match('" + param.paramValue + "', '" + 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 "In('" + param.paramValue + "', '" + paramValue + "')";
-            }
-            else if (oper == "not_in") //不在...中
-            {
-                return "!In('" + param.paramValue + "', '" + paramValue + "')";
-            }
-            else if (oper == "array_contains") //数组包含
-            {
-                return "In('" + param.paramValue + "', '" + paramValue + "')";
-            }
-            else if (oper == "array_not_contains") //数组不包含 
-            {
-                return "!In('" + param.paramValue + "', '" + paramValue + "')";
-            }
-            else if (oper == "array_length_equal") //数组长度等于
-            {
-                return "ArrayLen('" + param.paramValue + "') == " + paramValue;
-            }
-            else if (oper == "array_length_greater")
-            {
-                return "ArrayLen('" + param.paramValue + "') > " + paramValue;
-            }
-            else if (oper == "array_length_less") //数组长度小于
-            {
-                return "ArrayLen('" + param.paramValue + "') < " + paramValue;
-            }
-            else if (oper == "is_true") //为真
-            {
-                return param.paramValue + " == true";
-            }
-            else if (oper == "is_false") //为假
-            {
-                return param.paramValue + " == false";
-            }
-            else if (oper == "date_equal") //日期等于
-            {
-                return "'" + param.paramValue + "' == '" + paramValue + "'";
-            }
-            else if (oper == "date_before") //日期之前
-            {
-                return "'" + param.paramValue + "' < '" + paramValue + "'";
-            }
-            else if (oper == "date_after") //日期之后
-            {
-                return "'" + param.paramValue + "' > '" + paramValue + "'";
-            }
-            else if (oper == "date_between") //日期之间
-            {
-                string[] betweenValues = paramValue.Split(" - ", StringSplitOptions.None);
-                return "'" + param.paramValue + "' >= '" + betweenValues[0] + "' && '" + param.paramValue + "' <= '" + betweenValues[1] + "'";
-            }
-            return "";
-        }
-    
         /// <summary>
         /// 运算符转换(SQL)
         /// </summary>

+ 60 - 6
Util/LogicHelper.cs → Util/Logic/LogicHelper.cs

@@ -1,9 +1,12 @@
-using Infrastructure;
+using System.Text.RegularExpressions;
+using Feign;
+using Infrastructure;
 using LitJson;
 using Model.Custom;
+using Model.Source;
 using Services;
 
-namespace Util
+namespace Util.Logic
 {
     public class LogicHelper
     {
@@ -20,7 +23,7 @@ namespace Util
             {
                 return;
             }
-            string jsonData = logicProject.setData;
+            string jsonData = logicProject.setData ?? string.Empty;
             if(string.IsNullOrEmpty(jsonData))
             {
                 return;
@@ -72,8 +75,27 @@ namespace Util
                 paramList.Add(paramListObj);
             }
 
+            //获取数据库信息
+            var matches = Regex.Matches(jsonData, "\"dbId\":.*");
+            string dbIdList = string.Empty;
+            foreach(Match match in matches)
+            {
+                dbIdList += match.Value.Replace(" ", "").Replace("\"dbId\":", "").Replace("\"", "") + ",";
+            }
+            dbIdList = dbIdList.TrimEnd(',');
+            List<DatabaseInfo> databaseInfos = ISource.getDatabaseInfoListByIds(dbIdList);
+            // 获取数据库表信息
+            var tableMatches = Regex.Matches(jsonData, "\"dbTableId\":.*");
+            string dbTableIdList = string.Empty;
+            foreach(Match match in tableMatches)
+            {
+                dbTableIdList += match.Value.Replace(" ", "").Replace("\"dbTableId\":", "").Replace("\"", "") + ",";
+            }
+            dbTableIdList = dbTableIdList.TrimEnd(',');
+            List<DatabaseTable> tables = ISource.getDatabaseTableListByIds(dbTableIdList);
+
             // 从起始节点开始
-            sortEdge(edgeList, nodeList, paramList, startNodeId);
+            sortEdge(databaseInfos, tables, edgeList, nodeList, paramList, startNodeId);
         }
 
         /// <summary>
@@ -81,7 +103,7 @@ namespace Util
         /// </summary>
         /// <param name="edgeList">边列表</param>
         /// <param name="startNodeId">起始节点ID</param>
-        public static void sortEdge(List<EdgeList> edgeList, List<NodeList> nodeList, List<ParamList> paramList, string startNodeId)
+        public static void sortEdge(List<DatabaseInfo> databaseInfos, List<DatabaseTable> tables, List<EdgeList> edgeList, List<NodeList> nodeList, List<ParamList> paramList, string startNodeId)
         {
             foreach(EdgeList item in edgeList)
             {
@@ -98,29 +120,61 @@ namespace Util
                                 {
                                     if(result)
                                     {
-                                        sortEdge(edgeList, nodeList, paramList, item.target);
+                                        if (node.nodeData.ToJson().Contains("\"parentNode\""))
+                                        { 
+                                            string pNodeId = node.nodeData["parentNode"]?.ToString() ?? string.Empty;
+                                            sortEdge(databaseInfos, tables, edgeList, nodeList, paramList, pNodeId + "-child-start-node");
+                                        }
+                                        else
+                                        {
+                                            sortEdge(databaseInfos, tables, edgeList, nodeList, paramList, item.target);
+                                        }
                                         break;
                                     }
                                 }
                             }
                             break;                            
                         case "iteration": // 迭代节点
+                            // var iterationParamList = LogicNodeHelper.iteration(node, paramList);
+                            sortEdge(databaseInfos, tables, edgeList, nodeList, paramList, node.nodeId + "-child-start-node");
+                            break;
+                        case "child-start": // 子流程起始节点
+                            var iterationParamList = LogicNodeHelper.iterationChildStart(node, paramList);
+                            sortEdge(databaseInfos, tables, edgeList, nodeList, paramList, item.target);
+                            break;
+                        case "break": // 跳出循环
+                            // LogicNodeHelper.iterationBreak(node, paramList);
+                            // 跳出循环后,继续执行循环后面的节点
+                            string parentNodeId = node.nodeData["parentNode"]?.ToString() ?? string.Empty;
+                            EdgeList breakEdge = edgeList.FirstOrDefault(x => x.source == parentNodeId) ?? new EdgeList();
+                            if(string.IsNullOrEmpty(breakEdge.source))
+                            {
+                                sortEdge(databaseInfos, tables, edgeList, nodeList, paramList, breakEdge.target);
+                            }
                             break;
                         case "loop": // 循环节点
                             break;
                         case "code-execute": // 代码执行节点
+                            LogicNodeHelper.codeExecute(node, paramList);
+                            sortEdge(databaseInfos, tables, edgeList, nodeList, paramList, item.target);
                             break;
                         case "sql-execute": // SQL执行节点
+                            LogicDatabaseNodeHelper.dbSqlQuery(node, databaseInfos, paramList);
+                            sortEdge(databaseInfos, tables, edgeList, nodeList, paramList, item.target);
                             break;
                         case "insert-data": // 插入数据节点
                             break;
                         case "update-data": // 更新数据节点
                             break;
                         case "query-data": // 查询数据节点
+                            LogicDatabaseNodeHelper.dbQuery(node, databaseInfos, tables, paramList);
+                            sortEdge(databaseInfos, tables, edgeList, nodeList, paramList, item.target);
                             break;
                         case "delete-data": // 删除数据节点
                             break;
                         case "http-request": // HTTP请求节点
+                            LogicToolNodeHelper.httpRequest(node, paramList);
+                            sortEdge(databaseInfos, tables, edgeList, nodeList, paramList, item.target);
                             break;
                         default:
                             break;

+ 295 - 0
Util/Logic/LogicNodeHelper.cs

@@ -0,0 +1,295 @@
+using Infrastructure;
+using Jint;
+using LitJson;
+using Model;
+using Model.Custom;
+using Model.Source;
+
+namespace Util.Logic
+{
+    public class LogicNodeHelper
+    {
+        /// <summary>
+        /// 如果-否则节点
+        /// </summary>
+        /// <param name="node">节点数据</param>
+        /// <param name="paramList">参数列表</param>
+        /// <param name="parentNodeParamList">父节点参数列表</param>
+        public static List<bool> ifElse(NodeList node, List<ParamList> paramList)
+        {
+            List<bool> ifElseResult = new List<bool>(); // 如果-否则节点结果
+            JsonData nodeData = node.nodeData;
+            JsonData ifCondition = nodeData["data"]["formData"]["ifelse"]["value"]; // 如果条件
+            int ifIndex = 0; // 如果条件索引
+            foreach (JsonData item in ifCondition)
+            {
+                string conditionExpression = ""; // 条件表达式
+                string logicTag = item["logic"].ToString(); // 逻辑
+                JsonData conditions = item["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 += " || ";
+                            }
+                        }
+                    }
+                }
+                if (conditionExpression.EndsWith(" && ") || conditionExpression.EndsWith(" || "))
+                {
+                    conditionExpression = conditionExpression.Substring(0, conditionExpression.Length - 4);
+                }
+                ifElseResult.Add(Utils.EvaluateBoolean(conditionExpression));
+                ifIndex += 1;
+            }
+            return ifElseResult;
+        }
+
+        /// <summary>
+        /// 迭代节点
+        /// </summary>
+        /// <param name="node">节点数据</param>
+        /// <param name="paramList">参数列表</param>
+        public static List<ParamList> iteration(NodeList node, List<ParamList> paramList)
+        {
+            JsonData nodeData = node.nodeData;
+            string inputField = nodeData["data"]["formData"]["input"]["value"]?.ToString() ?? string.Empty; // 迭代字段
+            inputField = inputField.Substring(inputField.LastIndexOf(".") + 1);
+            ParamList inputFieldParam = paramList.FirstOrDefault(x => x.paramName == inputField) ?? new ParamList(); // 迭代字段值
+            List<ParamList> paramListObj = new List<ParamList>();
+            paramListObj.Add(new ParamList()
+            {
+                nodeId = node.nodeId,
+                paramName = inputFieldParam.paramName,
+                paramType = inputFieldParam.paramType,
+                paramValue = inputFieldParam.paramValue
+            });
+            paramListObj.Add(new ParamList()
+            {
+                nodeId = node.nodeId,
+                paramName = "nodeId",
+                paramType = "string",
+                paramValue = node.nodeId
+            });
+            return paramListObj;
+        }
+        /// <summary>
+        /// 迭代子流程起始节点
+        /// </summary>
+        /// <param name="node"></param>
+        /// <param name="paramList"></param>
+        public static List<ParamList> iterationChildStart(NodeList node, List<ParamList> paramList)
+        { 
+            JsonData nodeData = node.nodeData;
+            string inputField = nodeData["data"]["formData"][node.nodeId]["value"]?.ToString() ?? string.Empty; // 迭代字段
+            inputField = inputField.Substring(inputField.LastIndexOf(".") + 1);
+            ParamList inputFieldParam = paramList.FirstOrDefault(x => x.paramName == inputField) ?? new ParamList(); // 迭代字段值
+            List<ParamList> paramListObj = new List<ParamList>();
+            paramListObj.Add(new ParamList()
+            {
+                nodeId = node.nodeId,
+                paramAttribute = "iterationInputField",
+                paramName = inputFieldParam.paramName,
+                paramType = inputFieldParam.paramType,
+                paramValue = inputFieldParam.paramValue
+            });
+            return paramListObj;
+        }
+        /// <summary>
+        /// 跳出循环节点
+        /// </summary>
+        /// <param name="node"></param>
+        /// <param name="paramList"></param>
+        public static void iterationBreak(NodeList node, List<ParamList> paramList)
+        { 
+
+        }
+
+        /// <summary>
+        /// 代码执行节点
+        /// </summary>
+        /// <param name="node"></param>
+        /// <param name="paramList"></param>
+        public static void codeExecute(NodeList node, List<ParamList> paramList)
+        { 
+            JsonData nodeData = node.nodeData;
+            string code = nodeData["data"]["formData"]["code"]["value"]["code"]["content"].ToString(); // 代码
+            JsonData outputParam = nodeData["data"]["formData"]["output"]["value"]; // 输出参数
+            var engine = new Engine();
+            engine.Execute(code);
+            foreach (JsonData param in outputParam)
+            {
+                string paramName = param["label"].ToString(); // 字段名
+                paramList.Add(new ParamList()
+                {
+                    nodeId = node.nodeId,
+                    paramName = paramName,
+                    paramValue = engine.GetValue(paramName).ToString(),
+                    paramType = param["type"][0].ToString(),
+                });
+            }
+        }
+
+        /// <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 "Contains('" + param.paramValue + "', '" + paramValue + "')";
+            }
+            else if (oper == "not_contains") //不包含
+            {
+                return "!Contains('" + param.paramValue + "', '" + paramValue + "')";
+            }
+            else if (oper == "starts_with") //以...开头
+            {
+                return "StartsWith('" + param.paramValue + "', '" + paramValue + "')";
+            }
+            else if (oper == "ends_with") //以...结尾
+            {
+                return "EndsWith('" + param.paramValue + "', '" + paramValue + "')";
+            }
+            else if (oper == "matches_regex") //匹配正则表达式
+            {
+                return "Match('" + param.paramValue + "', '" + paramValue + "')";
+            }
+            else if (oper == "not_matches_regex") //不匹配正则表达式
+            {
+                return "!Match('" + param.paramValue + "', '" + 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 "In('" + param.paramValue + "', '" + paramValue + "')";
+            }
+            else if (oper == "not_in") //不在...中
+            {
+                return "!In('" + param.paramValue + "', '" + paramValue + "')";
+            }
+            else if (oper == "array_contains") //数组包含
+            {
+                return "In('" + param.paramValue + "', '" + paramValue + "')";
+            }
+            else if (oper == "array_not_contains") //数组不包含 
+            {
+                return "!In('" + param.paramValue + "', '" + paramValue + "')";
+            }
+            else if (oper == "array_length_equal") //数组长度等于
+            {
+                return "ArrayLen('" + param.paramValue + "') == " + paramValue;
+            }
+            else if (oper == "array_length_greater")
+            {
+                return "ArrayLen('" + param.paramValue + "') > " + paramValue;
+            }
+            else if (oper == "array_length_less") //数组长度小于
+            {
+                return "ArrayLen('" + param.paramValue + "') < " + paramValue;
+            }
+            else if (oper == "is_true") //为真
+            {
+                return param.paramValue + " == true";
+            }
+            else if (oper == "is_false") //为假
+            {
+                return param.paramValue + " == false";
+            }
+            else if (oper == "date_equal") //日期等于
+            {
+                return "'" + param.paramValue + "' == '" + paramValue + "'";
+            }
+            else if (oper == "date_before") //日期之前
+            {
+                return "'" + param.paramValue + "' < '" + paramValue + "'";
+            }
+            else if (oper == "date_after") //日期之后
+            {
+                return "'" + param.paramValue + "' > '" + paramValue + "'";
+            }
+            else if (oper == "date_between") //日期之间
+            {
+                string[] betweenValues = paramValue.Split(" - ", StringSplitOptions.None);
+                return "'" + param.paramValue + "' >= '" + betweenValues[0] + "' && '" + param.paramValue + "' <= '" + betweenValues[1] + "'";
+            }
+            return "";
+        }
+    
+    }
+}

+ 91 - 0
Util/Logic/LogicToolNodeHelper.cs

@@ -0,0 +1,91 @@
+using System.Text.RegularExpressions;
+using Common;
+using Infrastructure;
+using LitJson;
+using Model;
+using Model.Custom;
+using Model.Source;
+
+namespace Util.Logic
+{
+    public class LogicToolNodeHelper
+    {
+        /// <summary>
+        /// HTTP请求节点
+        /// </summary>
+        /// <param name="node">节点数据</param>
+        /// <param name="paramList">参数列表</param>
+        public static void httpRequest(NodeList node, List<ParamList> paramList)
+        {
+            JsonData nodeData = node.nodeData;
+            string requestMethod = nodeData["data"]["formData"]["requestMethod"]["value"].ToString(); // HTTP方法
+            string requestUrl = nodeData["data"]["formData"]["requestUrl"]["value"].ToString(); // HTTP请求URL
+            string responseParam = nodeData["data"]["formData"]["output"]["value"].ToString(); // HTTP响应参数
+            string response = ""; // HTTP响应
+            if(requestMethod == "GET") // GET请求
+            {
+                // 处理GET请求参数
+                JsonData requestParams = nodeData["data"]["formData"]["requestParams"]["value"]; // HTTP请求参数
+                // 处理GET请求参数中的参数
+                Dictionary<string, string> requestParamsDict = new Dictionary<string, string>();
+                foreach(JsonData param in requestParams)
+                {
+                    string label = param["label"].ToString();
+                    string value = param["value"].ToString();
+                    if (value.Contains('.'))
+                    {
+                        value = value.Substring(value.LastIndexOf(".") + 1);
+                        var paramData = paramList.FirstOrDefault(x => x.paramName == value);
+                        if (paramData != null)
+                        {
+                            value = paramData.paramValue;
+                        }
+                    }
+                    requestParamsDict.Add(label, value);
+                }
+                response = Function.GetWebRequest( requestUrl + "?value=" + Newtonsoft.Json.JsonConvert.SerializeObject(requestParamsDict)); // 发送GET请求
+            }
+            else if(requestMethod == "POST" || requestMethod == "PUT") // POST/PUT请求
+            {
+                // 处理POST/PUT请求参数
+                string requestBody = nodeData["data"]["formData"]["requestBody"]["value"].ToString(); // HTTP请求体
+                // 处理POST/PUT请求体中的参数
+                MatchCollection matches = Regex.Matches(requestBody, "${.*?}");
+                foreach(Match match in matches)
+                {
+                    string paramName = match.Value.Replace("${", "").Replace("}", "");
+                    var paramData = paramList.FirstOrDefault(x => x.paramName == paramName);
+                    if (paramData != null)
+                    {
+                        requestBody = requestBody.Replace("{" + paramName + "}", paramData.paramValue);
+                    }
+                }
+                response = Function.PostWebRequest( requestUrl, requestBody, requestMethod, "application/json"); // 发送POST/PUT请求
+            }
+            // 处理POST/PUT请求响应
+            JsonData responseJson = JsonMapper.ToObject(response);
+            // 处理POST/PUT请求响应中的参数
+            foreach(JsonData param in responseParam)
+            {
+                string paramName = param["label"].ToString();
+                string paramType = param["type"][0].ToString();
+                JsonData paramValue = responseJson[paramName];
+                ParamList paramListObj = new ParamList();
+                paramListObj.nodeId = node.nodeId;
+                paramListObj.paramName = paramName;
+                paramListObj.paramType = paramType;
+                if(paramType == "object" || paramType == "array")
+                {
+                    paramListObj.paramValue = paramValue.ToJson();
+                }
+                else
+                {
+                    paramListObj.paramValue = paramValue.ToString();
+                }
+                paramList.Add(paramListObj);
+            }
+        }
+
+    
+    }
+}

+ 1 - 0
Util/Utils.cs

@@ -3,6 +3,7 @@ using NCalc;
 
 public class Utils
 {
+    public static Dictionary<string, string> FeignUrl = new Dictionary<string, string>();
     
     #region 打控制台日志
 

+ 91 - 27
node.json

@@ -68,8 +68,8 @@
             "type": "end",
             "initialized": false,
             "position": {
-                "x": 2728.093793103448,
-                "y": 613.056551724138
+                "x": 3032.1285615387983,
+                "y": 584.0086439118434
             },
             "data": {
                 "nodeMeta": {
@@ -483,7 +483,18 @@
                         "label": "输入变量"
                     },
                     "output": {
-                        "value": [],
+                        "value": [
+                            {
+                                "label": "",
+                                "required": false,
+                                "type": [
+                                    "string"
+                                ],
+                                "desc": "",
+                                "defaultVal": null,
+                                "children": []
+                            }
+                        ],
                         "type": "selectOutput",
                         "label": "输出变量",
                         "scope": "nextNodes"
@@ -492,7 +503,7 @@
             },
             "zIndex": 0,
             "style": {
-                "width": "1315.6962923681951px",
+                "width": "1124.08988405629px",
                 "height": "339.0067442198491px"
             },
             "targetPosition": "left",
@@ -617,7 +628,7 @@
                     "output": {
                         "value": [
                             {
-                                "label": "id",
+                                "label": "user_id",
                                 "required": false,
                                 "type": [
                                     "number"
@@ -829,8 +840,8 @@
             "type": "http-request",
             "initialized": false,
             "position": {
-                "x": 2358.093793103448,
-                "y": 384.7893103448276
+                "x": 2571.1117837269417,
+                "y": 295.7090597204574
             },
             "data": {
                 "nodeMeta": {
@@ -911,7 +922,7 @@
                     "output": {
                         "value": [
                             {
-                                "label": "statusCode",
+                                "label": "status",
                                 "type": [
                                     "number"
                                 ],
@@ -919,7 +930,7 @@
                                 "isRef": false
                             },
                             {
-                                "label": "headers",
+                                "label": "msg",
                                 "type": [
                                     "string"
                                 ],
@@ -927,16 +938,17 @@
                                 "isRef": false
                             },
                             {
-                                "label": "body",
+                                "label": "data",
                                 "type": [
-                                    "string"
+                                    "object"
                                 ],
                                 "desc": "响应体",
-                                "isRef": false
+                                "isRef": false,
+                                "value": ""
                             }
                         ],
-                        "type": "outputVar",
-                        "label": "响应结果",
+                        "type": "declareVar",
+                        "label": "输出",
                         "scope": "nextNodes"
                     }
                 }
@@ -983,6 +995,39 @@
                 }
             },
             "zIndex": 0
+        },
+        {
+            "id": "node_mn74w4iq-1858481e3e6r4z4m-node_mnic8n7z-x424f356gl444n",
+            "type": "break",
+            "initialized": false,
+            "position": {
+                "x": 938.03506637078,
+                "y": 159.46262341885748
+            },
+            "data": {
+                "nodeMeta": {
+                    "category": "basic",
+                    "label": "跳出循环",
+                    "icon": "https://api.iconify.design/tabler/arrow-right-circle.svg?color=white",
+                    "iconColor": "#FF4D4F",
+                    "showEditBtn": false,
+                    "showRunBtn": false
+                }
+            },
+            "style": {
+                "minHeight": "auto",
+                "width": "140px"
+            },
+            "extent": {
+                "range": "parent",
+                "padding": [
+                    55,
+                    20,
+                    20
+                ]
+            },
+            "parentNode": "node_mn74w4iq-1858481e3e6r4z4m",
+            "zIndex": 1000
         }
     ],
     "edges": [
@@ -1110,8 +1155,8 @@
             "zIndex": 0,
             "sourceX": 1062.5,
             "sourceY": 455,
-            "targetX": 2725.593793103448,
-            "targetY": 668.056551724138,
+            "targetX": 3029.6285615387983,
+            "targetY": 639.0086439118434,
             "animated": false,
             "style": {
                 "stroke": "",
@@ -1201,10 +1246,10 @@
             "data": {},
             "label": "",
             "zIndex": 0,
-            "sourceX": 2456.580018015895,
+            "sourceX": 2264.970643015895,
             "sourceY": 85.96344827586205,
-            "targetX": 2355.593793103448,
-            "targetY": 439.7893103448276,
+            "targetX": 2568.6117837269417,
+            "targetY": 350.7090597204574,
             "animated": false,
             "style": {
                 "stroke": "",
@@ -1241,10 +1286,10 @@
             "data": {},
             "label": "",
             "zIndex": 0,
-            "sourceX": 2680.593793103448,
-            "sourceY": 439.7893103448276,
-            "targetX": 2725.593793103448,
-            "targetY": 668.056551724138,
+            "sourceX": 2893.6117837269417,
+            "sourceY": 350.7090597204574,
+            "targetX": 3029.6285615387983,
+            "targetY": 639.0086439118434,
             "animated": false,
             "style": {
                 "stroke": "",
@@ -1269,16 +1314,35 @@
                 "stroke": "",
                 "strokeWidth": ""
             }
+        },
+        {
+            "id": "vueflow__edge-node_mn74w4iq-1858481e3e6r4z4m-node_mn74zx0x-4h492v3n2x46l3bcondition-0-node_mn74w4iq-1858481e3e6r4z4m-node_mnic8n7z-x424f356gl444n",
+            "type": "base-edge",
+            "source": "node_mn74w4iq-1858481e3e6r4z4m-node_mn74zx0x-4h492v3n2x46l3b",
+            "target": "node_mn74w4iq-1858481e3e6r4z4m-node_mnic8n7z-x424f356gl444n",
+            "sourceHandle": "condition-0",
+            "data": {},
+            "label": "",
+            "zIndex": 1003,
+            "sourceX": 2028.7661796210302,
+            "sourceY": 66.46344827586205,
+            "targetX": 2073.9198939569874,
+            "targetY": 99.92607169471952,
+            "animated": false,
+            "style": {
+                "stroke": "",
+                "strokeWidth": ""
+            }
         }
     ],
     "position": [
         157,
-        265.8796742610871
+        287.67568300805954
     ],
-    "zoom": 0.5163883091659773,
+    "zoom": 0.4695523966650771,
     "viewport": {
         "x": 157,
-        "y": 265.8796742610871,
-        "zoom": 0.5163883091659773
+        "y": 287.67568300805954,
+        "zoom": 0.4695523966650771
     }
 }