AreaController.cs 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450
  1. using Microsoft.Azure.Cosmos;
  2. using Microsoft.AspNetCore.Authorization;
  3. using Microsoft.AspNetCore.Http;
  4. using Microsoft.AspNetCore.Mvc;
  5. using Microsoft.Extensions.Options;
  6. using StackExchange.Redis;
  7. using System;
  8. using System.Collections.Generic;
  9. using System.Linq;
  10. using System.Text;
  11. using System.Text.Json;
  12. using System.Threading.Tasks;
  13. using TEAMModelOS.Filter;
  14. using TEAMModelOS.Models;
  15. using TEAMModelOS.SDK.Context.Constant;
  16. using TEAMModelOS.SDK.DI;
  17. using TEAMModelOS.SDK.Extension;
  18. using TEAMModelOS.SDK.Models;
  19. using TEAMModelOS.SDK.Models.Cosmos.BI;
  20. using TEAMModelOS.SDK.Models.Cosmos.BI.BISchool;
  21. using TEAMModelOS.SDK.Models.Service.BI;
  22. using TEAMModelOS.SDK.Models.Service.BIStatsWay;
  23. namespace TEAMModelOS.Controllers.Research
  24. {
  25. [ProducesResponseType(StatusCodes.Status200OK)]
  26. [ProducesResponseType(StatusCodes.Status400BadRequest)]
  27. [Route("area")]
  28. [ApiController]
  29. public class AreaController : ControllerBase
  30. {
  31. private readonly AzureCosmosFactory _azureCosmos;
  32. private readonly AzureRedisFactory _azureRedis;
  33. private readonly SnowflakeId _snowflakeId;
  34. private readonly DingDing _dingDing;
  35. private readonly Option _option;
  36. public AreaController(AzureCosmosFactory azureCosmos, AzureRedisFactory azureRedis, SnowflakeId snowflakeId, DingDing dingDing, IOptionsSnapshot<Option> option)
  37. {
  38. _azureCosmos = azureCosmos;
  39. _azureRedis = azureRedis;
  40. _snowflakeId = snowflakeId;
  41. _dingDing = dingDing;
  42. _option = option?.Value;
  43. } /*
  44. {"areaId":"册别id:0baf00db-0768-4b62-a8f7-280f6bcebf71","scope":"school","abilityCode":"册别分区键"}
  45. */
  46. /// <summary>
  47. /// 查找能力点
  48. /// </summary>
  49. /// <param name="request"></param>
  50. /// <returns></returns>
  51. [ProducesDefaultResponseType]
  52. [HttpPost("find-all")]
  53. [Authorize(Roles = "IES")]
  54. [AuthToken(Roles = "teacher,student,admin,area")]
  55. public async Task<IActionResult> FindAll(JsonElement request)
  56. {
  57. var client = _azureCosmos.GetCosmosClient();
  58. List<Area> areas = new List<Area>();
  59. await foreach (var item in client.GetContainer(Constant.TEAMModelOS, "Normal").GetItemQueryIteratorSql<Area>(queryText: "SELECT value(c) FROM c", requestOptions: new QueryRequestOptions { PartitionKey = new PartitionKey("Base-Area") }))
  60. {
  61. areas.Add(item);
  62. }
  63. return Ok(new { areas });
  64. }
  65. /// <summary>
  66. /// 区级统计接口
  67. /// </summary>
  68. /// <param name="jsonElement"></param>
  69. /// <returns></returns>
  70. [ProducesDefaultResponseType]
  71. [HttpPost("get-areastats")]
  72. #if !DEBUG
  73. [Authorize(Roles = "IES")]
  74. #endif
  75. [AuthToken(Roles = "area")]
  76. public async Task<IActionResult> GetAreaStats(JsonElement jsonElement)
  77. {
  78. try
  79. {
  80. if (!jsonElement.TryGetProperty("areaId", out JsonElement areaId)) return BadRequest();
  81. var cosmosClient = _azureCosmos.GetCosmosClient();
  82. var redisClinet = _azureRedis.GetRedisClient(8);
  83. DateTimeOffset dateTime = DateTimeOffset.UtcNow;
  84. Area area = null;
  85. AreaStats areaScStats = new();
  86. List<string> scIds = new();
  87. List<BISchoolInfo> schoolInfos = new();
  88. List<ScStats> scStatss = new();
  89. List<StatsInfo> statsInfos = new();
  90. long useSize = 0;
  91. Dictionary<string, double?> typeStics = new(); //所有类型
  92. var (weekS, weekE) = TimeHelper.GetStartOrEnd(dateTime, "week"); //计算本周开始/结束时间
  93. var (mthS, mthE) = TimeHelper.GetStartOrEnd(dateTime, "month"); //本月开始/结束时间
  94. await foreach (var item in cosmosClient.GetContainer(Constant.TEAMModelOS, "School").GetItemQueryIteratorSql<BISchoolInfo>(queryText: $"select c.id,c.name,c.picture,c.areaId,c.areaName,c.size,c.scale,c.assists,c.sales,c.createDate,c.serial,c.service,c.hard from c where c.areaId='{areaId}'", requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey("BIRel") }))
  95. {
  96. schoolInfos.Add(item);
  97. }
  98. if (schoolInfos.Count > 0)
  99. {
  100. scIds = schoolInfos.Select(s => s.id).ToList();
  101. }
  102. StringBuilder statsSql = new($"select value(c) from c where c.year={dateTime.Year}");
  103. if (scIds.Count > 0)
  104. {
  105. statsSql.Append($" and {BICommonWay.ManyScSql("c.id", scIds, $"{dateTime.Year}-")}");
  106. await foreach (var item in cosmosClient.GetContainer(Constant.TEAMModelOS, "Common").GetItemQueryIteratorSql<StatsInfo>(queryText: statsSql.ToString(), requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey("Statistics") }))
  107. {
  108. statsInfos.Add(item);
  109. }
  110. }
  111. List<LastYearLessAndAct> lastYear = new();
  112. StringBuilder lastStsSql = new($"select c.lesson,c.activity from c where c.year={dateTime.Year - 1}");
  113. if (scIds.Count > 0)
  114. {
  115. lastStsSql.Append($" and {BICommonWay.ManyScSql("c.id", scIds, $"{dateTime.Year - 1}-")}");
  116. await foreach (var item in cosmosClient.GetContainer(Constant.TEAMModelOS, "Common").GetItemQueryIteratorSql<LastYearLessAndAct>(queryText: lastStsSql.ToString(), requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey("Statistics") }))
  117. {
  118. lastYear.Add(item);
  119. }
  120. }
  121. StatsInfo statsInfo = null;
  122. statsInfo = SchoolStatsWay.GetAreaStats(cosmosClient, _option, statsInfos, scIds, area);
  123. if (statsInfo != null)
  124. {
  125. areaScStats.id = statsInfo.id;
  126. areaScStats.name = statsInfo.name;
  127. areaScStats.weekSc = schoolInfos.Where(w => w.createDate >= weekS && w.createDate <= weekE).Count();
  128. areaScStats.monthSc = schoolInfos.Where(w => w.createDate >= mthS && w.createDate <= mthE).Count();
  129. areaScStats.tch = statsInfo.tch;
  130. areaScStats.dayTch = statsInfo.dayTch;
  131. areaScStats.weekTch = statsInfo.weekTch;
  132. areaScStats.monthTch = statsInfo.monthTch;
  133. areaScStats.stu = statsInfo.stu;
  134. areaScStats.dayStu = statsInfo.dayStu;
  135. areaScStats.weekStu = statsInfo.weekStu;
  136. areaScStats.monthStu = statsInfo.monthStu;
  137. areaScStats.room = statsInfo.room;
  138. areaScStats.witRoom = statsInfo.witRoom;
  139. areaScStats.resourceCnt = statsInfo.resourceCnt;
  140. areaScStats.size = statsInfo.size;
  141. //areaScStats.useSize = statsInfo.useSize;
  142. areaScStats.lessStats.all = statsInfo.lesson.all;
  143. areaScStats.lessStats.open = statsInfo.lesson.open;
  144. areaScStats.lessStats.less = statsInfo.lesson.less;
  145. areaScStats.lessStats.lastDay = statsInfo.lesson.lastDay;
  146. areaScStats.lessStats.day = statsInfo.lesson.day;
  147. areaScStats.lessStats.lastWeek = statsInfo.lesson.lastWeek;
  148. areaScStats.lessStats.week = statsInfo.lesson.week;
  149. areaScStats.lessStats.lastTerm = statsInfo.lesson.lastTerm;
  150. areaScStats.lessStats.term = statsInfo.lesson.term;
  151. areaScStats.lessStats.lastDayInter = statsInfo.lesson.lastDayInter;
  152. areaScStats.lessStats.dayInter = statsInfo.lesson.dayInter;
  153. areaScStats.lessStats.lastMonthInter = statsInfo.lesson.lastMonthInter;
  154. areaScStats.lessStats.monthInter = statsInfo.lesson.monthInter;
  155. areaScStats.lessStats.lastYearInter = statsInfo.lesson.lastYearInter;
  156. areaScStats.lessStats.yearInter = statsInfo.lesson.yearInter;
  157. areaScStats.lessStats.yearInters = TimeHelper.GetYearMonth(statsInfo.lesson.yearInters, dateTime.Year, dateTime.Month);
  158. areaScStats.lessStats.lastYear = ((int)BICommonWay.ManyDoubleMerge(lastYear.Select(s => s.lesson.year).Where(w => w.Count > 0).ToList()).Sum());
  159. areaScStats.lessStats.year = TimeHelper.GetYearMonth(statsInfo.lesson.year, dateTime.Year, dateTime.Month);
  160. areaScStats.actStats.all = statsInfo.activity.all;
  161. areaScStats.actStats.exam = statsInfo.activity.exam;
  162. areaScStats.actStats.survey = statsInfo.activity.survey;
  163. areaScStats.actStats.vote = statsInfo.activity.vote;
  164. areaScStats.actStats.homework = statsInfo.activity.homework;
  165. areaScStats.actStats.lastDay = statsInfo.activity.lastDay;
  166. areaScStats.actStats.dayCnt = statsInfo.activity.dayCnt;
  167. areaScStats.actStats.lastWeek = statsInfo.activity.lastWeek;
  168. areaScStats.actStats.week = statsInfo.activity.week;
  169. areaScStats.actStats.lastTerm = statsInfo.activity.lastTerm;
  170. areaScStats.actStats.term = statsInfo.activity.term;
  171. areaScStats.actStats.lastMonth = statsInfo.activity.lastMonth;
  172. areaScStats.actStats.month = statsInfo.activity.month;
  173. areaScStats.actStats.lastYear = ((int)BICommonWay.ManyDoubleMerge(lastYear.Select(s => s.activity.year).Where(w => w.Count > 0).ToList()).Sum());
  174. areaScStats.actStats.year = TimeHelper.GetYearMonth(statsInfo.activity.year, dateTime.Year, dateTime.Month);
  175. if (statsInfo.study != null)
  176. {
  177. areaScStats.srStats.learnTime = statsInfo.study.learnTime;
  178. areaScStats.srStats.online = statsInfo.study.online;
  179. areaScStats.srStats.offline = statsInfo.study.offline;
  180. areaScStats.srStats.classRoom = statsInfo.study.classRoom;
  181. areaScStats.srStats.submit = statsInfo.study.submit;
  182. areaScStats.srStats.notStarted = statsInfo.study.notStarted;
  183. areaScStats.srStats.ongoing = statsInfo.study.ongoing;
  184. areaScStats.srStats.finish = statsInfo.study.finish;
  185. }
  186. }
  187. List<double> weekLess = BICommonWay.weekDoubleMerge(statsInfos.Select(s => s.lesson.year).Where(w => w.Count > 0).ToList(), dateTime);
  188. schoolInfos.ForEach(fe =>
  189. {
  190. var tempSts = statsInfos.Find(f => f.schoolId.Equals(fe.id));
  191. if (tempSts != null)
  192. {
  193. fe.less = tempSts.lesson.all;
  194. fe.lastWeekLess = tempSts.lesson.lastWeek;
  195. fe.monthLess = tempSts.lesson.month;
  196. }
  197. });
  198. List<IdInfo> assits = new();
  199. schoolInfos.ForEach(fe => assits.AddRange(fe.assists));
  200. List<IdInfo> saless = new();
  201. schoolInfos.ForEach(fe => saless.AddRange(fe.sales));
  202. foreach (var itemId in scIds)
  203. {
  204. RedisValue value = redisClinet.HashGet($"Blob:Record", itemId);
  205. if (value != default && !value.IsNullOrEmpty)
  206. {
  207. JsonElement record = value.ToString().ToObject<JsonElement>();
  208. if (record.TryGetInt64(out long blobsize))
  209. {
  210. useSize += blobsize;
  211. }
  212. }
  213. SortedSetEntry[] Scores = redisClinet.SortedSetRangeByScoreWithScores($"Blob:Catalog:{itemId}");
  214. if (Scores.Length > 0)
  215. {
  216. Dictionary<string, double?> schoolStics = new(); //学校空间
  217. foreach (var score in Scores)
  218. {
  219. double val = score.Score;
  220. string key = score.Element.ToString();
  221. schoolStics.Add(key, val);
  222. }
  223. typeStics = typeStics.Concat(schoolStics).GroupBy(g => g.Key).ToDictionary(k => k.Key, k => k.Sum(kvp => kvp.Value)); //lamebda表达式
  224. }
  225. }
  226. return Ok(new { state = RespondCode.Ok, areaScStats, schoolInfos, weekLess, assists = assits.Where((w, i) => assits.FindIndex(s => s.id.Equals(w.id)) == i).ToList(), saless = saless.Where((w, i) => saless.FindIndex(f => f.id.Equals(w.id)) == i).ToList(), useSize, typeStics = typeStics.ToList() });
  227. }
  228. catch (Exception ex)
  229. {
  230. await _dingDing.SendBotMsg($"OS,{_option.Location},Area/GetAreaStats()\n{ex.Message}\n{ex.StackTrace}\n", GroupNames.醍摩豆服務運維群組);
  231. return BadRequest(new { ex.Message, ex.StackTrace });
  232. }
  233. }
  234. /// <summary>
  235. /// 学校统计接口
  236. /// </summary>
  237. /// <param name="jsonElement"></param>
  238. /// <returns></returns>
  239. [ProducesDefaultResponseType]
  240. [HttpPost("get-schoolstats")]
  241. #if !DEBUG
  242. [Authorize(Roles = "IES")]
  243. #endif
  244. [AuthToken(Roles = "area,admin")]
  245. public async Task<IActionResult> GetSchoolStats(JsonElement jsonElement)
  246. {
  247. try
  248. {
  249. if (!jsonElement.TryGetProperty("schoolId", out JsonElement scId)) return BadRequest();
  250. var cosmosClient = _azureCosmos.GetCosmosClient();
  251. School school = new();
  252. ScStats scStats = new();
  253. var respSc = await cosmosClient.GetContainer(Constant.TEAMModelOS, "School").ReadItemStreamAsync($"{scId}", new PartitionKey($"Base"));
  254. if (respSc.StatusCode==System.Net.HttpStatusCode.OK)
  255. {
  256. using var fileJson = await JsonDocument.ParseAsync(respSc.Content);
  257. school = fileJson.ToObject<School>();
  258. }
  259. else
  260. return Ok(new { state = RespondCode.NotFound, msg = $"未找到id:{scId};相关的学校,请检查" });
  261. StatsInfo statsInfo = null;
  262. List<LastYearLessAndAct> lastYear = new();
  263. var scDataStats = await cosmosClient.GetContainer(Constant.TEAMModelOS, "Common").ReadItemStreamAsync($"{DateTimeOffset.UtcNow.Year}-{scId}", new PartitionKey("Statistics"));
  264. if (scDataStats.StatusCode==System.Net.HttpStatusCode.OK)
  265. {
  266. using var fileJson = await JsonDocument.ParseAsync(scDataStats.Content);
  267. statsInfo = fileJson.ToObject<StatsInfo>();
  268. await foreach (var item in cosmosClient.GetContainer(Constant.TEAMModelOS, "Common").GetItemQueryIteratorSql<LastYearLessAndAct>(queryText: $"select c.activity,c.lesson from c where c.id='{DateTimeOffset.UtcNow.Year - 1}-{scId}'", requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey("Statistics") }))
  269. {
  270. lastYear.Add(item);
  271. }
  272. }
  273. else
  274. {
  275. scStats.id = $"{DateTimeOffset.UtcNow.Year}-{school.id}";
  276. scStats.schoolId = school.id;
  277. scStats.name = school.name;
  278. scStats.picture = school.picture;
  279. scStats.areaId = school.areaId;
  280. }
  281. DateTimeOffset dateTime = DateTimeOffset.UtcNow;
  282. long now = dateTime.ToUnixTimeMilliseconds();
  283. if (statsInfo != null)
  284. {
  285. scStats.id = statsInfo.id;
  286. scStats.schoolId = statsInfo.schoolId;
  287. scStats.name = statsInfo.name;
  288. scStats.picture = statsInfo.picture;
  289. scStats.areaId = statsInfo.areaId;
  290. scStats.tch = statsInfo.tch;
  291. scStats.dayTch = statsInfo.dayTch;
  292. scStats.weekTch = statsInfo.weekTch;
  293. scStats.monthTch = statsInfo.monthTch;
  294. scStats.stu = statsInfo.stu;
  295. scStats.dayStu = statsInfo.dayStu;
  296. scStats.weekStu = statsInfo.weekStu;
  297. scStats.monthStu = statsInfo.monthStu;
  298. scStats.room = statsInfo.room;
  299. scStats.witRoom = statsInfo.witRoom;
  300. scStats.resourceCnt = statsInfo.resourceCnt;
  301. scStats.size = statsInfo.size;
  302. scStats.scCreateTime = statsInfo.scCreateTime;
  303. scStats.upTime = statsInfo.upTime;
  304. scStats.lessStats.all = statsInfo.lesson.all;
  305. scStats.lessStats.open = statsInfo.lesson.open;
  306. scStats.lessStats.less = statsInfo.lesson.less;
  307. scStats.lessStats.lastDay = statsInfo.lesson.lastDay;
  308. scStats.lessStats.day = statsInfo.lesson.day;
  309. scStats.lessStats.lastWeek = statsInfo.lesson.lastWeek;
  310. scStats.lessStats.week = statsInfo.lesson.week;
  311. scStats.lessStats.lastTerm = statsInfo.lesson.lastTerm;
  312. scStats.lessStats.term = statsInfo.lesson.term;
  313. scStats.lessStats.month = statsInfo.lesson.month;
  314. scStats.lessStats.lastMonth = statsInfo.lesson.lastMonth;
  315. scStats.lessStats.lastDayInter = statsInfo.lesson.lastDayInter;
  316. scStats.lessStats.dayInter = statsInfo.lesson.dayInter;
  317. scStats.lessStats.lastMonthInter = statsInfo.lesson.lastMonthInter;
  318. scStats.lessStats.monthInter = statsInfo.lesson.monthInter;
  319. scStats.lessStats.lastYear = ((int)BICommonWay.ManyDoubleMerge(lastYear.Select(s => s.lesson.year).Where(w => w.Count > 0).ToList()).Sum());
  320. scStats.lessStats.lastYearInter = statsInfo.lesson.lastYearInter;
  321. scStats.lessStats.yearInter = statsInfo.lesson.yearInter;
  322. scStats.lessStats.yearInters = TimeHelper.GetYearMonth(statsInfo.lesson.yearInters, dateTime.Year, dateTime.Month);
  323. scStats.lessStats.year = TimeHelper.GetYearMonth(statsInfo.lesson.year, dateTime.Year, dateTime.Month);
  324. scStats.actStats.all = statsInfo.activity.all;
  325. scStats.actStats.exam = statsInfo.activity.exam;
  326. scStats.actStats.survey = statsInfo.activity.survey;
  327. scStats.actStats.vote = statsInfo.activity.vote;
  328. scStats.actStats.homework = statsInfo.activity.homework;
  329. scStats.actStats.lastDay = statsInfo.activity.lastDay;
  330. scStats.actStats.dayCnt = statsInfo.activity.dayCnt;
  331. scStats.actStats.lastWeek = statsInfo.activity.lastWeek;
  332. scStats.actStats.week = statsInfo.activity.week;
  333. scStats.actStats.lastTerm = statsInfo.activity.lastTerm;
  334. scStats.actStats.term = statsInfo.activity.term;
  335. scStats.actStats.lastMonth = statsInfo.activity.lastMonth;
  336. scStats.actStats.month = statsInfo.activity.month;
  337. scStats.actStats.lastYear = ((int)BICommonWay.ManyDoubleMerge(lastYear.Select(s => s.activity.year).Where(w => w.Count > 0).ToList()).Sum());
  338. scStats.actStats.year = TimeHelper.GetYearMonth(statsInfo.activity.year, dateTime.Year, dateTime.Month);
  339. if (statsInfo.study != null)
  340. {
  341. scStats.srStats.learnTime = statsInfo.study.learnTime;
  342. scStats.srStats.online = statsInfo.study.online;
  343. scStats.srStats.offline = statsInfo.study.offline;
  344. scStats.srStats.classRoom = statsInfo.study.classRoom;
  345. scStats.srStats.submit = statsInfo.study.submit;
  346. scStats.srStats.notStarted = statsInfo.study.notStarted;
  347. scStats.srStats.ongoing = statsInfo.study.ongoing;
  348. scStats.srStats.finish = statsInfo.study.finish;
  349. }
  350. }
  351. return Ok(new { state = RespondCode.Ok, scStats, school.edition });
  352. }
  353. catch (Exception ex)
  354. {
  355. await _dingDing.SendBotMsg($"OS,{_option.Location},Area/GetSchoolStats()\n{ex.Message}\n{ex.StackTrace}\n", GroupNames.醍摩豆服務運維群組);
  356. return BadRequest(new { ex.Message, ex.StackTrace });
  357. }
  358. }
  359. /// <summary>
  360. /// 学校基础信息,科目、年级课例占比
  361. /// </summary>
  362. /// <param name="jsonElement"></param>
  363. /// <returns></returns>
  364. [ProducesDefaultResponseType]
  365. [HttpPost("get-schoolgrade")]
  366. #if !DEBUG
  367. [Authorize(Roles = "IES")]
  368. #endif
  369. [AuthToken(Roles = "area,admin")]
  370. public async Task<IActionResult> GetSchoolGrade(JsonElement jsonElement)
  371. {
  372. try
  373. {
  374. if (!jsonElement.TryGetProperty("schoolId", out JsonElement schoolId)) return BadRequest();
  375. //jsonElement.TryGetProperty("site", out JsonElement site);//分开部署,就不需要,一站多用时,取消注释
  376. var cosmosClient = _azureCosmos.GetCosmosClient();
  377. ////分开部署,就不需要,一站多用时,取消注释
  378. //if ($"{site}".Equals(BIConst.Global))
  379. // cosmosClient = _azureCosmos.GetCosmosClient(name: BIConst.Global);
  380. AnSchool school = new(); //学校基础基础信息
  381. var response = await cosmosClient.GetContainer("TEAMModelOS", "School").ReadItemStreamAsync($"{schoolId}", new PartitionKey("Base"));
  382. if (response.StatusCode==System.Net.HttpStatusCode.OK)
  383. {
  384. using var json = await JsonDocument.ParseAsync(response.Content);
  385. school = json.ToObject<AnSchool>();
  386. }
  387. else return Ok(new { state = RespondCode.NotFound, msg = "未找到该学校" });
  388. List<LessAnalyse> lessAnalyses = new();
  389. await foreach (var lessItem in cosmosClient.GetContainer("TEAMModelOS", "School").GetItemQueryIteratorSql<LessAnalyse>(queryText: "select c.id,c.code,c.periodId,c.subjectId,c.grade from c", requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"LessonRecord-{school.id}") }))
  390. {
  391. lessAnalyses.Add(lessItem);
  392. }
  393. List<(string name, string periodId, int count)> grades = LessonStatisWay.GetGradeCount(lessAnalyses);
  394. var subs = lessAnalyses.GroupBy(x => x.subjectId).Where(y => !string.IsNullOrEmpty(y.Key)).Select(y => new { key = y.Key, count = y.ToList().Count }).ToList();
  395. var gradeCnt = grades.Select(x => new { x.name, x.periodId, value = x.count });
  396. var subCnt = subs.Select(x => new { name = x.key, value = x.count });
  397. var responseProduct = await cosmosClient.GetContainer("TEAMModelOS", "School").ReadItemStreamAsync(school.id, new PartitionKey("ProductSum"));
  398. if (responseProduct.StatusCode==System.Net.HttpStatusCode.OK)
  399. {
  400. using var json = await JsonDocument.ParseAsync(responseProduct.Content);
  401. if (json.RootElement.TryGetProperty("serial", out JsonElement _serial) && !_serial.ValueKind.Equals(JsonValueKind.Null))
  402. {
  403. school.serial = _serial.ToObject<List<SchoolProductSumData>>().Select(x => x.prodCode).ToList();
  404. }
  405. if (json.RootElement.TryGetProperty("service", out JsonElement _service) && !_service.ValueKind.Equals(JsonValueKind.Null))
  406. {
  407. school.service = _service.ToObject<List<SchoolProductSumData>>().Select(x => x.prodCode).ToList();
  408. }
  409. if (json.RootElement.TryGetProperty("hard", out JsonElement _hard) && !_hard.ValueKind.Equals(JsonValueKind.Null))
  410. {
  411. school.hard = _hard.ToObject<List<SchoolProductSumDataHard>>().Select(x => x.prodCode).ToList();
  412. }
  413. }
  414. return Ok(new { state = RespondCode.Ok, school, gradeCnt, subCnt });
  415. }
  416. catch (Exception ex)
  417. {
  418. await _dingDing.SendBotMsg($"OS,{_option.Location},Area/GetSchoolGrade()\n{ex.Message}\n{ex.StackTrace}\n", GroupNames.醍摩豆服務運維群組);
  419. return BadRequest(new { ex.Message, ex.StackTrace });
  420. }
  421. }
  422. }
  423. }