using System.Net; using System.Net.Sockets; using Dlhis.Basic.Device.Request; using Dlhis.Basic.Device.Response; using Dlhis.Entity.Basic.Entity; using Dlhis.Entity.Device.Entities; using Dlhis.Entity.Device.Enums; using Kurisu.AspNetCore.CustomClass; using Kurisu.AspNetCore.DataAccess.SqlSugar.Services; using Kurisu.AspNetCore.Utils.Extensions; using Mapster; namespace Dlhis.Basic.Device.Services.Implements; public class DeviceConnectService : IDeviceConnectService { private readonly IDbContext _dbContext; public DeviceConnectService(IDbContext dbContext) { _dbContext = dbContext; } public async Task RegisterAsync(DeviceResigterRequest request) { var businessPlace = await _dbContext.Queryable().Where(x => x.CustomCode == request.BusinessCustomCode).FirstAsync(); businessPlace.ThrowIfNull("营业点不存在"); var device = await GetEnableDeviceAsync(request.UniqueNo, false, request.DeployPlace, businessPlace.TenantId); var registry = await _dbContext.Queryable().Where(x => x.DeviceUniqueNo == request.UniqueNo).FirstAsync(); if (registry == null) { registry = new DeviceRegistryEntity { DeviceUniqueNo = request.UniqueNo, LastHeartbeatTime = DateTime.Now, RegisterTime = DateTime.Now, BusinessPlaceCode = businessPlace?.Code, TenantId = device.TenantId, CreatedBy = 1, CreateTime = DateTime.Now, ModifiedBy = 1, ModifiedTime = DateTime.Now, }; await _dbContext.InsertAsync(registry); return "设备注册成功"; } return "请勿重复注册设备"; } public async Task> GetNotSetBusinessPlaceDevicesAsync() { var devices = await _dbContext.Queryable().Where(x => x.Enable).ToListAsync(); devices = devices.Where(x => x.Type == DeviceTypeEnumType.Meal).ToList(); return devices.Adapt>(); } public async Task SetRegisterBusinessPlaceAsync(DeviceSetResigterBusinessPlaceRequest request) { var device = await GetEnableDeviceAsync(request.UniqueNo); (device.Type != DeviceTypeEnumType.Meal).ThrowIfTrue("非就餐类型设备,无法设置"); var registry = await _dbContext.Queryable().Where(x => x.DeviceUniqueNo == request.UniqueNo).FirstAsync(); registry.ThrowIfNull($"{request.UniqueNo}的设备注册信息不存在,无法设置营业点"); if (request.BusinessPlaceCode.HasValue) { var businessPlace = await _dbContext.Queryable().Where(x => x.Code == request.BusinessPlaceCode).FirstAsync(); businessPlace.ThrowIfNull("营业点不存在,无法设置到设备注册信息中"); } //更新营业点信息 registry.BusinessPlaceCode = request.BusinessPlaceCode; await _dbContext.UpdateAsync(registry); } 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); } public async Task TryConnectAsync(DeviceConnectionTryRequest request) { try { var ipInfo = request.ConnectionInfo.ToObject(); //超时时间 var cancellationTokenSource = new CancellationTokenSource(300); await new TcpClient().ConnectAsync(IPAddress.Parse(ipInfo.IP), ipInfo.Port, cancellationTokenSource.Token); return true; } catch (Exception) { return false; } } //******************************************************** help methods ********************************************************** /// /// 获取启用的设备 /// /// /// /// /// /// private async Task GetEnableDeviceAsync(string uniqueNo, bool checkExists = true, string deployPlace = "", string tenantId = "") { var device = await _dbContext.Queryable() .Where(x => x.UniqueNo == uniqueNo) .FirstAsync(); if (checkExists) { device.ThrowIfNull($"未知的设备唯一编码{uniqueNo}"); device.Enable.ThrowIfFalse("设备尚未启用"); } else { if (device == null) { var templateCode = await _dbContext.Queryable().Where(x => x.Name == "其他").Select(x => x.Code).FirstAsync(); device = new DeviceEntity { Code = Guid.NewGuid(), ConnectionInfo = "{}", TemplateCode = templateCode, UniqueNo = uniqueNo, TenantId = tenantId, Supplier = string.Empty, Funcs = new List(), Type = DeviceTypeEnumType.Meal, DeployPlace = deployPlace, HeartbeatInterval = 30, DeployDirection = null, Enable = true, AsAttendance = false, DeployPosition = string.Empty, CreatedBy = 1, CreateTime = DateTime.Now, ModifiedBy = 1, ModifiedTime = DateTime.Now, }; await _dbContext.InsertAsync(device); } } return device; } }