This commit is contained in:
tanglong 2025-10-17 17:55:29 +08:00
parent 6bd396d622
commit 5adc269011
24 changed files with 626 additions and 42 deletions

View File

@ -0,0 +1,17 @@
using YD_AllHeartRates.Commons.Dto.Mqtt;
namespace YD_AllHeartRates.Api.Mqtt.Device
{
public abstract class BleDeviceParser
{
/// <summary>
/// 设备识别标识,比如 "GTY0", "RS207"
/// </summary>
public abstract bool CanHandle(string deviceName);
/// <summary>
/// 解析并写入缓存、生成实体
/// </summary>
public abstract void Parse(DeviceDto ble, DateTime scoreTime, byte[] data);
}
}

View File

@ -0,0 +1,13 @@
using System.Text.Json.Serialization;
namespace YD_AllHeartRates.Api.Mqtt.Device
{
public class DeviceDto
{
[JsonPropertyName("bs_name")]
public string BsName { get; set; }
[JsonPropertyName("Broadcast_data")]
public string BstData { get; set; }
}
}

View File

@ -0,0 +1,33 @@
using System.Collections.Concurrent;
using YD_AllHeartRates.Api.Entitys;
using YD_AllHeartRates.Commons.Dto.Student;
using YD_AllHeartRates.Commons.MemoryCaches;
namespace YD_AllHeartRates.Api.Mqtt.Device.Parser
{
public class ParserContext
{
public ICaching Caching { get; }
public ILogger Log { get; }
public ConcurrentDictionary<string, StudentDto> StudentHMap { get; }
public ConcurrentDictionary<string, StudentDto> StudentJMap { get; }
public ConcurrentBag<HeartRateData> HeartRateEntities { get; }
public ConcurrentBag<JumpRopeData> JumpRopeEntities { get; }
public ParserContext(
ICaching caching,
ILogger log,
ConcurrentDictionary<string, StudentDto> studentHMap,
ConcurrentDictionary<string, StudentDto> studentJMap,
ConcurrentBag<HeartRateData> heartRateEntities,
ConcurrentBag<JumpRopeData> jumpRopeEntities)
{
Caching = caching;
Log = log;
StudentHMap = studentHMap;
StudentJMap = studentJMap;
HeartRateEntities = heartRateEntities;
JumpRopeEntities = jumpRopeEntities;
}
}
}

View File

@ -0,0 +1,63 @@
using System.Collections.Concurrent;
using YD_AllHeartRates.Api.Entitys;
using YD_AllHeartRates.Commons.Dto.Mqtt;
using YD_AllHeartRates.Commons.Dto.Student;
using YD_AllHeartRates.Commons.MemoryCaches;
namespace YD_AllHeartRates.Api.Mqtt.Device.Parser
{
public class QL_HeartRateDeviceParser : BleDeviceParser
{
private readonly ConcurrentBag<HeartRateData> _heartRateEntities;
private readonly ICaching _caching;
private readonly ILogger _log;
private readonly ConcurrentDictionary<string, StudentDto> _studentHMap;
public QL_HeartRateDeviceParser(
ConcurrentBag<HeartRateData> heartRateEntities,
ICaching caching,
ILogger log,
ConcurrentDictionary<string, StudentDto> studentHMap)
{
_heartRateEntities = heartRateEntities;
_caching = caching;
_log = log;
_studentHMap = studentHMap;
}
public override bool CanHandle(string deviceName) => deviceName.Contains("GTY0");
public override void Parse(DeviceDto ble, DateTime scoreTime, byte[] data)
{
if (!_studentHMap.TryGetValue(ble.BsName, out var student)) return;
int cd = Array.IndexOf(data, (byte)0xCD);
if (cd < 0 || data.Length < cd + 9) return;
int battery = data[cd + 1];
int heartRate = data[cd + 2];
if (heartRate == 0) return;
var entity = new HeartRateData
{
ScoreTime = scoreTime,
Code = ble.BsName,
GradeId = student.GradeId,
GradeName = student.GradeName,
ClassId = student.ClassId,
ClassName = student.ClassName ?? "",
SchoolCode = student.SchoolCode ?? "",
Sex = student.Sex,
Value = heartRate,
QuantityOfElectricity = battery,
StudentNo = student.StudentNo,
StudentName = student.StudentName,
Strength = (int)Math.Round(((double)heartRate / (220 - student.Age)) * 100)
};
_heartRateEntities.Add(entity);
_caching.AddObject($"heartRate:{student.StudentNo}", entity, 60);
RedisHelper.SAdd($"school:{student.SchoolCode}:students", student.StudentNo);
}
}
}

