This commit is contained in:
tanglong 2026-03-16 10:33:46 +08:00
parent 3fb2268bb0
commit 1666169397
25 changed files with 143 additions and 135 deletions

View File

@ -1,6 +0,0 @@
C:\Users\tangl\Desktop\Git\YD_AllHeartRates.Api\YD_AllHeartRates.Api\Fakes\YD_AllHeartRates.Commons.fakes : warning : 无法为 YD_AllHeartRates.Commons.Dto.ResponseMsg 生成存根: 类型没有对程序集可见的构造函数。构造函数本身或参数可能不可见。。
C:\Users\tangl\Desktop\Git\YD_AllHeartRates.Api\YD_AllHeartRates.Api\Fakes\YD_AllHeartRates.Commons.fakes : warning : 无法为 YD_AllHeartRates.Commons.MemoryCaches.MemoryCacheSetup 生成存根: 类型没有对程序集可见的构造函数。构造函数本身或参数可能不可见。。
C:\Users\tangl\Desktop\Git\YD_AllHeartRates.Api\YD_AllHeartRates.Api\Fakes\YD_AllHeartRates.Commons.fakes : warning : 无法为 YD_AllHeartRates.Commons.Middlewares.SystemExceptionApplicationBuilderExtensions 生成存根: 类型没有对程序集可见的构造函数。构造函数本身或参数可能不可见。。
C:\Users\tangl\Desktop\Git\YD_AllHeartRates.Api\YD_AllHeartRates.Api\Fakes\YD_AllHeartRates.Commons.fakes : warning : 无法为 YD_AllHeartRates.Commons.Utils.Util 生成存根: 类型没有对程序集可见的构造函数。构造函数本身或参数可能不可见。。
C:\Users\tangl\Desktop\Git\YD_AllHeartRates.Api\YD_AllHeartRates.Api\Fakes\YD_AllHeartRates.Commons.fakes : warning : 正在跳过 method System.Int32 YD_AllHeartRates.Commons.Utils.Util.GetRank(!!0 score),method System.Int32 YD_AllHeartRates.Commons.Utils.Util.GetRank(!!0 score) unstubbable: 无法同时指定类约束和 "class" 或 "struct" 约束
C:\Users\tangl\Desktop\Git\YD_AllHeartRates.Api\YD_AllHeartRates.Api\Fakes\YD_AllHeartRates.Commons.fakes : warning : 正在跳过 method System.String YD_AllHeartRates.Commons.Utils.Util.GetRankStr(!!0 score),method System.String YD_AllHeartRates.Commons.Utils.Util.GetRankStr(!!0 score) unstubbable: 无法同时指定类约束和 "class" 或 "struct" 约束

View File

