AutoTempHelp.cs 13 KB

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