瀏覽代碼

学情分析

CrazyIter_Bin 4 年之前
父節點
當前提交
6eba93eccd

+ 262 - 0
TEAMModelOS/Controllers/Analysis/AnalysisController.cs

@@ -0,0 +1,262 @@
+using ClouDASLibx;
+using Microsoft.AspNetCore.Mvc;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text.Json;
+using System.Threading.Tasks;
+using TEAMModelOS.SDK.Models;
+
+using TEAMModelOS.SDK;
+using TEAMModelOS.SDK.DI;
+using TEAMModelOS.SDK.Extension;
+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("analysis")]
+    [ApiController]
+    public class AnalysisController: ControllerBase
+    {
+        private readonly AzureCosmosFactory _azureCosmos;
+        private readonly DingDing _dingDing;
+        private readonly Option _option;
+        private const string CacheCosmosPrefix = "Analysis:";
+        private const int timeoutSeconds = 3600;
+        public AnalysisController(AzureCosmosFactory azureCosmos, DingDing dingDing, IOptionsSnapshot<Option> option)
+        {
+            _azureCosmos = azureCosmos;
+            _dingDing = dingDing;
+            _option = option?.Value;
+        }
+        [HttpPost("process")]
+        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();
+            List<StudentAys> students = new List<StudentAys>();
+            List<ClassAys> classes = new List<ClassAys>();
+            List<GradeAys> grades = new List<GradeAys>();
+            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,c.classes 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}") }))
+                {
+                    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);
+
+                }
+                //获取进线标准
+                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(info.stuCount * (touch / 100.0), MidpointRounding.AwayFromZero);
+
+                /* //声明年级所有科目总分
+                 List<double> total = new List<double>();*/
+              
+                List<ClassRange> classReses = null;
+                //按科目获取所有学生的分数
+                Dictionary<string, List<double>> subjectTotal = new Dictionary<string, List<double>>();
+                Dictionary<string, double> paperScore = new Dictionary<string, double>();
+                foreach (ExamResult examResult in examResults)
+                {
+                    //获取一张试卷的满分
+                    paperScore.Add(examResult.subjectId, examResult.paper.point.Sum());
+                    List<double> StuSubjectTotals = new List<double>();
+                    classReses = examResult.classes;
+                    //处理个人
+                    foreach (var stuid in examResult.studentIds)
+                    {
+                        StudentAys student = null;
+                        int index = examResult.studentIds.IndexOf(stuid);
+                        if (students.Select(x => x.id).Contains(stuid))
+                        {
+                            student = students[index];
+                        }
+                        else
+                        {
+                            student = new StudentAys() { id=stuid } ;
+                            students.Add(student);
+                        }
+                        var score = examResult.studentScores[index].Sum();
+                        student.total += score;
+                        StuSubjectTotals.Add(score);
+                        if (student.subjects.Select(x => x.id).Contains(examResult.subjectId))
+                        {
+                            student.subjects.ForEach(y =>
+                            {
+                                if (y.id.Equals(examResult.subjectId))
+                                {
+                                    y.score = score;
+                                }
+                            });
+                        }
+                        else
+                        {
+                            StudentSubject subject = new StudentSubject
+                            {
+                                id = examResult.subjectId,
+                                name = info.subjects.Where(x => x.id == examResult.subjectId).FirstOrDefault().name
+                            };
+                            subject.score = score;
+                            student.subjects.Add(subject);
+                        }
+                    }
+                    subjectTotal.Add(examResult.subjectId, StuSubjectTotals);
+                }
+                //以班级为单位
+                foreach (string classId in info.targetClassIds)
+                {
+                    Class classroom = null;
+                    var sresponse = await client.GetContainer("TEAMModelOS", "School").ReadItemStreamAsync(classId, new PartitionKey($"Class-{code}"));
+                    if (sresponse.Status == 200)
+                    {
+                        using var json = await JsonDocument.ParseAsync(sresponse.ContentStream);
+                        classroom = json.ToObject<Class>();
+                      
+                    }
+                    //处理班级
+                    var classRes = classReses.Where(x => x.id == classId).FirstOrDefault();
+                    var stuCount = classRes.range[1] - classRes.range[0] + 1;
+                    var classStudents = students.GetRange(classRes.range[0], classRes.range[1] - classRes.range[0] + 1);
+                    List<double> stuTotals = classStudents.Select(x=>x.total).ToList();
+                    stuTotals.Sort(delegate (double s1, double s2) { return s2.CompareTo(s1); });
+                    double ipoint = stuTotals[personCount];
+                    //初始化进线人数
+                    int lineCount = 0;
+                    //初始化班级总分
+                    double classTotal = stuTotals.Sum();
+                    //标准差
+                    double powSum = 0;
+                    //计算标准差
+                    //总平均分
+                    double totalAverage = 0;
+                    //获取整个班级 科目的分数情况
+                    List<KeyValuePair<string, double>> keyValues = new List<KeyValuePair<string, double>>();
+                    List<string> studentIds = new List<string>();
+                    classStudents.ForEach(x => {
+                        studentIds.Add(x.id);
+                        x.classId = classId;
+                        x.className = classroom.name;
+                        x.name = classroom.students.Where(s => x.id == x.id).First().name;
+                        //标准差
+                        powSum += Math.Pow(x.total - totalAverage, 2);
+                        //进线人数
+                        if (x.total > ipoint) { 
+                            lineCount++; 
+                        }
+                        //班级全科的pr
+                        int index = stuTotals.IndexOf(x.total);
+                        double CPR = 100 - (100 * (index + 1) - 50) / stuCount;
+                        x.cpr = CPR;
+                        //班级单科的pr
+                        x.subjects.ForEach(y=> {
+                            var subjectT= subjectTotal[y.id];
+                            subjectT.Sort(delegate (double s1, double s2) { return s2.CompareTo(s1); });
+                            int index = subjectT.IndexOf(y.score);
+                            double CPR = 100 - (100 * (index + 1) - 50) / stuCount;
+                            y.cpr = CPR;
+                            //按科目获取一个班的分数
+                            keyValues.Add(new KeyValuePair<string, double>(y.id, y.score));
+                        });
+                    });
+                    totalAverage = classTotal / stuCount;
+                    var pow = Math.Pow(powSum / stuCount, 0.5);
+                    ClassAys classAys = new ClassAys
+                    {
+                        gradeId = classroom.gradeId,
+                        studentIds = studentIds,
+                        stuCount = stuCount,
+                        classId = classId,
+                        className = classroom.name,
+                        totalAverage = totalAverage,
+                        lineCount = lineCount,
+                        standardDeviation = pow
+                    };
+                    foreach (var key in paperScore.Keys) {
+                        var subScore= keyValues.Where(x => x.Key.Equals(key)).Select(x=>x.Value).ToList();
+                        //计算及格率
+                        int passCount = 0;
+                        double passScore = paperScore[key] * 0.6;
+                        subScore.ForEach(x => {
+                            if (x > passScore) {
+                                passCount += 1;
+                            }
+                        });
+                        
+                        double passPercent = passCount * 1.0 / stuCount ;
+                        double average = subScore.Sum()* 1.0 / stuCount ;
+                        classAys.subjects.Add(new AysSubject { id = key, passPercent= passPercent, passCount= passCount, average= average ,name= info.subjects.Where(x => x.id == key).FirstOrDefault().name });
+                    }
+                    classes.Add(classAys);
+                }
+                //处理年级
+                var tgrades= classes.GroupBy(x => x.gradeId).Select(x=>x.Key);
+                foreach (var greade in tgrades) {
+                    var clases = classes.Where(x => x.gradeId.Equals(greade));
+                    var classCount = clases.Count();
+                    var stu= clases.SelectMany(x => x.studentIds).ToList();
+                    var lineCount = clases.Select(x => x.lineCount).Sum();
+                    var totalAverage = clases.Select(x => x.totalAverage).Sum() * 1.0 / classCount;
+                    GradeAys gradeAys = new GradeAys
+                    {
+                        gradeId = greade,
+                        studentIds = stu,
+                        gradeName = info.grades.Where(x => x.id == greade).FirstOrDefault().name,
+                        stuCount = stu.Count,
+                        lineCount = lineCount,
+                        totalAverage = totalAverage,
+                    };
+                    foreach (var key in paperScore.Keys)
+                    {
+                        var AysSubject = clases.SelectMany(c=>c.subjects).Where(x => x.id.Equals(key)).Select(x => x).ToList();
+                        var passCount= AysSubject.Select(x => x.passCount).Sum();
+                        var average = AysSubject.Select(x => x.average).Sum()*1.0/ classCount;
+                        var passPercent = passCount * 1.0/ stu.Count;
+                        AysSubject subject = new AysSubject  { 
+                            id=key,
+                            passCount= passCount, 
+                            passPercent= passPercent, 
+                            average= average,
+                            name = info.subjects.Where(x => x.id == key).FirstOrDefault().name };
+                        gradeAys.subjects.Add(subject);
+                    }
+                    grades.Add(gradeAys);
+                }
+            }
+            catch (Exception ex) { 
+            
+            }
+            return Ok(new { students, classes, grades });
+        }
+    }
+}

