From 82a3994d4dacccae3811171229f80a73ebbffc92 Mon Sep 17 00:00:00 2001 From: liguoyang Date: Sun, 9 Jun 2024 02:40:08 +0800 Subject: [PATCH] =?UTF-8?q?fix=20=E4=BB=BB=E5=8A=A1=E6=A0=B9=E6=8D=AE?= =?UTF-8?q?=E8=AE=BE=E5=A4=87=E5=BF=83=E8=B7=B3=E7=8A=B6=E6=80=81=E8=8E=B7?= =?UTF-8?q?=E5=8F=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Controllers/DevicesConnectController.cs | 21 ++++++++--- .../Dtos/DeviceUniqueWithConnectionInfoDto.cs | 14 ++++++++ .../Device/Response/DevicePageResponse.cs | 10 +++--- .../Device/Services/IDeviceConnectService.cs | 13 +++++-- .../Device/Services/IDeviceService.cs | 2 -- .../Implements/DeviceConnectService.cs | 35 +++++++++++++------ .../Services/Implements/DeviceService.cs | 22 ++---------- Src/Dlhis.ScheduledTask/Jobs/HeartbeatJob.cs | 32 +++++++---------- .../Services/Implements/AssignmentService.cs | 8 +++-- 9 files changed, 90 insertions(+), 67 deletions(-) create mode 100644 Src/Dlhis.Basic/Device/Dtos/DeviceUniqueWithConnectionInfoDto.cs diff --git a/Src/Dlhis.Basic/Device/Controllers/DevicesConnectController.cs b/Src/Dlhis.Basic/Device/Controllers/DevicesConnectController.cs index ba0c2773..d7526017 100644 --- a/Src/Dlhis.Basic/Device/Controllers/DevicesConnectController.cs +++ b/Src/Dlhis.Basic/Device/Controllers/DevicesConnectController.cs @@ -1,4 +1,5 @@ -using Dlhis.Basic.Device.Request; +using Dlhis.Basic.Device.Dtos; +using Dlhis.Basic.Device.Request; using Dlhis.Basic.Device.Services; using Kurisu.AspNetCore.DataAccess.SqlSugar.Aop; using Microsoft.AspNetCore.Authorization; @@ -38,9 +39,9 @@ public class DevicesConnectController : ControllerBase /// /// /// - [HttpPost("resigter")] + [HttpPost("register")] [IgnoreTenant] - public async Task ResigterAsync(DeviceResigterRequest request) + public async Task RegisterAsync(DeviceResigterRequest request) { return await _deviceConnectService.RegisterAsync(request); } @@ -50,9 +51,19 @@ public class DevicesConnectController : ControllerBase /// /// /// - [HttpPost("try-connect")] + [HttpPost("tryConnect")] public async Task TryConnectAsync(DeviceConnectionTryRequest request) { return await _deviceConnectService.TryConnectAsync(request); } -} + + /// + /// 获取在线设备 + /// + /// + [HttpGet("online-devices")] + public async Task> GetOnlineDeviceUniqueInfoAsync() + { + return await _deviceConnectService.GetOnlineDeviceUniqueInfoAsync(); + } +} \ No newline at end of file diff --git a/Src/Dlhis.Basic/Device/Dtos/DeviceUniqueWithConnectionInfoDto.cs b/Src/Dlhis.Basic/Device/Dtos/DeviceUniqueWithConnectionInfoDto.cs new file mode 100644 index 00000000..932c57a4 --- /dev/null +++ b/Src/Dlhis.Basic/Device/Dtos/DeviceUniqueWithConnectionInfoDto.cs @@ -0,0 +1,14 @@ +namespace Dlhis.Basic.Device.Dtos; + +public class DeviceUniqueWithConnectionInfoDto +{ + /// + /// 设备号 + /// + public string DeviceUnique { get; set; } + + /// + /// 连接信息 + /// + public string ConnectionInfo { get; set; } +} \ No newline at end of file diff --git a/Src/Dlhis.Basic/Device/Response/DevicePageResponse.cs b/Src/Dlhis.Basic/Device/Response/DevicePageResponse.cs index 1e6658fd..50de5f73 100644 --- a/Src/Dlhis.Basic/Device/Response/DevicePageResponse.cs +++ b/Src/Dlhis.Basic/Device/Response/DevicePageResponse.cs @@ -86,7 +86,7 @@ public class DevicePageResponse /// public bool Enable { get; set; } - + /// /// 是否作为考勤 /// @@ -109,11 +109,11 @@ public class DevicePageResponse { if (!LastHeartbeatTime.HasValue) return false; - + if (HeartbeatInterval <= 0) return true; - - return LastHeartbeatTime.Value.AddSeconds(HeartbeatInterval * 3) >= DateTime.Now; + + return LastHeartbeatTime.Value.AddSeconds(HeartbeatInterval) >= DateTime.Now; } } @@ -126,4 +126,4 @@ public class DevicePageResponse /// 营业点名称 /// public string BusinessPlaceName { get; set; } -} +} \ No newline at end of file diff --git a/Src/Dlhis.Basic/Device/Services/IDeviceConnectService.cs b/Src/Dlhis.Basic/Device/Services/IDeviceConnectService.cs index a7ef65a8..e70b94f9 100644 --- a/Src/Dlhis.Basic/Device/Services/IDeviceConnectService.cs +++ b/Src/Dlhis.Basic/Device/Services/IDeviceConnectService.cs @@ -1,4 +1,5 @@ -using Dlhis.Basic.Device.Request; +using Dlhis.Basic.Device.Dtos; +using Dlhis.Basic.Device.Request; using Dlhis.Basic.Device.Response; namespace Dlhis.Basic.Device.Services; @@ -31,7 +32,7 @@ public interface IDeviceConnectService : IScopeDependency /// /// /// - Task HeartbeatAsync(DeviceHeartbeatRequest request); + Task HeartbeatAsync(DeviceHeartbeatRequest request); /// /// 尝试连接 @@ -39,4 +40,10 @@ public interface IDeviceConnectService : IScopeDependency /// /// Task TryConnectAsync(DeviceConnectionTryRequest request); -} + + /// + /// 获取在线设备信息 + /// + /// + Task> GetOnlineDeviceUniqueInfoAsync(); +} \ No newline at end of file diff --git a/Src/Dlhis.Basic/Device/Services/IDeviceService.cs b/Src/Dlhis.Basic/Device/Services/IDeviceService.cs index abf4cf44..5592e608 100644 --- a/Src/Dlhis.Basic/Device/Services/IDeviceService.cs +++ b/Src/Dlhis.Basic/Device/Services/IDeviceService.cs @@ -12,8 +12,6 @@ public interface IDeviceService : IScopeDependency Task CheckExistsAsync(string deviceUniqueNo); - Task GetDeviceByNoAsync(DeviceByNoRequest request); - Task> GetAttendanceDevicesAsync(); Task GetDeviceNumberAsync(); diff --git a/Src/Dlhis.Basic/Device/Services/Implements/DeviceConnectService.cs b/Src/Dlhis.Basic/Device/Services/Implements/DeviceConnectService.cs index 21bab18a..a797bf00 100644 --- a/Src/Dlhis.Basic/Device/Services/Implements/DeviceConnectService.cs +++ b/Src/Dlhis.Basic/Device/Services/Implements/DeviceConnectService.cs @@ -1,5 +1,6 @@ using System.Net; using System.Net.Sockets; +using Dlhis.Basic.Device.Dtos; using Dlhis.Basic.Device.Request; using Dlhis.Basic.Device.Response; using Dlhis.Entity.Basic.Entity; @@ -9,6 +10,7 @@ using Kurisu.AspNetCore.CustomClass; using Kurisu.AspNetCore.DataAccess.SqlSugar.Services; using Kurisu.AspNetCore.Utils.Extensions; using Mapster; +using SqlSugar; namespace Dlhis.Basic.Device.Services.Implements; @@ -71,7 +73,7 @@ public class DeviceConnectService : IDeviceConnectService if (request.BusinessPlaceCode.HasValue) { var businessPlace = await _dbContext.Queryable().Where(x => x.Code == request.BusinessPlaceCode).FirstAsync(); - businessPlace.ThrowIfNull("营业点不存在,无法设置到设备注册信息中"); + businessPlace.ThrowIfNull("营业点不存在,无法设置到设备注册信息中"); } //更新营业点信息 @@ -81,13 +83,12 @@ public class DeviceConnectService : IDeviceConnectService } - public async Task HeartbeatAsync(DeviceHeartbeatRequest request) + public async Task HeartbeatAsync(DeviceHeartbeatRequest request) { - var registry = await _dbContext.Queryable().Where(x => x.DeviceUniqueNo == request.UniqueNo).FirstAsync(); - registry.ThrowIfNull($"注册信息不存在,无法发起心跳"); - - registry.LastHeartbeatTime = DateTime.Now; - await _dbContext.UpdateAsync(registry); + return await _dbContext.Updateable() + .SetColumns(x => x.LastHeartbeatTime == DateTime.Now) + .Where(x => x.DeviceUniqueNo == request.UniqueNo) + .ExecuteCommandAsync(); } @@ -110,6 +111,20 @@ public class DeviceConnectService : IDeviceConnectService } + public async Task> GetOnlineDeviceUniqueInfoAsync() + { + return await _dbContext.Queryable() + .LeftJoin((d, dr) => d.UniqueNo == dr.DeviceUniqueNo) + .Where((d, dr) => d.Enable && SqlFunc.DateAdd(dr.LastHeartbeatTime, SqlFunc.IIF(d.HeartbeatInterval == 0, 30, 30), DateType.Second) > DateTime.Now) + .Select((d, dr) => new DeviceUniqueWithConnectionInfoDto + { + DeviceUnique = d.UniqueNo, + ConnectionInfo = d.ConnectionInfo + }) + .ToListAsync(); + } + + //******************************************************** help methods ********************************************************** /// @@ -123,8 +138,8 @@ public class DeviceConnectService : IDeviceConnectService private async Task GetEnableDeviceAsync(string uniqueNo, bool checkExists = true, string deployPlace = "", string tenantId = "") { var device = await _dbContext.Queryable() - .Where(x => x.UniqueNo == uniqueNo) - .FirstAsync(); + .Where(x => x.UniqueNo == uniqueNo) + .FirstAsync(); if (checkExists) { @@ -165,4 +180,4 @@ public class DeviceConnectService : IDeviceConnectService return device; } -} +} \ No newline at end of file diff --git a/Src/Dlhis.Basic/Device/Services/Implements/DeviceService.cs b/Src/Dlhis.Basic/Device/Services/Implements/DeviceService.cs index d473c478..5d1949f8 100644 --- a/Src/Dlhis.Basic/Device/Services/Implements/DeviceService.cs +++ b/Src/Dlhis.Basic/Device/Services/Implements/DeviceService.cs @@ -274,25 +274,7 @@ public class DeviceService : IDeviceService _dbContext.Client.QueryFilter.Restore(); } } - - /// - /// 获取设备 - /// - /// - /// - public async Task GetDeviceByNoAsync(DeviceByNoRequest request) - { - var device = await _dbContext.Queryable() - .Where(x => x.UniqueNo == request.UniqueNo) - .Select(device => new DeviceResponse - { - FuncsStr = device.Funcs.ToString(), - ConnectionInfoStr = device.ConnectionInfo - }, true) - .SingleAsync(); - - return device; - } + public async Task> GetAttendanceDevicesAsync() { @@ -347,7 +329,7 @@ public class DeviceService : IDeviceService var onlineDevices = deviceRegistries.Where(x => { if (x.HeartbeatInterval <= 0) return true; - return x.LastHeartbeatTime.AddSeconds(x.HeartbeatInterval * 3) >= now; + return x.LastHeartbeatTime.AddSeconds(x.HeartbeatInterval) >= now; }) .Select(x => new { diff --git a/Src/Dlhis.ScheduledTask/Jobs/HeartbeatJob.cs b/Src/Dlhis.ScheduledTask/Jobs/HeartbeatJob.cs index 02a1a4a4..cc25cb4e 100644 --- a/Src/Dlhis.ScheduledTask/Jobs/HeartbeatJob.cs +++ b/Src/Dlhis.ScheduledTask/Jobs/HeartbeatJob.cs @@ -4,7 +4,6 @@ using Dlhis.Entity.Basic.Entity; using Dlhis.Entity.Device.Entities; using Dlhis.ScheduledTask.Attributes; using Kurisu.AspNetCore.CustomClass; -using Kurisu.AspNetCore.Utils; using Newtonsoft.Json; namespace Dlhis.ScheduledTask.Jobs; @@ -12,40 +11,33 @@ namespace Dlhis.ScheduledTask.Jobs; /// /// 设备心跳 /// -[RecurringJob(nameof(HeartbeatJob), "0/10 * * * * ?", Name = "设备心跳")] +[RecurringJob(nameof(HeartbeatJob), "0/30 * * * * ?", Name = "设备心跳")] public class HeartbeatJob : BaseJob { - private readonly RedisCache _redisCache; - - public HeartbeatJob(IServiceProvider serviceProvider, RedisCache redisCache) : base(serviceProvider) + public HeartbeatJob(IServiceProvider serviceProvider) : base(serviceProvider) { - _redisCache = redisCache; } protected override async Task RunAsync(IServiceProvider serviceProvider) { - const string key = "heartbeat-devices"; - await _redisCache.KeyDeleteAsync(key); - var devices = await DbContext.Queryable().Where(x => x.Enable).Where(x => x.HeartbeatInterval > 0).ToListAsync(); - foreach (var device in devices) + + devices.AsParallel().ForAll(device => { try { var ipInfo = JsonConvert.DeserializeObject(device.ConnectionInfo); + new TcpClient().Connect(IPAddress.Parse(ipInfo.IP), ipInfo.Port); - //超时时间 - var cancellationTokenSource = new CancellationTokenSource(300); - await new TcpClient().ConnectAsync(IPAddress.Parse(ipInfo.IP), ipInfo.Port, cancellationTokenSource.Token); - - await DbContext.Updateable().SetColumns(x => x.LastHeartbeatTime == DateTime.Now) - .Where(x => x.DeviceUniqueNo == device.UniqueNo).ExecuteCommandAsync(cancellationTokenSource.Token); - - await _redisCache.ListLeftPushAsync(key, device.UniqueNo); + DbContext.Updateable() + .SetColumns(x => x.LastHeartbeatTime == DateTime.Now) + .Where(x => x.DeviceUniqueNo == device.UniqueNo) + .ExecuteCommand(); } catch (Exception) { + //ignore } - } + }); } -} +} \ No newline at end of file diff --git a/Src/Dlhis.ScheduledTask/TaskAssignment/Services/Implements/AssignmentService.cs b/Src/Dlhis.ScheduledTask/TaskAssignment/Services/Implements/AssignmentService.cs index 150bf62a..50ba6c81 100644 --- a/Src/Dlhis.ScheduledTask/TaskAssignment/Services/Implements/AssignmentService.cs +++ b/Src/Dlhis.ScheduledTask/TaskAssignment/Services/Implements/AssignmentService.cs @@ -236,6 +236,8 @@ public class AssignmentService : IAssignmentService .LeftJoin((deviceTask, device, deviceTemplate, ga, gaLeave) => deviceTask.UserNo == gaLeave.No) .LeftJoin((deviceTask, device, deviceTemplate, ga, gaLeave, department) => department.No == ga.DepartmentNo) .LeftJoin((deviceTask, device, deviceTemplate, ga, gaLeave, department, gainfoEx) => deviceTask.UserNo == gainfoEx.No) + .LeftJoin((deviceTask, device, deviceTemplate, ga, gaLeave, department, gainfoEx, deviceRegistry) => deviceRegistry.DeviceUniqueNo == deviceTask.DeviceUniqueNo) + .Where((deviceTask, device) => device.Enable) .WhereIF(!request.IsProcess, deviceTask => deviceTask.Status == DeviceTaskStatusEnumType.Wait) .WhereIF(request.IsProcess, deviceTask => deviceTask.Status == DeviceTaskStatusEnumType.Process && SqlFunc.DateDiff(DateType.Minute, deviceTask.ModifiedTime, DateTime.Now) > 30) @@ -243,6 +245,8 @@ public class AssignmentService : IAssignmentService .WhereIF(request.Factory.IsPresent(), (deviceTask, device) => deviceTask.TenantId == request.Factory) .WhereIF(request.Types.IsPresent(), deviceTask => request.Types.Contains(deviceTask.Type)) .WhereIF(request.Brand.IsPresent(), (deviceTask, device, deviceTemplate) => deviceTemplate.Brand == request.Brand) + .Where((deviceTask, device, deviceTemplate, ga, gaLeave, department, gainfoEx, deviceRegistry) => + SqlFunc.DateAdd(deviceRegistry.LastHeartbeatTime, SqlFunc.IIF(device.HeartbeatInterval == 0, 30, 30), DateType.Second) > DateTime.Now) .OrderBy(deviceTask => new { Priority = SqlFunc.Desc(deviceTask.Priority), deviceTask.CreateTime }) .Select((deviceTask, device, deviceTemplate, ga, gaLeave, department, gainfoEx) => new TaskDto { @@ -273,14 +277,14 @@ public class AssignmentService : IAssignmentService var where = LinqExpressionExtensions.False(); taskIdVs.ForEach(p => { where = where.Or(x => x.Id == p.TaskId && x.Version == p.Version && x.Status == p.Status); }); - var effecet = await _dbContext.Updateable() + var effect = await _dbContext.Updateable() .SetColumns(x => x.Version == x.Version + 1) .SetColumns(x => x.Status == DeviceTaskStatusEnumType.Process) .SetColumns(x => x.ModifiedTime == DateTime.Now) .Where(where) .ExecuteCommandAsync(); - (taskIdVs.Count != effecet).ThrowIfTrue("获取任务失败"); + (taskIdVs.Count != effect).ThrowIfTrue("获取任务失败"); return page.Data; }, 5);