Compare commits

...

3 Commits

Author SHA1 Message Date
5c3471dbcd s 2025-07-10 11:31:03 +08:00
3969283904 d 2025-07-10 11:30:57 +08:00
2d0f01d902 s 2025-07-10 11:27:10 +08:00
7 changed files with 7775 additions and 42 deletions

View File

@ -43,24 +43,31 @@ namespace VOL.Ai.Services
private readonly ISportsTestDataRepository _sportsTestDataRepository; private readonly ISportsTestDataRepository _sportsTestDataRepository;
private readonly ITrainingDataRepository _trainingDataRepository; private readonly ITrainingDataRepository _trainingDataRepository;
private readonly IFastJumpRopeDataRepository _fastJumpRopeDataRepository; private readonly IFastJumpRopeDataRepository _fastJumpRopeDataRepository;
private readonly ISys_UserRepository _userRepository;
private readonly IClassroomStageRepository _classroomStageRepository;
private readonly IClassroomSettingRepository _classroomSettingRepository;
[ActivatorUtilitiesConstructor] [ActivatorUtilitiesConstructor]
public AiAppService(IMapper mapper, public AiAppService(IMapper mapper,
IS_StudentRepository studentRepository, IS_StudentRepository studentRepository,
IS_TeacherRepository teacherRepository, IS_TeacherRepository teacherRepository,
IS_ClassRepository classRepository, IS_ClassRepository classRepository,
IN_SportsTestCategoryRepository sportsTestCategoryRepository, IN_SportsTestCategoryRepository sportsTestCategoryRepository,
IN_HealthStandardsRepository healthStandardsRepository, IN_HealthStandardsRepository healthStandardsRepository,
IScanCodeLoginRepository scanCodeLoginRepository, IScanCodeLoginRepository scanCodeLoginRepository,
IN_SportsTrainingCategoryRepository sportsTrainingCategoryRepository, IN_SportsTrainingCategoryRepository sportsTrainingCategoryRepository,
IClassRoomRecordRepository classRoomRecordRepository, IClassRoomRecordRepository classRoomRecordRepository,
IHeartRateDataRepository heartRateDataRepository, IHeartRateDataRepository heartRateDataRepository,
IActivitiestDataRepository activitiestDataRepository, IActivitiestDataRepository activitiestDataRepository,
ILevelExamDataRepository levelExamDataRepository, ILevelExamDataRepository levelExamDataRepository,
ISportsTestDataRepository sportsTestDataRepository, ISportsTestDataRepository sportsTestDataRepository,
ITrainingDataRepository trainingDataRepository, ITrainingDataRepository trainingDataRepository,
IFastJumpRopeDataRepository fastJumpRopeDataRepository IFastJumpRopeDataRepository fastJumpRopeDataRepository,
) ISys_UserRepository userRepository,
IClassroomStageRepository classroomStageRepository,
IClassroomSettingRepository classroomSettingRepository
)
{ {
_mapper = mapper; _mapper = mapper;
_studentRepository = studentRepository; _studentRepository = studentRepository;
@ -77,6 +84,9 @@ namespace VOL.Ai.Services
_trainingDataRepository = trainingDataRepository; _trainingDataRepository = trainingDataRepository;
_classRepository = classRepository; _classRepository = classRepository;
_fastJumpRopeDataRepository = fastJumpRopeDataRepository; _fastJumpRopeDataRepository = fastJumpRopeDataRepository;
_userRepository = userRepository;
_classroomStageRepository = classroomStageRepository;
_classroomSettingRepository = classroomSettingRepository;
} }
#region New #region New
@ -1234,6 +1244,49 @@ namespace VOL.Ai.Services
if (res == null) if (res == null)
throw new Exception("未查询到登陆信息"); 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<Ai_TeacherFaceInfo> Login(Ai_LoginRequest paramDto)
{
var userInfo = await _userRepository.FindFirstAsync(x => x.UserName == paramDto.UserName && x.UserPwd == paramDto.Password);
if (userInfo == null)
throw new Exception("用户名或密码错误");
var res = await _teacherRepository.FindAsIQueryable(x => x.SchoolCode == paramDto.SchoolCode && x.TeacherStatus != TeacherStatus.Depart && x.TeacherPhoneNo == userInfo.UserName)
.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 ( var grades = await (
from t in _studentRepository.DbContext.Set<S_ClassAssocTeacher>() from t in _studentRepository.DbContext.Set<S_ClassAssocTeacher>()
@ -1266,34 +1319,180 @@ namespace VOL.Ai.Services
return await _teacherRepository.SaveChangesAsync() > 0; return await _teacherRepository.SaveChangesAsync() > 0;
} }
public Task<Ai_TeacherFaceInfo> Login(Ai_LoginRequest paramDto) /// <summary>
/// 获取课堂记录列表
/// </summary>
/// <param name="paramDto"></param>
/// <returns></returns>
public async Task<PageDataDto<Ai_ClassRoomRecordPageListDto>> ClassRoomRecordPageList(ClassRoomRecordPageListRequest paramDto)
{ {
throw new NotImplementedException(); var res = new PageDataDto<Ai_ClassRoomRecordPageListDto>();
var query = _classRoomRecordRepository.FindAsIQueryable(x => x.TeacherId == paramDto.TeacherId);
// 获取总记录数
res.Total = await query.CountAsync();
// 分页查询
var list = await query
.OrderByDescending(x => x.StartTime)
.Skip((paramDto.PageIndex - 1) * paramDto.PageSize)
.Take(paramDto.PageSize)
.Select(x => new Ai_ClassRoomRecordPageListDto
{
GradeAndClassName = $"{x.GradeName}-{x.ClassName}",
StartEndTime = $"{x.StartTime.ToString("yyyy-MM-dd HH:mm")}-{x.EndTime.ToString("yyyy-MM-dd HH:mm")}",
TeacherName = x.TeacherName
}).ToListAsync();
res.Datas = list;
return res;
} }
public Task<PageDataDto<Ai_ClassRoomRecordPageListDto>> ClassRoomRecordPageList(ClassRoomRecordPageListRequest paramDto) /// <summary>
/// 获取课堂阶段列表
/// </summary>
/// <param name="paramDto"></param>
/// <returns></returns>
public async Task<List<ClassroomStageDto>> ClassroomStagePageList(Ai_Request paramDto)
{ {
throw new NotImplementedException(); var res = await _classroomStageRepository.FindAsIQueryable(x => true).Select(x => new ClassroomStageDto()
{
Id = x.Id,
Name = x.Name
}).ToListAsync();
return res;
} }
public Task<List<ClassroomStageDto>> ClassroomStagePageList(Ai_Request paramDto) /// <summary>
/// 添加课堂设置
/// </summary>
/// <param name="paramDto"></param>
/// <returns></returns>
public async Task<bool> AddClassroomSetting(AddClassroomSettingRequest paramDto)
{ {
throw new NotImplementedException(); var classroomSettingList = new List<Ai_ClassroomSetting>();
foreach (var item in paramDto.ClassroomSettingList)
{
classroomSettingList.Add(new Ai_ClassroomSetting()
{
ClassRoomRecordId = paramDto.ClassRoomRecordId,
ClassroomStageId = item.ClassroomStageId,
Density = item.Density,
Duration = item.Duration
});
}
if (classroomSettingList.Count > 0)
{
await _classroomSettingRepository.AddRangeAsync(classroomSettingList);
return await _classroomSettingRepository.SaveChangesAsync() > 0;
}
return false;
} }
public Task<bool> AddClassroomSetting(AddClassroomSettingRequest paramDto) /// <summary>
/// 更新课堂设置
/// </summary>
/// <param name="paramDto"></param>
/// <returns></returns>
public async Task<bool> UpdateClassroomSetting(UpdateClassroomSettingRequest paramDto)
{ {
throw new NotImplementedException(); var classroomSetting = await _classroomSettingRepository.FindAsyncFirst(x => x.ClassRoomRecordId == paramDto.ClassRoomRecordId && x.ClassroomStageId == paramDto.ClassroomStageId);
if (classroomSetting == null)
return false;
classroomSetting.Density = paramDto.Density;
classroomSetting.Duration = paramDto.Duration;
_classroomSettingRepository.Update(classroomSetting);
return await _classroomSettingRepository.SaveChangesAsync() > 0;
} }
public Task<bool> UpdateClassroomSetting(UpdateClassroomSettingRequest paramDto) /// <summary>
/// 获取课堂心率报告
/// </summary>
/// <param name="paramDto"></param>
/// <returns></returns>
public async Task<Ai_HeartRateReportDto> HeartRateReport(HeartRateReportRequest paramDto)
{ {
throw new NotImplementedException(); var res = new GetClassReportDetailsModel();
}
public Task<Ai_HeartRateReportDto> HeartRateReport(HeartRateReportRequest paramDto) var query = from hrd in _teacherRepository.DbContext.Set<Ai_HeartRateData>()
{ where hrd.ClassRoomRecordId == paramDto.ClassRoomRecordId &&
throw new NotImplementedException(); select hrd;
var heartRateDataList = await query.ToListAsync();
if (heartRateDataList.Count == 0)
return res;
var classRoom = await _teacherRepository.DbContext.Set<Ai_ClassRoomRecord>().Include(x => x.ClassroomStudentRecord)
.Where(x => x.SchoolCode == UserContext.Current.TenantId && x.Id == id)
.FirstAsync();
var classRoomStudent = await _teacherRepository.DbContext.Set<Ai_ClassroomStudentRecord>()
.Where(x => x.SchoolCode == UserContext.Current.TenantId && x.ClassRoomRecordId == id)
.ToListAsync();
res.GradeAndClass = $"{classRoom.GradeName}-{classRoom.ClassName}";
res.TeacherName = classRoom.TeacherName;
res.StartingEndingTime = $"{(classRoom.StartTime.HasValue ? classRoom.StartTime.Value.ToString("yyyy-MM-dd HH:mm") : string.Empty)}{(classRoom.EndTime.HasValue ? " - " + classRoom.EndTime.Value.ToString("yyyy-MM-dd HH:mm") : string.Empty)}";
res.PeopleNumber = $"{heartRateDataList.GroupBy(x => x.StudentNo).Count()}/{classRoomStudent.Count}";
res.PeopleNumberBySex = $"{classRoomStudent.Count(x => x.Sex == SexType.Male)}/{classRoomStudent.Count(x => x.Sex == SexType.Female)}";
res.AvgHR = $"{(int)(heartRateDataList.Sum(x => x.Value) / heartRateDataList.Count)} 次/分";
res.Consumption = $"{Math.Abs(heartRateDataList.Sum(x => x.Consumption ?? 0) / heartRateDataList.Count)} 千卡";
//res.Density = $"{(int)(heartRateDataList.Where(x => x.Strength > 50).Sum(x => x.Strength) / heartRateDataList.Count)} %";
res.Density = $"{(int)CalculatePercentage(heartRateDataList.Count(x => x.Strength > 50), heartRateDataList.Count)} %";
res.HighIntensity = $"{heartRateDataList.Where(x => x.Strength > 50).GroupBy(x => x.StudentNo).Count()} 人";
var studentTrainingRecordList = classRoom.ClassroomStudentRecord.ToList();
List<StudentTrainingRecordDto> studentList = new List<StudentTrainingRecordDto>();
foreach (var item in studentTrainingRecordList)
{
var studentTrainingData = heartRateDataList.Where(x => x.StudentNo == item.StudentNo).ToList();
if (studentTrainingData.Count > 0)
{
var student = new StudentTrainingRecordDto()
{
StudentNo = item.StudentNo,
Age = item.Age,
Sex = item.Sex
};
student.StudentName = studentTrainingData[0].StudentName;
student.AvgHR = (int)(studentTrainingData.Sum(x => x.Value) / studentTrainingData.Count);
student.Density = (int)CalculatePercentage(studentTrainingData.Count(x => x.Strength > 50), studentTrainingData.Count);
student.Strength = (int)studentTrainingData.Average(x => x.Strength);
student.Consumption = Math.Abs((int)studentTrainingData.Average(x => x.Consumption ?? 0));
studentList.Add(student);
}
}
res.HeartRateNumber = GetHeartRateNumber(heartRateDataList);
res.HeartRateTrend = GetHeartRateTrend(heartRateDataList);
res.StudentTrainingRecordList = studentList;
//return new GetClassReportDetailsModel()
//{
// HeartRateNumber = GetHeartRateNumber(heartRateDataList),
// HeartRateTrend = GetHeartRateTrend(heartRateDataList),
// HeartRateIntensityNumber = GetHeartRateIntensityNumber(heartRateDataList),
// TimeIntervalHeartRateIntensityNumber = GetTimeIntervalHeartRateIntensityNumber(heartRateDataList)
//};
return res;
} }
public Task<GetStudentClassReportDetailsModel> StudentHeartRateReport(GetStudentClassReportDetailsDto paramDto) public Task<GetStudentClassReportDetailsModel> StudentHeartRateReport(GetStudentClassReportDetailsDto paramDto)

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,39 @@
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace VOL.Core.Migrations
{
public partial class _20250710v3 : Migration
{
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropColumn(
name: "ClassroomStageId",
table: "Ai_ClassRoomRecord");
migrationBuilder.AddColumn<int>(
name: "ClassroomStageId",
table: "Ai_HeartRateData",
type: "int",
nullable: false,
defaultValue: 0,
comment: "阶段Id");
}
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropColumn(
name: "ClassroomStageId",
table: "Ai_HeartRateData");
migrationBuilder.AddColumn<int>(
name: "ClassroomStageId",
table: "Ai_ClassRoomRecord",
type: "int",
nullable: false,
defaultValue: 0,
comment: "阶段Id");
}
}
}

