GroupListService.cs 70 KB

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