StudentCommonController.cs 39 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774
  1. using Azure.Cosmos;
  2. using Microsoft.AspNetCore.Authorization;
  3. using Microsoft.AspNetCore.Http;
  4. using Microsoft.AspNetCore.Mvc;
  5. using Microsoft.Extensions.Options;
  6. using System;
  7. using System.Collections.Generic;
  8. using System.Linq;
  9. using System.Text;
  10. using System.Text.Json;
  11. using System.Threading.Tasks;
  12. using TEAMModelOS.Filter;
  13. using TEAMModelOS.Models;
  14. using TEAMModelOS.SDK;
  15. using TEAMModelOS.SDK.DI;
  16. using TEAMModelOS.SDK.Extension;
  17. using TEAMModelOS.SDK.Models;
  18. using TEAMModelOS.SDK.Models.Cosmos;
  19. using TEAMModelOS.SDK.Models.Cosmos.Common;
  20. using TEAMModelOS.SDK.Services;
  21. using static TEAMModelOS.SDK.StudentService;
  22. namespace TEAMModelOS.Controllers
  23. {
  24. [ProducesResponseType(StatusCodes.Status200OK)]
  25. [ProducesResponseType(StatusCodes.Status400BadRequest)]
  26. //
  27. [Route("student")]
  28. [ApiController]
  29. public class StudentCommonController : ControllerBase
  30. {
  31. private readonly AzureCosmosFactory _azureCosmos;
  32. private readonly AzureRedisFactory _azureRedis;
  33. private readonly DingDing _dingDing;
  34. private readonly Option _option;
  35. public StudentCommonController(AzureCosmosFactory azureCosmos, AzureRedisFactory azureRedis, DingDing dingDing, IOptionsSnapshot<Option> option)
  36. {
  37. _azureCosmos = azureCosmos;
  38. _azureRedis = azureRedis;
  39. _dingDing = dingDing;
  40. _option = option?.Value;
  41. }
  42. /// <summary>
  43. /// 查询活动所有活动类型的列表,学生端
  44. /// </summary>
  45. /// <param name="request">
  46. ///加入的班级信息 ?classes:[{"classid":"S-C-00001","scope":"school"},{"classid":"P-C-00004","scope":"private"}]
  47. ///活动类型 ?"type":"Vote"/"Exam"/"Homework"/"Learn"/"Survey"" // Vote投票 Survey问卷 Exam评测 Learn学习活动 Homework作业活动
  48. ///时间筛选范围开始时间 默认30天之前 ?"stime":1608274766154
  49. ///时间筛选范围结束时间 默认当前时间 ?"etime":1608274766666
  50. ///是否展示列表的 Tips ? "tips":true/false
  51. ///每页大小 ?"count":10/null/Undefined
  52. ///分页Token ?"continuationToken":Undefined/null/"[{\"token\":\"+RID:~omxMAP3ipcSEEwAAAAAAAA==#RT:2#TRC:20#ISV:2#IEO:65551#QCF:1#FPC:AYQTAAAAAAAAiRMAAAAAAAA=\",\"range\":{\"min\":\"\",\"max\":\"FF\"}}]"
  53. /// 当前状态 ?"progress":Undefined/null/"" 表示两种状态都要查询/ "going"/"finish" 表示查询进行中/ 或者已完成 学生端只能查询正在进行或已经结束 going 已发布|finish 已结束
  54. /// </param>
  55. ///
  56. /// <returns></returns>
  57. [ProducesDefaultResponseType]
  58. [HttpPost("student-activity")]
  59. [Authorize(Roles = "IES")]
  60. [AuthToken(Roles = "teacher,admin,student")]
  61. #if !DEBUG
  62. [Authorize(Roles = "IES")]
  63. #endif
  64. public async Task<IActionResult> StudentActivity(JsonElement request)
  65. {
  66. var (id, name, pic, school) = HttpContext.GetAuthTokenInfo();
  67. object _scope = null;
  68. List<string> groupListIds = new List<string>();
  69. List<string> subjects = new List<string>();
  70. if (request.TryGetProperty("groupListIds", out JsonElement _groupListIds)) {
  71. groupListIds= _groupListIds.ToObject<List<string>>();
  72. }
  73. if (request.TryGetProperty("subjects", out JsonElement _subjects))
  74. {
  75. subjects= _subjects.ToObject<List<string>>();
  76. }
  77. List<string> types = new List<string>();
  78. if (request.TryGetProperty("types", out JsonElement _types))
  79. {
  80. types= _types.ToObject<List<string>>();
  81. }
  82. HttpContext?.Items.TryGetValue("Scope", out _scope);
  83. List<StudentActivity> activities = await StudentService.FindActivity(request, id, $"{_scope}", groupListIds, subjects, school, types, _azureCosmos);
  84. return Ok(new { code =200, activities ,serverTime=DateTimeOffset.UtcNow.ToUnixTimeMilliseconds()});
  85. }
  86. /// <summary>
  87. /// 查询活动所有活动类型的列表,学生端
  88. /// </summary>
  89. /// <param name="request">
  90. ///加入的班级信息 ?classes:[{"classid":"S-C-00001","scope":"school"},{"classid":"P-C-00004","scope":"private"}]
  91. ///活动类型 ?"type":"Vote"/"Exam"/"Homework"/"Learn"/"Survey"" // Vote投票 Survey问卷 Exam评测 Learn学习活动 Homework作业活动
  92. ///时间筛选范围开始时间 默认30天之前 ?"stime":1608274766154
  93. ///时间筛选范围结束时间 默认当前时间 ?"etime":1608274766666
  94. ///是否展示列表的 Tips ? "tips":true/false
  95. ///每页大小 ?"count":10/null/Undefined
  96. ///分页Token ?"continuationToken":Undefined/null/"[{\"token\":\"+RID:~omxMAP3ipcSEEwAAAAAAAA==#RT:2#TRC:20#ISV:2#IEO:65551#QCF:1#FPC:AYQTAAAAAAAAiRMAAAAAAAA=\",\"range\":{\"min\":\"\",\"max\":\"FF\"}}]"
  97. /// 当前状态 ?"progress":Undefined/null/"" 表示两种状态都要查询/ "going"/"finish" 表示查询进行中/ 或者已完成 学生端只能查询正在进行或已经结束 going 已发布|finish 已结束
  98. /// </param>
  99. ///
  100. /// <returns></returns>
  101. [ProducesDefaultResponseType]
  102. [HttpPost("stu-activity")]
  103. [Authorize(Roles = "IES")]
  104. [AuthToken(Roles = "teacher,admin,student")]
  105. #if !DEBUG
  106. [Authorize(Roles = "IES")]
  107. #endif
  108. public async Task<IActionResult> StuActivity(JsonElement request)
  109. {
  110. var (id, name, pic, school) = HttpContext.GetAuthTokenInfo();
  111. (List<StuActivity> datas, string continuationToken) = await ActivityStudentService.FindActivity(request, id, school, _azureCosmos, _azureRedis);
  112. return Ok(new { datas, continuationToken });
  113. }
  114. [ProducesDefaultResponseType]
  115. [HttpPost("stu-score")]
  116. [AuthToken(Roles = "teacher,admin,student")]
  117. #if !DEBUG
  118. [Authorize(Roles = "IES")]
  119. #endif
  120. public async Task<IActionResult> StuScore(JsonElement request)
  121. {
  122. var (id, name, pic, school) = HttpContext.GetAuthTokenInfo();
  123. //if (!HttpContext.Items.TryGetValue("Scope", out object _scope)) return BadRequest();
  124. (List<StuActivity> datas, string continuationToken) = await ActivityStudentService.FindActivity(request, id, school, _azureCosmos, _azureRedis);
  125. List<(string id, string scope, string name, string source, List<string> cIds, int qamode, string createId, Dictionary<string, JsonElement> ext, long time, string owner)> eIds = new();
  126. //List<(string id, string scope, string name, List<string> cIds, string createId,long time)> wIds = new();
  127. foreach (var data in datas)
  128. {
  129. eIds.Add((data.id, data.scope, data.name, data.source, data.classIds, data.qamode, data.creatorId, data.ext, data.createTime, data.owner));
  130. }
  131. if (eIds.Count == 0)
  132. {
  133. return Ok(new { code = 404, msg = "暂无数据" });
  134. }
  135. var client = _azureCosmos.GetCosmosClient();
  136. List<(string eId, string sub, string cId, string cname, List<string> sIds, List<double> sum)> classResults = await getExamClassResult(eIds, client);
  137. List<(string id, double ps)> points = new();
  138. await foreach (var item in client.GetContainer(Constant.TEAMModelOS, "Common").GetItemQueryStreamIterator(
  139. queryText: $"select A0.point,c.id from c join A0 in c.papers where c.id in ({string.Join(",", eIds.Select(o => $"'{o.id}'"))})"))
  140. {
  141. using var json = await JsonDocument.ParseAsync(item.ContentStream);
  142. if (json.RootElement.TryGetProperty("_count", out JsonElement count) && count.GetUInt16() > 0)
  143. {
  144. var accounts = json.RootElement.GetProperty("Documents").EnumerateArray();
  145. while (accounts.MoveNext())
  146. {
  147. JsonElement account = accounts.Current;
  148. List<double> ps = new();
  149. if (account.TryGetProperty("point", out JsonElement point))
  150. {
  151. ps = point.ToObject<List<double>>();
  152. }
  153. points.Add((account.GetProperty("id").GetString(), ps.Sum()));
  154. }
  155. }
  156. }
  157. List<(string id, List<ExamSubject> sub)> subs = new();
  158. await foreach (var item in client.GetContainer(Constant.TEAMModelOS, "Common").GetItemQueryStreamIterator(
  159. queryText: $"select c.subjects,c.id from c where c.id in ({string.Join(",", eIds.Select(o => $"'{o.id}'"))})"))
  160. {
  161. using var json = await JsonDocument.ParseAsync(item.ContentStream);
  162. if (json.RootElement.TryGetProperty("_count", out JsonElement count) && count.GetUInt16() > 0)
  163. {
  164. var accounts = json.RootElement.GetProperty("Documents").EnumerateArray();
  165. while (accounts.MoveNext())
  166. {
  167. JsonElement account = accounts.Current;
  168. List<ExamSubject> sj = new();
  169. if (account.TryGetProperty("subjects", out JsonElement sn))
  170. {
  171. sj = sn.ToObject<List<ExamSubject>>();
  172. }
  173. subs.Add((account.GetProperty("id").GetString(), sj));
  174. }
  175. }
  176. }
  177. var pst = points.GroupBy(x => x.id).Select(p => new { key = p.Key, po = p.Select(o => o.ps) });
  178. var sut = subs.GroupBy(x => x.id).Select(p => new { key = p.Key, po = p.Select(o => o.sub) });
  179. var exam = eIds.Select(e => new
  180. {
  181. e.id,
  182. e.name,
  183. e.scope,
  184. e.source,
  185. e.createId,
  186. e.qamode,
  187. e.ext,
  188. e.time,
  189. e.owner,
  190. point = pst.Where(s => s.key == e.id).Select(c => c.po),
  191. subject = subs.Where(s => s.id == e.id).FirstOrDefault().sub,
  192. result = classResults.Where(c => c.eId == e.id).Select(s => new { s.sub, s.cId, s.cname, s.sum, s.sIds })
  193. });
  194. var result = exam.Where(e => e.result.Any()).Select(s => new
  195. {
  196. s.id,
  197. s.name,
  198. s.scope,
  199. s.source,
  200. s.createId,
  201. s.qamode,
  202. s.ext,
  203. s.time,
  204. s.owner,
  205. point = s.point.FirstOrDefault(),
  206. s.subject,
  207. s.result
  208. });
  209. return Ok(new { result, continuationToken });
  210. }
  211. [ProducesDefaultResponseType]
  212. [HttpPost("stu-hw-score")]
  213. [Authorize(Roles = "IES")]
  214. [AuthToken(Roles = "teacher,student,admin")]
  215. public async Task<IActionResult> StuHwScore(JsonElement request)
  216. {
  217. var (id, name, pic, school) = HttpContext.GetAuthTokenInfo();
  218. //if (!HttpContext.Items.TryGetValue("Scope", out object _scope)) return BadRequest();
  219. (List<StuActivity> datas, string continuationToken) = await ActivityStudentService.FindActivity(request, id, school, _azureCosmos, _azureRedis);
  220. //List<(string id, string scope, string name, string source, List<string> cIds, int qamode, string createId, Dictionary<string, JsonElement> ext, long time, string owner)> eIds = new();
  221. List<(string id, string scope, string name, List<string> cIds, string createId, long time)> wIds = new();
  222. foreach (var data in datas)
  223. {
  224. wIds.Add((data.id, data.scope, data.name, data.classIds, data.creatorId, data.createTime));
  225. }
  226. var client = _azureCosmos.GetCosmosClient();
  227. string partitionKey = String.Empty;
  228. if (request.TryGetProperty("userType", out JsonElement userType)) {
  229. if (userType.GetString().Equals("schoolid"))
  230. {
  231. partitionKey = $"HomeworkRecord-{school}-{id}";
  232. }
  233. else {
  234. if (request.TryGetProperty("userid", out JsonElement userid)) {
  235. id = userid.GetString();
  236. partitionKey = $"HomeworkRecord-{id}";
  237. }
  238. }
  239. }
  240. List<(string id, double score, List<HomeworkComment> comments, string comid)> work = new();
  241. //List<string> comid = new();
  242. if (wIds.Count > 0) {
  243. await foreach (var item in client.GetContainer(Constant.TEAMModelOS, "Student").GetItemQueryStreamIterator(
  244. queryText: $"select c.id,c.score,c.comments,c.comid from c where c.id in ({string.Join(",", wIds.Select(o => $"'{o.id}'"))})",
  245. requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey(partitionKey) }))
  246. {
  247. using var json = await JsonDocument.ParseAsync(item.ContentStream);
  248. if (json.RootElement.TryGetProperty("_count", out JsonElement count) && count.GetUInt16() > 0)
  249. {
  250. var accounts = json.RootElement.GetProperty("Documents").EnumerateArray();
  251. while (accounts.MoveNext())
  252. {
  253. JsonElement account = accounts.Current;
  254. double sc = 0;
  255. List<HomeworkComment> hc = new();
  256. if (account.TryGetProperty("score", out JsonElement score))
  257. {
  258. sc = score.GetDouble();
  259. if (sc == -1)
  260. {
  261. sc = 0;
  262. }
  263. }
  264. if (account.TryGetProperty("comments", out JsonElement comments))
  265. {
  266. hc = comments.ToObject<List<HomeworkComment>>();
  267. }
  268. //comid.Add(account.GetProperty("comid").GetString());
  269. work.Add((account.GetProperty("id").GetString(), sc, hc, account.GetProperty("comid").GetString()));
  270. }
  271. }
  272. }
  273. }
  274. List<(string id, List<DebateReply> comments)> debates = new();
  275. List<string> scomid = new();
  276. List<string> tcomid = new();
  277. foreach (var cc in wIds)
  278. {
  279. if (cc.scope.Equals("school"))
  280. {
  281. scomid.Add(work.Where(w => w.id == cc.id).FirstOrDefault().comid);
  282. }
  283. else
  284. {
  285. tcomid.Add(work.Where(w => w.id == cc.id).FirstOrDefault().comid);
  286. }
  287. }
  288. if (scomid.Count > 0)
  289. {
  290. await foreach (var item in client.GetContainer(Constant.TEAMModelOS, "School").GetItemQueryStreamIterator(
  291. queryText: $"select c.id,c.replies from c where c.id in ({string.Join(",", scomid.Select(o => $"'{o}'"))})",
  292. requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"Debate-{school}") }))
  293. {
  294. using var json = await JsonDocument.ParseAsync(item.ContentStream);
  295. if (json.RootElement.TryGetProperty("_count", out JsonElement count) && count.GetUInt16() > 0)
  296. {
  297. var accounts = json.RootElement.GetProperty("Documents").EnumerateArray();
  298. while (accounts.MoveNext())
  299. {
  300. JsonElement account = accounts.Current;
  301. List<DebateReply> debate = new();
  302. if (account.TryGetProperty("replies", out JsonElement replies))
  303. {
  304. debate = replies.ToObject<List<DebateReply>>();
  305. }
  306. debates.Add((account.GetProperty("id").GetString(), debate));
  307. }
  308. }
  309. }
  310. }
  311. if (tcomid.Count > 0)
  312. {
  313. await foreach (var item in client.GetContainer(Constant.TEAMModelOS, "Teacher").GetItemQueryStreamIterator(
  314. queryText: $"select c.id,c.replies from c where c.pk = 'Debate' and c.id in ({string.Join(",", tcomid.Select(o => $"'{o}'"))})"))
  315. {
  316. using var json = await JsonDocument.ParseAsync(item.ContentStream);
  317. if (json.RootElement.TryGetProperty("_count", out JsonElement count) && count.GetUInt16() > 0)
  318. {
  319. var accounts = json.RootElement.GetProperty("Documents").EnumerateArray();
  320. while (accounts.MoveNext())
  321. {
  322. JsonElement account = accounts.Current;
  323. List<DebateReply> debate = new();
  324. if (account.TryGetProperty("replies", out JsonElement replies))
  325. {
  326. debate = replies.ToObject<List<DebateReply>>();
  327. }
  328. debates.Add((account.GetProperty("id").GetString(), debate));
  329. }
  330. }
  331. }
  332. }
  333. var coment = work.Select(w => new
  334. {
  335. w.id,
  336. w.comid,
  337. reply = debates.Where(d => d.id == w.comid).FirstOrDefault().comments
  338. });
  339. var replay = coment.Where(c => c.reply != null);
  340. var works = wIds.Select(w => new
  341. {
  342. w.id,
  343. w.name,
  344. w.cIds,
  345. w.createId,
  346. w.time,
  347. score = work.Where(x => x.id == w.id).Select(s =>
  348. new
  349. {
  350. s.score,
  351. s.comments
  352. }),
  353. comment = replay.Any() ? replay.Where(c => c.id == w.id).Select(r => new { r.reply }) : null,
  354. });
  355. return Ok(new { works, continuationToken });
  356. }
  357. //获取学期信息
  358. [ProducesDefaultResponseType]
  359. [HttpPost("get-semesters")]
  360. [Authorize(Roles = "IES")]
  361. [AuthToken(Roles = "teacher,student,admin")]
  362. public async Task<IActionResult> getSemesters(JsonElement request) {
  363. if (!request.TryGetProperty("code", out JsonElement code)) return BadRequest();
  364. if (!request.TryGetProperty("periodId", out JsonElement periodId)) return BadRequest();
  365. try {
  366. var client = _azureCosmos.GetCosmosClient();
  367. List<Semester> semesters = new();
  368. await foreach (var item in client.GetContainer(Constant.TEAMModelOS, "School").GetItemQueryStreamIterator(
  369. queryText: $"select A0.semesters from c join A0 in c.period where A0.id = '{periodId}' and c.id = '{code}'",
  370. requestOptions: new QueryRequestOptions() {PartitionKey = new PartitionKey("Base") }))
  371. {
  372. using var json = await JsonDocument.ParseAsync(item.ContentStream);
  373. if (json.RootElement.TryGetProperty("_count", out JsonElement count) && count.GetUInt16() > 0)
  374. {
  375. foreach (var obj in json.RootElement.GetProperty("Documents").EnumerateArray())
  376. {
  377. semesters.Add(obj.ToObject<Semester>());
  378. }
  379. }
  380. }
  381. return Ok(semesters);
  382. } catch (Exception ex) {
  383. await _dingDing.SendBotMsg($"OS,{_option.Location},student/get-semesters()\n{ex.Message}\n{ex.StackTrace}", GroupNames.成都开发測試群組);
  384. }
  385. return Ok(new { code = 404, msg = "未找到相应内容"});
  386. }
  387. [ProducesDefaultResponseType]
  388. [HttpPost("stu-record-score")]
  389. [Authorize(Roles = "IES")]
  390. [AuthToken(Roles = "teacher,student,admin")]
  391. public async Task<IActionResult> StuRecordScore(JsonElement request)
  392. {
  393. if (!HttpContext.Items.TryGetValue("Scope", out object _scope)) return BadRequest();
  394. var (id, name, pic, school) = HttpContext.GetAuthTokenInfo();
  395. /*if (!request.TryGetProperty("stime", out JsonElement stime)) return BadRequest();
  396. if (!request.TryGetProperty("etime", out JsonElement etime)) return BadRequest();*/
  397. var client = _azureCosmos.GetCosmosClient();
  398. List<StudentLessonRecord> records = new();
  399. try
  400. {
  401. //是否需要进行分页查询,默认不分页
  402. string token = default;
  403. bool iscontinuation = false;
  404. if (request.TryGetProperty("token", out JsonElement token_1))
  405. {
  406. token = token_1.GetString();
  407. };
  408. //默认不指定返回大小
  409. int? topcout = null;
  410. if (request.TryGetProperty("count", out JsonElement jcount))
  411. {
  412. if (!jcount.ValueKind.Equals(JsonValueKind.Undefined) && !jcount.ValueKind.Equals(JsonValueKind.Null) && jcount.TryGetInt32(out int data))
  413. {
  414. topcout = data;
  415. }
  416. }
  417. if (topcout != null && topcout.Value > 0)
  418. {
  419. iscontinuation = true;
  420. }
  421. StringBuilder stringBuilder = null ;
  422. if ($"{_scope}".Equals(Constant.ScopeStudent)) {
  423. stringBuilder = new($"select A0.tmdid,A0.school,A0.scope,A0.lessonId,A0.courseId,A0.periodId,A0.subjectId,A0.gscore,A0.pscore,A0.tscore,A0.time from c join A0 in c.lessonRecords where c.stuid = '{id}'");
  424. } else {
  425. stringBuilder = new($"select A0.tmdid,A0.school,A0.scope,A0.lessonId,A0.courseId,A0.periodId,A0.subjectId,A0.gscore,A0.pscore,A0.tscore,A0.time from c join A0 in c.lessonRecords where c.tmdid = '{id}'");
  426. }
  427. if (request.TryGetProperty("stime", out JsonElement stime)) {
  428. stringBuilder.Append($" and A0.time >= {stime} ");
  429. }
  430. if (request.TryGetProperty("etime", out JsonElement etime))
  431. {
  432. stringBuilder.Append($" and A0.time <= {etime} ");
  433. }
  434. if (request.TryGetProperty("courseId", out JsonElement courseId))
  435. {
  436. stringBuilder.Append($" and A0.courseId = '{courseId}' ");
  437. }
  438. await foreach (var item in client.GetContainer(Constant.TEAMModelOS, "Student").GetItemQueryStreamIterator(
  439. queryText: stringBuilder.ToString(),
  440. continuationToken: token, requestOptions: new QueryRequestOptions() { MaxItemCount = topcout, PartitionKey = new PartitionKey("StudentScoreRecord") }))
  441. {
  442. using var json = await JsonDocument.ParseAsync(item.ContentStream);
  443. if (json.RootElement.TryGetProperty("_count", out JsonElement count) && count.GetUInt16() > 0)
  444. {
  445. foreach (var obj in json.RootElement.GetProperty("Documents").EnumerateArray())
  446. {
  447. records.Add(obj.ToObject<StudentLessonRecord>());
  448. }
  449. }
  450. if (iscontinuation)
  451. {
  452. token = item.GetContinuationToken();
  453. break;
  454. }
  455. }
  456. //List<string> ids = records.Select(x => x.lessonId).ToList();
  457. List<(string id, string name)> info = new();
  458. if (records.Count > 0) {
  459. List<string> slessons = records.Where(r => r.scope.Equals("school")).Select(o => o.lessonId).ToList();
  460. if (slessons.Count > 0) {
  461. await foreach (var item in client.GetContainer(Constant.TEAMModelOS, "School").GetItemQueryStreamIterator(
  462. queryText: $"select c.id,c.name from c where c.id in ({string.Join(",", slessons.Select(o => $"'{o}'"))})",
  463. requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"LessonRecord-{school}") }))
  464. {
  465. using var json = await JsonDocument.ParseAsync(item.ContentStream);
  466. if (json.RootElement.TryGetProperty("_count", out JsonElement count) && count.GetUInt16() > 0)
  467. {
  468. var accounts = json.RootElement.GetProperty("Documents").EnumerateArray();
  469. while (accounts.MoveNext())
  470. {
  471. JsonElement account = accounts.Current;
  472. info.Add((account.GetProperty("id").GetString(), account.GetProperty("name").GetString()));
  473. }
  474. }
  475. }
  476. }
  477. List<string> plessons = records.Where(r => r.scope.Equals("private")).Select(o => o.lessonId).ToList();
  478. if (plessons.Count > 0) {
  479. await foreach (var item in client.GetContainer(Constant.TEAMModelOS, "Teacher").GetItemQueryStreamIterator(
  480. queryText: $"select c.id,c.name from c where c.id in ({string.Join(",", plessons.Select(o => $"'{o}'"))})",
  481. requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"LessonRecord") }))
  482. {
  483. using var json = await JsonDocument.ParseAsync(item.ContentStream);
  484. if (json.RootElement.TryGetProperty("_count", out JsonElement count) && count.GetUInt16() > 0)
  485. {
  486. var accounts = json.RootElement.GetProperty("Documents").EnumerateArray();
  487. while (accounts.MoveNext())
  488. {
  489. JsonElement account = accounts.Current;
  490. info.Add((account.GetProperty("id").GetString(), account.GetProperty("name").GetString()));
  491. }
  492. }
  493. }
  494. }
  495. }
  496. var score = records.Select(x => new
  497. {
  498. x.tmdid,
  499. x.school,
  500. x.scope,
  501. x.lessonId,
  502. lessonName = info.Count > 0 ? info.Where(c => c.id.Equals(x.lessonId)).FirstOrDefault().name : "",
  503. x.courseId,
  504. x.subjectId,
  505. x.gscore,
  506. x.pscore,
  507. x.tscore,
  508. x.time
  509. }).OrderByDescending(c => c.time);
  510. return Ok(new { score });
  511. }
  512. catch (Exception e)
  513. {
  514. return Ok(new { code = 404, msg = e.StackTrace });
  515. }
  516. }
  517. private async Task<List<(string eId, string sub, string cId, string cname, List<string> sIds, List<double> sum)>> getExamClassResult(List<(string id, string scope, string name, string source, List<string> cIds, int qamode, string createId, Dictionary<string, JsonElement> ext, long time, string owner)> eIds, CosmosClient client)
  518. {
  519. List<(string eId, string sub, string cId, string cname, List<string> sIds, List<double> sum)> classResults = new();
  520. await foreach (var item in client.GetContainer(Constant.TEAMModelOS, "Common").GetItemQueryStreamIterator(
  521. queryText: $"select c.examId as eId,c.info.id as cId,c.info.name as cName,c.studentIds,c.sum,c.subjectId from c where c.pk = 'ExamClassResult' and c.examId in ({string.Join(",", eIds.Select(o => $"'{o.id}'"))})"))
  522. {
  523. using var json = await JsonDocument.ParseAsync(item.ContentStream);
  524. if (json.RootElement.TryGetProperty("_count", out JsonElement count) && count.GetUInt16() > 0)
  525. {
  526. var accounts = json.RootElement.GetProperty("Documents").EnumerateArray();
  527. while (accounts.MoveNext())
  528. {
  529. JsonElement account = accounts.Current;
  530. List<string> sIds = new();
  531. List<double> sums = new();
  532. string sub = string.Empty;
  533. string cid = string.Empty;
  534. string cname = string.Empty;
  535. if (account.TryGetProperty("studentIds", out JsonElement stu))
  536. {
  537. sIds = stu.ToObject<List<string>>();
  538. }
  539. if (account.TryGetProperty("sum", out JsonElement sum))
  540. {
  541. sums = sum.ToObject<List<double>>();
  542. }
  543. if (account.TryGetProperty("subjectId", out JsonElement subject))
  544. {
  545. sub = subject.GetString();
  546. }
  547. if (account.TryGetProperty("cId", out JsonElement cc))
  548. {
  549. cid = cc.GetString();
  550. }
  551. if (account.TryGetProperty("cName", out JsonElement cn))
  552. {
  553. cname = cn.GetString();
  554. }
  555. classResults.Add((account.GetProperty("eId").GetString(), sub, cid, cname, sIds, sums));
  556. }
  557. }
  558. }
  559. return classResults;
  560. }
  561. /// <summary>
  562. /// 查询活动所有活动类型的列表,学生端
  563. /// </summary>
  564. /// <param name="request">
  565. /// userid
  566. /// school
  567. /// </param>
  568. ///
  569. /// <returns></returns>
  570. [ProducesDefaultResponseType]
  571. [HttpPost("stu-course")]
  572. #if !DEBUG
  573. [Authorize(Roles = "IES")]
  574. #endif
  575. [AuthToken(Roles = "student")]
  576. public async Task<IActionResult> StuCourse(JsonElement request)
  577. {
  578. var (id, name, pic, school) = HttpContext.GetAuthTokenInfo();
  579. if (string.IsNullOrWhiteSpace(id))
  580. {
  581. if (request.TryGetProperty("userid", out JsonElement userid))
  582. {
  583. if (!userid.ValueKind.Equals(JsonValueKind.Undefined) && !userid.ValueKind.Equals(JsonValueKind.Null) && userid.ValueKind.Equals(JsonValueKind.String))
  584. {
  585. id = userid.GetString();
  586. }
  587. }
  588. }
  589. if (string.IsNullOrWhiteSpace(school))
  590. {
  591. if (request.TryGetProperty("school", out JsonElement schooljson))
  592. {
  593. if (!schooljson.ValueKind.Equals(JsonValueKind.Undefined) && !schooljson.ValueKind.Equals(JsonValueKind.Null) && schooljson.ValueKind.Equals(JsonValueKind.String))
  594. {
  595. school = schooljson.GetString();
  596. }
  597. }
  598. }
  599. /// tmdid, schoolid
  600. var userType = "tmdid";
  601. if (request.TryGetProperty("userType", out JsonElement usertype))
  602. {
  603. if (!usertype.ValueKind.Equals(JsonValueKind.Undefined) && !usertype.ValueKind.Equals(JsonValueKind.Null) && usertype.ValueKind.Equals(JsonValueKind.String))
  604. {
  605. userType = usertype.GetString();
  606. }
  607. }
  608. string containerId = "";
  609. string PartitionKey = "";
  610. if (!string.IsNullOrWhiteSpace(school) && userType.Equals("schoolid"))
  611. {
  612. containerId = "Student";
  613. PartitionKey = $"StuCourse-{school}-{id}";
  614. }
  615. else
  616. {
  617. containerId = "Student";
  618. PartitionKey = $"StuCourse-{id}";
  619. }
  620. List<StuCourse> stus = new List<StuCourse>();
  621. List<StuCourseDto> sc = new List<StuCourseDto>();
  622. await foreach (var item in _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, containerId).GetItemQueryIterator<StuCourse>(queryText: $"select value(c) from c ",
  623. requestOptions: new QueryRequestOptions() { PartitionKey = new Azure.Cosmos.PartitionKey(PartitionKey) }))
  624. {
  625. stus.Add(item);
  626. }
  627. foreach (var cos in stus)
  628. {
  629. if (cos.scope.Equals("school"))
  630. {
  631. Course course = new();
  632. try
  633. {
  634. course = await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, "School").ReadItemAsync<Course>(cos.id, new Azure.Cosmos.PartitionKey(cos.scode));
  635. }
  636. catch (CosmosException ex) { course = null; }
  637. sc.Add(new StuCourseDto { course = course, stuCourse = cos });
  638. }
  639. else
  640. {
  641. Course course = new();
  642. try
  643. {
  644. course = await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, "Teacher").ReadItemAsync<Course>(cos.id, new Azure.Cosmos.PartitionKey(cos.scode));
  645. var list = course.schedule.Where(x => string.IsNullOrWhiteSpace(x.stulist)).Select(x => x.stulist);
  646. }
  647. //需要处理 当前这个老师已经不在相关名单内。
  648. catch (CosmosException ex) { course = null; }
  649. sc.Add(new StuCourseDto { course = course, stuCourse = cos });
  650. }
  651. }
  652. //获取老师详细信息
  653. HashSet<string> info = new HashSet<string>();
  654. HashSet<string> room = new HashSet<string>();
  655. foreach (StuCourseDto dto in sc)
  656. {
  657. if (dto.course != null)
  658. {
  659. if (dto.course.schedule.Count > 0)
  660. {
  661. foreach (Schedule schedule in dto.course.schedule)
  662. {
  663. if (!string.IsNullOrEmpty(schedule.teacherId))
  664. {
  665. info.Add(schedule.teacherId);
  666. }
  667. if (!string.IsNullOrEmpty(schedule.room))
  668. {
  669. room.Add(schedule.room);
  670. }
  671. }
  672. }
  673. }
  674. }
  675. //处理教师基础信息
  676. List<(string id, string name)> teachers = new();
  677. if (info.Count > 0)
  678. {
  679. await foreach (var item in _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, "Teacher").GetItemQueryStreamIterator(
  680. queryText: $"select c.id,c.name from c where c.id in ({string.Join(",", info.Select(o => $"'{o}'"))})", requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey("Base") }))
  681. {
  682. using var json = await JsonDocument.ParseAsync(item.ContentStream);
  683. if (json.RootElement.TryGetProperty("_count", out JsonElement count) && count.GetUInt16() > 0)
  684. {
  685. var accounts = json.RootElement.GetProperty("Documents").EnumerateArray();
  686. while (accounts.MoveNext())
  687. {
  688. JsonElement account = accounts.Current;
  689. teachers.Add((account.GetProperty("id").GetString(), account.GetProperty("name").GetString()));
  690. }
  691. }
  692. }
  693. }
  694. //处理教室基础信息
  695. List<(string id, string name)> rooms = new();
  696. if (room.Count > 0)
  697. {
  698. await foreach (var item in _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, "School").GetItemQueryStreamIterator(
  699. queryText: $"select c.id,c.name from c where c.id in ({string.Join(",", room.Select(o => $"'{o}'"))})", requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"Room-{school}") }))
  700. {
  701. using var json = await JsonDocument.ParseAsync(item.ContentStream);
  702. if (json.RootElement.TryGetProperty("_count", out JsonElement count) && count.GetUInt16() > 0)
  703. {
  704. var accounts = json.RootElement.GetProperty("Documents").EnumerateArray();
  705. while (accounts.MoveNext())
  706. {
  707. JsonElement account = accounts.Current;
  708. rooms.Add((account.GetProperty("id").GetString(), account.GetProperty("name").GetString()));
  709. }
  710. }
  711. }
  712. }
  713. var courses = sc.Select(s => new
  714. {
  715. course = s.course != null ? new
  716. {
  717. id = s.course.id,
  718. name = s.course.name,
  719. code = s.course.code,
  720. creatorId = s.course.creatorId,
  721. no = s.course.no,
  722. period = s.course.period,
  723. desc = s.course.desc,
  724. school = s.course.school,
  725. scope = s.course.scope,
  726. pk = s.course.pk,
  727. subject = s.course.subject,
  728. schedule = s.course.schedule.Select(c => new
  729. {
  730. room = c.room,
  731. roomName = rooms.FirstOrDefault(t => t.id == c.room).name,
  732. classId = c.classId,
  733. teacherId = c.teacherId,
  734. teacherName = teachers.FirstOrDefault(t => t.id == c.teacherId).name,
  735. time = c.time,
  736. stulist = c.stulist
  737. })
  738. } : null,
  739. s.stuCourse
  740. });
  741. return Ok(new { courses });
  742. }
  743. }
  744. public class StuCourseDto
  745. {
  746. public StuCourse stuCourse { get; set; }
  747. public Course course { get; set; }
  748. }
  749. }