diff --git a/VOL.Business/IServices/SportsHall/ISportsHallService.cs b/VOL.Business/IServices/SportsHall/ISportsHallService.cs index f4f2415..0f16717 100644 --- a/VOL.Business/IServices/SportsHall/ISportsHallService.cs +++ b/VOL.Business/IServices/SportsHall/ISportsHallService.cs @@ -41,6 +41,13 @@ namespace VOL.Business.IServices.SportsHall /// Task> GetSportsHallStudentsTestPageList(SportsHallStudentsTestParam paramDto); + /// + /// 体测成绩管理分页列表(全部体测项目) + /// + /// + /// + Task> GetSummaryOfGradesStudentsTestPageList(SportsHallStudentsTestParam paramDto); + /// /// 成绩推送 /// diff --git a/VOL.Business/Services/SportsHall/SportsHallService.cs b/VOL.Business/Services/SportsHall/SportsHallService.cs index b57617e..d167dc5 100644 --- a/VOL.Business/Services/SportsHall/SportsHallService.cs +++ b/VOL.Business/Services/SportsHall/SportsHallService.cs @@ -571,6 +571,142 @@ namespace VOL.Business.Services.SportsHall return result; } + /// + /// 体测成绩管理分页列表(全部体测项目) + /// + /// + /// + public async Task> GetSummaryOfGradesStudentsTestPageList(SportsHallStudentsTestParam paramDto) + { + var result = new PageDataDto(); + paramDto.PageIndex = paramDto.PageIndex <= 0 ? 1 : paramDto.PageIndex; + paramDto.PageSize = paramDto.PageSize <= 0 ? 10 : paramDto.PageSize; + + var baseQuery = _sportsTestResultRepository.DbContext.Set() + .Where(s => s.SchoolCode == UserContext.Current.TenantId); + + if (paramDto.StartTime.HasValue) + baseQuery = baseQuery.Where(x => x.CreateDate >= paramDto.StartTime.Value); + if (paramDto.EndTime.HasValue) + baseQuery = baseQuery.Where(x => x.CreateDate <= paramDto.EndTime.Value); + if (paramDto.ClassId.HasValue) + baseQuery = baseQuery.Where(x => x.ClassId == paramDto.ClassId.Value); + if (paramDto.Sex.HasValue) + baseQuery = baseQuery.Where(x => (int)x.Sex == paramDto.Sex); + if (!string.IsNullOrWhiteSpace(paramDto.ResultLevel)) + baseQuery = baseQuery.Where(x => x.Rank == paramDto.ResultLevel); + + var filteredQuery = baseQuery; + if (paramDto.ItemType.HasValue && paramDto.ItemType.Value > 0) + filteredQuery = filteredQuery.Where(x => x.CategoryValue == paramDto.ItemType.Value); + + var latestScoreTimeQuery = filteredQuery + .GroupBy(x => x.StudentNo) + .Select(g => new { StudentNo = g.Key, MaxScoreTime = g.Max(x => x.ScoreTime) }); + + var latestRecordsQuery = from record in filteredQuery + join latest in latestScoreTimeQuery + on new { record.StudentNo, record.ScoreTime } + equals new { latest.StudentNo, ScoreTime = latest.MaxScoreTime } + select record; + + result.Total = await latestRecordsQuery + .Select(x => x.StudentNo) + .Distinct() + .CountAsync(); + + var pagedStudentKeys = await latestRecordsQuery + .OrderByDescending(x => x.ScoreTime) + .Select(x => new { x.StudentNo, x.ScoreTime }) + .Distinct() + .Skip((paramDto.PageIndex - 1) * paramDto.PageSize) + .Take(paramDto.PageSize) + .ToListAsync(); + + if (!pagedStudentKeys.Any()) + { + result.Datas = new List(); + return result; + } + + var pagedStudentNos = pagedStudentKeys.Select(x => x.StudentNo).Distinct().ToList(); + var pageRecords = await baseQuery + .Where(x => pagedStudentNos.Contains(x.StudentNo)) + .Select(x => new + { + x.Id, + x.StudentNo, + x.StudentName, + x.Sex, + x.ClassName, + x.GradeName, + x.ScoreTime, + x.IsDisplay, + x.CategoryValue, + x.CategoryEnum, + x.Value, + x.Score, + x.Rank + }) + .ToListAsync(); + + pageRecords = pageRecords + .Where(x => pagedStudentKeys.Any(k => k.StudentNo == x.StudentNo && k.ScoreTime == x.ScoreTime)) + .ToList(); + + var sportsTestItemTypes = Enum.GetValues(typeof(SportsTestItemType)) + .Cast() + .OrderBy(x => (int)x) + .ToList(); + + result.Datas = pageRecords + .GroupBy(x => new + { + x.StudentNo, + x.StudentName, + x.Sex, + x.ClassName, + x.GradeName, + x.ScoreTime, + x.IsDisplay + }) + .Select(g => + { + var records = g + .GroupBy(x => x.CategoryValue) + .ToDictionary(x => x.Key, x => x.OrderByDescending(r => r.Id).First()); + + return new SummaryOfGradesStudentsTestModel + { + Id = g.Max(x => x.Id), + StudentNo = g.Key.StudentNo, + StudentName = g.Key.StudentName, + SexName = g.Key.Sex.GetDescription(), + GradeAndClass = $"{g.Key.GradeName} {g.Key.ClassName}", + ScoreTime = g.Key.ScoreTime, + IsDisplay = g.Key.IsDisplay, + Items = sportsTestItemTypes.Select(itemType => + { + records.TryGetValue((int)itemType, out var record); + return new SummaryOfGradesSportsTestItemModel + { + ItemType = (int)itemType, + ItemCode = itemType.ToString(), + ItemName = itemType.GetDisplayName(), + Unit = itemType.GetDisplayDescription(), + Value = record?.Value, + Score = record?.Score, + Rank = record?.Rank ?? string.Empty + }; + }).ToList() + }; + }) + .OrderByDescending(x => x.ScoreTime) + .ToList(); + + return result; + } + /// /// 成绩推送 /// diff --git a/VOL.Model/School/Request/SportsHallStudentsTestParam.cs b/VOL.Model/School/Request/SportsHallStudentsTestParam.cs index 7bb05ac..7848cf9 100644 --- a/VOL.Model/School/Request/SportsHallStudentsTestParam.cs +++ b/VOL.Model/School/Request/SportsHallStudentsTestParam.cs @@ -26,6 +26,11 @@ namespace VOL.Model.School.Request /// public string? ResultLevel { get; set; } + /// + /// 体测项目类型 + /// + public int? ItemType { get; set; } + /// /// 开始时间 /// diff --git a/VOL.Model/School/Response/SummaryOfGradesStudentsTestModel.cs b/VOL.Model/School/Response/SummaryOfGradesStudentsTestModel.cs new file mode 100644 index 0000000..141074c --- /dev/null +++ b/VOL.Model/School/Response/SummaryOfGradesStudentsTestModel.cs @@ -0,0 +1,99 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; + +namespace VOL.Model.School.Response +{ + /// + /// 体测成绩管理汇总查询 + /// + public class SummaryOfGradesStudentsTestModel + { + /// + /// Id + /// + public int Id { get; set; } + + /// + /// 学号 + /// + [Display(Name = "学号")] + public string StudentNo { get; set; } + + /// + /// 姓名 + /// + [Display(Name = "姓名")] + public string StudentName { get; set; } + + /// + /// 年级班级 + /// + [Display(Name = "年级班级")] + public string GradeAndClass { get; set; } + + /// + /// 性别 + /// + [Display(Name = "性别")] + public string SexName { get; set; } + + /// + /// 测试时间 + /// + [Display(Name = "测试时间")] + public DateTime ScoreTime { get; set; } + + /// + /// 是否显示 + /// + [Display(Name = "是否显示")] + public bool IsDisplay { get; set; } + + /// + /// 全部体测项目成绩 + /// + public List Items { get; set; } = new(); + } + + /// + /// 体测项目成绩 + /// + public class SummaryOfGradesSportsTestItemModel + { + /// + /// 项目类型 + /// + public int ItemType { get; set; } + + /// + /// 项目枚举名称 + /// + public string ItemCode { get; set; } + + /// + /// 项目名称 + /// + public string ItemName { get; set; } + + /// + /// 单位 + /// + public string Unit { get; set; } + + /// + /// 成绩值 + /// + public float? Value { get; set; } + + /// + /// 分数 + /// + public float? Score { get; set; } + + /// + /// 等级 + /// + public string Rank { get; set; } + } +} diff --git a/VOL.WebApi/Controllers/SportsHall/SportsHallController.cs b/VOL.WebApi/Controllers/SportsHall/SportsHallController.cs index f4d033d..47b38fe 100644 --- a/VOL.WebApi/Controllers/SportsHall/SportsHallController.cs +++ b/VOL.WebApi/Controllers/SportsHall/SportsHallController.cs @@ -79,6 +79,17 @@ namespace VOL.WebApi.Controllers.SportsHall return await _sportsHallService.GetSportsHallStudentsTestPageList(paramDto); } + /// + /// 体测成绩管理分页列表(全部体测项目) + /// + /// + /// + [HttpGet(nameof(GetSummaryOfGradesStudentsTestPageList))] + public async Task> GetSummaryOfGradesStudentsTestPageList(SportsHallStudentsTestParam paramDto) + { + return await _sportsHallService.GetSummaryOfGradesStudentsTestPageList(paramDto); + } + /// /// 成绩推送 ///