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);