zhouj1203@hotmail.com 4 лет назад
Родитель
Сommit
f64e45a926

+ 32 - 0
TEAMModelOS.SDK/Models/Cosmos/School/ClassAnalysis.cs

@@ -0,0 +1,32 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace TEAMModelOS.SDK.Models.Cosmos.School
+{
+    public class ClassAnalysis
+    {
+        public ClassAnalysis()
+        {
+            subjects = new List<SubjectScore>();
+            total = new List<double>();
+        }
+        public int stuCount { get; set; }
+        public int lineCount { get; set; }
+        public List<SubjectScore> subjects { get; set; }
+        public string classId { get; set; }
+        public List<double> total { get; set; }
+        public double  totalAverage { get; set; }
+        public double standardDeviation { get; set; }
+        public class SubjectScore {
+            public SubjectScore() {
+                passPersent = new List<double>();
+                averageScore = new List<double>();
+            }
+            public string id { get; set; }
+            public List<double> passPersent { get; set; }
+            public List<double> averageScore { get; set; }
+
+        }
+    }
+}

+ 1 - 0
TEAMModelOS.SDK/Models/Cosmos/School/ExamResult.cs

@@ -19,6 +19,7 @@ namespace TEAMModelOS.SDK.Models
             studentScores = new List<List<double>>();
             studentIds = new List<string>();
             point = new List<double>();
+            paper = new PaperSimple();
         }
         
         public string name { get; set; }

+ 34 - 0
TEAMModelOS.SDK/Models/Cosmos/School/GradeAnalysis.cs

@@ -0,0 +1,34 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace TEAMModelOS.SDK.Models.Cosmos.School
+{
+    public class GradeAnalysis
+    {
+        public GradeAnalysis()
+        {
+            subjects = new List<GradeSubjectScore>();
+            passPersent = new List<double>();
+        }
+        //public List<string> subjectId { get; set; }
+        public string gradeId { get; set; }
+        public List<double> passPersent { get; set; }
+
+        public List<double> averageScore { get; set; }
+
+        public double GradeaverageScore { get; set; }
+        public List<GradeSubjectScore> subjects { get; set; }
+        public class GradeSubjectScore
+        {
+            public GradeSubjectScore() {
+                passPersent = new List<double>();
+                averageScore = new List<double>();
+            }
+            public string id { get; set; }
+            public List<double> passPersent { get; set; }
+            public List<double> averageScore { get; set; }
+
+        }
+    }
+}

+ 34 - 0
TEAMModelOS.SDK/Models/Cosmos/Student/StudentAnalysis.cs

@@ -0,0 +1,34 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace TEAMModelOS.SDK.Models.Cosmos.Student
+{
+   public  class StudentAnalysis
+    {
+        public StudentAnalysis() {
+            ids = new List<string>();
+            scores = new List<Score>();
+            gpr = new List<double>();
+            cpr = new List<double>();
+            total = new List<double>();
+        }
+        public List<string> ids { get; set; }
+        public List<double> gpr { get; set; }
+        public List<double> cpr { get; set; }
+        public List<Score> scores { get; set; }
+        public List<double> total { get; set; }
+        public class Score {
+            public Score() {
+                sc = new List<double>();
+                cdpr = new List<double>();
+                gdpr = new List<double>();
+            }
+            public string subjectId { get; set; }
+            public List<double> sc { get; set; }
+            public List<double> cdpr { get; set; }
+            public List<double> gdpr { get; set; }
+        }
+       
+    }
+}

+ 309 - 3
TEAMModelOS/Controllers/Analysis/AchievementController.cs

@@ -14,21 +14,32 @@ using TEAMModelOS.SDK.Helper.Common.CollectionHelper;
 using TEAMModelOS.SDK.Helper.Common.StringHelper;
 using TEAMModelOS.SDK.Helper.Security.ShaHash;
 using TEAMModelOS.Services.Analysis;
