ErrorItemsService.cs 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156
  1. using Microsoft.Azure.Cosmos;
  2. using StackExchange.Redis;
  3. using System;
  4. using System.Collections.Generic;
  5. using System.Linq;
  6. using System.Text;
  7. using System.Text.Json;
  8. using System.Threading.Tasks;
  9. using TEAMModelOS.SDK.DI;
  10. namespace TEAMModelOS.SDK.Models.Service
  11. {
  12. public static class ErrorItemsService
  13. {
  14. public static async Task cntStuErrorItemsAsync(AzureRedisFactory _azureRedis, CosmosClient _azureCosmosClient, DingDing _dingDing)
  15. {
  16. try
  17. {
  18. var redisClinet8 = _azureRedis.GetRedisClient(8);
  19. //各校在學學生名單製作
  20. Dictionary<string, List<string>> schStuDic = new Dictionary<string, List<string>>();
  21. await foreach (var item in _azureCosmosClient.GetContainer(Constant.TEAMModelOS, "Student").GetItemQueryStreamIteratorSql(queryText: "SELECT c.id, c.schoolId FROM c WHERE (NOT IS_DEFINED(c.graduate) OR c.graduate = 0) AND IS_DEFINED(c.schoolId) AND CONTAINS(c.code, 'Base-')", null))
  22. {
  23. using var json = await JsonDocument.ParseAsync(item.Content);
  24. if (json.RootElement.TryGetProperty("_count", out JsonElement count) && count.GetUInt16() > 0)
  25. {
  26. foreach (var obj in json.RootElement.GetProperty("Documents").EnumerateArray())
  27. {
  28. string stuId = obj.GetProperty("id").GetString();
  29. string stuschId = obj.GetProperty("schoolId").GetString();
  30. if(schStuDic.ContainsKey(stuschId))
  31. {
  32. if (!schStuDic[stuschId].Contains(stuId))
  33. {
  34. schStuDic[stuschId].Add(stuId);
  35. }
  36. }
  37. else
  38. {
  39. schStuDic.Add(stuschId, new List<string>() { stuId });
  40. }
  41. }
  42. }
  43. }
  44. //取得ErrorItems錯題
  45. Dictionary<string, Dictionary<string, List<ErrorItemsStuRowWithItems>>> ErrorItemsDic = new Dictionary<string, Dictionary<string, List<ErrorItemsStuRowWithItems>>>();
  46. string qry = "SELECT ARRAY(SELECT VALUE t.id FROM t IN c.its ) AS itemIds, c.stuId, c.school AS schoolId, c.subjectId, c.code FROM c WHERE " +
  47. "CONTAINS(c.code, 'ErrorItems') ";
  48. await foreach (var item in _azureCosmosClient.GetContainer(Constant.TEAMModelOS, "Student").GetItemQueryIteratorSql<ErrorItemsDoc>(queryText: qry, requestOptions: null))
  49. {
  50. string schoolId = (!string.IsNullOrWhiteSpace(item.schoolId)) ? item.schoolId : "noschoolid";
  51. string stuId = item.stuId;
  52. string subjectId = item.subjectId;
  53. bool goFlg = ((schStuDic.ContainsKey(schoolId) && schStuDic[schoolId].Contains(item.stuId)) || schoolId.Equals("noschoolid")) ? true : false;
  54. if (goFlg)
  55. {
  56. if (ErrorItemsDic.ContainsKey(schoolId))
  57. {
  58. if (ErrorItemsDic[schoolId].ContainsKey(stuId))
  59. {
  60. List<ErrorItemsStuRowWithItems> ErrorItemsStuRowList = ErrorItemsDic[schoolId][stuId];
  61. ErrorItemsStuRowWithItems ErrorItemsStuRow = ErrorItemsStuRowList.Where(s => s.subjectId.Equals(subjectId)).FirstOrDefault();
  62. if (ErrorItemsStuRow == null)
  63. {
  64. ErrorItemsDic[schoolId][stuId].Add(new ErrorItemsStuRowWithItems() { subjectId = subjectId });
  65. ErrorItemsStuRow = ErrorItemsDic[schoolId][stuId].Where(s => s.subjectId.Equals(subjectId)).FirstOrDefault();
  66. }
  67. ErrorItemsStuRow.itemIds = ErrorItemsStuRow.itemIds.Union(item.itemIds).ToList();
  68. ErrorItemsStuRow.number = ErrorItemsStuRow.itemIds.Count;
  69. }
  70. else
  71. {
  72. List<ErrorItemsStuRowWithItems> ErrorItemsStuRowList = new List<ErrorItemsStuRowWithItems>();
  73. ErrorItemsStuRowWithItems ErrorItemsStuRow = new ErrorItemsStuRowWithItems() { subjectId = subjectId };
  74. ErrorItemsStuRow.itemIds = item.itemIds;
  75. ErrorItemsStuRow.number = ErrorItemsStuRow.itemIds.Count;
  76. ErrorItemsStuRowList.Add(ErrorItemsStuRow);
  77. ErrorItemsDic[schoolId].Add(stuId, ErrorItemsStuRowList);
  78. }
  79. }
  80. else
  81. {
  82. List<ErrorItemsStuRowWithItems> ErrorItemsStuRowList = new List<ErrorItemsStuRowWithItems>();
  83. ErrorItemsStuRowWithItems ErrorItemsStuRow = new ErrorItemsStuRowWithItems() { subjectId = subjectId };
  84. ErrorItemsStuRow.itemIds = item.itemIds;
  85. ErrorItemsStuRow.number = ErrorItemsStuRow.itemIds.Count;
  86. ErrorItemsStuRowList.Add(ErrorItemsStuRow);
  87. Dictionary<string, List<ErrorItemsStuRowWithItems>> ErrorItemsSchRow = new Dictionary<string, List<ErrorItemsStuRowWithItems>> { { stuId, ErrorItemsStuRowList } };
  88. ErrorItemsDic.Add(schoolId, ErrorItemsSchRow);
  89. }
  90. }
  91. }
  92. //Dic整形:去除itemIds欄位
  93. Dictionary<string, Dictionary<string, List<ErrorItemsStuRow>>> ErrorItemsDicResult = new Dictionary<string, Dictionary<string, List<ErrorItemsStuRow>>>();
  94. foreach (KeyValuePair<string, Dictionary<string, List<ErrorItemsStuRowWithItems>>> schItem in ErrorItemsDic)
  95. {
  96. string schoolId = schItem.Key;
  97. ErrorItemsDicResult.Add(schoolId, new Dictionary<string, List<ErrorItemsStuRow>>());
  98. Dictionary<string, List<ErrorItemsStuRowWithItems>> schDic = schItem.Value;
  99. foreach(KeyValuePair<string, List<ErrorItemsStuRowWithItems>> stuItem in schDic)
  100. {
  101. string stuId = stuItem.Key;
  102. ErrorItemsDicResult[schoolId].Add(stuId, new List<ErrorItemsStuRow>());
  103. List<ErrorItemsStuRowWithItems> stuList = stuItem.Value;
  104. foreach(ErrorItemsStuRowWithItems stuRow in stuList)
  105. {
  106. ErrorItemsStuRow stuRowNew = new ErrorItemsStuRow() { subjectId = stuRow.subjectId , number = stuRow.number };
  107. ErrorItemsDicResult[schoolId][stuId].Add(stuRowNew);
  108. }
  109. }
  110. }
  111. //寫入Redis
  112. foreach (var SchItem in ErrorItemsDicResult)
  113. {
  114. string schoolId = SchItem.Key;
  115. string hkey = $"ErrorItems:{schoolId}";
  116. List<HashEntry> hvalList = new List<HashEntry>();
  117. Dictionary<string, List<ErrorItemsStuRow>> itemSch = SchItem.Value;
  118. foreach(var itemStu in itemSch)
  119. {
  120. string stuId = itemStu.Key;
  121. string stuVal = JsonSerializer.Serialize(itemStu.Value);
  122. hvalList.Add(new HashEntry($"{stuId}", stuVal));
  123. }
  124. await redisClinet8.HashSetAsync(hkey, hvalList.ToArray());
  125. }
  126. }
  127. catch (Exception ex)
  128. {
  129. await _dingDing.SendBotMsg($"{Environment.GetEnvironmentVariable("Option:Location")},ErrorItemsService/cntStuErrorItemsAsync()\n{ex.Message}\n{ex.StackTrace}", GroupNames.醍摩豆服務運維群組);
  130. }
  131. }
  132. }
  133. //ErrorItems 各學生資料項目
  134. public class ErrorItemsStuRow
  135. {
  136. public string subjectId { get; set; }
  137. public int number { get; set; }
  138. }
  139. //ErrorItems 各學生資料項目
  140. public class ErrorItemsStuRowWithItems : ErrorItemsStuRow
  141. {
  142. public List<string> itemIds { get; set; } = new List<string>();
  143. }
  144. //ErrorItems承接DB用
  145. public class ErrorItemsDoc
  146. {
  147. public string code { get; set; }
  148. public string stuId { get; set; }
  149. public string schoolId { get; set; }
  150. public string subjectId { get; set; }
  151. public List<string> itemIds { get; set; } = new();
  152. }
  153. }