GroupListService.cs 61 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189
  1. using Azure.Cosmos;
  2. using System;
  3. using System.Collections.Generic;
  4. using System.Threading.Tasks;
  5. using TEAMModelOS.SDK.DI;
  6. using TEAMModelOS.SDK.Extension;
  7. using TEAMModelOS.SDK.Models.Cosmos.Common;
  8. using HTEXLib.COMM.Helpers;
  9. using System.Linq;
  10. using System.Text;
  11. using System.Text.Json;
  12. using TEAMModelOS.Models;
  13. using Azure.Messaging.ServiceBus;
  14. using Microsoft.Extensions.Configuration;
  15. using TEAMModelOS.SDK.Models.Service;
  16. using System.Text.RegularExpressions;
  17. using TEAMModelOS.SDK.Models;
  18. using System.Net.Http;
  19. namespace TEAMModelOS.SDK
  20. {
  21. public class GroupListService
  22. {
  23. public static async Task DeleteGrouplistEvent(string id , string code,string tbname ,CosmosClient client, IConfiguration _configuration, AzureServiceBusFactory _serviceBus)
  24. {
  25. GroupChange change = new GroupChange();
  26. GroupList groupList = await client.GetContainer(Constant.TEAMModelOS, tbname).ReadItemAsync<GroupList>(id.ToString(), new PartitionKey(code));
  27. var tleave = groupList.members.FindAll(x => x.type == 1);
  28. if (tleave.IsNotEmpty())
  29. {
  30. if (groupList.type.Equals("research") || groupList.type.Equals("yxtrain"))
  31. {
  32. change.tchleave.AddRange(tleave);
  33. }
  34. else
  35. {
  36. change.tmdleave.AddRange(tleave);
  37. }
  38. }
  39. var sleave = groupList.members.FindAll(x => x.type == 2);
  40. if (sleave.IsNotEmpty())
  41. {
  42. change.stuleave.AddRange(sleave);
  43. }
  44. change.listid = groupList.id;
  45. change.scope = groupList.scope;
  46. change.originCode = $"{code}";
  47. change.school = groupList.school;
  48. change.creatorId = groupList.creatorId;
  49. change.type = groupList.type;
  50. change.status = "delete";
  51. if (change.tmdleave.IsNotEmpty() || change.tchleave.IsNotEmpty() || change.stuleave.IsNotEmpty())
  52. {
  53. var messageChange = new ServiceBusMessage(change.ToJsonString());
  54. messageChange.ApplicationProperties.Add("name", "GroupChange");
  55. var ActiveTask = _configuration.GetValue<string>("Azure:ServiceBus:ActiveTask");
  56. await _serviceBus.GetServiceBusClient().SendMessageAsync(ActiveTask, messageChange);
  57. }
  58. await client.GetContainer(Constant.TEAMModelOS, tbname).DeleteItemStreamAsync(id.ToString(), new PartitionKey(code));
  59. }
  60. /// <summary>
  61. /// 查询名单成员所在的名单列表,
  62. /// </summary>
  63. /// <param name="_coreAPIHttpService"></param>
  64. /// <param name="client"></param>
  65. /// <param name="_dingDing"></param>
  66. /// <param name="memberId">成员id </param>
  67. /// <param name="memberType">成员类型</param>
  68. /// <param name="school">成员所在的学校 ,可为空</param>
  69. /// <param name="groupTypes">过滤名单的类型集合,不传则是全部</param>
  70. /// <returns></returns>
  71. public static async Task<List<GroupListGrp>> GetMemberInGroupList(CoreAPIHttpService _coreAPIHttpService, CosmosClient client, DingDing _dingDing, string memberId, int memberType, string school,List<string> groupTypes) {
  72. List<GroupListGrp> groupLists = new List<GroupListGrp>();
  73. if (groupTypes.IsEmpty() || groupTypes.Contains("class")) {
  74. if (!string.IsNullOrWhiteSpace(school) && memberType == 2)
  75. {
  76. Student student = null;
  77. try
  78. {
  79. student = await client.GetContainer(Constant.TEAMModelOS, Constant.Student).ReadItemAsync<Student>(memberId, new PartitionKey($"Base-{school}"));
  80. }
  81. catch (CosmosException ex) when (ex.Status == 404)
  82. {
  83. return null;
  84. }
  85. if (!string.IsNullOrWhiteSpace(student.classId))
  86. {
  87. try
  88. {
  89. Class clazz = await client.GetContainer(Constant.TEAMModelOS, Constant.School).ReadItemAsync<Class>(student.classId, new PartitionKey($"Class-{school}"));
  90. GroupListGrp groupList = new GroupListGrp
  91. {
  92. id = clazz.id,
  93. code = $"GroupList-{clazz.school}",
  94. name = clazz.name,
  95. periodId = clazz.periodId,
  96. pk = "GroupList",
  97. year = clazz.year,
  98. school = clazz.school,
  99. scope = "school",
  100. type = "class",
  101. no = clazz.no,
  102. leader = clazz.teacher?.id,
  103. };
  104. groupLists.Add(groupList);
  105. }
  106. catch (CosmosException ex) when (ex.Status == 404)
  107. {
  108. }
  109. }
  110. }
  111. }
  112. string SummarySql = " c.id,c.code,c.name,c.no,c.periodId,c.scope,c.school,c.creatorId,c.type,c.year,c.tcount,c.scount,c.leader ";
  113. if (groupTypes.IsEmpty() || groupTypes.Contains("teach")) {
  114. //教学班
  115. StringBuilder teachsql = new StringBuilder();
  116. if (!string.IsNullOrWhiteSpace(school) && memberType == 2) {
  117. teachsql.Append($"SELECT distinct {SummarySql} FROM c join m in c.members where c.type='teach' and m.id='{memberId}' and m.code='{school}' and m.type=2 ");
  118. }
  119. if (memberType == 1)
  120. {
  121. teachsql.Append($"SELECT distinct {SummarySql} FROM c join m in c.members where c.type='teach' and m.id='{memberId}' and m.type=1 ");
  122. }
  123. await foreach (var item in client.GetContainer(Constant.TEAMModelOS, "School").
  124. GetItemQueryIterator<GroupList>(queryText: teachsql.ToString(), requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"GroupList-{school}") }))
  125. {
  126. HashSet<string> groupName = item.members.Where(x => !string.IsNullOrEmpty(x.groupName)).Select(y => y.groupName).ToHashSet();
  127. groupLists.Add(new GroupListGrp(item, groupName));
  128. }
  129. //个人名单
  130. await foreach (var item in client.GetContainer(Constant.TEAMModelOS, Constant.Teacher).
  131. GetItemQueryIterator<GroupList>(queryText: teachsql.ToString(), requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"GroupList") }))
  132. {
  133. HashSet<string> groupName = item.members.Where(x => !string.IsNullOrEmpty(x.groupName)).Select(y => y.groupName).ToHashSet();
  134. groupLists.Add(new GroupListGrp(item, groupName));
  135. }
  136. }
  137. if (!string.IsNullOrWhiteSpace(school) && (groupTypes.IsEmpty() || groupTypes.Contains("research")))
  138. {
  139. //教研组
  140. StringBuilder teachsql = new StringBuilder();
  141. teachsql.Append($"SELECT distinct {SummarySql} FROM c join m in c.members where c.type='research' and m.id='{memberId}' and m.type=1 ");
  142. await foreach (var item in client.GetContainer(Constant.TEAMModelOS, "School").
  143. GetItemQueryIterator<GroupList>(queryText: teachsql.ToString(), requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"GroupList-{school}") }))
  144. {
  145. HashSet<string> groupName = item.members.Where(x => !string.IsNullOrEmpty(x.groupName)).Select(y => y.groupName).ToHashSet();
  146. groupLists.Add(new GroupListGrp(item, groupName));
  147. }
  148. }
  149. if (!string.IsNullOrWhiteSpace(school) && (groupTypes.IsEmpty() || groupTypes.Contains("yxtrain")))
  150. {
  151. //研修名单
  152. StringBuilder teachsql = new StringBuilder();
  153. teachsql.Append($"SELECT distinct {SummarySql} FROM c join m in c.members where c.type='yxtrain' and m.id='{memberId}' and m.type=1 ");
  154. await foreach (var item in client.GetContainer(Constant.TEAMModelOS, "School").
  155. GetItemQueryIterator<GroupList>(queryText: teachsql.ToString(), requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"GroupList-{school}") }))
  156. {
  157. HashSet<string> groupName = item.members.Where(x => !string.IsNullOrEmpty(x.groupName)).Select(y => y.groupName).ToHashSet();
  158. groupLists.Add(new GroupListGrp(item, groupName));
  159. }
  160. }
  161. return groupLists;
  162. }
  163. /// <summary>
  164. ///-1状态异常,0加入成功, 1加入学生或醍摩豆ID为空,2重复加入 ,3不允许跨校加入名单, 4表示个人名单未开放加入
  165. /// </summary>
  166. /// <param name="client"></param>
  167. /// <param name="_stuListNo"></param>
  168. /// <param name="userid"></param>
  169. /// <param name="type"></param>
  170. /// <param name="school"></param>
  171. /// <returns></returns>
  172. public static async Task<(int status, GroupList stuList,Member member)> CodeJoinList(CosmosClient client, string _stuListNo, string userid, int type, string school)
  173. {
  174. var queryNo = $"SELECT value(c) FROM c where c.no ='{_stuListNo}'";
  175. (int status, GroupList stuList,Member member) data = (-1, null,null);
  176. if (!string.IsNullOrEmpty(school))
  177. {
  178. await foreach (var item in client.GetContainer(Constant.TEAMModelOS, "School").GetItemQueryIterator<GroupList>(queryText: queryNo,
  179. requestOptions: new QueryRequestOptions() { PartitionKey = new Azure.Cosmos.PartitionKey($"GroupList-{school}") }))
  180. {
  181. data = JoinList(item, userid, type, school);
  182. break;
  183. }
  184. }
  185. await foreach (var item in client.GetContainer(Constant.TEAMModelOS, "Teacher").GetItemQueryIterator<GroupList>(queryText: queryNo,
  186. requestOptions: new QueryRequestOptions() { PartitionKey = new Azure.Cosmos.PartitionKey($"GroupList") }))
  187. {
  188. if (item.joinLock == 0) {
  189. //状态=4 表示未开放加入。
  190. return (4, item, null) ;
  191. }
  192. data = JoinList(item, userid, type, school);
  193. break;
  194. }
  195. return data;
  196. }
  197. public static (int status, GroupList stuList, Member member) JoinList(GroupList stuList, string userid, int type, string school)
  198. {
  199. int status = -1;
  200. if (!string.IsNullOrWhiteSpace(stuList.school) && !string.IsNullOrWhiteSpace(school))
  201. {
  202. if (!stuList.school.Equals(school))
  203. {
  204. status = 3;//不允许跨校加入名单
  205. return (status, stuList,null);
  206. }
  207. }
  208. string irs = string.Empty;
  209. List<string> irsOrder = stuList.members.Select(x => x.irs)?.Where(y => !string.IsNullOrEmpty(y) && Regex.IsMatch(y, @"^\d*$")).OrderBy(x => int.Parse(x)).ToList();
  210. if (!irsOrder.Contains("0"))
  211. {
  212. irsOrder.Insert(0, "0");
  213. }
  214. if (irsOrder != null)
  215. {
  216. if (!irsOrder.Contains("0"))
  217. {
  218. irsOrder.Insert(0, "0");
  219. }
  220. }
  221. else { irsOrder = new List<string>() { "0" }; }
  222. for (int i = 0; i < irsOrder.Count; i++)
  223. {
  224. irs = $"{int.Parse(irsOrder[i]) + 1}";
  225. int index = i + 1;
  226. if (index <= irsOrder.Count - 1)
  227. {
  228. if (!irs.Equals(irsOrder[index]))
  229. {
  230. break;
  231. }
  232. }
  233. }
  234. Member member = null;
  235. if (string.IsNullOrEmpty($"{userid}"))
  236. {
  237. //加入学生或醍摩豆ID为空
  238. status = 1;
  239. }
  240. else
  241. {
  242. if (type == 1)
  243. {
  244. member = stuList.members.Find(x => x.type == 1 && x.id.Equals(userid));
  245. if (member != null)
  246. {
  247. //重复加入
  248. status = 2;
  249. }
  250. else
  251. {
  252. //加入成功
  253. status = 0;
  254. member = new Member { id = userid, type = type, irs = irs, no = irs };
  255. stuList.members.Add(member);
  256. }
  257. }
  258. else if (type == 2)
  259. {
  260. member = stuList.members.Find(x => x.type == 2 && x.id.Equals(userid) && x.code.Equals(school));
  261. if (member != null)
  262. {
  263. //重复加入
  264. status = 2;
  265. }
  266. else
  267. {
  268. status = 0;
  269. member = new Member { id = userid, code = school, type = type, irs = irs, no = irs };
  270. stuList.members.Add(member);
  271. }
  272. }
  273. }
  274. return (status, stuList, member);
  275. }
  276. public static async Task<GroupList> UpsertList(GroupList list, AzureCosmosFactory _azureCosmos, IConfiguration _configuration, AzureServiceBusFactory _serviceBus)
  277. {
  278. bool isnew = false;
  279. var client = _azureCosmos.GetCosmosClient();
  280. if (string.IsNullOrEmpty(list.id))
  281. {
  282. list.id = Guid.NewGuid().ToString();
  283. isnew = true;
  284. }
  285. string tbname = list.scope.Equals("private") ? "Teacher" : "School";
  286. var tmembers = list.members.Where(x => x.type == 1);
  287. var smembers = list.members.Where(x => x.type == 2);
  288. list.scount = smembers.Count();
  289. list.tcount = tmembers.Count();
  290. //if (smembers.Count() > 0 && smembers.Select(x => x.code).ToHashSet().Count()>=2) {
  291. // //处理移除多个学校的名单,只保留一个学校的。
  292. // if (string.IsNullOrWhiteSpace(list.school))
  293. // {
  294. // HashSet<string> codes = smembers.Select(x => x.code).ToHashSet();
  295. // list.school = codes.First();
  296. // codes.Remove(codes.First());
  297. // list.members.RemoveAll(x => codes.Contains(x.code));
  298. // }
  299. // else {
  300. // list.members.RemoveAll(x => !x.code.Equals(list.school));
  301. // }
  302. //}
  303. if (string.IsNullOrWhiteSpace(list.school) && smembers.Count() >= 1)
  304. {
  305. list.school = smembers.First().code;
  306. }
  307. if (!string.IsNullOrWhiteSpace(list.school) && smembers.Count() == 0 && list.scope.Equals("private"))
  308. {
  309. list.school = null;
  310. }
  311. //学生名单,教研组会触发活动中间表刷新
  312. if (list.type.Equals("teach") || list.type.Equals("research") || list.type.Equals("yxtrain") || list.type.Equals("activity"))
  313. {
  314. GroupChange change = new GroupChange()
  315. {
  316. type = list.type,
  317. listid = list.id,
  318. scope = list.scope,
  319. originCode = list.school,
  320. school = list.school,
  321. creatorId = list.creatorId
  322. };
  323. GroupList oldList = null;
  324. if (!isnew)
  325. {
  326. try
  327. {
  328. oldList = await client.GetContainer(Constant.TEAMModelOS, tbname).ReadItemAsync<GroupList>(list.id, new PartitionKey(list.code));
  329. }
  330. catch (CosmosException)
  331. {
  332. oldList = null;
  333. }
  334. }
  335. if (list.members.IsNotEmpty() && (oldList == null || !oldList.members.IsNotEmpty()))
  336. {
  337. //加入的
  338. var tmdids = list.members.FindAll(x => x.type == 1);
  339. if (tmdids.IsNotEmpty())
  340. {
  341. if (list.type.Equals("research") || list.type.Equals("yxtrain"))
  342. {
  343. change.tchjoin.AddRange(tmdids);
  344. }
  345. else
  346. {
  347. change.tmdjoin.AddRange(tmdids);
  348. }
  349. }
  350. var stuids = list.members.FindAll(x => x.type == 2);
  351. if (stuids.IsNotEmpty())
  352. {
  353. change.stujoin.AddRange(stuids);
  354. }
  355. }
  356. else
  357. {
  358. if (list.members.IsNotEmpty())
  359. {
  360. var tmdids = list.members.FindAll(x => x.type == 1);
  361. var oldtmdids = oldList.members.FindAll(x => x.type == 1);
  362. //取各自的差集
  363. //新=》旧差集,表示新增
  364. var jointmdid = tmdids.Select(x => x.id).Except(oldtmdids.Select(y => y.id)).ToList();
  365. //旧=》新差集,表示离开
  366. var leavetmdid = oldtmdids.Select(x => x.id).Except(tmdids.Select(y => y.id)).ToList();
  367. if (list.type.Equals("research") || list.type.Equals("yxtrain"))
  368. {
  369. change.tchjoin.AddRange(tmdids.Where(x => jointmdid.Exists(y => y.Equals(x.id))));
  370. change.tchleave.AddRange(oldtmdids.Where(x => leavetmdid.Exists(y => y.Equals(x.id))));
  371. }
  372. else
  373. {
  374. change.tmdjoin.AddRange(tmdids.Where(x => jointmdid.Exists(y => y.Equals(x.id))));
  375. change.tmdleave.AddRange(oldtmdids.Where(x => leavetmdid.Exists(y => y.Equals(x.id))));
  376. }
  377. var stuids = list.members.FindAll(x => x.type == 2);
  378. var oldstuids = oldList.members.FindAll(x => x.type == 2);
  379. var joinstudent = stuids.Select(x => (x.id, x.code)).Except(oldstuids.Select(y => (y.id, y.code)), new CompareIdCode()).ToList();
  380. var leavestudent = oldstuids.Select(x => (x.id, x.code)).Except(stuids.Select(y => (y.id, y.code)), new CompareIdCode()).ToList();
  381. change.stujoin.AddRange(stuids.Where(x => joinstudent.Exists(y => y.id.Equals(x.id) && y.code.Equals(x.code))));
  382. change.stuleave.AddRange(oldstuids.Where(x => leavestudent.Exists(y => y.id.Equals(x.id) && y.code.Equals(x.code))));
  383. }
  384. else
  385. {
  386. //离开的
  387. if (oldList != null)
  388. {
  389. var tmdids = oldList.members.FindAll(x => x.type == 1);
  390. if (tmdids.IsNotEmpty())
  391. {
  392. if (list.type.Equals("research") || list.type.Equals("yxtrain"))
  393. {
  394. change.tchleave.AddRange(tmdids);
  395. }
  396. else
  397. {
  398. change.tmdleave.AddRange(tmdids);
  399. }
  400. }
  401. var stuids = oldList.members.FindAll(x => x.type == 2);
  402. if (stuids.IsNotEmpty())
  403. {
  404. change.stuleave.AddRange(stuids);
  405. }
  406. }
  407. }
  408. }
  409. if (change.tmdjoin.Count != 0 || change.tmdleave.Count != 0 || change.stujoin.Count != 0 || change.stuleave.Count != 0
  410. || change.tchjoin.Count != 0 || change.tchleave.Count != 0)
  411. {
  412. var messageChange = new ServiceBusMessage(change.ToJsonString());
  413. messageChange.ApplicationProperties.Add("name", "GroupChange");
  414. var ActiveTask = _configuration.GetValue<string>("Azure:ServiceBus:ActiveTask");
  415. await _serviceBus.GetServiceBusClient().SendMessageAsync(ActiveTask, messageChange);
  416. }
  417. }
  418. await client.GetContainer(Constant.TEAMModelOS, tbname).UpsertItemAsync(list, new PartitionKey(list.code));
  419. return list;
  420. }
  421. public static async Task<GroupList> CheckListNo(GroupList list, AzureCosmosFactory _azureCosmos, DingDing _dingDing, Option _option)
  422. {
  423. try
  424. {
  425. var client = _azureCosmos.GetCosmosClient();
  426. if (string.IsNullOrEmpty(list.no))
  427. {
  428. list.no = $"{Utils.CreatSaltString(6, "123456789")}";
  429. for (int i = 0; i < 10; i++)
  430. {
  431. List<string> noStus = new List<string>();
  432. var queryNo = $"SELECT c.no FROM c where c.no ='{list.no}'";
  433. if (list.scope.Equals("school"))
  434. {
  435. await foreach (var item in client.GetContainer(Constant.TEAMModelOS, "School").GetItemQueryStreamIterator(queryText: queryNo,
  436. requestOptions: new QueryRequestOptions() { PartitionKey = new Azure.Cosmos.PartitionKey($"{list.code}") }))
  437. {
  438. using var jsonNo = await JsonDocument.ParseAsync(item.ContentStream);
  439. if (jsonNo.RootElement.TryGetProperty("_count", out JsonElement count) && count.GetUInt16() > 0)
  440. {
  441. var accounts = jsonNo.RootElement.GetProperty("Documents").EnumerateArray();
  442. while (accounts.MoveNext())
  443. {
  444. JsonElement account = accounts.Current;
  445. noStus.Add(account.GetProperty("no").GetString());
  446. }
  447. }
  448. }
  449. }
  450. await foreach (var item in client.GetContainer(Constant.TEAMModelOS, "Teacher").GetItemQueryStreamIterator(queryText: queryNo,
  451. requestOptions: new QueryRequestOptions() { PartitionKey = new Azure.Cosmos.PartitionKey("GroupList") }))
  452. {
  453. using var jsonNo = await JsonDocument.ParseAsync(item.ContentStream);
  454. if (jsonNo.RootElement.TryGetProperty("_count", out JsonElement count) && count.GetUInt16() > 0)
  455. {
  456. var accounts = jsonNo.RootElement.GetProperty("Documents").EnumerateArray();
  457. while (accounts.MoveNext())
  458. {
  459. JsonElement account = accounts.Current;
  460. noStus.Add(account.GetProperty("no").GetString());
  461. }
  462. }
  463. }
  464. if (noStus.Count == 0)
  465. {
  466. break;
  467. }
  468. else
  469. {
  470. if (i == 9)
  471. {
  472. string msg = $"OS,{_option.Location},school/course/upsert-list()\n 编号生成异常,重复生成次数超过10次";
  473. await _dingDing.SendBotMsg(msg, GroupNames.醍摩豆服務運維群組);
  474. throw new Exception(msg);
  475. }
  476. else
  477. {
  478. list.no = $"{Utils.CreatSaltString(6, "123456789")}";
  479. }
  480. }
  481. }
  482. }
  483. }
  484. catch (Exception ex)
  485. {
  486. }
  487. return list;
  488. }
  489. public static async Task<List<GroupListDto>> GetGroupListListids(CosmosClient client, DingDing _dingDing, List<string> classes, string school,
  490. string SummarySql = " c.id,c.code,c.name,c.no,c.periodId,c.scope,c.school,c.creatorId,c.type,c.year,c.tcount,c.scount,c.leader ,c.froms ,c.joinLock ")
  491. {
  492. classes.RemoveAll(x => x == null);
  493. if (!classes.IsNotEmpty()) {
  494. return null;
  495. }
  496. List<GroupListDto> groupLists = null;
  497. if (classes.Count == 1 && classes.First().Equals("TeacherAll") && !string.IsNullOrEmpty(school))
  498. {
  499. //默认的教研组
  500. GroupListDto groupList = new GroupListDto
  501. {
  502. id = "TeacherAll",
  503. name = "TeacherAll",
  504. code = $"GroupList-{school}",
  505. school = school,
  506. scope = "school",
  507. type = "yxtrain",
  508. };
  509. groupLists = new List<GroupListDto> { groupList };
  510. }
  511. else
  512. {
  513. Dictionary<string, List<GroupListDto>> groups = new Dictionary<string, List<GroupListDto>>();
  514. //List<Student> students = new List<Student>();
  515. string sql = string.Join(",", classes.Select(x => $"'{x}'"));
  516. if (!string.IsNullOrEmpty(school))
  517. {
  518. List<GroupListDto> schoolList = new List<GroupListDto>();
  519. await foreach (var item in client.GetContainer(Constant.TEAMModelOS, "School").GetItemQueryIterator<GroupListDto>(queryText: $"select {SummarySql} from c where c.id in ({sql})",
  520. requestOptions: new QueryRequestOptions() { PartitionKey = new Azure.Cosmos.PartitionKey($"GroupList-{school}") }))
  521. {
  522. schoolList.Add(item);
  523. }
  524. if (schoolList.IsNotEmpty())
  525. {
  526. groups.Add("School", schoolList);
  527. }
  528. //取差集,减少二次搜寻
  529. classes = classes.Except(schoolList.Select(y => y.id)).ToList();
  530. if (classes.IsNotEmpty())
  531. {
  532. if (!groupLists.IsNotEmpty())
  533. {
  534. groupLists = new List<GroupListDto>();
  535. }
  536. string insql = string.Join(",", classes.Select(x => $"'{x}'"));
  537. //搜寻没有关联学生的行政班
  538. await foreach (var item in client.GetContainer(Constant.TEAMModelOS, "School").GetItemQueryIterator<GroupListDto>(queryText: $"select c.id,c.code,c.name,c.no,c.periodId,c.scope,c.school,c.creatorId,c.type,c.year,c.tcount,c.scount,c.teacher.id as leader from c where c.id in ({insql})",
  539. requestOptions: new QueryRequestOptions() { PartitionKey = new Azure.Cosmos.PartitionKey($"Class-{school}") }))
  540. {
  541. ///行政班(学生搜寻classId动态返回)class
  542. GroupListDto group = new GroupListDto
  543. {
  544. id = item.id,
  545. code = $"GroupList-{school}",
  546. name = item.name,
  547. periodId = item.periodId,
  548. scope = "school",
  549. school = school,
  550. type = "class",
  551. year = item.year,
  552. leader = item.leader,
  553. no = item.no,
  554. pk = "GroupList",
  555. };
  556. groupLists.Add(group);
  557. }
  558. //取差集,减少二次搜寻
  559. classes = classes.Except(groupLists.Select(y => y.id)).ToList();
  560. }
  561. }
  562. if (classes.IsNotEmpty())
  563. {
  564. List<GroupListDto> privateList = new List<GroupListDto>();
  565. sql = string.Join(",", classes.Select(x => $"'{x}'"));
  566. await foreach (var item in client.GetContainer(Constant.TEAMModelOS, "Teacher").GetItemQueryIterator<GroupListDto>(queryText: $"select {SummarySql} from c where c.id in ({sql})",
  567. requestOptions: new QueryRequestOptions() { PartitionKey = new Azure.Cosmos.PartitionKey($"GroupList") }))
  568. {
  569. privateList.Add(item);
  570. //if (string.IsNullOrWhiteSpace(school))
  571. //{
  572. // privateList.Add(item);
  573. //}
  574. //else
  575. //{
  576. // if (!string.IsNullOrWhiteSpace(item.school))
  577. // {
  578. // if (item.school.Equals(school))
  579. // {
  580. // privateList.Add(item);
  581. // }
  582. // }
  583. // else
  584. // {
  585. // privateList.Add(item);
  586. // }
  587. //}
  588. }
  589. if (privateList.IsNotEmpty())
  590. {
  591. groups.Add("Teacher", privateList);
  592. }
  593. }
  594. if (groups.Count != 0)
  595. {
  596. if (groupLists.IsNotEmpty())
  597. {
  598. groupLists.AddRange(groups.SelectMany(x => x.Value).ToList());
  599. }
  600. else
  601. {
  602. groupLists = groups.SelectMany(x => x.Value).ToList();
  603. }
  604. }
  605. }
  606. return groupLists;
  607. }
  608. public static async Task<(List<RMember>, List<RGroupList> groups)> GetStutmdidListids(CoreAPIHttpService _coreAPIHttpService, CosmosClient client, DingDing _dingDing, List<string> classes, string school, List<(string, List<string>)> groupids = null)
  609. {
  610. List<RMember> members = new List<RMember>();
  611. List<RGroupList> groupLists = new List<RGroupList>();
  612. if (classes != null)
  613. {
  614. classes.RemoveAll(x => x == null);
  615. }
  616. if (classes == null || classes.Count <= 0)
  617. {
  618. return (members, groupLists);
  619. }
  620. if (classes.Count == 1 && classes.First().Equals("TeacherAll") && !string.IsNullOrEmpty(school))
  621. {
  622. //默认的教研组
  623. members = new List<RMember>();
  624. await foreach (var item in client.GetContainer(Constant.TEAMModelOS, "School").GetItemQueryIterator<TmdInfo>(queryText: $"SELECT c.id,c.name,c.picture FROM c ", requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"Teacher-{school}") }))
  625. {
  626. RMember member = new RMember
  627. {
  628. id = item.id,
  629. name = item.name,
  630. picture = item.picture,
  631. type = 1,
  632. // nickname=item.name,
  633. };
  634. members.Add(member);
  635. }
  636. RGroupList groupList = new RGroupList
  637. {
  638. id = "TeacherAll",
  639. name = "TeacherAll",
  640. code = $"GroupList-{school}",
  641. school = school,
  642. scope = "school",
  643. type = "TeacherAll",
  644. members = members
  645. };
  646. groupLists = new List<RGroupList> { groupList };
  647. }
  648. else
  649. {
  650. Dictionary<string, List<RGroupList>> groups = new Dictionary<string, List<RGroupList>>();
  651. List<Student> students = new List<Student>();
  652. string sql = string.Join(",", classes.Select(x => $"'{x}'"));
  653. if (!string.IsNullOrEmpty(school))
  654. {
  655. List<RGroupList> schoolList = new List<RGroupList>();
  656. string queryText = $"select value(c) from c where c.id in ({sql})";
  657. await foreach (var item in client.GetContainer(Constant.TEAMModelOS, "School").GetItemQueryIterator<RGroupList>(queryText: queryText,
  658. requestOptions: new QueryRequestOptions() { PartitionKey = new Azure.Cosmos.PartitionKey($"GroupList-{school}") }))
  659. {
  660. schoolList.Add(item);
  661. }
  662. if (schoolList.IsNotEmpty())
  663. {
  664. groups.Add("School", schoolList);
  665. }
  666. //取差集,减少二次搜寻
  667. classes = classes.Except(schoolList.Select(y => y.id)).ToList();
  668. if (classes.IsNotEmpty())
  669. {
  670. sql = string.Join(",", classes.Select(x => $"'{x}'"));
  671. await foreach (var item in client.GetContainer(Constant.TEAMModelOS, "Student").GetItemQueryIterator<Student>(queryText: $"select value(c) from c where c.classId in ({sql})",
  672. requestOptions: new QueryRequestOptions() { PartitionKey = new Azure.Cosmos.PartitionKey($"Base-{school}") }))
  673. {
  674. students.Add(item);
  675. }
  676. //取差集,减少二次搜寻
  677. classes = classes.Except(students.Select(y => y.classId)).ToList();
  678. }
  679. if (classes.IsNotEmpty())
  680. {
  681. string insql = string.Join(",", classes.Select(x => $"'{x}'"));
  682. //搜寻没有关联学生的行政班
  683. await foreach (var item in client.GetContainer(Constant.TEAMModelOS, "School")
  684. .GetItemQueryIterator<RGroupList>(queryText: $"select c.id,c.code,c.name,c.no,c.periodId,c.scope,c.school,c.creatorId,c.type,c.year,c.tcount,c.scount,c.teacher.id as leader from c where c.id in ({insql})",
  685. requestOptions: new QueryRequestOptions() { PartitionKey = new Azure.Cosmos.PartitionKey($"Class-{school}") }))
  686. {
  687. ///行政班(学生搜寻classId动态返回)class
  688. List<RMember> smembers = new List<RMember>();
  689. RGroupList group = new RGroupList
  690. {
  691. id = item.id,
  692. code = $"GroupList-{school}",
  693. name = item.name,
  694. periodId = item.periodId,
  695. scope = "school",
  696. school = school,
  697. type = "class",
  698. year = item.year,
  699. members = smembers,
  700. scount = smembers.Count,
  701. pk = "GroupList",
  702. leader = item.leader,
  703. no = item.no,
  704. };
  705. groupLists.Add(group);
  706. }
  707. //取差集,减少二次搜寻
  708. classes = classes.Except(groupLists.Select(y => y.id)).ToList();
  709. }
  710. }
  711. if (classes.IsNotEmpty())
  712. {
  713. List<RGroupList> privateList = new List<RGroupList>();
  714. sql = string.Join(",", classes.Select(x => $"'{x}'"));
  715. await foreach (var item in client.GetContainer(Constant.TEAMModelOS, "Teacher").GetItemQueryIterator<RGroupList>(queryText: $"select value(c) from c where c.id in ({sql})",
  716. requestOptions: new QueryRequestOptions() { PartitionKey = new Azure.Cosmos.PartitionKey($"GroupList") }))
  717. {
  718. privateList.Add(item);
  719. //if (string.IsNullOrWhiteSpace(school))
  720. //{
  721. // privateList.Add(item);
  722. //}
  723. //else
  724. //{
  725. // if (!string.IsNullOrWhiteSpace(item.school))
  726. // {
  727. // if (item.school.Equals(school))
  728. // {
  729. // privateList.Add(item);
  730. // }
  731. // }
  732. // else
  733. // {
  734. // privateList.Add(item);
  735. // }
  736. //}
  737. }
  738. if (privateList.IsNotEmpty())
  739. {
  740. groups.Add("Teacher", privateList);
  741. }
  742. }
  743. foreach (var item in groups)
  744. {
  745. var list = item.Value.GroupBy(x => x.type).Select(y => new { key = y.Key, list = y.ToList() });
  746. foreach (var group in list)
  747. {
  748. (List<RGroupList> rgroups, List<RMember> rmembers) = await GetGroupListMemberInfo(_coreAPIHttpService, client, group.key, group.list, item.Key, _dingDing, school);
  749. members.AddRange(rmembers);
  750. }
  751. }
  752. groupLists.AddRange(groups.SelectMany(x => x.Value).ToList());
  753. if (students.IsNotEmpty())
  754. {
  755. List<string> sqlList = students.Select(x => x.classId).ToList();
  756. string insql = string.Join(",", sqlList.Select(x => $"'{x}'"));
  757. await foreach (var item in client.GetContainer(Constant.TEAMModelOS, "School").
  758. GetItemQueryIterator<RGroupList>(queryText: $"select c.id,c.code,c.name,c.no,c.periodId,c.scope,c.school,c.creatorId,c.type,c.year,c.tcount,c.scount,c.teacher.id as leader from c where c.id in ({insql})",
  759. requestOptions: new QueryRequestOptions() { PartitionKey = new Azure.Cosmos.PartitionKey($"Class-{school}") }))
  760. {
  761. ///行政班(学生搜寻classId动态返回)class
  762. List<RMember> smembers = students.Where(x => x.classId.Equals(item.id))
  763. .Select(y => new RMember
  764. {
  765. id = y.id,
  766. code = school,
  767. name = y.name,
  768. //nickname = y.name,
  769. type = 2,
  770. picture = y.picture,
  771. no = y.no,
  772. classId = y.classId,
  773. //groupId=y.groupId,
  774. groupName = y.groupName,
  775. irs = y.irs,
  776. }).ToList();
  777. members.AddRange(smembers);
  778. RGroupList group = new RGroupList
  779. {
  780. id = item.id,
  781. code = $"GroupList-{school}",
  782. name = item.name,
  783. periodId = item.periodId,
  784. scope = "school",
  785. school = school,
  786. type = "class",
  787. year = item.year,
  788. members = smembers,
  789. scount = smembers.Count,
  790. no = item.no,
  791. leader = item.leader,
  792. pk = "GroupList"
  793. };
  794. groupLists.Add(group);
  795. }
  796. //去重。
  797. members = members.FindAll(x => x.type == 2).Where((x, i) => members.FindAll(x => x.type == 2).FindIndex(n => n.id.Equals(x.id) && n.code.Equals(x.code)) == i).ToList();
  798. }
  799. }
  800. if (groupids.IsNotEmpty())
  801. {
  802. List<RMember> rmembers = new List<RMember>();
  803. groupLists.ForEach(y => {
  804. (string id, List<string> grpids) = groupids.Find(x => x.Item1.Equals(y.id));
  805. var gpmember = y.members.FindAll(x => !string.IsNullOrEmpty(x.groupName) && grpids.Contains(x.groupName));
  806. if (grpids.Contains("default"))
  807. {
  808. var gpmemberdft = y.members.FindAll(x => string.IsNullOrWhiteSpace(x.groupName));
  809. if (gpmember.IsNotEmpty())
  810. {
  811. gpmember.AddRange(gpmemberdft);
  812. }
  813. else
  814. {
  815. gpmember = gpmemberdft;
  816. }
  817. }
  818. y.members = gpmember;
  819. });
  820. var gpgpmembers = groupLists.SelectMany(x => x.members).ToList();
  821. List<RMember> tmdids = gpgpmembers.FindAll(x => x.type == 1).Where((x, i) => gpgpmembers.FindAll(x => x.type == 1).FindIndex(n => n.id.Equals(x.id)) == i).ToList();
  822. List<RMember> students = gpgpmembers.FindAll(x => x.type == 2).Where((x, i) => gpgpmembers.FindAll(x => x.type == 2).FindIndex(n => n.id.Equals(x.id) && n.code.Equals(x.code)) == i).ToList();
  823. if (tmdids.IsNotEmpty())
  824. {
  825. rmembers.AddRange(tmdids);
  826. }
  827. if (students.IsNotEmpty())
  828. {
  829. rmembers.AddRange(students);
  830. }
  831. return (rmembers, groupLists);
  832. }
  833. else
  834. {
  835. return (members, groupLists);
  836. }
  837. }
  838. public static async Task<List<RGroupList>> GetGroupListMemberByType(CoreAPIHttpService _coreAPIHttpService, CosmosClient client, string type, List<string> scopes, string school, DingDing _dingDing)
  839. {
  840. StringBuilder sql = new StringBuilder($"SELECT distinct value(c) FROM c where c.type='{type}'");
  841. Dictionary<string, List<RGroupList>> groups = new Dictionary<string, List<RGroupList>>();
  842. if (scopes.Contains("school"))
  843. {
  844. if (!string.IsNullOrEmpty(school))
  845. {
  846. List<RGroupList> groupLists = new List<RGroupList>();
  847. await foreach (var item in client.GetContainer(Constant.TEAMModelOS, "School").GetItemQueryIterator<RGroupList>(queryText: sql.ToString(),
  848. requestOptions: new QueryRequestOptions() { PartitionKey = new Azure.Cosmos.PartitionKey($"GroupList-{school}") }))
  849. {
  850. groupLists.Add(item);
  851. }
  852. groups.Add("School", groupLists);
  853. }
  854. }
  855. else if (scopes.Contains("private"))
  856. {
  857. List<RGroupList> groupLists = new List<RGroupList>();
  858. await foreach (var item in client.GetContainer(Constant.TEAMModelOS, "Teacher").GetItemQueryIterator<RGroupList>(queryText: sql.ToString(),
  859. requestOptions: new QueryRequestOptions() { PartitionKey = new Azure.Cosmos.PartitionKey($"GroupList") }))
  860. {
  861. groupLists.Add(item);
  862. //if (string.IsNullOrWhiteSpace(school))
  863. //{
  864. // groupLists.Add(item);
  865. //}
  866. //else
  867. //{
  868. // if (!string.IsNullOrWhiteSpace(item.school))
  869. // {
  870. // if (item.school.Equals(school))
  871. // {
  872. // groupLists.Add(item);
  873. // }
  874. // }
  875. // else {
  876. // groupLists.Add(item);
  877. // }
  878. //}
  879. }
  880. groups.Add("Teacher", groupLists);
  881. }
  882. foreach (var item in groups)
  883. {
  884. var list = item.Value.GroupBy(x => x.type).Select(y => new { key = y.Key, list = y.ToList() });
  885. foreach (var group in list)
  886. {
  887. (List<RGroupList> rgroups, List<RMember> rmembers) = await GetGroupListMemberInfo(_coreAPIHttpService, client, group.key, group.list, item.Key, _dingDing, school);
  888. }
  889. }
  890. var lists = groups.SelectMany(x => x.Value).ToList();
  891. return lists;
  892. }
  893. public static async Task<(List<RGroupList> groups, List<RMember> members)> GetGroupListMemberInfo(CoreAPIHttpService _coreAPIHttpService, CosmosClient client, string type, List<RGroupList> groups, string groupTbname, DingDing _dingDing, string school)
  894. {
  895. try
  896. {
  897. HashSet<RGroupList> changes = new HashSet<RGroupList>();
  898. var members = groups.SelectMany(y => y.members).ToList();
  899. //去重
  900. List<RMember> tmdids = members.FindAll(x => x.type == 1).Where((x, i) => members.FindAll(x => x.type == 1).FindIndex(n => n.id.Equals(x.id)) == i).ToList();
  901. List<RMember> students = members.FindAll(x => x.type == 2).Where((x, i) => members.FindAll(x => x.type == 2).FindIndex(n => n.id.Equals(x.id) && n.code.Equals(x.code)) == i).ToList();
  902. var stu = students.GroupBy(x => x.code).Select(y => new { key = y.Key, list = y.ToList() });
  903. List<Student> studentsData = new List<Student>();
  904. if (stu != null)
  905. {
  906. foreach (var item in stu)
  907. {
  908. var ids = item.list.Select(x => x.id).ToList();
  909. if (ids.IsNotEmpty())
  910. {
  911. StringBuilder stuSql = new StringBuilder($"SELECT distinct c.name,c.id,c.code,c.picture,c.no,c.irs,c.classId FROM c ");
  912. string insql = string.Join(",", ids.Select(x => $"'{x}'"));
  913. stuSql.Append($"where c.id in ({insql})");
  914. await foreach (var student in client.GetContainer(Constant.TEAMModelOS, "Student").GetItemQueryIterator<Student>(queryText: stuSql.ToString(),
  915. requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"Base-{item.key}") }))
  916. {
  917. student.schoolId = item.key;
  918. studentsData.Add(student);
  919. }
  920. }
  921. }
  922. var unexist_student = students.Select(x => (x.id, x.code)).Except(studentsData.Select(y => (y.id, y.schoolId)), new CompareIdCode()).ToList();
  923. groups.ForEach(x =>
  924. {
  925. int item = x.members.RemoveAll(y => y.type == 2 && unexist_student.Exists(x => x.id.Equals(y.id) && x.Item2.Equals(y.code)));
  926. if (item > 0)
  927. {
  928. changes.Add(x);
  929. }
  930. });
  931. }
  932. List<TmdUser> tmdsData = new List<TmdUser>();
  933. if (tmdids.IsNotEmpty())
  934. {
  935. string memberTbname = "";
  936. if ($"{type}".Equals("activity"))
  937. {
  938. var mbers = groups.SelectMany(x => x.members).Where(z => !string.IsNullOrEmpty(z.code));
  939. var schoolTeachers = mbers.GroupBy(y => y.code).Select(m => new { key = m.Key, list = m.ToList() });
  940. foreach (var schoolTeacher in schoolTeachers)
  941. {
  942. StringBuilder tmdidSql = new StringBuilder($"SELECT distinct c.name,c.id,c.picture FROM c ");
  943. string insql = string.Join(",", schoolTeacher.list.Select(x => $"'{x.id}'"));
  944. tmdidSql.Append($" where c.id in ({insql})");
  945. await foreach (var tmd in client.GetContainer(Constant.TEAMModelOS, "School").GetItemQueryIterator<TmdUser>(queryText: tmdidSql.ToString(),
  946. requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"Teacher-{schoolTeacher.key}") }))
  947. {
  948. tmdsData.Add(tmd);
  949. }
  950. }
  951. var unexist_teachers = mbers.Select(x => (x.id, x.code)).Except(tmdsData.Select(y => (y.id, y.code)), new CompareIdCode()).ToList();
  952. groups.ForEach(x =>
  953. {
  954. int item = x.members.RemoveAll(y => y.type == 2 && unexist_teachers.Exists(x => x.id.Equals(y.id) && x.Item2.Equals(y.code)));
  955. if (item > 0)
  956. {
  957. changes.Add(x);
  958. }
  959. });
  960. }
  961. else
  962. {
  963. //处理研修名单,如果是学校老师的,则需要检查SchoolTeacher
  964. //处理 学校教研组,学校管理人员,学校任课教师,学校研修名单。
  965. if (!string.IsNullOrEmpty(school) && ($"{type}".Equals("yxtrain") || $"{type}".Equals("research") || $"{type}".Equals("manage") || $"{type}".Equals("subject")))
  966. {
  967. StringBuilder tmdidSql = new StringBuilder($"SELECT distinct c.name,c.id,c.picture FROM c ");
  968. string insql = string.Join(",", tmdids.Select(x => $"'{x.id}'"));
  969. tmdidSql.Append($" where c.id in ({insql})");
  970. await foreach (var tmd in client.GetContainer(Constant.TEAMModelOS, "School").GetItemQueryIterator<TmdUser>(queryText: tmdidSql.ToString(),
  971. requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"Teacher-{school}") }))
  972. {
  973. tmdsData.Add(tmd);
  974. }
  975. }
  976. else
  977. {
  978. {
  979. StringBuilder tmdidSql = new StringBuilder($"SELECT distinct c.name,c.id,c.picture FROM c ");
  980. string insql = string.Join(",", tmdids.Select(x => $"'{x.id}'"));
  981. tmdidSql.Append($" where c.id in ({insql})");
  982. memberTbname = "Teacher";
  983. await foreach (var tmd in client.GetContainer(Constant.TEAMModelOS, memberTbname).GetItemQueryIterator<TmdUser>(queryText: tmdidSql.ToString(),
  984. requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"Base") }))
  985. {
  986. tmdsData.Add(tmd);
  987. }
  988. }
  989. {
  990. //取差集,减少二次搜寻
  991. var tmdidexp = tmdids.Select(x => x.id).Except(tmdsData.Select(y => y.id)).ToList();
  992. if (tmdidexp.IsNotEmpty())
  993. {
  994. StringBuilder tmdidSql = new StringBuilder($"SELECT distinct c.name,c.id,c.picture FROM c ");
  995. string insql = string.Join(",", tmdidexp.Select(x => $"'{x}'"));
  996. tmdidSql.Append($" where c.id in ({insql})");
  997. memberTbname = "Student";
  998. await foreach (var tmd in client.GetContainer(Constant.TEAMModelOS, memberTbname).GetItemQueryIterator<TmdUser>(queryText: tmdidSql.ToString(),
  999. requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"Base") }))
  1000. {
  1001. tmdsData.Add(tmd);
  1002. }
  1003. }
  1004. }
  1005. }
  1006. tmdsData = tmdsData.Where((x, i) => tmdsData.FindIndex(n => n.id.Equals(x.id)) == i).ToList();
  1007. var unexist_tmdid = tmdids.Select(x => x.id).Except(tmdsData.Select(y => y.id)).ToList();
  1008. groups.ForEach(x =>
  1009. {
  1010. int item = x.members.RemoveAll(y => unexist_tmdid.Contains(y.id) && y.type == 1);
  1011. if (item > 0)
  1012. {
  1013. changes.Add(x);
  1014. }
  1015. });
  1016. }
  1017. }
  1018. if (tmdids.IsNotEmpty() && _coreAPIHttpService.check) {
  1019. ///获取真实的名称
  1020. var content = new StringContent(tmdids.Select(x => x.id).ToHashSet().ToJsonString(), Encoding.UTF8, "application/json");
  1021. string json = null;
  1022. try
  1023. {
  1024. json = await _coreAPIHttpService.GetUserInfos(content);
  1025. if (!string.IsNullOrWhiteSpace(json))
  1026. {
  1027. List<TmdInfo> tmdInfos = json.ToObject<List<TmdInfo>>();
  1028. if (tmdInfos.IsNotEmpty())
  1029. {
  1030. tmdsData.ForEach(y =>
  1031. {
  1032. var tmd = tmdInfos.Find(x => x.id.Equals(y.id));
  1033. if (tmd != null)
  1034. {
  1035. y.name = tmd?.name;
  1036. y.picture = tmd?.picture;
  1037. }
  1038. else
  1039. {
  1040. groups.ForEach(x =>
  1041. {
  1042. int item = x.members.RemoveAll(z => z.id.Equals(y.id) && z.type == 1);
  1043. if (item > 0)
  1044. {
  1045. changes.Add(x);
  1046. }
  1047. });
  1048. }
  1049. });
  1050. }
  1051. }
  1052. }
  1053. catch (Exception ex)
  1054. {
  1055. await _dingDing.SendBotMsg($"{_coreAPIHttpService.options.Get("Default").location}用户转换失败:{_coreAPIHttpService.options.Get("Default").url}{json}\n {ex.Message}\n{ex.StackTrace}{tmdids.Select(x => x.id).ToJsonString()}", GroupNames.醍摩豆服務運維群組);
  1056. }
  1057. }
  1058. tmdids.ForEach(x =>
  1059. {
  1060. var user = tmdsData.Find(y => y.id.Equals(x.id));
  1061. x.name = user?.name;
  1062. // x.nickname = string.IsNullOrWhiteSpace(x.nickname) ? user?.name : x.nickname;
  1063. x.picture = user?.picture;
  1064. });
  1065. students.ForEach(x =>
  1066. {
  1067. var student = studentsData.Find(y => y.id.Equals(x.id) && y.schoolId.Equals(x.code));
  1068. x.name = student?.name;
  1069. // x.nickname = string.IsNullOrWhiteSpace(x.nickname) ? student?.name:x.nickname;
  1070. x.picture = student?.picture;
  1071. x.classId = student?.classId;
  1072. });
  1073. var mbs = tmdids;
  1074. mbs.AddRange(students);
  1075. if (changes.Count > 0 && !string.IsNullOrEmpty(groupTbname))
  1076. {
  1077. foreach (var change in changes)
  1078. {
  1079. change.tcount = change.members.Where(x => x.type == 1).Count();
  1080. change.scount = change.members.Where(x => x.type == 2).Count();
  1081. GroupList group = change.ToJsonString().ToObject<GroupList>();
  1082. await client.GetContainer(Constant.TEAMModelOS, groupTbname).ReplaceItemAsync(group, group.id, new PartitionKey(group.code));
  1083. }
  1084. }
  1085. groups.ForEach(x => x.members.ForEach(y => {
  1086. if (y.type == 1)
  1087. {
  1088. var tmd = tmdids.Find(t => t.id.Equals(y.id));
  1089. y.name = tmd?.name;
  1090. //y.nickname = string.IsNullOrWhiteSpace(y.nickname) ? tmd?.nickname : y.nickname;
  1091. y.picture = tmd?.picture;
  1092. }
  1093. if (y.type == 2)
  1094. {
  1095. var student = students.Find(t => t.id.Equals(y.id) && t.code.Equals(y.code));
  1096. y.name = student?.name;
  1097. // y.nickname = string.IsNullOrWhiteSpace(y.nickname) ? student?.nickname : y.nickname;
  1098. y.picture = student?.picture;
  1099. y.classId = student?.classId;
  1100. }
  1101. }));
  1102. HashSet<string> schoolCodes = groups.SelectMany(x => x.members).Where(y => !string.IsNullOrEmpty(y.code)).Select(z => z.code).ToHashSet();
  1103. if (schoolCodes != null && schoolCodes.Count > 0)
  1104. {
  1105. List<School> schools = new List<School>();
  1106. string insql = $"select c.name,c.id from c where c.id in ({string.Join(",", schoolCodes.Select(x => $"'{x}'"))})";
  1107. await foreach (var item in client.GetContainer(Constant.TEAMModelOS, "School").GetItemQueryIterator<School>(queryText: insql, requestOptions: new QueryRequestOptions { PartitionKey = new PartitionKey("Base") }))
  1108. {
  1109. schools.Add(item);
  1110. }
  1111. if (schools.IsNotEmpty())
  1112. {
  1113. groups.SelectMany(x => x.members).Where(y => !string.IsNullOrEmpty(y.code)).ToList().ForEach(z => {
  1114. var school = schools.Find(j => j.id.Equals(z.code));
  1115. z.schoolName = school?.name;
  1116. });
  1117. }
  1118. }
  1119. return (groups, mbs);
  1120. }
  1121. catch (Exception ex)
  1122. {
  1123. await _dingDing.SendBotMsg($"{_coreAPIHttpService.options.Get("Default").location},GetGroupListMemberInfo()\n{ex.Message}\n{ex.StackTrace}\n", GroupNames.醍摩豆服務運維群組);
  1124. }
  1125. return (null, null);
  1126. }
  1127. }
  1128. public class CompareIdCode : IEqualityComparer<(string id, string code)>
  1129. {
  1130. public bool Equals((string id, string code) x, (string id, string code) y)
  1131. {
  1132. return x.id.Equals(y.id) && x.code.Equals(y.code);
  1133. }
  1134. public int GetHashCode((string id, string code) obj)
  1135. {
  1136. if (obj.id != null && obj.code != null)
  1137. {
  1138. return 1;
  1139. }
  1140. else
  1141. {
  1142. return 0;
  1143. }
  1144. }
  1145. }
  1146. }