| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546 |
- using System.Text.RegularExpressions;
- using Common;
- using Feign;
- using Infrastructure;
- using LitJson;
- using Mapster;
- using Model;
- using Model.Custom;
- using Model.Source;
- using Services;
- namespace Util.Logic
- {
- public class LogicHelper
- {
- /// <summary>
- /// 获取逻辑项目的Json数据
- /// </summary>
- /// <param name="projectId">项目ID</param>
- /// <param name="request">请求参数</param>
- public static Dictionary<string, object> DoLogic(int projectId, string requestId, string env, string request, int nodeKind = 1)
- {
- Dictionary<string, object> result = new Dictionary<string, object>();
- LogicProject logicProject = new LogicProject();
- if (nodeKind == 1)
- {
- var logicProjectService = App.GetService<ILogicProjectService>();
- logicProject = logicProjectService.GetById(projectId);
- }
- else if (nodeKind == 2)
- {
- var testProjectService = App.GetService<ITestProjectService>();
- logicProject = testProjectService.GetById(projectId).Adapt<LogicProject>();
- }
- else if (nodeKind == 3)
- {
- var serverProjectService = App.GetService<IServerProjectService>();
- logicProject = serverProjectService.GetById(projectId).Adapt<LogicProject>();
- }
- if(logicProject == null)
- {
- return new Dictionary<string, object>();
- }
- List<LogItem> logDic = new List<LogItem>();
- try
- {
- // 记录日志
- logDic.Add(new LogItem()
- {
- title = "开始节点" + env,
- param = new Dictionary<string, object>()
- {
- { "请求参数", request },
- { "项目ID", projectId },
- { "请求ID", requestId },
- }
- });
- var logicLogRecordService = App.GetService<ILogicLogRecordService>();
- var logId = logicLogRecordService.addLogicLogRecord(new LogicLogRecord()
- {
- createTime = DateTime.Now,
- requestId = requestId,
- requestParam = request,
- logicProjectName = logicProject.projectName,
- logicId = logicProject.id,
- });
- // var logRecord = logicLogRecordService.getLogicLogRecordQuery(new LogicLogRecord(){ id = logId });
- string jsonData = logicProject.setData ?? string.Empty;
- if(string.IsNullOrEmpty(jsonData))
- {
- return new Dictionary<string, object>();
- }
- JsonData requestObj = JsonMapper.ToObject(request);
- JsonData jsonDataObj = JsonMapper.ToObject(jsonData);
- JsonData nodes = jsonDataObj["nodes"]; // 节点数据
- List<NodeList> nodeList = new List<NodeList>(); // 节点列表
- foreach(JsonData node in nodes)
- {
- JsonData id = node["id"];
- JsonData type = node["type"];
- NodeList nodeListObj = new NodeList();
- nodeListObj.nodeId = id.ToString();
- nodeListObj.nodeType = type.ToString();
- nodeListObj.nodeData = node;
- nodeList.Add(nodeListObj);
- }
- List<EdgeList> edgeList = new List<EdgeList>(); // 边列表
- JsonData edges = jsonDataObj["edges"]; // 边数据
- foreach(JsonData edge in edges)
- {
- JsonData source = edge["source"];
- JsonData target = edge["target"];
- JsonData edgeId = edge["id"];
- EdgeList edgeListObj = new EdgeList();
- edgeListObj.source = source.ToString();
- edgeListObj.target = target.ToString();
- edgeListObj.id = edgeId.ToString();
- edgeListObj.edgeData = edge;
- edgeList.Add(edgeListObj);
- }
- string startNodeId = "start"; // 起始节点ID
- // 获取起始节点数据
- List<ParamList> paramList = new List<ParamList>();
- NodeList startNode = nodeList.FirstOrDefault(x => x.nodeId == startNodeId) ?? new NodeList();
- JsonData nodeData = startNode.nodeData;
- JsonData input = nodeData["data"]["formData"]["input"]["value"];
- for(int i = 0; i < input.Count; i++)
- {
- JsonData item = input[i];
- string paramName = item["label"].ToString();
- string paramType = item["type"][0].ToString();
- string paramValue = requestObj[paramName].ToString();
- ParamList paramListObj = new ParamList();
- paramListObj.nodeId = startNodeId;
- paramListObj.paramName = paramName;
- paramListObj.paramType = paramType;
- paramListObj.paramValue = paramValue;
- paramListObj.paramAttribute = "startinput";
- paramList.Add(paramListObj);
- }
- //获取数据库信息
- List<string> dbIdValues = LitJsonHelper.FindAllValuesByKey(jsonDataObj, "dbId");
- if(dbIdValues.Count > 0) dbIdValues = dbIdValues.Where(m => !string.IsNullOrEmpty(m)).Distinct().ToList();
- List<string> dbTableIdValues = LitJsonHelper.FindAllValuesByKey(jsonDataObj, "dbTableId");
- if(dbTableIdValues.Count > 0) dbTableIdValues = dbTableIdValues.Where(m => !string.IsNullOrEmpty(m)).Distinct().ToList();
- string dbIdList = string.Join(",", dbIdValues);
- List<DatabaseInfo> databaseInfos = ISource.getDatabaseInfoListByIds(dbIdList);
- // 获取数据库表信息
- string dbTableIdList = string.Join(",", dbTableIdValues);
- List<DatabaseTable> tables = ISource.getDatabaseTableListByIds(dbTableIdList);
- // 从起始节点开始
- sortEdge(requestId, databaseInfos, tables, edgeList, nodeList, paramList, startNodeId, new Dictionary<string, int>(), logDic, env);
- // 返回结果
- foreach(ParamList item in paramList.Where(m => m.paramAttribute == "endoutput").ToList())
- {
- result.Add(item.paramName, item.paramValue);
- }
- startNodeId = "end"; // 起始节点ID
- // 获取起始节点数据
- startNode = nodeList.FirstOrDefault(x => x.nodeId == startNodeId) ?? new NodeList();
- nodeData = startNode.nodeData;
- input = nodeData["data"]["formData"]["output"]["value"];
- for(int i = 0; i < input.Count; i++)
- {
- JsonData item = input[i];
- string paramName = item["label"].ToString();
- string paramType = item["type"][0].ToString();
- string paramValue = item["value"].ToString();
- if (paramValue.Contains('.'))
- {
- string nodeId = paramValue.Substring(0, paramValue.IndexOf(":"));
- paramValue = paramValue.Substring(paramValue.LastIndexOf(".") + 1);
- var paramData = paramList.FirstOrDefault(x => x.paramName == paramValue && x.nodeId == nodeId);
- if (paramData != null)
- {
- paramValue = paramData.paramValueTransfer;
- }
- }
- result.Add(paramName, paramValue);
- }
- string logPath = "/logRecord/";
- string logString = JsonMapper.ToJson(logDic);
- logString = UnicodeToChinese(logString);
- Function.WritePage(logPath, requestId + ".json", logString);
- OssHelper.Instance.Upload(Function.getPath(logPath + requestId + ".json"));
- // logRecord.logicLogFilePath = logPath + requestId + ".json";
- // logicLogRecordService.updateLogicLogRecord(logRecord);
- }
- catch(Exception ex)
- {
- RedisServer.Cache.Set("logic_error_" + requestId, ex.ToString());
- RedisServer.Cache.Set("logic_log_" + requestId, JsonMapper.ToJson(logDic));
- // Function.WriteLog(ex.ToString(), "逻辑异常");
- Utils.WriteLog(ex.ToString(), "逻辑异常");
- try
- {
- logDic.Add(new LogItem()
- {
- title = "error",
- detail = ex.ToString(),
- });
- string logPath = "/logRecord/";
- string logString = JsonMapper.ToJson(logDic);
- logString = UnicodeToChinese(logString);
- Function.WritePage(logPath, requestId + ".json", logString);
- OssHelper.Instance.Upload(Function.getPath(logPath + requestId + ".json"));
- } catch
- {
- }
- }
- try
- {
- Task.Run(async () =>
- {
- await Task.Delay(1000);
- // 延迟后执行查询/补偿逻辑
- updateLogPath(requestId, "/logRecord/" + requestId + ".json");
- });
- }
- catch(Exception ex)
- {
- }
- return result;
- }
- public static void updateLogPath(string requestId, string logPath)
- {
- var logicLogRecordService = App.GetService<ILogicLogRecordService>();
- LogicLogRecord logRecord = logicLogRecordService.getLogicLogRecordQuery(requestId);
- logRecord.logicLogFilePath = logPath;
- logicLogRecordService.updateLogicLogRecord(logRecord);
- }
- public static string UnicodeToChinese(string input)
- {
- return Regex.Replace(input, @"\\u([0-9a-fA-F]{4})", m =>
- {
- int code = Convert.ToInt32(m.Groups[1].Value, 16);
- return ((char)code).ToString();
- });
- }
- /// <summary>
- /// 运行逻辑项目的Json数据
- /// </summary>
- /// <param name="edgeList">边列表</param>
- /// <param name="startNodeId">起始节点ID</param>
- public static void sortEdge(string requestId, List<DatabaseInfo> databaseInfos, List<DatabaseTable> tables, List<EdgeList> edgeList, List<NodeList> nodeList, List<ParamList> paramList, string startNodeId, Dictionary<string, int> doEdgeCount, List<LogItem> logDic, string env)
- {
- var edges = edgeList.Where(m => m.source == startNodeId).ToList();
- foreach(EdgeList item in edges)
- {
- doNode(requestId, databaseInfos, tables, edgeList, nodeList, paramList, item.target, doEdgeCount, logDic, env);
- }
- }
- /// <summary>
- /// 执行节点
- /// </summary>
- /// <param name="edgeList">边列表</param>
- /// <param name="startNodeId">起始节点ID</param>
- public static void doNode(string requestId, List<DatabaseInfo> databaseInfos, List<DatabaseTable> tables, List<EdgeList> edgeList, List<NodeList> nodeList, List<ParamList> paramList, string nodeId, Dictionary<string, int> doEdgeCount, List<LogItem> logDic, string env)
- {
- NodeList node = nodeList.FirstOrDefault(x => x.nodeId == nodeId) ?? new NodeList();
- var edges = edgeList.Where(m => m.source == nodeId).ToList();
- int targetEdgeCount = edgeList.Count(m => m.target == nodeId);
- //记录同一层级的节点执行计数,保证当前层级的所有节点都执行完后,再执行下一层级的节点
- // if(doEdgeCount.ContainsKey(nodeId))
- // {
- // doEdgeCount[nodeId]++;
- // }
- // else
- // {
- // doEdgeCount.Add(nodeId, 1);
- // }
- // if(doEdgeCount[nodeId] < targetEdgeCount && targetEdgeCount > 1)
- // {
- // return;
- // }
- switch(node.nodeType)
- {
- case "ifelse": // 如果-否则节点
- var ifElseResult = LogicNodeHelper.ifElse(node, paramList, logDic);
- if(ifElseResult.Count > 0)
- {
- int ifIndex = 0;
- foreach(bool result in ifElseResult)
- {
- if(result)
- {
- string checkIdString = nodeId + "condition-" + ifIndex;
- var items = edges.Where(m => m.id.Contains(checkIdString)).ToList();
- foreach(EdgeList item in items)
- {
- doNode(requestId, databaseInfos, tables, edgeList, nodeList, paramList, item.target, doEdgeCount, logDic, env);
- }
- break;
- }
- ifIndex += 1;
- }
- }
- if(ifElseResult.Count(m => m) == 0)
- {
- string elseString = nodeId + "condition-else";
- var elseItems = edges.Where(m => m.id.Contains(elseString)).ToList();
- foreach(EdgeList item in elseItems)
- {
- doNode(requestId, databaseInfos, tables, edgeList, nodeList, paramList, item.target, doEdgeCount, logDic, env);
- }
- }
- break;
- case "iteration": // 迭代节点
- LogicNodeHelper.iterationChildStart(node, paramList, logDic);
- bool op = true;
- while (op)
- {
- sortEdge(requestId, databaseInfos, tables, edgeList, nodeList, paramList, node.nodeId + "-child-start-node", doEdgeCount, logDic, env);
- op = RedisServer.Cache.Get("break_" + requestId + "_" + node.nodeId) != "1";
- JsonData upField = node.nodeData["data"]["formData"]["output"]["value"]; // 递归字段
- foreach(JsonData item in upField)
- {
- string paramName = item["label"].ToString(); // 递归字段名
- string paramValue = item["value"].ToString(); // 递归字段值
- var param = paramList.FirstOrDefault(x => x.paramName == paramName && x.paramAttribute == "iterationInputField");
- if (param != null)
- {
- var upParam = paramList.FirstOrDefault(x => x.paramName == paramValue && x.paramAttribute == "iterationInputField");
- if(upParam != null)
- {
- param.paramValue = upParam.paramValue;
- }
- else
- {
- param.paramValue = "0";
- }
- }
- }
- }
- RedisServer.Cache.Del("break_" + requestId + "_" + node.nodeId);
- sortEdge(requestId, databaseInfos, tables, edgeList, nodeList, paramList, node.nodeId, doEdgeCount, logDic, env);
- break;
- case "child_start": // 子流程起始节点
- // LogicNodeHelper.iterationChildStart(node, paramList);
- sortEdge(requestId, databaseInfos, tables, edgeList, nodeList, paramList, node.nodeId, doEdgeCount, logDic, env);
- break;
- case "break": // 跳出循环
- LogicNodeHelper.iterationBreak(node, requestId, logDic);
- // 跳出循环后,继续执行循环后面的节点
- string parentNodeId = node.nodeData["parentNode"]?.ToString() ?? string.Empty;
- EdgeList breakEdge = edgeList.FirstOrDefault(x => x.source == parentNodeId) ?? new EdgeList();
- if(string.IsNullOrEmpty(breakEdge.source))
- {
- sortEdge(requestId, databaseInfos, tables, edgeList, nodeList, paramList, breakEdge.target, doEdgeCount, logDic, env);
- }
- break;
- case "loop": // 循环节点
- List<Dictionary<string, object>> loopResult = LogicNodeHelper.loop(node, paramList, logDic);
- foreach(Dictionary<string, object> subLoop in loopResult)
- {
- if(RedisServer.Cache.Get("break_" + node.nodeId) == "1")
- {
- break;
- }
- else
- {
- foreach(string key in subLoop.Keys)
- {
- var loopParam = paramList.FirstOrDefault(x => x.paramName == key && x.nodeId == node.nodeId && x.paramAttribute == "loop");
- if(loopParam != null)
- {
- loopParam.paramValue = subLoop[key]?.ToString();
- }
- else
- {
- paramList.Add(new ParamList()
- {
- nodeId = node.nodeId,
- paramAttribute = "loop",
- paramName = key,
- paramType = "string",
- paramValue = subLoop[key]?.ToString(),
- });
- }
- }
- doEdgeCount.Remove(node.nodeId + "-child-start-node");
- sortEdge(requestId, databaseInfos, tables, edgeList, nodeList, paramList, node.nodeId + "-child-start-node", doEdgeCount, logDic, env);
- }
- }
- sortEdge(requestId, databaseInfos, tables, edgeList, nodeList, paramList, node.nodeId, doEdgeCount, logDic, env);
- break;
- case "code-execute": // 代码执行节点
- LogicNodeHelper.codeExecute(node, paramList, logDic);
- sortEdge(requestId, databaseInfos, tables, edgeList, nodeList, paramList, node.nodeId, doEdgeCount, logDic, env);
- break;
- case "sql-execute": // SQL执行节点
- LogicDatabaseNodeHelper.dbSqlQuery(node, databaseInfos, paramList, logDic, env);
- sortEdge(requestId, databaseInfos, tables, edgeList, nodeList, paramList, node.nodeId, doEdgeCount, logDic, env);
- break;
- case "insert-data": // 插入数据节点
- LogicDatabaseNodeHelper.dbInsert(node, databaseInfos, tables, paramList, logDic, env);
- sortEdge(requestId, databaseInfos, tables, edgeList, nodeList, paramList, node.nodeId, doEdgeCount, logDic, env);
- break;
- case "update-data": // 更新数据节点
- LogicDatabaseNodeHelper.dbUpdate(node, databaseInfos, tables, paramList, logDic, env);
- sortEdge(requestId, databaseInfos, tables, edgeList, nodeList, paramList, node.nodeId, doEdgeCount, logDic, env);
- break;
- case "query-data": // 查询数据节点
- LogicDatabaseNodeHelper.dbQuery(node, databaseInfos, tables, paramList, logDic, env);
- sortEdge(requestId, databaseInfos, tables, edgeList, nodeList, paramList, node.nodeId, doEdgeCount, logDic, env);
- break;
- case "delete-data": // 删除数据节点
- LogicDatabaseNodeHelper.dbDelete(node, databaseInfos, tables, paramList, logDic, env);
- sortEdge(requestId, databaseInfos, tables, edgeList, nodeList, paramList, node.nodeId, doEdgeCount, logDic, env);
- break;
- case "setredis": // 设置Redis值节点
- LogicCacheNodeHelper.setRedisObject(node, paramList, logDic);
- sortEdge(requestId, databaseInfos, tables, edgeList, nodeList, paramList, node.nodeId, doEdgeCount, logDic, env);
- break;
- case "getredis": // 获取Redis值节点
- LogicCacheNodeHelper.getRedisObject(node, paramList, logDic);
- sortEdge(requestId, databaseInfos, tables, edgeList, nodeList, paramList, node.nodeId, doEdgeCount, logDic, env);
- break;
- case "http-request": // HTTP请求节点
- LogicToolNodeHelper.httpRequest(node, paramList, logDic);
- sortEdge(requestId, databaseInfos, tables, edgeList, nodeList, paramList, node.nodeId, doEdgeCount, logDic, env);
- break;
- case "apiSource": // 内部API请求节点
- LogicToolNodeHelper.apiSourceRequest(node, paramList, logDic);
- sortEdge(requestId, databaseInfos, tables, edgeList, nodeList, paramList, node.nodeId, doEdgeCount, logDic, env);
- break;
- case "var-aggregate": // 变量聚合节点
- LogicNodeHelper.varAggregate(node, paramList, logDic);
- sortEdge(requestId, databaseInfos, tables, edgeList, nodeList, paramList, node.nodeId, doEdgeCount, logDic, env);
- break;
- case "document-extractor": // 文档提取节点
- sortEdge(requestId, databaseInfos, tables, edgeList, nodeList, paramList, node.nodeId, doEdgeCount, logDic, env);
- break;
- case "document-export": // 文档导出节点
- sortEdge(requestId, databaseInfos, tables, edgeList, nodeList, paramList, node.nodeId, doEdgeCount, logDic, env);
- break;
- case "end": // 结束节点
- break;
- default:
- sortEdge(requestId, databaseInfos, tables, edgeList, nodeList, paramList, node.nodeId, doEdgeCount, logDic, env);
- break;
- }
- }
- public static string GetExpressionVal(string str)
- {
- if(str == "#{now}#") return DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
- if(str == "#{today}#") return DateTime.Now.ToString("yyyy-MM-dd");
- if(str == "#{this_month}#") return DateTime.Now.ToString("yyyy-MM");
- if(str.StartsWith("#{now") && str.EndsWith("DAY}#")) return DateTime.Now.AddDays(int.Parse(str.Replace("#", "").Replace("{", "").Replace("}", "").Split(',')[1])).ToString("yyyy-MM-dd HH:mm:ss");
- if(str.StartsWith("#{now") && str.EndsWith("MONTH}#")) return DateTime.Now.AddMonths(int.Parse(str.Replace("#", "").Replace("{", "").Replace("}", "").Split(',')[1])).ToString("yyyy-MM-dd HH:mm:ss");
- if(str.StartsWith("#{today") && str.EndsWith("DAY}#")) return DateTime.Now.AddDays(int.Parse(str.Replace("#", "").Replace("{", "").Replace("}", "").Split(',')[1])).ToString("yyyy-MM-dd");
- if(str.StartsWith("#{today") && str.EndsWith("MONTH}#")) return DateTime.Now.AddMonths(int.Parse(str.Replace("#", "").Replace("{", "").Replace("}", "").Split(',')[1])).ToString("yyyy-MM-dd");
- if(str.StartsWith("#{this_month") && str.EndsWith("DAY}#")) return DateTime.Now.AddDays(int.Parse(str.Replace("#", "").Replace("{", "").Replace("}", "").Split(',')[1])).ToString("yyyy-MM");
- if(str.StartsWith("#{this_month") && str.EndsWith("MONTH}#")) return DateTime.Now.AddMonths(int.Parse(str.Replace("#", "").Replace("{", "").Replace("}", "").Split(',')[1])).ToString("yyyy-MM");
- if(str.StartsWith("#{") && str.EndsWith("DAY}#")) return DateTime.Parse(str.Replace("#", "").Replace("{", "").Replace("}", "").Split(',')[0]).AddDays(int.Parse(str.Replace("#", "").Replace("{", "").Replace("}", "").Split(',')[1])).ToString("yyyy-MM-dd HH:mm:ss");
- if(str.StartsWith("#{") && str.EndsWith("MONTH}#")) return DateTime.Parse(str.Replace("#", "").Replace("{", "").Replace("}", "").Split(',')[0]).AddMonths(int.Parse(str.Replace("#", "").Replace("{", "").Replace("}", "").Split(',')[1])).ToString("yyyy-MM-dd HH:mm:ss");
- if(str.StartsWith("#{split") && str.EndsWith("}#"))
- {
- string[] data = str.Replace("#{", "").Replace("}#", "").Split(',');
- string text = data[1];
- string splitTag = data[2];
- string index = data[3];
- return text.Split(new string[]{ splitTag }, StringSplitOptions.None)[int.Parse(index)];
- }
- else if(str.StartsWith("#{") && str.EndsWith("}#"))
- {
- string[] data = str.Replace("#{", "").Replace("}#", "").Split(',');
- string tag = data[0];
- string format = data[data.Length - 1];
- if(format.StartsWith("yyyy"))
- {
- if(tag == "now")
- {
- if(data.Length == 2)
- {
- return DateTime.Now.ToString(format);
- }
- else if(data.Length == 4)
- {
- if(data[2] == "DAY") return DateTime.Now.AddDays(int.Parse(data[1])).ToString(format);
- if(data[2] == "MONTH") return DateTime.Now.AddMonths(int.Parse(data[1])).ToString(format);
- }
- }
- else
- {
- if(data.Length == 2)
- {
- return DateTime.Parse(tag).ToString(format);
- }
- else if(data.Length == 4)
- {
- if(data[2] == "DAY") return DateTime.Parse(tag).AddDays(int.Parse(data[1])).ToString(format);
- if(data[2] == "MONTH") return DateTime.Parse(tag).AddMonths(int.Parse(data[1])).ToString(format);
- }
- }
- }
- }
- return str;
- }
- public static string MatchExpressionVal(string str)
- {
- if(string.IsNullOrEmpty(str)) return str;
- MatchCollection mc = Regex.Matches(str, "#\\{.*?\\}#");
- foreach(Match m in mc)
- {
- str = str.Replace(m.Value, GetExpressionVal(m.Value));
- }
- return str;
- }
- public static List<Dictionary<string, object>> initNodeData(string nodeType)
- {
- if(string.IsNullOrEmpty(nodeType)) return new List<Dictionary<string, object>>();
- var data = new List<Dictionary<string, object>>();
- if(nodeType == "json")
- {
- var item = new Dictionary<string, object>();
- item.Add("title", "标题1");
- item.Add("detail", "介绍1");
- item.Add("id", 1);
- var children = new List<Dictionary<string, object>>();
- var childItem = new Dictionary<string, object>();
- childItem.Add("title", "子标题1");
- childItem.Add("detail", "子介绍1");
- childItem.Add("id", 3);
- children.Add(childItem);
- childItem = new Dictionary<string, object>();
- childItem.Add("title", "子标题2");
- childItem.Add("detail", "子介绍2");
- childItem.Add("id", 4);
- children.Add(childItem);
- item.Add("children", children);
- data.Add(item);
- return data;
- }
- var input = new Dictionary<string, object>();
- input.Add("label", "user_id");
- input.Add("required", true);
- input.Add("type", new List<string>() { "number" });
- input.Add("desc", "");
- input.Add("children", new List<object>());
- input.Add("_id", "mqeuhpvg-1o5m6i612c4o4ph");
- data.Add(input);
- return data;
- }
- }
- }
|