GroupListService.cs 69 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369
  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. ///获取真实的名称
  1140. var content = new StringContent(tmdids.Select(x => x.id).ToHashSet().ToJsonString(), Encoding.UTF8, "application/json");
  1141. string json = null;
  1142. try
  1143. {
  1144. json = await _coreAPIHttpService.GetUserInfos(content);
  1145. if (!string.IsNullOrWhiteSpace(json))
  1146. {
  1147. List<TmdInfo> tmdInfos = json.ToObject<List<TmdInfo>>();
  1148. if (tmdInfos.IsNotEmpty())
  1149. {
  1150. tmdsData.ForEach(y =>
  1151. {
  1152. var tmd = tmdInfos.Find(x => x.id.Equals(y.id));
  1153. if (tmd != null)
  1154. {
  1155. y.name = tmd?.name;
  1156. y.picture = tmd?.picture;
  1157. }
  1158. else
  1159. {
  1160. groups.ForEach(x =>
  1161. {
  1162. int item = x.members.RemoveAll(z => z.id.Equals(y.id) && z.type == 1);
  1163. if (item > 0)
  1164. {
  1165. changes.Add(x);
  1166. }
  1167. });
  1168. }
  1169. });
  1170. }
  1171. }
  1172. }
  1173. catch (Exception ex)
  1174. {
  1175. 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.醍摩豆服務運維群組);
  1176. }
  1177. }
  1178. tmdids.ForEach(x =>
  1179. {
  1180. var user = tmdsData.Find(y => y.id.Equals(x.id));
  1181. x.name = user?.name;
  1182. // x.nickname = string.IsNullOrWhiteSpace(x.nickname) ? user?.name : x.nickname;
  1183. x.picture = user?.picture;
  1184. });
  1185. students.ForEach(x =>
  1186. {
  1187. var student = studentsData.Find(y => y.id.Equals(x.id) && y.schoolId.Equals(x.code));
  1188. x.name = student?.name;
  1189. // x.nickname = string.IsNullOrWhiteSpace(x.nickname) ? student?.name:x.nickname;
  1190. x.picture = student?.picture;
  1191. x.classId = student?.classId;
  1192. x.graduate = student.graduate;
  1193. });
  1194. var mbs = tmdids;
  1195. mbs.AddRange(students);
  1196. if (changes.Count > 0 && !string.IsNullOrEmpty(groupTbname))
  1197. {
  1198. foreach (var change in changes)
  1199. {
  1200. change.tcount = change.members.Where(x => x.type == 1).Count();
  1201. change.scount = change.members.Where(x => x.type == 2).Count();
  1202. GroupList group = change.ToJsonString().ToObject<GroupList>();
  1203. await client.GetContainer(Constant.TEAMModelOS, groupTbname).ReplaceItemAsync(group, group.id, new PartitionKey(group.code));
  1204. }
  1205. }
  1206. groups.ForEach(x => x.members.ForEach(y => {
  1207. if (y.type == 1)
  1208. {
  1209. var tmd = tmdids.Find(t => t.id.Equals(y.id));
  1210. y.name = tmd?.name;
  1211. //y.nickname = string.IsNullOrWhiteSpace(y.nickname) ? tmd?.nickname : y.nickname;
  1212. y.picture = tmd?.picture;
  1213. }
  1214. if (y.type == 2)
  1215. {
  1216. var student = students.Find(t => t.id.Equals(y.id) && t.code.Equals(y.code));
  1217. y.name = student?.name;
  1218. // y.nickname = string.IsNullOrWhiteSpace(y.nickname) ? student?.nickname : y.nickname;
  1219. y.picture = student?.picture;
  1220. y.classId = student?.classId;
  1221. y.graduate = student.graduate;
  1222. }
  1223. }));
  1224. HashSet<string> schoolCodes = groups.SelectMany(x => x.members).Where(y => !string.IsNullOrEmpty(y.code)).Select(z => z.code).ToHashSet();
  1225. if (schoolCodes != null && schoolCodes.Count > 0)
  1226. {
  1227. List<School> schools = new List<School>();
  1228. string insql = $"select c.name,c.id from c where c.id in ({string.Join(",", schoolCodes.Select(x => $"'{x}'"))})";
  1229. await foreach (var item in client.GetContainer(Constant.TEAMModelOS, "School").GetItemQueryIterator<School>(queryText: insql, requestOptions: new QueryRequestOptions { PartitionKey = new PartitionKey("Base") }))
  1230. {
  1231. schools.Add(item);
  1232. }
  1233. if (schools.IsNotEmpty())
  1234. {
  1235. groups.SelectMany(x => x.members).Where(y => !string.IsNullOrEmpty(y.code)).ToList().ForEach(z => {
  1236. var school = schools.Find(j => j.id.Equals(z.code));
  1237. z.schoolName = school?.name;
  1238. });
  1239. }
  1240. }
  1241. if (graduate >= 0)
  1242. {
  1243. groups= groups.FindAll(x => x.graduate == graduate);
  1244. if (groups != null) {
  1245. groups.ForEach(x =>
  1246. {
  1247. x.members.RemoveAll(y => y.graduate != graduate);
  1248. });
  1249. }
  1250. mbs.RemoveAll(z => z.graduate != graduate);
  1251. }
  1252. //直接返回
  1253. else {
  1254. return (groups, mbs);
  1255. }
  1256. }
  1257. catch (Exception ex)
  1258. {
  1259. await _dingDing.SendBotMsg($"{_coreAPIHttpService.options.Get("Default").location},GetGroupListMemberInfo()\n{ex.Message}\n{ex.StackTrace}\n", GroupNames.醍摩豆服務運維群組);
  1260. }
  1261. return (null, null);
  1262. }
  1263. /// <summary>
  1264. /// 处理活动结束的
  1265. /// </summary>
  1266. /// <param name="_coreAPIHttpService"></param>
  1267. /// <param name="cosmosClient">数据库</param>
  1268. /// <param name="_dingDing">钉钉消息</param>
  1269. /// <param name="school">学校编码</param>
  1270. /// <param name="classes">行政班</param>
  1271. /// <param name="stuLists">学生</param>
  1272. /// <param name="tchLists">教师</param>
  1273. /// <param name="_groupLists">分组</param>
  1274. /// <param name="graduate">毕业类型0在校,1毕业 , -1查全部。</param>
  1275. /// <returns></returns>
  1276. 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)
  1277. {
  1278. List<FMember> fMembers = new();
  1279. if (classes != null && classes.Count > 0)
  1280. {
  1281. (List<RMember> staffList, List<RGroupList> classInfos) = await GetMemberByListids(_coreAPIHttpService, cosmosClient, _dingDing, classes, school);
  1282. staffList.ForEach(x => fMembers.Add(new FMember() { id = x.id, code = school, type = 1, }));
  1283. }
  1284. if (stuLists != null && stuLists.Count > 0)
  1285. {
  1286. (List<RMember> staffList, List<RGroupList> classInfos) = await GetMemberByListids(_coreAPIHttpService, cosmosClient, _dingDing, stuLists, school);
  1287. staffList.ForEach(x => fMembers.Add(new FMember() { id = x.id, code = school, type = 2 }));
  1288. }
  1289. if (tchLists != null && tchLists.Count > 0)
  1290. {
  1291. (List<RMember> staffList, List<RGroupList> classInfos) = await GetMemberByListids(_coreAPIHttpService, cosmosClient, _dingDing, tchLists, school);
  1292. staffList.ForEach(x => fMembers.Add(new FMember() { id = x.id, code = school, type = 2 }));
  1293. }
  1294. if (_groupLists != null && _groupLists.Count > 0)
  1295. {
  1296. (List<RMember> staffList, List<RGroupList> groupLists1) = await GetMemberByListids(_coreAPIHttpService, cosmosClient, _dingDing, classes, school, _groupLists);
  1297. staffList.ForEach(x => fMembers.Add(new FMember() { id = x.id, code = school, type = 2 }));
  1298. }
  1299. return fMembers;
  1300. }
  1301. }
  1302. public class CompareIdCode : IEqualityComparer<(string id, string code)>
  1303. {
  1304. public bool Equals((string id, string code) x, (string id, string code) y)
  1305. {
  1306. return x.id.Equals(y.id) && x.code.Equals(y.code);
  1307. }
  1308. public int GetHashCode((string id, string code) obj)
  1309. {
  1310. if (obj.id != null && obj.code != null)
  1311. {
  1312. return 1;
  1313. }
  1314. else
  1315. {
  1316. return 0;
  1317. }
  1318. }
  1319. }
  1320. }