@ -1,4 +1,5 @@
using Newtonsoft.Json;
using Microsoft.EntityFrameworkCore;
using Newtonsoft.Json;
using System;
using YD_AllHeartRates.Api.Context;
using YD_AllHeartRates.Api.Entitys;
@ -30,34 +31,34 @@ namespace YD_AllHeartRates.Api.Middlewares
"方欣玥",
"宫恩佑",
"郭依诺",
"黄子熙",
"计永安",
"蒋圣煊",
"李锦娴",
"李语汐",
"李梓皓",
"刘家耀",
"龙正柏瑀",
"罗昕",
"聂新淼",
"彭禹凡",
"宋皓晨",
"孙海翔",
"唐瀚宇",
"陶柔紫若",
"万欣怡",
"王心语",
"王梓皓",
"王梓煜",
"徐子琪",
"许穆晨",
"杨温馨",
"杨子墨",
"袁洛霏",
"张宸溪",
"张羽曦",
"赵昊辰",
"周舒洋"
//"黄子熙",
//"计永安",
//"蒋圣煊",
//"李锦娴",
//"李语汐",
//"李梓皓",
//"刘家耀",
//"龙正柏瑀",
//"罗昕",
//"聂新淼",
//"彭禹凡",
//"宋皓晨",
//"孙海翔",
//"唐瀚宇",
//"陶柔紫若",
//"万欣怡",
//"王心语",
//"王梓皓",
//"王梓煜",
//"徐子琪",
//"许穆晨",
//"杨温馨",
//"杨子墨",
//"袁洛霏",
//"张宸溪",
//"张羽曦",
//"赵昊辰",
//"周舒洋"
};
private static string[] ZhengDa = new string[]
@ -72,30 +73,30 @@ namespace YD_AllHeartRates.Api.Middlewares
"朱灏辰",
"王叡之",
"施梓俊",
"龚怡豪",
"张子赫",
"仇泽宇",
"陈歆蕾",
"朱旖文",
"郭笑笑",
"陈瑾萱",
"蔡乐妮",
"侯熙琰",
"龚思涵",
"朱瑾萱",
"宋依涵",
"顾渝尧",
"张赛文",
"沈美夕",
"吴佳凤",
"蒋添依",
"茅苹苹",
"李腾宇",
"林少熙",
"史梓晨",
"丁文洁",
"董利妍",
"朱紫芸"
//"龚怡豪",
//"张子赫",
//"仇泽宇",
//"陈歆蕾",
//"朱旖文",
//"郭笑笑",
//"陈瑾萱",
//"蔡乐妮",
//"侯熙琰",
//"龚思涵",
//"朱瑾萱",
//"宋依涵",
//"顾渝尧",
//"张赛文",
//"沈美夕",
//"吴佳凤",
//"蒋添依",
//"茅苹苹",
//"李腾宇",
//"林少熙",
//"史梓晨",
//"丁文洁",
//"董利妍",
//"朱紫芸"
};
private readonly List<StudentCacheInfo> _students = new();
@ -185,60 +186,69 @@ namespace YD_AllHeartRates.Api.Middlewares
{
var now = DateTime.Now;
var heartRateDatas = new List<HeartRateData>();
// 每天 8:30 ~ 18:30 每小时30分执行
if (now.Hour < 8 || now.Hour > 18 || now.Minute != 23)
return;
// 每天 8:30 ~ 18:30,每小时的第 30 分钟执行
if (now.Hour >= 8 && now.Hour <= 18 && now.Minute == 30)
var startTime = now.AddHours(-1);
var endTime = now;
Console.WriteLine($"[{now}] 开始统计心率数据 {startTime} ~ {endTime}");
try
{
var random = new Random();
// 1 查询1小时心率数据,并按分钟计算平均值
var list = await _userContext.HeartRateData
.Where(x => x.SchoolCode == AppSettings.SchoolCode && x.ScoreTime >= startTime && x.ScoreTime <= endTime)
.GroupBy(x => new
{
x.StudentNo,
Minute = new DateTime(
x.ScoreTime.Year,
x.ScoreTime.Month,
x.ScoreTime.Day,
x.ScoreTime.Hour,
x.ScoreTime.Minute,
0)
})
.Select(g => new
{
g.Key.StudentNo,
Minute = g.Key.Minute,
AvgValue = g.Average(x => x.Value),
AvgInstant = g.Average(x => x.InstantValue)
})
.ToListAsync();
// 2 按学生分组(提高查找效率)
var groups = list
.GroupBy(x => x.StudentNo)
.ToDictionary(
x => x.Key,
x => x.OrderBy(t => t.Minute).ToList()
);
var data = new List<StudentData>();
// 3 生成推送数据
for (int i = 0; i < _students.Count; i++)
{
var stu = _students[i]; // 学生完整信息(含学校/班级/姓名/EduId)
var hdsjList = new List<HeartRateRecordDto>();
var stu = _students[i];
// 从当前时间往前推 59 分钟
var recordTime = now.AddMinutes(-59);
if (!groups.TryGetValue(stu.EduId, out var stuData))
continue;
for (int j = 0; j < 60; j++)
var hdsjList = stuData.Select(x => new HeartRateRecordDto
{
var xl = random.Next(70, 111);
var jxxl = random.Next(60, 91);
hdsjList.Add(new HeartRateRecordDto
{
SJSJ = recordTime.ToString("yyyy-MM-dd HH:mm:ss"),
XL = xl,
JXXL = jxxl
});
SJSJ = x.Minute.ToString("yyyy-MM-dd HH:mm:ss"),
XL = (int)Math.Round(x.AvgValue),
JXXL = (int)Math.Round(x.AvgInstant)
}).ToList();
recordTime = recordTime.AddMinutes(1); // 间隔 1 分钟
// 保证每个学生60条数据
if (hdsjList.Count == 0)
continue;
heartRateDatas.Add(new HeartRateData()
{
SchoolCode = stu.School,
Area = "本部",
Code = stu.EduId,
GradeName = stu.Grade,
ClassName = stu.ClassName,
GradeId = 1,
ClassId = 1,
StudentName = stu.Name,
Sex = 0,
Consumption = 0,
CreateTime = now,
UploadTime = now,
Value = xl,
InstantValue = jxxl,
ScoreTime = recordTime,
MotionDuration = 0,
Strength = 0,
QuantityOfElectricity = 0,
StudentNo = stu.EduId
});
}
// SBID = 设备编号(按顺序递增)
var student = new StudentData
{
SBID = (i + 1).ToString("D2"),
@ -249,32 +259,26 @@ namespace YD_AllHeartRates.Api.Middlewares
data.Add(student);
Console.WriteLine(
$"生成数据 → {stu.School}-{stu.Grade}-{stu.ClassName}-{stu.Name} | EduId:{stu.EduId}");
$"生成数据 → {stu.School}-{stu.Grade}-{stu.ClassName}-{stu.Name} | EduId:{stu.EduId} | {hdsjList.Count}条");
}
try
// 4 推送数据
if (data.Count > 0)
{
var res = await _dataPushService.SportsRoutineReport(data);
Console.WriteLine($"[{DateTime.Now}] HeartRate job code:{res?.code} msg:{res?.msg}");
}
catch (Exception ex)
{
Console.WriteLine($"[{DateTime.Now}] HeartRate job msg:{ex.Message}");
}
try
{
await _userContext.HeartRateData.AddRangeAsync(heartRateDatas);
await _userContext.SaveChangesAsync();
Console.WriteLine($"[{DateTime.Now}] HeartRate Add:{heartRateDatas.Count}");
Console.WriteLine(
$"[{DateTime.Now}] HeartRate job code:{res?.code} msg:{res?.msg} 学生数:{data.Count}");
}
catch (Exception ex)
else
{
Console.WriteLine($"[{DateTime.Now}] HeartRate Add:{ex.Message}");
Console.WriteLine($"[{DateTime.Now}] 无心率数据需要推送");
}
}
catch (Exception ex)
{
Console.WriteLine($"[{DateTime.Now}] HeartRate job error:{ex.Message}");
}
}
public Task StopAsync(CancellationToken cancellationToken)