View File

@ -384,7 +384,15 @@ namespace YD_AllHeartRates.Api.Mqtt
var today = DateTime.Today;
var dateStr = today.ToString("yyyyMMdd");
var keys = RedisHelper.Keys($"jumpRope:active:*:{dateStr}");
var keys = new List<string>();
var cursor = 0L;
do
{
var scan = RedisHelper.Scan(cursor, $"jumpRope:active:*:{dateStr}", 200);
cursor = scan.Cursor;
if (scan.Items != null && scan.Items.Any())
keys.AddRange(scan.Items);
} while (cursor != 0);
using var scope = _scopeFactory.CreateScope();
var dbContext = scope.ServiceProvider.GetRequiredService<UserContext>();

View File

@ -0,0 +1,446 @@

using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.FileSystemGlobbing.Internal;
using MQTTnet;
using MQTTnet.Client;
using MQTTnet.Protocol;
using System.Collections.Concurrent;
using System.Globalization;
using System.Reflection.PortableExecutable;
using System.Runtime.CompilerServices;
using System.Text;
using System.Text.Json;
using System.Threading.Channels;
using YD_AllHeartRates.Api.Context;
using YD_AllHeartRates.Api.Entitys;
using YD_AllHeartRates.Api.SmartSportsEntitys;
using YD_AllHeartRates.Api.Utilities;
using YD_AllHeartRates.Api.WebSocket;
using YD_AllHeartRates.Commons.Dto.Mqtt;
using YD_AllHeartRates.Commons.Dto.Student;
using YD_AllHeartRates.Commons.MemoryCaches;
namespace YD_AllHeartRates.Api.Mqtt
{
/// <summary>
/// 接受写入数据
/// </summary>
public class MqttBackgroundServiceback : BackgroundService
{
private readonly IMqttClient _client;
private readonly ILogger _log;
private readonly UserContext _userContext;
private readonly SmartSportsContext _smartSportsContext;
private readonly ICaching _caching;
private readonly IServiceScopeFactory _scopeFactory;
private readonly List<HeartRateData> _pendingHeartRates = new();
private DateTime _lastHeartRateSaveTime = DateTime.Now;
private DateTime _lastJumpRopeSaveTime = DateTime.Now;
private readonly Channel<MqttMessage> _queue = Channel.CreateUnbounded<MqttMessage>();
static readonly JsonSerializerOptions _jsonOpt = new() { PropertyNameCaseInsensitive = true };
public MqttBackgroundServiceback(
IMqttClient client,
ILogger<MqttBackgroundService> log,
UserContext userContext,
SmartSportsContext smartSportsContext,
ICaching caching,
IServiceScopeFactory scopeFactory
)
{
_client = client;
_log = log;
_userContext = userContext;
_smartSportsContext = smartSportsContext;
_caching = caching;
_scopeFactory = scopeFactory;
}
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
_ = RunJumpSyncLoopAsync(stoppingToken);
await _client.ConnectAsync(new MqttClientOptionsBuilder()
.WithTcpServer(AppSettings.Mqtt.Host, AppSettings.Mqtt.Port)
.Build(), stoppingToken);
await _client.SubscribeAsync(new MqttTopicFilterBuilder()
.WithTopic(AppSettings.Mqtt.Topic)
.WithQualityOfServiceLevel(MqttQualityOfServiceLevel.AtLeastOnce)
.Build(), stoppingToken);
_client.ApplicationMessageReceivedAsync += e =>
{
var msg = new MqttMessage
{
Topic = e.ApplicationMessage.Topic,
Payload = e.ApplicationMessage.Payload == null ? string.Empty : Encoding.UTF8.GetString(e.ApplicationMessage.Payload),
ReceivedAt = DateTime.Now
};
return _queue.Writer.WriteAsync(msg, stoppingToken).AsTask();
};
await foreach (var batch in ReadBatchesAsync(stoppingToken))
{
List<StudentDto> studentList;
//List<S_Device> devices;
var studentListCacheKey = $"{AppSettings.StudentListCacheKey}_{AppSettings.SchoolCode}";
//var deviceListCacheKey = $"{AppSettings.DeviceListCacheKey}_{AppSettings.SchoolCode}";
studentList = _caching.Get<List<StudentDto>>(studentListCacheKey);
//devices = _caching.Get<List<S_Device>>(deviceListCacheKey);
if (studentList == null || studentList.Count > 0)
{
studentList = (
from s in _smartSportsContext.Student
join c in _smartSportsContext.Class on s.ClassId equals c.Id
join d in _smartSportsContext.Device on s.StudentNo equals d.StudentNo into sd
from d in sd.DefaultIfEmpty()
where s.SchoolCode == AppSettings.SchoolCode && s.StudentStatus == 1
select new StudentDto
{
SchoolCode = s.SchoolCode,
StudentNo = s.StudentNo,
StudentName = s.StudentName,
Sex = s.Sex,
Age = s.Age,
HeartRateId = d != null ? d.Code : "",
JumpRopeId = d != null ? d.Code : "",
ClassId = s.ClassId,
ClassName = s.ClassName,
GradeId = c.GradeId,
GradeName = c.GradeName ?? "",
DeviceType = d != null ? d.DeviceType : 0
}
).ToList();
//devices = _smartSportsContext.Device.Where(x => x.SchoolCode == AppSettings.SchoolCode && !string.IsNullOrWhiteSpace(x.StudentNo)).ToList();
_caching.AddObject(studentListCacheKey, studentList, 600);
//_caching.AddObject(deviceListCacheKey, devices, 600);
}
var heartRateEntities = new ConcurrentBag<HeartRateData>();
var jumpRopeEntities = new ConcurrentBag<JumpRopeData>();
//var deviceHMap = devices.Where(x => x.DeviceType == 1).ToDictionary(x => x.Code, x => x.StudentNo);
//var deviceJMap = devices.Where(x => x.DeviceType == 2).ToDictionary(x => x.Code, x => x.StudentNo);
var studentHMap = studentList.Where(x => x.DeviceType == 1).GroupBy(x => x.HeartRateId).ToDictionary(g => g.Key, g => g.First());
var studentJMap = studentList.Where(x => x.DeviceType == 2).GroupBy(x => x.JumpRopeId).ToDictionary(g => g.Key, g => g.First());
Parallel.ForEach(batch, new ParallelOptions { MaxDegreeOfParallelism = Environment.ProcessorCount }, msg =>
{
try
{
if (string.IsNullOrWhiteSpace(msg.Payload)) return;
var payload = JsonSerializer.Deserialize<BlePayload>(msg.Payload, _jsonOpt);
if (payload == null || payload.devices == null || payload.devices.Count == 0) return;
var scoreTime = DateTime.ParseExact(payload.send_time, "yyyy-MM-dd HH:mm:ss", CultureInfo.InvariantCulture);
foreach (var ble in payload.devices)
{
if (string.IsNullOrWhiteSpace(ble.Broadcast_data)) continue;
var data = ParseHexData(ble.Broadcast_data);
if (data == null) continue;
if (ble.bs_name.Contains("GTY0"))
{
//if (!deviceHMap.TryGetValue(ble.bs_name, out var studentNo)) continue;
if (!studentHMap.TryGetValue(ble.bs_name, out var student)) continue;
int cd = Array.IndexOf(data, (byte)0xCD);
if (cd < 0 || data.Length < cd + 9) continue;
int battery = data[cd + 1];
int heartRate = data[cd + 2];
if (heartRate == 0) continue;
var entity = new HeartRateData
{
ScoreTime = scoreTime,
Code = ble.bs_name,
GradeId = student.GradeId,
GradeName = student.GradeName,
ClassId = student.ClassId,
ClassName = student.ClassName ?? "",
SchoolCode = student.SchoolCode ?? "",
Sex = student.Sex,
Value = heartRate,
QuantityOfElectricity = battery,
StudentNo = student.StudentNo,
StudentName = student.StudentName,
Strength = (int)Math.Round(((double)heartRate / (220 - student.Age)) * 100)
};
heartRateEntities.Add(entity);
_caching.AddObject($"heartRate:{student.StudentNo}", entity, 60);
RedisHelper.SAdd($"school:{student.SchoolCode}:students", student.StudentNo);
}
else if (ble.bs_name.Contains("RS207"))
{
//if (!deviceJMap.TryGetValue(ble.bs_name, out var studentNo)) continue;
if (!studentJMap.TryGetValue(ble.bs_name, out var student)) continue;
int mfIndex = IndexOfSequence(data, new byte[] { 0xFF, 0x04, 0xFF, 0xCF });
if (mfIndex < 0 || data.Length < mfIndex + 10) continue;
int jumpCount = data[mfIndex + 5];
int errorCount = data[mfIndex + 7];
int battery = data[mfIndex + 10];
var jumpData = new JumpRopeData
{
ScoreTime = scoreTime,
Code = ble.bs_name,
GradeId = student.GradeId,
GradeName = student.GradeName,
ClassId = student.ClassId,
ClassName = student.ClassName ?? "",
SchoolCode = student.SchoolCode ?? "",
Sex = student.Sex,
JumpValue = jumpCount,
QuantityOfElectricity = battery,
ErrorNumber = errorCount,
StudentNo = student.StudentNo,
StudentName = student.StudentName
};
var jumpKey = $"jumpRope:active:{student.StudentNo}:{DateTime.Now:yyyyMMdd}";
var rawKey = $"jumpRope:raw:{student.StudentNo}:{DateTime.Now:yyyyMMdd}";
var totalData = _caching.Get<JumpRopeData>(jumpKey) ?? new JumpRopeData
{
Id = jumpData.Id,
StudentNo = jumpData.StudentNo,
ClassId = jumpData.ClassId,
ClassName = jumpData.ClassName,
Code = jumpData.Code,
GradeId = jumpData.GradeId,
GradeName = jumpData.GradeName,
SchoolCode = jumpData.SchoolCode,
Sex = jumpData.Sex,
StudentName = jumpData.StudentName,
JumpValue = 0,
ErrorNumber = 0,
QuantityOfElectricity = jumpData.QuantityOfElectricity,
ScoreTime = jumpData.ScoreTime
};
var lastRaw = _caching.Get<JumpRopeData>(rawKey);
int deltaJump = jumpData.JumpValue;
int deltaError = jumpData.ErrorNumber;
if (lastRaw != null)
{
deltaJump = jumpData.JumpValue >= lastRaw.JumpValue
? jumpData.JumpValue - lastRaw.JumpValue
: jumpData.JumpValue;
deltaError = jumpData.ErrorNumber >= lastRaw.ErrorNumber
? jumpData.ErrorNumber - lastRaw.ErrorNumber
: jumpData.ErrorNumber;
}
totalData.JumpValue += deltaJump;
totalData.ErrorNumber += deltaError;
totalData.QuantityOfElectricity = jumpData.QuantityOfElectricity;
totalData.ScoreTime = jumpData.ScoreTime;
_caching.AddObject(jumpKey, totalData, 600);
_caching.AddObject(rawKey, jumpData, 60);
}
}
}
catch (Exception ex)
{
_log.LogError(ex, "处理 BLE 消息异常");
}
});
// 心率每分钟保存一次
if ((DateTime.Now - _lastHeartRateSaveTime).TotalSeconds >= 60 && _pendingHeartRates.Any())
{
_userContext.HeartRateData.AddRange(_pendingHeartRates);
await _userContext.SaveChangesAsync();
_pendingHeartRates.Clear();
_lastHeartRateSaveTime = DateTime.Now;
}
_pendingHeartRates.AddRange(heartRateEntities);
// 跳绳每日更新保存
// 每隔 60 秒执行一次
//_ = Task.Run(async () =>
//{
// while (true)
// {
// await SyncTodayJumpDataToDbAsync();
// await Task.Delay(10000); // 每 10 秒检查一次
// }
//});
}
}
private async Task RunJumpSyncLoopAsync(CancellationToken token)
{
while (!token.IsCancellationRequested)
{
try
{
await SyncTodayJumpDataToDbAsync();
}
catch (Exception ex)
{
_log.LogError(ex, "跳绳数据同步异常");
}
try
{
await Task.Delay(TimeSpan.FromSeconds(10), token);
}
catch (TaskCanceledException)
{
// 如果是取消任务导致 delay 中断,直接退出
break;
}
}
_log.LogInformation("跳绳数据同步任务已退出");
}
private byte[]? ParseHexData(string hex)
{
try
{
int len = hex.Length / 2;
var bytes = new byte[len];
for (int i = 0; i < len; i++)
bytes[i] = Convert.ToByte(hex.Substring(i * 2, 2), 16);
return bytes;
}
catch
{
return null;
}
}
private async IAsyncEnumerable<List<MqttMessage>> ReadBatchesAsync(
[EnumeratorCancellation] CancellationToken ct)
{
var buffer = new List<MqttMessage>(AppSettings.Mqtt.BatchSize);
while (await _queue.Reader.WaitToReadAsync(ct))
{
while (_queue.Reader.TryRead(out var m))
{
buffer.Add(m);
if (buffer.Count == AppSettings.Mqtt.BatchSize)
{
yield return buffer;
buffer = new List<MqttMessage>(AppSettings.Mqtt.BatchSize);
}
}
}
if (buffer.Count > 0) yield return buffer;
}
public static int IndexOfSequence(byte[] buffer, byte[] pattern)
{
if (pattern.Length == 0 || buffer.Length < pattern.Length)
return -1;
for (int i = 0; i <= buffer.Length - pattern.Length; i++)
{
bool matched = true;
for (int j = 0; j < pattern.Length; j++)
{
if (buffer[i + j] != pattern[j])
{
matched = false;
break;
}
}
if (matched)
return i;
}
return -1;
}
public async Task SyncTodayJumpDataToDbAsync()
{
try
{
if ((DateTime.Now - _lastJumpRopeSaveTime).TotalSeconds < 60)
return;
var today = DateTime.Today;
var dateStr = today.ToString("yyyyMMdd");
var keys = RedisHelper.Keys($"jumpRope:active:*:{dateStr}");
using var scope = _scopeFactory.CreateScope();
var dbContext = scope.ServiceProvider.GetRequiredService<UserContext>();
foreach (var key in keys)
{
var data = _caching.Get<JumpRopeData>(key);
if (data == null || string.IsNullOrWhiteSpace(data.StudentNo)) continue;
var exist = await dbContext.JumpRopeData
.FirstOrDefaultAsync(x => x.StudentNo == data.StudentNo && x.ScoreTime.Date == today);
if (exist != null)
{
if (data.JumpValue > exist.JumpValue)
{
exist.JumpValue = data.JumpValue;
exist.ErrorNumber = data.ErrorNumber;
exist.QuantityOfElectricity = data.QuantityOfElectricity;
exist.ScoreTime = data.ScoreTime;
}
}
else
{
try
{
dbContext.JumpRopeData.Add(data);
await dbContext.SaveChangesAsync();
}
catch (DbUpdateException ex)
{
// 如果是唯一约束冲突,说明有并发插入
// 可以忽略或重试更新
var existRetry = await dbContext.JumpRopeData
.FirstOrDefaultAsync(x => x.StudentNo == data.StudentNo && x.ScoreTime.Date == today);
if (existRetry != null && data.JumpValue > existRetry.JumpValue)
{
existRetry.JumpValue = data.JumpValue;
existRetry.ErrorNumber = data.ErrorNumber;
existRetry.QuantityOfElectricity = data.QuantityOfElectricity;
existRetry.ScoreTime = data.ScoreTime;
await dbContext.SaveChangesAsync();
}
}
}
}
await dbContext.SaveChangesAsync();
_lastJumpRopeSaveTime = DateTime.Now;
}
catch (Exception ex)
{
_log.LogError(ex, "SyncTodayJumpDataToDbAsync:数据同步错误。");
}
}
}
}

