hhb 8 months ago
parent
commit
acd0f842d2

+ 352 - 44
TEAMModelOS/Controllers/Analysis/ArtAnalysisController.cs

@@ -17,6 +17,7 @@ using TEAMModelOS.SDK.Extension;
 using TEAMModelOS.SDK.Helper.Common.StringHelper;
 using TEAMModelOS.SDK.Models;
 using TEAMModelOS.SDK.Models.Cosmos.Student;
+using StackExchange.Redis;
 
 namespace TEAMModelOS.Controllers.Analysis
 {
@@ -29,14 +30,17 @@ namespace TEAMModelOS.Controllers.Analysis
         private readonly Option _option;
         private readonly CoreAPIHttpService _coreAPIHttpService;
         private readonly AzureStorageFactory _azureStorage;
+        private readonly AzureRedisFactory _azureRedis;
 
-        public ArtAnalysisController(AzureCosmosFactory azureCosmos, DingDing dingDing, IOptionsSnapshot<Option> option, CoreAPIHttpService coreAPIHttpService, AzureStorageFactory azureStorage)
+        public ArtAnalysisController(AzureCosmosFactory azureCosmos, DingDing dingDing, IOptionsSnapshot<Option> option, CoreAPIHttpService coreAPIHttpService, AzureStorageFactory azureStorage, AzureRedisFactory azureRedis)
         {
             _azureCosmos = azureCosmos;
             _dingDing = dingDing;
             _option = option?.Value;
             _coreAPIHttpService = coreAPIHttpService;
             _azureStorage = azureStorage;
+            _azureRedis = azureRedis;
+
         }
 
         /* [ProducesDefaultResponseType]
@@ -88,6 +92,160 @@ namespace TEAMModelOS.Controllers.Analysis
                 string artId = id.GetString();
                 List<string> classIds = cIds.ToObject<List<string>>();
 
+                if (classIds.Count == 1)
+                {
+
+                    RedisValue value = await _azureRedis.GetRedisClient(8).HashGetAsync($"ArtSchool:students:{code}:{classIds[0]}", $"students:{subjectId}:{id}");
+                    if (value != default && !value.IsNullOrEmpty)
+                    {
+                        var value_count = await _azureRedis.GetRedisClient(8).HashGetAsync($"ArtSchool:count:{code}", $"count:{subjectId}:{id}");
+                        var value_max = await _azureRedis.GetRedisClient(8).HashGetAsync($"ArtSchool:max:{code}", $"max:{subjectId}:{id}");
+                        var value_min = await _azureRedis.GetRedisClient(8).HashGetAsync($"ArtSchool:min:{code}", $"min:{subjectId}:{id}");
+                        var value_average = await _azureRedis.GetRedisClient(8).HashGetAsync($"ArtSchool:average:{code}", $"average:{subjectId}:{id}");
+                        var value_excellent = await _azureRedis.GetRedisClient(8).HashGetAsync($"ArtSchool:excellent:{code}", $"excellent:{subjectId}:{id}");
+                        var value_pass = await _azureRedis.GetRedisClient(8).HashGetAsync($"ArtSchool:pass:{code}", $"pass:{subjectId}:{id}");
+                        var value_pow = await _azureRedis.GetRedisClient(8).HashGetAsync($"ArtSchool:pow:{code}", $"pow:{subjectId}:{id}");
+                        var value_blks = await _azureRedis.GetRedisClient(8).HashGetAsync($"ArtSchool:blk:{code}", $"blk:{subjectId}:{id}");
+                        var value_kno = await _azureRedis.GetRedisClient(8).HashGetAsync($"ArtSchool:kno:{code}", $"kno:{subjectId}:{id}");
+                        var value_dim = await _azureRedis.GetRedisClient(8).HashGetAsync($"ArtSchool:dim:{code}", $"dim:{subjectId}:{id}");
+                        var value_optCount = await _azureRedis.GetRedisClient(8).HashGetAsync($"ArtSchool:optCount:{code}", $"optCount:{subjectId}:{id}");
+                        var value_realClassCount = await _azureRedis.GetRedisClient(8).HashGetAsync($"ArtSchool:realClassCount:{code}", $"realClassCount:{subjectId}:{id}");
+                        var value_cInfo = await _azureRedis.GetRedisClient(8).HashGetAsync($"ArtSchool:cInfo:{code}:{classIds[0]}", $"cInfo:{subjectId}:{id}");
+                        var value_gscore = await _azureRedis.GetRedisClient(8).HashGetAsync($"ArtSchool:gscore:{code}", $"gscore:{subjectId}:{id}");
+
+                        var count_1 = value_count.ToString().ToObject<JsonElement>();
+                        var scount_1 = value_realClassCount.ToString().ToObject<JsonElement>();
+                        var max_1 = value_max.ToString().ToObject<JsonElement>();
+                        var min_1 = value_min.ToString().ToObject<JsonElement>();
+                        var average_1 = value_average.ToString().ToObject<JsonElement>();
+                        var excellent_1 = value_excellent.ToString().ToObject<JsonElement>();
+                        var pass_1 = value_pass.ToString().ToObject<JsonElement>();
+                        var pow_1 = value_pow.ToString().ToObject<JsonElement>();
+                        var blk_1 = value_blks.ToString().ToObject<JsonElement>();
+                        var kno_1 = value_kno.ToString().ToObject<JsonElement>();
+                        var dim_1 = value_dim.ToString().ToObject<JsonElement>();
+                        var optCount_1 = value_optCount.ToString().ToObject<JsonElement>();
+                        var students_1 = value.ToString().ToObject<JsonElement>();
+                        var cInfo_1 = value_cInfo.ToString().ToObject<JsonElement>();
+                        var gscore_1 = value_gscore.ToString().ToObject<JsonElement>();
+                        return Ok(new
+                        {
+                            count = count_1,
+                            scount = scount_1,
+                            max = max_1,
+                            min = min_1,
+                            average = average_1,
+                            excellent = excellent_1,
+                            pass = pass_1,
+                            pow = pow_1,
+                            blk = blk_1,
+                            kno = kno_1,
+                            dim = dim_1,
+                            optCount = optCount_1,
+                            students = students_1,
+                            cInfo = cInfo_1,
+                            gscore = gscore_1
+                        });
+                    }
+                }
+                else if (classIds.Count == 0)
+                {
+
+                    RedisValue value = await _azureRedis.GetRedisClient(8).HashGetAsync($"ArtSchool:grade:{code}:{classIds[0]}", $"grade:{subjectId}:{id}");
+                    if (value != default && !value.IsNullOrEmpty)
+                    {
+                        var value_count = await _azureRedis.GetRedisClient(8).HashGetAsync($"ArtSchool:count:{code}", $"count:{subjectId}:{id}");
+                        var value_max = await _azureRedis.GetRedisClient(8).HashGetAsync($"ArtSchool:max:{code}", $"max:{subjectId}:{id}");
+                        var value_min = await _azureRedis.GetRedisClient(8).HashGetAsync($"ArtSchool:min:{code}", $"min:{subjectId}:{id}");
+                        var value_average = await _azureRedis.GetRedisClient(8).HashGetAsync($"ArtSchool:average:{code}", $"average:{subjectId}:{id}");
+                        var value_excellent = await _azureRedis.GetRedisClient(8).HashGetAsync($"ArtSchool:excellent:{code}", $"excellent:{subjectId}:{id}");
+                        var value_pass = await _azureRedis.GetRedisClient(8).HashGetAsync($"ArtSchool:pass:{code}", $"pass:{subjectId}:{id}");
+                        var value_pow = await _azureRedis.GetRedisClient(8).HashGetAsync($"ArtSchool:pow:{code}", $"pow:{subjectId}:{id}");
+                        var value_blks = await _azureRedis.GetRedisClient(8).HashGetAsync($"ArtSchool:blk:{code}", $"blk:{subjectId}:{id}");
+                        var value_kno = await _azureRedis.GetRedisClient(8).HashGetAsync($"ArtSchool:kno:{code}", $"kno:{subjectId}:{id}");
+                        var value_dim = await _azureRedis.GetRedisClient(8).HashGetAsync($"ArtSchool:dim:{code}", $"dim:{subjectId}:{id}");
+                        var value_optCount = await _azureRedis.GetRedisClient(8).HashGetAsync($"ArtSchool:optCount:{code}", $"optCount:{subjectId}:{id}");
+                        var value_scount = await _azureRedis.GetRedisClient(8).HashGetAsync($"ArtSchool:scount:{code}", $"scount:{subjectId}:{id}");
+
+                        var count_1 = value_count.ToString().ToObject<JsonElement>();
+                        var scount_1 = value_scount.ToString().ToObject<JsonElement>();
+                        var max_1 = value_max.ToString().ToObject<JsonElement>();
+                        var min_1 = value_min.ToString().ToObject<JsonElement>();
+                        var average_1 = value_average.ToString().ToObject<JsonElement>();
+                        var excellent_1 = value_excellent.ToString().ToObject<JsonElement>();
+                        var pass_1 = value_pass.ToString().ToObject<JsonElement>();
+                        var pow_1 = value_pow.ToString().ToObject<JsonElement>();
+                        var blk_1 = value_blks.ToString().ToObject<JsonElement>();
+                        var kno_1 = value_kno.ToString().ToObject<JsonElement>();
+                        var dim_1 = value_dim.ToString().ToObject<JsonElement>();
+                        var optCount_1 = value_optCount.ToString().ToObject<JsonElement>();
+                        return Ok(new
+                        {
+                            count = count_1,
+                            scount = scount_1,
+                            max = max_1,
+                            min = min_1,
+                            average = average_1,
+                            excellent = excellent_1,
+                            pass = pass_1,
+                            pow = pow_1,
+                            blk = blk_1,
+                            kno = kno_1,
+                            dim = dim_1,
+                            optCount = optCount_1,
+                        });
+                    }
+
+                }
+                else {
+                    RedisValue value = await _azureRedis.GetRedisClient(8).HashGetAsync($"ArtSchool:cInfo:{code}", $"cInfo:{subjectId}:{id}");
+                    if (value != default && !value.IsNullOrEmpty)
+                    {
+                        var value_count = await _azureRedis.GetRedisClient(8).HashGetAsync($"ArtSchool:count:{code}", $"count:{subjectId}:{id}");
+                        var value_max = await _azureRedis.GetRedisClient(8).HashGetAsync($"ArtSchool:max:{code}", $"max:{subjectId}:{id}");
+                        var value_min = await _azureRedis.GetRedisClient(8).HashGetAsync($"ArtSchool:min:{code}", $"min:{subjectId}:{id}");
+                        var value_average = await _azureRedis.GetRedisClient(8).HashGetAsync($"ArtSchool:average:{code}", $"average:{subjectId}:{id}");
+                        var value_excellent = await _azureRedis.GetRedisClient(8).HashGetAsync($"ArtSchool:excellent:{code}", $"excellent:{subjectId}:{id}");
+                        var value_pass = await _azureRedis.GetRedisClient(8).HashGetAsync($"ArtSchool:pass:{code}", $"pass:{subjectId}:{id}");
+                        var value_pow = await _azureRedis.GetRedisClient(8).HashGetAsync($"ArtSchool:pow:{code}", $"pow:{subjectId}:{id}");
+                        var value_blks = await _azureRedis.GetRedisClient(8).HashGetAsync($"ArtSchool:blk:{code}", $"blk:{subjectId}:{id}");
+                        var value_kno = await _azureRedis.GetRedisClient(8).HashGetAsync($"ArtSchool:kno:{code}", $"kno:{subjectId}:{id}");
+                        var value_dim = await _azureRedis.GetRedisClient(8).HashGetAsync($"ArtSchool:dim:{code}", $"dim:{subjectId}:{id}");
+                        var value_optCount = await _azureRedis.GetRedisClient(8).HashGetAsync($"ArtSchool:optCount:{code}", $"optCount:{subjectId}:{id}");
+                        var value_scount = await _azureRedis.GetRedisClient(8).HashGetAsync($"ArtSchool:scount:{code}", $"scount:{subjectId}:{id}");
+
+                        var count_1 = value_count.ToString().ToObject<JsonElement>();
+                        var scount_1 = value_scount.ToString().ToObject<JsonElement>();
+                        var max_1 = value_max.ToString().ToObject<JsonElement>();
+                        var min_1 = value_min.ToString().ToObject<JsonElement>();
+                        var average_1 = value_average.ToString().ToObject<JsonElement>();
+                        var excellent_1 = value_excellent.ToString().ToObject<JsonElement>();
+                        var pass_1 = value_pass.ToString().ToObject<JsonElement>();
+                        var pow_1 = value_pow.ToString().ToObject<JsonElement>();
+                        var blk_1 = value_blks.ToString().ToObject<JsonElement>();
+                        var kno_1 = value_kno.ToString().ToObject<JsonElement>();
+                        var dim_1 = value_dim.ToString().ToObject<JsonElement>();
+                        var optCount_1 = value_optCount.ToString().ToObject<JsonElement>();
+                        var cInfo_1 = value.ToString().ToObject<JsonElement>();
+                        return Ok(new
+                        {
+                            count = count_1,
+                            scount = scount_1,
+                            max = max_1,
+                            min = min_1,
+                            average = average_1,
+                            excellent = excellent_1,
+                            pass = pass_1,
+                            pow = pow_1,
+                            blk = blk_1,
+                            kno = kno_1,
+                            dim = dim_1,
+                            optCount = optCount_1,
+                            cInfo = cInfo_1
+                        });
+                    }
+                }
+
                 if (!request.TryGetProperty("areaId", out JsonElement _areaId)) return BadRequest();
                 ArtSetting setting = await client.GetContainer(Constant.TEAMModelOS, "Normal").ReadItemAsync<ArtSetting>($"{_areaId}", partitionKey: new PartitionKey("ArtSetting"));
                 //学校基本信息
@@ -125,6 +283,7 @@ namespace TEAMModelOS.Controllers.Analysis
                         }
                     }
                 }
+
                 var subjectScore = new
                 {
                     name = As.Where(a => a.subjectId.Equals(subjectId.GetString())).Select(x => x.score).Where(c => c > 0)
@@ -152,7 +311,7 @@ namespace TEAMModelOS.Controllers.Analysis
                 {
                     classResults.Add(item);
                 }
-                (List<RMember> tchList, List<RGroupList> classLists) = await GroupListService.GetMemberByListids(_coreAPIHttpService, client, _dingDing, classIds, code.GetString(), null,-1,info.startTime);
+                (List<RMember> tchList, List<RGroupList> classLists) = await GroupListService.GetMemberByListids(_coreAPIHttpService, client, _dingDing, classIds, code.GetString(), null, -1, info.startTime);
                 //获取评测ID
                 //var examId = arts[0].settings.SelectMany(s => s.task).Where(a => a.type == 1 && a.subject.Equals(subjectId.GetString())).FirstOrDefault().acId;
                 //根据科目标识获取科目ID以及知识块和知识点关系TODO 引用不同试卷时 获取知识点得差异
@@ -296,7 +455,7 @@ namespace TEAMModelOS.Controllers.Analysis
                             claDims.Add((claDim.Key, dimCScore, dimCPoint, dimm.dimension));
                         }
                     }
-                }              
+                }
 
                 var dim = setting.dimensions.Where(q => q.subjectBind.Equals(subjectId.GetString())).Select(x => new
                 {
@@ -306,7 +465,7 @@ namespace TEAMModelOS.Controllers.Analysis
                         persent =
                              blockScore.Where(z => z.name.Equals(c)).Sum(v => v.score) > 0 ?
                              blockScore.Where(z => z.name.Equals(c)).Sum(v => v.av) / blockScore.Where(z => z.name.Equals(c)).Sum(v => v.score) : 0
-                    }).Sum(o => o.persent) , 4)
+                    }).Sum(o => o.persent), 4)
                 });
 
 
@@ -316,8 +475,33 @@ namespace TEAMModelOS.Controllers.Analysis
                     persent = x.score,
                     block = knos.Where(v => null != v.kno && v.kno.Contains(x.name)).Select(x => x.name)
                 });
+
+                var stuInfo = stus.Select(c => new
+                {
+                    c.scs,
+                    c.sIds,
+                    c.cd
+                });
+
+                List<(string id, double score, string name, string classId, string className,string gradeId, List<(string kname, double persent, List<string> blok)> kno,
+                List<(string kname, double persent)> block, List<(string kname, double persent)> dim)> stuAsync = [];
+                await foreach (var ss in stuTask(stus, tchList, examResults, subjectId.GetString(), key6, knos, stuBlockScore, stuDims))
+                {
+                    stuAsync = ss.students;
+                }
+                var students = stuAsync.Select(c => new { 
+                    c.id,
+                    c.score,
+                    c.name,
+                    c.classId,
+                    c.className,
+                    c.gradeId,
+                    kno = c.kno.Select(x => new { name = x.kname,x.persent,x.blok}),
+                    block = c.block.Select(x => new { name = x.kname ,x.persent }),
+                    dim = c.dim.Select(x => new { name = x.kname, x.persent })
+                });
                 //学生信息
-                var students = stus.Select(s => new
+                /*var students = stus.Select(s => new
                 {
                     id = s.sIds,
                     s.scs.FirstOrDefault(x => !string.IsNullOrWhiteSpace(x.subjectId) && x.subjectId.Equals(subjectId.GetString()))?.score,
@@ -344,36 +528,40 @@ namespace TEAMModelOS.Controllers.Analysis
                         name = z.dim,
                         persent = z.point > 0 ? Math.Round(z.score / z.point, 4) : 0
                     })
-                });
-                List<(string cId, double sc, double max, double min, double excellent, double pass, double count)> clsInfo = new();
-                var cInfo = students.GroupBy(c => (c.classId, c.className)).Select(x => new
-                {
-                    id = x.Key.classId,
-                    name = x.Key.className,
-                    max = x.ToList().Where(p => p.score > 0).Select(z => z.score).ToList().Count > 0 ? x.ToList().Where(p => p.score > 0).Select(z => z.score).ToList().Max(s => Math.Abs((double)s)) : 0,
-                    min = x.ToList().Where(p => p.score > 0).Select(z => z.score).ToList().Count > 0 ? x.ToList().Where(p => p.score > 0).Select(z => z.score).ToList().Min(s => Math.Abs((double)s)) : 0,
-                    excellent = x.ToList().Where(p => p.score > 0).Select(z => z.score).ToList().Count > 0 ? Math.Round(x.ToList().Where(p => p.score > 0).Select(z => z.score).ToList().Where(s => s >= 80).Count() * 1.0 / x.ToList().Count, 4) : 0,
-                    pass = x.ToList().Where(p => p.score > 0).Select(z => z.score).ToList().Count > 0 ? Math.Round(x.ToList().Where(p => p.score > 0).Select(z => z.score).ToList().Where(s => s >= 60).Count() * 1.0 / x.ToList().Count, 4) : 0,
-                    score = x.ToList().Count > 0 ? Math.Round((double)x.ToList().Sum(z => z.score) * 1.0 / x.ToList().Count, 2) : 0,
-                    persent = x.ToList().Count > 0 ? Math.Round((double)x.ToList().Sum(z => z.score) * 1.0 / x.ToList().Count / key7.Value, 4) : 0,
-                    kno = key5.Value.Where(c => c.cId.Equals(x.Key.classId)).Select(z => new
-                    {
-                        z.name,
-                        persent = Math.Round(z.point > 0 ? z.score / z.point : 0, 4),
-                        block = knos.Where(v => null != v.kno && v.kno.Contains(z.name)).Select(x => x.name)
-                    }),
-                    block = claBlock.Count() > 0 ? claBlock.Where(c => c.Key.Equals(x.Key.classId))?.FirstOrDefault().block.Select(z => new
+                });*/
+                //List<(string cId, double sc, double max, double min, double excellent, double pass, double count)> clsInfo = new();
+                    var cInfo = students.GroupBy(c => (c.classId, c.className)).Select(x => new
                     {
-                        name = z.Key,
-                        persent = Math.Round(z.point > 0 ? z.score / z.point : 0, 4)
-                    }) : null,
-                    dim = claDims.Where(c => c.claId.Equals(x.Key.classId)).Select(z => new
-                    {
-                        name = z.dim,
-                        persent = Math.Round(z.point > 0 ? z.score / z.point : 0, 4)
-                    }),
-                    examResults[0].classes.Where(c => c.id.Equals(x.Key.classId))?.FirstOrDefault().gradeId
-                });
+                        id = x.Key.classId,
+                        name = x.Key.className,
+                        max = x.ToList().Where(p => p.score > 0).Select(z => z.score).ToList().Count > 0 ? x.ToList().Where(p => p.score > 0).Select(z => z.score).ToList().Max(s => Math.Abs((double)s)) : 0,
+                        min = x.ToList().Where(p => p.score > 0).Select(z => z.score).ToList().Count > 0 ? x.ToList().Where(p => p.score > 0).Select(z => z.score).ToList().Min(s => Math.Abs((double)s)) : 0,
+                        excellent = x.ToList().Where(p => p.score > 0).Select(z => z.score).ToList().Count > 0 ? Math.Round(x.ToList().Where(p => p.score > 0).Select(z => z.score).ToList().Where(s => s >= 80).Count() * 1.0 / x.ToList().Count, 4) : 0,
+                        pass = x.ToList().Where(p => p.score > 0).Select(z => z.score).ToList().Count > 0 ? Math.Round(x.ToList().Where(p => p.score > 0).Select(z => z.score).ToList().Where(s => s >= 60).Count() * 1.0 / x.ToList().Count, 4) : 0,
+                        score = x.ToList().Count > 0 ? Math.Round((double)x.ToList().Sum(z => z.score) * 1.0 / x.ToList().Count, 2) : 0,
+                        persent = x.ToList().Count > 0 ? Math.Round((double)x.ToList().Sum(z => z.score) * 1.0 / x.ToList().Count / key7.Value, 4) : 0,
+                        kno = key5.Value.Where(c => c.cId.Equals(x.Key.classId)).Select(z => new
+                        {
+                            z.name,
+                            persent = Math.Round(z.point > 0 ? z.score / z.point : 0, 4),
+                            block = knos.Where(v => null != v.kno && v.kno.Contains(z.name)).Select(x => x.name)
+                        }),
+                        block = claBlock.Count() > 0 ? claBlock.Where(c => c.Key.Equals(x.Key.classId))?.FirstOrDefault().block.Select(z => new
+                        {
+                            name = z.Key,
+                            persent = Math.Round(z.point > 0 ? z.score / z.point : 0, 4)
+                        }) : null,
+                        dim = claDims.Where(c => c.claId.Equals(x.Key.classId)).Select(z => new
+                        {
+                            name = z.dim,
+                            persent = Math.Round(z.point > 0 ? z.score / z.point : 0, 4)
+                        }),
+                        examResults[0].classes.Where(c => c.id.Equals(x.Key.classId))?.FirstOrDefault().gradeId
+                    });
+
+                
+                
+
                 //年级信息
                 var grades = students.GroupBy(c => c.gradeId).Select(x => new { gradeId = x.Key, list = x.ToList().Select(v => v.score).Where(c => c > 0) });
                 var gscore = grades.Select(x => new
@@ -418,17 +606,37 @@ namespace TEAMModelOS.Controllers.Analysis
                      url = _azureStorage.GetBlobContainerClient($"{code}").GetBlobClient($"/art/{id}/{subjectId}.json").Uri.ToString();
                  }*/
                 var realCount = stus.Count - info.lostStu.Count;
