SchoolService.cs 52 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065
  1. using Azure.Cosmos;
  2. using DocumentFormat.OpenXml.Bibliography;
  3. using HTEXLib.COMM.Helpers;
  4. using Microsoft.AspNetCore.Hosting;
  5. using Microsoft.International.Converters.PinYinConverter;
  6. using Microsoft.International.Converters.TraditionalChineseToSimplifiedConverter;
  7. using System;
  8. using System.Collections.Generic;
  9. using System.IO;
  10. using System.Linq;
  11. using System.Text;
  12. using System.Text.Json;
  13. using System.Text.RegularExpressions;
  14. using System.Threading.Tasks;
  15. using TEAMModelOS.Models;
  16. using TEAMModelOS.SDK.DI;
  17. using TEAMModelOS.SDK.Extension;
  18. using TEAMModelOS.SDK.Models;
  19. namespace TEAMModelOS.SDK
  20. {
  21. public class SchoolService
  22. {
  23. /// <summary>
  24. /// 根据年级获取入学
  25. /// </summary>
  26. /// <param name="semesterList"></param>
  27. /// <returns></returns>
  28. public static (List<KeyValuePair<int, int>> gradeYear, HashSet<int> years) GetYears(School school, string periodId, IEnumerable<int> grades, long time = 0) {
  29. var date = DateTimeOffset.UtcNow;
  30. //2001-09-09 09:46:40
  31. if (time > 1000000000000)
  32. {
  33. date = DateTimeOffset.FromUnixTimeMilliseconds(time);
  34. }
  35. //年级算法
  36. var period = school.period.Find(x => x.id.Equals(periodId));
  37. int Day = date.Day;
  38. int Month = date.Month;
  39. int Year = date.Year;
  40. int start = int.Parse($"{Year}0901");
  41. var se = period.semesters.Find(x => x.start == 1);
  42. if (se == null)
  43. {
  44. se = period.semesters.First();
  45. }
  46. string sm = "09";
  47. string sd = "01";
  48. if (se != null)
  49. {
  50. sm = se.month >= 10 ? $"{se.month}" : $"0{se.month}";
  51. sd = se.day >= 10 ? $"{se.day}" : $"0{se.day}";
  52. start = int.Parse($"{Year}{sm}{sd}");
  53. }
  54. int curr = int.Parse(date.ToString("yyyyMMdd"));
  55. //新学年开学时间大于当前时间,计算年级需要减1 20220901-20220408 > 0 则当前20220408是2021年入学的,
  56. //当前时间大于新学年开学时间,计算年级则不需要 20220901-20221203 < 1 则当前20221203是2022年入学的,
  57. //20230901-20230101 > 0 则当前20230101是2022年入学的,
  58. int dis = start - curr;
  59. List<int > years= new List<int>();
  60. List<KeyValuePair<int, int>> gradeYear = new List<KeyValuePair<int, int>>();
  61. foreach (int grade in grades) {
  62. int year = 0;
  63. if (dis > 0)
  64. {
  65. year = Year - grade -1;
  66. }
  67. else {
  68. year= Year - grade ;
  69. }
  70. years.Add(year);
  71. gradeYear.Add(new KeyValuePair<int, int>(grade,year ));
  72. }
  73. return (gradeYear,years.ToHashSet());
  74. }
  75. /// <summary>
  76. /// 根据年份获取年级,只返回time 或当前时间以前入学的学生年级。
  77. /// </summary>
  78. /// <param name="semesterList"></param>
  79. /// <returns></returns>
  80. public static (List<KeyValuePair<int, string>> yearGrade,HashSet<string> grades) GetGrades(School school,string periodId , IEnumerable<int> years,long time =0) {
  81. var date = DateTimeOffset.UtcNow;
  82. //2001-09-09 09:46:40
  83. if (time > 1000000000000) {
  84. date = DateTimeOffset.FromUnixTimeMilliseconds(time);
  85. }
  86. //年级算法
  87. var period = school.period.Find(x => x.id.Equals(periodId));
  88. int? Count = period?.grades?.Count;
  89. List<KeyValuePair<int, string>> yearGrades = new List<KeyValuePair<int, string>>();
  90. if (Count.HasValue)
  91. {
  92. int Day = date.Day;
  93. int Month = date.Month;
  94. int Year = date.Year;
  95. int start = int.Parse($"{Year}0901");
  96. var se = period.semesters.Find(x => x.start == 1);
  97. if (se == null)
  98. {
  99. se = period.semesters.First();
  100. }
  101. string sm = "09";
  102. string sd = "01";
  103. if (se != null)
  104. {
  105. sm = se.month >= 10 ? $"{se.month}" : $"0{se.month}";
  106. sd = se.day >= 10 ? $"{se.day}" : $"0{se.day}";
  107. start = int.Parse($"{Year}{sm}{sd}");
  108. }
  109. int curr = int.Parse(date.ToString("yyyyMMdd"));
  110. //新学年开学时间大于当前时间,计算年级需要减1 20220901-20220408 > 0 则当前20220408是2021年入学的,
  111. //当前时间大于新学年开学时间,计算年级则不需要 20220901-20221203 < 1 则当前20221203是2022年入学的,
  112. //20230901-20230101 > 0 则当前20230101是2022年入学的,
  113. int dis = start - curr;
  114. foreach (int year in years)
  115. {
  116. if (int.Parse($"{year}{sm}{sd}") < curr) {
  117. int grade;
  118. if (dis > 0)
  119. {
  120. grade = Math.Abs((Year - year - 1)) % Count.Value;
  121. }
  122. else
  123. {
  124. grade = Math.Abs((Year - year)) % Count.Value;
  125. }
  126. yearGrades.Add(new KeyValuePair<int, string>(year, $"{grade}"));
  127. }
  128. }
  129. }
  130. return (yearGrades, yearGrades.Select(z=>z.Value).ToHashSet());
  131. }
  132. /// <summary>
  133. /// 处理学期排序
  134. /// </summary>
  135. /// <param name="semesterList"></param>
  136. /// <returns></returns>
  137. public static List<Semester> SortSemester(List<Semester> semesterList)
  138. {
  139. int Year = DateTimeOffset.UtcNow.Year;
  140. List<KeyValuePair<int, Semester>> pairs = new List<KeyValuePair<int, Semester>>();
  141. semesterList.ForEach(se => {
  142. string sm = se.month >= 10 ? $"{se.month}" : $"0{se.month}";
  143. string sd = se.day >= 10 ? $"{se.day}" : $"0{se.day}";
  144. int order = int.Parse($"{Year}{sm}{sd}");
  145. pairs.Add(new KeyValuePair<int, Semester>(order, se));
  146. });
  147. var orderPairs = pairs.OrderBy(z => z.Key);
  148. semesterList = orderPairs.Select(z => z.Value).ToList();
  149. int startIndex = semesterList.FindIndex(z => z.start == 1);
  150. if (startIndex == -1)
  151. {
  152. //未设置学期的情况默认9月份开始的。
  153. startIndex = semesterList.FindIndex(z => z.month == 9);
  154. //如果还未找到,就以排序结果为准
  155. if (startIndex == -1)
  156. {
  157. startIndex = 0;
  158. }
  159. }
  160. if (startIndex > 0)
  161. {
  162. List<Semester> before = semesterList.Take(startIndex).ToList();
  163. List<Semester> after = semesterList.Skip(startIndex).ToList();
  164. semesterList = new List<Semester>();
  165. semesterList.AddRange(after);
  166. semesterList.AddRange(before);
  167. return semesterList;
  168. }
  169. else
  170. {
  171. return semesterList;
  172. }
  173. }
  174. public static async Task<(List<Class> school_classes, List<Class> graduate_classes)> DoGraduateClasses(HttpTrigger _httpTrigger, AzureCosmosFactory _azureCosmos, List<string> periodIds, School school_base, Option _option,DingDing _dingDing, int waite = 0) {
  175. List<Class> school_classes = new List<Class>();
  176. List<Class> graduate_classes = new List<Class>();
  177. try
  178. {
  179. var client = _azureCosmos.GetCosmosClient();
  180. //取得班级
  181. int nowYear = DateTimeOffset.UtcNow.Year;
  182. int nowMonth = DateTimeOffset.UtcNow.Month;
  183. int nowDay = DateTimeOffset.UtcNow.Day;
  184. //因为修改年级,而导致取消的
  185. List<Class> cancel_graduate_classes = new List<Class>();
  186. string sql = $"SELECT value c FROM c where (c.graduate = 0 or IS_DEFINED(c.graduate) = false) ";
  187. if (periodIds.IsNotEmpty())
  188. {
  189. sql = $"SELECT value c FROM c where c.periodId in ({string.Join(",", periodIds.Select(x => $"'{x}'"))}) ";
  190. }
  191. await foreach (var item in client.GetContainer(Constant.TEAMModelOS, "School").GetItemQueryIterator<Class>
  192. //(queryText: $"SELECT value c FROM c where (c.graduate = 0 or IS_DEFINED(c.graduate) = false)",
  193. (queryText: sql,
  194. requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"Class-{school_base.id}") }))
  195. {
  196. bool isgraduate = false;
  197. if (!string.IsNullOrWhiteSpace(item.periodId))
  198. {
  199. var period = school_base.period.Find(x => x.id.Equals(item.periodId));
  200. if (period != null)
  201. {
  202. var gradeCount = period.grades.Count();
  203. //2022-2016=6(待判断月份日期是否是毕业) 2022-2017=5(未毕业)
  204. if (nowYear - item.year > gradeCount)
  205. {
  206. isgraduate = true;
  207. }
  208. else if (nowYear - item.year == gradeCount)
  209. {
  210. var semester = period.semesters.Find(x => x.start == 1);
  211. if (semester != null)
  212. {
  213. if (nowMonth > semester.month)
  214. {
  215. isgraduate = true;
  216. }
  217. else if (nowMonth == semester.month)
  218. {
  219. if (nowDay >= semester.day)
  220. {
  221. isgraduate = true;
  222. }
  223. else
  224. {
  225. }
  226. }
  227. else { isgraduate = false; }
  228. }
  229. }
  230. else
  231. {
  232. isgraduate = false;
  233. }
  234. }
  235. }
  236. if (isgraduate)
  237. {
  238. graduate_classes.Add(item);
  239. }
  240. else
  241. {
  242. if (item.graduate == 1)
  243. {
  244. item.graduate = 0;
  245. cancel_graduate_classes.Add(item);
  246. }
  247. school_classes.Add(item);
  248. }
  249. }
  250. if (graduate_classes.Any() || cancel_graduate_classes.Any())
  251. {
  252. if (waite == 0)
  253. {
  254. _ = _httpTrigger.RequestHttpTrigger(new { graduate_classes = graduate_classes, cancel_graduate_classes = cancel_graduate_classes, schoolId = $"{school_base.id}" }, _option.Location, "graduate-change");
  255. }
  256. else
  257. {
  258. await _httpTrigger.RequestHttpTrigger(new { graduate_classes = graduate_classes, cancel_graduate_classes = cancel_graduate_classes, schoolId = $"{school_base.id}" }, _option.Location, "graduate-change");
  259. }
  260. }
  261. } catch (Exception ex) {
  262. await _dingDing.SendBotMsg($"{_option.Location},{ex.Message}\n{ex.StackTrace}", GroupNames.醍摩豆服務運維群組);
  263. }
  264. return (school_classes,graduate_classes);
  265. }
  266. public static async Task<object> DoScsApiSchool(HttpTrigger _httpTrigger,Dictionary<string,object> dict, Option _option, List<IdNameCode> ignore,
  267. string areaId,string city,string dist, AzureStorageFactory _azureStorage ,DingDing _dingDing, IWebHostEnvironment _environment
  268. )
  269. {
  270. List<ScSchool> tbschools = null;
  271. List<ScSchool> matchSchools = null;
  272. List<ScSchool> schools = null;
  273. List<ScSchool> saveschools = null;
  274. var table = _azureStorage.GetCloudTableClient().GetTableReference("ScYxpt");
  275. // 5.3.1.18根据机构ID、项目ID、子项目ID返回学校列表
  276. ( int status, string json) = await _httpTrigger.RequestHttpTrigger(dict, _option.Location, "GetSchoolList");
  277. if (status == 200)
  278. {
  279. schools = json.ToObject<List<ScSchool>>(new JsonSerializerOptions { PropertyNameCaseInsensitive = false });
  280. if (ignore.IsNotEmpty())
  281. {
  282. matchSchools = schools.FindAll(x => ignore.Select(y => y.name).Contains(x.schoolname));
  283. if (matchSchools.IsNotEmpty())
  284. {
  285. if (matchSchools.Count != ignore.Count)
  286. {
  287. var matched = matchSchools.Select(x => x.schoolname);
  288. var unmatch = ignore.Select(y => y.name).Except(matched);
  289. List<string> scschoolUnmatch = schools.Select(y => y.schoolname).Except(matched).ToList();
  290. if (scschoolUnmatch.IsNotEmpty())
  291. {
  292. return new { matched, unmatch, scschoolUnmatch };
  293. }
  294. }
  295. else
  296. {
  297. matchSchools.ForEach(x => {
  298. var exschool = ignore.Find(y => y.name.Equals(x.schoolname));
  299. if (exschool != null)
  300. {
  301. x.schoolCode = exschool.id;
  302. x.areaId = $"{areaId}";
  303. x.city = $"{city}";
  304. x.dist = $"{dist}";
  305. }
  306. });
  307. }
  308. }
  309. else
  310. {
  311. return new { unmatch = ignore, schools };
  312. }
  313. }
  314. //数据校验
  315. tbschools = await table.FindListByDict<ScSchool>(new Dictionary<string, object>() { { "PartitionKey", "ScSchool" } });
  316. if (tbschools.IsNotEmpty())
  317. {
  318. var a = tbschools.Select(y => $"{y.RowKey}").ToList();
  319. saveschools = schools.Where(x => !a.Exists(z => z.Equals($"{x.schoolid}"))).ToList();
  320. List<SchoolData> schoolDatas = new List<SchoolData>();
  321. saveschools.ForEach(x =>
  322. {
  323. x.RowKey = $"{x.schoolid}";
  324. x.PartitionKey = "ScSchool";
  325. x.areaId = $"{areaId}";
  326. x.city = $"{city}";
  327. x.dist = $"{dist}";
  328. if (string.IsNullOrEmpty(x.schoolCode))
  329. {
  330. if (string.IsNullOrEmpty(x.schoolCode))
  331. {
  332. schoolDatas.Add(new SchoolData { uid = $"{x.schoolid}", province = "四川省", city = $"{city}", name = x.schoolname });
  333. }
  334. }
  335. });
  336. schoolDatas = await SchoolService.GenerateSchoolCode(schoolDatas, _dingDing, _environment);
  337. saveschools.ForEach(x => {
  338. var schoolData = schoolDatas.Find(y => y.uid.Equals($"{x.schoolid}"));
  339. if (schoolData != null && !string.IsNullOrEmpty(schoolData.id))
  340. {
  341. x.schoolCode = schoolData.id;
  342. x.areaId = $"{areaId}";
  343. x.city = $"{city}";
  344. x.dist = $"{dist}";
  345. }
  346. });
  347. saveschools.RemoveAll(x => string.IsNullOrEmpty(x.schoolCode));
  348. saveschools.RemoveAll(x => tbschools.FindAll(z => !string.IsNullOrEmpty(z.schoolCode)).Exists(y => y.schoolCode.Equals(x.schoolCode)));
  349. saveschools = await table.SaveAll(saveschools);
  350. }
  351. else
  352. {
  353. List<SchoolData> schoolDatas = new List<SchoolData>();
  354. schools.ForEach(x =>
  355. {
  356. x.RowKey = $"{x.schoolid}";
  357. x.PartitionKey = "ScSchool";
  358. x.areaId = $"{areaId}";
  359. x.city = $"{city}";
  360. x.dist = $"{dist}";
  361. var a = ignore.Find(z => z.name.Equals(x.schoolname));
  362. if (a != null)
  363. {
  364. x.schoolCode = a.id;
  365. }
  366. else
  367. {
  368. if (string.IsNullOrEmpty(x.schoolCode))
  369. {
  370. schoolDatas.Add(new SchoolData { uid = $"{x.schoolid}", province = "四川省", city = $"{city}", name = x.schoolname });
  371. }
  372. }
  373. });
  374. schoolDatas = await SchoolService.GenerateSchoolCode(schoolDatas, _dingDing, _environment);
  375. schools.ForEach(x => {
  376. var schoolData = schoolDatas.Find(y => y.uid.Equals($"{x.schoolid}"));
  377. if (schoolData != null && !string.IsNullOrEmpty(schoolData.id))
  378. {
  379. x.schoolCode = schoolData.id;
  380. x.areaId = $"{areaId}";
  381. x.city = $"{city}";
  382. x.dist = $"{dist}";
  383. }
  384. });
  385. schools.RemoveAll(x => string.IsNullOrEmpty(x.schoolCode));
  386. saveschools = await table.SaveOrUpdateAll(schools);
  387. }
  388. }
  389. return null;
  390. }
  391. public static async Task<List<SchoolData>> GenerateSchoolCode(List<SchoolData> schools, DingDing _dingDing, IWebHostEnvironment _environment)
  392. {
  393. string path = $"{_environment.ContentRootPath}/JsonFile/Core/region.json";
  394. //var schools = jsonstr.ToObject<JsonElement>().GetProperty("schools").ToObject<List<SchoolData>>();
  395. schools = schools.Where((x, i) => schools.FindIndex(n => n.name.Equals(x.name)) == i).ToList();
  396. StreamReader streamReader = new StreamReader(new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.ReadWrite), Encoding.UTF8);
  397. StringBuilder stringBuilder = new StringBuilder();
  398. string text;
  399. while ((text = streamReader.ReadLine()) != null)
  400. {
  401. stringBuilder.Append(text.ToString());
  402. }
  403. streamReader.Close();
  404. string input = stringBuilder.ToString();
  405. List<Region> region = input.ToObject<List<Region>>();
  406. try
  407. {
  408. schools.ForEach(x =>
  409. {
  410. x.province = ChineseConverter.Convert(x.province, ChineseConversionDirection.TraditionalToSimplified);
  411. if (String.IsNullOrEmpty(x.city))
  412. {
  413. x.city = x.province;
  414. }
  415. else
  416. {
  417. x.city = ChineseConverter.Convert(x.city, ChineseConversionDirection.TraditionalToSimplified);
  418. }
  419. x.name = ChineseConverter.Convert(x.name, ChineseConversionDirection.TraditionalToSimplified);
  420. comeRemoveStr.ForEach(c => { x.province = x.province.Replace(c, ""); });
  421. prvcRemoveStr.ForEach(c => { x.province = x.province.Replace(c, ""); });
  422. var province = region.Find(r => r.name.Contains(x.province));
  423. string tmpprovince = x.province;
  424. string tmpcity = x.city;
  425. if (province != null)
  426. {
  427. x.province = province.name;
  428. comeRemoveStr.ForEach(c => { x.city = x.city.Replace(c, ""); });
  429. cityRemoveStr.ForEach(c => { x.city = x.city.Replace(c, ""); });
  430. nationRemoveStr.ForEach(c => { x.city = x.city.Replace(c, ""); });
  431. tmpcity = x.city;
  432. var city = province.children.Find(r => r.name.Contains(x.city));
  433. if (city == null)
  434. {
  435. city = province.children.Find(r => r.name.Contains(x.city));
  436. if (city == null)
  437. {
  438. city = province.children.SelectMany(x => x.children).ToList().Find(r => r.name.Contains(x.city));
  439. }
  440. }
  441. if (city != null)
  442. {
  443. x.city = city.name;
  444. }
  445. }
  446. string name = x.name;
  447. //去除冗余的学校信息,只保留地名和校名关键信息
  448. schemoveStr.ForEach(str =>
  449. {
  450. name = name.Replace(str, "");
  451. });
  452. string[] names = name.Split("(");
  453. if (names.Length > 1)
  454. {
  455. name = $"{names[0]}";
  456. for (int index = 1; index < names.Length; index++)
  457. {
  458. name = $"{name}{names[index].Substring(0, 1)}";
  459. var afnames = names[index].Split(")");
  460. if (afnames.Length > 1)
  461. {
  462. for (int i = 1; i < afnames.Length; i++)
  463. {
  464. name = $"{name}{afnames[i]}";
  465. }
  466. }
  467. }
  468. }
  469. names = name.Split("(");
  470. if (names.Length > 1)
  471. {
  472. name = $"{names[0]}";
  473. for (int index = 1; index < names.Length; index++)
  474. {
  475. name = $"{name}{names[index].Substring(0, 1)}";
  476. var afnames = names[index].Split(")");
  477. if (afnames.Length > 1)
  478. {
  479. for (int i = 1; i < afnames.Length; i++)
  480. {
  481. name = $"{name}{afnames[i]}";
  482. }
  483. }
  484. }
  485. }
  486. name = Regex.Replace(name, "[ \\[ \\] \\^ \\-|()【】/' {}_*×――(^)$%~!@#$…&%¥—+=<>《》!!???::•`·、。,;,.;\"‘’“”-]", " ");
  487. //检查是否有英文
  488. if (Regex.Matches(name, "[a-zA-Z]").Count > 0)
  489. {
  490. var array = Regex.Split(name, "\\s+", RegexOptions.IgnoreCase);
  491. StringBuilder tmpname = new StringBuilder();
  492. if (array.Length > 1)
  493. {
  494. foreach (var item in array)
  495. {
  496. var arr = item.Select(x => $"{x}");
  497. int index = 0;
  498. foreach (var stra in arr)
  499. {
  500. if (Regex.Matches(stra, "[a-zA-Z]").Count > 0)
  501. {
  502. if (index == 1|| index == 0)
  503. {
  504. tmpname.Append(stra);
  505. }
  506. else
  507. {
  508. }
  509. }
  510. else
  511. {
  512. tmpname.Append(stra);
  513. }
  514. index++;
  515. }
  516. }
  517. }
  518. else
  519. {
  520. var arr = name.Select(x => $"{x}");
  521. int index = 0;
  522. foreach (var stra in arr)
  523. {
  524. if (Regex.Matches(stra, "[A-Z]").Count > 0)
  525. {
  526. tmpname.Append(stra);
  527. }
  528. else if (Regex.Matches(stra, "[a-z]").Count > 0)
  529. {
  530. }
  531. else
  532. {
  533. tmpname.Append(stra);
  534. }
  535. index++;
  536. }
  537. }
  538. name = tmpname.ToString();
  539. }
  540. name = Regex.Replace(name, @"\s", "");
  541. name = name.Replace("\\", "");
  542. if (name.Length > 6)
  543. {
  544. //新区,高新,产业等非新政单位
  545. areaRemoveStr.ForEach(str =>
  546. {
  547. name = name.Replace(str.Key, str.Value);
  548. });
  549. //去除冗余的学校信息,只保留地名和校名关键信息
  550. schooRemoveStr.ForEach(str =>
  551. {
  552. name = name.Replace(str, "");
  553. });
  554. //替换民族信息词
  555. if (name.Length > 6)
  556. {
  557. nationRemoveStr.ForEach(str =>
  558. {
  559. name = name.Replace(str, "");
  560. });
  561. }
  562. //替换学校信息的副词
  563. if (name.Length > 6)
  564. {
  565. foreach (var str in schooReplaceStr)
  566. {
  567. if (name.Length <= 6)
  568. {
  569. break;
  570. }
  571. name = name.Replace(str.Key, str.Value);
  572. }
  573. }
  574. //替换省简称信息词
  575. string tmpname = name;
  576. if (name.Length > 6)
  577. {
  578. proReplaceStr.ForEach(str =>
  579. {
  580. name = name.Replace(str.Key, str.Value);
  581. });
  582. //如果替换后仍然大于6位,则取消,直接替换省份完整的词
  583. if (name.Length > 6)
  584. {
  585. name = tmpname.Replace(tmpprovince, "");
  586. }
  587. }
  588. //替换城市信息词
  589. if (name.Length > 6)
  590. {
  591. name = name.Replace(tmpcity, "");
  592. }
  593. }
  594. int len = name.Length;
  595. if (len > 6)
  596. {
  597. foreach (var str in afterSchoolRm)
  598. {
  599. if (name.Length <= 6)
  600. {
  601. break;
  602. }
  603. name = name.Replace(str, "");
  604. }
  605. }
  606. len = name.Length;
  607. if (len >= 6)
  608. {
  609. name = $"{name.Substring(0, 1)}{name.Substring(len - 5, 3)}{name.Substring(len - 2, 2)}";
  610. }
  611. //if (len <= 7 && len > 6)
  612. //{
  613. // name = name.Substring(len - 6);
  614. //}
  615. if (len <= 4)
  616. {
  617. name = $"{x.city.Substring(0, 2)}{name}";
  618. }
  619. if (len == 5)
  620. {
  621. name = $"{x.city.Substring(0, 1)}{name}";
  622. }
  623. string code = ToFirstPinYin(name);
  624. x.aname = name;
  625. x.id = code;
  626. });
  627. }
  628. catch (Exception ex)
  629. {
  630. await _dingDing.SendBotMsg($"{ex.Message}\n{ex.StackTrace}\n", GroupNames.醍摩豆服務運維群組);
  631. }
  632. string a_z = "abcdefghijklmnopqrstuvwxyz";
  633. var data = schools.GroupBy(x => x.id).Select(x => new { key = x.Key, more = x.ToList().Count > 2, count = x.ToList().Count, list = x.ToList() }).ToList();
  634. data.ForEach(x =>
  635. {
  636. if (x.count > 1)
  637. {
  638. var first = x.list.First();
  639. var same = x.list.Skip(1).Take(x.count - 1).ToList();
  640. var fs = first.aname.Select(x => x).ToArray();
  641. same.ForEach(z =>
  642. {
  643. var sp = z.aname.Select(x => x).ToArray();
  644. int len = sp.Length;
  645. if (sp.Length >= fs.Length)
  646. {
  647. len = fs.Count();
  648. }
  649. for (int index = 0; index < len; index++)
  650. {
  651. if (!$"{sp[index]}".Equals($"{fs[index]}"))
  652. {
  653. short st = ChineseChar.GetStrokeNumber(sp[index]);
  654. if (st > 0)
  655. {
  656. var ins = st % 27;
  657. var insch = a_z[ins];
  658. if (z.aname.EndsWith($"{insch}"))
  659. {
  660. ins = (st + 1) % 27;
  661. insch = a_z[ins];
  662. }
  663. z.id = z.id.Insert(index, $"{insch}").Remove(index + 1, 1);
  664. break;
  665. }
  666. }
  667. }
  668. });
  669. }
  670. });
  671. var dataz = data.SelectMany(y=>y.list).GroupBy(x => x.id).Select(x => new { key = x.Key, more = x.ToList().Count > 2, count = x.ToList().Count, list = x.ToList() }).ToList();
  672. dataz.ForEach(x =>
  673. {
  674. if (x.count > 1)
  675. {
  676. var first = x.list.First();
  677. var same = x.list.Skip(1).Take(x.count - 1).ToList();
  678. var fs = first.aname.Select(x => x).ToArray();
  679. same.ForEach(z =>
  680. {
  681. var sp = z.aname.Select(x => x).ToArray();
  682. int len = sp.Length;
  683. if (sp.Length >= fs.Length)
  684. {
  685. len = fs.Count();
  686. }
  687. for (int index = 0; index < len; index++)
  688. {
  689. if (!$"{sp[index]}".Equals($"{fs[index]}"))
  690. {
  691. var spstr = ToPinYin($"{sp[index]}" );
  692. var fsstr = ToPinYin($"{fs[index]}");
  693. var insch= spstr.Select(x => $"{x}").Except( fsstr.Select(z => $"{z}"));
  694. if (insch != null && insch.Count() > 0) {
  695. if (index > 1)
  696. {
  697. z.id = z.id.Insert(index - 1, insch.First()).Remove(index, 1);
  698. }
  699. else if (index == 1)
  700. {
  701. z.id = z.id.Insert(index, insch.First()).Remove(index - 1, 1);
  702. }
  703. }
  704. }
  705. }
  706. });
  707. }
  708. });
  709. var dataa = dataz.SelectMany(y => y.list).GroupBy(x => x.id).Select(x => new { key = x.Key, more = x.ToList().Count > 2, count = x.ToList().Count, list = x.ToList() }).ToList();
  710. Random random = new Random();
  711. List<SchoolData> list = new List<SchoolData>();
  712. dataa.ForEach(x =>
  713. {
  714. if (x.count > 1)
  715. {
  716. x.list.ForEach(y => {
  717. int r= random.Next(25);
  718. int index= random.Next(5);
  719. y.id = y.id.Insert(index - 1, $"{a_z[r]}").Remove(index, 1);
  720. });
  721. }
  722. list.AddRange(x.list);
  723. });
  724. return list;
  725. }
  726. public static string ToPinYin(string val)
  727. {
  728. StringBuilder sb = new StringBuilder();
  729. val.ToCharArray().ToList().ForEach(x =>
  730. {
  731. if (('a' <= x && x <= 'z') || ('A' <= x && x <= 'Z') || ('0' <= x && x <= '9'))
  732. {
  733. sb.Append(x);
  734. }
  735. else
  736. {
  737. try
  738. {
  739. ChineseChar cc = new ChineseChar(x);
  740. if (cc.Pinyins.Count > 0 && cc.Pinyins[0].Length > 0)
  741. {
  742. sb.Append(cc.Pinyins[0]);
  743. }
  744. }
  745. catch (Exception ex)
  746. {
  747. }
  748. }
  749. });
  750. return sb.ToString().ToLower();
  751. }
  752. public static string ToFirstPinYin(string val)
  753. {
  754. StringBuilder sb = new StringBuilder();
  755. val.ToCharArray().ToList().ForEach(x =>
  756. {
  757. if (('a' <= x && x <= 'z') || ('A' <= x && x <= 'Z') || ('0' <= x && x <= '9'))
  758. {
  759. sb.Append(x);
  760. }
  761. else
  762. {
  763. try
  764. {
  765. ChineseChar cc = new ChineseChar(x);
  766. if (cc.Pinyins.Count > 0 && cc.Pinyins[0].Length > 0)
  767. {
  768. sb.Append(cc.Pinyins[0][0]);
  769. }
  770. }
  771. catch (Exception ex)
  772. {
  773. }
  774. }
  775. });
  776. return sb.ToString().ToLower();
  777. }
  778. public class SchoolData
  779. {
  780. public string province { get; set; }
  781. public string id { get; set; }
  782. public string name { get; set; }
  783. public string city { get; set; }
  784. public string aname { get; set; }
  785. public string uid { get; set; }
  786. }
  787. public static List<string> comeRemoveStr = new List<string>() { "省", "市", "区", "州", "县", "旗", "盟", "自治" };
  788. public static List<string> prvcRemoveStr = new List<string>() { "回族", "维吾尔", "壮族", };
  789. public static List<string> cityRemoveStr = new List<string>() { "蒙古族", "地区", "壮族", "朝鲜族", "直辖" };
  790. public static List<string> nationRemoveStr = new List<string> {
  791. "维吾尔","回族", "自治", "满族", "蒙古", "壮族", "苗族" , "侗族", "瑶族",
  792. "达斡尔","鄂温克","朝鲜","畲族","土家","各族","仫佬","毛南","羌族","彝族","仡佬","布依","水族",
  793. "傣族","纳西","哈尼","拉祜","佤族","傈僳","独龙","怒族","白族","普米","固族","哈萨克","土族","撒拉","景颇","族"
  794. };
  795. public static List<string> schemoveStr = new List<string> { "第", "校区", "部", "楼", "与", "学校", "校园", };
  796. public static List<string> schooRemoveStr = new List<string>() {"省", "市", "区", "州", "县", "旗", "盟","办事处","街道", "自治",
  797. "镇","村","乡","街","路","站","馆"
  798. };
  799. public static List<string> afterSchoolRm = new List<string>() {"校","园","院", "湾","峡","沟","山","庄",
  800. "堡","江","屯","岭","溪","河","桥","营","铺","坡","寨","场","湖","巷","集","关","庙","寺","矿","塘"};
  801. public static List<KeyValuePair<string, string>> areaRemoveStr = new List<KeyValuePair<string, string>>{
  802. new KeyValuePair<string, string>("高新技术产业开发区", "高") ,
  803. new KeyValuePair<string, string>("经济技术开发区", "经") ,
  804. new KeyValuePair<string, string>("国际", "际") ,
  805. new KeyValuePair<string, string>("中国", ""),
  806. new KeyValuePair<string, string>("国家", ""),
  807. new KeyValuePair<string, string>("新区", ""),
  808. new KeyValuePair<string, string>("高新", "高"),
  809. new KeyValuePair<string, string>("园区", ""),
  810. new KeyValuePair<string, string>("产业", "产"),
  811. new KeyValuePair<string, string>("经济", "经"),
  812. new KeyValuePair<string, string>("开发", "开"),
  813. new KeyValuePair<string, string>("中心", "") ,
  814. new KeyValuePair<string, string>("集团", "") ,
  815. new KeyValuePair<string, string>("公司", "") ,
  816. new KeyValuePair<string, string>("有限", "") ,
  817. new KeyValuePair<string, string>("股份", "") ,
  818. new KeyValuePair<string, string>("服务", "") ,
  819. new KeyValuePair<string, string>("基地", "") ,
  820. new KeyValuePair<string, string>("社区", "社") ,
  821. new KeyValuePair<string, string>("职工", "") ,
  822. new KeyValuePair<string, string>("专修", ""),
  823. new KeyValuePair<string, string>("实验", "验"),
  824. new KeyValuePair<string, string>("完全", ""),
  825. new KeyValuePair<string, string>("一贯制", "") ,
  826. new KeyValuePair<string, string>("联办", ""),
  827. new KeyValuePair<string, string>("联合", ""),
  828. new KeyValuePair<string, string>("完小", "小"),
  829. new KeyValuePair<string, string>("义务", ""),
  830. new KeyValuePair<string, string>("基础", ""),
  831. new KeyValuePair<string, string>("制造", "")
  832. };
  833. public static List<KeyValuePair<string, string>> schooReplaceStr = new List<KeyValuePair<string, string>> {
  834. new KeyValuePair<string, string>("分校", "分") ,
  835. new KeyValuePair<string, string>("分园", "分") ,
  836. new KeyValuePair<string, string>("分院", "分") ,
  837. new KeyValuePair<string, string>("藏文", "藏"),
  838. new KeyValuePair<string, string>("职业技术学院", "职") ,
  839. new KeyValuePair<string, string>("创新创业", "创") ,
  840. new KeyValuePair<string, string>("就业创业", "就") ,
  841. new KeyValuePair<string, string>("应用核技术", "核") ,
  842. new KeyValuePair<string, string>("职业学院", "职") ,
  843. new KeyValuePair<string, string>("幼儿园", "幼") ,
  844. new KeyValuePair<string, string>("幼儿", "幼") ,
  845. new KeyValuePair<string, string>("小学", "小") ,
  846. new KeyValuePair<string, string>("中学", "中") ,
  847. new KeyValuePair<string, string>("中等", "中") ,
  848. new KeyValuePair<string, string>("双语", "双") ,
  849. new KeyValuePair<string, string>("初中", "初") ,
  850. new KeyValuePair<string, string>("初级", "初") ,
  851. new KeyValuePair<string, string>("广播", "广"),
  852. new KeyValuePair<string, string>("高中", "高") ,
  853. new KeyValuePair<string, string>("高级", "高") ,
  854. new KeyValuePair<string, string>("大学", "大") ,
  855. new KeyValuePair<string, string>("学院", "院") ,
  856. new KeyValuePair<string, string>("综合", "综") ,
  857. new KeyValuePair<string, string>("职业", "职") ,
  858. new KeyValuePair<string, string>("技术", "技") ,
  859. new KeyValuePair<string, string>("专科", "专") ,
  860. new KeyValuePair<string, string>("外国语", "外") ,
  861. new KeyValuePair<string, string>("九年", "九") ,
  862. new KeyValuePair<string, string>("五年", "五") ,
  863. new KeyValuePair<string, string>("年制", "制") ,
  864. new KeyValuePair<string, string>("高等", "高") ,
  865. new KeyValuePair<string, string>("院校", "院") ,
  866. new KeyValuePair<string, string>("初等", "小") ,
  867. new KeyValuePair<string, string>("附属", "附"),
  868. new KeyValuePair<string, string>("寄宿制", "寄") ,
  869. new KeyValuePair<string, string>("寄宿", "寄") ,
  870. new KeyValuePair<string, string>("卫生", "卫") ,
  871. new KeyValuePair<string, string>("创业", "创") ,
  872. new KeyValuePair<string, string>("继续", "继") ,
  873. new KeyValuePair<string, string>("开放", "开") ,
  874. new KeyValuePair<string, string>("技师", "技") ,
  875. new KeyValuePair<string, string>("成人", "成") ,
  876. new KeyValuePair<string, string>("教育", "教") ,
  877. new KeyValuePair<string, string>("科技", "科") ,
  878. new KeyValuePair<string, string>("行政", "政") ,
  879. new KeyValuePair<string, string>("生物", "生") ,
  880. new KeyValuePair<string, string>("美术", "美") ,
  881. new KeyValuePair<string, string>("设计", "设") ,
  882. new KeyValuePair<string, string>("传播", "传") ,
  883. new KeyValuePair<string, string>("计算机", "算") ,
  884. new KeyValuePair<string, string>("土木", "土") ,
  885. new KeyValuePair<string, string>("石油", "油") ,
  886. new KeyValuePair<string, string>("科普", "普") ,
  887. new KeyValuePair<string, string>("电信", "信") ,
  888. new KeyValuePair<string, string>("联合", "联") ,
  889. new KeyValuePair<string, string>("电商", "商") ,
  890. new KeyValuePair<string, string>("纺织", "织") ,
  891. new KeyValuePair<string, string>("服装", "服") ,
  892. new KeyValuePair<string, string>("新闻", "新") ,
  893. new KeyValuePair<string, string>("网络", "网") ,
  894. new KeyValuePair<string, string>("应用", "应") ,
  895. new KeyValuePair<string, string>("畜牧", "畜") ,
  896. new KeyValuePair<string, string>("兽医", "兽") ,
  897. new KeyValuePair<string, string>("师范", "师") ,
  898. new KeyValuePair<string, string>("人文", "文") ,
  899. new KeyValuePair<string, string>("创新", "创") ,
  900. new KeyValuePair<string, string>("法官", "法") ,
  901. new KeyValuePair<string, string>("邮电", "邮") ,
  902. new KeyValuePair<string, string>("文化", "文") ,
  903. new KeyValuePair<string, string>("函授", "函") ,
  904. new KeyValuePair<string, string>("科学", "科") ,
  905. new KeyValuePair<string, string>("信息", "息") ,
  906. new KeyValuePair<string, string>("水利", "利") ,
  907. new KeyValuePair<string, string>("水电", "电") ,
  908. new KeyValuePair<string, string>("电力", "力") ,
  909. new KeyValuePair<string, string>("环境", "环") ,
  910. new KeyValuePair<string, string>("建材", "材") ,
  911. new KeyValuePair<string, string>("机电", "机") ,
  912. new KeyValuePair<string, string>("航空", "空") ,
  913. new KeyValuePair<string, string>("航天", "天") ,
  914. new KeyValuePair<string, string>("警察", "警") ,
  915. new KeyValuePair<string, string>("警官", "警") ,
  916. new KeyValuePair<string, string>("财贸", "财") ,
  917. new KeyValuePair<string, string>("电子", "电") ,
  918. new KeyValuePair<string, string>("建筑", "筑") ,
  919. new KeyValuePair<string, string>("艺术", "艺") ,
  920. new KeyValuePair<string, string>("体育", "体") ,
  921. new KeyValuePair<string, string>("城市", "城") ,
  922. new KeyValuePair<string, string>("地质", "地") ,
  923. new KeyValuePair<string, string>("医药", "药") ,
  924. new KeyValuePair<string, string>("政法", "法") ,
  925. new KeyValuePair<string, string>("铁路", "铁") ,
  926. new KeyValuePair<string, string>("铁道", "道") ,
  927. new KeyValuePair<string, string>("轨道", "轨") ,
  928. new KeyValuePair<string, string>("交通", "通") ,
  929. new KeyValuePair<string, string>("医学院", "医") ,
  930. new KeyValuePair<string, string>("医学", "医") ,
  931. new KeyValuePair<string, string>("传媒", "媒") ,
  932. new KeyValuePair<string, string>("工程", "程") ,
  933. new KeyValuePair<string, string>("临床", "临") ,
  934. new KeyValuePair<string, string>("化工", "化") ,
  935. new KeyValuePair<string, string>("林业", "林") ,
  936. new KeyValuePair<string, string>("老年", "老") ,
  937. new KeyValuePair<string, string>("旅游", "游") ,
  938. new KeyValuePair<string, string>("护理", "护") ,
  939. new KeyValuePair<string, string>("贸易", "贸") ,
  940. new KeyValuePair<string, string>("中医药", "中医") ,
  941. new KeyValuePair<string, string>("资源", "源") ,
  942. new KeyValuePair<string, string>("冶金", "冶") ,
  943. new KeyValuePair<string, string>("能源", "能") ,
  944. new KeyValuePair<string, string>("汽车", "车") ,
  945. new KeyValuePair<string, string>("医科", "医") ,
  946. new KeyValuePair<string, string>("机械", "械") ,
  947. new KeyValuePair<string, string>("应用", "应") ,
  948. new KeyValuePair<string, string>("电气", "电") ,
  949. new KeyValuePair<string, string>("材料", "材") ,
  950. new KeyValuePair<string, string>("劳动", "劳") ,
  951. new KeyValuePair<string, string>("轻工", "轻") ,
  952. new KeyValuePair<string, string>("农业", "农") ,
  953. new KeyValuePair<string, string>("委员会", "委") ,
  954. new KeyValuePair<string, string>("专业", "专") ,
  955. new KeyValuePair<string, string>("广播", "广"),
  956. new KeyValuePair<string, string>("电视", "电") ,
  957. new KeyValuePair<string, string>("工商", "商") ,
  958. new KeyValuePair<string, string>("工业", "工") ,
  959. new KeyValuePair<string, string>("管理", "管") ,
  960. new KeyValuePair<string, string>("社会主义", "社") ,
  961. new KeyValuePair<string, string>("社会", "社") ,
  962. new KeyValuePair<string, string>("自动化", "自") ,
  963. };
  964. public static List<KeyValuePair<string, string>> proReplaceStr = new List<KeyValuePair<string, string>> {
  965. new KeyValuePair<string, string>("北京","京") ,
  966. new KeyValuePair<string, string>("天津","津") ,
  967. new KeyValuePair<string, string>("河北","冀") ,
  968. new KeyValuePair<string, string>("山西","晋") ,
  969. new KeyValuePair<string, string>("内蒙古","蒙") ,
  970. new KeyValuePair<string, string>("辽宁","辽") ,
  971. new KeyValuePair<string, string>("吉林","吉") ,
  972. new KeyValuePair<string, string>("黑龙江","黑") ,
  973. new KeyValuePair<string, string>("上海","沪") ,
  974. new KeyValuePair<string, string>("江苏","苏") ,
  975. new KeyValuePair<string, string>("浙江","浙") ,
  976. new KeyValuePair<string, string>("安徽","皖") ,
  977. new KeyValuePair<string, string>("福建","闽") ,
  978. new KeyValuePair<string, string>("江西","赣") ,
  979. new KeyValuePair<string, string>("山东","鲁") ,
  980. new KeyValuePair<string, string>("河南","豫") ,
  981. new KeyValuePair<string, string>("湖北","鄂") ,
  982. new KeyValuePair<string, string>("湖南","湘") ,
  983. new KeyValuePair<string, string>("广东","粤") ,
  984. new KeyValuePair<string, string>("广西","桂") ,
  985. new KeyValuePair<string, string>("海南","琼") ,
  986. new KeyValuePair<string, string>("四川","川") ,
  987. new KeyValuePair<string, string>("贵州","贵") ,
  988. new KeyValuePair<string, string>("云南","云") ,
  989. new KeyValuePair<string, string>("重庆","渝") ,
  990. new KeyValuePair<string, string>("西藏","藏") ,
  991. new KeyValuePair<string, string>("陕西","陕") ,
  992. new KeyValuePair<string, string>("甘肃","甘") ,
  993. new KeyValuePair<string, string>("青海","青") ,
  994. new KeyValuePair<string, string>("宁夏","宁") ,
  995. new KeyValuePair<string, string>("新疆","新") ,
  996. new KeyValuePair<string, string>("香港","港") ,
  997. new KeyValuePair<string, string>("澳门","澳") ,
  998. new KeyValuePair<string, string>("台湾","台")
  999. };
  1000. /*
  1001. [
  1002. {"method":"台北市","params":{"CountryId":"TW","CityId":"30"}},1
  1003. {"method":"新北市","params":{"CountryId":"TW","CityId":"01"}},1
  1004. {"method":"桃园市","params":{"CountryId":"TW","CityId":"03"}},1
  1005. {"method":"台中市","params":{"CountryId":"TW","CityId":"66"}},1
  1006. {"method":"台南市","params":{"CountryId":"TW","CityId":"67"}},1
  1007. {"method":"高雄市","params":{"CountryId":"TW","CityId":"64"}},1
  1008. {"method":"基隆市","params":{"CountryId":"TW","CityId":"17"}},1
  1009. {"method":"新竹市","params":{"CountryId":"TW","CityId":"18"}},1
  1010. {"method":"嘉义市","params":{"CountryId":"TW","CityId":"20"}},1
  1011. {"method":"新竹县","params":{"CountryId":"TW","CityId":"04"}},1
  1012. {"method":"苗栗县","params":{"CountryId":"TW","CityId":"05"}},1
  1013. {"method":"彰化县","params":{"CountryId":"TW","CityId":"07"}},1
  1014. {"method":"南投县","params":{"CountryId":"TW","CityId":"08"}},1
  1015. {"method":"云林县","params":{"CountryId":"TW","CityId":"09"}},1
  1016. {"method":"嘉义县","params":{"CountryId":"TW","CityId":"10"}},1
  1017. {"method":"屏东县","params":{"CountryId":"TW","CityId":"13"}},1
  1018. {"method":"宜兰县","params":{"CountryId":"TW","CityId":"02"}},1
  1019. {"method":"花莲县","params":{"CountryId":"TW","CityId":"15"}},1
  1020. {"method":"台东县","params":{"CountryId":"TW","CityId":"14"}},1
  1021. {"method":"澎湖县","params":{"CountryId":"TW","CityId":"16"}},1
  1022. {"method":"金门县","params":{"CountryId":"TW","CityId":"71"}},
  1023. {"method":"连江县","params":{"CountryId":"TW","CityId":"72"}}
  1024. ]
  1025. */
  1026. }
  1027. }