LogicNodeHelper.cs 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557
  1. using System.Text.RegularExpressions;
  2. using System.Web;
  3. using Common;
  4. using Infrastructure;
  5. using Jint;
  6. using LitJson;
  7. using Model;
  8. using Model.Custom;
  9. using Model.Source;
  10. namespace Util.Logic
  11. {
  12. public class LogicNodeHelper
  13. {
  14. /// <summary>
  15. /// 如果-否则节点
  16. /// </summary>
  17. /// <param name="node">节点数据</param>
  18. /// <param name="paramList">参数列表</param>
  19. /// <param name="parentNodeParamList">父节点参数列表</param>
  20. public static List<bool> ifElse(NodeList node, List<ParamList> paramList, List<LogItem> logDic)
  21. {
  22. Dictionary<string, object> condi = new Dictionary<string, object>(); // 条件参数字典
  23. List<bool> ifElseResult = new List<bool>(); // 如果-否则节点结果
  24. JsonData nodeData = node.nodeData;
  25. JsonData ifCondition = nodeData["data"]["formData"]["ifelse"]["value"]; // 如果条件
  26. string paramAttribute = "";
  27. if (nodeData.ToJson().Contains("\"parentNode\""))
  28. {
  29. paramAttribute = "iterationInputField";
  30. }
  31. else
  32. {
  33. paramAttribute = "";
  34. }
  35. int ifIndex = 0; // 如果条件索引
  36. foreach (JsonData item in ifCondition)
  37. {
  38. string conditionExpression = ""; // 条件表达式
  39. string conditionExpressionLog = ""; // 条件表达式日志
  40. string logicTag = item["logic"].ToString(); // 逻辑
  41. JsonData conditions = item["conditions"]; // 条件
  42. foreach (JsonData condition in conditions)
  43. {
  44. string oper = condition["operator"].ToString(); // 运算符
  45. string value = condition["value"].ToString(); // 值
  46. string variable = condition["variable"].ToString(); // 变量
  47. if (variable.Contains("."))
  48. {
  49. string nodeId = variable.Substring(0, variable.IndexOf(":"));
  50. variable = variable.Substring(variable.LastIndexOf(".") + 1);
  51. if(variable.EndsWith("_Init"))
  52. {
  53. variable = variable.Replace("_Init", "");
  54. }
  55. ParamList param = paramList.FirstOrDefault(x => x.paramName == variable && x.nodeId == nodeId) ?? paramList.FirstOrDefault(x => x.paramName == variable) ?? new ParamList();
  56. if (!string.IsNullOrEmpty(param.paramName))
  57. {
  58. // string paramValue = param.paramValueTransfer;
  59. value = LogicHelper.MatchExpressionVal(value);
  60. if(value.Contains("."))
  61. {
  62. string nId = value.Substring(0, value.IndexOf(":"));
  63. value = value.Substring(value.LastIndexOf(".") + 1);
  64. if(value.EndsWith("_Init"))
  65. {
  66. value = value.Replace("_Init", "");
  67. }
  68. var paramc = paramList.FirstOrDefault(x => x.paramName == value && x.nodeId == nId);
  69. if (paramc != null)
  70. {
  71. value = paramc.paramValueTransfer;
  72. }
  73. }
  74. string paramType = param.paramType;
  75. conditionExpression += operatorTransfer(param, oper, value);
  76. conditionExpressionLog += operatorTransfer(param, oper, value, true);
  77. if (logicTag == "and")
  78. {
  79. conditionExpression += " && ";
  80. conditionExpressionLog += " && ";
  81. continue;
  82. }
  83. else if (logicTag == "or")
  84. {
  85. conditionExpression += " || ";
  86. conditionExpressionLog += " || ";
  87. continue;
  88. }
  89. }
  90. else
  91. {
  92. conditionExpression += "false"; // 如果参数未找到,则条件表达式为false
  93. conditionExpressionLog += "false"; // 如果参数未找到,则条件表达式为false
  94. if (logicTag == "and")
  95. {
  96. conditionExpression += " && ";
  97. conditionExpressionLog += " && ";
  98. }
  99. else if (logicTag == "or")
  100. {
  101. conditionExpression += " || ";
  102. conditionExpressionLog += " || ";
  103. }
  104. }
  105. }
  106. }
  107. if (conditionExpression.EndsWith(" && ") || conditionExpression.EndsWith(" || "))
  108. {
  109. conditionExpression = conditionExpression.Substring(0, conditionExpression.Length - 4);
  110. }
  111. if (conditionExpressionLog.EndsWith(" && ") || conditionExpressionLog.EndsWith(" || "))
  112. {
  113. conditionExpressionLog = conditionExpressionLog.Substring(0, conditionExpressionLog.Length - 4);
  114. }
  115. bool conditionResult = Utils.EvaluateBoolean(conditionExpression);
  116. ifElseResult.Add(conditionResult);
  117. condi.Add("条件" + ifIndex, conditionExpressionLog);
  118. condi.Add("结果" + ifIndex, conditionResult);
  119. ifIndex += 1;
  120. }
  121. // 记录日志
  122. logDic.Add(new LogItem()
  123. {
  124. title = node.nodeData["data"]["nodeMeta"]["label"].ToString(),
  125. param = condi
  126. });
  127. return ifElseResult;
  128. }
  129. /// <summary>
  130. /// 循环节点
  131. /// </summary>
  132. /// <param name="node">节点数据</param>
  133. /// <param name="paramList">参数列表</param>
  134. public static List<Dictionary<string, object>> loop(NodeList node, List<ParamList> paramList, List<LogItem> logDic)
  135. {
  136. JsonData nodeData = node.nodeData;
  137. JsonData inputField = nodeData["data"]["formData"]["loopVar"]["value"];
  138. if(inputField.Count > 0)
  139. {
  140. string paramType = inputField[0]["type"][0].ToString(); // 字段类型
  141. if(paramType == "array")
  142. {
  143. string paramValue = inputField[0]["value"].ToString(); // 字段值
  144. Dictionary<string, object> condi = new Dictionary<string, object>(); // 条件参数字典
  145. if(paramValue.Contains("."))
  146. {
  147. paramValue = paramValue.Substring(paramValue.LastIndexOf(".") + 1);
  148. var param = paramList.FirstOrDefault(x => x.paramName == paramValue);
  149. if (param != null)
  150. {
  151. paramValue = param.paramValueTransfer;
  152. }
  153. }
  154. condi.Add("循环来源", paramValue);
  155. List<Dictionary<string, object>> loopResult = Newtonsoft.Json.JsonConvert.DeserializeObject<List<Dictionary<string, object>>>(paramValue) ?? new List<Dictionary<string, object>>();
  156. logDic.Add(new LogItem()
  157. {
  158. title = node.nodeData["data"]["nodeMeta"]["label"].ToString(),
  159. param = condi
  160. });
  161. return loopResult;
  162. }
  163. }
  164. return new List<Dictionary<string, object>>();
  165. }
  166. /// <summary>
  167. /// 迭代节点
  168. /// </summary>
  169. /// <param name="node">节点数据</param>
  170. /// <param name="paramList">参数列表</param>
  171. public static void iteration(NodeList node, List<ParamList> paramList, List<LogItem> logDic)
  172. {
  173. JsonData nodeData = node.nodeData;
  174. string inputField = nodeData["data"]["formData"]["input"]["value"]?.ToString() ?? string.Empty; // 迭代字段
  175. inputField = inputField.Substring(inputField.LastIndexOf(".") + 1);
  176. ParamList inputFieldParam = paramList.FirstOrDefault(x => x.paramName == inputField) ?? new ParamList(); // 迭代字段值
  177. var param = paramList.FirstOrDefault(x => x.paramName == inputField && x.paramAttribute == "iterationInputField");
  178. if(param == null)
  179. {
  180. paramList.Add(new ParamList()
  181. {
  182. nodeId = node.nodeId,
  183. paramAttribute = "iterationInputField",
  184. paramName = inputFieldParam.paramName,
  185. paramType = inputFieldParam.paramType,
  186. paramValue = inputFieldParam.paramValue
  187. });
  188. }
  189. else
  190. {
  191. param.paramName = inputFieldParam.paramName;
  192. param.paramType = inputFieldParam.paramType;
  193. param.paramValue = inputFieldParam.paramValue;
  194. }
  195. }
  196. /// <summary>
  197. /// 迭代子流程起始节点
  198. /// </summary>
  199. /// <param name="node"></param>
  200. /// <param name="paramList"></param>
  201. public static void iterationChildStart(NodeList node, List<ParamList> paramList, List<LogItem> logDic)
  202. {
  203. Dictionary<string, object> condi = new Dictionary<string, object>(); // 条件参数字典
  204. JsonData nodeData = node.nodeData;
  205. string inputField = nodeData["data"]["formData"]["input"]["value"]?.ToString() ?? string.Empty; // 迭代字段
  206. inputField = inputField.Substring(inputField.LastIndexOf(".") + 1);
  207. ParamList inputFieldParam = paramList.FirstOrDefault(x => x.paramName == inputField) ?? new ParamList(); // 迭代字段值
  208. bool iterationInputFieldCheck = paramList.Any(x => x.paramName == inputField && x.paramAttribute == "iterationInputField");
  209. if(!iterationInputFieldCheck)
  210. {
  211. paramList.Add(new ParamList()
  212. {
  213. nodeId = node.nodeId,
  214. paramAttribute = "iterationInputField",
  215. paramName = inputFieldParam.paramName,
  216. paramType = inputFieldParam.paramType,
  217. paramValue = inputFieldParam.paramValue
  218. });
  219. condi.Add(inputFieldParam.paramName, inputFieldParam.paramValue);
  220. }
  221. logDic.Add(new LogItem()
  222. {
  223. title = node.nodeData["data"]["nodeMeta"]["label"].ToString(),
  224. param = condi
  225. });
  226. }
  227. /// <summary>
  228. /// 跳出循环节点
  229. /// </summary>
  230. /// <param name="node"></param>
  231. /// <param name="paramList"></param>
  232. public static void iterationBreak(NodeList node, string requestId, List<LogItem> logDic)
  233. {
  234. string parentNodeId = node.nodeData["parentNode"]?.ToString() ?? string.Empty;
  235. RedisServer.Cache.Set("break_" + requestId + "_" + parentNodeId, "1", 60); // 设置循环跳出标志,过期时间10分钟
  236. logDic.Add(new LogItem()
  237. {
  238. title = node.nodeData["data"]["nodeMeta"]["label"].ToString(),
  239. detail = "跳出循环"
  240. });
  241. }
  242. /// <summary>
  243. /// 代码执行节点
  244. /// </summary>
  245. /// <param name="node"></param>
  246. /// <param name="paramList"></param>
  247. public static void codeExecute(NodeList node, List<ParamList> paramList, List<LogItem> logDic)
  248. {
  249. Dictionary<string, object> condi = new Dictionary<string, object>(); // 条件参数字典
  250. JsonData nodeData = node.nodeData;
  251. JsonData inputParam = nodeData["data"]["formData"]["code"]["value"]["inputVar"]; // 输出参数
  252. Dictionary<string, string> inputDic = new Dictionary<string, string>();
  253. foreach (JsonData param in inputParam)
  254. {
  255. string paramName = param["label"].ToString(); // 字段名
  256. string paramValue = param["value"].ToString(); // 字段值
  257. if(paramValue.Contains("."))
  258. {
  259. string nId = paramValue.Substring(0, paramValue.IndexOf(":"));
  260. paramValue = paramValue.Substring(paramValue.LastIndexOf(".") + 1);
  261. if (paramValue.EndsWith("_Init"))
  262. {
  263. paramValue = paramValue.Replace("_Init", "");
  264. }
  265. var paramc = paramList.FirstOrDefault(x => x.paramName == paramValue && x.nodeId == nId);
  266. if (paramc != null)
  267. {
  268. paramValue = paramc.paramValueTransfer;
  269. }
  270. }
  271. inputDic.Add(paramName, paramValue);
  272. }
  273. string code = nodeData["data"]["formData"]["code"]["value"]["code"]["content"].ToString(); // 代码
  274. JsonData outputParam = nodeData["data"]["formData"]["output"]["value"]; // 输出参数
  275. var engine = new Engine();
  276. MatchCollection mc = Regex.Matches(code, "\\$\\{.*?\\}");
  277. foreach(Match m in mc)
  278. {
  279. string field = m.Value.Replace("${", "").Replace("}", "");
  280. code = code.Replace("${" + field + "}", inputDic[field]);
  281. code = code.Replace("{" + field + "}", inputDic[field]);
  282. }
  283. engine.Execute(code);
  284. foreach (JsonData param in outputParam)
  285. {
  286. string paramName = param["label"].ToString(); // 字段名
  287. if (paramName.EndsWith("_Init"))
  288. {
  289. paramName = paramName.Replace("_Init", "");
  290. }
  291. string paramValue = engine.GetValue(paramName).ToString();
  292. var paramItem = paramList.FirstOrDefault(x => x.paramName == paramName);
  293. if(paramItem != null)
  294. {
  295. Utils.WriteLog("代码执行1:" + paramValue + ";");
  296. paramItem.paramValue = paramValue;
  297. }
  298. else
  299. {
  300. Utils.WriteLog("代码执行2:" + node.nodeId + "-" + paramValue + ";");
  301. paramList.Add(new ParamList()
  302. {
  303. nodeId = node.nodeId,
  304. paramName = paramName,
  305. paramValue = paramValue,
  306. paramType = param["type"][0].ToString(),
  307. });
  308. }
  309. condi.Add(paramName, paramValue);
  310. }
  311. Utils.WriteLog("代码执行:" + JsonMapper.ToJson(condi) + ";");
  312. logDic.Add(new LogItem()
  313. {
  314. title = node.nodeData["data"]["nodeMeta"]["label"].ToString(),
  315. param = condi,
  316. detail = HttpUtility.UrlEncode(code)
  317. });
  318. }
  319. /// <summary>
  320. /// 变量聚合节点
  321. /// </summary>
  322. /// <param name="node">节点数据</param>
  323. /// <param name="paramList">参数列表</param>
  324. /// <param name="parentNodeParamList">父节点参数列表</param>
  325. public static void varAggregate(NodeList node, List<ParamList> paramList, List<LogItem> logDic)
  326. {
  327. Dictionary<string, object> condi = new Dictionary<string, object>(); // 条件参数字典
  328. JsonData nodeData = node.nodeData;
  329. JsonData aggregateFields = nodeData["data"]["formData"]["output"]["value"]; // 聚合字段
  330. string paramAttribute = "";
  331. if (nodeData.ToJson().Contains("\"parentNode\""))
  332. {
  333. paramAttribute = "iterationInputField";
  334. }
  335. foreach (JsonData item in aggregateFields)
  336. {
  337. string paramName = item["label"].ToString(); // 聚合字段名
  338. bool updateFlag = true;
  339. if(paramName.EndsWith("_Init"))
  340. {
  341. updateFlag = false;
  342. paramName = paramName.Replace("_Init", "");
  343. }
  344. string paramValue = item["value"].ToString(); // 聚合字段值
  345. string nId = "";
  346. if (paramValue.Contains(":"))
  347. {
  348. nId = paramValue.Substring(0, paramValue.IndexOf(":"));
  349. }
  350. if(paramValue.Contains("."))
  351. {
  352. paramValue = paramValue.Substring(paramValue.LastIndexOf(".") + 1);
  353. var param = paramList.FirstOrDefault(x => x.paramName == paramValue && x.nodeId == nId) ?? paramList.FirstOrDefault(x => x.paramName == paramValue) ?? new ParamList();
  354. paramValue = param.paramValue;
  355. }
  356. string paramType = item["type"][0].ToString(); // 聚合字段类型
  357. if(!paramList.Any(x => x.paramName == paramName && x.nodeId == nId))
  358. {
  359. paramList.Add(new ParamList()
  360. {
  361. nodeId = node.nodeId,
  362. paramAttribute = paramAttribute,
  363. paramName = paramName,
  364. paramValue = paramValue,
  365. paramType = paramType
  366. });
  367. condi.Add(paramName, paramValue);
  368. }
  369. else
  370. {
  371. var paramItem = paramList.FirstOrDefault(x => x.paramName == paramName && x.nodeId == nId) ?? paramList.FirstOrDefault(x => x.paramName == paramName) ?? new ParamList();
  372. if (paramValue.StartsWith("+"))
  373. {
  374. int newValue = int.Parse(paramItem.paramValue) + int.Parse(paramValue.TrimStart('+'));
  375. paramValue = newValue.ToString();
  376. }
  377. if(updateFlag)
  378. {
  379. paramItem.paramValue = paramValue;
  380. condi.Add(paramName, paramValue);
  381. }
  382. }
  383. }
  384. logDic.Add(new LogItem()
  385. {
  386. title = node.nodeData["data"]["nodeMeta"]["label"].ToString(),
  387. param = condi
  388. });
  389. }
  390. /// <summary>
  391. /// 运算符转换
  392. /// </summary>
  393. /// <param name="oper">运算符</param>
  394. /// <returns>转换后的运算符</returns>
  395. public static string operatorTransfer(ParamList param, string oper, string paramValue, bool isLog = false)
  396. {
  397. if(param.paramType == "number")
  398. {
  399. param.paramValue = Function.CheckNum(param.paramValue);
  400. }
  401. string condiLeftData = param.paramValue;
  402. if(isLog)
  403. {
  404. condiLeftData = param.paramName + "(" + param.paramValue + ")";
  405. }
  406. if (oper == "equal") //等于
  407. {
  408. if(param.paramType == "string" || param.paramType == "time")
  409. {
  410. return "'" + condiLeftData + "' == '" + paramValue + "'";
  411. }
  412. return condiLeftData + " == " + paramValue;
  413. }
  414. else if (oper == "not_equal") //不等于
  415. {
  416. if(param.paramType == "string" || param.paramType == "time")
  417. {
  418. return "'" + condiLeftData + "' != '" + paramValue + "'";
  419. }
  420. return condiLeftData + " != " + paramValue;
  421. }
  422. else if (oper == "greater") //大于
  423. {
  424. return condiLeftData + " > " + paramValue;
  425. }
  426. else if (oper == "greater_equal") //大于等于
  427. {
  428. return condiLeftData + " >= " + paramValue;
  429. }
  430. else if (oper == "less") //小于
  431. {
  432. return condiLeftData + " < " + paramValue;
  433. }
  434. else if (oper == "less_equal") //小于等于
  435. {
  436. return condiLeftData + " <= " + paramValue;
  437. }
  438. else if (oper == "between") //在之间
  439. {
  440. string[] betweenValues = paramValue.Split(',');
  441. return condiLeftData + " >= " + betweenValues[0] + " && " + condiLeftData + " <= " + betweenValues[1];
  442. }
  443. else if (oper == "not_between") //不在之间
  444. {
  445. string[] betweenValues = paramValue.Split(',');
  446. return "(" + condiLeftData + " < " + betweenValues[0] + " || " + condiLeftData + " > " + betweenValues[1] + ")";
  447. }
  448. else if (oper == "contains") //包含
  449. {
  450. return "Contains('" + condiLeftData + "', '" + paramValue + "')";
  451. }
  452. else if (oper == "not_contains") //不包含
  453. {
  454. return "!Contains('" + condiLeftData + "', '" + paramValue + "')";
  455. }
  456. else if (oper == "starts_with") //以...开头
  457. {
  458. return "StartsWith('" + condiLeftData + "', '" + paramValue + "')";
  459. }
  460. else if (oper == "ends_with") //以...结尾
  461. {
  462. return "EndsWith('" + condiLeftData + "', '" + paramValue + "')";
  463. }
  464. else if (oper == "matches_regex") //匹配正则表达式
  465. {
  466. return "Match('" + condiLeftData + "', '" + paramValue + "')";
  467. }
  468. else if (oper == "not_matches_regex") //不匹配正则表达式
  469. {
  470. return "!Match('" + condiLeftData + "', '" + paramValue + "')";
  471. }
  472. else if (oper == "is_empty")
  473. {
  474. return "IsNullOrEmpty('" + condiLeftData + "')";
  475. }
  476. else if (oper == "is_not_empty") //不为空
  477. {
  478. return "!" + "IsNullOrEmpty('" + condiLeftData + "')";
  479. }
  480. else if (oper == "is_null") //为空
  481. {
  482. return "('" + condiLeftData + "'=='{}' || '" + condiLeftData + "'=='[]')";
  483. }
  484. else if (oper == "is_not_null") //不为空
  485. {
  486. return "('" + condiLeftData + "'!='{}' || '" + condiLeftData + "'!='[]')";
  487. }
  488. else if (oper == "in") //在...中
  489. {
  490. return "In('" + condiLeftData + "', '" + paramValue + "')";
  491. }
  492. else if (oper == "not_in") //不在...中
  493. {
  494. return "!In('" + condiLeftData + "', '" + paramValue + "')";
  495. }
  496. else if (oper == "array_contains") //数组包含
  497. {
  498. return "In('" + condiLeftData + "', '" + paramValue + "')";
  499. }
  500. else if (oper == "array_not_contains") //数组不包含
  501. {
  502. return "!In('" + condiLeftData + "', '" + paramValue + "')";
  503. }
  504. else if (oper == "array_length_equal") //数组长度等于
  505. {
  506. return "ArrayLen('" + condiLeftData + "') == " + paramValue;
  507. }
  508. else if (oper == "array_length_greater")
  509. {
  510. return "ArrayLen('" + condiLeftData + "') > " + paramValue;
  511. }
  512. else if (oper == "array_length_less") //数组长度小于
  513. {
  514. return "ArrayLen('" + condiLeftData + "') < " + paramValue;
  515. }
  516. else if (oper == "is_true") //为真
  517. {
  518. return condiLeftData + " == true";
  519. }
  520. else if (oper == "is_false") //为假
  521. {
  522. return condiLeftData + " == false";
  523. }
  524. else if (oper == "date_equal") //日期等于
  525. {
  526. return "'" + condiLeftData + "' == '" + paramValue + "'";
  527. }
  528. else if (oper == "date_before") //日期之前
  529. {
  530. return "'" + condiLeftData + "' < '" + paramValue + "'";
  531. }
  532. else if (oper == "date_after") //日期之后
  533. {
  534. return "'" + condiLeftData + "' > '" + paramValue + "'";
  535. }
  536. else if (oper == "date_between") //日期之间
  537. {
  538. string[] betweenValues = paramValue.Split(" - ", StringSplitOptions.None);
  539. return "'" + condiLeftData + "' >= '" + betweenValues[0] + "' && '" + condiLeftData + "' <= '" + betweenValues[1] + "'";
  540. }
  541. return "";
  542. }
  543. }
  544. }