View File

@ -14,7 +14,7 @@ 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+39d73477fa9f5a21da7997a3dd7c8944e0d40ed0")]
[assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0+6bd396d622f20bc5ca99fb500d0466a90a7f409c")]
[assembly: System.Reflection.AssemblyProductAttribute("YD_AllHeartRates.Api")]
[assembly: System.Reflection.AssemblyTitleAttribute("YD_AllHeartRates.Api")]
[assembly: System.Reflection.AssemblyVersionAttribute("1.0.0.0")]

View File

@ -1 +1 @@
7edb1c4b66ea7aaa8d8126de81bd88fca00f6b5a820f3c5d394050afeae97abc
a3a980977d20bb57fa1f83ee6bf5d8f1bf2b6b14f55da2f2582dca10b8411b17

View File

@ -1,5 +1,7 @@
is_global = true
build_property.TargetFramework = net6.0
build_property.TargetFrameworkIdentifier = .NETCoreApp
build_property.TargetFrameworkVersion = v6.0
build_property.TargetPlatformMinVersion =
build_property.UsingMicrosoftNETSdkWeb = true
build_property.ProjectTypeGuids =

View File

@ -1,17 +1,17 @@
// <auto-generated/>
global using global::Microsoft.AspNetCore.Builder;
global using global::Microsoft.AspNetCore.Hosting;
global using global::Microsoft.AspNetCore.Http;
global using global::Microsoft.AspNetCore.Routing;
global using global::Microsoft.Extensions.Configuration;
global using global::Microsoft.Extensions.DependencyInjection;
global using global::Microsoft.Extensions.Hosting;
global using global::Microsoft.Extensions.Logging;
global using global::System;
global using global::System.Collections.Generic;
global using global::System.IO;
global using global::System.Linq;
global using global::System.Net.Http;
global using global::System.Net.Http.Json;
global using global::System.Threading;
global using global::System.Threading.Tasks;
global using Microsoft.AspNetCore.Builder;
global using Microsoft.AspNetCore.Hosting;
global using Microsoft.AspNetCore.Http;
global using Microsoft.AspNetCore.Routing;
global using Microsoft.Extensions.Configuration;
global using Microsoft.Extensions.DependencyInjection;
global using Microsoft.Extensions.Hosting;
global using Microsoft.Extensions.Logging;
global using System;
global using System.Collections.Generic;
global using System.IO;
global using System.Linq;
global using System.Net.Http;
global using System.Net.Http.Json;
global using System.Threading;
global using System.Threading.Tasks;

View File

@ -49,7 +49,7 @@
"auditLevel": "low",
"auditMode": "direct"
},
"SdkAnalysisLevel": "9.0.200"
"SdkAnalysisLevel": "10.0.100"
},
"frameworks": {
"net6.0": {
@ -139,7 +139,7 @@
"privateAssets": "all"
}
},
"runtimeIdentifierGraphPath": "C:\\Program Files\\dotnet\\sdk\\9.0.201\\RuntimeIdentifierGraph.json"
"runtimeIdentifierGraphPath": "C:\\Program Files\\dotnet\\sdk\\10.0.100-rc.2.25502.107\\RuntimeIdentifierGraph.json"
}
}
},
@ -184,7 +184,7 @@
"auditLevel": "low",
"auditMode": "direct"
},
"SdkAnalysisLevel": "9.0.200"
"SdkAnalysisLevel": "10.0.100"
},
"frameworks": {
"net6.0": {
@ -231,7 +231,7 @@
"privateAssets": "all"
}
},
"runtimeIdentifierGraphPath": "C:\\Program Files\\dotnet\\sdk\\9.0.201\\RuntimeIdentifierGraph.json"
"runtimeIdentifierGraphPath": "C:\\Program Files\\dotnet\\sdk\\10.0.100-rc.2.25502.107\\RuntimeIdentifierGraph.json"
}
}
}

