2025-06-26 17:36:12 +08:00

151 lines
5.3 KiB
C#

using AutoMapper;
using Microsoft.EntityFrameworkCore;
using System.Drawing;
using YD_AllHeartRates.Api.Context;
using YD_AllHeartRates.Api.Services.Interface;
using YD_AllHeartRates.Api.SmartSportsEntitys;
using YD_AllHeartRates.Commons.Dto;
using YD_AllHeartRates.Commons.Dto.LargeScreen;
using YD_AllHeartRates.Commons.Utils;
namespace YD_AllHeartRates.Api.Services.Impl
{
/// <summary>
/// 服务实现
/// </summary>
public class HeartRateReportService : IHeartRateReportService
{
public SmartSportsContext _sportsContext;
public UserContext _userContext;
/// <summary>
/// 构造
/// </summary>
public HeartRateReportService(SmartSportsContext sportsContext, UserContext userContext)
{
_sportsContext = sportsContext;
_userContext = userContext;
}
/// <summary>
/// 学校心率报告
/// </summary>
/// <returns></returns>
public async Task<SchoolHeartRateReportDataDto> SchoolHeartRateReport(DateTime scoreTime)
{
var schoolCode = "202501060001";
DateTime dayStart = scoreTime.Date; // 自动为 00:00:00
DateTime dayEnd = scoreTime.Date.AddDays(1).AddSeconds(-1); // 23:59:59
var res = new SchoolHeartRateReportDataDto();
var gradeList = await (
from g in _sportsContext.Grade
join a in _sportsContext.SchoolAssocGrade on g.Id equals a.GradeId
where a.SchoolCode == schoolCode
select new GradeListDto()
{
GradeId = g.Id,
GradeName = g.GradeName,
}).OrderBy(x => x.GradeId).ToListAsync();
var studentCount = await (
from s in _sportsContext.Student
join c in _sportsContext.Class
on s.ClassId equals c.Id
where s.SchoolCode == schoolCode
select new
{
s.StudentNo,
s.Sex,
c.GradeId
}).ToListAsync();
res.GradeCount = gradeList.Count;
res.MaleCount = studentCount.Where(x => x.Sex == 1).Count();
res.FemaleCount = studentCount.Where(x => x.Sex == 2).Count();
res.StartEndTime = scoreTime.ToString();
var data = await _userContext.HeartRateData.Where(x => x.SchoolCode == schoolCode && x.ScoreTime > dayStart && x.ScoreTime <= dayEnd).ToListAsync();
res.OnlineDevicesCount = data.GroupBy(x => x.StudentNo).Count();
res.AvgHeartRate = (int)data.Average(x => x.Value);
// 先筛选达标学生及对应性别
var durationsByStudent = data
.Where(x => x.Strength >= 50)
.GroupBy(x => new { x.StudentNo, x.Sex })
.ToDictionary(
g => g.Key,
g => g.Select(x => x.ScoreTime).ToList().CalculateDuration()
);
res.AvgDuration = (int)durationsByStudent.Values.DefaultIfEmpty(0).Average();
// 统计男女达标人数
int maleQualified = durationsByStudent.Count(kv => kv.Key.Sex == 1 && kv.Value >= 7200);
int femaleQualified = durationsByStudent.Count(kv => kv.Key.Sex == 2 && kv.Value >= 7200);
res.ReachCount = maleQualified + femaleQualified;
res.NotReachCount = res.StudentCount - res.ReachCount;
var hourlyAvg = data
.Where(x => x.ScoreTime.Hour >= 8 && x.ScoreTime.Hour <= 16)
.GroupBy(x => x.ScoreTime.Hour)
.OrderBy(g => g.Key)
.ToDictionary(
g => g.Key,
g => (int)Math.Round(g.Average(x => x.Value))
);
var chartData = new ChartDataDto();
for (int hour = 8; hour <= 16; hour++)
{
chartData.AxisX.Add($"{hour:00}:00");
if (hourlyAvg.TryGetValue(hour, out int avg))
chartData.AxisY.Add(avg);
else
chartData.AxisY.Add(0);
}
res.HeartRateTrend = chartData;
foreach (var item in gradeList)
{
res.GradeList.Add(new GradeListDto()
{
GradeId = item.GradeId,
GradeName = item.GradeName,
StudentCount = studentCount.Where(x => x.GradeId == item.GradeId).Count(),
MaleReachCount = maleQualified,
FemaleReachCount = femaleQualified,
ReachRate = (int)((double)res.ReachCount / res.StudentCount * 100)
});
}
return res;
}
public Task<GradeHeartRateReportDataDto> GradeHeartRateReport(int gradeId)
{
throw new NotImplementedException();
}
public Task<ClassHeartRateReportDataDto> ClassHeartRateReport(int classId)
{
throw new NotImplementedException();
}
public Task<StudentHeartRateReportDataDto> StudentHeartRateReport(string studentNo)
{
throw new NotImplementedException();
}
}
}