using AutoMapper; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Metadata.Internal; using Microsoft.Extensions.DependencyInjection; using Quartz; using System; using System.Collections.Generic; using System.Linq; using System.Linq.Expressions; using System.Text; using System.Threading.Tasks; using VOL.Business.IRepositories; using VOL.Business.IServices; using VOL.Business.IServices.Norm; using VOL.Business.Repositories; using VOL.Core.CacheManager; using VOL.Core.Extensions; using VOL.Core.Extensions.AutofacManager; using VOL.Core.ManageUser; using VOL.Core.Utilities; using VOL.Entity.DomainModels; using VOL.Entity.Enum; using VOL.Model; using VOL.Model.Ai; using VOL.Model.Norm.Request; using VOL.Model.Norm.Response; using VOL.Model.School.Response; using VOL.System.IRepositories; using VOL.System.Repositories; using static Microsoft.EntityFrameworkCore.DbLoggerCategory; namespace VOL.Business.Services.Norm { public class G_ActivitiesService : IG_ActivitiesService, IDependency { #region 初始化 private readonly IMapper _mapper; private readonly IG_ActivitiesRepository _activitiesRepository; private readonly ICacheQueryService _cacheQueryService; private readonly IN_SportsTestResultRepository _sportsTestResultRepository; [ActivatorUtilitiesConstructor] public G_ActivitiesService(IMapper mapper, IG_ActivitiesRepository activitiesRepository, IN_SportsTestResultRepository sportsTestResultRepository, ICacheQueryService cacheQueryService) { _mapper = mapper; _activitiesRepository = activitiesRepository; _sportsTestResultRepository = sportsTestResultRepository; _cacheQueryService = cacheQueryService; } #endregion public async Task> GetActivitiesPageList(ActivitiesPageListParam paramDto) { var res = new PageDataDto(); var query = from s in _activitiesRepository.DbContext.Set() where s.SchoolCode.Equals(UserContext.Current.TenantId) select new ActivitiesListModel() { Id = s.Id, ActivitiesName = s.ActivitiesName, CategoryId = s.CategoryId, CategoryName = s.CategoryName, EndDate = s.EndDate, StartDate = s.StartDate, ActivitiesStatus = s.ActivitiesStatus, ActivitiesStatusName = s.ActivitiesStatus.Description(), ImagePath = s.ImagePath, ActivitiesGradeClassList = s.EntryStudents .GroupBy(x => new { x.GradeId, x.ClassId }) .OrderBy(g => g.Key.GradeId) .ThenBy(g => g.Key.ClassId) .Select(g => new ActivitiesGradeClassModel() { ClassName = g.First().ClassName, GradeName = g.First().GradeName }) .ToList() }; if (!string.IsNullOrWhiteSpace(paramDto.ActivitiesName)) { query = query.Where(x => x.ActivitiesName.Contains(paramDto.ActivitiesName)); } if (paramDto.ActivitiesStatus > 0) { query = query.Where(x => x.ActivitiesStatus == paramDto.ActivitiesStatus); } if (paramDto.CategoryId > 0) { query = query.Where(x => x.CategoryId == paramDto.CategoryId); } if (paramDto.StartDate.HasValue) { DateTime detectionDate = paramDto.StartDate.Value.Date; query = query.Where(x => x.StartDate.HasValue && x.StartDate.Value.Date >= detectionDate); } if (paramDto.EndDate.HasValue) { DateTime detectionDate = paramDto.EndDate.Value.Date; query = query.Where(x => x.EndDate.HasValue && x.EndDate.Value.Date < detectionDate); } res.Total = await query.CountAsync(); var list = await query .OrderByDescending(x => x.Id) .Skip((paramDto.PageIndex - 1) * paramDto.PageSize) .Take(paramDto.PageSize) .ToListAsync(); res.Datas = list; return res; } public async Task> GetActivitiesList(ActivitiesExportParam paramDto) { var query = from s in _activitiesRepository.DbContext.Set() where s.SchoolCode.Equals(UserContext.Current.TenantId) select new ActivitiesListModel() { Id = s.Id, ActivitiesName = s.ActivitiesName, CategoryId = s.CategoryId, CategoryName = s.CategoryName, EndDate = s.EndDate, StartDate = s.StartDate, ActivitiesStatus = s.ActivitiesStatus, ActivitiesStatusName = s.ActivitiesStatus.GetDescription(), ImagePath = s.ImagePath }; if (!string.IsNullOrWhiteSpace(paramDto.ActivitiesName)) { query = query.Where(x => x.ActivitiesName.Contains(paramDto.ActivitiesName)); } if (paramDto.ActivitiesStatus > 0) { query = query.Where(x => x.ActivitiesStatus.Equals(paramDto.ActivitiesStatus.GetDescription())); } if (paramDto.StartDate.HasValue) { DateTime detectionDate = paramDto.StartDate.Value.Date; query = query.Where(x => x.StartDate.HasValue && x.StartDate.Value.Date >= detectionDate); } if (paramDto.EndDate.HasValue) { DateTime detectionDate = paramDto.EndDate.Value.Date; query = query.Where(x => x.EndDate.HasValue && x.EndDate.Value.Date < detectionDate); } var list = await query.OrderByDescending(x => x.Id).ToListAsync(); return list; } public async Task> GetActivitiesNameList() { var list = await _activitiesRepository.FindAsIQueryable(x => x.ActivitiesStatus == ActivitiesStatus.NotStarted).Select(x => new ActivitiesListNameModel() { Id = x.Id, ActivitiesName = x.ActivitiesName }).ToListAsync(); return list; } public List GetActivitiesCategoryList() { var res = new List() { /* new ActivitiesCategoryModel() { SportsTestType = SportsTestDataType.TrainingData, CategorId = (int)TrainingItemType.Coordinate, CategoryName=TrainingItemType.Coordinate.GetDisplayName() }, new ActivitiesCategoryModel() { SportsTestType = SportsTestDataType.SportsTestData, CategorId = (int)SportsTestItemType.StandingLongJump, CategoryName=SportsTestItemType.StandingLongJump.GetDisplayName() }, new ActivitiesCategoryModel() { SportsTestType = SportsTestDataType.SportsTestData, CategorId = (int)SportsTestItemType.Sit_And_Reach, CategoryName=SportsTestItemType.Sit_And_Reach.GetDisplayName() }, new ActivitiesCategoryModel() { SportsTestType = SportsTestDataType.SportsTestData, CategorId = (int)SportsTestItemType.Pull_Up, CategoryName=SportsTestItemType.Pull_Up.GetDisplayName() }, */ new ActivitiesCategoryModel() { SportsTestType = SportsTestDataType.TrainingData, CategorId = (int)TrainingItemType.JumpingJack, CategoryName=TrainingItemType.JumpingJack.GetDisplayName() }, new ActivitiesCategoryModel() { SportsTestType = SportsTestDataType.TrainingData, CategorId = (int)TrainingItemType.JumpSquat, CategoryName=TrainingItemType.JumpSquat.GetDisplayName() }, new ActivitiesCategoryModel() { SportsTestType = SportsTestDataType.TrainingData, CategorId = (int)TrainingItemType.HighKnee, CategoryName=TrainingItemType.HighKnee.GetDisplayName() }, new ActivitiesCategoryModel() { SportsTestType = SportsTestDataType.TrainingData, CategorId = (int)TrainingItemType.KneeDrivePalmarPalpation, CategoryName=TrainingItemType.KneeDrivePalmarPalpation.GetDisplayName() } /* new ActivitiesCategoryModel() { SportsTestType = SportsTestDataType.TrainingData, CategorId = (int)TrainingItemType.CrossQuadrantJump, CategoryName=TrainingItemType.CrossQuadrantJump.GetDisplayName() }*/ }; return res; } public async Task AddActivities(ActivitiesDetailsParam paramDto) { if (paramDto == null) throw new ArgumentNullException($"{nameof(paramDto)}参数为空"); var entitys = new G_Activities() { ActivitiesName = paramDto.ActivitiesName, ActivitiesStatus = ActivitiesStatus.NotStarted, SportsTestDataType = paramDto.SportsTestDataType, CategoryId = paramDto.CategoryId, CategoryName = paramDto.CategoryName, StartDate = paramDto.StartDate, EndDate = paramDto.EndDate, ImagePath = paramDto.ImagePath, ParticipantType = paramDto.ParticipantType, SchoolCode = UserContext.Current.TenantId, Creator = UserContext.Current.UserId, CreateDate = DateTime.Now }; // 全部学生 if (entitys.ParticipantType == ParticipantType.AllStudents) { var entryStudent = from s in _activitiesRepository.DbContext.Set() join c in _activitiesRepository.DbContext.Set() on s.ClassId equals c.Id into sclasss from sclass in sclasss.DefaultIfEmpty() where s.SchoolCode.Equals(UserContext.Current.TenantId) select new G_EntryStudent() { SchoolCode = s.SchoolCode, GradeId = sclass != null ? sclass.GradeId : 0, GradeName = sclass != null ? sclass.GradeName : "", ClassId = sclass != null ? sclass.Id : 0, ClassName = sclass != null ? sclass.ClassName : "", StudentNo = s.StudentNo, StudentName = s.StudentName, Sex = s.Sex, Age = s.Age, Photo = s.Photo }; entitys.EntryStudents = await entryStudent.ToListAsync(); } // 自定义学生 if (entitys.ParticipantType == ParticipantType.CustomStudent) { var studentNoList = paramDto.GradeClassStudentList.SelectMany(c => c.EntryStudentNoList).ToList(); var entryStudent = from s in _activitiesRepository.DbContext.Set() join c in _activitiesRepository.DbContext.Set() on s.ClassId equals c.Id into sclasss from sclass in sclasss.DefaultIfEmpty() where s.SchoolCode.Equals(UserContext.Current.TenantId) && studentNoList.Contains(s.StudentNo) select new G_EntryStudent() { SchoolCode = s.SchoolCode, GradeId = sclass != null ? sclass.GradeId : 0, GradeName = sclass != null ? sclass.GradeName : "", ClassId = sclass != null ? sclass.Id : 0, ClassName = sclass != null ? sclass.ClassName : "", StudentNo = s.StudentNo, StudentName = s.StudentName, Sex = s.Sex, Age = s.Age, Photo = s.Photo }; entitys.EntryStudents = await entryStudent.ToListAsync(); } await _activitiesRepository.AddAsync(entitys); await _activitiesRepository.SaveChangesAsync(); return entitys.Id; } public async Task ModifyActivities(ActivitiesDetailsParam paramDto) { if (paramDto == null || paramDto.Id == 0) throw new ArgumentNullException($"参数为空"); var model = await _activitiesRepository.FindAsyncFirst(x => x.Id == paramDto.Id); if (model == null) throw new ArgumentNullException($"未找到要更新的数据"); if (model.ActivitiesStatus != ActivitiesStatus.NotStarted) throw new ArgumentNullException($"已开始无法修改"); model.ActivitiesName = paramDto.ActivitiesName; model.SportsTestDataType = paramDto.SportsTestDataType; model.CategoryName = paramDto.CategoryName; model.CategoryId = paramDto.CategoryId; model.ActivitiesStatus = ActivitiesStatus.NotStarted; model.StartDate = paramDto.StartDate; model.EndDate = paramDto.EndDate; model.EndDate = paramDto.EndDate; model.ImagePath = paramDto.ImagePath; model.ParticipantType = paramDto.ParticipantType; model.Modifier = UserContext.Current.UserId; model.ModifyDate = DateTime.Now; await this.ModifyActivitiesEntryStudent(paramDto); _activitiesRepository.Update(model); await _activitiesRepository.SaveChangesAsync(); } public async Task ModifyActivitiesStatus(int id, ActivitiesStatus status) { var model = await _activitiesRepository.FindAsyncFirst(x => x.Id == id); if (model == null) throw new ArgumentNullException($"未找到要更新的数据"); model.ActivitiesStatus = status; model.ModifyDate = DateTime.Now; _activitiesRepository.Update(model); await _activitiesRepository.SaveChangesAsync(); } public async Task ModifyActivitiesEntryStudent(ActivitiesDetailsParam paramDto) { var deleteEntryStudents = await this._activitiesRepository.FindAsync(c => c.SchoolCode == UserContext.Current.TenantId && c.ActivitiesId == paramDto.Id); foreach (var item in deleteEntryStudents) { _activitiesRepository.Delete(item); } var entryStudents = new List(); // 全部学生 if (paramDto.ParticipantType == ParticipantType.AllStudents) { var entryStudent = from s in _activitiesRepository.DbContext.Set() join c in _activitiesRepository.DbContext.Set() on s.ClassId equals c.Id into sclasss from sclass in sclasss.DefaultIfEmpty() where s.SchoolCode.Equals(UserContext.Current.TenantId) select new G_EntryStudent() { ActivitiesId = paramDto.Id, SchoolCode = s.SchoolCode, GradeId = sclass.GradeId, GradeName = sclass.GradeName, ClassId = sclass.Id, ClassName = sclass.ClassName, StudentNo = s.StudentNo, StudentName = s.StudentName, Sex = s.Sex, Age = s.Age, Photo = s.Photo }; entryStudents = await entryStudent.ToListAsync(); } // 自定义学生 if (paramDto.ParticipantType == ParticipantType.CustomStudent) { var studentNoList = paramDto.GradeClassStudentList.SelectMany(c => c.EntryStudentNoList).ToList(); var entryStudent = from s in _activitiesRepository.DbContext.Set() join c in _activitiesRepository.DbContext.Set() on s.ClassId equals c.Id into sclasss from sclass in sclasss.DefaultIfEmpty() where s.SchoolCode.Equals(UserContext.Current.TenantId) && studentNoList.Contains(s.StudentNo) select new G_EntryStudent() { ActivitiesId = paramDto.Id, SchoolCode = s.SchoolCode, GradeId = sclass.GradeId, GradeName = sclass.GradeName, ClassId = sclass.Id, ClassName = sclass.ClassName, StudentNo = s.StudentNo, StudentName = s.StudentName, Sex = s.Sex, Age = s.Age, Photo = s.Photo }; entryStudents = await entryStudent.ToListAsync(); } _activitiesRepository.AddRange(entryStudents); } /// /// 上传活动照片 /// public string UploadActivitiesImage(IFormFile file) { var url = ALiYunOss.Upload(file, $"Upload/{UserContext.Current.TenantId}/Activities/", file.FileName, true); return url; } public async Task DeleteActivities(List Ids) { var model = await _activitiesRepository.FindAsync(x => Ids.Contains(x.Id)); if (model == null) throw new ArgumentNullException($"未找到删除的数据"); _activitiesRepository.DbContext.RemoveRange(model); await _activitiesRepository.SaveChangesAsync(); } public async Task GetActivitiesDetails(int id) { if (id <= 0) { throw new ArgumentNullException("请求参数错误"); } var model = await _activitiesRepository.FindAsyncFirst(x => x.Id == id); if (model == null) { throw new ArgumentNullException("未找到数据"); } var entryStudents = await this._activitiesRepository.FindAsync(c => c.SchoolCode == UserContext.Current.TenantId && c.ActivitiesId == id); var classEntitys = await this._activitiesRepository.FindAsync(c => c.SchoolCode == UserContext.Current.TenantId); var classStudentCounts = await _activitiesRepository.DbContext.Set() .Where(s => s.SchoolCode == UserContext.Current.TenantId) .GroupBy(s => s.ClassId) .Select(g => new { ClassId = g.Key, Total = g.Count() }) .ToDictionaryAsync(x => x.ClassId, x => x.Total); var result = new ActivitiesDetailsModel() { Id = model.Id, EndDate = model.EndDate, StartDate = model.StartDate, ActivitiesName = model.ActivitiesName, ActivitiesStatus = model.ActivitiesStatus, CategoryId = model.CategoryId, CategoryName = model.CategoryName, ImagePath = model.ImagePath, ParticipantType = model.ParticipantType, GradeClassStudentList = classEntitys .OrderBy(c => c.GradeId) .ThenBy(c => c.Id) .Select(c => { // 获取当前班级参与人数 var participateCount = entryStudents.Count(d => d.ClassId == c.Id && d.GradeId == c.GradeId); // 获取当前班级总人数 var totalStudents = classStudentCounts.GetValueOrDefault(c.Id, 0); return new ActivitiesGradeClassDetailsModel() { ClassId = c.Id, GradeId = c.GradeId, ClassName = c.ClassName, GradeName = c.GradeName, IsAllParticipate = totalStudents > 0 && participateCount == totalStudents, // 判断是否全参与 IsParticipate = participateCount > 0, // 简化的参与判断 NumberParticipate = participateCount }; }) .ToList() }; return result; } /// /// 获取学生详情 /// /// /// public async Task> GetActivitiesStudentDetails(int classId, int activitiesId) { var entryStudentEntitys = await this._activitiesRepository.FindAsync(c => c.SchoolCode == UserContext.Current.TenantId && c.ClassId == classId && c.Activities.Id == activitiesId); var studentEntitys = await this._activitiesRepository.FindAsync(c => c.SchoolCode == UserContext.Current.TenantId && c.ClassId == classId && !entryStudentEntitys.Select(d => d.StudentNo).Contains(c.StudentNo)); var combinedList = entryStudentEntitys.Select(c => new ActivitiesStudentDetailsModel() { IsParticipate = true, StudentNo = c.StudentNo, StudentName = c.StudentName, Sex = c.Sex, Age = c.Age, Photo = c.Photo }) .Concat( studentEntitys.Select(c => new ActivitiesStudentDetailsModel() { IsParticipate = false, StudentNo = c.StudentNo, StudentName = c.StudentName, Sex = c.Sex, Age = c.Age, Photo = c.Photo }) ) .OrderBy(c => c.Age) .ToList(); return combinedList; } /// /// 获取赛事统计列表 /// /// /// public async Task> GetActivitiesStatisticsPageList(ActivitiesStatisticsPageListParam paramDto) { var res = new PageDataDto(); var query = from s in _activitiesRepository.DbContext.Set() where s.SchoolCode.Equals(UserContext.Current.TenantId) select new ActivitiesStatisticsModel { Id = s.Id, ActivitiesName = s.ActivitiesName, CategoryId = s.CategoryId, CategoryName = s.CategoryName, EndDate = s.EndDate, StartDate = s.StartDate, ActivitiesStatus = s.ActivitiesStatus, ActivitiesStatusName = s.ActivitiesStatus.GetDescription(), ImagePath = s.ImagePath, ParticipantsCount = s.EntryStudents.Count() }; if (!string.IsNullOrWhiteSpace(paramDto.ActivitiesName)) { query = query.Where(x => x.ActivitiesName.Equals(paramDto.ActivitiesName)); } if (paramDto.CategoryId > 0) { query = query.Where(x => x.CategoryId == paramDto.CategoryId); } if (paramDto.StartDate.HasValue) { DateTime detectionDate = paramDto.StartDate.Value.Date; query = query.Where(x => x.StartDate.HasValue && x.StartDate.Value.Date >= detectionDate); } if (paramDto.EndDate.HasValue) { DateTime detectionDate = paramDto.EndDate.Value.Date; query = query.Where(x => x.EndDate.HasValue && x.EndDate.Value.Date < detectionDate); } res.Total = await query.CountAsync(); var list = await query .OrderByDescending(x => x.Id) .Skip((paramDto.PageIndex - 1) * paramDto.PageSize) .Take(paramDto.PageSize) .ToListAsync(); var sportsTestData = _sportsTestResultRepository.DbContext.Set() .Where(at => at.ActivitiesId != null && at.RankEnum != AchievementRank.Fail) .ToList(); foreach (var item in list) { item.CompletedCount = sportsTestData .Where(at => at.ActivitiesId == item.Id) .Count(); } res.Datas = list; return res; } /// /// 赛事统计详情 /// /// public async Task> GetActivitiesStatisticsDetails(ActivitiesStatisticsDetailsParam paramDto) { var entryStudents = await this._activitiesRepository.FindAsync(c => c.SchoolCode == UserContext.Current.TenantId && c.ActivitiesId == paramDto.ActivitiesId); var query = from st in _activitiesRepository.DbContext.Set() join s in _activitiesRepository.DbContext.Set() on st.StudentNo equals s.StudentNo where st.SchoolCode.Equals(UserContext.Current.TenantId) && st.ActivitiesId.Equals(paramDto.ActivitiesId) && st.TrainingModule == Ai_TrainingModuleEnum.Arena && ( (paramDto.ScoreStatus == 1 && st.RankEnum != AchievementRank.Fail) || (paramDto.ScoreStatus == 2 && st.RankEnum == AchievementRank.Fail) ) select new ActivitiesStatisticsDetailsModel { GradeAndClass = $"{st.GradeName}-{st.ClassName}", StudentName = s.StudentName, Sex = s.Sex == SexType.Male ? "男" : "女", Age = s.Age, Score = st.Score }; var list = await query.ToListAsync(); if (paramDto.ScoreStatus == 2) { var uncompletedStudents = entryStudents.Where(es => !list.Any(l => l.StudentName == es.StudentName)) .Select(es => new ActivitiesStatisticsDetailsModel { GradeAndClass = $"{es.GradeName}-{es.ClassName}", StudentName = es.StudentName, Sex = es.Sex == SexType.Male ? "男" : "女", Age = es.Age, Score = 0 }).ToList(); list.AddRange(uncompletedStudents); } return list.OrderBy(c => c.Score) .Select((c, index) => { c.Ranking = index + 1; return c; }) .ToList(); } } }