View File

@ -7,7 +7,7 @@
<NuGetPackageRoot Condition=" '$(NuGetPackageRoot)' == '' ">$(UserProfile)\.nuget\packages\</NuGetPackageRoot>
<NuGetPackageFolders Condition=" '$(NuGetPackageFolders)' == '' ">C:\Users\tangl\.nuget\packages\;C:\Program Files (x86)\Microsoft Visual Studio\Shared\NuGetPackages</NuGetPackageFolders>
<NuGetProjectStyle Condition=" '$(NuGetProjectStyle)' == '' ">PackageReference</NuGetProjectStyle>
<NuGetToolVersion Condition=" '$(NuGetToolVersion)' == '' ">6.13.2</NuGetToolVersion>
<NuGetToolVersion Condition=" '$(NuGetToolVersion)' == '' ">7.0.0</NuGetToolVersion>
</PropertyGroup>
<ItemGroup Condition=" '$(ExcludeRestorePackageImports)' != 'true' ">
<SourceRoot Include="C:\Users\tangl\.nuget\packages\" />

View File

@ -7217,7 +7217,7 @@
"auditLevel": "low",
"auditMode": "direct"
},
"SdkAnalysisLevel": "9.0.200"
"SdkAnalysisLevel": "10.0.100"
},
"frameworks": {
"net6.0": {
@ -7307,7 +7307,7 @@
"privateAssets": "all"
}
},
"runtimeIdentifierGraphPath": "C:\\Program Files\\dotnet\\sdk\\9.0.201\\RuntimeIdentifierGraph.json"
"runtimeIdentifierGraphPath": "C:\\Program Files\\dotnet\\sdk\\10.0.100-rc.2.25502.107\\RuntimeIdentifierGraph.json"
}
}
}

