GroupListService.cs 61 KB

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