+ 35 - 0
TEAMModelOS/Controllers/Analysis/ClassAys.cs

@@ -0,0 +1,35 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading.Tasks;
+
+namespace TEAMModelOS.Controllers.Analysis
+{
+    public class ClassAys
+    {
+        public ClassAys()
+        {
+            subjects = new List<AysSubject>();
+           
+        }
+        public List<string> studentIds { get; set; } = new List<string>();
+        public int stuCount { get; set; }
+        public int lineCount { get; set; }
+        public List<AysSubject> subjects { get; set; }
+        public string classId { get; set; }
+        public string className { get; set; }
+        public double totalAverage { get; set; }
+        public double standardDeviation { get; set; }
+        public string gradeId { get; set; }
+    }
+    public class AysSubject
+    {
+        public int passCount { get; set; }
+        public string name { get; set; }
+        public string id { get; set; }
+        public double passPercent { get; set; }
+        public double average { get; set; }
+        
+
+    }
+}

+ 23 - 0
TEAMModelOS/Controllers/Analysis/GradeAys.cs

@@ -0,0 +1,23 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading.Tasks;
+
+namespace TEAMModelOS.Controllers.Analysis
+{
+    public class GradeAys
+    {
+        public GradeAys()
+        {
+            subjects = new List<AysSubject>();
+
+        }
+        public List<string> studentIds { get; set; } = new List<string>();
+        public int stuCount { get; set; }
+        public int lineCount { get; set; }
+        public List<AysSubject> subjects { get; set; }
+        public string gradeId { get; set; }
+        public string gradeName { get; set; }
+        public double totalAverage { get; set; }
+    }
+}

+ 26 - 0
TEAMModelOS/Controllers/Analysis/StudentAys.cs

@@ -0,0 +1,26 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading.Tasks;
+
+namespace TEAMModelOS.Controllers.Analysis
+{
+    public class StudentAys
+    {
+        public string id { get; set; }
+        public string name { get; set; }
+        public double total { get; set; }
+        public double gpr { get; set; }
+        public double cpr { get; set; }
+        public List<StudentSubject> subjects { get; set; } = new List<StudentSubject>();
+        public string classId { get; set; }
+        public string className { get; set; }
+    }
+    public class StudentSubject{ 
+        public string id { get; set; }
+        public string name { get; set; }
+        public double gpr { get; set; }
+        public double cpr { get; set; }
+        public double score { get; set; }
+    }
+}