View File

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

View File

@ -14,7 +14,7 @@ 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+adb7a5132ba408ee1c99d16fb2ead9bed7a7ccc5")]
[assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0+6bd396d622f20bc5ca99fb500d0466a90a7f409c")]
[assembly: System.Reflection.AssemblyProductAttribute("YD_AllHeartRates.Commons")]
[assembly: System.Reflection.AssemblyTitleAttribute("YD_AllHeartRates.Commons")]
[assembly: System.Reflection.AssemblyVersionAttribute("1.0.0.0")]

View File

@ -1 +1 @@
39e19d927f4b3fa147400b1bba96cb47a1b0af113b4d9bd138d8a25b4ed27817
6ee32e37865a6a4bc603c1673def4e33a752eb3490ab8db8e6549d7513049ad8

View File

@ -1,5 +1,7 @@
is_global = true
build_property.TargetFramework = net6.0
build_property.TargetFrameworkIdentifier = .NETCoreApp
build_property.TargetFrameworkVersion = v6.0
build_property.TargetPlatformMinVersion =
build_property.UsingMicrosoftNETSdkWeb =
build_property.ProjectTypeGuids =

View File

@ -1,8 +1,8 @@
// <auto-generated/>
global using global::System;
global using global::System.Collections.Generic;
global using global::System.IO;
global using global::System.Linq;
global using global::System.Net.Http;
global using global::System.Threading;
global using global::System.Threading.Tasks;
global using System;
global using System.Collections.Generic;
global using System.IO;
global using System.Linq;
global using System.Net.Http;
global using System.Threading;
global using System.Threading.Tasks;

View File

@ -45,7 +45,7 @@
"auditLevel": "low",
"auditMode": "direct"
},
"SdkAnalysisLevel": "9.0.200"
"SdkAnalysisLevel": "10.0.100"
},
"frameworks": {
"net6.0": {
@ -92,7 +92,7 @@
"privateAssets": "all"
}
},
"runtimeIdentifierGraphPath": "C:\\Program Files\\dotnet\\sdk\\9.0.201\\RuntimeIdentifierGraph.json"
"runtimeIdentifierGraphPath": "C:\\Program Files\\dotnet\\sdk\\10.0.100-rc.2.25502.107\\RuntimeIdentifierGraph.json"
}
}
}

