using AutoMapper;
using Castle.DynamicProxy.Generators;
using Confluent.Kafka;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.ML;
using OfficeOpenXml.ConditionalFormatting;
using OfficeOpenXml.FormulaParsing.Excel.Functions.DateTime;
using OfficeOpenXml.FormulaParsing.Excel.Functions.Math;
using OfficeOpenXml.FormulaParsing.Excel.Functions.Text;
using SkiaSharp;
using StackExchange.Redis;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Dynamic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using VOL.Business.IServices;
using VOL.Business.IServices.Norm;
using VOL.Core.CacheManager;
using VOL.Core.Configuration;
using VOL.Core.Extensions;
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.Norm.Request;
using VOL.Model.Norm.Response;
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
{
public class N_SportsTestResultService : IN_SportsTestResultService, IDependency
{
#region 初始化
private readonly IMapper _mapper;
private readonly ICacheService _cacheService;
private readonly ICacheQueryService _cacheQueryService;
private readonly IN_SportsTestResultRepository _sportsTestResultRepository;
private readonly IS_GradeRepository _gradeRepository;
private readonly IS_ClassRepository _classRepository;
private readonly IS_StudentRepository _studentRepository;
private readonly IN_HealthStandardsRepository _healthStandardsRepository;
private readonly IN_SportsTestCategoryRepository _sportsTestCategoryRepository;
//private readonly IG_ActivitiesRepository _activitiesRepository;
[ActivatorUtilitiesConstructor]
public N_SportsTestResultService(IMapper mapper,
ICacheService cacheService,
ICacheQueryService cacheQueryService,
IN_SportsTestResultRepository sportsTestResultRepository,
IS_GradeRepository gradeRepository,
IS_ClassRepository classRepository,
IS_StudentRepository studentRepository,
IN_HealthStandardsRepository healthStandardsRepository,
IN_SportsTestCategoryRepository sportsTestCategoryRepository
//IG_ActivitiesRepository activitiesRepository
)
{
_mapper = mapper;
_cacheService = cacheService;
_cacheQueryService = cacheQueryService;
_sportsTestResultRepository = sportsTestResultRepository;
_gradeRepository = gradeRepository;
_classRepository = classRepository;
_studentRepository = studentRepository;
_healthStandardsRepository = healthStandardsRepository;
_sportsTestCategoryRepository = sportsTestCategoryRepository;
//_activitiesRepository = activitiesRepository;
}
#endregion
///
/// 导入学生体测成绩
///
///
///
///
public async Task ImportStudentsTestData(IFormFile file)
{
if (file == null || file.Length <= 0)
throw new Exception("操作失败");
List dataObjects;
using (var fileStream = file.OpenReadStream())
{
dataObjects = Tool.ConvertExcelToList(fileStream);
}
var studentNos = dataObjects.Select(x => x.StudentNo).Distinct().ToList();
// 用一个查询一次性获取所有学生信息
var students = await (from s in _studentRepository.DbContext.Set()
join c in _studentRepository.DbContext.Set() on s.ClassId equals c.Id
join g in _studentRepository.DbContext.Set() on c.GradeId equals g.Id
where c.SchoolCode.Equals(UserContext.Current.TenantId)
select new
{
s.Id,
s.Age,
s.ClassId,
c.ClassName,
s.StudentName,
GradeId = g.Id,
g.GradeName,
s.Sex,
s.StudentNo
}).ToListAsync();
// 将学生信息存入字典,快速查找
var studentsDict = students.ToDictionary(x => x.StudentNo);
var entityList = new List();
// 将时间变量移到外部,避免重复赋值
var timeNow = DateTime.Now;
foreach (var data in dataObjects)
{
if (!studentsDict.TryGetValue(data.StudentNo, out var student))
{
throw new Exception($"未找到此编号为{data.StudentNo}的学生");
}
// 为每个学生添加多条体测数据
if (data.BMIValue > 0)
entityList.Add(await AddEnumStudentsTestData(data, SportsTestItemType.BMI, student, timeNow));
if (data.Sit_And_ReachValue > 0)
entityList.Add(await AddEnumStudentsTestData(data, SportsTestItemType.Sit_And_Reach, student, timeNow));
if (data.VitalCapacityValue > 0)
entityList.Add(await AddEnumStudentsTestData(data, SportsTestItemType.VitalCapacity, student, timeNow));
if (data.MeterRun_50Value > 0)
entityList.Add(await AddEnumStudentsTestData(data, SportsTestItemType.MeterRun_50, student, timeNow));
if (data.OneMinuteJumpRopeValue > 0)
entityList.Add(await AddEnumStudentsTestData(data, SportsTestItemType.OneMinuteJumpRope, student, timeNow));
if (data.One_Minute_Sit_UpValue > 0)
entityList.Add(await AddEnumStudentsTestData(data, SportsTestItemType.One_Minute_Sit_Up, student, timeNow));
if (data.ShuttleRun_50x8Value > 0)
entityList.Add(await AddEnumStudentsTestData(data, SportsTestItemType.ShuttleRun_50x8, student, timeNow));
if (data.StandingLongJumpValue > 0)
entityList.Add(await AddEnumStudentsTestData(data, SportsTestItemType.StandingLongJump, student, timeNow));
if (data.MeterRun_800Value > 0)
entityList.Add(await AddEnumStudentsTestData(data, SportsTestItemType.MeterRun_800, student, timeNow));
if (data.MeterRun_1000Value > 0)
entityList.Add(await AddEnumStudentsTestData(data, SportsTestItemType.MeterRun_1000, student, timeNow));
if (data.Pull_UpValue > 0)
entityList.Add(await AddEnumStudentsTestData(data, SportsTestItemType.Pull_Up, student, timeNow));
}
// 批量添加数据
await _sportsTestResultRepository.AddRangeAsync(entityList);
// 一次性保存所有修改
await _sportsTestResultRepository.SaveChangesAsync();
}
public async Task AddEnumStudentsTestData(ImportStudentsTestDataParam data, SportsTestItemType type, dynamic student, DateTime timeNow)
{
int classId = student.ClassId;
var teachers = await (from c in _studentRepository.DbContext.Set()
join t in _studentRepository.DbContext.Set() on c.TeacherId equals t.Id
where c.ClassId == classId
select new
{
t.Id,
t.TeacherName
}).FirstOrDefaultAsync();
var entity = new N_SportsTestValue
{
TeacherId = teachers?.Id ?? 0,
TeacherName = teachers?.TeacherName ?? string.Empty,
DataSource = DataSource.IOT,
ScoreTime = timeNow,
GradeId = student.GradeId,
ClassId = student.ClassId,
GradeName = student.GradeName,
ClassName = student.ClassName,
SchoolCode = UserContext.Current.TenantId,
Sex = student.Sex,
StudentNo = data.StudentNo,
StudentName = student.StudentName,
Creator = UserContext.Current.UserId,
CreateDate = timeNow,
IsDisplay = true
};
int gradeId = student.GradeId;
SexType sexType = student.Sex;
string sex = sexType == SexType.Male ? "男" : "女";
string typeStr = type.ToString();
// 根据测试项目类型设置对应的值
if (type == SportsTestItemType.BMI)
{
entity.Value = data.BMIValue;
entity.Weight = data.Weight;
entity.Height = data.Height;
// 根据测试项目查找标准
var standard = await _healthStandardsRepository.FindFirstAsync(x =>
x.CategoryEnum.Equals(typeStr) &&
x.GradeId == gradeId &&
x.Sex == sexType &&
data.BMIValue >= x.MinValue &&
data.BMIValue < x.MaxValue
);
if (standard != null)
{
entity.Score = standard.Score;
entity.Rank = standard.Rank;
}
}
else if (type == SportsTestItemType.Sit_And_Reach)
{
entity.Value = data.Sit_And_ReachValue;
// 根据测试项目查找标准
var standard = await _healthStandardsRepository.FindFirstAsync(x =>
x.CategoryEnum.Equals(typeStr) &&
x.GradeId == gradeId &&
x.Sex == sexType &&
data.Sit_And_ReachValue >= x.MinValue &&
data.Sit_And_ReachValue < x.MaxValue
);
if (standard != null)
{
entity.Score = standard.Score;
entity.Rank = standard.Rank;
}
}
else if (type == SportsTestItemType.VitalCapacity)
{
entity.Value = data.VitalCapacityValue;
// 根据测试项目查找标准
var standard = await _healthStandardsRepository.FindFirstAsync(x =>
x.CategoryEnum.Equals(typeStr) &&
x.GradeId == gradeId &&
x.Sex == sexType &&
data.VitalCapacityValue >= x.MinValue &&
data.VitalCapacityValue < x.MaxValue
);
if (standard != null)
{
entity.Score = standard.Score;
entity.Rank = standard.Rank;
}
}
else if (type == SportsTestItemType.MeterRun_50)
{
entity.Value = data.MeterRun_50Value;
// 根据测试项目查找标准
var standard = await _healthStandardsRepository.FindFirstAsync(x =>
x.CategoryEnum.Equals(typeStr) &&
x.GradeId == gradeId &&
x.Sex == sexType &&
data.MeterRun_50Value >= x.MinValue &&
data.MeterRun_50Value < x.MaxValue
);
if (standard != null)
{
entity.Score = standard.Score;
entity.Rank = standard.Rank;
}
}
else if (type == SportsTestItemType.OneMinuteJumpRope)
{
entity.Value = data.OneMinuteJumpRopeValue;
// 根据测试项目查找标准
var standard = await _healthStandardsRepository.FindFirstAsync(x =>
x.CategoryEnum.Equals(typeStr) &&
x.GradeId == gradeId &&
x.Sex == sexType &&
data.OneMinuteJumpRopeValue >= x.MinValue &&
data.OneMinuteJumpRopeValue < x.MaxValue
);
if (standard != null)
{
entity.Score = standard.Score;
if (standard.Score >= 100)
{
int count = (int)(data.Value - standard.MinValue);
var additionalScore = GetRopeSkipAdditionalScore(sex, count);
entity.Score = entity.Score + additionalScore;
}
entity.Rank = standard.Rank;
}
}
else if (type == SportsTestItemType.One_Minute_Sit_Up)
{
entity.Value = data.One_Minute_Sit_UpValue;
// 根据测试项目查找标准
var standard = await _healthStandardsRepository.FindFirstAsync(x =>
x.CategoryEnum.Equals(typeStr) &&
x.GradeId == gradeId &&
x.Sex == sexType &&
data.One_Minute_Sit_UpValue >= x.MinValue &&
data.One_Minute_Sit_UpValue < x.MaxValue
);
if (standard != null)
{
entity.Score = standard.Score;
if (standard.Score >= 100)
{
int count = (int)(data.Value - standard.MinValue);
var additionalScore = GetPullUpSitUpsAdditionalScore(sex, count);
entity.Score = entity.Score + additionalScore;
}
entity.Rank = standard.Rank;
}
}
else if (type == SportsTestItemType.ShuttleRun_50x8)
{
entity.Value = data.ShuttleRun_50x8Value;
// 根据测试项目查找标准
var standard = await _healthStandardsRepository.FindFirstAsync(x =>
x.CategoryEnum.Equals(typeStr) &&
x.GradeId == gradeId &&
x.Sex == sexType &&
data.ShuttleRun_50x8Value >= x.MinValue &&
data.ShuttleRun_50x8Value < x.MaxValue
);
if (standard != null)
{
entity.Score = standard.Score;
entity.Rank = standard.Rank;
}
}
else if (type == SportsTestItemType.StandingLongJump)
{
entity.Value = data.StandingLongJumpValue;
// 根据测试项目查找标准
var standard = await _healthStandardsRepository.FindFirstAsync(x =>
x.CategoryEnum.Equals(typeStr) &&
x.GradeId == gradeId &&
x.Sex == sexType &&
data.StandingLongJumpValue >= x.MinValue &&
data.StandingLongJumpValue < x.MaxValue
);
if (standard != null)
{
entity.Score = standard.Score;
entity.Rank = standard.Rank;
}
}
else if (type == SportsTestItemType.MeterRun_800)
{
entity.Value = data.MeterRun_800Value;
// 根据测试项目查找标准
var standard = await _healthStandardsRepository.FindFirstAsync(x =>
x.CategoryEnum.Equals(typeStr) &&
x.GradeId == gradeId &&
x.Sex == sexType &&
data.MeterRun_800Value >= x.MinValue &&
data.MeterRun_800Value < x.MaxValue
);
if (standard != null)
{
entity.Score = standard.Score;
if (standard.Score >= 100)
{
int count = (int)(standard.MinValue - data.Value);
var additionalScore = GetRunAdditionalScore(sex, count);
entity.Score = entity.Score + additionalScore;
}
entity.Rank = standard.Rank;
}
}
else if (type == SportsTestItemType.MeterRun_1000)
{
entity.Value = data.MeterRun_1000Value;
// 根据测试项目查找标准
var standard = await _healthStandardsRepository.FindFirstAsync(x =>
x.CategoryEnum.Equals(typeStr) &&
x.GradeId == gradeId &&
x.Sex == sexType &&
data.MeterRun_1000Value >= x.MinValue &&
data.MeterRun_1000Value < x.MaxValue
);
if (standard != null)
{
entity.Score = standard.Score;
if (standard.Score >= 100)
{
int count = (int)(standard.MinValue - data.Value);
var additionalScore = GetRunAdditionalScore(sex, count);
entity.Score = entity.Score + additionalScore;
}
entity.Rank = standard.Rank;
}
}
else if (type == SportsTestItemType.Pull_Up)
{
entity.Value = data.Pull_UpValue;
// 根据测试项目查找标准
var standard = await _healthStandardsRepository.FindFirstAsync(x =>
x.CategoryEnum.Equals(typeStr) &&
x.GradeId == gradeId &&
x.Sex == sexType &&
data.Pull_UpValue >= x.MinValue &&
data.Pull_UpValue < x.MaxValue
);
if (standard != null)
{
entity.Score = standard.Score;
if (standard.Score >= 100)
{
int count = (int)(data.Value - standard.MinValue);
var additionalScore = GetPullUpSitUpsAdditionalScore(sex, count);
entity.Score = entity.Score + additionalScore;
}
entity.Rank = standard.Rank;
}
}
entity.CategoryEnum = type.ToString();
entity.CategoryValue = (int)type;
return entity;
}
///
/// 大屏数据统计
///
///
///
public async Task LargeScreenDataStat(LargeScreenDataStatParam paramDto)
{
if (paramDto.StartTime == DateTime.MinValue || paramDto.EndTime == DateTime.MinValue)
{
throw new Exception($"请求参数不可为空");
}
var res = new LargeScreenDataStatModel();
//学校信息
res.SchoolInfo = await GetLargeScreenSchoolInfo(paramDto);
//体测情况(体质健康监控)
res.TestSituations = await GetLargeScreenTestSituations(paramDto);
//体质监测排行榜
res.PhysicalMonitoringRanking = await GetLargeScreenPhysicalMonitoringRanking(paramDto);
//赛事活动情况
res.ActivitiesSituation = await GetLargeScreenActivitiesSituation(paramDto);
//肥胖情况
res.ObesitySituation = await GetLargeScreenObesitySituation(paramDto);
//视力情况
res.DicVisionSituation = await GetLargeScreenDicVisionSituation(paramDto);
//年级体测项目成绩监控
res.GradeSportsTestTranscript = await GetLargeScreenGradeSportsTestTranscript(paramDto);
return res;
}
#region 大屏信息
///
/// 获取学期
///
///
///
public async Task> SemesterList()
{
var tenantId = UserContext.Current.TenantId;
var school = await _gradeRepository.DbContext.Set().Where(x => x.SchoolCode == tenantId).FirstAsync();
return CalculateSemesters(school.CreateDate, DateTime.Now);
}
///
/// 大屏学校信息
///
///
///
public async Task GetLargeScreenSchoolInfo(LargeScreenDataStatParam paramDto)
{
var schoolInfo = new SchoolInfoModel();
var tenantId = UserContext.Current.TenantId;
//年级信息
var gradeModels = await (
from g in _gradeRepository.DbContext.Set()
join a in _gradeRepository.DbContext.Set() on g.Id equals a.GradeId
join c in _gradeRepository.DbContext.Set() on g.Id equals c.GradeId into classGroup
from c in classGroup.DefaultIfEmpty()
where a.SchoolCode.Equals(tenantId) && c.SchoolCode.Equals(tenantId)
group new { c } by new { g.Id, g.GradeName } into groupedData
select new
{
groupedData.Key.Id,
groupedData.Key.GradeName,
ClassCount = groupedData.Select(x => x.c.Id).Distinct().Count(),
ClassIds = groupedData.Select(x => x.c.Id).Distinct().ToList()
}).ToListAsync();
//老师信息
var teacherCountModels = await (
from t in _gradeRepository.DbContext.Set()
join a in _gradeRepository.DbContext.Set() on t.Id equals a.TeacherId into assocTeachers
from at in assocTeachers.DefaultIfEmpty()
where t.SchoolCode.Equals(UserContext.Current.TenantId) && t.TeacherStatus != TeacherStatus.Depart
group new { t, at } by new { t.Id } into groupedData
select new TeacherPageListModel()
{
Id = groupedData.Key.Id
}).ToListAsync();
var tCount = teacherCountModels.Count;
//老师信息
var teacherDetailsModels = from a in _gradeRepository.DbContext.Set()
join t in _gradeRepository.DbContext.Set() on a.TeacherId equals t.Id into teacher
from tea in teacher.DefaultIfEmpty()
where tea.SchoolCode.Equals(UserContext.Current.TenantId) && tea.TeacherStatus != TeacherStatus.Depart
group new { a } by new { a.ClassId } into groupedData
select new
{
ClassId = groupedData.Key.ClassId,
TeacherIds = groupedData
.Where(x => x.a.ClassId == groupedData.Key.ClassId)
.Select(x => x.a.TeacherId)
};
var teacherModels = await teacherDetailsModels.ToListAsync();
///班级信息
gradeModels.ForEach(x =>
{
schoolInfo.ClassData.Add(new ClassModel() { GradeName = x.GradeName, ClassCount = x.ClassCount });
var teachers = teacherModels.Where(t => x.ClassIds.Contains(t.ClassId)).ToList();
schoolInfo.TeacherData.Add(new TeacherModel()
{
GradeName = x.GradeName,
TeacherCount = teachers
.SelectMany(c => c.TeacherIds)
.Distinct()
.Count()
});
});
var classIds = gradeModels.SelectMany(x => x.ClassIds).ToList();
var students = await (from s in _studentRepository.DbContext.Set()
join c in _studentRepository.DbContext.Set() on s.ClassId equals c.Id
join g in _studentRepository.DbContext.Set() on c.GradeId equals g.Id
where s.SchoolCode.Equals(tenantId) && s.StudentStatus == StudentStatus.Normal
select s
).ToListAsync();
schoolInfo.StudentData.MaleCount = students.Where(x => x.Sex == SexType.Male).Count();
schoolInfo.StudentData.FemaleCount = students.Where(x => x.Sex == SexType.Female).Count();
schoolInfo.TotalClassCount = gradeModels.Select(x => x.ClassCount).Sum();
schoolInfo.TotalTeacherCount = tCount;
// 从缓存中获取数据
var sportsTestResults = await _cacheQueryService.GeSportsTestDataCacheAsync(x => x.ScoreTime >= paramDto.StartTime && x.ScoreTime <= paramDto.EndTime);
// 运动时长
schoolInfo.AccumulatedTrainDuration = sportsTestResults.Select(x => x.MotionDuration).Sum();
var largeScreenTrainingDataModel = new List
{
await GeLargeScreenTrainingInfo(1, paramDto),
await GeLargeScreenTrainingInfo(2, paramDto),
await GeLargeScreenTrainingInfo(3, paramDto)
};
schoolInfo.LargeScreenTrainingDataModel = largeScreenTrainingDataModel;
return schoolInfo;
}
///
/// 大屏训练数据
///
/// 时间类型(1:今日,2:本周,3:本月)
///
///
public async Task GeLargeScreenTrainingInfo(int dateType, LargeScreenDataStatParam paramDto)
{
var largeScreenTrainingDataModel = new LargeScreenTrainingDataModel();
var tenantId = UserContext.Current.TenantId;
DateTime startTime;
DateTime endTime;
if (dateType == 1)
{
startTime = DateTime.Today;
endTime = DateTime.Today.AddDays(1).AddSeconds(-1);
largeScreenTrainingDataModel.DataType = "今日";
}
else if (dateType == 2)
{
// 获取本周的开始和结束时间
int diff = (7 + (DateTime.Now.DayOfWeek - DayOfWeek.Monday)) % 7;
startTime = DateTime.Now.AddDays(-1 * diff).Date;
endTime = startTime.AddDays(7).AddSeconds(-1);
largeScreenTrainingDataModel.DataType = "本周";
}
else if (dateType == 3)
{
// 获取本月的开始和结束时间
startTime = new DateTime(DateTime.Now.Year, DateTime.Now.Month, 1);
endTime = startTime.AddMonths(1).AddSeconds(-1);
largeScreenTrainingDataModel.DataType = "本月";
}
else
{
return largeScreenTrainingDataModel;
}
// 从缓存中获取数据
var sportsTestResults = await _cacheQueryService.GeSportsTestDataCacheAsync(x => x.ScoreTime >= startTime && x.ScoreTime <= endTime);
var testCategorys = sportsTestResults.Select(x => x.CategoryEnum).Distinct().ToList();
#region 总数据
// 训练次数
largeScreenTrainingDataModel.TrainingCount = sportsTestResults.Count();
// 上课节数
largeScreenTrainingDataModel.AttendClassCount = sportsTestResults.GroupBy(x => x.ClassRoomRecordId).Count();
// 上课时长
largeScreenTrainingDataModel.AttendClassDuration = sportsTestResults.Select(x => x.MotionDuration).Sum();
// 赛事参与人数
var activitiestDatas = await (from ad in _gradeRepository.DbContext.Set()
join a in _gradeRepository.DbContext.Set() on ad.ActivitiesId equals a.Id into activitiesDto
from a in activitiesDto.DefaultIfEmpty()
where a.SchoolCode == tenantId && a.StartDate >= startTime &&
a.EndDate <= endTime && a.ActivitiesStatus == ActivitiesStatus.Completed
select ad).ToListAsync();
largeScreenTrainingDataModel.EventParticipationBodCount = activitiestDatas.GroupBy(x => x.StudentNo).Count();
// 项目测试人数
largeScreenTrainingDataModel.ProjectTestingBodCount = sportsTestResults.GroupBy(x => x.StudentNo).Count();
#endregion
#region 平均数据 (全校学生不区分训练/体测/AI赛事/考级测评/作业)
// 运动人数
largeScreenTrainingDataModel.AccumulatedTrainCount = sportsTestResults.GroupBy(x => x.StudentNo).Count();
// 平均跳绳次数(跳绳个数少于10个不计算在内)
var sportsTestCategorys = await _sportsTestCategoryRepository
.FindAsIQueryable(x => x.StatisticType >= 0 && testCategorys.Contains(x.CategoryEnum))
.Select(x => new SportsTestCategoryModel()
{
Id = x.Id,
CategoryEnum = x.CategoryEnum,
CategoryName = x.CategoryName,
StatisticType = x.StatisticType,
IsRopeSkip = x.IsRopeSkip
}).ToListAsync();
var ropeSkipCategorys = sportsTestCategorys.Where(x => x.IsRopeSkip).Select(x => x.CategoryEnum).ToList();
var avgRopeSkips = sportsTestResults.Where(x => x.CategoryValue.Equals((int)SportsTestItemType.OneMinuteJumpRope) && ropeSkipCategorys.Contains(x.CategoryEnum)).ToList();
largeScreenTrainingDataModel.AvgRopeSkipCount = avgRopeSkips.Count > 0 ? (int)avgRopeSkips.Where(x => x.Value > 10).Average(x => x.Value) : 0;
// 平均运动强度
largeScreenTrainingDataModel.AvgStrength = sportsTestResults.Count > 0 ? (int)sportsTestResults.Average(x => x.Strength) : 0;
// 运动时长
largeScreenTrainingDataModel.MotionDuration = sportsTestResults.Select(x => x.MotionDuration).Sum();
// 平均心率
//var avgHeartRates = sportsTestResults.Where(x => x.CategoryEnum.Equals("HeartRate")).ToList();
largeScreenTrainingDataModel.AvgHeartRate = sportsTestResults.Count > 0 ? (int)sportsTestResults.Average(x => x.Value) : 0;
// 平均消耗
largeScreenTrainingDataModel.AvgConsume = sportsTestResults.Count > 0 ? (int)sportsTestResults.Average(x => x.Consumption) : 0;
#endregion
return largeScreenTrainingDataModel;
}
///
/// 大屏体测情况(体质健康监控)
///
///
///
public async Task GetLargeScreenTestSituations(LargeScreenDataStatParam paramDto)
{
var testSituations = new TestSituations();
var tenantId = UserContext.Current.TenantId;
// 从缓存中获取数据
var sportsTestResults = await _cacheQueryService.GeSportsTestDataCacheAsync(
x => x.ScoreTime >= paramDto.StartTime && x.ScoreTime <= paramDto.EndTime
);
// 获取年级关联的分类
var categoryList = await (from s in _classRepository.DbContext.Set()
join n in _classRepository.DbContext.Set()
on s.CategoryValue equals n.CategoryValue
select new
{
s.GradeId,
s.CategoryValue,
n.CategoryName,
s.Weight
}).ToListAsync();
// 将 categoryList 转换为嵌套字典,外层键为 GradeId,内层键为 CategoryValue
var gradeCategoryDictionary = categoryList
.GroupBy(c => c.GradeId)
.ToDictionary(
g => g.Key,
g => g.ToDictionary(c => c.CategoryValue, c => c)
);
// 按学生分组,计算每个学生的总分和等级
var studentScores = sportsTestResults
.GroupBy(x => x.StudentNo)
.Select(g =>
{
var gradeId = g.First().GradeId;
// 计算总分
double totalScore = 0;
totalScore = g.Sum(x =>
{
if (gradeCategoryDictionary.TryGetValue(gradeId, out var categoryByGrade) &&
categoryByGrade.TryGetValue(x.CategoryValue, out var category))
{
decimal score = (decimal)(x.Score + x.AdditionalScore);
decimal value = score * (decimal)category.Weight;
return (double)value;
}
return 0;
});
return new
{
StudentNo = g.Key,
Sex = g.First().Sex,
TotalScore = totalScore,
Rank = totalScore.GetRank()
};
})
.ToList();
// 定义等级列表
var rankValues = new List { "优秀", "良好", "及格", "不及格" };
// 计算每个等级的人数(总人数、男生人数、女生人数)
var rankStats = rankValues.ToDictionary(
rank => rank,
rank => new
{
Count = studentScores.Count(x => x.Rank == rank),
MaleCount = studentScores.Count(x => x.Sex == SexType.Male && x.Rank == rank),
FemaleCount = studentScores.Count(x => x.Sex == SexType.Female && x.Rank == rank)
}
);
// 计算总人数
float totalCount = studentScores.Count;
// 计算每个等级的原始百分比(保留小数)
var rawRankPercentages = rankStats.ToDictionary(
rank => rank.Key,
rank => (totalCount == 0) ? 0 : (rank.Value.Count / totalCount) * 100
);
// 对原始百分比进行取整操作
var rankPercentages = rawRankPercentages.ToDictionary(
rank => rank.Key,
rank => (int)Math.Floor(rank.Value)
);
// 计算取整后百分比的总和
int sum = rankPercentages.Values.Sum();
// 计算差值
int adjustment = 100 - sum;
// 如果差值不为 0,按原始百分比大小顺序分配调整值
if (adjustment != 0)
{
// 按原始百分比降序排序
var sortedRanks = rawRankPercentages
.OrderByDescending(r => r.Value)
.Select(r => r.Key)
.ToList();
// 依次分配调整值
foreach (var rank in sortedRanks)
{
if (adjustment > 0)
{
rankPercentages[rank]++;
adjustment--;
}
else
{
break;
}
}
}
// 处理不及格率为 0 但有不及格人数的情况
if (rankPercentages["不及格"] == 0 && rankStats["不及格"].Count > 0)
{
rankPercentages["不及格"] = 1;
// 按比例最大的等级依次减 1%
var sortedRanks = rankPercentages
.OrderByDescending(r => r.Value)
.Select(r => r.Key)
.ToList();
foreach (var rank in sortedRanks)
{
if (rankPercentages[rank] > 0)
{
rankPercentages[rank]--;
break;
}
}
}
// 构建 TestSituation 列表
var testSituationList = rankValues.Select(rank => new TestSituation
{
Title = $"{rank}率",
Value = rankPercentages[rank],
MaleCount = rankStats[rank].MaleCount,
FemaleCount = rankStats[rank].FemaleCount
}).ToList();
// 计算优秀率和良好率的总和
var excellentAndGoodRates = testSituationList
.Where(x => x.Title == "优秀率" || x.Title == "良好率")
.ToList();
testSituations.ExcellentRate = excellentAndGoodRates.Sum(x => x.Value);
testSituations.ExcellentCount = excellentAndGoodRates.Sum(x => x.MaleCount + x.FemaleCount);
// 填充 TestSituationsData
testSituations.TestSituationsData = testSituationList;
return testSituations;
}
///
/// 获取视力统计数据
///
/// 查询参数
/// 左右眼统计数据
public async Task> GetLargeScreenDicVisionSituation(LargeScreenDataStatParam paramDto)
{
var sportsProportionDataList = new List();
// 获取指定时间范围内的视力记录
var visionData = await _sportsTestCategoryRepository.DbContext.Set()
.Where(v => v.SchoolCode == UserContext.Current.TenantId)
.ToListAsync();
// 定义维度范围
var visionCategories = new List<(string Title, float Min, float Max)>
{
("正常", float.MinValue, 50), // 正常 (<50°)
("轻度", 50, 300), // 轻度 (50-300°)
("中度", 300, 600), // 中度 (300-600°)
("高度", 600, float.MaxValue) // 高度 (>600°)
};
// 左右眼统计
var leftEyeStats = new List();
var rightEyeStats = new List();
foreach (var category in visionCategories)
{
// 左眼统计
var leftCount = visionData
.Count(v => v.VisionLeft >= category.Min && v.VisionLeft < category.Max);
leftEyeStats.Add(new StudentSportsProportionData
{
Title = category.Title,
Value = leftCount
});
// 右眼统计
var rightCount = visionData
.Count(v => v.VisionReight >= category.Min && v.VisionReight < category.Max);
rightEyeStats.Add(new StudentSportsProportionData
{
Title = category.Title,
Value = rightCount
});
}
// 组装结果
sportsProportionDataList.Add(new SportsProportionData
{
Name = "右眼",
Datas = rightEyeStats
});
sportsProportionDataList.Add(new SportsProportionData
{
Name = "左眼",
Datas = leftEyeStats
});
return sportsProportionDataList;
}
///
/// 大屏肥胖情况
///
///
///
public async Task> GetLargeScreenObesitySituation(LargeScreenDataStatParam paramDto)
{
var sportsProportionDataList = new List();
var tenantId = UserContext.Current.TenantId;
// 从缓存中获取数据
var sportsTestResults = await _cacheQueryService.GeSportsTestDataCacheAsync(x => x.CategoryEnum != null && x.Rank != null && x.ScoreTime >= paramDto.StartTime && x.ScoreTime <= paramDto.EndTime);
var obesityTitles = new List() { "偏瘦", "正常", "超重", "肥胖" };
var m_Obesity = new List();
var f_Obesity = new List();
foreach (var title in obesityTitles)
{
var maleCount = sportsTestResults.Where(x => x.Sex == SexType.Male && x.CategoryEnum.Equals("BMI") && x.Rank.Equals(title)).Count();
var femaleCount = sportsTestResults.Where(x => x.Sex == SexType.Female && x.CategoryEnum.Equals("BMI") && x.Rank.Equals(title)).Count();
if (m_Obesity.Any(c => c.Title == title) || f_Obesity.Any(c => c.Title == title))
{
m_Obesity.First().Value += maleCount;
f_Obesity.First().Value += femaleCount;
}
else
{
m_Obesity.Add(new StudentSportsProportionData()
{
Title = title,
Value = maleCount,
});
f_Obesity.Add(new StudentSportsProportionData()
{
Title = title,
Value = femaleCount,
});
}
}
sportsProportionDataList.Add(new SportsProportionData() { Name = "男", Datas = m_Obesity });
sportsProportionDataList.Add(new SportsProportionData() { Name = "女", Datas = f_Obesity });
return sportsProportionDataList;
}
///
/// 大屏赛事活动情况
///
///
///
public async Task GetLargeScreenActivitiesSituation(LargeScreenDataStatParam paramDto)
{
var activitiesSituation = new ActivitiesSituation();
var tenantId = UserContext.Current.TenantId;
// 从缓存中获取数据
var sportsTestResults = await _cacheQueryService.GeSportsTestDataCacheAsync(x => x.ScoreTime >= paramDto.StartTime && x.ScoreTime <= paramDto.EndTime);
var activities = await _gradeRepository.DbContext.Set().Where(x => x.SchoolCode == tenantId).ToListAsync();
activitiesSituation.ActivitiesTotalCount = activities.Count();
activitiesSituation.CompletedCount = activities.Where(x => x.ActivitiesStatus == ActivitiesStatus.Completed).Count();
activitiesSituation.AfootCount = activities.Where(x => x.ActivitiesStatus == ActivitiesStatus.Afoot).Count();
activitiesSituation.NotStartedCount = activities.Where(x => x.ActivitiesStatus == ActivitiesStatus.NotStarted).Count();
activitiesSituation.ParticipationRate = activitiesSituation.ActivitiesTotalCount > 0 ? activitiesSituation.CompletedCount / activitiesSituation.ActivitiesTotalCount * 100 : 0;
return activitiesSituation;
}
///
/// 大屏体质监测排行榜
///
///
///
public async Task> GetLargeScreenPhysicalMonitoringRanking(LargeScreenDataStatParam paramDto)
{
var physicalMonitoringList = new List();
var tenantId = UserContext.Current.TenantId;
// 获取所有班级信息
var classList = await _classRepository.DbContext.Set()
.Where(x => x.SchoolCode == tenantId)
.ToListAsync();
var classIds = classList.Select(c => c.Id).ToList();
// 获取体测成绩
var sportsTestResults = await _cacheQueryService.GeSportsTestDataCacheAsync(x =>
x.ScoreTime >= paramDto.StartTime && x.ScoreTime <= paramDto.EndTime &&
classIds.Contains(x.ClassId)
);
// 获取年级关联的分类
var categoryList = await (from s in _classRepository.DbContext.Set()
join n in _classRepository.DbContext.Set()
on s.CategoryValue equals n.CategoryValue
select new
{
s.CategoryValue,
n.CategoryName,
s.Weight,
s.GradeId
}).ToListAsync();
// 计算每个学生的总分
var studentScores = sportsTestResults
.GroupBy(x => x.StudentNo)
.Select(g => new
{
StudentNo = g.Key,
ClassId = g.First().ClassId,
GradeId = g.First().GradeId,
ClassName = g.First().ClassName,
GradeName = g.First().GradeName,
Sex = g.First().Sex,
TotalScore = g.Sum(x => (x.Score + x.AdditionalScore) *
(categoryList.FirstOrDefault(c => c.GradeId == g.First().GradeId && c.CategoryValue == x.CategoryValue)?.Weight ?? 0))
})
.ToList();
// 计算每个班级的优良率
var classRankings = studentScores
.GroupBy(x => new { x.ClassId, x.GradeId, x.ClassName, x.GradeName })
.Select(g => new
{
GradeAndClassName = $"{g.Key.GradeName}-{g.Key.ClassName}",
MaleValue = (float)g.Count(x => x.Sex == SexType.Male && x.TotalScore >= 80) / g.Count() * 100,
FemaleValue = (float)g.Count(x => x.Sex == SexType.Female && x.TotalScore >= 80) / g.Count() * 100,
OverallValue = (float)g.Count(x => x.TotalScore >= 80) / g.Count() * 100
})
.OrderByDescending(g => g.OverallValue)
.Select((g, index) => new PhysicalMonitoring
{
GradeAndClassName = g.GradeAndClassName,
ExcellentRate = Math.Round(g.OverallValue),
Ranking = index + 1
})
.ToList();
// 处理未参与统计的班级
var allClasses = classList.Select(c => $"{c.GradeName}-{c.ClassName}").ToList();
var rankedClasses = classRankings.Select(c => c.GradeAndClassName).ToList();
var unrankedClasses = allClasses.Except(rankedClasses).ToList();
var ranking = classRankings.Count + 1;
foreach (var className in unrankedClasses)
{
classRankings.Add(new PhysicalMonitoring
{
GradeAndClassName = className,
ExcellentRate = 0,
Ranking = ranking++
});
}
return classRankings;
}
///
/// 大屏 年级体测项目成绩监控
///
///
///
public async Task> GetLargeScreenGradeSportsTestTranscript(LargeScreenDataStatParam paramDto)
{
var gradeSportsTestTranscriptList = new List();
var tenantId = UserContext.Current.TenantId;
// 从缓存中获取数据
var sportsTestResults = await _cacheQueryService.GeSportsTestDataCacheAsync(x => x.ScoreTime >= paramDto.StartTime && x.ScoreTime <= paramDto.EndTime);
// 年级-班级信息
var gradeClassQuery = from g in _classRepository.DbContext.Set()
join a in _classRepository.DbContext.Set() on g.Id equals a.GradeId
where a.SchoolCode == tenantId
select new
{
GradeId = g.Id,
GradeAndClassName = $"{g.GradeName}",
};
var gradeCategory = await (
from g in _gradeRepository.DbContext.Set()
join s in _gradeRepository.DbContext.Set() on g.CategoryValue equals s.CategoryValue
select new
{
GradeId = g.GradeId,
CategoryId = g.CategoryValue,
CategoryName = s.CategoryName,
}).ToListAsync();
var gradeClassModels = await gradeClassQuery.ToListAsync();
var sportsTestList = sportsTestResults.GroupBy(x => new { x.GradeId, x.GradeName }).OrderBy(g => g.Key.GradeId).ToList();
foreach (var gradeClass in gradeClassModels)
{
var sportsProportionDataList = new List();
var sportsTest = sportsTestList.FirstOrDefault(s => s.Key.GradeId == gradeClass.GradeId);
foreach (var type in gradeCategory.Where(c => c.GradeId == gradeClass.GradeId).OrderBy(c => c.CategoryId))
{
var typeSportsTestResults = sportsTest != null ? sportsTest.Where(x => x.CategoryValue == type.CategoryId).ToList() : new List();
// 计算平均值
var maleAverage = typeSportsTestResults.Where(x => x.Sex == SexType.Male).Any()
? typeSportsTestResults.Where(x => x.Sex == SexType.Male).Average(x => x.Score)
: 0;
var femaleAverage = typeSportsTestResults.Where(x => x.Sex == SexType.Female).Any()
? typeSportsTestResults.Where(x => x.Sex == SexType.Female).Average(x => x.Score)
: 0;
var sumAverage = typeSportsTestResults.Any() ? typeSportsTestResults.Average(x => x.Score) : 0;
var studentSportsProportionData = new List
{
new StudentSportsProportionData { Title = "总分数", Value = (int)sumAverage },
new StudentSportsProportionData { Title = "男生", Value = (int)maleAverage },
new StudentSportsProportionData { Title = "女生", Value = (int)femaleAverage }
};
sportsProportionDataList.Add(new SportsProportionData
{
Name = type.CategoryName,
Datas = studentSportsProportionData
});
}
gradeSportsTestTranscriptList.Add(new GradeSportsTestTranscript()
{
GradeAndClassName = gradeClass.GradeAndClassName,
Datas = sportsProportionDataList
});
}
return gradeSportsTestTranscriptList;
}
///
/// 大屏 班级平均运动强度监控
///
///
///
public async Task> LargeScreenAverageClassExerciseIntensity(LargeScreenAverageClassExerciseIntensityParam paramDto)
{
if (paramDto.GradeId < 0 || paramDto.StartTime == DateTime.MinValue || paramDto.EndTime == DateTime.MinValue)
{
throw new Exception($"请求参数不可为空");
}
var sportsProportionDataList = new List();
var tenantId = UserContext.Current.TenantId;
// 从缓存中获取数据
var sportsTestResults = await _cacheQueryService.GeSportsTestDataCacheAsync(x => x.GradeId == paramDto.GradeId && x.ScoreTime >= paramDto.StartTime && x.ScoreTime <= paramDto.EndTime);
// 班级信息
var classQuery = 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 a.SchoolCode == tenantId && c.SchoolCode == tenantId && g.Id == paramDto.GradeId
select c;
var classModels = await classQuery.ToListAsync();
if (classModels == null || classModels.Count == 0)
throw new ArgumentNullException("未找到班级数据");
var totalStrength = sportsTestResults.Any() ? sportsTestResults.Select(x => x.Strength).Average(x => x) : 0;
var classGroups = sportsTestResults.Any() ? sportsTestResults.GroupBy(c => new { c.ClassId, c.ClassName }).ToList() : null;
foreach (var classModel in classModels)
{
var classGroup = classGroups?.FirstOrDefault(c => c.Key.ClassId == classModel.Id && c.Key.ClassName == classModel.ClassName);
if (classGroup != null)
{
// 计算该班级的平均强度
var averageStrength = classGroup.Select(x => x.Strength).Average(x => x);
var percentage = averageStrength == 0 ? 0 : (averageStrength / totalStrength) * 100;
var studentSportsProportionData = new List
{
new StudentSportsProportionData { Title = "平均强度", Value =((int)Math.Round(percentage) > 100 ? 100 : (int)Math.Round(percentage)) }
};
sportsProportionDataList.Add(new SportsProportionData
{
Name = classGroup.Key.ClassName,
Datas = studentSportsProportionData
});
}
else
{
var studentSportsProportionData = new List
{
new StudentSportsProportionData { Title = "平均强度", Value = 0 }
};
sportsProportionDataList.Add(new SportsProportionData
{
Name = classModel.ClassName,
Datas = studentSportsProportionData
});
}
}
return sportsProportionDataList;
}
#endregion
public async Task> GetSportsTestCategoryPageList(StudentsTestDataListParam paramDto)
{
var res = new PageDataDto();
var query = from r in _healthStandardsRepository.DbContext.Set()
join c in _healthStandardsRepository.DbContext.Set() on r.CategoryEnum equals c.CategoryEnum
where r.SchoolCode.Equals(UserContext.Current.TenantId)
select new StudentsTestDataModel()
{
Id = r.Id,
GradeId = r.Id,
GradeName = r.GradeName,
StudentNo = r.StudentNo,
CategoryName = c.CategoryName,
ClassId = r.ClassId,
ClassName = r.ClassName,
ClassRank = r.ClassRank,
Consumption = r.Consumption,
MotionDuration = r.MotionDuration,
Strength = r.Strength,
TeacherId = r.TeacherId,
Remarks = r.Remarks,
Value = r.Value,
Rank = r.Rank,
CategoryId = c.Id,
Score = r.Score,
Sex = r.Sex == SexType.Male ? "男" : "女"
};
if (!string.IsNullOrWhiteSpace(paramDto.StudentNo))
{
query = query.Where(x => x.StudentNo.Equals(paramDto.StudentNo));
}
if (paramDto.TeacherId > 0)
{
query = query.Where(x => x.TeacherId == paramDto.TeacherId);
}
if (paramDto.GradeId > 0)
{
query = query.Where(x => x.GradeId == paramDto.GradeId);
}
if (paramDto.ClassId > 0)
{
query = query.Where(x => x.ClassId == paramDto.ClassId);
}
if (paramDto.CategoryId > 0)
{
query = query.Where(x => x.CategoryId == paramDto.CategoryId);
}
if (paramDto.Sex > 0)
{
query = query.Where(x => x.Sex.Equals(paramDto.Sex == SexType.Male ? "男" : "女"));
}
res.Total = await query.CountAsync();
var list = await query
.Skip((paramDto.PageIndex - 1) * paramDto.PageSize)
.Take(paramDto.PageSize)
.ToListAsync();
res.Datas = list;
return res;
}
public async Task> GetStudentsTestDataList(StudentsTestDataListParam paramDto)
{
var query = from r in _healthStandardsRepository.DbContext.Set()
join c in _healthStandardsRepository.DbContext.Set() on r.CategoryEnum equals c.CategoryEnum
where r.SchoolCode.Equals(UserContext.Current.TenantId)
select new StudentsTestDataModel()
{
Id = r.Id,
GradeId = r.Id,
GradeName = r.GradeName,
StudentNo = r.StudentNo,
CategoryName = c.CategoryName,
ClassId = r.ClassId,
ClassName = r.ClassName,
ClassRank = r.ClassRank,
Consumption = r.Consumption,
MotionDuration = r.MotionDuration,
Strength = r.Strength,
TeacherId = r.TeacherId,
Remarks = r.Remarks,
Value = r.Value,
Rank = r.Rank,
CategoryId = c.Id,
Score = r.Score,
Sex = r.Sex == SexType.Male ? "男" : "女"
};
if (!string.IsNullOrWhiteSpace(paramDto.StudentNo))
{
query = query.Where(x => x.StudentNo.Equals(paramDto.StudentNo));
}
if (paramDto.TeacherId > 0)
{
query = query.Where(x => x.TeacherId == paramDto.TeacherId);
}
if (paramDto.GradeId > 0)
{
query = query.Where(x => x.GradeId == paramDto.GradeId);
}
if (paramDto.ClassId > 0)
{
query = query.Where(x => x.ClassId == paramDto.ClassId);
}
if (paramDto.CategoryId > 0)
{
query = query.Where(x => x.CategoryId == paramDto.CategoryId);
}
if (paramDto.Sex > 0)
{
query = query.Where(x => x.Sex.Equals(paramDto.Sex == SexType.Male ? "男" : "女"));
}
var list = await query.ToListAsync();
return list;
}
public async Task AddStudentsTestData(List paramDto)
{
var studentNos = paramDto.Select(x => x.StudentNo).Distinct().ToList();
var students = await (from s in _studentRepository.DbContext.Set()
join c in _studentRepository.DbContext.Set() on s.ClassId equals c.Id
join g in _studentRepository.DbContext.Set() on c.GradeId equals g.Id
where g.SchoolCode.Equals(UserContext.Current.TenantId)
select new
{
Id = s.Id,
Age = s.Age,
ClassId = s.ClassId,
ClassName = c.ClassName,
GradeId = g.Id,
GradeName = g.GradeName,
Sex = s.Sex,
StudentNo = s.StudentNo,
}).ToListAsync();
var distinctCategoryTypes = paramDto.Select(c => c.CategoryEnum).Distinct().ToList();
var healthStandards = await _healthStandardsRepository.FindAsync(x => distinctCategoryTypes.Contains(x.CategoryEnum));
var entityList = new List();
var timeNow = DateTime.Now;
foreach (var data in paramDto)
{
var entity = _mapper.Map(data);
var student = students.FirstOrDefault(x => x.StudentNo.Equals(data.StudentNo));
if (student == null)
throw new Exception($"未找到此编号为{data.StudentNo}的学生");
var standard = healthStandards.Where(x =>
x.CategoryEnum.Equals(data.CategoryEnum) &&
x.GradeId == student.GradeId &&
x.Sex == student.Sex &&
data.Value >= x.MinValue &&
data.Value < x.MaxValue
).FirstOrDefault();
if (standard != null)
{
entity.Score = standard.Score;
entity.Rank = standard.Rank;
}
entity.GradeId = student.GradeId;
entity.ClassId = student.ClassId;
entity.GradeName = student.GradeName;
entity.ClassName = student.ClassName;
entity.Sex = student.Sex;
entity.Creator = UserContext.Current.UserId;
entity.CreateDate = timeNow;
entityList.Add(entity);
}
await _sportsTestResultRepository.AddRangeAsync(entityList);
await _sportsTestResultRepository.SaveChangesAsync();
var ranks = await _sportsTestResultRepository.FindAsIQueryable(x => distinctCategoryTypes.Contains(x.CategoryEnum))
.Select(x => x.Score)
.Distinct()
.OrderByDescending(value => value)
.ToListAsync();
foreach (var entity in entityList)
{
if (entity.Score > 0)
{
entity.ClassRank = ranks.IndexOf(entity.Score) + 1;
}
}
_sportsTestResultRepository.UpdateRange(entityList);
await _sportsTestResultRepository.SaveChangesAsync();
}
public async Task ModifyStudentsTestData(List paramDto)
{
var studentNos = paramDto.Select(x => x.StudentNo).Distinct().ToList();
var entityList = await _sportsTestResultRepository.FindAsync(x => studentNos.Contains(x.StudentNo));
var distinctCategoryTypes = paramDto.Select(c => c.CategoryEnum).Distinct().ToList();
var healthStandards = await _healthStandardsRepository.FindAsync(x => distinctCategoryTypes.Contains(x.CategoryEnum));
var timeNow = DateTime.Now;
foreach (var data in paramDto)
{
var entity = entityList.FirstOrDefault(x => x.StudentNo.Equals(data.StudentNo));
if (entity == null)
throw new Exception($"未找到要更新的数据");
entity = _mapper.Map(data);
var standard = healthStandards.Where(x =>
x.CategoryEnum.Equals(data.CategoryEnum) &&
x.GradeId == entity.GradeId &&
x.Sex == entity.Sex &&
data.Value >= x.MinValue &&
data.Value < x.MaxValue
).FirstOrDefault();
if (standard != null)
{
entity.Score = standard.Score;
entity.Rank = standard.Rank;
}
entity.Modifier = UserContext.Current.UserId;
entity.ModifyDate = timeNow;
entityList.Add(entity);
}
_sportsTestResultRepository.UpdateRange(entityList);
await _sportsTestResultRepository.SaveChangesAsync();
var ranks = await _sportsTestResultRepository.FindAsIQueryable(x => distinctCategoryTypes.Contains(x.CategoryEnum))
.Select(x => x.Score)
.Distinct()
.OrderByDescending(value => value)
.ToListAsync();
foreach (var entity in entityList)
{
if (entity.Score > 0)
{
entity.ClassRank = ranks.IndexOf(entity.Score) + 1;
}
}
_sportsTestResultRepository.UpdateRange(entityList);
await _sportsTestResultRepository.SaveChangesAsync();
}
public async Task DeleteStudentsTestData(List Ids)
{
var model = await _sportsTestResultRepository.FindAsync(x => Ids.Contains(x.Id));
if (model == null)
throw new ArgumentNullException($"未找到删除的数据");
_sportsTestResultRepository.DbContext.RemoveRange(model);
await _sportsTestResultRepository.SaveChangesAsync();
}
///
/// 获取学期
///
///
///
///
public List CalculateSemesters(DateTime startDate, DateTime endDate)
{
List semesters = new List();
// 每年分为上学期和下学期
for (int year = startDate.Year; year <= endDate.Year; year++)
{
// 计算每个学期的开始和结束时间
DateTime springStart = new DateTime(year, 1, 1); // 上学期开始时间(春季学期)
DateTime springEnd = new DateTime(year, 6, 30); // 上学期结束时间(春季学期)
DateTime autumnStart = new DateTime(year, 9, 1); // 下学期开始时间(秋季学期)
DateTime autumnEnd = new DateTime(year, 12, 31); // 下学期结束时间(秋季学期)
// 对于每个学期,如果它部分或完全在范围内,都算作一个完整学期
if (startDate <= springEnd && endDate >= springStart)
{
semesters.Add(new SemesterModel
{
Semester = $"{year - 1}~{year}下学期",
StartTime = springStart.ToString("yyyy-MM-dd"),
EndTime = springEnd.ToString("yyyy-MM-dd")
});
}
if (startDate <= autumnEnd && endDate >= autumnStart)
{
semesters.Add(new SemesterModel
{
Semester = $"{year - 1}~{year}上学期",
StartTime = autumnStart.ToString("yyyy-MM-dd"),
EndTime = autumnEnd.ToString("yyyy-MM-dd")
});
}
}
return semesters;
}
//获取跳绳附加分
public int GetRopeSkipAdditionalScore(string gender, int score)
{
Dictionary> genderScoreToAdditionalPoints = new Dictionary>()
{
{ "男", new Dictionary()
{
{ 20, 40 },
{ 19, 38 },
{ 18, 36 },
{ 17, 34 },
{ 16, 32 },
{ 15, 30 },
{ 14, 28 },
{ 13, 26 },
{ 12, 24 },
{ 11, 22 },
{ 10, 20 },
{ 9, 18 },
{ 8, 16 },
{ 7, 14 },
{ 6, 12 },
{ 5, 10 },
{ 4, 8 },
{ 3, 6 },
{ 2, 4 },
{ 1, 2 }
}
},
{ "女", new Dictionary()
{
{ 20, 40 },
{ 19, 38 },
{ 18, 36 },
{ 17, 34 },
{ 16, 32 },
{ 15, 30 },
{ 14, 28 },
{ 13, 26 },
{ 12, 24 },
{ 11, 22 },
{ 10, 20 },
{ 9, 18 },
{ 8, 16 },
{ 7, 14 },
{ 6, 12 },
{ 5, 10 },
{ 4, 8 },
{ 3, 6 },
{ 2, 4 },
{ 1, 2 }
}
}
};
var scoreToAdditionalPoints = genderScoreToAdditionalPoints[gender];
return scoreToAdditionalPoints[score];
}
//获取引体向上和仰卧起坐附加分
public int GetPullUpSitUpsAdditionalScore(string gender, int score)
{
Dictionary> genderScoreToAdditionalPoints = new Dictionary>()
{
{ "男", new Dictionary()
{
{ 10, 10 },
{ 9, 9 },
{ 8, 8 },
{ 7, 7 },
{ 6, 6 },
{ 5, 5 },
{ 4, 4 },
{ 3, 3 },
{ 2, 2 },
{ 1, 1 }
}
},
{ "女", new Dictionary()
{
{ 10, 13 },
{ 9, 12 },
{ 8, 11 },
{ 7, 10 },
{ 6, 9 },
{ 5, 8 },
{ 4, 7 },
{ 3, 6 },
{ 2, 4 },
{ 1, 2 }
}
}
};
var scoreToAdditionalPoints = genderScoreToAdditionalPoints[gender];
return scoreToAdditionalPoints[score];
}
//获取跑步附加分
public int GetRunAdditionalScore(string gender, int score)
{
Dictionary> genderScoreToAdditionalPoints = new Dictionary>()
{
{ "男", new Dictionary()
{
{ 10, 35 },
{ 9, 32 },
{ 8, 29 },
{ 7, 26 },
{ 6, 23 },
{ 5, 20 },
{ 4, 16 },
{ 3, 12 },
{ 2, 8 },
{ 1, 4 }
}
},
{ "女", new Dictionary()
{
{ 10, 50 },
{ 9, 45 },
{ 8, 40 },
{ 7, 35 },
{ 6, 30 },
{ 5, 25 },
{ 4, 20 },
{ 3, 15 },
{ 2, 10 },
{ 1, 5 }
}
}
};
var scoreToAdditionalPoints = genderScoreToAdditionalPoints[gender];
return scoreToAdditionalPoints[score];
}
}
}