2025-06-06 16:00:39 +08:00
|
|
|
|
using AutoMapper;
|
|
|
|
|
using Castle.DynamicProxy.Generators;
|
|
|
|
|
using Microsoft.EntityFrameworkCore;
|
|
|
|
|
using Microsoft.Extensions.DependencyInjection;
|
|
|
|
|
using Newtonsoft.Json;
|
|
|
|
|
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
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 根据年级Id获取所有班级
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="gradeId"></param>
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
/// <exception cref="NotImplementedException"></exception>
|
|
|
|
|
public async Task<List<ClassNameModel>> GetClassNames(int gradeId)
|
|
|
|
|
{
|
|
|
|
|
var list = await (
|
|
|
|
|
from g in _classRepository.DbContext.Set<S_Class>()
|
|
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 获取班级列表
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="paramDto"></param>
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
/// <exception cref="NotImplementedException"></exception>
|
|
|
|
|
public async Task<PageDataDto<ClassPageListModel>> GetClassPageList(ClassPageListParam paramDto)
|
|
|
|
|
{
|
|
|
|
|
var tenantId = UserContext.Current.TenantId;
|
|
|
|
|
|
|
|
|
|
var teacherClassIds = new List<int>();
|
|
|
|
|
var isTeacher = (UserContext.Current.RoleId == 3);
|
|
|
|
|
|
|
|
|
|
if (isTeacher)
|
|
|
|
|
{
|
|
|
|
|
var teacher = await _classRepository.DbContext.Set<S_Teacher>().FirstOrDefaultAsync(x => x.SchoolCode == tenantId && x.TeacherPhoneNo == UserContext.Current.UserInfo.PhoneNo);
|
|
|
|
|
|
|
|
|
|
var teacherClassList = await (
|
|
|
|
|
from at in _classRepository.DbContext.Set<S_ClassAssocTeacher>()
|
|
|
|
|
join c in _classRepository.DbContext.Set<S_Class>() 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<S_Class>()
|
|
|
|
|
join g in _classRepository.DbContext.Set<S_Grade>() on c.GradeId equals g.Id
|
|
|
|
|
join a in _classRepository.DbContext.Set<S_SchoolAssocGrade>() 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<S_ClassAssocTeacher>()
|
|
|
|
|
join t in _classRepository.DbContext.Set<S_Teacher>() 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<S_Student>()
|
|
|
|
|
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<ClassPageListModel>
|
|
|
|
|
{
|
|
|
|
|
Total = classIds.Count,
|
|
|
|
|
Datas = result
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 导出班级
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="paramDto"></param>
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
/// <exception cref="NotImplementedException"></exception>
|
|
|
|
|
public async Task<List<ClassPageListModel>> GetClassList(ClassPageListExportParam paramDto)
|
|
|
|
|
{
|
|
|
|
|
var tenantId = UserContext.Current.TenantId;
|
|
|
|
|
|
|
|
|
|
var teacherClassIds = new List<int>();
|
|
|
|
|
var isTeacher = (UserContext.Current.RoleId == 3);
|
|
|
|
|
|
|
|
|
|
if (isTeacher)
|
|
|
|
|
{
|
|
|
|
|
var teacher = await _classRepository.DbContext.Set<S_Teacher>().FirstOrDefaultAsync(x => x.SchoolCode == tenantId && x.TeacherPhoneNo == UserContext.Current.UserInfo.PhoneNo);
|
|
|
|
|
|
|
|
|
|
var teacherClassList = await (
|
|
|
|
|
from at in _classRepository.DbContext.Set<S_ClassAssocTeacher>()
|
|
|
|
|
join c in _classRepository.DbContext.Set<S_Class>() 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<S_Class>()
|
|
|
|
|
join g in _classRepository.DbContext.Set<S_Grade>() on c.GradeId equals g.Id
|
|
|
|
|
join a in _classRepository.DbContext.Set<S_SchoolAssocGrade>() 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<S_ClassAssocTeacher>()
|
|
|
|
|
join t in _classRepository.DbContext.Set<S_Teacher>() 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<S_Student>()
|
|
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 班级详情
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="classId"></param>
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
/// <exception cref="NotImplementedException"></exception>
|
|
|
|
|
public async Task<ClassDetailsModel> 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
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 更新班级
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="paramDto"></param>
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
/// <exception cref="NotImplementedException"></exception>
|
|
|
|
|
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<S_ClassAssocTeacher>();
|
|
|
|
|
|
|
|
|
|
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);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 添加班级
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="paramDto"></param>
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
/// <exception cref="NotImplementedException"></exception>
|
|
|
|
|
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<S_ClassAssocTeacher>();
|
|
|
|
|
|
|
|
|
|
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<S_Class>() { classEntity })
|
|
|
|
|
//}));
|
|
|
|
|
|
|
|
|
|
await _iotDataSyncService.DataSyncCallBack(new DataSyncCallBackParam
|
|
|
|
|
{
|
|
|
|
|
EventType = EventType.Add.GetDisplayName(),
|
|
|
|
|
DataType = IOTDataSyncType.Class.GetDisplayName(),
|
|
|
|
|
Json = JsonConvert.SerializeObject(new List<S_Class>() { classEntity })
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
catch (Exception ex)
|
|
|
|
|
{
|
|
|
|
|
// 发生错误,回滚事务
|
|
|
|
|
transaction.Rollback();
|
|
|
|
|
Console.WriteLine("事务回滚:" + ex.Message);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 批量添加班级
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="paramDto"></param>
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
/// <exception cref="NotImplementedException"></exception>
|
|
|
|
|
public async Task BatchAddClass(BatchAddClassParam paramDto)
|
|
|
|
|
{
|
|
|
|
|
var tenantId = UserContext.Current.TenantId;
|
|
|
|
|
|
|
|
|
|
var classEntityList = new List<S_Class>();
|
|
|
|
|
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<S_ClassAssocTeacher>();
|
|
|
|
|
|
|
|
|
|
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<ClassDataStatsModel> 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<S_Class>().First().Id;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var classModel = await (from c in _classRepository.DbContext.Set<S_Class>()
|
|
|
|
|
join a in _classRepository.DbContext.Set<S_ClassAssocTeacher>() on c.Id equals a.ClassId into associations
|
|
|
|
|
from association in associations.DefaultIfEmpty()
|
|
|
|
|
join t in _classRepository.DbContext.Set<S_Teacher>() 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();
|
2025-06-06 16:55:14 +08:00
|
|
|
|
|
|
|
|
|
res.ExcellentRate = totalCount > 0 ? Math.Round((monitorList.Count(x => x.Rank == "优秀") / totalCount) * 100) : 0;
|
|
|
|
|
res.FineRate = totalCount > 0 ? Math.Round((monitorList.Count(x => x.Rank == "良好") / totalCount) * 100) : 0;
|
|
|
|
|
res.PassRate = totalCount > 0 ? Math.Round((monitorList.Count(x => x.Rank == "及格") / totalCount) * 100) : 0;
|
|
|
|
|
res.FailRate = totalCount > 0 ? Math.Round((monitorList.Count(x => x.Rank == "不及格") / totalCount) * 100) : 0;
|
2025-06-06 16:00:39 +08:00
|
|
|
|
|
|
|
|
|
if (res != null)
|
|
|
|
|
{
|
|
|
|
|
// 计算并调整最后一个百分比(确保总和为100%)
|
|
|
|
|
double sum = (res.ExcellentRate + res.FineRate + res.PassRate + res.FailRate);
|
|
|
|
|
double adjustment = 100 - sum;
|
2025-06-06 16:55:14 +08:00
|
|
|
|
res.FailRate += (totalCount > 0 ? adjustment : 0);
|
2025-06-06 16:00:39 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 各体测项目等级占比
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="paramDto"></param>
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
/// <exception cref="NotImplementedException"></exception>
|
|
|
|
|
public async Task<Dictionary<string, float>> 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<string, float>();
|
|
|
|
|
}
|
|
|
|
|
|
2025-06-06 16:55:14 +08:00
|
|
|
|
if (paramDto.CategoryValue == (int)SportsTestItemType.BMI)
|
|
|
|
|
{
|
|
|
|
|
var newResult = new Dictionary<string, float>();
|
|
|
|
|
foreach (var kvp in result)
|
|
|
|
|
{
|
|
|
|
|
string newRank = kvp.Key switch
|
|
|
|
|
{
|
|
|
|
|
"正常" => "优秀",
|
|
|
|
|
"超重" => "及格",
|
|
|
|
|
"偏瘦" => "良好",
|
|
|
|
|
"肥胖" => "不及格",
|
|
|
|
|
_ => kvp.Key
|
|
|
|
|
};
|
|
|
|
|
if (newResult.ContainsKey(newRank))
|
|
|
|
|
{
|
|
|
|
|
newResult[newRank] += kvp.Value;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
newResult[newRank] = kvp.Value;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
result = newResult;
|
|
|
|
|
}
|
|
|
|
|
|
2025-06-06 16:00:39 +08:00
|
|
|
|
// 计算比例
|
|
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 班级体侧等级占比人数
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="paramDto"></param>
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
/// <exception cref="NotImplementedException"></exception>
|
|
|
|
|
public async Task<ExcellentRateChart> 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<S_GradeAssocCategory>()
|
|
|
|
|
join n in _sportsTestResultRepository.DbContext.Set<N_SportsTestCategory>()
|
|
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 成绩趋势
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="paramDto"></param>
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
/// <exception cref="NotImplementedException"></exception>
|
|
|
|
|
public async Task<VariousSportsProportion> 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;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|