+using Microsoft.Extensions.Options;
+using TEAMModelOS.Models;
+using Azure.Cosmos;
+using TEAMModelOS.SDK.Models.Cosmos.Student;
+using static TEAMModelOS.SDK.Models.Cosmos.Student.StudentAnalysis;
+using TEAMModelOS.SDK.Models.Cosmos.School;
+using static TEAMModelOS.SDK.Models.Cosmos.School.ClassAnalysis;
+using static TEAMModelOS.SDK.Models.Cosmos.School.GradeAnalysis;
 
 namespace TEAMModelOS.Controllers.Analysis
 {
-    [Route("api/[controller]")]
+    [Route("analysis")]
     [ApiController]
     public class AchievementController : Controller
     {
 
         private readonly AzureCosmosFactory _azureCosmos;
-
+        private readonly DingDing _dingDing;
+        private readonly Option _option;
         private const string CacheCosmosPrefix = "Analysis:";
         private const int timeoutSeconds = 3600;
-        public AchievementController(AzureCosmosFactory azureCosmos)
+        public AchievementController(AzureCosmosFactory azureCosmos, DingDing dingDing, IOptionsSnapshot<Option> option)
         {
             _azureCosmos = azureCosmos;
+            _dingDing = dingDing;
+            _option = option?.Value;
 
 
         }
@@ -2209,5 +2220,300 @@ namespace TEAMModelOS.Controllers.Analysis
             //       throw new BizException(e.Message);
             //   }
         }
+
+        [HttpPost("getAnalysis")]
+        public async Task<IActionResult> getAnalysis(JsonElement request) {
+            //获取评测的ID
+            if (!request.TryGetProperty("id", out JsonElement id)) return BadRequest();
+            if (!request.TryGetProperty("code", out JsonElement code)) return BadRequest();
+            try {
+                var client = _azureCosmos.GetCosmosClient();
+                //获取本次评测所有科目结算结果
+                ExamInfo info = await client.GetContainer("TEAMModelOS", "Common").ReadItemAsync<ExamInfo>(id.ToString(), new PartitionKey($"Exam-{code}"));
+                School school = await client.GetContainer("TEAMModelOS", "School").ReadItemAsync<School>(code.ToString(), new PartitionKey($"Base"));
+                List<ExamResult> examResults = new List<ExamResult>();
+                var query = $"select c.id,c.name,c.subjectId,c.studentScores,c.studentIds,c.paper from c where c.examId =  '{id}' ";
+                await foreach (var item in client.GetContainer("TEAMModelOS", "Common").GetItemQueryIterator<ExamResult>(queryText: query, requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"ExamResult-{id}") }))
+                {
+                    /*using var json = await JsonDocument.ParseAsync(item.ContentStream);
+                    if (json.RootElement.TryGetProperty("_count", out JsonElement count) && count.GetUInt16() > 0)
+                    {
+                        foreach (var obj in json.RootElement.GetProperty("Documents").EnumerateArray())
+                        {
+                            examResults.Add(obj.ToObject<ExamResult>());
+                        }
+                    }*/
+                    examResults.Add(item);
+                }
+                //获取本次评测所有班级作答结果
+                List<ExamClassResult> examClassResults = new List<ExamClassResult>();
+                var queryClass = $"select c.id,c.name,c.subjectId,c.studentScores,c.studentIds,c.gradeId,c.info from c where c.examId =  '{id}' and c.progress = true ";
+                await foreach (var item in client.GetContainer("TEAMModelOS", "Common").GetItemQueryIterator<ExamClassResult>(queryText: queryClass, requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"ExamClassResult-{code}") }))
+                {
+                    examClassResults.Add(item);
+                    /*using var json = await JsonDocument.ParseAsync(item.ContentStream);
+                    if (json.RootElement.TryGetProperty("_count", out JsonElement count) && count.GetUInt16() > 0)
+                    {
+                        foreach (var obj in json.RootElement.GetProperty("Documents").EnumerateArray())
+                        {
+                            examClassResults.Add(obj.ToObject<ExamClassResult>());
+                        }
+                    }*/
+                }
+                //获取进线标准
+                int touch = 0;
+                foreach (Period period in school.period) {
+                    if (info.period.id.Equals(period.id)) {
+                        touch = period.analysis.touch;
+                    }
+                }
+                //获取进线人数
+                int personCount = (int)System.Math.Round( (double)info.stuCount * (touch / 100), 1 ,MidpointRounding.AwayFromZero);
+                
+                StudentAnalysis analysis = new StudentAnalysis();
+                List<ClassAnalysis> classAnalyses = new List<ClassAnalysis>();
+                //以班级为单位
+                List<double> stuTotals = new List<double>();
+                foreach (string s in info.targetClassIds) {
+                    //声明班级所有科目总分
+                    double total = 0;
+                    //存放每个班级学生总分
+                    List<double> totalClass = new List<double>();
+                    ClassAnalysis classAnalysis = new ClassAnalysis();
+                    classAnalysis.classId = s;
+                    var sresponse = await client.GetContainer("TEAMModelOS", "School").ReadItemStreamAsync(s, new PartitionKey($"Class-{code}"));
+                    if (sresponse.Status == 200)
+                    {
+                        using var json = await JsonDocument.ParseAsync(sresponse.ContentStream);
+                        Class classroom = json.ToObject<Class>();
+                        classAnalysis.stuCount = classroom.students.Count;
+                        foreach (StudentSimple stu in classroom.students)
+                        {
+                            analysis.ids.Add(stu.id);
+                            //计算学生多科考试成绩总分
+                            double stuTotal = 0;
+                            foreach (ExamResult examResult in examResults)
+                            {
+                                int index = examResult.studentIds.IndexOf(stu.id);
+                                stuTotal = stuTotal + examResult.studentScores[index].Sum();
+                            }
+                            classAnalysis.total.Add(stuTotal);
+                            analysis.total.Add(stuTotal);
+                            stuTotals.Add(stuTotal);
+                            totalClass.Add(stuTotal);
+                        }
+                    }
+                    /* //声明单个班级单科总分
+                     double subjectTotal = 0;*/
+                    info.subjects.ForEach(sub => {
+                        //初始化及格人数
+                        int i = 0;
+                        //初始化单科总分
+                        double sumClass = 0;
+                        //记录每个科目数据
+                        SubjectScore subjectScore = new SubjectScore();
+                        subjectScore.id = sub.id;
+                        double subjectSum = 0;
+                        double passScore = 0;
+                        //计算单科评测总分
+                        foreach (ExamResult examResult in examResults)
+                        {
+                            if (sub.id.Equals(examResult.subjectId))
+                            {
+                                subjectSum = examResult.paper.point.Sum();
+                            }
+                        }
+                        //单科及格率分数
+                        passScore = subjectSum * 0.6;
+                        //存放学生单科记录
+                        Score score = new Score();
+                        score.subjectId = sub.id;
+                        List<double> subjectTotal = new List<double>();
+                        //处理每个班级各个学生各科总分
+                        foreach (ExamClassResult result in examClassResults)
+                        {
+                            if (sub.id.Equals(result.subjectId) && s.Equals(result.info.id))
+                            {
+                                foreach (List<double> scores in result.studentScores)
+                                {
+                                    //添加每个学生各科总分
+                                    score.sc.Add(scores.Sum());
+                                    //计算大于及格分数的人数
+                                    if (scores.Sum() >= passScore)
+                                    {
+                                        i++;
+                                    }
+                                    //totalClass.Add(scores.Sum());
+                                    subjectTotal.Add(scores.Sum());
+                                    sumClass = sumClass + scores.Sum();
+
+                                }
+                                //处理班级及格率以及均分
+                                double persentClass = i / result.studentIds.Count;
+                                double averageClass = sumClass / result.studentIds.Count;
+                                total += averageClass;
+                                subjectScore.passPersent.Add(persentClass);
+                                subjectScore.averageScore.Add(averageClass);
+                                classAnalysis.subjects.Add(subjectScore);
+                                //analysis.scores.Add(score);
+                            }
+                        }
+                        //处理单科科班级PR
+                        subjectTotal.Sort(delegate (double s1, double s2) { return s2.CompareTo(s1); });
+                        foreach (double sc in score.sc)
+                        {
+                            int index = subjectTotal.IndexOf(sc);
+                            double CPR = 100 - (100 * (index + 1) - 50) / score.sc.Count;
+                            score.cdpr.Add(CPR);
+
+                        }
+                        analysis.scores.Add(score);
+                    });
+                    //处理全科班级PR
+                    totalClass.Sort(delegate (double s1, double s2) { return s2.CompareTo(s1); });
+                    foreach (double pr in classAnalysis.total)
+                    {
+                        int index = totalClass.IndexOf(pr);
+                        double CPR = 100 - (100 * (index + 1) - 50) / classAnalysis.total.Count;
+                        analysis.cpr.Add(CPR);
+                    }
+                    classAnalyses.Add(classAnalysis);
+                }
+                /*info.targetClassIds.ForEach( async s => {
+                    
+                });*/
+                //初始化进线分数
+                double ipoint = 0;
+                stuTotals.Sort(delegate (double s1, double s2) { return s2.CompareTo(s1); });
+                ipoint = stuTotals[personCount];
+                //补充班级总平均分/进行人数/标准差
+                foreach (ClassAnalysis classAnalysis in classAnalyses) {
+                    //初始化进线人数
+                    int i = 0;
+                    //初始化班级总分
+                    double score = 0;
+                    //标准差
+                    double powSum = 0;
+                    foreach (double sc in classAnalysis.total) {
+                        if (sc > ipoint) {
+                            i++;
+                        }
+                        score = score + sc;                       
+                    }
+                    //总平均分
+                    double totalAverage = 0;
+                    totalAverage = score / classAnalysis.stuCount;
+                    //计算标准差
+                    foreach (double sc in classAnalysis.total)
+                    {
+                        powSum += Math.Pow(sc - totalAverage, 2);
+                    }
+                    
+                    var pow = Math.Pow(powSum / classAnalysis.stuCount, 0.5);
+
+                    classAnalysis.standardDeviation = pow;
+                    classAnalysis.totalAverage = totalAverage;
+                    classAnalysis.lineCount = i;
+                }
+                //处理全科年级PR值
+                foreach (double no in analysis.total) {
+                    int index = stuTotals.IndexOf(no);
+                    int GPR = 100 - (100 * (index+1) - 50) / analysis.total.Count;
+                    analysis.gpr.Add(GPR);
+                }
+                List<GradeAnalysis> gradeAnalyses = new List<GradeAnalysis>();
+                if (info.grades.Count > 0) {
+                    gradeAnalyses = GetGradeAnalyses(info, examResults, examClassResults, analysis);
+                }                              
+                return Ok(new { analysis, classAnalyses, gradeAnalyses });
+            } catch (Exception e) {
+                await _dingDing.SendBotMsg($"OS,{_option.Location},analysis/getAnalysis()\n{e.Message}", GroupNames.醍摩豆服務運維群組);
+                return BadRequest();
+            }
+
+        
+        }
+        private List<GradeAnalysis> GetGradeAnalyses(ExamInfo info, List<ExamResult> examResults, List<ExamClassResult> examClassResults,StudentAnalysis analysis) {
+            List<GradeAnalysis> gradeAnalyses = new List<GradeAnalysis>();
+            info.grades.ForEach(g => {
+                GradeAnalysis gradeAnalysis = new GradeAnalysis();
+                gradeAnalysis.gradeId = g.id;
+                //初始化单个年级总分
+                double gradeScore = 0;
+                info.subjects.ForEach(sub =>
+                {
+                    //初始化及格人数
+                    int i = 0;
+                    //初始化年级人数
+                    int count = 0;
+                    //初始化单科总分
+                    double sumClass = 0;
+                    //记录每个科目数据
+                    GradeSubjectScore subjectScore = new GradeSubjectScore();
+                    subjectScore.id = sub.id;
+                    double subjectSum = 0;
+                    double passScore = 0;
+                    //计算单科评测总分
+                    foreach (ExamResult examResult in examResults)
+                    {
+                        if (sub.id.Equals(examResult.subjectId))
+                        {
+                            subjectSum = examResult.paper.point.Sum();
+                        }
+                    }
+                    //单科及格率分数
+                    passScore = subjectSum * 0.6;
+                    //存放学生单科记录
+                    Score score = new Score();
+                    List<double> subjectTotal = new List<double>();
+                    //存放单科每个班级学生总分
+                    List<double> totalClass = new List<double>();
+                    //处理每个班级各个学生各科总分
+                    foreach (ExamClassResult result in examClassResults)
+                    {
+                        if (sub.id.Equals(result.subjectId) && g.id.Equals(result.gradeId))
+                        {
+                            foreach (List<double> scores in result.studentScores)
+                            {
+                                //添加每个学生各科总分
+                                score.sc.Add(scores.Sum());
+                                //计算大于及格分数的人数
+                                if (scores.Sum() >= passScore)
+                                {
+                                    i++;
+                                }
+                               subjectTotal.Add(scores.Sum());
+                               sumClass = sumClass + scores.Sum();
+
+                            }
+                            count += result.studentIds.Count;
+                        }
+                    }
+                    //处理班级及格率以及均分
+                    double persentClass = i / count;
+                    double averageClass = sumClass / count;
+                    gradeScore += averageClass;
+                    subjectScore.passPersent.Add(persentClass);
+                    subjectScore.averageScore.Add(averageClass);
+                    gradeAnalysis.subjects.Add(subjectScore);
+                    gradeAnalyses.Add(gradeAnalysis);
+                    //处理单科科年级PR
+                    subjectTotal.Sort(delegate (double s1, double s2) { return s2.CompareTo(s1); });
+                    foreach (double sc in score.sc)
+                    {
+                        int index = subjectTotal.IndexOf(sc);
+                        double GPR = 100 - (100 * (index + 1) - 50) / score.sc.Count;
+                        score.gdpr.Add(GPR);
+                        //analysis.gpr.Add(GPR);
+                    }
+                    analysis.scores.Add(score);
+
+                });
+                foreach (GradeAnalysis grade in gradeAnalyses) {
+                    grade.GradeaverageScore = gradeScore / grade.subjects.Count;
+                }
+                });
+            return gradeAnalyses;
+            }
     }
 }