1264 lines
52 KiB
C#
Raw Normal View History

2025-06-06 16:00:39 +08:00
using Microsoft.Extensions.DependencyInjection;
using VOL.Ai.IServices;
using VOL.Core.Extensions.AutofacManager;
using VOL.Entity.DomainModels.Business.People;
using VOL.Entity.DomainModels;
using VOL.System.IRepositories;
using Microsoft.EntityFrameworkCore;
using VOL.Model.Ai;
using VOL.Core.Utilities;
using VOL.Entity.Enum;
using VOL.Model.Ai.Request;
using VOL.Core.ManageUser;
using VOL.Core.Extensions;
using VOL.Model;
using VOL.Model.Ai.Response;
using VOL.Model.IOT.Response;
using VOL.System.Repositories;
using AutoMapper;
using VOL.Core.Configuration;
using VOL.Ai.IRepositories;
using Microsoft.AspNetCore.Http;
using OfficeOpenXml.FormulaParsing.Excel.Functions.DateTime;
using System.Collections.Concurrent;
using VOL.Core.Services;
namespace VOL.Ai.Services
{
public class AiAppService : IAiAppService, IDependency
{
private readonly IMapper _mapper;
private readonly IS_StudentRepository _studentRepository;
private readonly IS_TeacherRepository _teacherRepository;
private readonly IS_ClassRepository _classRepository;
private readonly IN_SportsTestCategoryRepository _sportsTestCategoryRepository;
private readonly IN_HealthStandardsRepository _healthStandardsRepository;
2025-07-09 10:01:31 +08:00
private readonly IScanCodeLoginRepository _scanCodeLoginRepository;
2025-06-06 16:00:39 +08:00
private readonly IN_SportsTrainingCategoryRepository _sportsTrainingCategoryRepository;
private readonly IClassRoomRecordRepository _classRoomRecordRepository;
private readonly IHeartRateDataRepository _heartRateDataRepository;
private readonly IActivitiestDataRepository _activitiestDataRepository;
private readonly ILevelExamDataRepository _levelExamDataRepository;
private readonly ISportsTestDataRepository _sportsTestDataRepository;
private readonly ITrainingDataRepository _trainingDataRepository;
private readonly IFastJumpRopeDataRepository _fastJumpRopeDataRepository;
[ActivatorUtilitiesConstructor]
public AiAppService(IMapper mapper,
IS_StudentRepository studentRepository,
IS_TeacherRepository teacherRepository,
IS_ClassRepository classRepository,
IN_SportsTestCategoryRepository sportsTestCategoryRepository,
IN_HealthStandardsRepository healthStandardsRepository,
2025-07-09 10:01:31 +08:00
IScanCodeLoginRepository scanCodeLoginRepository,
2025-06-06 16:00:39 +08:00
IN_SportsTrainingCategoryRepository sportsTrainingCategoryRepository,
IClassRoomRecordRepository classRoomRecordRepository,
IHeartRateDataRepository heartRateDataRepository,
IActivitiestDataRepository activitiestDataRepository,
ILevelExamDataRepository levelExamDataRepository,
ISportsTestDataRepository sportsTestDataRepository,
ITrainingDataRepository trainingDataRepository,
IFastJumpRopeDataRepository fastJumpRopeDataRepository
)
{
_mapper = mapper;
_studentRepository = studentRepository;
_sportsTestCategoryRepository = sportsTestCategoryRepository;
_healthStandardsRepository = healthStandardsRepository;
2025-07-09 10:01:31 +08:00
_scanCodeLoginRepository = scanCodeLoginRepository;
2025-06-06 16:00:39 +08:00
_teacherRepository = teacherRepository;
_sportsTrainingCategoryRepository = sportsTrainingCategoryRepository;
_classRoomRecordRepository = classRoomRecordRepository;
_heartRateDataRepository = heartRateDataRepository;
_activitiestDataRepository = activitiestDataRepository;
_levelExamDataRepository = levelExamDataRepository;
_sportsTestDataRepository = sportsTestDataRepository;
_trainingDataRepository = trainingDataRepository;
_classRepository = classRepository;
_fastJumpRopeDataRepository = fastJumpRopeDataRepository;
}
public async Task<Ai_DeviceDto> Ai_DeviceInfo(AiRequestDto paramDto)
{
var res = await (
from d in _studentRepository.DbContext.Set<Ai_Device>()
join a in _studentRepository.DbContext.Set<Ai_DeviceAssocSchool>() on d.Code equals a.Code
join s in _studentRepository.DbContext.Set<S_School>() on a.SchoolCode equals s.SchoolCode
where d.Code == paramDto.Code
select new Ai_DeviceDto()
{
Code = d.Code,
Name = d.Name,
SchoolName = s.SchoolName,
Status = d.Status,
StartTime = d.StartTime,
EndTime = d.EndTime
}).FirstOrDefaultAsync();
return res;
}
public async Task<Ai_SchoolDto> Ai_SchoolDetail(Ai_SchoolRequest paramDto)
{
var res = await (
from a in _studentRepository.DbContext.Set<Ai_DeviceAssocSchool>()
join s in _studentRepository.DbContext.Set<S_School>() on a.SchoolCode equals s.SchoolCode
where a.Code == paramDto.Code
select new Ai_SchoolDto
{
SchoolCode = s.SchoolCode,
Name = s.SchoolName,
Type = s.SchoolNatureId,
Province = s.Province,
City = s.City
}).FirstOrDefaultAsync();
if (res == null)
2025-07-07 14:56:38 +08:00
return new Ai_SchoolDto();
2025-06-06 16:00:39 +08:00
var gIds = await _studentRepository.DbContext.Set<S_SchoolAssocGrade>().Where(x => x.SchoolCode == res.SchoolCode).Select(x => x.GradeId).ToListAsync();
var grades = await (
from g in _studentRepository.DbContext.Set<S_Grade>()
join c in _studentRepository.DbContext.Set<S_Class>() on g.Id equals c.GradeId into classGroup
from c in classGroup.DefaultIfEmpty()
where gIds.Contains(g.Id) && c.SchoolCode == res.SchoolCode
group c by new { g.Id, g.GradeName } into gradeGroup
select new Grades()
{
Id = gradeGroup.Key.Id,
Name = gradeGroup.Key.GradeName,
Class = gradeGroup.Where(c => c != null).Select(c => new Classes
{
Id = c.Id,
Name = c.ClassName
}).ToList()
}).ToListAsync();
res.Grade = grades;
return res;
}
public Ai_OSSInfoDto OSSInfo(Ai_Request paramDto)
{
return new Ai_OSSInfoDto()
{
Accessid = AppSetting.ALiYunOSS.AccessKeyId,
AccessKeySecret = AppSetting.ALiYunOSS.SecretAccessKey,
Endpoint = AppSetting.ALiYunOSS.Endpoint,
BucketName = AppSetting.YueDongServerOSS.BucketName,
Prefix = AppSetting.YueDongServerOSS.Prefix
};
}
//public async Task<List<Ai_ItemTypeModel>> GetAiCategoryType()
//{
// return await Task.FromResult(Tool.GetEnumDescriptions<Ai_ItemTypeModel, SportsTestItemType>((code, description)
// => new Ai_ItemTypeModel { ItemCode = code, ItemTypeName = description }));
//}
public async Task<ResultFilesDto> ResultFiles(ResultFilesRequest paramDto, IFormFile file)
{
var path = $"Upload/{paramDto.SchoolCode}/Voide/{paramDto.ClassRoomRecordId}/";
var name = Path.GetFileNameWithoutExtension(file.FileName);
var url = ALiYunOss.Upload(file, path, name);
var updateModels = await _levelExamDataRepository.FindAsync(x => x.SchoolCode == paramDto.SchoolCode &&
x.Code == paramDto.Code &&
x.ClassRoomRecordId == paramDto.ClassRoomRecordId &&
x.FileName == name);
updateModels.ForEach(x =>
{
x.FileUrl = url;
});
_levelExamDataRepository.UpdateRange(updateModels);
await _levelExamDataRepository.SaveChangesAsync();
return new ResultFilesDto() { Name = name, Url = url };
}
public async Task<List<Ai_ModeTypeModel>> ItemTypeList()
{
var list = await (from t in _sportsTestCategoryRepository.DbContext.Set<N_TrainingAssocCategory>()
join a in _sportsTrainingCategoryRepository.DbContext.Set<N_SportsTrainingCategory>() on t.CategoryValue equals a.CategoryValue
where t.DataSource == DataSource.AI
select new
{
Id = a.CategoryValue,
t.ModeId,
ItemTypeName = a.CategoryName
}).ToListAsync();
List<Ai_ModeTypeModel> result = Enum.GetValues(typeof(Ai_ModeEnum))
.Cast<Ai_ModeEnum>()
.Select(modeEnum => new Ai_ModeTypeModel
{
ModeId = (int)modeEnum,
ModeName = modeEnum.GetDescription(),
ItemTypeList = list
.Where(x => x.ModeId == (int)modeEnum)
.Select(x => new Ai_ItemTypeModel
{
ItemCode = x.Id,
ItemTypeName = x.ItemTypeName
})
.ToList()
})
.Where(model => model.ItemTypeList.Any())
.ToList();
return result;
}
public async Task<List<Ai_ModeTypeModel>> CategoryList()
{
var list = await (from t in _sportsTestCategoryRepository.DbContext.Set<N_TestAssocCategory>()
join a in _sportsTrainingCategoryRepository.DbContext.Set<N_SportsTestCategory>() on t.CategoryValue equals a.CategoryValue
where t.DataSource == DataSource.AI
select new
{
Id = a.CategoryValue,
t.ModeId,
ItemTypeName = a.CategoryName
}).ToListAsync();
List<Ai_ModeTypeModel> result = Enum.GetValues(typeof(Ai_ModeEnum))
.Cast<Ai_ModeEnum>()
.Select(modeEnum => new Ai_ModeTypeModel
{
ModeId = (int)modeEnum,
ModeName = modeEnum.GetDescription(),
ItemTypeList = list
.Where(x => x.ModeId == (int)modeEnum)
.Select(x => new Ai_ItemTypeModel
{
ItemCode = x.Id,
ItemTypeName = x.ItemTypeName
})
.ToList()
})
.Where(model => model.ItemTypeList.Any())
.ToList();
return result;
}
public async Task<Ai_StudentFaceInfo> StudentFace(GetFaceParam paramDto)
{
2025-07-07 14:56:38 +08:00
var faces = await ALiYunFace.SearchFace(paramDto.Base64, false);
2025-06-06 16:00:39 +08:00
2025-07-07 14:56:38 +08:00
foreach (var body in faces)
2025-06-06 16:00:39 +08:00
{
2025-07-07 14:56:38 +08:00
if (body != null && body.Confidence >= 72.62)
{
var student = await (from s in _studentRepository.FindAsIQueryable(x => x.SchoolCode == paramDto.SchoolCode && x.StudentNo == body.EntityId)
join c in _studentRepository.DbContext.Set<S_Class>() on s.ClassId equals c.Id
select new Ai_StudentFaceInfo
{
ClassId = c.Id,
ClassName = c.ClassName,
Age = s.Age,
Sex = s.Sex,
StudentName = s.StudentName,
StudentCode = s.StudentNo,
GradeId = c.GradeId,
GradeName = c.GradeName,
Photo = s.Photo
}).FirstOrDefaultAsync();
if (student == null)
throw new Exception("未查询到学生信息");
2025-06-06 16:00:39 +08:00
return student;
2025-07-07 14:56:38 +08:00
}
2025-06-06 16:00:39 +08:00
}
2025-07-07 14:56:38 +08:00
throw new Exception("未查询到学生信息");
2025-06-06 16:00:39 +08:00
}
public async Task<Ai_TeacherFaceInfo> TeacherFace(GetFaceParam paramDto)
{
2025-07-07 14:56:38 +08:00
var faces = await ALiYunFace.SearchFace(paramDto.Base64, false);
2025-06-06 16:00:39 +08:00
2025-07-07 14:56:38 +08:00
foreach (var body in faces)
2025-06-06 16:00:39 +08:00
{
2025-07-07 14:56:38 +08:00
if (body != null && body.Confidence >= 72.62)
{
var teacher = await _teacherRepository.FindAsIQueryable(x => x.SchoolCode == paramDto.SchoolCode && x.TeacherStatus != TeacherStatus.Depart && x.TeacherPhoneNo == body.EntityId)
.Select(x =>
new Ai_TeacherFaceInfo()
{
Id = x.Id,
Age = x.Age,
//SchoolCode = x.SchoolCode,
Sex = x.Sex,
Phone = x.TeacherPhoneNo,
TeacherName = x.TeacherName,
Photo = x.TeacherPhoto,
}).FirstOrDefaultAsync();
if (teacher == null)
continue;
var grades = await (
from t in _studentRepository.DbContext.Set<S_ClassAssocTeacher>()
join c in _studentRepository.DbContext.Set<S_Class>() on t.ClassId equals c.Id into classGroup
from c in classGroup.DefaultIfEmpty()
where t.TeacherId == teacher.Id && c != null
select new Classes()
{
Id = c.Id,
Name = $"{c.GradeName}-{c.ClassName}",
}).ToListAsync();
2025-06-06 16:00:39 +08:00
2025-07-07 14:56:38 +08:00
teacher.GradeAndClassList = grades;
2025-06-06 16:00:39 +08:00
2025-07-07 14:56:38 +08:00
return teacher;
}
2025-06-06 16:00:39 +08:00
}
2025-07-07 14:56:38 +08:00
throw new Exception("未查询到老师信息");
2025-06-06 16:00:39 +08:00
}
public async Task<List<Ai_StudentListDto>> Ai_StudentList(Ai_StudentListRequest paramDto)
{
var query = from s in _studentRepository.DbContext.Set<S_Student>()
join c in _studentRepository.DbContext.Set<S_Class>() on s.ClassId equals c.Id
join g in _studentRepository.DbContext.Set<S_Grade>() on c.GradeId equals g.Id
where s.SchoolCode == paramDto.SchoolCode && s.ClassId == paramDto.Id && s.StudentStatus == StudentStatus.Normal
2025-07-07 14:56:38 +08:00
orderby s.OrderNo ascending
2025-06-06 16:00:39 +08:00
select new Ai_StudentListDto()
{
Code = paramDto.Code,
StudentNo = s.StudentNo,
StudentName = s.StudentName,
Sex = s.Sex,
Age = s.Age,
Photo = s.Photo,
ClassName = c.ClassName,
GradeName = g.GradeName,
OrderNo = s.OrderNo
};
var res = await query.OrderBy(x => x.OrderNo).ToListAsync();
return res;
}
public async Task<AiStudentDetailsDto> Ai_StudentDetail(Ai_StudentDetailRequest paramDto)
{
var res = await (
from s in _studentRepository.DbContext.Set<S_Student>()
join c in _studentRepository.DbContext.Set<S_Class>() on s.ClassId equals c.Id
join g in _studentRepository.DbContext.Set<S_Grade>() on c.GradeId equals g.Id
where s.StudentNo == paramDto.StudentNo && s.SchoolCode == paramDto.SchoolCode
select new AiStudentDetailsDto
{
StudentNo = s.StudentNo,
StudentName = s.StudentName,
Age = s.Age,
IdCard = s.IDCard,
Sex = s.Sex,
Photo = s.Photo,
ClassId = c.Id,
ClassName = c.ClassName,
GradeId = g.Id,
GradeName = g.GradeName
}).FirstOrDefaultAsync();
return res;
}
/// <summary>
/// 获取专项教学项目
/// </summary>
public async Task<List<Ai_ItemTypeModel>> TeachingItems(Ai_Request paramDto)
{
var list = await (
from s in _studentRepository.DbContext.Set<Ai_Special>()
select new Ai_ItemTypeModel()
{
ItemCode = s.Id,
2025-07-07 14:56:38 +08:00
ItemTypeName = s.SpecialName
2025-06-06 16:00:39 +08:00
}).ToListAsync();
return list;
}
/// <summary>
/// 获取专项教学项目详情
/// </summary>
public async Task<Ai_TeachingItemsDetailModel> TeachingItemsDetail(Ai_TeachingItemsRequest paramDto)
{
if (paramDto == null || paramDto.ItemCode <= 0)
2025-07-07 14:56:38 +08:00
{
Console.WriteLine("参数为空,跳过...");
return new Ai_TeachingItemsDetailModel();
}
2025-06-06 16:00:39 +08:00
var result = await (
from s in _studentRepository.DbContext.Set<Ai_Special>()
where s.Id == paramDto.ItemCode
select new Ai_TeachingItemsDetailModel
{
BasicSkillList = s.SpecialLevelList
.Select(level => new SpecialLevelBasicSkill
{
Id = level.Id,
Name = level.LevelName,
StartGrade = level.StartGrade,
EndGrade = level.EndGrade,
SpecialActionModes = level.SpecialActionList
.Where(a => a.ActionType == SpecialActionType.BasicSkill)
.Select(a => new SpecialActionBasicSkill
{
Id = a.Id,
Name = a.ActionName,
ActionVideoPath = a.ActionVideoPath,
ExplainVideoPath = a.ExplainVideoPath,
ExerciseVideoPath = a.ExerciseVideoPath,
StandardVideoPath = a.StandardVideoPath
}).ToList()
}).ToList(),
SpecialStaminaList = s.SpecialLevelList
.Select(level => new SpecialLevelSpecialStamina
{
Id = level.Id,
Name = level.LevelName,
StartGrade = level.StartGrade,
EndGrade = level.EndGrade,
SpecialActionModes = level.SpecialActionList
.Where(a => a.ActionType == SpecialActionType.SpecialStamina)
.Select(a => new SpecialActionSpecialStamina
{
Id = a.Id,
Name = a.ActionName,
ActionVideoPath = a.ActionVideoPath
}).ToList()
}).ToList(),
}).FirstOrDefaultAsync();
return result;
}
/// <summary>
/// 获取赛事活动列表
/// </summary>
public async Task<PageDataDto<Ai_ActivitiesListDto>> ActivitiesList(Ai_ActivitiesListRequest paramDto)
{
var res = new PageDataDto<Ai_ActivitiesListDto>();
var query = from s in _studentRepository.DbContext.Set<G_Activities>()
where s.SchoolCode.Equals(paramDto.SchoolCode)
select new Ai_ActivitiesListDto()
{
ActivitiesId = s.Id,
ItemCode = s.CategoryId,
ActivitiesName = s.ActivitiesName,
ItemName = s.CategoryName,
EndDate = s.EndDate,
StartDate = s.StartDate,
ActivitiesStatus = s.ActivitiesStatus,
ImagePath = s.ImagePath,
ModeType = s.ModeType,
DataType = s.DataType
};
if (paramDto.ActivitiesStatus > 0)
{
query = query.Where(x => x.ActivitiesStatus == paramDto.ActivitiesStatus);
}
if (paramDto.ModeType > 0)
{
query = query.Where(x => x.ModeType == paramDto.ModeType);
}
if (paramDto.DataType > 0)
{
query = query.Where(x => x.DataType == paramDto.DataType);
}
res.Total = await query.CountAsync();
res.PageIndex = paramDto.PageIndex;
res.PageSize = paramDto.PageSize;
res.TotalPages = (int)Math.Ceiling((double)res.Total / paramDto.PageSize);
var list = await query
.Skip((paramDto.PageIndex - 1) * paramDto.PageSize)
.Take(paramDto.PageSize)
.ToListAsync();
res.Datas = list;
return res;
}
/// <summary>
/// 获取赛事活动排行
/// </summary>
public async Task<ActivitiesRankingPageDataDto<Ai_ActivitiesRankingDto>> ActivitiesRanking(Ai_ActivitiesRequest paramDto)
{
var res = new ActivitiesRankingPageDataDto<Ai_ActivitiesRankingDto>();
var query = from a in _activitiestDataRepository.DbContext.Set<Ai_ActivitiestData>()
join s in _activitiestDataRepository.DbContext.Set<S_Student>() on a.StudentNo equals s.StudentNo
join c in _activitiestDataRepository.DbContext.Set<S_School>() on s.SchoolCode equals c.SchoolCode
where a.ActivitiesId == paramDto.ActivitiesId
orderby a.Value descending
select new Ai_ActivitiesRankingDto()
{
SchoolName = c.SchoolName,
Score = a.Value.ToString(),
GradeAndClass = $"{a.GradeName}-{a.ClassName}",
Sex = s.Sex,
StudentName = s.StudentName,
Photo = s.Photo,
SportsTestDataType = a.DataType,
CategoryEnumType = a.CategoryValue,
};
res.Total = await query.CountAsync();
res.Name = paramDto.ActivitiesName;
var pagedDataList = await query
.Skip((paramDto.PageIndex - 1) * paramDto.PageSize)
.Take(paramDto.PageSize)
.ToListAsync();
var rankedList = pagedDataList
.Select((item, index) => new Ai_ActivitiesRankingDto
{
SchoolName = item.SchoolName,
Score = item.Score,
GradeAndClass = item.GradeAndClass,
Sex = item.Sex,
StudentName = item.StudentName,
Photo = item.Photo,
SportsTestDataType = item.SportsTestDataType,
CategoryEnumType = item.CategoryEnumType,
Ranking = (paramDto.PageIndex - 1) * paramDto.PageSize + (index + 1)
})
.ToList();
res.Datas = rankedList;
return res;
}
/// <summary>
/// 获取体测排行
/// </summary>
/// <param name="paramDto"></param>
/// <returns></returns>
/// <exception cref="NotImplementedException"></exception>
public async Task<PageDataDto<Ai_RankingListDto>> SportsTestRanking(Ai_RankingListRequest paramDto)
{
var res = new PageDataDto<Ai_RankingListDto>();
// 构建查询
var query = _sportsTestDataRepository.FindAsIQueryable(x =>
x.CategoryValue == paramDto.ItemCode &&
x.SchoolCode == paramDto.SchoolCode && x.DataType == paramDto.DataType);
if (paramDto.TodayTime.HasValue)
{
var todayStart = paramDto.TodayTime.Value.Date;
var todayEnd = todayStart.AddDays(1).AddTicks(-1);
query = query.Where(x => x.StartTime >= todayStart && x.StartTime <= todayEnd);
}
if (paramDto.GradeId > 0)
{
query = query.Where(x => x.GradeId == paramDto.GradeId);
}
if (paramDto.ClassId > 0)
{
query = query.Where(x => x.ClassId == paramDto.ClassId);
}
// 异步获取数据列表
var rawData = await query.ToListAsync().ConfigureAwait(false);
// 在内存中分组并获取每个分组中最大的值
var data = rawData
.GroupBy(x => x.StudentNo)
.Select(g => g.OrderByDescending(x => x.Value).FirstOrDefault()) // 获取每个学生 Value 最大的数据
.OrderByDescending(x => x.Value)
.Skip((paramDto.PageIndex - 1) * paramDto.PageSize)
.Take(paramDto.PageSize)
.Select(x => new Ai_RankingListDto()
{
StudentNo = x.StudentNo,
StudentName = x.StudentName,
Value = x.Value,
})
.ToList();
res.Total = data.Count;
// 计算排名
var list = data
.Select((item, index) => new Ai_RankingListDto
{
StudentNo = item.StudentNo,
StudentName = item.StudentName,
Value = item.Value,
Ranking = (paramDto.PageIndex - 1) * paramDto.PageSize + (index + 1)
})
.ToList();
res.Datas = list;
return res;
}
/// <summary>
/// 体测成绩查询
/// </summary>
/// <param name="paramDto"></param>
/// <returns></returns>
/// <exception cref="NotImplementedException"></exception>
public async Task<PageDataDto<Ai_SportsTestDto>> SportsTestResult(Ai_SportsTestRequest paramDto)
{
var res = new PageDataDto<Ai_SportsTestDto>();
var query = from a in _sportsTestDataRepository.FindAsIQueryable(x =>
x.CategoryValue == paramDto.ItemCode &&
x.SchoolCode == paramDto.SchoolCode)
//.Include(c => c.FileList)
orderby a.ScoreTime descending
select new Ai_SportsTestDto()
{
//IfVideo = a.FileList.Count > 0,
//FileList = _mapper.Map<List<FileList>>(a.FileList),
Value = a.Value,
SportsTestDataType = a.DataType,
CategoryEnumType = a.CategoryValue,
TestTime = a.ScoreTime,
StudentNo = a.StudentNo,
StudentName = a.StudentName
};
res.Total = await query.CountAsync();
var list = await query
.Skip((paramDto.PageIndex - 1) * paramDto.PageSize)
.Take(paramDto.PageSize)
.ToListAsync();
res.Datas = list;
return res;
}
/// <summary>
/// 训练成绩上传
/// </summary>
public async Task TrainingDataUpload(Ai_ResultUploadRequest paramDto)
{
//var trainingDataIds = paramDto.Select(c => c.TrainingDataId).ToList();
//if (paramDto == null)
// throw new ArgumentNullException($"参数为空");
//if (trainingDataIds.Any(c => c < 0))
// throw new ArgumentNullException($"训练数据Id必传");
//var trainingDatas = await _studentRepository.FindAsync<Ai_TrainingData>(s =>
// s.SchoolCode.Equals(UserContext.Current.TenantId) &&
// trainingDataIds.Contains(s.Id)
//);
//// 判断是否所有训练详情都有训练数据
//if (!trainingDataIds.All(c => trainingDatas.Select(x => x.Id).Contains(c)))
// throw new ArgumentNullException($"存在未找到的训练数据Id");
//var students = await _studentRepository.FindAsync<S_Student>(s =>
// s.SchoolCode.Equals(UserContext.Current.TenantId) &&
// paramDto.Select(c => c.StudentNo).Contains(s.StudentNo)
//);
//// 判断是否都有学号
//if (!students.Select(c => c.StudentNo).All(c => students.Select(s => s.StudentNo).Contains(c)))
// throw new ArgumentNullException($"存在未找到的学号");
//var trainingDetailsData = paramDto.Select(c => new Ai_TrainingData
//{
// StudentNo = c.StudentNo,
// StudentName = students.First(d => d.StudentNo == c.StudentNo).StudentName,
// Sex = students.First(d => d.StudentNo == c.StudentNo).Sex,
// Value = c.Value,
// MotionDuration = c.MotionDuration,
// Consumption = c.Consumption,
// Strength = c.Strength,
// Score = c.Score,
// AdditionalScore = c.AdditionalScore,
// Rank = c.Rank,
// RankStr = c.RankStr,
// ErrorNumber = c.ErrorNumber,
// CorrectNumber = c.CorrectNumber,
// MaxValue = c.MaxValue,
// MinValue = c.MinValue
//}).ToList();
//_studentRepository.AddRange<Ai_TrainingData>(trainingDetailsData);
//await _studentRepository.SaveChangesAsync();
if (paramDto == null)
2025-07-07 14:56:38 +08:00
{
Console.WriteLine("参数为空,跳过...");
return;
}
2025-06-06 16:00:39 +08:00
var entity = _mapper.Map<Ai_TrainingData>(paramDto);
await _trainingDataRepository.AddAsync(entity);
await _trainingDataRepository.SaveChangesAsync();
}
/// <summary>
/// 体测成绩上传
/// </summary>
/// <param name="paramDto"></param>
/// <returns></returns>
/// <exception cref="NotImplementedException"></exception>
public async Task SportsTestResultUpload(SportsTestResultUploadRequest paramDto)
{
if (paramDto == null)
2025-07-07 14:56:38 +08:00
{
Console.WriteLine("参数为空,跳过...");
return;
}
2025-06-06 16:00:39 +08:00
var entity = _mapper.Map<Ai_SportsTestData>(paramDto);
var student = await (from s in _studentRepository.FindAsIQueryable(x => x.SchoolCode == paramDto.SchoolCode && x.StudentNo == paramDto.StudentNo)
join c in _studentRepository.DbContext.Set<S_Class>() on s.ClassId equals c.Id
select new
{
s.ClassId,
s.ClassName,
s.Sex,
s.StudentName,
c.GradeId,
c.GradeName
}).FirstOrDefaultAsync();
if (student == null)
2025-07-07 14:56:38 +08:00
{
Console.WriteLine("未找到学生信息,跳过...");
return;
}
2025-06-06 16:00:39 +08:00
SemesterDto semesterDto = new SemesterDto();
entity.Year = semesterDto.Year;
entity.Semester = semesterDto.Semester;
entity.ScoreTime = paramDto.StartTime;
entity.GradeId = student.GradeId;
entity.ClassId = student.ClassId;
entity.GradeName = student.GradeName;
entity.ClassName = student.ClassName;
entity.StudentName = student.StudentName;
entity.Sex = student.Sex;
2025-07-07 14:56:38 +08:00
entity.IsDisplay = true;
2025-06-06 16:00:39 +08:00
var categoryEnum = Tool.GetEnumNameByValue(paramDto.CategoryValue);
var healthStandards = await _healthStandardsRepository.FindAsync(x => x.CategoryEnum == categoryEnum);
var standard = healthStandards.Where(x =>
x.CategoryEnum.Equals(categoryEnum) &&
x.GradeId == student.GradeId &&
x.Sex == student.Sex &&
paramDto.Value >= x.MinValue &&
paramDto.Value < x.MaxValue
).FirstOrDefault();
if (standard != null)
{
entity.Score = standard.Score;
entity.Rank = standard.Rank;
entity.RankEnum = Tool.GetEnumByRankName(standard.Rank);
entity.AdditionalScore = entity.Score == 100 ? 20 : 0;
}
await _sportsTestDataRepository.AddAsync(entity);
await _sportsTestDataRepository.SaveChangesAsync();
}
/// <summary>
/// Ai赛场成绩上传
/// </summary>
/// <param name="paramDto"></param>
/// <returns></returns>
/// <exception cref="NotImplementedException"></exception>
public async Task ActivitiestResultUpload(Ai_ActivitiestResultUploadRequest paramDto)
{
if (paramDto == null)
2025-07-07 14:56:38 +08:00
{
Console.WriteLine("参数为空,跳过...");
return;
}
2025-06-06 16:00:39 +08:00
var entity = _mapper.Map<Ai_ActivitiestData>(paramDto);
SemesterDto semesterDto = new SemesterDto();
entity.Year = semesterDto.Year;
entity.Semester = semesterDto.Semester;
await _activitiestDataRepository.AddAsync(entity);
await _activitiestDataRepository.SaveChangesAsync();
}
/// <summary>
/// 考级测评成绩上传
/// </summary>
/// <param name="paramDto"></param>
/// <returns></returns>
/// <exception cref="NotImplementedException"></exception>
public async Task LevelExamResultUpload(LevelExamDataUploadRequest paramDto)
{
if (paramDto == null)
2025-07-07 14:56:38 +08:00
{
Console.WriteLine("参数为空,跳过...");
return;
}
2025-06-06 16:00:39 +08:00
var entity = _mapper.Map<Ai_LevelExamData>(paramDto);
SemesterDto semesterDto = new SemesterDto();
entity.Year = semesterDto.Year;
entity.Semester = semesterDto.Semester;
var student = await (from s in _studentRepository.FindAsIQueryable(x => x.SchoolCode == paramDto.SchoolCode && x.StudentNo == paramDto.StudentNo)
2025-07-09 10:01:31 +08:00
join c in _classRepository.DbContext.Set<S_Class>() on s.ClassId equals c.Id
2025-06-06 16:00:39 +08:00
select new
{
s.ClassId,
s.ClassName,
s.Sex,
s.StudentName,
c.GradeId,
c.GradeName
}).FirstOrDefaultAsync();
if (student == null)
2025-07-07 14:56:38 +08:00
{
Console.WriteLine("未找到学生信息,跳过...");
return;
}
2025-06-06 16:00:39 +08:00
entity.ScoreTime = paramDto.StartTime;
entity.StartTime = paramDto.StartTime;
entity.EndTime = paramDto.EndTime;
entity.GradeId = student.GradeId;
entity.ClassId = student.ClassId;
entity.GradeName = student.GradeName;
entity.ClassName = student.ClassName;
entity.StudentName = student.StudentName;
entity.Sex = student.Sex;
2025-07-07 14:56:38 +08:00
entity.IsDisplay = true;
2025-06-06 16:00:39 +08:00
await _levelExamDataRepository.AddAsync(entity);
await _levelExamDataRepository.SaveChangesAsync();
}
/// <summary>
/// 心率数据上传
/// </summary>
/// <param name="paramDto"></param>
/// <returns></returns>
/// <exception cref="NotImplementedException"></exception>
2025-07-07 14:56:38 +08:00
public async Task HeartRateResultUpload(AddHeartRateResultUploadRequest paramDto)
2025-06-06 16:00:39 +08:00
{
if (paramDto == null || paramDto.Datas == null || paramDto.Datas.Count == 0)
2025-07-07 14:56:38 +08:00
{
Console.WriteLine("参数为空或数据为空,跳过处理。");
return;
}
2025-06-06 16:00:39 +08:00
var heartRateDatas = _mapper.Map<List<Ai_HeartRateData>>(paramDto.Datas);
2025-07-07 14:56:38 +08:00
heartRateDatas = heartRateDatas.Where(data => data.Value != 0).ToList();
2025-06-06 16:00:39 +08:00
var classIds = paramDto.Datas.Select(x => x.ClassId).ToList();
var classList = await _classRepository.FindAsync(x => x.SchoolCode == paramDto.SchoolCode && classIds.Contains(x.Id));
2025-07-07 14:56:38 +08:00
var timeNow = DateTime.Now;
2025-06-06 16:00:39 +08:00
heartRateDatas.ForEach(heartRateData =>
{
var classInfo = classList.Where(x => x.Id == heartRateData.ClassId).First();
heartRateData.Code = paramDto.Code;
heartRateData.SchoolCode = paramDto.SchoolCode;
heartRateData.ClassRoomRecordId = paramDto.ClassRoomRecordId;
heartRateData.TeacherId = paramDto.TeacherId;
heartRateData.GradeId = classInfo.GradeId;
heartRateData.GradeName = classInfo.GradeName;
2025-07-07 14:56:38 +08:00
heartRateData.ScoreTime = timeNow;
heartRateData.IsDisplay = true;
//HeartRateQueueData.Add(heartRateData);
2025-06-06 16:55:14 +08:00
});
2025-07-07 14:56:38 +08:00
await _heartRateDataRepository.AddRangeAsync(heartRateDatas);
await _heartRateDataRepository.SaveChangesAsync();
2025-06-06 16:00:39 +08:00
}
/// <summary>
/// 速度跳绳成绩上传
/// </summary>
/// <param name="paramDto"></param>
/// <returns></returns>
/// <exception cref="NotImplementedException"></exception>
public async Task FastJumpRopeResultUpload(AddFastJumpRopeResultUploadRequest paramDto)
{
if (paramDto == null || paramDto.Datas == null || paramDto.Datas.Count == 0)
2025-07-07 14:56:38 +08:00
{
Console.WriteLine("参数为空或数据为空,跳过处理。");
return;
}
2025-06-06 16:00:39 +08:00
var fastJumpRopeDatas = _mapper.Map<List<Ai_FastJumpRopeData>>(paramDto.Datas);
var classIds = paramDto.Datas.Select(x => x.ClassId).ToList();
var classList = await _classRepository.FindAsync(x => x.SchoolCode == paramDto.SchoolCode && classIds.Contains(x.Id));
fastJumpRopeDatas.ForEach(data =>
{
var classInfo = classList.Where(x => x.Id == data.ClassId).First();
data.Code = paramDto.Code;
data.SchoolCode = paramDto.SchoolCode;
data.ClassRoomRecordId = paramDto.ClassRoomRecordId;
2025-07-07 14:56:38 +08:00
data.GroupId = paramDto.GroupId;
2025-06-06 16:00:39 +08:00
data.TeacherId = paramDto.TeacherId;
data.GradeId = classInfo.GradeId;
data.GradeName = classInfo.GradeName;
data.ClassName = classInfo.ClassName;
data.ScoreTime = paramDto.ScoreTime;
data.ModeType = paramDto.ModeType;
data.ModelName = paramDto.ModeType.GetDescription();
data.UniqueId = paramDto.UniqueId;
});
await _fastJumpRopeDataRepository.AddRangeAsync(fastJumpRopeDatas);
await _fastJumpRopeDataRepository.SaveChangesAsync();
}
/// <summary>
/// 速度跳绳测试列表
/// </summary>
/// <param name="paramDto"></param>
/// <returns></returns>
/// <exception cref="NotImplementedException"></exception>
public async Task<PageDataDto<Ai_FastJumpRopeDto>> FastJumpRopeTestList(Ai_FastJumpRopeRequest paramDto)
{
var res = new PageDataDto<Ai_FastJumpRopeDto>();
var groupedQuery = from a in _fastJumpRopeDataRepository.FindAsIQueryable(x =>
2025-07-07 14:56:38 +08:00
x.SchoolCode == paramDto.SchoolCode &&
(paramDto.ClassRoomRecordId == null || paramDto.ClassRoomRecordId <= 0 || x.ClassRoomRecordId == paramDto.ClassRoomRecordId))
2025-06-06 16:00:39 +08:00
group a by a.GroupId into g
select new
{
GroupId = g.Key,
2025-07-07 14:56:38 +08:00
g.FirstOrDefault().MotionDuration,
g.FirstOrDefault().ModeType,
g.FirstOrDefault().ModelName,
//MotionDuration = g.FirstOrDefault().MotionDuration,
2025-06-06 16:00:39 +08:00
ScoreTime = g.Max(x => x.ScoreTime),
TestItem = Ai_TrainingModuleEnum.FastJumpRope.GetDescription()
};
// 获取总记录数
res.Total = await groupedQuery.CountAsync();
// 分页查询
var list = await groupedQuery
.OrderByDescending(x => x.ScoreTime)
.Skip((paramDto.PageIndex - 1) * paramDto.PageSize)
.Take(paramDto.PageSize)
.Select(x => new Ai_FastJumpRopeDto
{
GroupId = x.GroupId,
2025-07-07 14:56:38 +08:00
ModeType = x.ModeType,
2025-06-06 16:00:39 +08:00
ModelName = x.ModelName,
MotionDuration = x.MotionDuration,
ScoreTime = x.ScoreTime,
TestItem = x.TestItem
})
.ToListAsync();
res.Datas = list;
return res;
}
/// <summary>
/// 速度跳绳成绩排行
/// </summary>
/// <param name="uniqueId"></param>
/// <returns></returns>
/// <exception cref="NotImplementedException"></exception>
public async Task<PageDataDto<Ai_FastJumpRopeStudentList>> FastJumpRopeRanking(Ai_FastJumpRopeRankingRequest paramDto)
{
var res = new PageDataDto<Ai_FastJumpRopeStudentList>();
2025-06-06 16:55:14 +08:00
// 构建查询
2025-07-07 14:56:38 +08:00
//var query = _fastJumpRopeDataRepository.FindAsIQueryable(x =>
// x.ClassRoomRecordId == paramDto.ClassRoomRecordId &&
// x.SchoolCode == paramDto.SchoolCode &&
// (paramDto.ModeType != Ai_FastJumpRopeModeEnum.FollowMode || x.GroupId == paramDto.GroupId)
// );
2025-06-06 16:00:39 +08:00
var query = _fastJumpRopeDataRepository.FindAsIQueryable(x =>
2025-07-07 14:56:38 +08:00
x.ClassRoomRecordId == paramDto.ClassRoomRecordId &&
x.SchoolCode == paramDto.SchoolCode && x.GroupId == paramDto.GroupId);
2025-06-06 16:00:39 +08:00
// 异步获取数据列表
var rawData = await query.ToListAsync();
// 在内存中分组并获取每个分组中最大的值
var data = rawData
.GroupBy(x => x.StudentNo)
.Select(g => g.OrderByDescending(x => x.JumpValue).FirstOrDefault())
.OrderByDescending(x => x.JumpValue)
.Skip((paramDto.PageIndex - 1) * paramDto.PageSize)
.Take(paramDto.PageSize)
.Select(x => new Ai_FastJumpRopeStudentList()
{
StudentNo = x.StudentNo,
StudentName = x.StudentName,
JumpValue = x.JumpValue,
ErrorNumber = x.ErrorNumber
})
.ToList();
res.Total = data.Count;
// 计算排名
var list = data
.Select((item, index) => new Ai_FastJumpRopeStudentList
{
StudentNo = item.StudentNo,
StudentName = item.StudentName,
JumpValue = item.JumpValue,
ErrorNumber = item.ErrorNumber,
Ranking = (paramDto.PageIndex - 1) * paramDto.PageSize + (index + 1)
})
.ToList();
res.Datas = list;
return res;
}
/// <summary>
/// 新增课堂记录
/// </summary>
/// <param name="paramDto"></param>
/// <returns></returns>
/// <exception cref="NotImplementedException"></exception>
public async Task<Ai_ClassRoomRecordDto> AddClassRoomRecord(Ai_ClassRoomRecordRequest paramDto)
{
if (paramDto == null)
2025-07-07 14:56:38 +08:00
{
Console.WriteLine("参数为空或数据为空,跳过处理。");
return new Ai_ClassRoomRecordDto();
}
2025-06-06 16:00:39 +08:00
var entity = _mapper.Map<Ai_ClassRoomRecord>(paramDto);
var ids = paramDto.ClassroomStudentRecord.Select(x => x.ClassId).ToList();
ids.Add(paramDto.ClassId);
var classInfos = await _classRepository.FindAsync(x => ids.Contains(x.Id) && x.SchoolCode == paramDto.SchoolCode);
var classInfo = classInfos.FirstOrDefault(x => x.Id == paramDto.ClassId);
if (classInfo == null)
2025-07-07 14:56:38 +08:00
{
Console.WriteLine("班级信息数据为空,跳过处理。");
return new Ai_ClassRoomRecordDto();
}
2025-06-06 16:00:39 +08:00
entity.ClassName = classInfo.ClassName;
entity.GradeId = classInfo.GradeId;
entity.GradeName = classInfo.GradeName;
entity.Name = $"{paramDto.TrainingModuleEnum.GetDescription()}-{paramDto.StartTime.ToUnixTimeMilliseconds()}";
SemesterDto semesterDto = new SemesterDto();
entity.Year = semesterDto.Year;
entity.Semester = semesterDto.Semester;
foreach (var student in entity.ClassroomStudentRecord)
{
var StuClass = classInfos.First(x => x.Id == student.ClassId);
if (StuClass == null)
2025-07-07 14:56:38 +08:00
{
Console.WriteLine("班级信息数据为空,跳过处理。");
return new Ai_ClassRoomRecordDto();
}
2025-06-06 16:00:39 +08:00
student.ClassName = StuClass.ClassName;
student.GradeId = StuClass.GradeId;
student.GradeName = StuClass.GradeName;
}
await _classRoomRecordRepository.AddAsync(entity);
await _classRoomRecordRepository.SaveChangesAsync();
return new Ai_ClassRoomRecordDto()
{
ClassRoomRecordId = entity.Id,
ClassRoomRecordName = entity.Name
};
}
/// <summary>
/// 结束授课
/// </summary>
/// <param name="paramDto"></param>
/// <returns></returns>
/// <exception cref="NotImplementedException"></exception>
public async Task EndTeaching(EndTeachingRequest paramDto)
{
if (paramDto == null)
2025-07-07 14:56:38 +08:00
{
Console.WriteLine("参数为空,跳过...");
return;
}
2025-06-06 16:00:39 +08:00
var entity = await _classRoomRecordRepository.FindAsyncFirst(x => x.Id == paramDto.ClassRoomRecordId && x.SchoolCode == paramDto.SchoolCode);
if (entity != null)
{
entity.EndTime = paramDto.EndTime;
_classRoomRecordRepository.Update(entity);
await _classRoomRecordRepository.SaveChangesAsync();
}
//if (paramDto.HeartRateResults != null && paramDto.HeartRateResults.Count > 0)
//{
// var entitys = _mapper.Map<List<Ai_HeartRateData>>(paramDto);
// await _heartRateDataRepository.AddRangeAsync(entitys);
// await _heartRateDataRepository.SaveChangesAsync();
//}
}
/// <summary>
/// 获取学生当前等级
/// </summary>
/// <param name="paramDto"></param>
/// <returns></returns>
/// <exception cref="NotImplementedException"></exception>
public async Task<StatusLevelExamDto> StatusLevelExam(StatusLevelExamRequest paramDto)
{
var maxRankModel = await _levelExamDataRepository.FindAsIQueryable(x => x.SpecialId == paramDto.SpecialId && x.StudentNo == paramDto.StudentNo && x.AssessmentResults == AssessmentResultsEnum.Pass).OrderByDescending(x => x.Rank).FirstOrDefaultAsync();
return new StatusLevelExamDto()
{
Rank = maxRankModel?.Rank ?? 0
};
}
/// <summary>
/// 验证学生是否在报名列表中
/// </summary>
/// <param name="paramDto"></param>
/// <returns></returns>
/// <exception cref="NotImplementedException"></exception>
public async Task<IsActivityInListDto> IsActivityInList(IsActivityInListRequest paramDto)
{
if (paramDto == null)
throw new ArgumentNullException($"参数为空");
var studentCount = await _studentRepository.DbContext.Set<G_EntryStudent>().Where(x =>
x.SchoolCode == paramDto.SchoolCode &&
x.ActivitiesId == paramDto.ActivitiesId &&
x.StudentNo == paramDto.StudentNo
).CountAsync();
var res = new IsActivityInListDto()
{
ActivitiesId = paramDto.ActivitiesId,
StudentNo = paramDto.StudentNo,
IsExist = studentCount > 0
};
return res;
}
2025-07-08 15:19:19 +08:00
/// <summary>
/// Ai一体机扫描那登录轮询
/// </summary>
/// <param name="paramDto"></param>
/// <returns></returns>
public async Task<Ai_TeacherFaceInfo> ScanCodeLogin(Ai_Request paramDto)
{
2025-07-09 10:01:31 +08:00
var loginInfo = await _scanCodeLoginRepository.FindAsIQueryable(x => x.Code == paramDto.Code && x.SchoolCode == paramDto.SchoolCode).FirstOrDefaultAsync();
2025-07-08 15:19:19 +08:00
if (loginInfo == null)
return new Ai_TeacherFaceInfo();
var res = await _teacherRepository.FindAsIQueryable(x => x.SchoolCode == paramDto.SchoolCode && x.TeacherStatus != TeacherStatus.Depart && x.TeacherPhoneNo == loginInfo.TeacherPhoneNo && x.Id == loginInfo.TeacherId)
.Select(x =>
new Ai_TeacherFaceInfo()
{
Id = x.Id,
Age = x.Age,
//SchoolCode = x.SchoolCode,
Sex = x.Sex,
Phone = x.TeacherPhoneNo,
TeacherName = x.TeacherName,
Photo = x.TeacherPhoto,
}).FirstOrDefaultAsync();
if (res == null)
throw new Exception("未查询到登陆信息");
var grades = await (
from t in _studentRepository.DbContext.Set<S_ClassAssocTeacher>()
join c in _studentRepository.DbContext.Set<S_Class>() on t.ClassId equals c.Id into classGroup
from c in classGroup.DefaultIfEmpty()
where t.TeacherId == res.Id && c != null
select new Classes()
{
Id = c.Id,
Name = $"{c.GradeName}-{c.ClassName}",
}).ToListAsync();
res.GradeAndClassList = grades;
return res;
}
/// <summary>
/// 退出登录
/// </summary>
/// <param name="paramDto"></param>
/// <returns></returns>
public async Task<bool> LogOut(LoginOutDto paramDto)
{
2025-07-09 10:01:31 +08:00
var teacher = await _scanCodeLoginRepository.FindAsIQueryable(x => x.Code == paramDto.Code && x.SchoolCode == paramDto.SchoolCode).FirstOrDefaultAsync();
2025-07-08 15:19:19 +08:00
if (teacher == null) return true;
2025-07-09 10:01:31 +08:00
_scanCodeLoginRepository.Delete(teacher);
2025-07-08 15:19:19 +08:00
return await _teacherRepository.SaveChangesAsync() > 0;
}
2025-06-06 16:00:39 +08:00
}
}