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;
}
}
}