+                await _azureRedis.GetRedisClient(8).HashSetAsync($"ArtSchool:count:{code}", $"count:{subjectId}:{id}", tchList.Count.ToJsonString());                
+                await _azureRedis.GetRedisClient(8).HashSetAsync($"ArtSchool:max:{code}", $"max:{subjectId}:{id}", max.ToJsonString());
+                await _azureRedis.GetRedisClient(8).HashSetAsync($"ArtSchool:min:{code}", $"min:{subjectId}:{id}", min.ToJsonString());
+                await _azureRedis.GetRedisClient(8).HashSetAsync($"ArtSchool:average:{code}", $"average:{subjectId}:{id}", average.ToJsonString());
+                await _azureRedis.GetRedisClient(8).HashSetAsync($"ArtSchool:excellent:{code}", $"excellent:{subjectId}:{id}", excellent.ToJsonString());
+                await _azureRedis.GetRedisClient(8).HashSetAsync($"ArtSchool:pass:{code}", $"pass:{subjectId}:{id}", pass.ToJsonString());
+                await _azureRedis.GetRedisClient(8).HashSetAsync($"ArtSchool:pow:{code}", $"pow:{subjectId}:{id}", pow.ToJsonString());
+                await _azureRedis.GetRedisClient(8).HashSetAsync($"ArtSchool:blk:{code}", $"blk:{subjectId}:{id}", blk.ToJsonString());
+                await _azureRedis.GetRedisClient(8).HashSetAsync($"ArtSchool:kno:{code}", $"kno:{subjectId}:{id}", kno.ToJsonString());
+                await _azureRedis.GetRedisClient(8).HashSetAsync($"ArtSchool:dim:{code}", $"dim:{subjectId}:{id}", dim.ToJsonString());
+                await _azureRedis.GetRedisClient(8).HashSetAsync($"ArtSchool:optCount:{code}", $"optCount:{subjectId}:{id}", optCount.ToJsonString());
                 if (classIds.Count == 1)
                 {
                     var realClassCount = classResults.Where(c => c.info.id.Equals(classIds[0])).SelectMany(z => z.status).Count(k => k == 0);
+                    await _azureRedis.GetRedisClient(8).HashSetAsync($"ArtSchool:realClassCount:{code}", $"realClassCount:{subjectId}:{id}", realClassCount);
+                    await _azureRedis.GetRedisClient(8).HashSetAsync($"ArtSchool:students:{code}:{classIds[0]}", $"students:{subjectId}:{id}", students.ToJsonString());
+                    await _azureRedis.GetRedisClient(8).HashSetAsync($"ArtSchool:gscore:{code}", $"gscore:{subjectId}:{id}", gscore.ToJsonString());
+                    await _azureRedis.GetRedisClient(8).HashSetAsync($"ArtSchool:cInfo:{code}:{classIds[0]}", $"cInfo:{subjectId}:{id}", cInfo.ToJsonString());
                     return Ok(new { count = tchList.Count, scount = realClassCount, max, min, average, excellent, pass, pow, blk, kno, dim, optCount, students, cInfo, gscore });
                 }
                 else if (classIds.Count == 0)
                 {
+                    await _azureRedis.GetRedisClient(8).HashSetAsync($"ArtSchool:scount:{code}", $"scount:{subjectId}:{id}", realCount);
+                    await _azureRedis.GetRedisClient(8).HashSetAsync($"ArtSchool:grade:{code}", $"grade:{subjectId}:{id}", "true");
                     return Ok(new { count = tchList.Count, scount = realCount, max, min, average, excellent, pass, pow, blk, kno, dim, optCount });
                 }
