From 43a16815ca62038413551779f3628bbea7535901 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=B0=8F=E8=82=A5=E7=BE=8A?= <1048382248@qq.com> Date: Tue, 23 Sep 2025 18:20:31 +0800 Subject: [PATCH] =?UTF-8?q?=E6=96=B0=E5=A2=9E=20=E8=80=83=E8=AF=95=20?= =?UTF-8?q?=E5=A4=9A=E5=AD=A6=E7=A7=91=E6=88=90=E7=BB=A9=E5=88=86=E6=AE=B5?= =?UTF-8?q?=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Controllers/ExamClassInfoController.cs | 93 +++++++++++++++---- .../Controllers/ExamController.cs | 10 +- .../Controllers/ExamTagsController.cs | 28 ++++++ Learn.Archives.API/appsettings.json | 2 +- Learn.Archives.Core/Model/Dto/ExamClassDto.cs | 13 +++ Learn.Archives.Core/Model/Exam.cs | 3 +- Learn.Archives.Core/Model/ExamClassInfo.cs | 28 +++--- Learn.Archives.Core/Model/ExamClassTag.cs | 77 +++++++++++++++ Learn.Archives.Core/Model/ExamTags.cs | 73 +++++++++++++++ 9 files changed, 291 insertions(+), 36 deletions(-) create mode 100644 Learn.Archives.API/Controllers/ExamTagsController.cs create mode 100644 Learn.Archives.Core/Model/Dto/ExamClassDto.cs create mode 100644 Learn.Archives.Core/Model/ExamClassTag.cs create mode 100644 Learn.Archives.Core/Model/ExamTags.cs diff --git a/Learn.Archives.API/Controllers/ExamClassInfoController.cs b/Learn.Archives.API/Controllers/ExamClassInfoController.cs index b74a5d7..b474e78 100644 --- a/Learn.Archives.API/Controllers/ExamClassInfoController.cs +++ b/Learn.Archives.API/Controllers/ExamClassInfoController.cs @@ -8,6 +8,7 @@ using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; using MiniExcelLibs; using System.Buffers.Text; +using System.Collections.Generic; using System.Diagnostics; using System.Security.Claims; using UserCenter.Model; @@ -25,10 +26,14 @@ namespace Learn.Archives.API.Controllers readonly Repository baseService; readonly Repository examService; readonly Repository schoolService; + readonly Repository tagService; readonly Repository examUserInfoService; readonly LiveUserInfo userInfo; readonly IHttpContextAccessor accessor; - public ExamClassInfoController(Repository baseService, LiveUserInfo userInfo, IHttpContextAccessor httpContext, Repository examUserInfoService, Repository examService, Repository schoolService) : base(baseService) + public ExamClassInfoController(Repository baseService, LiveUserInfo userInfo, + IHttpContextAccessor httpContext, Repository examUserInfoService, + Repository examService, Repository schoolService, + Repository tagService) : base(baseService) { this.baseService = baseService; this.userInfo = userInfo; @@ -36,8 +41,9 @@ namespace Learn.Archives.API.Controllers this.examUserInfoService = examUserInfoService; this.examService = examService; this.schoolService = schoolService; + this.tagService = tagService; } - + [NonAction] private Dictionary? ImportExamInfoSubjectDic(ImportExamInfo info) { @@ -54,7 +60,19 @@ namespace Learn.Archives.API.Controllers { SubjectEnum.地理, info.地理}, }; } - + [NonAction] + private static decimal? SubjectScore(ExamUserInfo info,SubjectEnum? s) + { + switch (s) + { + case null: + return info.AssignScore; + default: + if (info?.SubjectDic is null) + return -999; + return info.SubjectDic.ContainsKey(s.Value)? info.SubjectDic?[s.Value] : -999 ; + } + } /// /// 导入考试信息 /// @@ -175,7 +193,7 @@ namespace Learn.Archives.API.Controllers //写入数据库 await examUserInfoService.AsInsertable(insertUserInfo).ExecuteCommandAsync(); - await CalculatingTestResults(exam,examUserInfoService,schoolService); + await CalculatingTestResults(exam,examUserInfoService,schoolService, tagService); return Ok(); } @@ -188,18 +206,23 @@ namespace Learn.Archives.API.Controllers /// /// [NonAction] - public static async Task CalculatingTestResults(Exam exam, Repository eUService, Repository sService) + public static async Task CalculatingTestResults(Exam exam, Repository eUService, + Repository sService, Repository tagService) { var userInfoArr = await eUService.AsQueryable() .Where(s => s.ExamId == exam.Id) .ToArrayAsync(); var insertTotalClassInfo = new List(); + var insertTotalClassTag = new List(); + var eTagArr = await tagService.AsQueryable().Where(s => s.ExamId == exam.Id) + .ToArrayAsync(); var db = sService.Context; foreach (var schoolArr in userInfoArr.GroupBy(s => s.SchoolId)) { var insertClassInfo = new List(); + var insertClassTag = new List(); var school = await sService.GetFirstAsync(s => s.Id == schoolArr.Key); var classArr = await db.Queryable().Where(c => c.SchoolId == school.Id && c.GradeLevel == exam.GradeLevel && @@ -228,12 +251,43 @@ namespace Learn.Archives.API.Controllers }; insertClassInfo.Add(eCInfo); var avgTotal = 0m; + + //todo 班级分段分析 + var classTagDic = new Dictionary(); foreach (var eUserInfo in classUserArr) { - var v = eUserInfo.AssignScore; + if (!classTagDic.TryGetValue(eUserInfo.ClassId, out ExamClassTag[]? classTagArr)) + { + classTagArr = new ExamClassTag[10]; + classTagDic.Add(eUserInfo.ClassId, classTagArr); + } //上线人数 - if (v >= exam.ScoreLine) - eCInfo.OnLineCount++; + foreach (var item in eTagArr) + { + var subV = SubjectScore(eUserInfo, item.SubjectId); + //总分分段 + if (subV >= item.MinScore && subV <= item.MaxScore) + { + var tag = classTagArr[(int)(item.SubjectId ?? 0)]; + if (tag is null) + { + tag = new ExamClassTag() + { + MaxScore = item.MaxScore, + MinScore = item.MinScore, + ExamId =exam.Id, + ExamTagId = item.Id, + Name = item.TagName, + SubjectId = item.SubjectId + }; + insertClassTag.Add(tag); + classTagArr[(int)(item.SubjectId ?? 0)]= tag; + } + classTagArr[(int)(item.SubjectId ?? 0)].OnLineCount++; + } + + } + var v = eUserInfo.AssignScore; //最大小分 if (v < eCInfo.MinScore) eCInfo.MinScore = v; @@ -244,23 +298,28 @@ namespace Learn.Archives.API.Controllers //总分平均分 eCInfo.Average = avgTotal / eCInfo.PeopleCount; //计算上线率 - eCInfo.OnLineRate = (decimal)eCInfo.OnLineCount / (decimal)eCInfo.PeopleCount; + if(classTagDic.ContainsKey(eCInfo.ClassId)) + foreach (var item in classTagDic[eCInfo.ClassId]) + item.OnLineRate = (decimal)item.OnLineCount / (decimal)eCInfo.PeopleCount; } - insertTotalClassInfo.AddRange(insertClassInfo); + insertTotalClassTag.AddRange(insertClassTag); } - { //计算年级上线率排名 - var i = 0; - foreach (var item in insertTotalClassInfo.OrderByDescending(s => s.OnLineRate) - .GroupBy(s => s.OnLineRate)) + { //计算班级上线率排名 + foreach (var examTagArr in insertTotalClassTag.GroupBy(s => s.ExamTagId)) { - foreach (var u in item) - u.OnLineRanking = ++i; + var i = 0; + foreach (var item in examTagArr.OrderByDescending(s => s.OnLineRate) + .GroupBy(s => s.OnLineRate)) + { + foreach (var u in item) + u.OnLineRanking = ++i; + } } //计算年级平均分排名 - i = 0; + var i = 0; foreach (var item in insertTotalClassInfo.OrderByDescending(s => s.Average) .GroupBy(s => s.Average)) { diff --git a/Learn.Archives.API/Controllers/ExamController.cs b/Learn.Archives.API/Controllers/ExamController.cs index 1b8d7d8..e28a7d7 100644 --- a/Learn.Archives.API/Controllers/ExamController.cs +++ b/Learn.Archives.API/Controllers/ExamController.cs @@ -20,18 +20,20 @@ namespace Learn.Archives.API.Controllers { readonly Repository baseService; readonly Repository schoolService; + readonly Repository tagService; readonly Repository examClassInfoService; readonly Repository examUserInfoService; readonly LiveUserInfo userInfo; - public ExamController(Repository baseService, LiveUserInfo userInfo, - Repository examClassInfoService, Repository examUserInfoService, - Repository schoolService) : base(baseService) + public ExamController(Repository baseService, LiveUserInfo userInfo, + Repository examClassInfoService, Repository examUserInfoService, + Repository schoolService, Repository tagService) : base(baseService) { this.baseService = baseService; this.userInfo = userInfo; this.examClassInfoService = examClassInfoService; this.examUserInfoService = examUserInfoService; this.schoolService = schoolService; + this.tagService = tagService; } public override Task PageList([FromBody] QueryRequestBase model) { @@ -69,7 +71,7 @@ namespace Learn.Archives.API.Controllers } var res =await base.Edit(model); if (res) - await ExamClassInfoController.CalculatingTestResults(model, examUserInfoService, schoolService); + await ExamClassInfoController.CalculatingTestResults(model, examUserInfoService, schoolService, tagService); return res ; } public override async Task Del([FromBody] params long[] ids) diff --git a/Learn.Archives.API/Controllers/ExamTagsController.cs b/Learn.Archives.API/Controllers/ExamTagsController.cs new file mode 100644 index 0000000..2d61097 --- /dev/null +++ b/Learn.Archives.API/Controllers/ExamTagsController.cs @@ -0,0 +1,28 @@ +using Learn.Archives.API.Controllers.Dto; +using Learn.Archives.API.Expand; +using Learn.Archives.Core.Common; +using Learn.Archives.Core.Model; +using Learn.Archives.Core.Model.Dto; +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Mvc; +using System.Diagnostics; +using System.Linq; +using System.Security.Claims; +using UserCenter.Model; +using UserCenter.Model.Common; +using UserCenter.Model.Enum; + +namespace Learn.Archives.API.Controllers +{ + /// + /// 年级控制器 + /// + public class ExamTagsController : BackController + { + readonly Repository baseService; + public ExamTagsController(Repository baseService) : base(baseService) + { + this.baseService = baseService; + } + } +} diff --git a/Learn.Archives.API/appsettings.json b/Learn.Archives.API/appsettings.json index d3d0c1e..76c592f 100644 --- a/Learn.Archives.API/appsettings.json +++ b/Learn.Archives.API/appsettings.json @@ -14,7 +14,7 @@ "DB": { "ConnectionString": "AllowLoadLocalInfile=true;Server=58.17.132.2;User ID=marking;Password=qwe123!@#;Port=3306;Database=learn.archives;CharSet=utf8mb4;Port=43306;pooling=true;SslMode=None;", "SqlType": "MySql", - "UpdateTable": false + "UpdateTable": true }, "AuthKey": { "Secret": "9FAB7AC7-F1DB-4C56-B84F-044055A34AF2", diff --git a/Learn.Archives.Core/Model/Dto/ExamClassDto.cs b/Learn.Archives.Core/Model/Dto/ExamClassDto.cs new file mode 100644 index 0000000..ebe47a1 --- /dev/null +++ b/Learn.Archives.Core/Model/Dto/ExamClassDto.cs @@ -0,0 +1,13 @@ +using SqlSugar; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Learn.Archives.Core.Model.Dto +{ + + + +} diff --git a/Learn.Archives.Core/Model/Exam.cs b/Learn.Archives.Core/Model/Exam.cs index 58f9fbb..9e521a2 100644 --- a/Learn.Archives.Core/Model/Exam.cs +++ b/Learn.Archives.Core/Model/Exam.cs @@ -38,7 +38,8 @@ namespace Learn.Archives.Core.Model /// public string? _grade; /// - /// 年级 + /// 年级 + /// AOP自动转换年级 /// [SugarColumn(IsIgnore = true)] public string Grade diff --git a/Learn.Archives.Core/Model/ExamClassInfo.cs b/Learn.Archives.Core/Model/ExamClassInfo.cs index 4223d4c..8bf0b2d 100644 --- a/Learn.Archives.Core/Model/ExamClassInfo.cs +++ b/Learn.Archives.Core/Model/ExamClassInfo.cs @@ -1,4 +1,5 @@ -using Learn.Archives.Core.Model.Enum; +using Learn.Archives.Core.Model.Dto; +using Learn.Archives.Core.Model.Enum; using Learn.Archives.Core.Model.Interface; using SqlSugar; using System.ComponentModel.DataAnnotations; @@ -71,18 +72,19 @@ namespace Learn.Archives.Core.Model /// public int GradeYear { get; set; } - /// - /// 上线率 考试排名 - /// - public decimal OnLineRanking { get; set; } - /// - /// 上线率 - /// - public decimal OnLineRate { get; set; } - /// - /// 上线人数 - /// - public int OnLineCount { get; set; } + ///// + ///// 上线率 考试排名 + ///// + //public decimal OnLineRanking { get; set; } + ///// + ///// 上线率 + ///// + //public decimal OnLineRate { get; set; } + ///// + ///// 上线人数 + ///// + //public int OnLineCount { get; set; } + /// /// 参加人数 /// diff --git a/Learn.Archives.Core/Model/ExamClassTag.cs b/Learn.Archives.Core/Model/ExamClassTag.cs new file mode 100644 index 0000000..9cefd5c --- /dev/null +++ b/Learn.Archives.Core/Model/ExamClassTag.cs @@ -0,0 +1,77 @@ +using Learn.Archives.Core.Model.Dto; +using Learn.Archives.Core.Model.Enum; +using Learn.Archives.Core.Model.Interface; +using SqlSugar; +using System.ComponentModel.DataAnnotations; +using System.Net; +using System.Text.Json; +using UserCenter.Model; +using UserCenter.Model.Common; +using UserCenter.Model.Enum; +using UserCenter.Model.Interface; + +namespace Learn.Archives.Core.Model +{ + /// + /// 班级考试详情 + /// + [SugarTable("examclasstag")] + public class ExamClassTag : EntityBaseId, IDB + { + /// + /// 考试Id + /// + [SugarColumn(Length = 20)] + public long ExamId { get; set; } + + /// + /// 考试标签id + /// + public long ExamTagId { get; set; } + /// + /// 标签名称 + /// + public string Name { get; set; } + + + /// + /// 分段所属学科 + /// 可空 空即为总分分段 + /// + [SugarColumn(IsNullable = true)] + public SubjectEnum? SubjectId { get; set; } + + /// + /// 最小分值 + /// + [SugarColumn(DecimalDigits = 2)] + public decimal MinScore { get; set; } + + /// + /// 最大分值 + /// + [SugarColumn(DecimalDigits = 2)] + public decimal MaxScore { get; set; } + + /// + /// 上线率 考试排名 + /// + public int OnLineRanking { get; set; } + /// + /// 上线率 + /// + [SugarColumn(DecimalDigits = 2)] + public decimal OnLineRate { get; set; } + /// + /// 上线人数 + /// + public int OnLineCount { get; set; } + + /// + /// 创建时间 + /// + public DateTime CreateTime { get; set; } = DateTime.Now; + + + } +} diff --git a/Learn.Archives.Core/Model/ExamTags.cs b/Learn.Archives.Core/Model/ExamTags.cs new file mode 100644 index 0000000..edb3cde --- /dev/null +++ b/Learn.Archives.Core/Model/ExamTags.cs @@ -0,0 +1,73 @@ +using System; +using System.Linq; +using System.Text; + +using UserCenter.Model; +using UserCenter.Model.Interface; +using SqlSugar; +using UserCenter.Model.Enum; +using Learn.Archives.Core.Model.Interface; + +namespace Learn.Archives.Core.Model +{ + /// + /// 考试成绩分段表 + /// + [SugarTable("examtags")] + public partial class ExamTags : EntityBaseId, IDB + { + public ExamTags() + { + + this.IsDefault = Convert.ToInt32("0"); + this.CreateTime = DateTime.Now; + + } + /// + /// + /// + [SugarColumn(IsPrimaryKey = true, IsIdentity = true)] + public override long Id { get; set; } + + /// + /// 考试编号 + /// + public long ExamId { get; set; } + + + /// + /// 分段所属学科 + /// 可空 空即为总分分段 + /// + [SugarColumn(IsNullable = true)] + public SubjectEnum? SubjectId { get; set; } + + /// + /// 最小分值 + /// + [SugarColumn(DecimalDigits = 2)] + public decimal MinScore { get; set; } + + /// + /// 最大分值 + /// + [SugarColumn(DecimalDigits = 2)] + public decimal MaxScore { get; set; } + + /// + /// 标签名称 + /// + public string TagName { get; set; } + + /// + /// 是否为默认标签 0:否 1:是 + /// + public int IsDefault { get; set; } + + /// + /// 添加时间 + /// + public DateTime CreateTime { get; set; } + + } +}