using AutoMapper; using Castle.DynamicProxy.Generators; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.DependencyInjection; using Newtonsoft.Json; using OfficeOpenXml.FormulaParsing.Excel.Functions.Text; using System.Threading; using VOL.Business.IServices.Norm; using VOL.Business.IServices.School; using VOL.Core.CacheManager; using VOL.Core.Configuration; using VOL.Core.Extensions.AutofacManager; using VOL.Core.ManageUser; using VOL.Core.Utilities; using VOL.Entity.DomainModels; using VOL.Entity.DomainModels.Business.People; using VOL.Entity.Enum; using VOL.Model; using VOL.Model.Ai; using VOL.Model.IOT.Request; using VOL.Model.Norm.Response; using VOL.Model.School.Request; using VOL.Model.School.Response; using VOL.System.IRepositories; using VOL.System.Repositories; using static Dapper.SqlMapper; using static System.Formats.Asn1.AsnWriter; namespace VOL.Business.Services.School { public class S_ClassService : IS_ClassService, IDependency { #region 初始化 private readonly IMapper _mapper; private readonly ICacheService _cacheService; private readonly ICacheQueryService _cacheQueryService; private readonly IotDataSyncService _iotDataSyncService; private readonly IS_ClassRepository _classRepository; private readonly IS_StudentRepository _studentRepository; private readonly IS_ClassAssocTeacherRepository _classAssocTeacherRepository; private readonly IN_SportsTestResultRepository _sportsTestResultRepository; private readonly IN_SportsTestCategoryRepository _sportsTestCategoryRepository; [ActivatorUtilitiesConstructor] public S_ClassService(IMapper mapper, ICacheService cacheService, ICacheQueryService cacheQueryService, IS_ClassRepository classRepository, IS_ClassAssocTeacherRepository classAssocTeacherRepository, IS_StudentRepository studentRepository, IN_SportsTestResultRepository sportsTestResultRepository, IN_SportsTestCategoryRepository sportsTestCategoryRepository, IotDataSyncService iotDataSyncService) { _mapper = mapper; _cacheService = cacheService; _classRepository = classRepository; _cacheQueryService = cacheQueryService; _classAssocTeacherRepository = classAssocTeacherRepository; _studentRepository = studentRepository; _sportsTestResultRepository = sportsTestResultRepository; _sportsTestCategoryRepository = sportsTestCategoryRepository; _iotDataSyncService = iotDataSyncService; } #endregion /// /// 根据年级Id获取所有班级 /// /// /// /// public async Task> GetClassNames(int gradeId) { var list = await ( from g in _classRepository.DbContext.Set() where g.SchoolCode.Equals(UserContext.Current.TenantId) && g.GradeId == gradeId select new ClassNameModel() { Id = g.Id, ClassName = g.ClassName }).OrderBy(x => x.Id).ToListAsync(); return list; } /// /// 获取班级列表 /// /// /// /// public async Task> GetClassPageList(ClassPageListParam paramDto) { var tenantId = UserContext.Current.TenantId; var teacherClassIds = new List(); var isTeacher = (UserContext.Current.RoleId == 3); if (isTeacher) { var teacher = await _classRepository.DbContext.Set().FirstOrDefaultAsync(x => x.SchoolCode == tenantId && x.TeacherPhoneNo == UserContext.Current.UserInfo.PhoneNo); var teacherClassList = await ( from at in _classRepository.DbContext.Set() join c in _classRepository.DbContext.Set() on at.ClassId equals c.Id where at.TeacherId == teacher.Id select c).ToListAsync(); teacherClassIds = teacherClassList.Select(c => c.Id).Distinct().ToList(); } // 基础班级和年级查询 var query = (from c in _classRepository.DbContext.Set() join g in _classRepository.DbContext.Set() on c.GradeId equals g.Id join a in _classRepository.DbContext.Set() on g.Id equals a.GradeId where c.SchoolCode == tenantId && (!isTeacher || teacherClassIds.Contains(c.Id)) select new { c.Id, c.ClassName, c.GradeId, g.GradeName }).Distinct(); // 条件筛选 if (!string.IsNullOrWhiteSpace(paramDto.ClassName)) { query = query.Where(x => x.ClassName.Contains(paramDto.ClassName)); } if (paramDto.GradeId > 0) { query = query.Where(x => x.GradeId == paramDto.GradeId); } // 获取班级ID列表 var classIds = await query.Select(x => x.Id).ToListAsync(); // 查询教师信息并拼接 TeacherName 和 TeacherPhoneNo var teacherInfos = await (from assoc in _classRepository.DbContext.Set() join t in _classRepository.DbContext.Set() on assoc.TeacherId equals t.Id where classIds.Contains(assoc.ClassId) && t.SchoolCode.Equals(UserContext.Current.TenantId) && t.TeacherStatus != TeacherStatus.Depart group t by assoc.ClassId into groupedTeachers select new { ClassId = groupedTeachers.Key, TeacherNames = string.Join(", ", groupedTeachers.Select(t => t.TeacherName)), TeacherPhoneNos = string.Join(", ", groupedTeachers.Select(t => t.TeacherPhoneNo)) }).ToListAsync(); // 查询学生数量 var studentCounts = await (from s in _classRepository.DbContext.Set() where classIds.Contains(s.ClassId) && s.SchoolCode == tenantId group s by s.ClassId into groupedStudents select new { ClassId = groupedStudents.Key, Count = groupedStudents.Count() }).ToListAsync(); // 合并数据 var list = await query .OrderBy(x => x.Id) .Skip((paramDto.PageIndex - 1) * paramDto.PageSize) .Take(paramDto.PageSize) .ToListAsync(); var result = list.Select(x => { var teacherInfo = teacherInfos.FirstOrDefault(t => t.ClassId == x.Id); var studentCount = studentCounts.FirstOrDefault(s => s.ClassId == x.Id)?.Count ?? 0; return new ClassPageListModel { Id = x.Id, ClassName = x.ClassName, GradeId = x.GradeId, GradeName = x.GradeName, TeacherName = teacherInfo?.TeacherNames ?? "无", TeacherPhoneNo = teacherInfo?.TeacherPhoneNos ?? "无", StudentCount = studentCount }; }).ToList(); // 结果包装 return new PageDataDto { Total = classIds.Count, Datas = result }; } /// /// 导出班级 /// /// /// /// public async Task> GetClassList(ClassPageListExportParam paramDto) { var tenantId = UserContext.Current.TenantId; var teacherClassIds = new List(); var isTeacher = (UserContext.Current.RoleId == 3); if (isTeacher) { var teacher = await _classRepository.DbContext.Set().FirstOrDefaultAsync(x => x.SchoolCode == tenantId && x.TeacherPhoneNo == UserContext.Current.UserInfo.PhoneNo); var teacherClassList = await ( from at in _classRepository.DbContext.Set() join c in _classRepository.DbContext.Set() on at.ClassId equals c.Id where at.TeacherId == teacher.Id select c).ToListAsync(); teacherClassIds = teacherClassList.Select(c => c.Id).Distinct().ToList(); } var query = (from c in _classRepository.DbContext.Set() join g in _classRepository.DbContext.Set() on c.GradeId equals g.Id join a in _classRepository.DbContext.Set() on g.Id equals a.GradeId where c.SchoolCode == tenantId && (!isTeacher || teacherClassIds.Contains(c.Id)) select new { c.Id, c.ClassName, c.GradeId, g.GradeName }).Distinct(); // 条件筛选 if (!string.IsNullOrWhiteSpace(paramDto.ClassName)) { query = query.Where(x => x.ClassName.Contains(paramDto.ClassName)); } if (paramDto.GradeId > 0) { query = query.Where(x => x.GradeId == paramDto.GradeId); } // 获取班级ID列表 var classIds = await query.Select(x => x.Id).ToListAsync(); // 查询教师信息并拼接 TeacherName 和 TeacherPhoneNo var teacherInfos = await (from assoc in _classRepository.DbContext.Set() join t in _classRepository.DbContext.Set() on assoc.TeacherId equals t.Id where classIds.Contains(assoc.ClassId) && t.SchoolCode.Equals(UserContext.Current.TenantId) && t.TeacherStatus != TeacherStatus.Depart group t by assoc.ClassId into groupedTeachers select new { ClassId = groupedTeachers.Key, TeacherNames = string.Join(", ", groupedTeachers.Select(t => t.TeacherName)), TeacherPhoneNos = string.Join(", ", groupedTeachers.Select(t => t.TeacherPhoneNo)) }).ToListAsync(); // 查询学生数量 var studentCounts = await (from s in _classRepository.DbContext.Set() where classIds.Contains(s.ClassId) && s.SchoolCode == tenantId group s by s.ClassId into groupedStudents select new { ClassId = groupedStudents.Key, Count = groupedStudents.Count() }).ToListAsync(); var list = await query.OrderBy(x => x.Id).ToListAsync(); var result = list.Select(x => { var teacherInfo = teacherInfos.FirstOrDefault(t => t.ClassId == x.Id); var studentCount = studentCounts.FirstOrDefault(s => s.ClassId == x.Id)?.Count ?? 0; return new ClassPageListModel { Id = x.Id, ClassName = x.ClassName, GradeId = x.GradeId, GradeName = x.GradeName, TeacherName = teacherInfo?.TeacherNames ?? "无", TeacherPhoneNo = teacherInfo?.TeacherPhoneNos ?? "无", StudentCount = studentCount }; }).ToList(); return result; } /// /// 班级详情 /// /// /// /// public async Task GetClassDetails(int classId) { var classModel = await _classRepository.FindAsyncFirst(x => x.Id == classId); if (classModel == null) throw new ArgumentNullException("数据不存在"); var teacherList = await _classAssocTeacherRepository.FindAsIQueryable(x => x.ClassId == classId).Select(x => x.TeacherId).ToListAsync(); return new ClassDetailsModel() { ClassId = classModel.Id, GradeId = classModel.GradeId, TeacherIds = teacherList }; } /// /// 更新班级 /// /// /// /// public async Task ModifyClass(ModifyClassParam paramDto) { var tenantId = UserContext.Current.TenantId; var classModel = await _classRepository.FindAsyncFirst(x => x.Id == paramDto.ClassId); if (classModel == null) throw new ArgumentNullException("未找到要更新得数据"); var exist = await _classRepository.ExistsAsync( x => x.SchoolCode == tenantId && x.ClassName == paramDto.ClassName && x.GradeId == paramDto.GradeId && x.Id != paramDto.ClassId); if (exist) throw new Exception("班级名称已存在"); classModel.ClassName = paramDto.ClassName; using (var transaction = _classRepository.DbContext.Database.BeginTransaction()) { try { _classRepository.Update(classModel); var teacherList = await _classAssocTeacherRepository.FindAsync(x => x.ClassId == paramDto.ClassId); _classAssocTeacherRepository.DbContext.RemoveRange(teacherList); var classAssocTeacherList = new List(); paramDto.TeacherIds.ForEach(x => { classAssocTeacherList.Add(new S_ClassAssocTeacher() { ClassId = paramDto.ClassId, TeacherId = x, Creator = UserContext.Current.UserId, CreateDate = DateTime.Now, Modifier = UserContext.Current.UserId, ModifyDate = DateTime.Now, }); }); await _classAssocTeacherRepository.AddRangeAsync(classAssocTeacherList); await _classRepository.SaveChangesAsync(); // 提交事务 transaction.Commit(); //调用回调函数,同步数据到IOT //_ = Task.Run(() => _iotDataSyncService.DataSyncCallBack(new DataSyncCallBackParam //{ // EventType = EventType.Update.GetDisplayName(), // DataType = IOTDataSyncType.Class.GetDisplayName(), // Json = JsonConvert.SerializeObject(classModel) //})); await _iotDataSyncService.DataSyncCallBack(new DataSyncCallBackParam { EventType = EventType.Update.GetDisplayName(), DataType = IOTDataSyncType.Class.GetDisplayName(), Json = JsonConvert.SerializeObject(classModel) }); } catch (Exception ex) { // 发生错误,回滚事务 transaction.Rollback(); Console.WriteLine("事务回滚:" + ex.Message); } } } /// /// 添加班级 /// /// /// /// public async Task AddClass(AddClassParam paramDto) { var tenantId = UserContext.Current.TenantId; var exist = await _classRepository.ExistsAsync(x => x.SchoolCode == tenantId && x.ClassName == paramDto.ClassName && x.GradeId == paramDto.GradeId); if (exist) throw new Exception("班级名称已存在"); var classEntity = new S_Class() { GradeId = paramDto.GradeId, GradeName = paramDto.GradeName, ClassName = paramDto.ClassName, Creator = UserContext.Current.UserId, SchoolCode = UserContext.Current.TenantId, CreateDate = DateTime.Now }; using (var transaction = _classRepository.DbContext.Database.BeginTransaction()) { try { await _classRepository.AddAsync(classEntity); await _classRepository.SaveChangesAsync(); int classId = classEntity.Id; var classAssocTeacherList = new List(); paramDto.TeacherIds.ForEach(x => { classAssocTeacherList.Add(new S_ClassAssocTeacher() { ClassId = classId, TeacherId = x, Creator = UserContext.Current.UserId, CreateDate = DateTime.Now, Modifier = UserContext.Current.UserId, ModifyDate = DateTime.Now, }); }); await _classAssocTeacherRepository.AddRangeAsync(classAssocTeacherList); await _classRepository.SaveChangesAsync(); // 提交事务 transaction.Commit(); //调用回调函数,同步数据到IOT //_ = Task.Run(() => _iotDataSyncService.DataSyncCallBack(new DataSyncCallBackParam //{ // EventType = EventType.Add.GetDisplayName(), // DataType = IOTDataSyncType.Class.GetDisplayName(), // Json = JsonConvert.SerializeObject(new List() { classEntity }) //})); await _iotDataSyncService.DataSyncCallBack(new DataSyncCallBackParam { EventType = EventType.Add.GetDisplayName(), DataType = IOTDataSyncType.Class.GetDisplayName(), Json = JsonConvert.SerializeObject(new List() { classEntity }) }); } catch (Exception ex) { // 发生错误,回滚事务 transaction.Rollback(); Console.WriteLine("事务回滚:" + ex.Message); } } } /// /// 批量添加班级 /// /// /// /// public async Task BatchAddClass(BatchAddClassParam paramDto) { var tenantId = UserContext.Current.TenantId; var classEntityList = new List(); var nowTime = DateTime.Now; for (int i = 0; i < paramDto.ClassCount; i++) { var className = $"{(i + 1).ToChineseNumber()}班"; var exist = await _classRepository.ExistsAsync(x => x.SchoolCode == tenantId && x.ClassName == className && x.GradeId == paramDto.GradeId); if (exist) continue; var classEntity = new S_Class() { GradeId = paramDto.GradeId, GradeName = paramDto.GradeName, ClassName = className, SchoolCode = UserContext.Current.TenantId, Creator = UserContext.Current.UserId, CreateDate = nowTime }; classEntityList.Add(classEntity); } using (var transaction = _classRepository.DbContext.Database.BeginTransaction()) { try { await _classRepository.AddRangeAsync(classEntityList); await _classRepository.SaveChangesAsync(); var addedRecordIds = classEntityList.Select(c => c.Id).ToList(); var classAssocTeacherList = new List(); addedRecordIds.ForEach(c => { paramDto.TeacherIds.ForEach(x => { classAssocTeacherList.Add(new S_ClassAssocTeacher() { ClassId = c, TeacherId = x, Creator = UserContext.Current.UserId, CreateDate = DateTime.Now, Modifier = UserContext.Current.UserId, ModifyDate = DateTime.Now, }); }); }); await _classAssocTeacherRepository.AddRangeAsync(classAssocTeacherList); await _classRepository.SaveChangesAsync(); // 提交事务 transaction.Commit(); //调用回调函数,同步数据到IOT //_ = Task.Run(() => _iotDataSyncService.DataSyncCallBack(new DataSyncCallBackParam //{ // EventType = EventType.Update.GetDisplayName(), // DataType = IOTDataSyncType.Class.GetDisplayName(), // Json = JsonConvert.SerializeObject(classEntityList) //})); await _iotDataSyncService.DataSyncCallBack(new DataSyncCallBackParam { EventType = EventType.Update.GetDisplayName(), DataType = IOTDataSyncType.Class.GetDisplayName(), Json = JsonConvert.SerializeObject(classEntityList) }); } catch (Exception ex) { // 发生错误,回滚事务 transaction.Rollback(); Console.WriteLine("事务回滚:" + ex.Message); } } } public async Task ClassWholeDataStats(ClassDataStatsParam paramDto) { var res = new ClassDataStatsModel(); var tenantId = UserContext.Current.TenantId; if (!paramDto.ClassId.HasValue || paramDto.ClassId <= 0) { paramDto.ClassId = this._classRepository.DbContext.Set().First().Id; } var classModel = await (from c in _classRepository.DbContext.Set() join a in _classRepository.DbContext.Set() on c.Id equals a.ClassId into associations from association in associations.DefaultIfEmpty() join t in _classRepository.DbContext.Set() on association.TeacherId equals t.Id into teachers from teacher in teachers.DefaultIfEmpty() where c.Id == paramDto.ClassId && c.SchoolCode.Equals(UserContext.Current.TenantId) select new ClassPageListModel() { Id = c.Id, GradeId = c.GradeId, GradeName = c.GradeName, ClassName = c.ClassName, TeacherName = teacher.TeacherName, TeacherPhoneNo = teacher.TeacherPhoneNo }).FirstOrDefaultAsync(); if (classModel == null) throw new ArgumentNullException("未找到班级数据"); res.TeacherName = classModel.TeacherName; res.ClassName = classModel.ClassName; var students = await _studentRepository.FindAsIQueryable(x => x.ClassId == paramDto.ClassId) .Select(x => new { x.ClassId, x.StudentNo, x.StudentName, x.ClassName, x.Sex, x.Age }).ToListAsync(); res.StudentCount = students.Count; // 从缓存中获取数据 var sportsTestResults = await _cacheQueryService.GeSportsTestDataCacheAsync ( x => x.SchoolCode.Equals(tenantId) && x.ClassId == paramDto.ClassId , paramDto.Mode ); var monitorList = sportsTestResults .GroupBy(x => new { x.StudentNo }) .Select(g => new { g.Key.StudentNo, g.First().Sex, g.First().ClassId, g.First().ClassName, g.First().GradeId, g.First().GradeName, g.First().TeacherId, g.First().TeacherName, g.First().ClassRoomRecordId, Score = (g.Sum(x => x.Score) + g.Sum(x => x.AdditionalScore)) / (g.Select(x => x.CategoryEnum).Distinct().Count()) }) .Select(x => new { x.StudentNo, x.Sex, x.ClassId, x.ClassName, x.GradeId, x.GradeName, x.TeacherId, x.TeacherName, x.ClassRoomRecordId, x.Score, Rank = x.Score.GetRank() }).ToList(); // 计算总人数 double totalCount = monitorList.Count(); res.ExcellentRate = Math.Round((monitorList.Count(x => x.Rank == "优秀") / totalCount) * 100); res.FineRate = Math.Round((monitorList.Count(x => x.Rank == "良好") / totalCount) * 100); res.PassRate = Math.Round((monitorList.Count(x => x.Rank == "及格") / totalCount) * 100); //res.FailRate = totalCount > 0 ? Math.Round((monitorList.Count(x => x.Rank == "不及格") / totalCount) * 100) : 0; if (res != null) { // 计算并调整最后一个百分比(确保总和为100%) double sum = (res.ExcellentRate + res.FineRate + res.PassRate + res.FailRate); double adjustment = 100 - sum; res.FailRate += totalCount > 0 ? adjustment : 0; } var now = DateTime.Now; var currentQuarter = (now.Month - 1) / 3 + 1; var currentYear = now.Year; // 处理跨年情况 var quarters = new[] { new { Label = "本季度", Quarter = currentQuarter, Year = currentYear }, new { Label = "上季度", Quarter = currentQuarter - 1 == 0 ? 4 : currentQuarter - 1, Year = currentQuarter == 1 ? currentYear - 1 : currentYear }, new { Label = "前季度", Quarter = currentQuarter - 2 == 0 ? 4 : currentQuarter - 2 == -1 ? 3 : currentQuarter - 2, Year = currentQuarter <= 2 ? currentYear - 1 : currentYear } }; res.TestResultAvg = quarters.ToDictionary( q => q.Label, q => { var filteredResults = sportsTestResults .Where(x => x.ScoreTime >= Tool.GetQuarterStartDate(q.Quarter, q.Year) && x.ScoreTime <= Tool.GetQuarterEndDate(q.Quarter, q.Year)) .Select(x => x.Score) .ToList(); return filteredResults.Any() ? filteredResults.Average() : 0; } ); foreach (var stu in students) { var stuResults = monitorList.FirstOrDefault(c => c.StudentNo == stu.StudentNo); res.ClassDetailsList.Add(new ClassDetails() { StudentNo = stu.StudentNo, StudentName = stu.StudentName, Sex = stu.Sex == SexType.Male ? "男" : "女", GradeAndClassName = $"{classModel.GradeName}-{classModel.ClassName}", GradeId = classModel.GradeId, ClassId = classModel.Id, Rank = stuResults.Rank }); } return res; } /// /// 各体测项目等级占比 /// /// /// /// public async Task> CategoryRankRatio(CategoryParam paramDto) { var sportsTestResults = await _cacheQueryService.GeSportsTestDataCacheAsync(x => x.GradeId == paramDto.GradeId && x.ClassId == paramDto.ClassId && x.SchoolCode.Equals(UserContext.Current.TenantId) && x.CategoryValue == paramDto.CategoryValue , paramDto.Mode); var result = sportsTestResults .Where(x => x.CategoryValue == paramDto.CategoryValue) .GroupBy(x => x.Rank) .ToDictionary(g => g.Key, g => (float)g.Count()); int totalCount = sportsTestResults.Count(x => x.CategoryValue == paramDto.CategoryValue); if (totalCount == 0) { return new Dictionary(); } // 计算比例 foreach (var key in result.Keys.ToList()) { result[key] = (float)Math.Round(result[key] / totalCount, 2); } if (result != null) { // 计算并调整最后一个百分比(确保总和为100%) var sum = result.Values.Sum(c => c); var adjustment = 1 - sum; var lastKey = result.Keys.Last(); result[lastKey] += adjustment; // 如果最后一个值小于0.01,移除这一项 if (result[lastKey] < 0.01) { result.Remove(lastKey); } } return result; } /// /// 班级体侧等级占比人数 /// /// /// /// public async Task TestResultRankRate(ClassResultRankRate paramDto) { var res = new ExcellentRateChart(); var sportsTestResults = await _cacheQueryService.GeSportsTestDataCacheAsync(x => x.GradeId == paramDto.GradeId && x.ClassId == paramDto.ClassId && x.RankEnum == paramDto.Rank && x.SchoolCode.Equals(UserContext.Current.TenantId) , paramDto.Mode); var categoryList = await (from s in _sportsTestResultRepository.DbContext.Set() join n in _sportsTestResultRepository.DbContext.Set() on s.CategoryValue equals n.CategoryValue where s.GradeId == paramDto.GradeId select new { n.CategoryValue, n.CategoryName }).ToListAsync(); foreach (var category in categoryList) { var categoryResults = sportsTestResults.Where(x => x.CategoryValue == category.CategoryValue).ToList(); var sexAndOverall = new SexAndOverall { FemaleValue = categoryResults.Count(x => x.Sex == SexType.Female), MaleValue = categoryResults.Count(x => x.Sex == SexType.Male), OverallValue = categoryResults.Count() }; res.AxisX.Add(category.CategoryName); res.AxisY.Add(sexAndOverall); } return res; } /// /// 成绩趋势 /// /// /// /// public async Task ResultTrends(ClassResultTrendsParam paramDto) { var sportsTestResults = await _cacheQueryService.GeSportsTestDataCacheAsync(x => x.GradeId == paramDto.GradeId && x.ClassId == paramDto.ClassId && x.SchoolCode.Equals(UserContext.Current.TenantId) && x.CategoryValue == paramDto.CategoryValue , paramDto.Mode); var result = new VariousSportsProportion(); DateTime currentDate = DateTime.Now; switch (paramDto.CycleTime) { case CycleTimeEnum.InThePastWeek: // 近一周:按天展示 var pastWeekResults = sportsTestResults .Where(x => x.ScoreTime >= currentDate.AddDays(-7)) .GroupBy(x => x.ScoreTime.Date); foreach (var group in pastWeekResults) { result.AxisX.Add(group.Key.ToString("yyyy-MM-dd")); var score = (group.Sum(x => x.Score) + group.Sum(x => x.AdditionalScore)) / (group.Select(x => x.StudentNo).Distinct().Count()); result.AxisY.Add((float)Math.Round(score)); } break; case CycleTimeEnum.InThePastTwoWeeks: // 近两周:按天展示 var pastTwoWeeksResults = sportsTestResults .Where(x => x.ScoreTime >= currentDate.AddDays(-14)) .GroupBy(x => x.ScoreTime.Date); foreach (var group in pastTwoWeeksResults) { result.AxisX.Add(group.Key.ToString("yyyy-MM-dd")); var score = (group.Sum(x => x.Score) + group.Sum(x => x.AdditionalScore)) / (group.Select(x => x.StudentNo).Distinct().Count()); result.AxisY.Add((float)Math.Round(score)); } break; case CycleTimeEnum.InThePastMonth: // 近一月:每5天一个阶段展示 var pastMonthResults = sportsTestResults .Where(x => x.ScoreTime >= currentDate.AddDays(-30)) .GroupBy(x => (currentDate - x.ScoreTime).Days / 5); foreach (var group in pastMonthResults) { var minDate = group.Min(r => r.ScoreTime).ToString("yyyy-MM-dd"); var maxDate = group.Max(r => r.ScoreTime).ToString("yyyy-MM-dd"); result.AxisX.Add($"{minDate} - {maxDate}"); var score = (group.Sum(x => x.Score) + group.Sum(x => x.AdditionalScore)) / (group.Select(x => x.StudentNo).Distinct().Count()); result.AxisY.Add((float)Math.Round(score)); } break; case CycleTimeEnum.InThePastYear: // 近一年:按月展示 var pastYearResults = sportsTestResults .Where(x => x.ScoreTime >= currentDate.AddYears(-1)) .GroupBy(x => new { x.ScoreTime.Year, x.ScoreTime.Month }); foreach (var group in pastYearResults) { result.AxisX.Add($"{group.Key.Year}-{group.Key.Month:D2}"); var score = (group.Sum(x => x.Score) + group.Sum(x => x.AdditionalScore)) / (group.Select(x => x.StudentNo).Distinct().Count()); result.AxisY.Add((float)Math.Round(score)); } break; default: // 默认处理,如果没有匹配的情况 break; } return result; } } }