using AutoMapper; using Microsoft.EntityFrameworkCore; using VOL.Entity.DomainModels.XinWei; using VOL.Entity.Enum; using YD_XinWei.Api.Context; using YD_XinWei.Api.Services.Interface; using YD_XinWei.Api.SmartSportsEntitys; using YD_XinWei.Api.Utilities; using YD_XinWei.Commons.Dto.Common; using YD_XinWei.Commons.Dto.LargeScreen; using YD_XinWei.Commons.Enum; using YD_XinWei.Commons.MemoryCaches; namespace YD_XinWei.Api.Services.Impl { /// /// 大屏服务 /// public class LargeScreenService : ILargeScreenService { public SmartSportsContext _sportsContext; private readonly IMapper _mapper; private readonly ICacheService _caching; /// /// 构造 /// /// /// public LargeScreenService(SmartSportsContext sportsContext, IMapper mapper, ICacheService caching) { _sportsContext = sportsContext; _mapper = mapper; _caching = caching; } /// /// 获取项目列表 /// /// /// public async Task> SportsProjectList(int orgId) { var testingProjectKey = $"TestingProject_{orgId}"; var res = _caching.Get>(testingProjectKey); if (res == null || res.Count == 0) { res = await _sportsContext.XW_TestingProject.Where(x => x.OrgId == orgId) .Select(x => new SportsProjectListDto() { ProjectId = x.ProjectId, ProjectName = x.ProjectName, CategoryValue = x.CategoryValue, CategoryEnum = x.CategoryEnum, Unit = ((SportsTestItemType)x.CategoryValue).GetUnit() }).ToListAsync(); } return res; } /// /// 项目成绩大屏数据 /// /// /// public async Task ItemResultLargeScreenData(int orgId) { var res = new LargeScreenDto(); var schoolKeyKey = $"School_{orgId}"; var schoolCode = _caching.Get(schoolKeyKey); if (string.IsNullOrWhiteSpace(schoolCode)) { schoolCode = await _sportsContext.School.Where(x => x.Id == orgId).Select(x => x.SchoolCode).FirstAsync(); _caching.Add(schoolKeyKey, schoolCode); } var sportsTestDataKey = $"SportsTestData_{schoolCode}"; var studentListKey = $"StudentList_{schoolCode}"; var studentList = _caching.Get>(studentListKey); if (studentList == null || studentList.Count == 0) { studentList = await _sportsContext.Student.Where(x => x.SchoolCode == schoolCode).Select(x => new StudentListDto { StudentNo = x.StudentNo, Sex = x.Sex, Photo = x.Photo ?? "" }).ToListAsync(); _caching.AddObject(studentListKey, studentList, 3600); } res.BasicInfo.FemaleCount = studentList.Count(x => x.Sex == 2); res.BasicInfo.MaleCount = studentList.Count(x => x.Sex == 1); var sportsTestData = _caching.Get>(sportsTestDataKey); if (sportsTestData == null || sportsTestData.Count == 0) { sportsTestData = await _sportsContext.SportsTestValue.Where(x => x.SchoolCode == schoolCode && x.DataSource == DataSource.XW) .Select(x => new SportsTestDataDto() { SchoolCode = x.SchoolCode, CategoryValue = x.CategoryValue, ClassId = x.ClassId, ClassName = x.ClassName, GradeId = x.GradeId, GradeName = x.GradeName, TeacherId = x.TeacherId, StudentNo = x.StudentNo, StudentName = x.StudentName, Sex = x.Sex, ScoreTime = x.ScoreTime, Height = x.Height, Weight = x.Weight, Value = x.Value, Score = x.Score, Rank = x.Rank }).ToListAsync(); _caching.AddObject(sportsTestDataKey, sportsTestData, 3600); } var bestScoreData = sportsTestData .GroupBy(x => x.StudentNo) .Select(g => g.OrderByDescending(x => x.Score).First()) .ToList(); var projectResults = bestScoreData .GroupBy(x => x.CategoryValue) .Select(g => new ItemDataDto { CategoryValue = g.Key, // 优良率计算:分数 > 80 的人数 ÷ 总人数 ExcellentRate = g.Count(x => x.Score > 80) * 100.0 / Math.Max(g.Count(), 1), // 男生前十名 MaleRankList = g.Where(x => x.Sex == 1) .OrderByDescending(x => x.Value) .Take(10) .Select((x, index) => new StudentScoreRankingDto { Rank = index + 1, StudentNo = x.StudentNo, StudentName = x.StudentName, Value = x.Value }).ToList(), // 女生前十名 FemaleRankList = g.Where(x => x.Sex == 2) .OrderByDescending(x => x.Value) .Take(10) .Select((x, index) => new StudentScoreRankingDto { Rank = index + 1, StudentNo = x.StudentNo, StudentName = x.StudentName, Value = x.Value }).ToList() }) .ToList(); res.ItemDatalist = projectResults; var classListKey = $"ClassList_{schoolCode}"; var classList = _caching.Get>(classListKey); if (classList == null || classList.Count == 0) { classList = await _sportsContext.Class.Where(x => x.SchoolCode == schoolCode).ToListAsync(); _caching.AddObject(classListKey, classList, 3600); } var classRankingList = sportsTestData .GroupBy(x => new { x.ClassId }) .Select(g => new ClassSportsRankingDto { ClassId = g.Key.ClassId, ClassName = classList.Where(c => c.Id == g.Key.ClassId).Select(x => $"{x.GradeName}-{x.ClassName}").FirstOrDefault() ?? "", Count = g.Count() }) .OrderByDescending(x => x.Count) .Take(5) .Select((x, index) => { x.Rank = index + 1; return x; }) .ToList(); res.ClassSportsRankList = classRankingList; var testingProjectKey = $"TestingProject_{orgId}"; var testingProjects = _caching.Get>(testingProjectKey) ?? new List(); var projectNameDict = testingProjects.ToDictionary(t => t.CategoryValue, t => t.ProjectName); var studentPhotoDict = studentList.Where(s => !string.IsNullOrEmpty(s.StudentNo)).ToDictionary(s => s.StudentNo, s => s.Photo ?? string.Empty); var latestPerStudent = sportsTestData .GroupBy(x => x.StudentNo) .Select(g => g.OrderByDescending(x => x.ScoreTime).First()) .ToList(); var realTimeResults = latestPerStudent .OrderByDescending(x => x.ScoreTime) .Take(50) .Select(x => new ItemRealTimeResultDto { StudentNo = x.StudentNo, StudentName = x.StudentName, Photo = studentPhotoDict.TryGetValue(x.StudentNo, out var photo) ? photo : string.Empty, GradeAndClassName = $"{x.GradeName}-{x.ClassName}", ProjectName = projectNameDict.TryGetValue(x.CategoryValue, out var projectName) ? projectName : string.Empty, Value = x.Value, Score = x.Score, Rank = x.Rank ?? "不及格", ScoreTime = x.ScoreTime.ToString("yyyy-MM-dd HH:mm:ss") }) .ToList(); res.ItemRealTimeResultList = realTimeResults; return res; } } }