using Microsoft.Azure.Cosmos; using StackExchange.Redis; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Text.Json; using System.Threading.Tasks; using TEAMModelOS.SDK.DI; namespace TEAMModelOS.SDK.Models.Service { public static class ErrorItemsService { public static async Task cntStuErrorItemsAsync(AzureRedisFactory _azureRedis, CosmosClient _azureCosmosClient, DingDing _dingDing) { try { var redisClinet8 = _azureRedis.GetRedisClient(8); //各校在學學生名單製作 Dictionary> schStuDic = new Dictionary>(); 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)) { using var json = await JsonDocument.ParseAsync(item.Content); if (json.RootElement.TryGetProperty("_count", out JsonElement count) && count.GetUInt16() > 0) { foreach (var obj in json.RootElement.GetProperty("Documents").EnumerateArray()) { string stuId = obj.GetProperty("id").GetString(); string stuschId = obj.GetProperty("schoolId").GetString(); if(schStuDic.ContainsKey(stuschId)) { if (!schStuDic[stuschId].Contains(stuId)) { schStuDic[stuschId].Add(stuId); } } else { schStuDic.Add(stuschId, new List() { stuId }); } } } } //取得ErrorItems錯題 Dictionary>> ErrorItemsDic = new Dictionary>>(); 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 " + "CONTAINS(c.code, 'ErrorItems') "; await foreach (var item in _azureCosmosClient.GetContainer(Constant.TEAMModelOS, "Student").GetItemQueryIteratorSql(queryText: qry, requestOptions: null)) { string schoolId = (!string.IsNullOrWhiteSpace(item.schoolId)) ? item.schoolId : "noschoolid"; string stuId = item.stuId; string subjectId = item.subjectId; bool goFlg = ((schStuDic.ContainsKey(schoolId) && schStuDic[schoolId].Contains(item.stuId)) || schoolId.Equals("noschoolid")) ? true : false; if (goFlg) { if (ErrorItemsDic.ContainsKey(schoolId)) { if (ErrorItemsDic[schoolId].ContainsKey(stuId)) { List ErrorItemsStuRowList = ErrorItemsDic[schoolId][stuId]; ErrorItemsStuRowWithItems ErrorItemsStuRow = ErrorItemsStuRowList.Where(s => s.subjectId.Equals(subjectId)).FirstOrDefault(); if (ErrorItemsStuRow == null) { ErrorItemsDic[schoolId][stuId].Add(new ErrorItemsStuRowWithItems() { subjectId = subjectId }); ErrorItemsStuRow = ErrorItemsDic[schoolId][stuId].Where(s => s.subjectId.Equals(subjectId)).FirstOrDefault(); } ErrorItemsStuRow.itemIds = ErrorItemsStuRow.itemIds.Union(item.itemIds).ToList(); ErrorItemsStuRow.number = ErrorItemsStuRow.itemIds.Count; } else { List ErrorItemsStuRowList = new List(); ErrorItemsStuRowWithItems ErrorItemsStuRow = new ErrorItemsStuRowWithItems() { subjectId = subjectId }; ErrorItemsStuRow.itemIds = item.itemIds; ErrorItemsStuRow.number = ErrorItemsStuRow.itemIds.Count; ErrorItemsStuRowList.Add(ErrorItemsStuRow); ErrorItemsDic[schoolId].Add(stuId, ErrorItemsStuRowList); } } else { List ErrorItemsStuRowList = new List(); ErrorItemsStuRowWithItems ErrorItemsStuRow = new ErrorItemsStuRowWithItems() { subjectId = subjectId }; ErrorItemsStuRow.itemIds = item.itemIds; ErrorItemsStuRow.number = ErrorItemsStuRow.itemIds.Count; ErrorItemsStuRowList.Add(ErrorItemsStuRow); Dictionary> ErrorItemsSchRow = new Dictionary> { { stuId, ErrorItemsStuRowList } }; ErrorItemsDic.Add(schoolId, ErrorItemsSchRow); } } } //Dic整形:去除itemIds欄位 Dictionary>> ErrorItemsDicResult = new Dictionary>>(); foreach (KeyValuePair>> schItem in ErrorItemsDic) { string schoolId = schItem.Key; ErrorItemsDicResult.Add(schoolId, new Dictionary>()); Dictionary> schDic = schItem.Value; foreach(KeyValuePair> stuItem in schDic) { string stuId = stuItem.Key; ErrorItemsDicResult[schoolId].Add(stuId, new List()); List stuList = stuItem.Value; foreach(ErrorItemsStuRowWithItems stuRow in stuList) { ErrorItemsStuRow stuRowNew = new ErrorItemsStuRow() { subjectId = stuRow.subjectId , number = stuRow.number }; ErrorItemsDicResult[schoolId][stuId].Add(stuRowNew); } } } //寫入Redis foreach (var SchItem in ErrorItemsDicResult) { string schoolId = SchItem.Key; string hkey = $"ErrorItems:{schoolId}"; List hvalList = new List(); Dictionary> itemSch = SchItem.Value; foreach(var itemStu in itemSch) { string stuId = itemStu.Key; string stuVal = JsonSerializer.Serialize(itemStu.Value); hvalList.Add(new HashEntry($"{stuId}", stuVal)); } await redisClinet8.HashSetAsync(hkey, hvalList.ToArray()); } } catch (Exception ex) { await _dingDing.SendBotMsg($"{Environment.GetEnvironmentVariable("Option:Location")},ErrorItemsService/cntStuErrorItemsAsync()\n{ex.Message}\n{ex.StackTrace}", GroupNames.醍摩豆服務運維群組); } } } //ErrorItems 各學生資料項目 public class ErrorItemsStuRow { public string subjectId { get; set; } public int number { get; set; } } //ErrorItems 各學生資料項目 public class ErrorItemsStuRowWithItems : ErrorItemsStuRow { public List itemIds { get; set; } = new List(); } //ErrorItems承接DB用 public class ErrorItemsDoc { public string code { get; set; } public string stuId { get; set; } public string schoolId { get; set; } public string subjectId { get; set; } public List itemIds { get; set; } = new(); } }