using System;
using System.Threading.Tasks;
using AutoMapper;
using CSRedis;
using Microsoft.EntityFrameworkCore;
using YD_WeChatApplet.Api.SmartSportsEntitys;
using YD_WeChatApplet.Api.Utilities;
using YD_WeChatApplet.Commons.Dto;
using YD_WeChatApplet.Commons.Dto.ClassRoomRecord;
using YD_WeChatApplet.Commons.Dto.HomeWork;
using YD_WeChatApplet.Commons.Dto.SportsTest;
using YD_WeChatApplet.Commons.Dto.Teacher;
using YD_WeChatApplet.Context;
namespace YD_WeChatApplet.Services
{
public class TeacherService : ITeacherService
{
public UserContext _userContext;
public SmartSportsContext _sportsContext;
private readonly IMapper _mapper;
public TeacherService(UserContext userContext, SmartSportsContext sportsContext, IMapper mapper)
{
_userContext = userContext;
_sportsContext = sportsContext;
_mapper = mapper;
}
///
/// 老师个人信息
///
///
public async Task TeacherProfile()
{
var userId = UserLoginContext.Current.UserId;
var res = await _userContext.Users.Where(x => x.User_Id == userId).Select(x => new TeacherProfileDto()
{
UserTrueName = x.UserTrueName,
BirthDate = x.BirthDate,
Gender = x.Gender,
HeadImageUrl = x.HeadImageUrl,
Height = x.Height,
Weight = x.Weight
}).FirstOrDefaultAsync();
return res;
}
///
/// 修改个人信息
///
///
///
public async Task ModifyTeacherProfile(TeacherProfileDto paramDto)
{
var userId = UserLoginContext.Current.UserId;
var model = await _userContext.Users.FirstOrDefaultAsync(x => x.User_Id == userId);
if (model == null)
throw new Exception("更新数据为空");
model.UserTrueName = !string.IsNullOrWhiteSpace(paramDto.UserTrueName) ? paramDto.UserTrueName : model.UserTrueName;
model.HeadImageUrl = !string.IsNullOrWhiteSpace(paramDto.HeadImageUrl) ? paramDto.HeadImageUrl : model.HeadImageUrl;
model.BirthDate = paramDto.BirthDate ?? model.BirthDate;
model.Gender = paramDto.Gender ?? model.Gender;
model.Height = paramDto.Height ?? model.Height;
model.Weight = paramDto.Weight ?? model.Weight;
if (_userContext.Entry(model).State == EntityState.Modified)
{
await _userContext.SaveChangesAsync();
}
}
///
/// 修改密码
///
///
///
public async Task ModifyTeacherPwd(ModifyTeacherPwdDto paramDto)
{
if (paramDto.NewPwd != paramDto.ConfirmPwd)
throw new Exception("确认密码与新密码不一致");
var userId = UserLoginContext.Current.UserId;
var model = await _userContext.Users.FirstOrDefaultAsync(x => x.User_Id == userId && x.UserPwd == paramDto.OldPwd);
if (model == null)
throw new Exception("旧密码输入有误");
model.UserPwd = paramDto.NewPwd;
if (_userContext.Entry(model).State == EntityState.Modified)
{
_userContext.Update(model);
await _userContext.SaveChangesAsync();
}
}
///
/// 项目列表
///
///
public async Task> CategoryList(int gradeId)
{
var res = await (
from g in _sportsContext.GradeAssocCategory
join s in _sportsContext.SportsTestCategory on g.CategoryValue equals s.CategoryValue
where g.GradeId == gradeId
select new ComboBoxDto
{
Id = s.CategoryValue,
Name = s.CategoryName
}).ToListAsync();
return res;
}
///
/// 数据统计接口
///
///
///
///
public async Task DataStatistics(DataStatisticsFilterDto dto)
{
var res = new DataStatisticsDto();
var schoolCode = UserLoginContext.Current.SchoolCode;
var teacherId = await _sportsContext.Teacher.Where(x => x.TeacherPhoneNo == UserLoginContext.Current.PhoneNo).Select(x => x.Id).FirstOrDefaultAsync();
if (teacherId == 0)
return res;
var students = await (from a in _sportsContext.ClassAssocTeacher
join s in _sportsContext.Student on a.ClassId equals s.ClassId
where a.TeacherId == teacherId
&& s.SchoolCode == schoolCode
select new { s.StudentNo, s.Photo }).Distinct().ToListAsync();
res.HeadTotal = students.Count;
var currentDate = DateTime.Now;
var startOfMonth = new DateTime(currentDate.Year, currentDate.Month, 6);
var endOfMonth = startOfMonth.AddMonths(1).AddDays(-1);
// 构建基础查询
//IQueryable iotQuery = _sportsContext.SportsTestValue
// .Where(x => x.IsDisplay && x.SchoolCode == schoolCode && x.ScoreTime >= startOfMonth && x.ScoreTime <= endOfMonth);
//IQueryable aiQuery = _sportsContext.SportsTestData
// .Where(x => x.IsDisplay && x.SchoolCode == schoolCode && x.ScoreTime >= startOfMonth && x.ScoreTime <= endOfMonth);
IQueryable iotQuery = _sportsContext.SportsTestValue.Where(x => x.IsDisplay && x.SchoolCode == schoolCode);
//IQueryable aiQuery = _sportsContext.SportsTestData.Where(x => x.IsDisplay && x.SchoolCode == schoolCode);
// 动态追加筛选条件
if (dto.ClassId > 0)
{
iotQuery = iotQuery.Where(x => x.ClassId == dto.ClassId);
//aiQuery = aiQuery.Where(x => x.ClassId == dto.ClassId);
}
if (dto.CategoryValue > 0)
{
iotQuery = iotQuery.Where(x => x.CategoryValue == dto.CategoryValue);
//aiQuery = aiQuery.Where(x => x.CategoryValue == dto.CategoryValue);
}
//if (!string.IsNullOrWhiteSpace(dto.Rank))
//{
// iotQuery = iotQuery.Where(x => x.Rank == dto.Rank);
// aiQuery = aiQuery.Where(x => x.Rank == dto.Rank);
//}
// 并行执行查询
var iotTask = await iotQuery.ToListAsync();
//var aiTask = await aiQuery.ToListAsync();
// 映射并合并结果
//var sportsTestResults = _mapper.Map>(iotTask)
// .Concat(_mapper.Map>(aiTask))
// .ToList();
var sportsTestResults = _mapper.Map>(iotTask);
sportsTestResults = sportsTestResults
.GroupBy(x => new { x.StudentNo })
.Select(g =>
{
var latestRecord = g.OrderByDescending(x => x.Score).First();
//var latestRecord = g.Where(x => x.ScoreTime >= startOfMonth && x.ScoreTime <= endOfMonth).OrderByDescending(x => x.Score).First();
//latestRecord.Score = g.Max(x => x.Score);
//latestRecord.Value = g.Max(x => x.Value);
return latestRecord;
}).ToList();
if (!string.IsNullOrWhiteSpace(dto.Rank))
{
sportsTestResults = sportsTestResults.Where(x => x.Rank == dto.Rank).ToList();
}
res.RankDic.Add("优秀", sportsTestResults.Count(x => x.Rank == "优秀"));
res.RankDic.Add("良好", sportsTestResults.Count(x => x.Rank == "良好"));
res.RankDic.Add("及格", sportsTestResults.Count(x => x.Rank == "及格"));
res.RankDic.Add("不及格", sportsTestResults.Count(x => x.Rank == "不及格"));
res.Studentlist = new Commons.Dto.PageDataDto()
{
Total = sportsTestResults.Count,
Datas = sportsTestResults.Skip((dto.PageIndex - 1) * dto.PageSize).Take(dto.PageSize).Select(x => new StatisticsStudent()
{
StudentNo = x.StudentNo,
StudentName = x.StudentName,
Sex = x.Sex,
Photo = students.FirstOrDefault(y => y.StudentNo == x.StudentNo)?.Photo ?? "",
}).ToList()
};
return res;
}
///
/// 统计数据详情
///
///
///
///
public async Task DataStatisticsDetails(DataStatisticsDetailsFilterDto dto)
{
var res = new DataStatisticsDetailsDto();
var student = await _sportsContext.Student.Where(x => x.StudentNo == dto.StudentNo).FirstOrDefaultAsync();
var classInfo = await _sportsContext.Class.FirstOrDefaultAsync(x => x.Id == dto.ClassId);
var categorys = await (
from g in _sportsContext.GradeAssocCategory
join s in _sportsContext.SportsTestCategory on g.CategoryValue equals s.CategoryValue
where g.GradeId == classInfo.GradeId
select new
{
s.Id,
s.CategoryValue,
s.CategoryName,
g.Weight
}).ToListAsync();
if (student == null || categorys == null)
return res;
var iotQuery = await _sportsContext.SportsTestValue.Where(x => x.IsDisplay && x.SchoolCode == student.SchoolCode && x.StudentNo == dto.StudentNo).Select(x => new SportsTestValueModel()
{
StudentNo = x.StudentNo,
Value = x.Value,
Score = x.Score,
AdditionalScore = x.AdditionalScore,
CategoryValue = x.CategoryValue,
Rank = x.Rank
}).ToListAsync();
var aiQuery = await _sportsContext.SportsTestData.Where(x => x.IsDisplay && x.SchoolCode == student.SchoolCode && x.StudentNo == dto.StudentNo).Select(x => new SportsTestValueModel()
{
StudentNo = x.StudentNo,
Value = (float)x.Value,
Score = x.Score,
AdditionalScore = x.AdditionalScore,
CategoryValue = x.CategoryValue,
Rank = x.Rank
}).ToListAsync();
var sportsTestResults = iotQuery.Concat(aiQuery).ToList();
res.StudentNo = student.StudentNo;
res.StudentName = student.StudentName;
res.Sex = student.Sex == 1 ? "男" : "女";
res.Age = student.Age;
res.Photo = student.Photo;
res.CategoryScoreList = new List();
double totalScore = 0;
foreach (var item in categorys)
{
var maxResult = sportsTestResults.Where(x => x.CategoryValue == item.Id).OrderByDescending(x => x.Value).FirstOrDefault();
res.CategoryScoreList.Add(new CategoryScore()
{
CategoryName = item.CategoryName,
Value = maxResult != null ? Math.Round((double)maxResult.Value, 0) : 0,
Score = maxResult?.Score ?? 0,
Rank = maxResult?.Rank ?? ""
});
double currentScore = maxResult?.Score ?? 0;
double currentAdditionalScore = maxResult?.AdditionalScore ?? 0;
// 累积分数
totalScore += ((currentScore + currentAdditionalScore) * item.Weight);
}
res.ComprehensiveScore = totalScore.ToString("F0");
return res;
}
///
/// 课堂记录
///
///
///
public async Task> ClassRoomRecord(ClassRoomRecordDto dto)
{
var res = new PageDataDto();
IQueryable query;
// 如果传了学生学号,按学号查
if (!string.IsNullOrWhiteSpace(dto.StudentNo))
{
query = from s in _sportsContext.Ai_ClassroomStudentRecord
join c in _sportsContext.Ai_ClassRoomRecord on s.ClassRoomRecordId equals c.Id
where s.StudentNo == dto.StudentNo
select new ClassRoomRecordPageDto
{
Id = c.Id,
ClassId = c.ClassId,
Name = c.Name,
StartingEndingTime = (c.StartTime.HasValue ? c.StartTime.Value.ToString("yyyy-MM-dd HH:mm") : "") +
(c.EndTime.HasValue ? " - " + c.EndTime.Value.ToString("yyyy-MM-dd HH:mm") : "")
};
}
else
{
var roleId = UserLoginContext.Current.RoleId;
if (roleId == 3 || roleId == 5) // 学生
{
var studentNo = UserLoginContext.Current.UserNo;
query = from s in _sportsContext.Ai_ClassroomStudentRecord
join c in _sportsContext.Ai_ClassRoomRecord on s.ClassRoomRecordId equals c.Id
where s.StudentNo == studentNo
select new ClassRoomRecordPageDto
{
Id = c.Id,
ClassId = c.ClassId,
Name = c.Name,
StartingEndingTime = (c.StartTime.HasValue ? c.StartTime.Value.ToString("yyyy-MM-dd HH:mm") : "") +
(c.EndTime.HasValue ? " - " + c.EndTime.Value.ToString("yyyy-MM-dd HH:mm") : "")
};
}
else // 教师
{
var phoneNo = UserLoginContext.Current.PhoneNo;
var teacherId = await _sportsContext.Teacher
.Where(x => x.TeacherPhoneNo == phoneNo)
.Select(x => x.Id)
.FirstOrDefaultAsync();
query = _sportsContext.Ai_ClassRoomRecord
.Where(x => x.TeacherId == teacherId)
.Select(c => new ClassRoomRecordPageDto
{
Id = c.Id,
ClassId = c.ClassId,
Name = c.Name,
StartingEndingTime = (c.StartTime.HasValue ? c.StartTime.Value.ToString("yyyy-MM-dd HH:mm") : "") +
(c.EndTime.HasValue ? " - " + c.EndTime.Value.ToString("yyyy-MM-dd HH:mm") : "")
});
}
}
res.Total = await query.CountAsync();
res.Datas = await query
.OrderByDescending(x => x.Id)
.Skip((dto.PageIndex - 1) * dto.PageSize)
.Take(dto.PageSize)
.AsNoTracking()
.ToListAsync();
return res;
}
///
/// 课堂详情
///
///
///
public async Task ClassRoomReportDetails(int classRoomId)
{
var res = new ClassReportDetailsDto();
var query = from hrd in _sportsContext.Ai_HeartRateData
where hrd.ClassRoomRecordId == classRoomId
select hrd;
var heartRateDataList = await query.ToListAsync();
if (heartRateDataList.Count == 0)
return res;
var classRoom = await _sportsContext.Ai_ClassRoomRecord.Include(x => x.ClassroomStudentRecord)
.Where(x => x.Id == classRoomId)
.FirstAsync();
var classRoomStudent = await _sportsContext.Ai_ClassroomStudentRecord
.Where(x => x.ClassRoomRecordId == classRoomId)
.ToListAsync();
res.MaxHR = (int)heartRateDataList.Max(x => x.Value);
res.MinHR = (int)heartRateDataList.Min(x => x.Value);
res.AvgHR = (int)heartRateDataList.Average(x => x.Value);
res.HighIntensity = heartRateDataList.Where(x => x.Strength > 50).Sum(x => x.MotionDuration);
var studentTrainingRecordList = classRoom.ClassroomStudentRecord.ToList();
List studentList = new List();
var studentIds = studentTrainingRecordList.Select(x => x.StudentNo).ToList();
var students = await _sportsContext.Student.Where(x => studentIds.Contains(x.StudentNo)).Select(x => new
{
x.StudentNo,
x.StudentName,
x.Age,
x.Sex,
x.Photo
}).ToListAsync();
foreach (var item in studentTrainingRecordList)
{
var studentTrainingData = heartRateDataList.Where(x => x.StudentNo == item.StudentNo).ToList();
var stu = students.FirstOrDefault(x => x.StudentNo == item.StudentNo);
if (studentTrainingData.Count > 0)
{
studentList.Add(new StudentTrainingRecordDto()
{
StudentNo = stu?.StudentNo,
Age = stu?.Age ?? item.Age,
Sex = stu?.Sex ?? item.Sex,
StudentName = stu?.StudentName,
Photo = stu?.Photo ?? ""
});
}
}
res.HeartRateTrend = GetHeartRateTrend(heartRateDataList);
res.StudentTrainingRecordList = studentList;
return res;
}
///
/// 学员报告
///
///
///
///
public async Task StudentClassRoomReport(int classRoomId, string studentNo)
{
var res = new StudentClassRoomReportDto();
if (string.IsNullOrWhiteSpace(studentNo))
studentNo = UserLoginContext.Current.UserNo;
var query = from hrd in _sportsContext.Ai_HeartRateData
where hrd.ClassRoomRecordId == classRoomId &&
hrd.StudentNo == studentNo
select hrd;
var heartRateDataList = await query.ToListAsync();
if (heartRateDataList.Count == 0)
return res;
var student = heartRateDataList[0];
res.MaxHR = (int)heartRateDataList.Max(x => x.Value);
res.MinHR = (int)heartRateDataList.Min(x => x.Value);
res.AvgHR = (int)heartRateDataList.Average(x => x.Value);
res.HighIntensity = heartRateDataList.Where(x => x.Strength > 50).Sum(x => x.MotionDuration);
var baseTime = await _sportsContext.Ai_HeartRateData.Where(x => x.ClassRoomRecordId == classRoomId).MinAsync(x => x.ScoreTime);
var heartRateWithMinutes = heartRateDataList
.Select(data => new
{
Data = data,
MinuteBucket = (int)(data.ScoreTime - baseTime).TotalMinutes
})
.ToList();
var maxMinute = heartRateWithMinutes.Max(x => x.MinuteBucket);
for (int minute = 0; minute <= maxMinute; minute++)
{
var minuteData = heartRateWithMinutes
.Where(x => x.MinuteBucket == minute)
.Select(x => x.Data)
.ToList();
if (minuteData.Any())
{
res.HeartRateTrend.AxisX.Add($"{minute + 1} 分钟");
res.HeartRateTrend.AxisY.Add((int)minuteData.Average(x => x.Value));
}
}
var jumpRecordList = await _sportsContext.Ai_FastJumpRopeData.Where(x => x.ClassRoomRecordId == classRoomId && x.StudentNo == studentNo).OrderByDescending(x => x.ScoreTime).Select(x => new JumpRecordListDto()
{
TotalCount = x.JumpValue ?? 0,
TotalDuration = x.MotionDuration ?? 0,
}).ToListAsync();
res.JumpRecordList = jumpRecordList;
return res;
}
///
/// 心率变化趋势
///
///
///
public ChartDataDto GetHeartRateTrend(List heartRateDataList)
{
var result = new ChartDataDto();
if (heartRateDataList == null || !heartRateDataList.Any())
return result;
var baseTime = heartRateDataList.Min(x => x.ScoreTime);
var heartRateWithMinutes = heartRateDataList
.Select(data => new
{
Data = data,
MinuteBucket = (int)(data.ScoreTime - baseTime).TotalMinutes
})
.ToList();
var maxMinute = heartRateWithMinutes.Max(x => x.MinuteBucket);
for (int minute = 0; minute <= maxMinute; minute++)
{
var minuteData = heartRateWithMinutes
.Where(x => x.MinuteBucket == minute)
.Select(x => x.Data)
.ToList();
if (minuteData.Any())
{
result.AxisX.Add($"{minute + 1} 分钟");
result.AxisY.Add((int)minuteData.Average(x => x.Value));
}
}
return result;
}
}
}