using MediatR; using Microsoft.Extensions.Logging; using CellularManagement.Domain.Common; using CellularManagement.Domain.Entities.Device; using CellularManagement.Domain.Repositories; using CellularManagement.Domain.Repositories.Device; using CellularManagement.Domain.Repositories.Base; using CellularManagement.Domain.Services; using X1.DynamicClientCore.Features; using X1.DynamicClientCore.Models; using X1.DynamicClientCore.Interfaces; namespace CellularManagement.Application.Features.Devices.Commands.CreateDevice; /// /// 创建设备命令处理器 /// public class CreateDeviceCommandHandler : IRequestHandler> { private readonly ICellularDeviceRepository _deviceRepository; private readonly ILogger _logger; private readonly IUnitOfWork _unitOfWork; private readonly ICurrentUserService _currentUserService; private readonly IBaseInstrumentClient _instrumentClient; private readonly IServiceEndpointManager _endpointManager; /// /// 初始化命令处理器 /// public CreateDeviceCommandHandler( ICellularDeviceRepository deviceRepository, ILogger logger, IUnitOfWork unitOfWork, ICurrentUserService currentUserService, IBaseInstrumentClient instrumentClient, IServiceEndpointManager endpointManager) { _deviceRepository = deviceRepository; _logger = logger; _unitOfWork = unitOfWork; _currentUserService = currentUserService; _instrumentClient = instrumentClient; _endpointManager = endpointManager; } /// /// 处理创建设备命令 /// public async Task> Handle(CreateDeviceCommand request, CancellationToken cancellationToken) { // 验证请求参数 var validationResult = ValidateRequest(request); if (!validationResult.IsSuccess) { return OperationResult.CreateFailure(validationResult.ErrorMessages); } _logger.LogInformation("开始创建设备,设备名称: {DeviceName}, IP地址: {IpAddress}", request.DeviceName, request.IpAddress); // 验证用户认证 var currentUserId = ValidateUserAuthentication(); if (!currentUserId.IsSuccess) { return OperationResult.CreateFailure(currentUserId.ErrorMessages); } // 创建服务端点 var serviceEndpoint = CreateServiceEndpoint(request); // 获取设备序列号 var serialNumberResult = await GetDeviceSerialNumberAsync(request, serviceEndpoint, cancellationToken); if (!serialNumberResult.IsSuccess) { return OperationResult.CreateFailure(serialNumberResult.ErrorMessages); } var serialNumber = serialNumberResult.Data; // 验证序列号 if (string.IsNullOrWhiteSpace(serialNumber)) { _logger.LogError("获取到的序列号为空"); return OperationResult.CreateFailure("无法获取设备序列号"); } // 检查序列号是否已存在 if (await _deviceRepository.SerialNumberExistsAsync(serialNumber, cancellationToken)) { _logger.LogWarning("设备序列号已存在: {SerialNumber}", serialNumber); return OperationResult.CreateFailure($"设备序列号 {serialNumber} 已存在"); } // 生成设备编号 var deviceCode = await GenerateDeviceCodeAsync(serialNumber, cancellationToken); // 验证设备编号 if (string.IsNullOrWhiteSpace(deviceCode)) { _logger.LogError("生成的设备编号为空"); return OperationResult.CreateFailure("生成设备编号失败"); } // 创建设备并保存 var deviceResult = await CreateAndSaveDeviceAsync(request, serialNumber, deviceCode, currentUserId.Data, cancellationToken); if (!deviceResult.IsSuccess) { return OperationResult.CreateFailure(deviceResult.ErrorMessages); } var device = deviceResult.Data; // 设备保存成功后,修改端点名称并重新添加 serviceEndpoint.Name = deviceCode; _endpointManager.AddOrUpdateEndpoint(serviceEndpoint); _logger.LogDebug("设备保存成功后,已添加服务端点: {EndpointName}", deviceCode); // 构建响应 var response = new CreateDeviceResponse { DeviceId = device.Id, DeviceName = device.Name, SerialNumber = device.SerialNumber, DeviceCode = device.DeviceCode, Description = device.Description, AgentPort = device.AgentPort, IsEnabled = device.IsEnabled, IsRunning = device.IsRunning, CreatedAt = device.CreatedAt }; _logger.LogInformation("设备创建成功,设备ID: {DeviceId}, 设备名称: {DeviceName}, 序列号: {SerialNumber}", device.Id, device.Name, device.SerialNumber); return OperationResult.CreateSuccess(response); } /// /// 验证请求参数 /// private OperationResult ValidateRequest(CreateDeviceCommand request) { if (request == null) { _logger.LogError("请求参数为空"); return OperationResult.CreateFailure("请求参数不能为空"); } if (string.IsNullOrWhiteSpace(request.DeviceName)) { _logger.LogError("设备名称为空"); return OperationResult.CreateFailure("设备名称不能为空"); } if (string.IsNullOrWhiteSpace(request.IpAddress)) { _logger.LogError("IP地址为空"); return OperationResult.CreateFailure("IP地址不能为空"); } if (request.AgentPort <= 0 || request.AgentPort > 65535) { _logger.LogError("Agent端口无效: {AgentPort}", request.AgentPort); return OperationResult.CreateFailure("Agent端口必须在1-65535之间"); } return OperationResult.CreateSuccess(true); } /// /// 验证用户认证 /// private OperationResult ValidateUserAuthentication() { var currentUserId = _currentUserService.GetCurrentUserId(); if (string.IsNullOrEmpty(currentUserId)) { _logger.LogError("无法获取当前用户ID,用户可能未认证"); return OperationResult.CreateFailure("用户未认证,无法创建设备"); } return OperationResult.CreateSuccess(currentUserId); } /// /// 获取设备序列号 /// private async Task> GetDeviceSerialNumberAsync(CreateDeviceCommand request, ServiceEndpoint serviceEndpoint, CancellationToken cancellationToken) { try { // 添加服务端点到管理器 _endpointManager.AddOrUpdateEndpoint(serviceEndpoint); _logger.LogDebug("已添加服务端点: {EndpointName}", serviceEndpoint.Name); // 获取设备序列号 var serialNumber = await _instrumentClient.GetDeviceSerialNumberAsync(serviceEndpoint.Name, null, cancellationToken); if (string.IsNullOrEmpty(serialNumber)) { _logger.LogWarning("无法通过IP地址获取设备序列号,IP地址: {IpAddress}", request.IpAddress); // 获取序列号失败时清理服务端点 _endpointManager.RemoveEndpoint(serviceEndpoint.Name); _logger.LogDebug("已清理服务端点: {EndpointName}", serviceEndpoint.Name); return OperationResult.CreateFailure($"无法通过IP地址 {request.IpAddress} 获取设备序列号,请检查设备连接状态"); } _logger.LogInformation("成功获取设备序列号: {SerialNumber}, IP地址: {IpAddress}", serialNumber, request.IpAddress); // 获取序列号成功后,移除临时服务端点 _endpointManager.RemoveEndpoint(serviceEndpoint.Name); _logger.LogDebug("已移除临时服务端点: {EndpointName}", serviceEndpoint.Name); return OperationResult.CreateSuccess(serialNumber); } catch (Exception ex) { _logger.LogError(ex, "获取设备序列号时发生异常,IP地址: {IpAddress}", request.IpAddress); // 发生异常时清理服务端点 _endpointManager.RemoveEndpoint(serviceEndpoint.Name); _logger.LogDebug("已清理服务端点: {EndpointName}", serviceEndpoint.Name); return OperationResult.CreateFailure($"获取设备序列号时发生错误: {ex.Message}"); } } /// /// 生成设备编号 /// private async Task GenerateDeviceCodeAsync(string serialNumber, CancellationToken cancellationToken) { // 获取当前设备总数 var deviceCount = await _deviceRepository.GetDeviceCountAsync(cancellationToken); var nextNumber = deviceCount + 1; // 计算需要的位数,确保至少3位数 var digitCount = CalculateRequiredDigits(nextNumber); // 格式化序号,动态补0,确保从000开始 var formattedNumber = nextNumber.ToString($"D{digitCount}"); // 生成设备编号格式:DEV-000-SN, DEV-001-SN, DEV-002-SN 等 var deviceCode = $"DEV-{formattedNumber}-{serialNumber}"; _logger.LogDebug("生成设备编号: {DeviceCode}, 设备总数: {DeviceCount}, 位数: {DigitCount}", deviceCode, deviceCount, digitCount); return deviceCode; } /// /// 计算需要的位数 /// private int CalculateRequiredDigits(int number) { if (number <= 0) return 3; // 从000开始,至少3位数 // 计算位数:确保至少3位数,从000开始 // 1-999用3位,1000-9999用4位,10000-99999用5位,以此类推 var calculatedDigits = (int)Math.Floor(Math.Log10(number)) + 1; return Math.Max(calculatedDigits, 3); // 确保至少3位数 } /// /// 创建服务端点配置 /// private ServiceEndpoint CreateServiceEndpoint(CreateDeviceCommand request) { return new ServiceEndpoint { Name = $"DEV-{Guid.NewGuid():N}", Ip = request.IpAddress, Port = request.AgentPort, Protocol = "http", BasePath= "/api/v1", Timeout = 10, Enabled = true }; } /// /// 创建设备并保存到数据库 /// private async Task> CreateAndSaveDeviceAsync( CreateDeviceCommand request, string serialNumber, string deviceCode, string currentUserId, CancellationToken cancellationToken) { try { // 创建设备实体 var device = CellularDevice.Create( name: request.DeviceName, serialNumber: serialNumber, deviceCode: deviceCode, description: request.Description, agentPort: request.AgentPort, ipAddress: request.IpAddress, createdBy: currentUserId, isEnabled: request.IsEnabled, isRunning: request.IsRunning); // 保存设备 await _deviceRepository.AddDeviceAsync(device, cancellationToken); // 保存更改到数据库 await _unitOfWork.SaveChangesAsync(cancellationToken); return OperationResult.CreateSuccess(device); } catch (Exception ex) { _logger.LogError(ex, "创建设备实体时发生错误,设备名称: {DeviceName}", request.DeviceName); return OperationResult.CreateFailure($"创建设备时发生错误: {ex.Message}"); } } }