View File

@ -205,10 +205,6 @@ namespace VOL.Core.Migrations
.HasColumnType("nvarchar(100)") .HasColumnType("nvarchar(100)")
.HasComment("班级名称"); .HasComment("班级名称");
b.Property<int>("ClassroomStageId")
.HasColumnType("int")
.HasComment("阶段Id");
b.Property<string>("Code") b.Property<string>("Code")
.HasColumnType("nvarchar(100)") .HasColumnType("nvarchar(100)")
.HasComment("AI设备的唯一编码"); .HasComment("AI设备的唯一编码");
@ -617,6 +613,10 @@ namespace VOL.Core.Migrations
.HasColumnType("int") .HasColumnType("int")
.HasComment("课堂记录Id"); .HasComment("课堂记录Id");
b.Property<int>("ClassroomStageId")
.HasColumnType("int")
.HasComment("阶段Id");
b.Property<string>("Code") b.Property<string>("Code")
.HasColumnType("nvarchar(100)") .HasColumnType("nvarchar(100)")
.HasComment("AI设备的唯一编码"); .HasComment("AI设备的唯一编码");

View File

@ -45,14 +45,6 @@ namespace VOL.Entity.DomainModels
[Column(TypeName = "nvarchar(200)")] [Column(TypeName = "nvarchar(200)")]
public string Name { get; set; } public string Name { get; set; }
/// <summary>
/// 阶段Id
/// </summary>
[Display(Name = "阶段Id")]
[Comment("阶段Id")]
[Column(TypeName = "int")]
public int ClassroomStageId { get; set; }
/// <summary> /// <summary>
/// 年级编号 /// 年级编号
/// </summary> /// </summary>

View File

@ -15,5 +15,10 @@ namespace VOL.Model.Ai.Request
/// 课堂记录Id /// 课堂记录Id
/// </summary> /// </summary>
public int ClassRoomRecordId { get; set; } public int ClassRoomRecordId { get; set; }
/// <summary>
/// 课堂阶段Id
/// </summary>
public int ClassRoomStageId { get; set; }
} }
} }

View File

@ -4,7 +4,7 @@ using System.Linq;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
namespace VOL.Model.Ai.Request namespace VOL.Model.Ai.Response
{ {
/// <summary> /// <summary>
/// 课堂阶段 /// 课堂阶段