-                else {
-                    return Ok(new { count = tchList.Count, scount = realCount, max, min, average, excellent, pass, pow, blk, kno, dim, optCount,cInfo });
+                else
+                {
+                    await _azureRedis.GetRedisClient(8).HashSetAsync($"ArtSchool:scount:{code}", $"scount:{subjectId}:{id}", realCount);
+                    await _azureRedis.GetRedisClient(8).HashSetAsync($"ArtSchool:cInfo:{code}", $"cInfo:{subjectId}:{id}", cInfo.ToJsonString());
+                    return Ok(new { count = tchList.Count, scount = realCount, max, min, average, excellent, pass, pow, blk, kno, dim, optCount, cInfo});
                 }
                 //return Ok(new { count = tchList.Count, scount = realCount, max, min, average, excellent, pass, pow, blk, kno, dim, optCount, gscore });
             }
@@ -438,6 +646,105 @@ namespace TEAMModelOS.Controllers.Analysis
             }
         }
 
+        private async IAsyncEnumerable<(List<(string id, double score, string name, string classId,string className, string gradeId, List<(string kname, double persent, List<string> blok)> kno,
+                List<(string kname, double persent)> block, List<(string kname, double persent)> dim)> students,int code)> stuTask(List<(List<ArtSubjectScore> scs, string sIds, string cd)> stus, List<RMember> tchList, List<ExamResult> examResults, string subjectId,
+            KeyValuePair<string, List<(string name, double score, double point, string sId)>> key6, List<(string name, List<string> kno)> knos, List<(string name, double score, double av, string sId)> stuBlockScore,
+            List<(string stuId, double score, double point, string dim)> stuDims)
+        {
+
+            var stuBlock = stuBlockScore.GroupBy(x => x.sId).Select(z => new
+            {
+                z.Key,
+                block = z.ToList().GroupBy(c => c.name).Select(k => new
+                {
+                    k.Key,
+                    score = k.ToList().Sum(p => p.score),
+                    point = k.ToList().Sum(p => p.av)
+                })
+            });
+            List<(string id, double score,string name, string cId,string className, string gradeId, List<(string kname, double persent, List<string> blok)> kno,
+                List<(string kname, double persent)> block, List<(string kname, double persent)> dim)> students = new();
+            int code = 200;
+            foreach (var item in stus)
+            {
+                try {
+                    string id = item.sIds;
+                    double score = item.scs.Where(c => !string.IsNullOrWhiteSpace(c.subjectId) && c.subjectId.Equals(subjectId)).FirstOrDefault().score;
+                    string name = tchList.Where(t => t.id.Equals(item.sIds)).FirstOrDefault()?.name;
+                    string classId = item.cd;
+                    string className = examResults[0].classes.Where(c => c.id.Equals(item.cd)).FirstOrDefault()?.name;
+                    string gradeId = examResults[0].classes.Where(c => c.id.Equals(item.cd)).FirstOrDefault()?.gradeId;
+                    List<(string kname, double persent, List<string> blok)> kno = [];
+                    List<(string kname, double persent)> block = [];
+                    List<(string kname, double persent)> dim = [];
+                    var k =  key6.Value.Where(c => c.sId.Equals(item.sIds))?.Select(z => new
+                    {
+                        z.name,
+                        persent = z.point > 0 ? Math.Round(z.score / z.point, 4) : 0,
+                        block = knos.Where(v => null != v.kno && v.kno.Contains(z.name))?.Select(x => x.name).ToList(),
+                    });
+                    foreach (var kk in k) {
+                        kno.Add((kk.name,kk.persent,kk.block));
+                    }
+                    var b = stuBlock.Where(c => c.Key.Equals(item.sIds)).FirstOrDefault()?.block.Select(x => new
+                    {
+                        name = x.Key,
+                        persent = x.point > 0 ? Math.Round(x.score / x.point, 4) : 0
+                    });
+                    foreach (var bb in b) {
+                        block.Add((bb.name, bb.persent));
+                    }
+                    var c = stuDims.Where(c => c.stuId.Equals(item.sIds))?.Select(z => new
+                    {
+                        name = z.dim,
+                        persent = z.point > 0 ? Math.Round(z.score / z.point, 4) : 0
+                    });
+                    foreach (var cc in c)
+                    {
+                        dim.Add((cc.name, cc.persent));
+                    }
+
+                    students.Add((id, score, name, classId, className,gradeId, kno, block, dim));
+
+                }
+                catch (Exception e) {
+                    code = 500;
+                }
+               
+
+                yield return (students,code);
+            }
+            /*var students = stus.Select(s => new
+            {
+                id = s.sIds,
+                s.scs.FirstOrDefault(x => !string.IsNullOrWhiteSpace(x.subjectId) && x.subjectId.Equals(subjectId))?.score,
+                tchList.Where(t => t.id.Equals(s.sIds)).FirstOrDefault()?.name,
+                classId = s.cd,
+                className = examResults[0].classes.Where(c => c.id.Equals(s.cd)).FirstOrDefault()?.name,
+                examResults[0].classes.Where(c => c.id.Equals(s.cd)).FirstOrDefault()?.gradeId,
+                //key.Value.Where(c => c.id.Equals(s.sIds))?.FirstOrDefault().sta,
+                //key.Value.Where(c => c.id.Equals(s.sIds))?.FirstOrDefault().pass,
+                // key.Value.Where(c => c.id.Equals(s.sIds))?.FirstOrDefault().stu,
+                kno = key6.Value.Where(c => c.sId.Equals(s.sIds))?.Select(z => new
+                {
+                    z.name,
+                    persent = z.point > 0 ? Math.Round(z.score / z.point, 4) : 0,
+                    block = knos.Where(v => null != v.kno && v.kno.Contains(z.name))?.Select(x => x.name)
+                }),
+                block = stuBlock.Where(c => c.Key.Equals(s.sIds)).FirstOrDefault()?.block.Select(x => new
+                {
+                    name = x.Key,
+                    persent = x.point > 0 ? Math.Round(x.score / x.point, 4) : 0
+                }),
+                dim = stuDims.Where(c => c.stuId.Equals(s.sIds))?.Select(z => new
+                {
+                    name = z.dim,
+                    persent = z.point > 0 ? Math.Round(z.score / z.point, 4) : 0
+                })
+            });*/
+
+        }
+
         private static async Task<(string subId, List<(string name, List<string> kno)>)> getKnowledge(string school, CosmosClient client, string subjectBid, string pId)
         {
             try
@@ -446,7 +753,7 @@ namespace TEAMModelOS.Controllers.Analysis
                 string subjectId = string.Empty;
                 List<Knowledge> knowledges = new();
                 List<(string name, List<string> kno)> blocks = new();
-                if (response.StatusCode==System.Net.HttpStatusCode.OK)
+                if (response.StatusCode == System.Net.HttpStatusCode.OK)
                 {
                     using var json = await JsonDocument.ParseAsync(response.Content);
                     School sc = json.ToObject<School>();
@@ -525,7 +832,7 @@ namespace TEAMModelOS.Controllers.Analysis
             }
             else
             {
-                return (default, default, default, default, default, default,default);
+                return (default, default, default, default, default, default, default);
             }
             point = info.papers[index].point;
             result = exam.studentScores;
@@ -571,7 +878,8 @@ namespace TEAMModelOS.Controllers.Analysis
                     {
                         var itemPersent = kno.Count > 0 ? 1 / Convert.ToDouble(kno.Count) : 0;
                         OnePoint += point[n] * itemPersent;
-                        foreach (string id in exam.studentIds) {
+                        foreach (string id in exam.studentIds)
+                        {
                             int stuIndex = exam.studentIds.IndexOf(id);
                             scores += exam.studentScores[stuIndex][n] * itemPersent;
                         }
@@ -587,12 +895,12 @@ namespace TEAMModelOS.Controllers.Analysis
                     {
                         if (kno.Contains(knowledgeName[k]))
                         {
-                            var itemPersent = kno.Count > 0 ? 1 / Convert.ToDouble(kno.Count) : 0;                           
+                            var itemPersent = kno.Count > 0 ? 1 / Convert.ToDouble(kno.Count) : 0;
                             stuScore += exam.studentScores[stuIndex][a] * itemPersent;
-                            
+
                         }
                         a++;
-                    });                                    
+                    });
                     stuInfo.Add((knowledgeName[k], stuScore, OnePoint, id));
                 }
 
