ivr流程编辑器

IVRFlowSerializer.cs 24KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using HySoft.IVRFlowEditor.IVRControlUtility;
  6. using HySoft.IVRFlowEditor.Model;
  7. using System.Xml;
  8. using System.Xml.Serialization;
  9. using System.IO;
  10. using System.Reflection;
  11. using System.ComponentModel;
  12. using System.Drawing;
  13. namespace HySoft.IVRFlowEditor.Utility
  14. {
  15. /// <summary>
  16. /// IVR流程编辑器导入导出操作类
  17. /// </summary>
  18. public class IVRFlowSerializer:SerializerBase
  19. {
  20. /// <summary>
  21. /// 保存到文件(所有要序列化到文件的属性必须使用 IVRAttribute 特性加以描述)
  22. /// </summary>
  23. /// <param name="filePath">文件路径(包含文件名)</param>
  24. /// <param name="val">要保存的对象集合</param>
  25. /// <returns></returns>
  26. public override Model.MessageInfo SaveFileInfo(string filePath, List<IVRFlowSerializerInfo> val)
  27. {
  28. MessageInfo msg;
  29. try
  30. {
  31. StringBuilder xmlBuilder = new StringBuilder();
  32. xmlBuilder.Append("<?xml version=\"1.0\" encoding=\"utf-8\"?> \r\n<ivr> \r\n");
  33. foreach (IVRFlowSerializerInfo o in val)
  34. {
  35. if (o.IVRControl != null && o.IVRControl.Count > 0)
  36. {
  37. //xmlBuilder.Append("<flow Name=\"" + o.IVR_Name + "\" Type=\"" + o.IVRFlowType.ToString() + "\" IVR_Name=\"" + o.IVR_Name + "\" IVR_Text=\"" + o.IVR_Text + "\" MatchedNum=\"\" MatchedLine=\"\" Concurrency=\"1\"> \r\n");
  38. //2017-4-28修改
  39. //xmlBuilder.Append("<flow Name=\"" + o.IVR_Name + "\" Type=\"" + o.IVRFlowType.ToString() + "\" IVR_Name=\"" + o.IVR_Name + "\" IVR_Text=\"" + o.IVR_Text + "\" MatchedNum=\".\" MatchedLine=\"|-1|\" Concurrency=\"1\"> \r\n");//2019-7-25 注释掉
  40. xmlBuilder.Append("<flow Name=\"" + o.IVR_Name + "\" Type=\"" + o.IVRFlowType.ToString() + "\" IVR_Text=\"" + o.IVR_Text + "\" MatchedNum=\".\" MatchedLine=\"|-1|\" Concurrency=\"1\"> \r\n");
  41. foreach (IVRControlBase ivr in o.IVRControl)
  42. {
  43. Dictionary<int,string> disAtt=new Dictionary<int,string>();
  44. msg = CreateXmlNode("cell", ref xmlBuilder, ivr,true);
  45. if (!msg.State)
  46. return msg;
  47. }
  48. xmlBuilder.Append("</flow> \r\n");
  49. }
  50. }
  51. xmlBuilder.Append("</ivr> \r\n");
  52. File.Delete(filePath);
  53. using (FileStream fs = new FileStream(filePath, FileMode.CreateNew, FileAccess.ReadWrite))
  54. {
  55. StreamWriter sw = new StreamWriter(fs);
  56. sw.Write(xmlBuilder.ToString());
  57. sw.Close();
  58. fs.Close();
  59. }
  60. return new MessageInfo() { Code = 0, State = true, Message = "保存成功!" };
  61. }
  62. catch (Exception ex)
  63. {
  64. return new MessageInfo() { State = false, Code = -1, Message = "保存到文件发生异常,错误信息:" + ex.Message };
  65. }
  66. }
  67. /// <summary>
  68. /// 构建XML节点
  69. /// </summary>
  70. /// <param name="nodeName">节点名称</param>
  71. /// <param name="xmlBuilder">返回的XML内容</param>
  72. /// <param name="b">要解析的对象</param>
  73. /// <param name="isWriteName">是否写节点的属性名称 针对二级节点(二级子节点没有名称)</param>
  74. /// <returns></returns>
  75. private MessageInfo CreateXmlNode(string nodeName,ref StringBuilder xmlBuilder, object b,bool isWriteName)
  76. {
  77. try
  78. {
  79. Dictionary<int, string> disAtt =new Dictionary<int,string>();
  80. List<StringBuilder> nodes = new List<StringBuilder>();
  81. xmlBuilder.Append("<" + nodeName + " "+(isWriteName?" Name=\"" + (b.GetType().GetCustomAttributes(typeof(IVRAttribute), false)[0] as IVRAttribute).Name + "\" ":"")+" ");
  82. foreach(PropertyInfo p in b.GetType().GetProperties())
  83. {
  84. if (p.GetCustomAttributes(typeof(IVRAttribute), false) == null || p.GetCustomAttributes(typeof(IVRAttribute), false).Count() == 0)
  85. continue;
  86. var ivratt = p.GetCustomAttributes(typeof(IVRAttribute), false).Last() as IVRAttribute;
  87. switch (ivratt.IVRSerializerType)
  88. {
  89. case IVRSerializerType.元素:
  90. if (p.PropertyType == typeof(IVRControlBase) && p.GetValue(b, null) != null)
  91. {
  92. disAtt.Add(ivratt.Number, ivratt.Name.Trim() + "=\"" + p.GetValue(b, null).GetType().GetProperty("ID").GetValue(p.GetValue(b, null), null) + "\"");
  93. }
  94. else if (p.PropertyType.IsEnum)
  95. {
  96. if (p.PropertyType == typeof(FinishKeyType) && p.PropertyType.GetField(p.GetValue(b, null).ToString()).GetCustomAttributes(false).Count() > 0)
  97. {
  98. var des = p.PropertyType.GetField(p.GetValue(b, null).ToString()).GetCustomAttributes(false).Last() as DescriptionAttribute;
  99. disAtt.Add(ivratt.Number, p.Name + "=\"" + des.Description + "\" ");
  100. }
  101. else
  102. disAtt.Add(ivratt.Number, ivratt.Name + "=\"" + (int)Enum.Parse(p.PropertyType, p.GetValue(b, null).ToString()) + "\" ");
  103. }
  104. else
  105. {
  106. //2017-5-9将"<"保存为&lt;防止解析出错
  107. string ivalue = "";
  108. if (p.GetValue(b, null) != null)
  109. {
  110. ivalue = p.GetValue(b, null).ToString();
  111. }
  112. if (ivratt.Name == "SqlStr")
  113. {
  114. if (p.GetValue(b, null).ToString().Contains("<"))
  115. {
  116. ivalue = StringReplace(ivalue, "<", "&lt;");
  117. }
  118. }
  119. disAtt.Add(ivratt.Number, ivratt.Name.Trim() + "=\"" + ivalue + "\"");//disAtt.Add(ivratt.Number, ivratt.Name.Trim() + "=\"" + p.GetValue(b, null) + "\"");
  120. }
  121. break;
  122. case IVRSerializerType.节点:
  123. if (p.PropertyType.IsGenericType)
  124. {
  125. if (p.PropertyType == typeof(List<IVRDefinevarDefVar>))
  126. {
  127. var ivr = (List<IVRDefinevarDefVar>)p.GetValue(b, null);
  128. foreach (IVRDefinevarDefVar iv in ivr)
  129. {
  130. StringBuilder node = new StringBuilder();
  131. CreateXmlNode(p.Name, ref node, iv,false);
  132. nodes.Add(node);
  133. }
  134. }
  135. if (p.PropertyType == typeof(List<IVRDefaultVar>))
  136. {
  137. var ivr = (List<IVRDefaultVar>)p.GetValue(b, null);
  138. foreach (IVRDefaultVar iv in ivr)
  139. {
  140. StringBuilder node = new StringBuilder();
  141. CreateXmlNode(p.Name, ref node, iv,false);
  142. nodes.Add(node);
  143. }
  144. }
  145. if (p.PropertyType == typeof(List<IVRInputVar>))
  146. {
  147. var ivr = (List<IVRInputVar>)p.GetValue(b, null);
  148. foreach (IVRInputVar iv in ivr)
  149. {
  150. StringBuilder node = new StringBuilder();
  151. CreateXmlNode(p.Name, ref node, iv,false);
  152. nodes.Add(node);
  153. }
  154. }
  155. if (p.PropertyType == typeof(List<IVRBranchVar>))
  156. {
  157. var ivr = (List<IVRBranchVar>)p.GetValue(b, null);
  158. foreach (IVRBranchVar iv in ivr)
  159. {
  160. StringBuilder node = new StringBuilder();
  161. if (iv.Pos != "0")
  162. {
  163. CreateXmlNode(p.Name, ref node, iv,false);
  164. nodes.Add(node);
  165. }
  166. }
  167. }
  168. }
  169. break;
  170. }
  171. }
  172. foreach (int key in disAtt.Keys.OrderBy(a=>a))
  173. {
  174. if (key == 0)
  175. continue;
  176. xmlBuilder.Append(disAtt[key]+" ");
  177. }
  178. if (nodes.Count == 0)
  179. xmlBuilder.Append("/> \r\n");
  180. else
  181. {
  182. xmlBuilder.Append("> \r\n");
  183. foreach (StringBuilder s in nodes)
  184. xmlBuilder.Append(s.ToString());
  185. xmlBuilder.Append("</" + nodeName + ">");
  186. }
  187. return new MessageInfo() { State = true };
  188. }
  189. catch (Exception ex)
  190. {
  191. return new MessageInfo() { Code = -1, State = false, Message = "生成配置文件发生异常,错误信息:" + ex.Message };
  192. }
  193. }
  194. /// <summary>
  195. /// 解析XML文件到IVR流程设计器
  196. /// </summary>
  197. /// <param name="filePath">要打开的XML文件路径</param>
  198. /// <param name="val">返回解析后的对象</param>
  199. /// <returns></returns>
  200. public override Model.MessageInfo OpenFileInfo(string filePath, ref List<IVRFlowSerializerInfo> val)
  201. {
  202. try
  203. {
  204. Dictionary<string, string> lines = new Dictionary<string, string>();
  205. if (File.Exists(filePath))
  206. {
  207. using (StreamReader reader = new StreamReader(filePath))
  208. {
  209. XmlDocument doc = new XmlDocument();
  210. doc.Normalize();//2017-5-6
  211. doc.InnerXml = reader.ReadToEnd();
  212. XmlNodeList flowNodes = doc.GetElementsByTagName("flow");
  213. foreach (XmlNode node in flowNodes)
  214. {
  215. //val.Add(new IVRFlowSerializerInfo() { IVR_Name = node.Attributes["Name"].Value, IVR_Text = node.Attributes["Name"].Value, IVRFlowType = (IVRFlowType)Enum.Parse(typeof(IVRFlowType), node.Attributes["Type"].Value), IVRControl = new List<IVRControlBase>(), LineNodes = new List<LineInfo>(), IVRVar=new List<IVRDefinevarDefVar>() });
  216. //2017-4-27
  217. //val.Add(new IVRFlowSerializerInfo() { IVR_Name = node.Attributes["IVR_Name"].Value, IVR_Text = node.Attributes["IVR_Text"].Value, IVRFlowType = (IVRFlowType)Enum.Parse(typeof(IVRFlowType), node.Attributes["Type"].Value), IVRControl = new List<IVRControlBase>(), LineNodes = new List<LineInfo>(), IVRVar = new List<IVRDefinevarDefVar>(), FailLineNodes = new List<LineInfo>() });//2017-5-9添加FailLineNodes = new List<LineInfo>()//2019-7-25 注释掉
  218. val.Add(new IVRFlowSerializerInfo() { IVR_Text = node.Attributes["IVR_Text"].Value, IVRFlowType = (IVRFlowType)Enum.Parse(typeof(IVRFlowType), node.Attributes["Type"].Value), IVRControl = new List<IVRControlBase>(), LineNodes = new List<LineInfo>(), IVRVar = new List<IVRDefinevarDefVar>(), FailLineNodes = new List<LineInfo>() });
  219. XmlNodeList CellNode = node.SelectNodes("cell");
  220. foreach (XmlNode cell in CellNode)
  221. {
  222. var type = GlobalController.IVRControls[cell.Attributes["Name"].Value];
  223. val.Last().IVRControl.Add((IVRControlBase)Activator.CreateInstance(type, new object[] { cell.Attributes["Name"].Value }));
  224. val.Last().IVRControl.Last().IVR_Width = Int32.Parse(cell.Attributes["IVR_Width"].Value);
  225. val.Last().IVRControl.Last().IVR_Height = Int32.Parse(cell.Attributes["IVR_Height"].Value);
  226. val.Last().IVRControl.Last().Pos = cell.Attributes["Pos"].Value;
  227. val.Last().IVRControl.Last().CenterPoint = new Point(Int32.Parse(cell.Attributes["IVR_X"].Value), Int32.Parse(cell.Attributes["IVR_Y"].Value));
  228. val.Last().IVRControl.Last().SelectedImage = new Bitmap(@"pic\Selected.png");
  229. val.Last().IVRControl.Last().Image = new Bitmap(@"pic\NoSelect.png");
  230. foreach (PropertyInfo p in type.GetProperties())
  231. {
  232. if ((p.GetCustomAttributes(typeof(IVRAttribute), false)) == null || p.GetCustomAttributes(typeof(IVRAttribute), false).Count() == 0)
  233. continue;
  234. var att = p.GetCustomAttributes(typeof(IVRAttribute), false).Last() as IVRAttribute;
  235. switch (att.IVRSerializerType)
  236. {
  237. case IVRSerializerType.元素:
  238. if (p.Name == "Name") continue;
  239. if (p.PropertyType == typeof(IVRControlBase))
  240. {
  241. if (p.Name == "FailPos")//2017-5-9
  242. {
  243. if (cell.Attributes[p.Name].Value != "0" && !string.IsNullOrEmpty(cell.Attributes[p.Name].Value))
  244. val.Last().FailLineNodes.Add(new LineInfo() { AttributeName = p.Name, StartNodeID = val.Last().IVRControl.Last().Pos, EndNodeID = cell.Attributes[p.Name].Value });
  245. }
  246. else if (cell.Attributes[p.Name].Value != "0" && !string.IsNullOrEmpty(cell.Attributes[p.Name].Value))
  247. val.Last().LineNodes.Add(new LineInfo() { AttributeName = p.Name , StartNodeID = val.Last().IVRControl.Last().Pos, EndNodeID = cell.Attributes[p.Name].Value });
  248. }
  249. else if (p.PropertyType.IsEnum)
  250. {
  251. if (p.PropertyType == typeof(FinishKeyType))
  252. {
  253. foreach (MemberInfo finkey in p.PropertyType.GetMembers())
  254. {
  255. if (finkey.GetCustomAttributes(typeof(DescriptionAttribute), false) != null
  256. && finkey.GetCustomAttributes(typeof(DescriptionAttribute), false).Count() != 0
  257. && (finkey.GetCustomAttributes(typeof(DescriptionAttribute), false).Last() as DescriptionAttribute).Description == cell.Attributes[p.Name].Value)
  258. {
  259. p.SetValue(val.Last().IVRControl.Last(), (int)Enum.Parse(p.PropertyType, finkey.Name, false), null);
  260. }
  261. }
  262. }
  263. else
  264. {
  265. p.SetValue(val.Last().IVRControl.Last(), Enum.Parse(p.PropertyType, cell.Attributes[p.Name].Value), null);
  266. }
  267. }
  268. else
  269. {
  270. if (p.PropertyType == typeof(Int32) || p.PropertyType == typeof(int))
  271. p.SetValue(val.Last().IVRControl.Last(), Int32.Parse(cell.Attributes[p.Name].Value), null);
  272. else if (p.PropertyType == typeof(Boolean) || p.PropertyType == typeof(bool))
  273. //2017-4-28添加
  274. {
  275. bool bvalue = false;
  276. if (cell.Attributes[p.Name].Value.ToString() == "no")
  277. { bvalue = false; }
  278. else if (cell.Attributes[p.Name].Value.ToString() == "yes")
  279. { bvalue = true ; }
  280. else
  281. { bvalue = bool.Parse(cell.Attributes[p.Name].Value); }
  282. p.SetValue(val.Last().IVRControl.Last(), bvalue, null);//p.SetValue(val.Last().IVRControl.Last(), bool.Parse(cell.Attributes[p.Name].Value), null);//2017-4-28
  283. }
  284. else
  285. p.SetValue(val.Last().IVRControl.Last(), cell.Attributes[p.Name].Value.ToString(), null);
  286. }
  287. break;
  288. case IVRSerializerType.节点:
  289. foreach (XmlNode ivrflowNode in cell.ChildNodes)
  290. {
  291. switch (p.Name+" "+ivrflowNode.Name)
  292. {
  293. case "Branch Branch":
  294. ((IVRBranch)val.Last().IVRControl.Last()).Branch.Add(new IVRBranchVar() { Pos = ivrflowNode.Attributes["Pos"].Value, Value = ivrflowNode.Attributes["Value"].Value });
  295. val.Last().LineNodes.Add(new LineInfo() { AttributeName = ivrflowNode.Attributes["Value"].Value, StartNodeID = ((IVRBranch)val.Last().IVRControl.Last()).ID, EndNodeID = ivrflowNode.Attributes["Pos"].Value });
  296. break;
  297. case "DefVar DefVar":
  298. IVRDefinevarDefVar defval = (new IVRDefinevarDefVar() { VarName = ivrflowNode.Attributes["VarName"].Value, VarVal = ivrflowNode.Attributes["VarVal"].Value, VarType = (NumberType)Enum.Parse(typeof(NumberType), ivrflowNode.Attributes["VarType"].Value) });
  299. ((IVRDefinevar)val.Last().IVRControl.Last()).DefVar.Add(defval);
  300. val.Last().IVRVar.Add(defval);
  301. break;
  302. case "IVRInputVar IVRInputVar":
  303. ((IVRSocket)val.Last().IVRControl.Last()).IVRInputVar.Add(new IVRInputVar() { VarVal = ivrflowNode.Attributes["VarVal"].Value, VarType = (NumberType)Enum.Parse(typeof(NumberType), ivrflowNode.Attributes["VarType"].Value) });
  304. break;
  305. case "OutputVar OutputVar":
  306. ((IVRSocket)val.Last().IVRControl.Last()).OutputVar.Add(new IVRDefaultVar() { Var = ivrflowNode.Attributes["Var"].Value });
  307. break;
  308. case "Map Map":
  309. ((IVRRecordSet)val.Last().IVRControl.Last()).Map.Add(new IVRDefaultVar() { Var = ivrflowNode.Attributes["Var"].Value });
  310. break;
  311. default:
  312. break;
  313. }
  314. } break;
  315. }
  316. }
  317. }
  318. }
  319. return new MessageInfo() { Code = 0, Message = "解析完成!", State = true, };
  320. }
  321. }
  322. else
  323. {
  324. return new MessageInfo()
  325. {
  326. Code = -1,
  327. Message = "没有找到IVR图形文件!",
  328. State = false,
  329. };
  330. }
  331. }
  332. catch (Exception ex)
  333. {
  334. return new MessageInfo() { Code = -1, Message = "读取IVR图形文件发生异常,错误信息:" + ex.Message };
  335. }
  336. }
  337. #region 替换指定字符串
  338. /// <summary>
  339. /// 替换指定字符串
  340. /// </summary>
  341. /// <param name="str">待处理的字符串</param>
  342. /// <param name="toRep">要替换的字符串中的子串</param>
  343. /// <param name="strRep">用来替换toRep字符串的字符串</param>
  344. /// <returns>返回一个结果字符串</returns>
  345. public static string StringReplace(string str, string toRep, string strRep)
  346. {
  347. StringBuilder sb = new StringBuilder();
  348. int np = 0, n_ptmp = 0;
  349. for (;;)
  350. {
  351. string str_tmp = str.Substring(np);
  352. n_ptmp = str_tmp.IndexOf(toRep);
  353. if (n_ptmp == -1)
  354. {
  355. sb.Append(str_tmp);
  356. break;
  357. }
  358. else
  359. {
  360. sb.Append(str_tmp.Substring(0, n_ptmp)).Append(strRep);
  361. np += n_ptmp + toRep.Length;
  362. }
  363. }
  364. return sb.ToString();
  365. }
  366. #endregion
  367. }
  368. }