View File

@ -7,7 +7,7 @@
<NuGetPackageRoot Condition=" '$(NuGetPackageRoot)' == '' ">$(UserProfile)\.nuget\packages\</NuGetPackageRoot>
<NuGetPackageFolders Condition=" '$(NuGetPackageFolders)' == '' ">C:\Users\tangl\.nuget\packages\;C:\Program Files (x86)\Microsoft Visual Studio\Shared\NuGetPackages</NuGetPackageFolders>
<NuGetProjectStyle Condition=" '$(NuGetProjectStyle)' == '' ">PackageReference</NuGetProjectStyle>
<NuGetToolVersion Condition=" '$(NuGetToolVersion)' == '' ">6.13.2</NuGetToolVersion>
<NuGetToolVersion Condition=" '$(NuGetToolVersion)' == '' ">7.0.0</NuGetToolVersion>
</PropertyGroup>
<ItemGroup Condition=" '$(ExcludeRestorePackageImports)' != 'true' ">
<SourceRoot Include="C:\Users\tangl\.nuget\packages\" />

View File

@ -1007,7 +1007,7 @@
"auditLevel": "low",
"auditMode": "direct"
},
"SdkAnalysisLevel": "9.0.200"
"SdkAnalysisLevel": "10.0.100"
},
"frameworks": {
"net6.0": {
@ -1054,7 +1054,7 @@
"privateAssets": "all"
}
},
"runtimeIdentifierGraphPath": "C:\\Program Files\\dotnet\\sdk\\9.0.201\\RuntimeIdentifierGraph.json"
"runtimeIdentifierGraphPath": "C:\\Program Files\\dotnet\\sdk\\10.0.100-rc.2.25502.107\\RuntimeIdentifierGraph.json"
}
}
}

View File

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