View File

@ -83,7 +83,7 @@ namespace YD_AllHeartRates.Api
// ③ 后台批量写库服务
services.AddHostedService<MqttBackgroundService>();
//services.AddHostedService<SportsRoutineReportJob>();
services.AddHostedService<SportsRoutineReportJob>();
services.AddSingleton<JwtHelper>();

View File

@ -14,10 +14,10 @@ using System.Reflection;
[assembly: System.Reflection.AssemblyCompanyAttribute("YD_AllHeartRates.Api")]
[assembly: System.Reflection.AssemblyConfigurationAttribute("Debug")]
[assembly: System.Reflection.AssemblyFileVersionAttribute("1.0.0.0")]
[assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0+6050a80567dfcfd8b1a4733dae47b778e8de45f0")]
[assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0+3fb2268bb010dba28589cdc7a4186a566f598d0c")]
[assembly: System.Reflection.AssemblyProductAttribute("YD_AllHeartRates.Api")]
[assembly: System.Reflection.AssemblyTitleAttribute("YD_AllHeartRates.Api")]
[assembly: System.Reflection.AssemblyVersionAttribute("1.0.0.0")]
// 由 MSBuild WriteCodeFragment 类生成。
// Generated by the MSBuild WriteCodeFragment class.

View File

@ -1 +1 @@
6f0aadcb399a9fd745412b4579ef39629db7a4eb635e1e89bcf37d38de54ae14
45bbed3a25c19fc3e72e316405f040c6cd1751d64f9cada8b42789394000df94

View File

@ -16,5 +16,5 @@ using System.Reflection;
[assembly: Microsoft.AspNetCore.Mvc.ApplicationParts.ApplicationPartAttribute("YD_AllHeartRates.Commons")]
[assembly: Microsoft.AspNetCore.Mvc.ApplicationParts.ApplicationPartAttribute("YD_AllHeartRates.Commons.1.0.0.0.Fakes")]
// 由 MSBuild WriteCodeFragment 类生成。
// Generated by the MSBuild WriteCodeFragment class.

View File

@ -31,6 +31,7 @@
},
"frameworks": {
"net6.0": {
"framework": "net6.0",
"targetAlias": "net6.0",
"projectReferences": {
"C:\\Users\\tangl\\Desktop\\Git\\YD_AllHeartRates.Api\\YD_AllHeartRates.Commons\\YD_AllHeartRates.Commons.csproj": {
@ -53,6 +54,7 @@
},
"frameworks": {
"net6.0": {
"framework": "net6.0",
"targetAlias": "net6.0",
"dependencies": {
"AutoMapper.Collection": {
@ -143,7 +145,7 @@
"privateAssets": "all"
}
},
"runtimeIdentifierGraphPath": "C:\\Program Files\\dotnet\\sdk\\10.0.200-preview.0.26103.119\\RuntimeIdentifierGraph.json"
"runtimeIdentifierGraphPath": "C:\\Program Files\\dotnet\\sdk\\10.0.200\\RuntimeIdentifierGraph.json"
}
}
},
@ -174,6 +176,7 @@
},
"frameworks": {
"net6.0": {
"framework": "net6.0",
"targetAlias": "net6.0",
"projectReferences": {}
}
@ -192,6 +195,7 @@
},
"frameworks": {
"net6.0": {
"framework": "net6.0",
"targetAlias": "net6.0",
"dependencies": {
"Aliyun.OSS.SDK.NetCore": {
@ -235,7 +239,7 @@
"privateAssets": "all"
}
},
"runtimeIdentifierGraphPath": "C:\\Program Files\\dotnet\\sdk\\10.0.200-preview.0.26103.119\\RuntimeIdentifierGraph.json"
"runtimeIdentifierGraphPath": "C:\\Program Files\\dotnet\\sdk\\10.0.200\\RuntimeIdentifierGraph.json"
}
}
}

View File

@ -7228,6 +7228,7 @@
},
"frameworks": {
"net6.0": {
"framework": "net6.0",
"targetAlias": "net6.0",
"projectReferences": {
"C:\\Users\\tangl\\Desktop\\Git\\YD_AllHeartRates.Api\\YD_AllHeartRates.Commons\\YD_AllHeartRates.Commons.csproj": {
@ -7250,6 +7251,7 @@
},
"frameworks": {
"net6.0": {
"framework": "net6.0",
"targetAlias": "net6.0",
"dependencies": {
"AutoMapper.Collection": {
@ -7340,7 +7342,7 @@
"privateAssets": "all"
}
},
"runtimeIdentifierGraphPath": "C:\\Program Files\\dotnet\\sdk\\10.0.200-preview.0.26103.119\\RuntimeIdentifierGraph.json"
"runtimeIdentifierGraphPath": "C:\\Program Files\\dotnet\\sdk\\10.0.200\\RuntimeIdentifierGraph.json"
}
}
}

View File

@ -1,6 +1,6 @@
{
"version": 2,
"dgSpecHash": "EFwpte+qrlo=",
"dgSpecHash": "TABP7rZDE8o=",
"success": true,
"projectFilePath": "C:\\Users\\tangl\\Desktop\\Git\\YD_AllHeartRates.Api\\YD_AllHeartRates.Api\\YD_AllHeartRates.Api.csproj",
"expectedPackageFiles": [

View File

@ -14,10 +14,10 @@ using System.Reflection;
[assembly: System.Reflection.AssemblyCompanyAttribute("YD_AllHeartRates.Commons")]
[assembly: System.Reflection.AssemblyConfigurationAttribute("Debug")]
[assembly: System.Reflection.AssemblyFileVersionAttribute("1.0.0.0")]
[assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0+a3011552e4a905ce05e14a8ff0c44dca1c3ceeb3")]
[assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0+3fb2268bb010dba28589cdc7a4186a566f598d0c")]
[assembly: System.Reflection.AssemblyProductAttribute("YD_AllHeartRates.Commons")]
[assembly: System.Reflection.AssemblyTitleAttribute("YD_AllHeartRates.Commons")]
[assembly: System.Reflection.AssemblyVersionAttribute("1.0.0.0")]
// 由 MSBuild WriteCodeFragment 类生成。
// Generated by the MSBuild WriteCodeFragment class.

View File

@ -1 +1 @@
9449a9877321fe5de1ea0a820503de509581ed5d7e64230fef9c2bbcf92c1a53
570bf2cb94f3c5895254f5e1e956aeef4ad74c2361b0fe7de273549fbb278f22

View File

@ -31,6 +31,7 @@
},
"frameworks": {
"net6.0": {
"framework": "net6.0",
"targetAlias": "net6.0",
"projectReferences": {}
}
@ -49,6 +50,7 @@
},
"frameworks": {
"net6.0": {
"framework": "net6.0",
"targetAlias": "net6.0",
"dependencies": {
"Aliyun.OSS.SDK.NetCore": {
@ -92,7 +94,7 @@
"privateAssets": "all"
}
},
"runtimeIdentifierGraphPath": "C:\\Program Files\\dotnet\\sdk\\10.0.200-preview.0.26103.119\\RuntimeIdentifierGraph.json"
"runtimeIdentifierGraphPath": "C:\\Program Files\\dotnet\\sdk\\10.0.200\\RuntimeIdentifierGraph.json"
}
}
}

View File

@ -993,6 +993,7 @@
},
"frameworks": {
"net6.0": {
"framework": "net6.0",
"targetAlias": "net6.0",
"projectReferences": {}
}
@ -1011,6 +1012,7 @@
},
"frameworks": {
"net6.0": {
"framework": "net6.0",
"targetAlias": "net6.0",
"dependencies": {
"Aliyun.OSS.SDK.NetCore": {
@ -1054,7 +1056,7 @@
"privateAssets": "all"
}
},
"runtimeIdentifierGraphPath": "C:\\Program Files\\dotnet\\sdk\\10.0.200-preview.0.26103.119\\RuntimeIdentifierGraph.json"
"runtimeIdentifierGraphPath": "C:\\Program Files\\dotnet\\sdk\\10.0.200\\RuntimeIdentifierGraph.json"
}
}
}

View File

@ -1,6 +1,6 @@
{
"version": 2,
"dgSpecHash": "l9MQglnqMP4=",
"dgSpecHash": "R9lcaqHMGy8=",
"success": true,
"projectFilePath": "C:\\Users\\tangl\\Desktop\\Git\\YD_AllHeartRates.Api\\YD_AllHeartRates.Commons\\YD_AllHeartRates.Commons.csproj",
"expectedPackageFiles": [