CourseController.cs 105 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954
  1. using Azure.Cosmos;
  2. using Microsoft.AspNetCore.Http;
  3. using Microsoft.AspNetCore.Mvc;
  4. using Microsoft.Extensions.Options;
  5. using System;
  6. using System.Collections.Generic;
  7. using System.IdentityModel.Tokens.Jwt;
  8. using System.IO;
  9. using System.Linq;
  10. using System.Text;
  11. using System.Text.Json;
  12. using System.Threading.Tasks;
  13. using TEAMModelOS.Models;
  14. using TEAMModelOS.Models.Dto;
  15. using TEAMModelOS.SDK.Models;
  16. using TEAMModelOS.SDK;
  17. using TEAMModelOS.SDK.DI;
  18. using TEAMModelOS.SDK.DI.AzureCosmos.Inner;
  19. using TEAMModelOS.SDK.Extension;
  20. using TEAMModelOS.SDK;
  21. using TEAMModelOS.SDK.Helper.Common.StringHelper;
  22. using System.Dynamic;
  23. using Azure;
  24. using TEAMModelOS.SDK.Models.Cosmos.Common;
  25. using Azure.Messaging.ServiceBus;
  26. using Microsoft.Extensions.Configuration;
  27. using TEAMModelOS.Filter;
  28. using Azure.Storage.Blobs.Models;
  29. namespace TEAMModelOS.Controllers
  30. {
  31. [ProducesResponseType(StatusCodes.Status200OK)]
  32. [ProducesResponseType(StatusCodes.Status400BadRequest)]
  33. //[Authorize(Roles = "IES5")]
  34. [Route("school/course")]
  35. [ApiController]
  36. public class CourseController : ControllerBase
  37. {
  38. private AzureCosmosFactory _azureCosmos;
  39. private readonly DingDing _dingDing;
  40. private readonly Option _option;
  41. private readonly AzureServiceBusFactory _serviceBus;
  42. private readonly AzureStorageFactory _azureStorage;
  43. public IConfiguration _configuration { get; set; }
  44. public CourseController(AzureCosmosFactory azureCosmos, DingDing dingDing, IOptionsSnapshot<Option> option, AzureServiceBusFactory serviceBus, AzureStorageFactory azureStorage, IConfiguration configuration)
  45. {
  46. _azureCosmos = azureCosmos;
  47. _dingDing = dingDing;
  48. _option = option?.Value;
  49. _serviceBus = serviceBus;
  50. _configuration = configuration;
  51. _azureStorage = azureStorage;
  52. }
  53. /// <summary>
  54. /// 更新保存课程
  55. /// </summary>
  56. /// <param name="request"></param>
  57. /// <returns></returns>
  58. [ProducesDefaultResponseType]
  59. [AuthToken(Roles = "teacher")]
  60. [HttpPost("upsert")]
  61. public async Task<IActionResult> upsert(JsonElement requert)
  62. {
  63. try
  64. {
  65. (string id, _, _, string school) = HttpContext.GetAuthTokenInfo();
  66. Course course = new Course();
  67. if (!requert.TryGetProperty("course", out JsonElement _course)) return BadRequest();
  68. if (!requert.TryGetProperty("option", out JsonElement option)) return BadRequest();
  69. if (!requert.TryGetProperty("scope", out JsonElement scope)) return BadRequest();
  70. course = _course.ToObject<Course>();
  71. var client = _azureCosmos.GetCosmosClient();
  72. course.pk = typeof(Course).Name;
  73. if (course.scope.Equals("school", StringComparison.OrdinalIgnoreCase))
  74. {
  75. course.school = school;
  76. course.creatorId = id;
  77. }
  78. else
  79. {
  80. course.creatorId = id;
  81. }
  82. string code = course.code;
  83. course.code = typeof(Course).Name + "-" + course.code;
  84. if (option.ToString().Equals("insert"))
  85. {
  86. if (scope.ToString().Equals("school", StringComparison.OrdinalIgnoreCase))
  87. {
  88. var response = await client.GetContainer("TEAMModelOS", "School").ReadItemStreamAsync(course.id, new PartitionKey($"Course-{code}"));
  89. if (response.Status == 200)
  90. {
  91. return Ok(new { error = ResponseCode.DATA_EXIST, V = "课程编码已经存在!" });
  92. }
  93. else
  94. {
  95. CourseChange courseChange = new CourseChange { id = course.id, code = course.code, name = course.name, scope = course.scope, school = course.school, creatorId = course.creatorId };
  96. courseChange.addClass = course.schedule.Select(x => x.classId).ToList();
  97. courseChange.addList = course.schedule.Select(x => x.stulist).ToList();
  98. course = await _azureCosmos.GetCosmosClient().GetContainer("TEAMModelOS", "School").CreateItemAsync(course, new PartitionKey($"Course-{code}"));
  99. }
  100. }
  101. else
  102. {
  103. var response = await client.GetContainer("TEAMModelOS", "Teacher").ReadItemStreamAsync(course.id, new PartitionKey($"Course-{code}"));
  104. if (response.Status == 200)
  105. {
  106. return Ok(new { error = ResponseCode.DATA_EXIST, V = "课程编码已经存在!" });
  107. }
  108. else
  109. {
  110. CourseChange courseChange = new CourseChange { id = course.id, code = course.code, name = course.name, scope = course.scope, school = course.school, creatorId = course.creatorId };
  111. courseChange.addClass = course.schedule.Select(x => x.classId).ToList();
  112. courseChange.addList = course.schedule.Select(x => x.stulist).ToList();
  113. var messageBlob = new ServiceBusMessage(courseChange.ToJsonString()); ;
  114. messageBlob.ApplicationProperties.Add("name", "Course");
  115. var ActiveTask = _configuration.GetValue<string>("Azure:ServiceBus:ActiveTask");
  116. await _serviceBus.GetServiceBusClient().SendMessageAsync(ActiveTask, messageBlob);
  117. course = await _azureCosmos.GetCosmosClient().GetContainer("TEAMModelOS", "Teacher").CreateItemAsync(course, new PartitionKey($"Course-{code}"));
  118. }
  119. }
  120. }
  121. else
  122. {
  123. if (scope.ToString().Equals("school", StringComparison.OrdinalIgnoreCase))
  124. {
  125. Course odlCourse = await _azureCosmos.GetCosmosClient().GetContainer("TEAMModelOS", "School").ReadItemAsync<Course>(course.id, new PartitionKey($"Course-{code}"));
  126. CourseChange courseChange = new CourseChange { id = course.id, code = course.code, name = course.name, scope = course.scope, school = code };
  127. var oldCls = odlCourse.schedule.Select(x => x.classId).ToList();
  128. var oldLst = odlCourse.schedule.Select(x => x.stulist).ToList();
  129. var newCls = course.schedule.Select(x => x.classId).ToList();
  130. var newLst = course.schedule.Select(x => x.stulist).ToList();
  131. List<string> addCls = new List<string>();
  132. List<string> addLst = new List<string>();
  133. List<string> delCls = new List<string>();
  134. List<string> delLst = new List<string>();
  135. oldCls.ForEach(x =>
  136. {
  137. if (!newCls.Contains(x))
  138. {
  139. delCls.Add(x);
  140. }
  141. });
  142. newCls.ForEach(x =>
  143. {
  144. if (!oldCls.Contains(x))
  145. {
  146. addCls.Add(x);
  147. }
  148. });
  149. oldLst.ForEach(x =>
  150. {
  151. if (!newLst.Contains(x))
  152. {
  153. delLst.Add(x);
  154. }
  155. });
  156. newLst.ForEach(x =>
  157. {
  158. if (!oldLst.Contains(x))
  159. {
  160. addLst.Add(x);
  161. }
  162. });
  163. courseChange.addClass = addCls;
  164. courseChange.addList = addLst;
  165. courseChange.delClass = delCls;
  166. courseChange.delList = delLst;
  167. course = await _azureCosmos.GetCosmosClient().GetContainer("TEAMModelOS", "School").ReplaceItemAsync(course, course.id, new PartitionKey($"Course-{code}"));
  168. var messageBlob = new ServiceBusMessage(courseChange.ToJsonString()); ;
  169. messageBlob.ApplicationProperties.Add("name", "Course");
  170. var ActiveTask = _configuration.GetValue<string>("Azure:ServiceBus:ActiveTask");
  171. await _serviceBus.GetServiceBusClient().SendMessageAsync(ActiveTask, messageBlob);
  172. }
  173. else
  174. {
  175. Course odlCourse = await _azureCosmos.GetCosmosClient().GetContainer("TEAMModelOS", "Teacher").ReadItemAsync<Course>(course.id, new PartitionKey($"Course-{code}"));
  176. CourseChange courseChange = new CourseChange { id = course.id, code = course.code, name = course.name, scope = course.scope, creatorId = code };
  177. var oldCls = odlCourse.schedule.Select(x => x.classId).ToList();
  178. var oldLst = odlCourse.schedule.Select(x => x.stulist).ToList();
  179. var newCls = course.schedule.Select(x => x.classId).ToList();
  180. var newLst = course.schedule.Select(x => x.stulist).ToList();
  181. List<string> addCls = new List<string>();
  182. List<string> addLst = new List<string>();
  183. List<string> delCls = new List<string>();
  184. List<string> delLst = new List<string>();
  185. oldCls.ForEach(x =>
  186. {
  187. if (!newCls.Contains(x))
  188. {
  189. delCls.Add(x);
  190. }
  191. });
  192. newCls.ForEach(x =>
  193. {
  194. if (!oldCls.Contains(x))
  195. {
  196. addCls.Add(x);
  197. }
  198. });
  199. oldLst.ForEach(x =>
  200. {
  201. if (!newLst.Contains(x))
  202. {
  203. delLst.Add(x);
  204. }
  205. });
  206. newLst.ForEach(x =>
  207. {
  208. if (!oldLst.Contains(x))
  209. {
  210. addLst.Add(x);
  211. }
  212. });
  213. courseChange.addClass = addCls;
  214. courseChange.addList = addLst;
  215. courseChange.delClass = delCls;
  216. courseChange.delList = delLst;
  217. course = await _azureCosmos.GetCosmosClient().GetContainer("TEAMModelOS", "Teacher").ReplaceItemAsync(course, course.id, new PartitionKey($"Course-{code}"));
  218. var messageBlob = new ServiceBusMessage(courseChange.ToJsonString()); ;
  219. messageBlob.ApplicationProperties.Add("name", "Course");
  220. var ActiveTask = _configuration.GetValue<string>("Azure:ServiceBus:ActiveTask");
  221. await _serviceBus.GetServiceBusClient().SendMessageAsync(ActiveTask, messageBlob);
  222. }
  223. }
  224. return Ok(new { course });
  225. }
  226. catch (Exception ex)
  227. {
  228. await _dingDing.SendBotMsg($"OS,{_option.Location},course/upsert()\n{ex.Message}", GroupNames.醍摩豆服務運維群組);
  229. return BadRequest();
  230. }
  231. }
  232. [ProducesDefaultResponseType]
  233. [HttpPost("check")]
  234. public async Task<IActionResult> check(JsonElement json)
  235. {
  236. try
  237. {
  238. if (!json.TryGetProperty("tId", out JsonElement tId)) return BadRequest();
  239. if (!json.TryGetProperty("timeId", out JsonElement timeId)) return BadRequest();
  240. if (!json.TryGetProperty("code", out JsonElement code)) return BadRequest();
  241. if (!json.TryGetProperty("week", out JsonElement week)) return BadRequest();
  242. if (!json.TryGetProperty("cId", out JsonElement cId)) return BadRequest();
  243. var client = _azureCosmos.GetCosmosClient();
  244. var query = $"SELECT A0.room,A0.classId,A0.teacherId,A0.stulist,A0.time FROM c join A0 in c.schedule join A1 in A0.time where A0.teacherId = '{tId}'and A1.id = '{timeId}' and A1.week = '{week}' ";
  245. List<Schedule> teachers = new();
  246. await foreach (var item in client.GetContainer("TEAMModelOS", "School").GetItemQueryStreamIterator(queryText: query, requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"Course-{code}") }))
  247. {
  248. using var jsonCheck = await JsonDocument.ParseAsync(item.ContentStream);
  249. if (jsonCheck.RootElement.TryGetProperty("_count", out JsonElement count) && count.GetUInt16() > 0)
  250. {
  251. foreach (var obj in jsonCheck.RootElement.GetProperty("Documents").EnumerateArray())
  252. {
  253. teachers.Add(obj.ToObject<Schedule>());
  254. }
  255. }
  256. }
  257. if (teachers.Count > 0)
  258. {
  259. return Ok(new { msg = "该教师已有课程安排", code = 1 });
  260. }
  261. else
  262. {
  263. var queryClass = $"SELECT A0.room,A0.classId,A0.teacherId,A0.stulist,A0.time FROM c join A0 in c.schedule join A1 in A0.time where A1.id = '{timeId}' and A1.week = '{week}' and (A0.classId = '{cId}' or A0.stulist = '{cId}')";
  264. List<Schedule> courses = new();
  265. await foreach (var item in client.GetContainer("TEAMModelOS", "School").GetItemQueryStreamIterator(queryText: queryClass, requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"Course-{code}") }))
  266. {
  267. using var jsonCheck = await JsonDocument.ParseAsync(item.ContentStream);
  268. if (jsonCheck.RootElement.TryGetProperty("_count", out JsonElement count) && count.GetUInt16() > 0)
  269. {
  270. foreach (var obj in jsonCheck.RootElement.GetProperty("Documents").EnumerateArray())
  271. {
  272. courses.Add(obj.ToObject<Schedule>());
  273. }
  274. }
  275. }
  276. if (courses.Count > 0)
  277. {
  278. return Ok(new { msg = "该名单已有课程安排", code = 2 });
  279. }
  280. }
  281. return Ok(new { code = 0 });
  282. }
  283. catch (Exception ex)
  284. {
  285. await _dingDing.SendBotMsg($"OS,{_option.Location},course/check()\n{ex.Message}", GroupNames.醍摩豆服務運維群組);
  286. return BadRequest();
  287. }
  288. }
  289. /*
  290. {
  291. "stuListNo": "1124582",
  292. "studentId": "19990005",//tmdId/studentId 只能是其中一个有值
  293. "tmdId":"1538614518",
  294. }
  295. */
  296. /// <summary>
  297. /// 扫码加入名单
  298. /// </summary>
  299. /// <param name="json"></param>
  300. /// <returns></returns>
  301. [ProducesDefaultResponseType]
  302. [HttpPost("scan-code-join-list")]
  303. public async Task<IActionResult> ScanCodeJoinList(JsonElement json)
  304. {
  305. try
  306. {
  307. if (!json.TryGetProperty("stuListNo", out JsonElement _stuListNo)) return BadRequest();
  308. json.TryGetProperty("school", out JsonElement _school);
  309. string school = $"{_school}";
  310. var client = _azureCosmos.GetCosmosClient();
  311. var queryNo = $"SELECT * FROM c where c.no ='{_stuListNo}'";
  312. StuList stuList = null;
  313. json.TryGetProperty("studentId", out JsonElement _studentId);
  314. json.TryGetProperty("tmdId", out JsonElement _tmdId);
  315. if (!string.IsNullOrEmpty(school) && !string.IsNullOrEmpty($"{_studentId}"))
  316. {
  317. await foreach (var item in client.GetContainer("TEAMModelOS", "School").GetItemQueryStreamIterator(queryText: queryNo,
  318. requestOptions: new QueryRequestOptions() { PartitionKey = new Azure.Cosmos.PartitionKey($"StuList-{school}") }))
  319. {
  320. using var jsonNo = await JsonDocument.ParseAsync(item.ContentStream);
  321. if (jsonNo.RootElement.TryGetProperty("_count", out JsonElement count) && count.GetUInt16() > 0)
  322. {
  323. var stuDoc = jsonNo.RootElement.GetProperty("Documents").EnumerateArray();
  324. while (stuDoc.MoveNext())
  325. {
  326. JsonElement data = stuDoc.Current;
  327. stuList = data.ToObject<StuList>();
  328. if (stuList != null)
  329. {
  330. (int status, StuList stuLis) = JoinList(stuList, $"{_studentId}", $"{_tmdId}", school);
  331. stuLis = await upsertList(stuList, "school");
  332. return Ok(new { status, stuLis });
  333. }
  334. }
  335. }
  336. }
  337. }
  338. json.TryGetProperty("id_token", out JsonElement id_token);
  339. if (!string.IsNullOrEmpty($"{_tmdId}") && !string.IsNullOrEmpty($"{id_token}"))
  340. {
  341. var jwt = new JwtSecurityToken(id_token.GetString());
  342. var id = jwt.Payload.Sub;
  343. jwt.Payload.TryGetValue("name", out object name);
  344. jwt.Payload.TryGetValue("picture", out object picture);
  345. try
  346. {
  347. Teacher teacher = await client.GetContainer("TEAMModelOS", "Teacher").ReadItemAsync<Teacher>(id, new PartitionKey("Base"));
  348. }
  349. catch (CosmosException ex)
  350. {
  351. if (ex.Status == 404)
  352. {
  353. //如果沒有,則初始化Teacher基本資料到Cosmos
  354. Teacher teacher = new Teacher
  355. {
  356. id = id,
  357. pk = "Base",
  358. code = "Base",
  359. name = name?.ToString(),
  360. picture = picture?.ToString(),
  361. //创建账号并第一次登录IES5则默认赠送1G
  362. size = 1,
  363. defaultSchool = null,
  364. schools = new List<Teacher.School>(),
  365. };
  366. var container = _azureStorage.GetBlobContainerClient(id);
  367. await container.CreateIfNotExistsAsync(PublicAccessType.None); //嘗試創建Teacher私有容器,如存在則不做任何事,保障容器一定存在
  368. teacher = await _azureCosmos.GetCosmosClient().GetContainer("TEAMModelOS", "Teacher").CreateItemAsync<Teacher>(teacher, new PartitionKey("Base"));
  369. }
  370. }
  371. await foreach (var item in client.GetContainer("TEAMModelOS", "Teacher").GetItemQueryStreamIterator(queryText: queryNo,
  372. requestOptions: new QueryRequestOptions() { PartitionKey = new Azure.Cosmos.PartitionKey($"StuList") }))
  373. {
  374. using var jsonNo = await JsonDocument.ParseAsync(item.ContentStream);
  375. if (jsonNo.RootElement.TryGetProperty("_count", out JsonElement count) && count.GetUInt16() > 0)
  376. {
  377. var stuDoc = jsonNo.RootElement.GetProperty("Documents").EnumerateArray();
  378. while (stuDoc.MoveNext())
  379. {
  380. JsonElement data = stuDoc.Current;
  381. stuList = data.ToObject<StuList>();
  382. if (stuList != null)
  383. {
  384. (int status, StuList stuLis) = JoinList(stuList, $"{_studentId}", $"{_tmdId}", school);
  385. stuLis = await upsertList(stuList, "private");
  386. return Ok(new { status, stuLis });
  387. }
  388. }
  389. }
  390. }
  391. return Ok(new { status = -1 });
  392. }
  393. else
  394. {
  395. await _dingDing.SendBotMsg($"OS,{_option.Location},course/scan-code-join-list()\n扫码加入课程参数异常{json}", GroupNames.醍摩豆服務運維群組);
  396. return BadRequest();
  397. }
  398. }
  399. catch (Exception ex)
  400. {
  401. await _dingDing.SendBotMsg($"OS,{_option.Location},course/scan-code-join-list()\n{ex.Message}", GroupNames.醍摩豆服務運維群組);
  402. return BadRequest();
  403. }
  404. }
  405. /// <summary>
  406. /// 根据邀请码加入名单
  407. /// </summary>
  408. /// <param name="json"></param>
  409. /// <returns></returns>
  410. [ProducesDefaultResponseType]
  411. [AuthToken(Roles = "admin,teacher,student")]
  412. [HttpPost("get-list-by-no")]
  413. public async Task<IActionResult> GetListByNo(JsonElement json)
  414. {
  415. try
  416. {
  417. if (!json.TryGetProperty("stuListNo", out JsonElement _stuListNo)) return BadRequest();
  418. var (userid, _, _, school) = HttpContext.GetAuthTokenInfo();
  419. var client = _azureCosmos.GetCosmosClient();
  420. var queryNo = $"SELECT * FROM c where c.no ='{_stuListNo}'";
  421. StuList stuList = null;
  422. json.TryGetProperty("studentId", out JsonElement _studentId);
  423. json.TryGetProperty("tmdId", out JsonElement _tmdId);
  424. if (!string.IsNullOrEmpty(school))
  425. {
  426. await foreach (var item in client.GetContainer("TEAMModelOS", "School").GetItemQueryStreamIterator(queryText: queryNo,
  427. requestOptions: new QueryRequestOptions() { PartitionKey = new Azure.Cosmos.PartitionKey($"StuList-{school}") }))
  428. {
  429. using var jsonNo = await JsonDocument.ParseAsync(item.ContentStream);
  430. if (jsonNo.RootElement.TryGetProperty("_count", out JsonElement count) && count.GetUInt16() > 0)
  431. {
  432. var stuDoc = jsonNo.RootElement.GetProperty("Documents").EnumerateArray();
  433. while (stuDoc.MoveNext())
  434. {
  435. JsonElement data = stuDoc.Current;
  436. stuList = data.ToObject<StuList>();
  437. if (stuList != null)
  438. {
  439. (int status, StuList stuLis) = JoinList(stuList, $"{_studentId}", $"{_tmdId}", school);
  440. stuLis = await upsertList(stuList, "school");
  441. return Ok(new { status, stuLis });
  442. }
  443. }
  444. }
  445. }
  446. }
  447. await foreach (var item in client.GetContainer("TEAMModelOS", "Teacher").GetItemQueryStreamIterator(queryText: queryNo,
  448. requestOptions: new QueryRequestOptions() { PartitionKey = new Azure.Cosmos.PartitionKey($"StuList") }))
  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 stuDoc = jsonNo.RootElement.GetProperty("Documents").EnumerateArray();
  454. while (stuDoc.MoveNext())
  455. {
  456. JsonElement data = stuDoc.Current;
  457. stuList = data.ToObject<StuList>();
  458. if (stuList != null)
  459. {
  460. (int status, StuList stuLis) = JoinList(stuList, $"{_studentId}", $"{_tmdId}", school);
  461. stuLis = await upsertList(stuList, "private");
  462. return Ok(new { status, stuLis });
  463. }
  464. }
  465. }
  466. }
  467. return Ok(new { status = -1 });
  468. }
  469. catch (Exception ex)
  470. {
  471. await _dingDing.SendBotMsg($"OS,{_option.Location},course/get-list-by-no()\n{ex.Message}", GroupNames.醍摩豆服務運維群組);
  472. return BadRequest();
  473. }
  474. }
  475. public (int status, StuList stuList) JoinList(StuList stuList, string _studentId, string _tmdId, string school)
  476. {
  477. int status = -1;
  478. if (string.IsNullOrEmpty($"{_studentId}") && string.IsNullOrEmpty($"{_tmdId}"))
  479. {
  480. //加入学生或醍摩豆ID为空
  481. status = 1;
  482. }
  483. else
  484. {
  485. if (!string.IsNullOrEmpty($"{_studentId}") && !string.IsNullOrEmpty(school))
  486. {
  487. string _stuid = $"{_studentId}";
  488. var student = stuList.students.Find(x => x.id == _stuid);
  489. if (student != null)
  490. {
  491. //重复加入
  492. status = 2;
  493. }
  494. else
  495. {
  496. status = 0;
  497. stuList.students.Add(new Students { id = _stuid, code = $"Base-{school}", schoolId = $"{school}" });
  498. }
  499. }
  500. if (!string.IsNullOrEmpty($"{_tmdId}"))
  501. {
  502. string tmdid = $"{_tmdId}";
  503. var tmd = stuList.tmids.Find(x => x == tmdid);
  504. if (!string.IsNullOrEmpty(tmd))
  505. {
  506. //重复加入
  507. status = 2;
  508. }
  509. else
  510. {
  511. status = 0;
  512. stuList.tmids.Add(tmdid);
  513. }
  514. }
  515. }
  516. return (status, stuList);
  517. }
  518. //处理通用名单
  519. [ProducesDefaultResponseType]
  520. [AuthToken(Roles = "teacher,admin")]
  521. [HttpPost("upsert-list")]
  522. public async Task<IActionResult> upsertList(JsonElement json)
  523. {
  524. try
  525. {
  526. var (userid, _, _, school) = HttpContext.GetAuthTokenInfo();
  527. StuList stuList = new StuList();
  528. if (!json.TryGetProperty("stuList", out JsonElement student)) return BadRequest();
  529. if (!json.TryGetProperty("scope", out JsonElement scope)) return BadRequest();
  530. stuList = student.ToObject<StuList>();
  531. stuList.creatorId = userid;
  532. stuList.school = school;
  533. stuList = await upsertList(stuList, $"{scope}");
  534. return Ok(new { stuList });
  535. }
  536. catch (Exception ex)
  537. {
  538. await _dingDing.SendBotMsg($"OS,{_option.Location},course/upsert-list()\n{ex.Message}{ex.StackTrace}\n{json}", GroupNames.醍摩豆服務運維群組);
  539. return BadRequest();
  540. }
  541. }
  542. private async Task<StuList> upsertList(StuList stuList, string scope)
  543. {
  544. try
  545. {
  546. var client = _azureCosmos.GetCosmosClient();
  547. //todo 需要校验是否重复
  548. if (string.IsNullOrEmpty(stuList.no))
  549. {
  550. stuList.no = $"{Utils.CreatSaltString(6, "0123456789")}";
  551. //string table = $"{scope}" != "school" ? "Teacher" : "School";
  552. for (int i = 0; i < 10; i++)
  553. {
  554. var queryNo = $"SELECT c.no FROM c where c.no ='{stuList.no}'";
  555. List<string> noStus = new();
  556. await foreach (var item in client.GetContainer("TEAMModelOS", "School").GetItemQueryStreamIterator(queryText: queryNo,
  557. requestOptions: new QueryRequestOptions() { PartitionKey = new Azure.Cosmos.PartitionKey($"{stuList.code}") }))
  558. {
  559. using var jsonNo = await JsonDocument.ParseAsync(item.ContentStream);
  560. if (jsonNo.RootElement.TryGetProperty("_count", out JsonElement count) && count.GetUInt16() > 0)
  561. {
  562. var accounts = jsonNo.RootElement.GetProperty("Documents").EnumerateArray();
  563. while (accounts.MoveNext())
  564. {
  565. JsonElement account = accounts.Current;
  566. noStus.Add(account.GetProperty("no").GetString());
  567. }
  568. }
  569. }
  570. await foreach (var item in client.GetContainer("TEAMModelOS", "Teacher").GetItemQueryStreamIterator(queryText: queryNo,
  571. requestOptions: new QueryRequestOptions() { PartitionKey = new Azure.Cosmos.PartitionKey("StuList") }))
  572. {
  573. using var jsonNo = await JsonDocument.ParseAsync(item.ContentStream);
  574. if (jsonNo.RootElement.TryGetProperty("_count", out JsonElement count) && count.GetUInt16() > 0)
  575. {
  576. var accounts = jsonNo.RootElement.GetProperty("Documents").EnumerateArray();
  577. while (accounts.MoveNext())
  578. {
  579. JsonElement account = accounts.Current;
  580. noStus.Add(account.GetProperty("no").GetString());
  581. }
  582. }
  583. }
  584. if (noStus.Count == 0)
  585. {
  586. break;
  587. }
  588. else
  589. {
  590. if (i == 9)
  591. {
  592. string msg = $"OS,{_option.Location},school/course/upsert-list()\n 编号生成异常,重复生成次数超过10次";
  593. await _dingDing.SendBotMsg(msg, GroupNames.醍摩豆服務運維群組);
  594. throw new Exception(msg);
  595. }
  596. else
  597. {
  598. stuList.no = $"{Utils.CreatSaltString(6, "0123456789")}";
  599. }
  600. }
  601. }
  602. }
  603. stuList.code = stuList.pk + "-" + stuList.code.Replace("StuList-", "");
  604. if (scope.ToString().Equals("school", StringComparison.OrdinalIgnoreCase))
  605. {
  606. stuList.scope = "school";
  607. StuListChange change = new StuListChange()
  608. {
  609. listid = stuList.id,
  610. scope = $"{scope}",
  611. originCode = stuList.school,
  612. school = stuList.school,
  613. creatorId = stuList.creatorId
  614. };
  615. var query = $"SELECT distinct value(c) FROM c where c.id='{stuList.id}'";
  616. List<StuList> odlStus = new List<StuList>();
  617. await foreach (var item in client.GetContainer("TEAMModelOS", "School").GetItemQueryIterator<StuList>(queryText: query,
  618. requestOptions: new QueryRequestOptions() { PartitionKey = new Azure.Cosmos.PartitionKey($"StuList-{stuList.school}") }))
  619. {
  620. odlStus.Add(item);
  621. }
  622. if (odlStus.Count > 0)
  623. {
  624. if (stuList.students != null)
  625. {
  626. if (odlStus[0].students != null)
  627. {
  628. StuList oldStu = odlStus[0];
  629. foreach (var stu in stuList.students)
  630. {
  631. bool flag = false;
  632. //判断新增名单成员不在已经存在的名单
  633. foreach (var old in oldStu.students)
  634. {
  635. if (old.id == stu.id && old.code == stu.code)
  636. {
  637. flag = true;
  638. }
  639. }
  640. if (flag == false)
  641. {
  642. change.stujoin.Add(stu);
  643. }
  644. }
  645. }
  646. }
  647. if (stuList.tmids != null)
  648. {
  649. if (odlStus[0].tmids != null)
  650. {
  651. StuList oldStu = odlStus[0];
  652. foreach (var tmdid in stuList.tmids)
  653. {
  654. bool flag = false;
  655. //判断新增名单成员不在已经存在的名单
  656. foreach (var old in oldStu.tmids)
  657. {
  658. if (old == tmdid)
  659. {
  660. flag = true;
  661. }
  662. }
  663. if (flag == false)
  664. {
  665. change.tmdjoin.Add(tmdid);
  666. }
  667. }
  668. }
  669. }
  670. if (change.tmdjoin.Count != 0 || change.tmdhleave.Count != 0 || change.stujoin.Count != 0 || change.stuleave.Count != 0)
  671. {
  672. var messageChange = new ServiceBusMessage(change.ToJsonString());
  673. messageChange.ApplicationProperties.Add("name", "StuList");
  674. var ActiveTask = _configuration.GetValue<string>("Azure:ServiceBus:ActiveTask");
  675. await _serviceBus.GetServiceBusClient().SendMessageAsync(ActiveTask, messageChange);
  676. }
  677. }
  678. stuList = await _azureCosmos.GetCosmosClient().GetContainer("TEAMModelOS", "School").UpsertItemAsync(stuList, new PartitionKey($"StuList-{stuList.school}"));
  679. }
  680. else
  681. {
  682. stuList.scope = "private";
  683. if (stuList.students.IsNotEmpty())
  684. {
  685. stuList.school = stuList.students[0].code.Replace("Base-", "");
  686. }
  687. StuListChange change = new StuListChange()
  688. {
  689. listid = stuList.id,
  690. scope = $"{scope}",
  691. originCode = stuList.creatorId,
  692. school = stuList.school,
  693. creatorId = stuList.creatorId
  694. };
  695. var query = $"SELECT distinct value(c) FROM c where c.id='{stuList.id}'";
  696. List<StuList> odlStus = new List<StuList>();
  697. await foreach (var item in client.GetContainer("TEAMModelOS", "Teacher").GetItemQueryIterator<StuList>(queryText: query,
  698. requestOptions: new QueryRequestOptions() { PartitionKey = new Azure.Cosmos.PartitionKey($"StuList") }))
  699. {
  700. odlStus.Add(item);
  701. }
  702. if (odlStus.Count > 0)
  703. {
  704. if (stuList.students != null)
  705. {
  706. if (odlStus[0].students != null)
  707. {
  708. StuList oldStu = odlStus[0];
  709. foreach (var stu in stuList.students)
  710. {
  711. bool flag = false;
  712. //判断新增名单成员不在已经存在的名单
  713. foreach (var old in oldStu.students)
  714. {
  715. if (old.id == stu.id && old.code == stu.code)
  716. {
  717. flag = true;
  718. }
  719. }
  720. if (flag == false)
  721. {
  722. change.stujoin.Add(stu);
  723. }
  724. }
  725. }
  726. }
  727. if (stuList.tmids != null)
  728. {
  729. if (odlStus[0].tmids != null)
  730. {
  731. StuList oldStu = odlStus[0];
  732. foreach (var tmdid in stuList.tmids)
  733. {
  734. bool flag = false;
  735. //判断新增名单成员不在已经存在的名单
  736. foreach (var old in oldStu.tmids)
  737. {
  738. if (old == tmdid)
  739. {
  740. flag = true;
  741. }
  742. }
  743. if (flag == false)
  744. {
  745. change.tmdjoin.Add(tmdid);
  746. }
  747. }
  748. }
  749. else
  750. {
  751. }
  752. }
  753. if (change.tmdjoin.Count != 0 || change.tmdhleave.Count != 0 || change.stujoin.Count != 0 || change.stuleave.Count != 0)
  754. {
  755. var messageChange = new ServiceBusMessage(change.ToJsonString());
  756. messageChange.ApplicationProperties.Add("name", "StuList");
  757. var ActiveTask = _configuration.GetValue<string>("Azure:ServiceBus:ActiveTask");
  758. await _serviceBus.GetServiceBusClient().SendMessageAsync(ActiveTask, messageChange);
  759. }
  760. }
  761. stuList.code = "StuList";
  762. stuList = await _azureCosmos.GetCosmosClient().GetContainer("TEAMModelOS", "Teacher").UpsertItemAsync(stuList, new PartitionKey($"StuList"));
  763. }
  764. return stuList;
  765. }
  766. catch (Exception ex)
  767. {
  768. string msg = $"OS,{_option.Location},course/upsert-list()\n{ex.Message}{ex.StackTrace}\n{stuList.ToJsonString()}";
  769. await _dingDing.SendBotMsg(msg, GroupNames.醍摩豆服務運維群組);
  770. throw new Exception(msg, ex);
  771. }
  772. }
  773. //查询名单
  774. [ProducesDefaultResponseType]
  775. //[AuthToken(Roles = "Teacher")]
  776. [HttpPost("find-list")]
  777. public async Task<IActionResult> FindList(JsonElement requert)
  778. {
  779. try
  780. {
  781. if (!requert.TryGetProperty("code", out JsonElement code)) return BadRequest();
  782. if (!requert.TryGetProperty("scope", out JsonElement scope)) return BadRequest();
  783. var client = _azureCosmos.GetCosmosClient();
  784. List<object> stuList = new List<object>();
  785. //List<int> stuCount = new List<int>();
  786. var query = $"select c.id,c.name,c.students,c.tmids,c.periodId from c";
  787. if (scope.ToString().Equals("school", StringComparison.OrdinalIgnoreCase))
  788. {
  789. await foreach (var item in client.GetContainer("TEAMModelOS", "School").GetItemQueryStreamIterator(queryText: query, requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"StuList-{code}") }))
  790. {
  791. using var json = await JsonDocument.ParseAsync(item.ContentStream);
  792. if (json.RootElement.TryGetProperty("_count", out JsonElement count) && count.GetUInt16() > 0)
  793. {
  794. foreach (var obj in json.RootElement.GetProperty("Documents").EnumerateArray())
  795. {
  796. //List<Students> stu = obj.GetProperty("students").ToObject<List<Students>>();
  797. stuList.Add(obj.ToObject<object>());
  798. //stuList.Add(stu.Count);
  799. //stuCount.Add(stu.Count);
  800. }
  801. }
  802. }
  803. }
  804. else
  805. {
  806. await foreach (var item in client.GetContainer("TEAMModelOS", "Teacher").GetItemQueryStreamIterator(queryText: query, requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"StuList") }))
  807. {
  808. using var json = await JsonDocument.ParseAsync(item.ContentStream);
  809. if (json.RootElement.TryGetProperty("_count", out JsonElement count) && count.GetUInt16() > 0)
  810. {
  811. foreach (var obj in json.RootElement.GetProperty("Documents").EnumerateArray())
  812. {
  813. //List<Students> stu = obj.GetProperty("students").ToObject<List<Students>>();
  814. stuList.Add(obj.ToObject<object>());
  815. //stuList.Add(stu.Count);
  816. //stuCount.Add(stu.Count);
  817. }
  818. }
  819. }
  820. }
  821. return Ok(new { stuList });
  822. }
  823. catch (Exception ex)
  824. {
  825. await _dingDing.SendBotMsg($"OS,{_option.Location},course/find-list()\n{ex.Message}", GroupNames.醍摩豆服務運維群組);
  826. return BadRequest();
  827. }
  828. }
  829. //查询名单
  830. [ProducesDefaultResponseType]
  831. //[AuthToken(Roles = "Teacher")]
  832. [HttpPost("get-summary-list")]
  833. public async Task<IActionResult> getSummary(JsonElement requert)
  834. {
  835. try
  836. {
  837. if (!requert.TryGetProperty("code", out JsonElement code)) return BadRequest();
  838. if (!requert.TryGetProperty("scope", out JsonElement scope)) return BadRequest();
  839. if (!requert.TryGetProperty("ids", out JsonElement classId)) return BadRequest();
  840. var client = _azureCosmos.GetCosmosClient();
  841. List<object> stuList = new();
  842. //List<int> stuCount = new List<int>();
  843. List<string> ids = new();
  844. ids = classId.ToObject<List<string>>();
  845. //List<Students> stu = new();
  846. var query = $"select c.id,c.name,c.students,c.tmids,c.no,c.code,c.scope,c.school,c.creatorId from c where c.id in ({string.Join(",", ids.Select(o => $"'{o}'"))})";
  847. if (scope.ToString().Equals("school", StringComparison.OrdinalIgnoreCase))
  848. {
  849. await foreach (var item in client.GetContainer("TEAMModelOS", "School").GetItemQueryStreamIterator(queryText: query, requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"StuList-{code}") }))
  850. {
  851. using var json = await JsonDocument.ParseAsync(item.ContentStream);
  852. if (json.RootElement.TryGetProperty("_count", out JsonElement count) && count.GetUInt16() > 0)
  853. {
  854. foreach (var obj in json.RootElement.GetProperty("Documents").EnumerateArray())
  855. {
  856. //stu = obj.GetProperty("students").ToObject<List<Students>>();
  857. stuList.Add(obj.ToObject<object>());
  858. //stuList.Add(stu.Count);
  859. //stuCount.Add(stu.Count);
  860. }
  861. }
  862. }
  863. }
  864. else
  865. {
  866. await foreach (var item in client.GetContainer("TEAMModelOS", "Teacher").GetItemQueryStreamIterator(queryText: query, requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"StuList") }))
  867. {
  868. using var json = await JsonDocument.ParseAsync(item.ContentStream);
  869. if (json.RootElement.TryGetProperty("_count", out JsonElement count) && count.GetUInt16() > 0)
  870. {
  871. foreach (var obj in json.RootElement.GetProperty("Documents").EnumerateArray())
  872. {
  873. //stu = obj.GetProperty("students").ToObject<List<Students>>();
  874. stuList.Add(obj.ToObject<object>());
  875. //stuList.Add(stu.Count);
  876. //stuCount.Add(stu.Count);
  877. }
  878. }
  879. }
  880. }
  881. return Ok(new { stuList });
  882. }
  883. catch (Exception ex)
  884. {
  885. await _dingDing.SendBotMsg($"OS,{_option.Location},course/get-summary-list()\n{ex.Message}", GroupNames.醍摩豆服務運維群組);
  886. return BadRequest();
  887. }
  888. }
  889. //查询名单
  890. [ProducesDefaultResponseType]
  891. //[AuthToken(Roles = "Teacher")]
  892. [HttpPost("delete-list")]
  893. public async Task<IActionResult> deleteList(JsonElement requert)
  894. {
  895. try
  896. {
  897. if (!requert.TryGetProperty("code", out JsonElement code)) return BadRequest();
  898. if (!requert.TryGetProperty("scope", out JsonElement scope)) return BadRequest();
  899. if (!requert.TryGetProperty("id", out JsonElement id)) return BadRequest();
  900. var client = _azureCosmos.GetCosmosClient();
  901. //var query = $"select c.id,c.name,c.students,c.tmids from c where c.id in ({string.Join(",", ids.Select(o => $"'{o}'"))})";
  902. if (scope.ToString().Equals("school", StringComparison.OrdinalIgnoreCase))
  903. {
  904. /*List<string> classIds = new List<string>();
  905. var query = $"select c.id from c join A0 in c.schedule where A0.teacherId = '{id}'";
  906. await foreach (var item in client.GetContainer("TEAMModelOS", "Teacher").GetItemQueryStreamIterator(queryText: query, requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"Course-{id}") }))
  907. {
  908. using var json = await JsonDocument.ParseAsync(item.ContentStream);
  909. if (json.RootElement.TryGetProperty("_count", out JsonElement count) && count.GetUInt16() > 0)
  910. {
  911. var accounts = json.RootElement.GetProperty("Documents").EnumerateArray();
  912. while (accounts.MoveNext())
  913. {
  914. JsonElement account = accounts.Current;
  915. if (string.IsNullOrEmpty(account.GetProperty("id").GetString()))
  916. {
  917. continue;
  918. }
  919. classIds.Add(account.GetProperty("id").GetString());
  920. listClassInfo.Add((account.GetProperty("id").GetString(), account.GetProperty("scope").GetString()));
  921. }
  922. }
  923. }*/
  924. await client.GetContainer("TEAMModelOS", "School").DeleteItemStreamAsync(id.ToString(), new PartitionKey($"StuList-{code}"));
  925. }
  926. else
  927. {
  928. await client.GetContainer("TEAMModelOS", "Teacher").DeleteItemStreamAsync(id.ToString(), new PartitionKey($"StuLis"));
  929. /*await foreach (var item in client.GetContainer("TEAMModelOS", "Teacher").GetItemQueryStreamIterator(queryText: query, requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"StuList") }))
  930. {
  931. using var json = await JsonDocument.ParseAsync(item.ContentStream);
  932. if (json.RootElement.TryGetProperty("_count", out JsonElement count) && count.GetUInt16() > 0)
  933. {
  934. foreach (var obj in json.RootElement.GetProperty("Documents").EnumerateArray())
  935. {
  936. List<Students> stu = obj.GetProperty("students").ToObject<List<Students>>();
  937. stuList.Add(obj.ToObject<object>());
  938. //stuList.Add(stu.Count);
  939. //stuCount.Add(stu.Count);
  940. }
  941. }
  942. }*/
  943. }
  944. return Ok(new { id });
  945. }
  946. catch (Exception ex)
  947. {
  948. await _dingDing.SendBotMsg($"OS,{_option.Location},course/delete-list()\n{ex.Message}", GroupNames.醍摩豆服務運維群組);
  949. return BadRequest();
  950. }
  951. }
  952. /// <summary>
  953. /// 查询课程
  954. /// </summary>
  955. /// <param name="request"></param>
  956. /// <returns></returns>
  957. [ProducesDefaultResponseType]
  958. //[AuthToken(Roles = "Teacher")]
  959. [HttpPost("find")]
  960. public async Task<IActionResult> Find(JsonElement requert)
  961. {
  962. if (!requert.TryGetProperty("code", out JsonElement code)) return BadRequest();
  963. if (!requert.TryGetProperty("scope", out JsonElement scope)) return BadRequest();
  964. try
  965. {
  966. var client = _azureCosmos.GetCosmosClient();
  967. List<object> courses = new List<object>();
  968. /*string continuationToken = string.Empty;
  969. string token = default;
  970. //是否需要进行分页查询,默认不分页
  971. //bool iscontinuation = false;
  972. if (requert.TryGetProperty("token", out JsonElement token_1))
  973. {
  974. token = token_1.GetString();
  975. //iscontinuation = true;
  976. };
  977. //默认不指定返回大小
  978. int? topcout = null;
  979. if (requert.TryGetProperty("count", out JsonElement jcount))
  980. {
  981. if (!jcount.ValueKind.Equals(JsonValueKind.Undefined) && !jcount.ValueKind.Equals(JsonValueKind.Null) && jcount.TryGetInt32(out int data))
  982. {
  983. topcout = data;
  984. }
  985. }*/
  986. var query = $"select c.code,c.id,c.no,c.name,c.period,c.subject,c.scope from c";
  987. if (scope.ToString().Equals("school", StringComparison.OrdinalIgnoreCase))
  988. {
  989. await foreach (var item in client.GetContainer("TEAMModelOS", "School").GetItemQueryStreamIterator(queryText: query, requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"Course-{code.GetString()}") }))
  990. {
  991. //continuationToken = item.GetContinuationToken();
  992. using var json = await JsonDocument.ParseAsync(item.ContentStream);
  993. if (json.RootElement.TryGetProperty("_count", out JsonElement count) && count.GetUInt16() > 0)
  994. {
  995. foreach (var obj in json.RootElement.GetProperty("Documents").EnumerateArray())
  996. {
  997. courses.Add(obj.ToObject<object>());
  998. }
  999. }
  1000. //break;
  1001. }
  1002. }
  1003. else
  1004. {
  1005. await foreach (var item in client.GetContainer("TEAMModelOS", "Teacher").GetItemQueryStreamIterator(queryText: query, requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"Course-{code.GetString()}") }))
  1006. {
  1007. //continuationToken = item.GetContinuationToken();
  1008. using var json = await JsonDocument.ParseAsync(item.ContentStream);
  1009. if (json.RootElement.TryGetProperty("_count", out JsonElement count) && count.GetUInt16() > 0)
  1010. {
  1011. foreach (var obj in json.RootElement.GetProperty("Documents").EnumerateArray())
  1012. {
  1013. courses.Add(obj.ToObject<object>());
  1014. }
  1015. }
  1016. //break;
  1017. }
  1018. if (requert.TryGetProperty("schoolId", out JsonElement schoolId))
  1019. {
  1020. var querySchool = $"select distinct c.code,c.id,c.no,c.name,c.period,c.subject,c.scope from c join A0 in c.schedule where A0.teacherId = '{code}'";
  1021. await foreach (var item in client.GetContainer("TEAMModelOS", "School").GetItemQueryStreamIterator(queryText: querySchool, requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"Course-{schoolId.GetString()}") }))
  1022. {
  1023. //continuationToken = item.GetContinuationToken();
  1024. using var json = await JsonDocument.ParseAsync(item.ContentStream);
  1025. if (json.RootElement.TryGetProperty("_count", out JsonElement count) && count.GetUInt16() > 0)
  1026. {
  1027. foreach (var obj in json.RootElement.GetProperty("Documents").EnumerateArray())
  1028. {
  1029. courses.Add(obj.ToObject<object>());
  1030. }
  1031. }
  1032. //break;
  1033. }
  1034. };
  1035. }
  1036. return Ok(new { courses, courses.Count });
  1037. }
  1038. catch (Exception ex)
  1039. {
  1040. await _dingDing.SendBotMsg($"OS,{_option.Location},course/find()\n{ex.Message}", GroupNames.醍摩豆服務運維群組);
  1041. return BadRequest();
  1042. }
  1043. /* List<Course> data = new List<Course>();
  1044. if (StringHelper.getKeyCount(request) > 0) {
  1045. data = await _azureCosmos.FindByDict<Course>(request);
  1046. }
  1047. return builder.Data(data).Extend(new Dictionary<string, object> { { "count", data.Count } }).build();*/
  1048. }
  1049. /// <summary>
  1050. /// 查询课程
  1051. /// </summary>
  1052. /// <param name="request"></param>
  1053. /// <returns></returns>
  1054. [ProducesDefaultResponseType]
  1055. //[AuthToken(Roles = "Teacher")]
  1056. [HttpPost("find-all-by-teacher")]
  1057. public async Task<IActionResult> FindByTeacher(JsonElement requert)
  1058. {
  1059. if (!requert.TryGetProperty("code", out JsonElement code)) return BadRequest();
  1060. //if (!requert.TryGetProperty("tId", out JsonElement tId)) return BadRequest();
  1061. //if (!requert.TryGetProperty("scope", out JsonElement scope)) return BadRequest();
  1062. try
  1063. {
  1064. var client = _azureCosmos.GetCosmosClient();
  1065. List<object> courses = new List<object>();
  1066. List<(string id, string name, string scope)> teacherCourse = new();
  1067. List<(string id, string name, string scope)> tcCourse = new();
  1068. List<(string id, string name,string scope,List<(string id, string name, string type)> stuName)> ps = new();
  1069. var query = $"select c.id,c.name,c.scope from c";
  1070. await foreach (var item in client.GetContainer("TEAMModelOS", "Teacher").GetItemQueryStreamIterator(queryText: query, requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"Course-{code.GetString()}") }))
  1071. {
  1072. using var json = await JsonDocument.ParseAsync(item.ContentStream);
  1073. if (json.RootElement.TryGetProperty("_count", out JsonElement count) && count.GetUInt16() > 0)
  1074. {
  1075. var accounts = json.RootElement.GetProperty("Documents").EnumerateArray();
  1076. while (accounts.MoveNext())
  1077. {
  1078. JsonElement account = accounts.Current;
  1079. teacherCourse.Add((account.GetProperty("id").GetString(), account.GetProperty("name").GetString(),account.GetProperty("scope").GetString()));
  1080. }
  1081. }
  1082. }
  1083. foreach ((string s, string n,string sc) in teacherCourse)
  1084. {
  1085. List<(string id, string name,string type)> sName = new();
  1086. List<Schedule> schedules = new List<Schedule>();
  1087. var querySc = $"SELECT A0.room,A0.classId,A0.teacherId,A0.stulist,A0.time FROM c join A0 in c.schedule where c.id = '{s}'";
  1088. await foreach (var item in client.GetContainer("TEAMModelOS", "Teacher").GetItemQueryIterator<Schedule>(queryText: querySc, requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"Course-{code.GetString()}") }))
  1089. {
  1090. schedules.Add(item);
  1091. }
  1092. var queryInfo = $"select c.id ,c.name from c where c.id in ({string.Join(",", schedules.Select(o => $"'{o.stulist}'"))})";
  1093. await foreach (var item in client.GetContainer("TEAMModelOS", "Teacher").GetItemQueryStreamIterator(queryText: queryInfo, requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"StuList") }))
  1094. {
  1095. using var json = await JsonDocument.ParseAsync(item.ContentStream);
  1096. if (json.RootElement.TryGetProperty("_count", out JsonElement count) && count.GetUInt16() > 0)
  1097. {
  1098. var accounts = json.RootElement.GetProperty("Documents").EnumerateArray();
  1099. while (accounts.MoveNext())
  1100. {
  1101. JsonElement account = accounts.Current;
  1102. sName.Add((account.GetProperty("id").GetString(), account.GetProperty("name").GetString(),"stuList"));
  1103. }
  1104. }
  1105. }
  1106. ps.Add((s,n,sc, sName));
  1107. }
  1108. if (requert.TryGetProperty("schoolId", out JsonElement schoolId))
  1109. {
  1110. var querySchool = $"select distinct c.code,c.id,c.no,c.name,c.scope from c join A0 in c.schedule where A0.teacherId = '{code}'";
  1111. await foreach (var item in client.GetContainer("TEAMModelOS", "School").GetItemQueryStreamIterator(queryText: querySchool, requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"Course-{schoolId.GetString()}") }))
  1112. {
  1113. using var json = await JsonDocument.ParseAsync(item.ContentStream);
  1114. if (json.RootElement.TryGetProperty("_count", out JsonElement count) && count.GetUInt16() > 0)
  1115. {
  1116. var accounts = json.RootElement.GetProperty("Documents").EnumerateArray();
  1117. while (accounts.MoveNext())
  1118. {
  1119. JsonElement account = accounts.Current;
  1120. tcCourse.Add((account.GetProperty("id").GetString(), account.GetProperty("name").GetString(), account.GetProperty("scope").GetString()));
  1121. }
  1122. }
  1123. }
  1124. foreach ((string s, string n, string sc) in tcCourse)
  1125. {
  1126. List<Schedule> schedules = new List<Schedule>();
  1127. var querySc = $"SELECT A0.room,A0.classId,A0.teacherId,A0.stulist,A0.time FROM c join A0 in c.schedule where c.id = '{s}' and A0.teacherId = '{code}'";
  1128. await foreach (var item in client.GetContainer("TEAMModelOS", "School").GetItemQueryIterator<Schedule>(queryText: querySc, requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"Course-{schoolId.GetString()}") }))
  1129. {
  1130. schedules.Add(item);
  1131. }
  1132. List<(string id, string name,string type)> sName = new();
  1133. var queryInfo = $"select c.id ,c.name from c where c.id in ({string.Join(",", schedules.Select(o => $"'{o.stulist}'"))})";
  1134. await foreach (var item in client.GetContainer("TEAMModelOS", "School").GetItemQueryStreamIterator(queryText: queryInfo, requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"StuList-{schoolId.GetString()}") }))
  1135. {
  1136. using var json = await JsonDocument.ParseAsync(item.ContentStream);
  1137. if (json.RootElement.TryGetProperty("_count", out JsonElement count) && count.GetUInt16() > 0)
  1138. {
  1139. var accounts = json.RootElement.GetProperty("Documents").EnumerateArray();
  1140. while (accounts.MoveNext())
  1141. {
  1142. JsonElement account = accounts.Current;
  1143. sName.Add((account.GetProperty("id").GetString(), account.GetProperty("name").GetString(), "stuList"));
  1144. }
  1145. }
  1146. }
  1147. var queryClass = $"select c.id ,c.name from c where c.id in ({string.Join(",", schedules.Select(o => $"'{o.classId}'"))})";
  1148. await foreach (var item in client.GetContainer("TEAMModelOS", "School").GetItemQueryStreamIterator(queryText: queryClass, requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"Class-{schoolId.GetString()}") }))
  1149. {
  1150. using var json = await JsonDocument.ParseAsync(item.ContentStream);
  1151. if (json.RootElement.TryGetProperty("_count", out JsonElement count) && count.GetUInt16() > 0)
  1152. {
  1153. var accounts = json.RootElement.GetProperty("Documents").EnumerateArray();
  1154. while (accounts.MoveNext())
  1155. {
  1156. JsonElement account = accounts.Current;
  1157. sName.Add((account.GetProperty("id").GetString(), account.GetProperty("name").GetString(),"class"));
  1158. }
  1159. }
  1160. }
  1161. ps.Add((s,n, sc,sName));
  1162. }
  1163. }
  1164. var obj = ps.Select(p => new
  1165. {
  1166. p.id,
  1167. p.name,
  1168. p.scope,
  1169. classes = p.stuName.Select(s => new { s.id, s.name,s.type })
  1170. });
  1171. return Ok(new { obj });
  1172. }
  1173. catch (Exception ex)
  1174. {
  1175. await _dingDing.SendBotMsg($"OS,{_option.Location},course/find-all-by-teacher()\n{ex.Message}", GroupNames.醍摩豆服務運維群組);
  1176. return BadRequest();
  1177. }
  1178. }
  1179. /// <summary>
  1180. /// 查询课程详情
  1181. /// </summary>
  1182. /// <param name="request"></param>
  1183. /// <returns></returns>
  1184. [ProducesDefaultResponseType]
  1185. //[AuthToken(Roles = "Teacher")]
  1186. [HttpPost("find-summary")]
  1187. public async Task<IActionResult> FindSummary(JsonElement requert)
  1188. {
  1189. if (!requert.TryGetProperty("code", out JsonElement school_code)) return BadRequest();
  1190. if (!requert.TryGetProperty("scope", out JsonElement scope)) return BadRequest();
  1191. if (!requert.TryGetProperty("id", out JsonElement id)) return BadRequest();
  1192. try
  1193. {
  1194. var client = _azureCosmos.GetCosmosClient();
  1195. List<object> courses = new List<object>();
  1196. List<Course> courseList = new List<Course>();
  1197. var query = $"select value(c) from c where c.id = '{id}'";
  1198. //List<(string id, string code, string name)> listCourse = new List<(string id, string code, string name)>();
  1199. if (scope.ToString().Equals("school", StringComparison.OrdinalIgnoreCase))
  1200. {
  1201. await foreach (var item in client.GetContainer("TEAMModelOS", "School").GetItemQueryIterator<Course>(queryText: query, requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"Course-{school_code.GetString()}") }))
  1202. {
  1203. courseList.Add(item);
  1204. }
  1205. }
  1206. else
  1207. {
  1208. await foreach (var item in client.GetContainer("TEAMModelOS", "Teacher").GetItemQueryIterator<Course>(queryText: query, requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"Course-{school_code.GetString()}") }))
  1209. {
  1210. courseList.Add(item);
  1211. }
  1212. }
  1213. foreach (Course course in courseList)
  1214. {
  1215. dynamic courseExtobj = new ExpandoObject();
  1216. courseExtobj.id = course.id;
  1217. courseExtobj.name = course.name;
  1218. courseExtobj.id = course.id;
  1219. courseExtobj.subject = course.subject;
  1220. courseExtobj.period = course.period;
  1221. courseExtobj.scope = course.scope;
  1222. courseExtobj.no = course.no;
  1223. courseExtobj.code = course.code;
  1224. List<object> scheList = new List<object>();
  1225. foreach (Schedule schedule in course.schedule)
  1226. {
  1227. dynamic scheduleExtobj = new ExpandoObject();
  1228. scheduleExtobj.classId = schedule.classId;
  1229. scheduleExtobj.teacherId = schedule.teacherId;
  1230. if (!string.IsNullOrEmpty(schedule.teacherId))
  1231. {
  1232. var response = await client.GetContainer("TEAMModelOS", "Teacher").ReadItemStreamAsync(schedule.teacherId, new PartitionKey("Base"));
  1233. if (response.Status == 200)
  1234. {
  1235. using var json = await JsonDocument.ParseAsync(response.ContentStream);
  1236. Teacher teacher = json.ToObject<Teacher>();
  1237. scheduleExtobj.teacherName = teacher.name;
  1238. }
  1239. }
  1240. scheduleExtobj.stulist = schedule.stulist;
  1241. scheduleExtobj.time = schedule.time;
  1242. scheduleExtobj.notice = schedule.notice;
  1243. scheduleExtobj.room = schedule.room;
  1244. scheList.Add(scheduleExtobj);
  1245. }
  1246. courseExtobj.schedule = scheList;
  1247. courses.Add(courseExtobj);
  1248. }
  1249. return Ok(new { courses, courses.Count });
  1250. }
  1251. catch (Exception ex)
  1252. {
  1253. await _dingDing.SendBotMsg($"CoreAPI2,{_option.Location},course/find-summary()\n{ex.Message}", GroupNames.醍摩豆服務運維群組);
  1254. return BadRequest();
  1255. }
  1256. /* List<Course> data = new List<Course>();
  1257. if (StringHelper.getKeyCount(request) > 0) {
  1258. data = await _azureCosmos.FindByDict<Course>(request);
  1259. }
  1260. return builder.Data(data).Extend(new Dictionary<string, object> { { "count", data.Count } }).build();*/
  1261. }
  1262. /// <summary>
  1263. /// 删除课程
  1264. /// </summary>
  1265. /// <param name="request"></param>
  1266. /// <returns></returns>
  1267. [ProducesDefaultResponseType]
  1268. //[AuthToken(Roles = "Teacher")]
  1269. [HttpPost("delete")]
  1270. public async Task<IActionResult> Delete(JsonElement request)
  1271. {
  1272. try
  1273. {
  1274. if (!request.TryGetProperty("id", out JsonElement id)) return BadRequest();
  1275. if (!request.TryGetProperty("code", out JsonElement code)) return BadRequest();
  1276. if (!request.TryGetProperty("scope", out JsonElement scope)) return BadRequest();
  1277. //string school_code = code.ToString().Substring(typeof(Course).Name.Length + 1);
  1278. var client = _azureCosmos.GetCosmosClient();
  1279. if (scope.ToString().Equals("school"))
  1280. {
  1281. Course course = await client.GetContainer("TEAMModelOS", "School").ReadItemAsync<Course>(id.ToString(), new PartitionKey($"Course-{code}"));
  1282. CourseChange courseChange = new CourseChange { id = course.id, code = course.code, name = course.name, scope = course.scope, school = course.school, creatorId = course.creatorId };
  1283. courseChange.delClass = course.schedule.Select(x => x.classId).ToList();
  1284. courseChange.delList = course.schedule.Select(x => x.stulist).ToList();
  1285. var messageBlob = new ServiceBusMessage(courseChange.ToJsonString()); ;
  1286. messageBlob.ApplicationProperties.Add("name", "Course");
  1287. var ActiveTask = _configuration.GetValue<string>("Azure:ServiceBus:ActiveTask");
  1288. await _serviceBus.GetServiceBusClient().SendMessageAsync(ActiveTask, messageBlob);
  1289. await client.GetContainer("TEAMModelOS", "School").DeleteItemStreamAsync(id.ToString(), new PartitionKey($"Course-{code}"));
  1290. }
  1291. else
  1292. {
  1293. Course course = await client.GetContainer("TEAMModelOS", "Teacher").ReadItemAsync<Course>(id.ToString(), new PartitionKey($"Course-{code}"));
  1294. CourseChange courseChange = new CourseChange { id = course.id, code = course.code, name = course.name, scope = course.scope, school = course.school, creatorId = course.creatorId };
  1295. courseChange.delClass = course.schedule.Select(x => x.classId).ToList();
  1296. courseChange.delList = course.schedule.Select(x => x.stulist).ToList();
  1297. var messageBlob = new ServiceBusMessage(courseChange.ToJsonString()); ;
  1298. messageBlob.ApplicationProperties.Add("name", "Course");
  1299. var ActiveTask = _configuration.GetValue<string>("Azure:ServiceBus:ActiveTask");
  1300. await _serviceBus.GetServiceBusClient().SendMessageAsync(ActiveTask, messageBlob);
  1301. await client.GetContainer("TEAMModelOS", "Teacher").DeleteItemStreamAsync(id.ToString(), new PartitionKey($"Course-{code}"));
  1302. }
  1303. return Ok(new { id });
  1304. }
  1305. catch (Exception ex)
  1306. {
  1307. await _dingDing.SendBotMsg($"CN,{_option.Location},course/delete()\n{ex.Message}", GroupNames.醍摩豆服務運維群組);
  1308. return BadRequest();
  1309. }
  1310. }
  1311. /// <summary>
  1312. /// 删除课程
  1313. /// </summary>
  1314. /// <param name="request"></param>
  1315. /// <returns></returns>
  1316. [ProducesDefaultResponseType]
  1317. //[AuthToken(Roles = "Teacher")]
  1318. [HttpPost("delete-all")]
  1319. public async Task<IActionResult> DeleteAll(BatchOption request)
  1320. {
  1321. try
  1322. {
  1323. /* if (!request.TryGetProperty("id", out JsonElement id)) return BadRequest();
  1324. if (!request.TryGetProperty("code", out JsonElement code)) return BadRequest();*/
  1325. var client = _azureCosmos.GetCosmosClient();
  1326. if (request == null) return BadRequest();
  1327. string school_code = request.code;
  1328. if (request.scope.Equals("school", StringComparison.OrdinalIgnoreCase))
  1329. {
  1330. List<Response> res = await client.GetContainer("TEAMModelOS", "School").DeleteItemsStreamAsync(request.ids, $"Course-{school_code}");
  1331. }
  1332. else
  1333. {
  1334. List<Response> res = await client.GetContainer("TEAMModelOS", "Teacher").DeleteItemsStreamAsync(request.ids, $"Course-{school_code}");
  1335. }
  1336. return Ok(new { ids = request.ids });
  1337. }
  1338. catch (Exception ex)
  1339. {
  1340. await _dingDing.SendBotMsg($"CN,{_option.Location},course/delete()\n{ex.Message}", GroupNames.醍摩豆服務運維群組);
  1341. return BadRequest();
  1342. }
  1343. }
  1344. /// <summary>
  1345. /// 更新保存排课管理
  1346. /// </summary>
  1347. /// <param name="request"></param>
  1348. /// <returns></returns>
  1349. //[ProducesDefaultResponseType]
  1350. ////[AuthToken(Roles = "Teacher")]
  1351. //[HttpPost("upsert-management")]
  1352. //public async Task<IActionResult> upsertCourseManagement(CourseManagement requert)
  1353. //{
  1354. // try
  1355. // {
  1356. // CourseManagement course = new CourseManagement();
  1357. // //course = room.ToObject<CourseManagement>();
  1358. // var client = _azureCosmos.GetCosmosClient();
  1359. // string code = requert.code;
  1360. // requert.code = "CourseManagement-" + requert.code;
  1361. // /* if (requert.scope.Equals) {
  1362. // }*/
  1363. // var response = await client.GetContainer("TEAMModelOS", "School").ReadItemStreamAsync(requert.id, new PartitionKey($"CourseManagement-{code}"));
  1364. // if (response.Status == 200)
  1365. // {
  1366. // course = await _azureCosmos.GetCosmosClient().GetContainer("TEAMModelOS", "School").ReplaceItemAsync(requert, requert.id, new PartitionKey($"CourseManagement-{code}"));
  1367. // }
  1368. // else
  1369. // {
  1370. // course = await _azureCosmos.GetCosmosClient().GetContainer("TEAMModelOS", "School").CreateItemAsync(requert, new PartitionKey($"CourseManagement-{code}"));
  1371. // }
  1372. // return Ok(new { course });
  1373. // }
  1374. // catch (Exception ex)
  1375. // {
  1376. // await _dingDing.SendBotMsg($"CoreAPI2,{_option.Location},management/upsert()\n{ex.Message}", GroupNames.醍摩豆服務運維群組);
  1377. // return BadRequest();
  1378. // }
  1379. //}
  1380. /// <summary>
  1381. /// 查询排课管理
  1382. /// </summary>
  1383. /// <param name="request"></param>
  1384. /// <returns></returns>
  1385. //[ProducesDefaultResponseType]
  1386. ////[AuthToken(Roles = "Teacher")]
  1387. //[HttpPost("find-management")]
  1388. //public async Task<IActionResult> FindManagement(JsonElement requert)
  1389. //{
  1390. // //if (!requert.TryGetProperty("id", out JsonElement id)) return BadRequest();
  1391. // if (!requert.TryGetProperty("code", out JsonElement code)) return BadRequest();
  1392. // var client = _azureCosmos.GetCosmosClient();
  1393. // List<object> courses = new List<object>();
  1394. // StringBuilder sql = new StringBuilder();
  1395. // sql.Append("select c.code,c.id,c.name,c.courses,c.scope,c.teacher from c ");
  1396. // Dictionary<string, object> dict = new Dictionary<string, object>();
  1397. // var emobj = requert.EnumerateObject();
  1398. // while (emobj.MoveNext())
  1399. // {
  1400. // dict[emobj.Current.Name] = emobj.Current.Value;
  1401. // }
  1402. // //处理code
  1403. // if (dict.TryGetValue("code", out object _))
  1404. // {
  1405. // dict.Remove("code");
  1406. // }
  1407. // AzureCosmosQuery cosmosDbQuery = SQLHelper.GetSQL(dict, sql);
  1408. // await foreach (var item in client.GetContainer("TEAMModelOS", "School").GetItemQueryStreamIterator(queryDefinition: cosmosDbQuery.CosmosQueryDefinition, requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"CourseManagement-{code}") }))
  1409. // {
  1410. // using var json = await JsonDocument.ParseAsync(item.ContentStream);
  1411. // if (json.RootElement.TryGetProperty("_count", out JsonElement count) && count.GetUInt16() > 0)
  1412. // {
  1413. // foreach (var obj in json.RootElement.GetProperty("Documents").EnumerateArray())
  1414. // {
  1415. // courses.Add(obj.ToObject<object>());
  1416. // }
  1417. // }
  1418. // }
  1419. // return Ok(new { courses });
  1420. //}
  1421. //[ProducesDefaultResponseType]
  1422. ////[AuthToken(Roles = "Teacher")]
  1423. //[HttpPost("find-course")]
  1424. //public async Task<IActionResult> FindCourse(JsonElement requert)
  1425. //{
  1426. // if (!requert.TryGetProperty("id", out JsonElement id)) return BadRequest();
  1427. // if (!requert.TryGetProperty("code", out JsonElement code)) return BadRequest();
  1428. // var client = _azureCosmos.GetCosmosClient();
  1429. // List<object> courses = new List<object>();
  1430. // var query = $"select c.code,c.id,c.name,A0.course.id courseId,A0.course.name courseName ,A0.course.notice notice ,A1,c.scope,c.teacher from c join A0 in c.courses join A1 in A0.teachers where A1.id = '{id}' ";
  1431. // await foreach (var item in client.GetContainer("TEAMModelOS", "School").GetItemQueryStreamIterator(queryText: query, requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"CourseManagement-{code}") }))
  1432. // {
  1433. // using var json = await JsonDocument.ParseAsync(item.ContentStream);
  1434. // if (json.RootElement.TryGetProperty("_count", out JsonElement count) && count.GetUInt16() > 0)
  1435. // {
  1436. // foreach (var obj in json.RootElement.GetProperty("Documents").EnumerateArray())
  1437. // {
  1438. // courses.Add(obj.ToObject<object>());
  1439. // }
  1440. // }
  1441. // }
  1442. // return Ok(new { courses });
  1443. //}
  1444. [ProducesDefaultResponseType]
  1445. //[AuthToken(Roles = "Teacher")]
  1446. [HttpPost("find-course-by-room")]
  1447. public async Task<IActionResult> FindCourseByRoom(JsonElement requert)
  1448. {
  1449. if (!requert.TryGetProperty("id", out JsonElement id)) return BadRequest();
  1450. if (!requert.TryGetProperty("code", out JsonElement code)) return BadRequest();
  1451. if (!requert.TryGetProperty("scope", out JsonElement scope)) return BadRequest();
  1452. var client = _azureCosmos.GetCosmosClient();
  1453. HashSet<Course> courseList = new HashSet<Course>();
  1454. List<object> courses = new List<object>();
  1455. //var query = $"select c.code,c.id,c.name from c join A0 in c.schedule where A0.classId = '{id}'";
  1456. //此处存在不同老师在同一间教室上相同的课程
  1457. if (scope.ToString().Equals("school", StringComparison.OrdinalIgnoreCase))
  1458. {
  1459. var query = $"select distinct value(c) from c join A0 in c.schedule where A0.room = '{id}'";
  1460. await foreach (var item in client.GetContainer("TEAMModelOS", "School").GetItemQueryIterator<Course>(queryText: query, requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"Course-{code}") }))
  1461. {
  1462. courseList.Add(item);
  1463. }
  1464. }
  1465. else
  1466. {
  1467. var query = $"select distinct value(c) from c join A0 in c.schedule where A0.room = '{id}'";
  1468. await foreach (var item in client.GetContainer("TEAMModelOS", "Teacher").GetItemQueryIterator<Course>(queryText: query, requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"Course-{code}") }))
  1469. {
  1470. courseList.Add(item);
  1471. }
  1472. }
  1473. HashSet<string> teacherIds = new HashSet<string>();
  1474. foreach (Course course in courseList)
  1475. {
  1476. foreach (Schedule schedule in course.schedule)
  1477. {
  1478. teacherIds.Add(schedule.teacherId);
  1479. }
  1480. }
  1481. List<(string id, string name)> teachers = new List<(string id, string name)>();
  1482. if (teacherIds.Count > 0)
  1483. {
  1484. await foreach (var item in client.GetContainer("TEAMModelOS", "Teacher").GetItemQueryStreamIterator(
  1485. queryText: $"select c.id,c.name from c where c.id in ({ string.Join(",", teacherIds.Select(o => $"'{o}'"))})", requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey("Base") }))
  1486. {
  1487. using var json = await JsonDocument.ParseAsync(item.ContentStream);
  1488. if (json.RootElement.TryGetProperty("_count", out JsonElement count) && count.GetUInt16() > 0)
  1489. {
  1490. var accounts = json.RootElement.GetProperty("Documents").EnumerateArray();
  1491. while (accounts.MoveNext())
  1492. {
  1493. JsonElement account = accounts.Current;
  1494. teachers.Add((account.GetProperty("id").GetString(), account.GetProperty("name").GetString()));
  1495. }
  1496. }
  1497. }
  1498. }
  1499. foreach (Course course in courseList)
  1500. {
  1501. dynamic courseExtobj = new ExpandoObject();
  1502. courseExtobj.id = course.id;
  1503. courseExtobj.name = course.name;
  1504. courseExtobj.subject = course.subject;
  1505. courseExtobj.period = course.period;
  1506. courseExtobj.scope = course.scope;
  1507. courseExtobj.no = course.no;
  1508. courseExtobj.code = course.code;
  1509. courseExtobj.pk = course.pk;
  1510. List<object> scheList = new List<object>();
  1511. foreach (Schedule schedule in course.schedule)
  1512. {
  1513. dynamic scheduleExtobj = new ExpandoObject();
  1514. scheduleExtobj.classId = schedule.classId;
  1515. scheduleExtobj.teacherId = schedule.teacherId;
  1516. if (!string.IsNullOrEmpty(schedule.teacherId))
  1517. {
  1518. scheduleExtobj.teacherName = teachers.FirstOrDefault(c => c.id == schedule.teacherId).name;
  1519. }
  1520. scheduleExtobj.stulist = schedule.stulist;
  1521. scheduleExtobj.time = schedule.time;
  1522. scheduleExtobj.notice = schedule.notice;
  1523. scheduleExtobj.room = schedule.room;
  1524. scheList.Add(scheduleExtobj);
  1525. }
  1526. courseExtobj.schedule = scheList;
  1527. courses.Add(courseExtobj);
  1528. }
  1529. return Ok(new { courses });
  1530. }
  1531. //[ProducesDefaultResponseType]
  1532. ////[AuthToken(Roles = "Teacher")]
  1533. //[HttpPost("upsert-notice")]
  1534. //public async Task<IActionResult> upsertNotice(JsonElement requert)
  1535. //{
  1536. // if (!requert.TryGetProperty("courseId", out JsonElement courseId)) return BadRequest();
  1537. // if (!requert.TryGetProperty("code", out JsonElement code)) return BadRequest();
  1538. // if (!requert.TryGetProperty("id", out JsonElement id)) return BadRequest();
  1539. // if (!requert.TryGetProperty("notice", out JsonElement notice)) return BadRequest();
  1540. // if (!requert.TryGetProperty("A1", out JsonElement teacherInfo)) return BadRequest();
  1541. // Teachers teachers = teacherInfo.ToObject<Teachers>();
  1542. // var client = _azureCosmos.GetCosmosClient();
  1543. // List<CourseManagement> courseManagements = new List<CourseManagement>();
  1544. // StringBuilder sql = new StringBuilder();
  1545. // sql.Append("select value(c) from c");
  1546. // Dictionary<string, object> dict = new Dictionary<string, object>();
  1547. // //dict.Add("id", id);
  1548. // dict.Add("courses[*].course.id", courseId);
  1549. // dict.Add("courses[*].teachers[*].id", teachers.id);
  1550. // //dict.Add("id", classroom.id);
  1551. // AzureCosmosQuery cosmosDbQuery = SQLHelper.GetSQL(dict, sql);
  1552. // await foreach (var item in client.GetContainer("TEAMModelOS", "School").GetItemQueryStreamIterator(queryDefinition: cosmosDbQuery.CosmosQueryDefinition, requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"CourseManagement-{code}") }))
  1553. // {
  1554. // using var json = await JsonDocument.ParseAsync(item.ContentStream);
  1555. // if (json.RootElement.TryGetProperty("_count", out JsonElement count) && count.GetUInt16() > 0)
  1556. // {
  1557. // foreach (var obj in json.RootElement.GetProperty("Documents").EnumerateArray())
  1558. // {
  1559. // courseManagements.Add(obj.ToObject<CourseManagement>());
  1560. // }
  1561. // }
  1562. // }
  1563. // for (int i = 0; i < courseManagements.Count; i++)
  1564. // {
  1565. // for (int j = 0; j < courseManagements[i].courses.Count; j++)
  1566. // {
  1567. // if (courseManagements[i].courses[j].course.id.Equals(courseId.ToString()))
  1568. // {
  1569. // courseManagements[i].courses[j].course.notice = notice.ToString();
  1570. // await client.GetContainer("TEAMModelOS", "School").ReplaceItemAsync(courseManagements[i], courseManagements[i].id, new PartitionKey($"{courseManagements[i].code}"));
  1571. // break;
  1572. // }
  1573. // }
  1574. // }
  1575. // return Ok(new { id });
  1576. //}
  1577. [ProducesDefaultResponseType]
  1578. //[AuthToken(Roles = "Teacher")]
  1579. [HttpPost("upsert-teacher-course")]
  1580. public async Task<IActionResult> upsertCourse(JsonElement requert)
  1581. {
  1582. try
  1583. {
  1584. TeacherCourse course = new TeacherCourse();
  1585. if (!requert.TryGetProperty("course", out JsonElement room)) return BadRequest();
  1586. if (!requert.TryGetProperty("option", out JsonElement option)) return BadRequest();
  1587. course = room.ToObject<TeacherCourse>();
  1588. var client = _azureCosmos.GetCosmosClient();
  1589. course.pk = typeof(Course).Name;
  1590. string code = course.code;
  1591. course.code = typeof(Course).Name + "-" + course.code;
  1592. if (option.ToString().Equals("insert"))
  1593. {
  1594. var response = await client.GetContainer("TEAMModelOS", "Teacher").ReadItemStreamAsync(course.id, new PartitionKey($"Course-{code}"));
  1595. if (response.Status == 200)
  1596. {
  1597. return Ok(new { error = ResponseCode.DATA_EXIST, V = "课程编码已经存在!" });
  1598. }
  1599. else
  1600. {
  1601. course = await _azureCosmos.GetCosmosClient().GetContainer("TEAMModelOS", "Teacher").CreateItemAsync(course, new PartitionKey($"Course-{code}"));
  1602. }
  1603. }
  1604. else
  1605. {
  1606. if (course.classes.Count > 0)
  1607. {
  1608. //TODO 教师创建的个人的校本班级待处理冗余数据
  1609. foreach (ClassSimple classSimple in course.classes)
  1610. {
  1611. if (classSimple.scope.Equals("private", StringComparison.OrdinalIgnoreCase))
  1612. {
  1613. Class cla = new Class();
  1614. cla.id = classSimple.id;
  1615. cla.code = cla.pk + "-" + code;
  1616. cla.name = classSimple.name;
  1617. //cla.scope = classSimple.scope;
  1618. cla.teacher.id = classSimple.teacher.id;
  1619. cla.teacher.name = classSimple.teacher.name;
  1620. await _azureCosmos.GetCosmosClient().GetContainer("TEAMModelOS", "Teacher").UpsertItemAsync(cla, new PartitionKey($"Class-{code}"));
  1621. }
  1622. else
  1623. {
  1624. var response = await client.GetContainer("TEAMModelOS", "School").ReadItemStreamAsync(classSimple.id, new PartitionKey($"Class-{classSimple.code}"));
  1625. if (response.Status == 200)
  1626. {
  1627. using var json = await JsonDocument.ParseAsync(response.ContentStream);
  1628. Class cla = json.ToObject<Class>();
  1629. Class newCla = new Class();
  1630. newCla.id = cla.id;
  1631. newCla.code = cla.pk + "-" + code;
  1632. newCla.name = classSimple.name;
  1633. // newCla.scope = classSimple.scope;
  1634. /*foreach (StudentSimple student in cla.students)
  1635. {
  1636. StudentSimple studentSimple = new StudentSimple();
  1637. studentSimple.id = student.id;
  1638. studentSimple.name = student.name;
  1639. studentSimple.no = student.no;
  1640. newCla.students.Add(studentSimple);
  1641. }*/
  1642. newCla.teacher.id = classSimple.teacher.id;
  1643. newCla.teacher.name = classSimple.teacher.name;
  1644. await _azureCosmos.GetCosmosClient().GetContainer("TEAMModelOS", "Teacher").UpsertItemAsync(newCla, new PartitionKey($"Class-{code}"));
  1645. classSimple.code = code;
  1646. }
  1647. else
  1648. {
  1649. Class cla = await client.GetContainer("TEAMModelOS", "Teacher").ReadItemAsync<Class>(classSimple.id, new PartitionKey($"Class-{classSimple.code}"));
  1650. Class newCla = new Class();
  1651. newCla.id = cla.id;
  1652. newCla.code = cla.pk + "-" + code;
  1653. newCla.name = classSimple.name;
  1654. //newCla.scope = classSimple.scope;
  1655. //newCla.students = cla.students;
  1656. newCla.teacher.id = classSimple.teacher.id;
  1657. newCla.teacher.name = classSimple.teacher.name;
  1658. await _azureCosmos.GetCosmosClient().GetContainer("TEAMModelOS", "Teacher").UpsertItemAsync(newCla, new PartitionKey($"Class-{code}"));
  1659. }
  1660. }
  1661. }
  1662. }
  1663. course = await _azureCosmos.GetCosmosClient().GetContainer("TEAMModelOS", "Teacher").ReplaceItemAsync(course, course.id, new PartitionKey($"Course-{code}"));
  1664. }
  1665. return Ok(new { course });
  1666. }
  1667. catch (Exception ex)
  1668. {
  1669. await _dingDing.SendBotMsg($"CoreAPI2,{_option.Location},teacherCourse/upsert()\n{ex.Message}", GroupNames.醍摩豆服務運維群組);
  1670. return BadRequest();
  1671. }
  1672. }
  1673. [ProducesDefaultResponseType]
  1674. //[AuthToken(Roles = "Teacher")]
  1675. [HttpPost("find-teacher-course")]
  1676. public async Task<IActionResult> FindTeacherCourse(JsonElement requert)
  1677. {
  1678. if (!requert.TryGetProperty("id", out JsonElement id)) return BadRequest();
  1679. //if (!requert.TryGetProperty("code", out JsonElement code)) return BadRequest();
  1680. var client = _azureCosmos.GetCosmosClient();
  1681. List<object> courses = new List<object>();
  1682. var query = $"select c.code,c.id,c.name,c.subjectId,c.periodId,c.scope,c.notice,c.classes from c ";
  1683. await foreach (var item in client.GetContainer("TEAMModelOS", "Teacher").GetItemQueryStreamIterator(queryText: query, requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"Course-{id}") }))
  1684. {
  1685. using var json = await JsonDocument.ParseAsync(item.ContentStream);
  1686. if (json.RootElement.TryGetProperty("_count", out JsonElement count) && count.GetUInt16() > 0)
  1687. {
  1688. foreach (var obj in json.RootElement.GetProperty("Documents").EnumerateArray())
  1689. {
  1690. courses.Add(obj.ToObject<object>());
  1691. }
  1692. }
  1693. }
  1694. return Ok(new { courses });
  1695. }
  1696. /// <summary>
  1697. /// 查询执教助教的课程班级
  1698. /// </summary>
  1699. /// <param name="request"></param>
  1700. /// <returns></returns>
  1701. [ProducesDefaultResponseType]
  1702. //[AuthToken(Roles = "Teacher")]
  1703. [HttpPost("find-teach-class")]
  1704. public async Task<IActionResult> FindPlanClass(JsonElement request)
  1705. {
  1706. HashSet<string> data = new HashSet<string>();
  1707. if (!request.TryGetProperty("id", out JsonElement id)) return BadRequest();
  1708. if (!request.TryGetProperty("code", out JsonElement code)) return BadRequest();
  1709. var client = _azureCosmos.GetCosmosClient();
  1710. //List<object> courses = new List<object>();
  1711. List<string> classIds = new List<string>();
  1712. List<(string id, string scope)> listClassInfo = new List<(string id, string scope)>();
  1713. var query = $"select distinct c.scope,A0.stulist id from c join A0 in c.schedule where A0.teacherId = '{id}'";
  1714. await foreach (var item in client.GetContainer("TEAMModelOS", "Teacher").GetItemQueryStreamIterator(queryText: query, requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"Course-{id}") }))
  1715. {
  1716. using var json = await JsonDocument.ParseAsync(item.ContentStream);
  1717. if (json.RootElement.TryGetProperty("_count", out JsonElement count) && count.GetUInt16() > 0)
  1718. {
  1719. var accounts = json.RootElement.GetProperty("Documents").EnumerateArray();
  1720. while (accounts.MoveNext())
  1721. {
  1722. JsonElement account = accounts.Current;
  1723. if (string.IsNullOrEmpty(account.GetProperty("id").GetString()))
  1724. {
  1725. continue;
  1726. }
  1727. classIds.Add(account.GetProperty("id").GetString());
  1728. listClassInfo.Add((account.GetProperty("id").GetString(), account.GetProperty("scope").GetString()));
  1729. }
  1730. }
  1731. }
  1732. var querySchool = $"select distinct c.scope,A0.classId id from c join A0 in c.schedule where A0.teacherId = '{id}'";
  1733. await foreach (var item in client.GetContainer("TEAMModelOS", "Teacher").GetItemQueryStreamIterator(queryText: querySchool, requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"Course-{id}") }))
  1734. {
  1735. using var json = await JsonDocument.ParseAsync(item.ContentStream);
  1736. if (json.RootElement.TryGetProperty("_count", out JsonElement count) && count.GetUInt16() > 0)
  1737. {
  1738. var accounts = json.RootElement.GetProperty("Documents").EnumerateArray();
  1739. while (accounts.MoveNext())
  1740. {
  1741. JsonElement account = accounts.Current;
  1742. if (string.IsNullOrEmpty(account.GetProperty("id").GetString()))
  1743. {
  1744. continue;
  1745. }
  1746. classIds.Add(account.GetProperty("id").GetString());
  1747. listClassInfo.Add((account.GetProperty("id").GetString(), account.GetProperty("scope").GetString()));
  1748. }
  1749. }
  1750. }
  1751. //List<object> coursesBySchool = new List<object>();
  1752. //var queryBySchool = $"select distinct c.id,c.name,c.scope from c join A0 in c.courses join A1 in A0.teachers where A1.id = '{id}' ";
  1753. await foreach (var item in client.GetContainer("TEAMModelOS", "School").GetItemQueryStreamIterator(queryText: query, requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"Course-{code}") }))
  1754. {
  1755. using var json = await JsonDocument.ParseAsync(item.ContentStream);
  1756. if (json.RootElement.TryGetProperty("_count", out JsonElement count) && count.GetUInt16() > 0)
  1757. {
  1758. var accounts = json.RootElement.GetProperty("Documents").EnumerateArray();
  1759. while (accounts.MoveNext())
  1760. {
  1761. JsonElement account = accounts.Current;
  1762. if (string.IsNullOrEmpty(account.GetProperty("id").GetString()))
  1763. {
  1764. continue;
  1765. }
  1766. classIds.Add(account.GetProperty("id").GetString());
  1767. listClassInfo.Add((account.GetProperty("id").GetString(), account.GetProperty("scope").GetString()));
  1768. }
  1769. }
  1770. }
  1771. await foreach (var item in client.GetContainer("TEAMModelOS", "School").GetItemQueryStreamIterator(queryText: querySchool, requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"Course-{code}") }))
  1772. {
  1773. using var json = await JsonDocument.ParseAsync(item.ContentStream);
  1774. if (json.RootElement.TryGetProperty("_count", out JsonElement count) && count.GetUInt16() > 0)
  1775. {
  1776. var accounts = json.RootElement.GetProperty("Documents").EnumerateArray();
  1777. while (accounts.MoveNext())
  1778. {
  1779. JsonElement account = accounts.Current;
  1780. if (string.IsNullOrEmpty(account.GetProperty("id").GetString()))
  1781. {
  1782. continue;
  1783. }
  1784. classIds.Add(account.GetProperty("id").GetString());
  1785. listClassInfo.Add((account.GetProperty("id").GetString(), account.GetProperty("scope").GetString()));
  1786. }
  1787. }
  1788. }
  1789. List<(string id, string name)> listClassList = new List<(string id, string name)>();
  1790. if (classIds.Count > 0)
  1791. {
  1792. //List<(string id, string name)> listClassList = new List<(string id, string name)>();
  1793. await foreach (var item in client.GetContainer("TEAMModelOS", "School").GetItemQueryStreamIterator(
  1794. queryText: $"select c.id,c.name from c where c.id in ({string.Join(",", classIds.Select(o => $"'{o}'"))})", requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"Class-{code}") }))
  1795. {
  1796. using var json = await JsonDocument.ParseAsync(item.ContentStream);
  1797. if (json.RootElement.TryGetProperty("_count", out JsonElement count) && count.GetUInt16() > 0)
  1798. {
  1799. var accounts = json.RootElement.GetProperty("Documents").EnumerateArray();
  1800. while (accounts.MoveNext())
  1801. {
  1802. JsonElement account = accounts.Current;
  1803. listClassList.Add((account.GetProperty("id").GetString(), account.GetProperty("name").GetString()));
  1804. //stuIds.Add(account.GetProperty("id").GetString());
  1805. }
  1806. }
  1807. }
  1808. await foreach (var item in client.GetContainer("TEAMModelOS", "School").GetItemQueryStreamIterator(
  1809. queryText: $"select c.id,c.name from c where c.id in ({string.Join(",", classIds.Select(o => $"'{o}'"))})", requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"StuList-{code}") }))
  1810. {
  1811. using var json = await JsonDocument.ParseAsync(item.ContentStream);
  1812. if (json.RootElement.TryGetProperty("_count", out JsonElement count) && count.GetUInt16() > 0)
  1813. {
  1814. var accounts = json.RootElement.GetProperty("Documents").EnumerateArray();
  1815. while (accounts.MoveNext())
  1816. {
  1817. JsonElement account = accounts.Current;
  1818. listClassList.Add((account.GetProperty("id").GetString(), account.GetProperty("name").GetString()));
  1819. //stuIds.Add(account.GetProperty("id").GetString());
  1820. }
  1821. }
  1822. }
  1823. await foreach (var item in client.GetContainer("TEAMModelOS", "Teacher").GetItemQueryStreamIterator(
  1824. queryText: $"select c.id,c.name from c where c.id in ({string.Join(",", classIds.Select(o => $"'{o}'"))})", requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"StuList") }))
  1825. {
  1826. using var json = await JsonDocument.ParseAsync(item.ContentStream);
  1827. if (json.RootElement.TryGetProperty("_count", out JsonElement count) && count.GetUInt16() > 0)
  1828. {
  1829. var accounts = json.RootElement.GetProperty("Documents").EnumerateArray();
  1830. while (accounts.MoveNext())
  1831. {
  1832. JsonElement account = accounts.Current;
  1833. listClassList.Add((account.GetProperty("id").GetString(), account.GetProperty("name").GetString()));
  1834. //stuIds.Add(account.GetProperty("id").GetString());
  1835. }
  1836. }
  1837. }
  1838. }
  1839. var courses = listClassInfo.Select(o =>
  1840. new
  1841. {
  1842. o.id,
  1843. o.scope,
  1844. name = listClassList.FirstOrDefault(c => c.id == o.id).name,
  1845. }
  1846. );
  1847. //courses.Add(grpBalance);
  1848. //courses = courses.Distinct().ToList();
  1849. return Ok(new { courses });
  1850. }
  1851. public class Student
  1852. {
  1853. public string id { get; set; }
  1854. public string name { get; set; }
  1855. public string scope { get; set; }
  1856. }
  1857. public class ListDistinct : IEqualityComparer<Student>
  1858. {
  1859. public bool Equals(Student s1, Student s2)
  1860. {
  1861. return (s1.id == s2.id);
  1862. }
  1863. public int GetHashCode(Student s)
  1864. {
  1865. return s == null ? 0 : s.ToString().GetHashCode();
  1866. }
  1867. }
  1868. }
  1869. public class BatchOption
  1870. {
  1871. public List<string> ids { get; set; }
  1872. public string code { get; set; }
  1873. public string scope { get; set; }
  1874. }
  1875. }