222 lines
8.0 KiB
C#
222 lines
8.0 KiB
C#
|
|
using AutoMapper;
|
|
using Microsoft.EntityFrameworkCore;
|
|
using System.Drawing;
|
|
using System.Reflection.PortableExecutable;
|
|
using YD_AllHeartRates.Api.Context;
|
|
using YD_AllHeartRates.Api.Entitys;
|
|
using YD_AllHeartRates.Api.Services.Interface;
|
|
using YD_AllHeartRates.Api.SmartSportsEntitys;
|
|
using YD_AllHeartRates.Api.Utilities;
|
|
using YD_AllHeartRates.Commons.Dto.LargeScreen;
|
|
using YD_AllHeartRates.Commons.MemoryCaches;
|
|
|
|
namespace YD_AllHeartRates.Api.Services.Impl
|
|
{
|
|
/// <summary>
|
|
/// 服务实现
|
|
/// </summary>
|
|
public class LargeScreenService : ILargeScreenService
|
|
{
|
|
public SmartSportsContext _sportsContext;
|
|
public UserContext _userContext;
|
|
private readonly LoginContext _loginContext;
|
|
private string schoolCode;
|
|
private readonly ICaching _caching;
|
|
|
|
/// <summary>
|
|
/// 构造
|
|
/// </summary>
|
|
public LargeScreenService(SmartSportsContext sportsContext, UserContext userContext, LoginContext loginContext, ICaching caching)
|
|
{
|
|
_sportsContext = sportsContext;
|
|
_userContext = userContext;
|
|
_loginContext = loginContext;
|
|
_caching = caching;
|
|
|
|
|
|
schoolCode = _loginContext.SchoolCode;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 获取学校数据
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
public async Task<SchoolDto> SchoolInfo()
|
|
{
|
|
var res = new SchoolDto();
|
|
|
|
res.SchoolCode = schoolCode;
|
|
res.Name = _loginContext.UserName;
|
|
|
|
var gIds = await _sportsContext.SchoolAssocGrade.Where(x => x.SchoolCode == schoolCode).Select(x => x.GradeId).ToListAsync();
|
|
|
|
var grades = await (
|
|
from g in _sportsContext.Grade
|
|
join c in _sportsContext.Class on g.Id equals c.GradeId into classGroup
|
|
from c in classGroup.DefaultIfEmpty()
|
|
where gIds.Contains(g.Id) && c.SchoolCode == 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;
|
|
|
|
|
|
var devices = await _sportsContext.Device.Where(x => x.SchoolCode == schoolCode).ToListAsync();
|
|
|
|
var heartRateDevices = devices.Where(x => x.DeviceType == 1).ToList();
|
|
var jumpingRopeDevices = devices.Where(x => x.DeviceType == 2).ToList();
|
|
|
|
res.HeartRateAllCount = heartRateDevices.Count();
|
|
res.JumpingRopeAllCount = jumpingRopeDevices.Count();
|
|
|
|
var tenMinutesAgo = DateTime.Now.AddMinutes(-10);
|
|
|
|
#region 心率
|
|
var heartRateData = _userContext.HeartRateData
|
|
.Where(x => x.SchoolCode == schoolCode && x.ScoreTime >= tenMinutesAgo)
|
|
.ToList();
|
|
var onlineHeartRateDeviceCodes = heartRateData
|
|
.Select(x => x.Code)
|
|
.Distinct()
|
|
.ToHashSet();
|
|
|
|
// 在线设备
|
|
var onlineHeartRateDevices = heartRateDevices
|
|
.Where(x => onlineHeartRateDeviceCodes.Contains(x.Code))
|
|
.ToList();
|
|
|
|
// 离线设备 = 所有心率设备 - 在线设备
|
|
var offlineHeartRateDevices = heartRateDevices
|
|
.Where(x => !onlineHeartRateDeviceCodes.Contains(x.Code))
|
|
.ToList();
|
|
|
|
// 设置返回值或继续处理
|
|
res.HeartRateOnlineCount = onlineHeartRateDevices.Count;
|
|
res.HeartRateOfflineCount = offlineHeartRateDevices.Count;
|
|
|
|
#endregion
|
|
|
|
#region 跳绳
|
|
|
|
var jumpRopeData = _userContext.JumpRopeData
|
|
.Where(x => x.SchoolCode == schoolCode && x.ScoreTime >= tenMinutesAgo)
|
|
.ToList();
|
|
|
|
var onlineJumpRopeDeviceCodes = jumpRopeData
|
|
.Select(x => x.Code)
|
|
.Distinct()
|
|
.ToHashSet();
|
|
|
|
// 在线设备
|
|
var onlineJumpRopeDevices = jumpingRopeDevices
|
|
.Where(x => onlineJumpRopeDeviceCodes.Contains(x.Code))
|
|
.ToList();
|
|
|
|
// 离线设备 = 所有心率设备 - 在线设备
|
|
var offlineJumpRopeDevices = jumpingRopeDevices
|
|
.Where(x => !onlineJumpRopeDeviceCodes.Contains(x.Code))
|
|
.ToList();
|
|
|
|
// 设置返回值或继续处理
|
|
res.JumpingRopeOnLineCount = onlineJumpRopeDevices.Count;
|
|
res.JumpingRopeOfflineCount = offlineJumpRopeDevices.Count;
|
|
|
|
#endregion
|
|
|
|
return res;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 心率数据
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
public async Task<HeartRateDataDto> HeartRateData(int classId)
|
|
{
|
|
var res = new HeartRateDataDto();
|
|
|
|
var now = DateTime.Now;
|
|
var tenMinutesAgo = now.AddMinutes(-10);
|
|
|
|
// 班级学生列表
|
|
var studentList = await _sportsContext.Student
|
|
.Where(x => x.ClassId == classId && x.SchoolCode == schoolCode && x.StudentStatus == 1)
|
|
.ToListAsync();
|
|
|
|
int warmUp = 0, low = 0, medium = 0, high = 0, warning = 0;
|
|
|
|
foreach (var student in studentList)
|
|
{
|
|
var heartRateKey = $"heartRate:{student.StudentNo}";
|
|
var jumpRopeKey = $"jumpRope:{student.StudentNo}";
|
|
|
|
// 先从缓存拿
|
|
var heartRate = _caching.Get<HeartRateData>(heartRateKey);
|
|
var jumpRope = _caching.Get<JumpRopeData>(jumpRopeKey);
|
|
|
|
// ❗心率缓存未命中 → 单独查数据库
|
|
if (heartRate == null)
|
|
{
|
|
heartRate = await _userContext.HeartRateData
|
|
.Where(x => x.StudentNo == student.StudentNo && x.ScoreTime >= tenMinutesAgo)
|
|
.OrderByDescending(x => x.ScoreTime)
|
|
.FirstOrDefaultAsync();
|
|
|
|
if (heartRate != null)
|
|
_caching.AddObject(heartRateKey, heartRate, 600);
|
|
}
|
|
|
|
// ❗跳绳缓存未命中 → 单独查数据库
|
|
if (jumpRope == null)
|
|
{
|
|
jumpRope = await _userContext.JumpRopeData
|
|
.Where(x => x.StudentNo == student.StudentNo && x.ScoreTime.Date == now.Date)
|
|
.OrderByDescending(x => x.ScoreTime)
|
|
.FirstOrDefaultAsync();
|
|
|
|
if (jumpRope != null)
|
|
_caching.AddObject(jumpRopeKey, jumpRope, 600);
|
|
}
|
|
|
|
// 心率强度判断
|
|
int strength = heartRate?.Strength ?? 0;
|
|
if (strength < 50) warmUp++;
|
|
else if (strength < 60) low++;
|
|
else if (strength < 70) medium++;
|
|
else if (strength < 85) high++;
|
|
else warning++;
|
|
|
|
res.StudentList.Add(new StudentDto
|
|
{
|
|
StudentName = student.StudentName,
|
|
StudentNo = student.StudentNo,
|
|
Photo = student.Photo ?? "",
|
|
Sex = student.Sex,
|
|
HeartRate = heartRate?.Value ?? 0,
|
|
JumpingRope = jumpRope?.JumpValue ?? 0,
|
|
Strength = strength
|
|
});
|
|
}
|
|
|
|
int total = studentList.Count == 0 ? 1 : studentList.Count;
|
|
res.WarmUp = (int)Math.Round(warmUp * 100.0 / total);
|
|
res.Low = (int)Math.Round(low * 100.0 / total);
|
|
res.Medium = (int)Math.Round(medium * 100.0 / total);
|
|
res.High = (int)Math.Round(high * 100.0 / total);
|
|
res.Warning = (int)Math.Round(warning * 100.0 / total);
|
|
|
|
return res;
|
|
}
|
|
|
|
}
|
|
}
|