AutoTempHelp.cs 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333
  1. using Newtonsoft.Json.Linq;
  2. using System;
  3. using System.Collections.Generic;
  4. using System.ComponentModel.DataAnnotations;
  5. using System.Linq;
  6. using System.Reflection;
  7. using System.Text.RegularExpressions;
  8. using Vit.AutoTemp.DataProvider;
  9. using Vit.Core.Module.Log;
  10. using Vit.Core.Util.XmlComment;
  11. using Vit.Db.Module.Schema;
  12. using Vit.Extensions;
  13. namespace Vit.AutoTemp
  14. {
  15. public class AutoTempHelp
  16. {
  17. #region EfEntityToTableSchema
  18. public static TableSchema EfEntityToTableSchema(Type type)
  19. {
  20. TableSchema tableSchema = new TableSchema { table_name=type.GetCustomAttribute<System.ComponentModel.DataAnnotations.Schema.TableAttribute>()?.Name , columns = new List<ColumnSchema>() };
  21. using (var xmlMng = new XmlCommentMng())
  22. {
  23. xmlMng.AddBin();
  24. var xmlHelp = xmlMng.GetXmlHelp(type);
  25. foreach (var field in type.GetProperties())
  26. {
  27. tableSchema.columns.Add(new ColumnSchema
  28. {
  29. column_name = field.Name,
  30. primary_key = (field.GetCustomAttribute<KeyAttribute>() != null) ? 1 : 0,
  31. column_comment = xmlHelp.Property_GetSummary(field),
  32. column_clr_type = field.ReflectedType
  33. });
  34. }
  35. }
  36. return tableSchema;
  37. }
  38. #endregion
  39. #region BuildControllerConfigByTable
  40. public static JObject BuildControllerConfigByType(Type type)
  41. {
  42. return BuildControllerConfigByTable(EfEntityToTableSchema(type));
  43. }
  44. public static JObject BuildControllerConfigByTable(TableSchema tableInfo)
  45. {
  46. #region SplitStringTo2
  47. void SplitStringTo2(string oriString,string splitString,out string part1,out string part2)
  48. {
  49. int splitIndex = oriString.IndexOf(splitString);
  50. if (splitIndex >= 0)
  51. {
  52. part1 = oriString.Substring(0, splitIndex);
  53. part2 = oriString.Substring(splitIndex + splitString.Length);
  54. }
  55. else
  56. {
  57. part1 = oriString;
  58. part2 = null;
  59. }
  60. }
  61. #endregion
  62. var controllerConfig = new JObject();
  63. string idField = null;
  64. string pidField = null;
  65. string rootPidValue = "0";
  66. string treeField = null;
  67. var fields = new JArray();
  68. var filterFields = new JArray();
  69. #region build field
  70. Regex ctrlAttribute = new Regex("\\[[^\\[\\]]+?\\]"); //正则匹配 [editable:true]
  71. foreach (var column in tableInfo.columns)
  72. {
  73. // { field: 'name', title: '装修商', list_width: 200 ,visiable:false,editable:false }
  74. if (column.primary_key == 1)
  75. {
  76. idField = column.column_name;
  77. }
  78. var field = new JObject();
  79. field["field"] = column.column_name;
  80. field["list_width"] = 200;
  81. if (column.primary_key == 1)
  82. {
  83. field["editable"] = false;
  84. }
  85. #region (x.2)从column_comment获取用户配置
  86. // [editable:true]
  87. string comment = column.column_comment;
  88. if (!string.IsNullOrEmpty(comment))
  89. {
  90. foreach (Match item in ctrlAttribute.Matches(comment))
  91. {
  92. string key, value;
  93. #region (x.x.1)获取key value 用户配置信息
  94. var comm = item.Value.Substring(1, item.Value.Length - 2);
  95. SplitStringTo2(comm,":",out key,out value);
  96. value = value?.Replace("\\x5B", "[").Replace("\\x5D", "]");
  97. if (string.IsNullOrWhiteSpace(key)) continue;
  98. #endregion
  99. //(x.x.2)
  100. BuildFieldConfigFromComment(key, value);
  101. }
  102. }
  103. #endregion
  104. //fieldIgnore
  105. if ((comment ?? "").Contains("[fieldIgnore]"))
  106. {
  107. continue;
  108. }
  109. fields.Add(field);
  110. #region (x.3)设置title
  111. {
  112. var title = field["title"].ConvertToString();
  113. if (string.IsNullOrWhiteSpace(title))
  114. {
  115. title = comment ?? column.column_name;
  116. }
  117. title = ctrlAttribute.Replace(title, "");
  118. if (string.IsNullOrWhiteSpace(title))
  119. {
  120. title = column.column_name;
  121. }
  122. field["title"] = title;
  123. }
  124. #endregion
  125. #region (x.4)设置筛选条件的title
  126. {
  127. var title = field["title"];
  128. filterFields.Where(token => token["field"].EqualIgnore(column.column_name)
  129. && string.IsNullOrWhiteSpace(token["title"].ConvertToString())).IEnumerable_ForEach(
  130. token =>
  131. {
  132. token["title"] = title;
  133. });
  134. }
  135. #endregion
  136. #region Method BuildFieldConfigFromComment
  137. void BuildFieldConfigFromComment(string key, string value)
  138. {
  139. if (string.IsNullOrEmpty(key)) return;
  140. #region (x.1)手动指定idField
  141. if (key == "idField")
  142. {
  143. idField = column.column_name;
  144. return;
  145. }
  146. #endregion
  147. #region (x.2)树形列表配置
  148. if (key == "pidField")
  149. {
  150. pidField = column.column_name;
  151. return;
  152. }
  153. if (key == "treeField")
  154. {
  155. treeField = column.column_name;
  156. return;
  157. }
  158. if (key == "rootPidValue")
  159. {
  160. rootPidValue = value;
  161. return;
  162. }
  163. #endregion
  164. #region (x.3)列表筛选条件
  165. // [filter:开始时间,>=] 当前列作为筛选条件,筛选条件名称为开始时间,筛选方式为">="
  166. // filter:
  167. // { field: 'name', title: '装修商',filterOpt:'=' }
  168. if (key == "filter")
  169. {
  170. var prorerty = value.Split(',');
  171. var filterField = new JObject()
  172. {
  173. ["class"] = "Text",
  174. ["field"] = column.column_name,
  175. //["title"] = "Text",
  176. ["filterOpt"] = "="
  177. };
  178. filterFields.Add(filterField);
  179. #region (x.x.1)筛选方式
  180. if (prorerty.Length > 1)
  181. {
  182. filterField["filterOpt"] = prorerty[1];
  183. }
  184. #endregion
  185. #region (x.x.2)title
  186. if (prorerty.Length > 0)
  187. {
  188. filterField["title"] = prorerty[0];
  189. }
  190. #endregion
  191. }
  192. #endregion
  193. #region (x.4)设置controller的属性
  194. if (key == "controller")
  195. {
  196. try
  197. {
  198. SplitStringTo2(value, "=", out var part1, out var part2);
  199. object jsonValue;
  200. try
  201. {
  202. jsonValue = part2?.Deserialize<object>();
  203. }
  204. catch
  205. {
  206. jsonValue = part2;
  207. }
  208. controllerConfig.ValueSetByPath(jsonValue, part1.Split('.'));
  209. }
  210. catch (Exception ex)
  211. {
  212. Logger.Error(ex);
  213. }
  214. return;
  215. }
  216. #endregion
  217. #region (x.5)直接作为控件属性
  218. if (key == "field")
  219. {
  220. try
  221. {
  222. SplitStringTo2(value, "=", out var part1, out var part2);
  223. object jsonValue;
  224. try
  225. {
  226. jsonValue = part2?.Deserialize<object>();
  227. }
  228. catch
  229. {
  230. jsonValue = part2;
  231. }
  232. field.ValueSetByPath(jsonValue, part1.Split('.'));
  233. }
  234. catch (Exception ex)
  235. {
  236. Logger.Error(ex);
  237. }
  238. return;
  239. }
  240. #endregion
  241. }
  242. #endregion
  243. }
  244. #endregion
  245. controllerConfig["fields"] = fields;
  246. controllerConfig["filterFields"] = filterFields;
  247. controllerConfig["idField"] = idField;
  248. controllerConfig["treeField"] = treeField;
  249. controllerConfig["pidField"] = pidField;
  250. controllerConfig["rootPidValue"] = rootPidValue;
  251. return controllerConfig;
  252. }
  253. #endregion
  254. #region static dataProviderMap
  255. public readonly static SortedDictionary<string, IDataProvider> dataProviderMap = new SortedDictionary<string, IDataProvider>();
  256. public static void RegistDataProvider(params IDataProvider[] dataProviders)
  257. {
  258. lock (dataProviderMap)
  259. {
  260. foreach (var dataProvider in dataProviders)
  261. {
  262. dataProviderMap[dataProvider.template] = dataProvider;
  263. }
  264. }
  265. }
  266. public static void UnRegistDataProvider(params IDataProvider[] dataProviders)
  267. {
  268. lock (dataProviderMap)
  269. foreach (var dataProvider in dataProviders)
  270. {
  271. dataProviderMap.Remove(dataProvider.template);
  272. }
  273. }
  274. public static IDataProvider GetDataProvider(string template)
  275. {
  276. return dataProviderMap.TryGetValue(template, out var v) ? v : null;
  277. }
  278. #endregion
  279. }
  280. }