@@ -611,7 +919,7 @@ namespace TEAMModelOS.Controllers.Analysis
                             }
                         }
                         b++;
-                    });                    
+                    });
                     classInfo.Add((knowledgeName[k], classScores, OnePoint, cla.id));
                 }
                 Score.Add(scores);
@@ -641,7 +949,7 @@ namespace TEAMModelOS.Controllers.Analysis
             KeyValuePair<string, List<(string name, double score, double point, string sId)>> key6 = new(exam.subjectId, stuInfo);
             KeyValuePair<string, double> key7 = new(exam.subjectId, TotalPoint);
             //KeyValuePair<string, List<double>> key3 = new KeyValuePair<string, List<double>>(exam.subjectId, allPer);          
-            return (key1, key2, key3, key4, key5, key6,key7);
+            return (key1, key2, key3, key4, key5, key6, key7);
         }
         private KeyValuePair<string, List<(string id, double sta, double pass, string stu)>> DoSubjectScatter(ExamResult e)
         {

+ 2 - 2
TEAMModelOS/Controllers/Common/ExamController.cs

@@ -898,9 +898,9 @@ namespace TEAMModelOS.Controllers
 
 
         [ProducesDefaultResponseType]
-
-        [AuthToken(Roles = "teacher,admin,student")]
 #if !DEBUG
+        [AuthToken(Roles = "teacher,admin,student")]
+
         [Authorize(Roles = "IES")]
 #endif
         [HttpPost("find-by-analysis")]