Browse Source

feat: 添加设备序列号获取功能,遵循DDD设计架构

- 新增DeviceInfo模型,包含IsSuccess字段用于状态判断
- 实现IDeviceService接口和DeviceService实现类
- 支持Windows和Linux系统序列号获取
- 修复ParseSerialNumber方法,支持Linux输出格式解析
- 创建GetSerialNumberCommand和GetSerialNumberCommandHandler
- 添加SystemController API控制器
- 修复CS0234编译错误,添加System.Net引用
- 更新依赖注入配置
- 完善错误处理和日志记录
feature/protocol-log-Perfect
hyh 6 days ago
parent
commit
fee41aaf7d
  1. 34
      CoreAgent.API/Controllers/SystemController.cs
  2. 13
      CoreAgent.Application/Commands/System/GetSerialNumberCommand.cs
  3. 5
      CoreAgent.Application/Handlers/CellularNetwork/StartCellularNetworkCommandHandler.cs
  4. 5
      CoreAgent.Application/Handlers/CellularNetwork/StopCellularNetworkCommandHandler.cs
  5. 5
      CoreAgent.Application/Handlers/NetworkConfig/Commands/CreateNetworkConfigurationCommandHandler.cs
  6. 5
      CoreAgent.Application/Handlers/NetworkConfig/Commands/DeleteNetworkConfigurationCommandHandler.cs
  7. 3
      CoreAgent.Application/Handlers/NetworkConfig/Commands/GetAllNetworkConfigurationsQueryHandler.cs
  8. 5
      CoreAgent.Application/Handlers/NetworkConfig/Commands/GetNetworkConfigurationByKeyQueryHandler.cs
  9. 51
      CoreAgent.Application/Handlers/System/GetSerialNumberCommandHandler.cs
  10. 21
      CoreAgent.Domain/Interfaces/System/IDeviceService.cs
  11. 22
      CoreAgent.Domain/Models/System/DeviceInfo.cs
  12. 5
      CoreAgent.Infrastructure/Extensions/ServiceCollection/CommandServiceExtensions.cs
  13. 2
      CoreAgent.Infrastructure/Services/Network/NetworkProtocolLogObserver.cs
  14. 217
      CoreAgent.Infrastructure/Services/System/DeviceService.cs
  15. 2
      CoreAgent.WebSocketTransport/Models/MessageTransferProtocolLog.cs
  16. 216
      modify.md

34
CoreAgent.API/Controllers/SystemController.cs

@ -0,0 +1,34 @@
using CoreAgent.Application.Commands.System;
using CoreAgent.Domain.Models.System;
using MediatR;
using Microsoft.AspNetCore.Mvc;
namespace CoreAgent.API.Controllers;
/// <summary>
/// 系统控制器
/// </summary>
public class SystemController : BaseApiController
{
public SystemController(IMediator mediator, ILogger<SystemController> logger)
: base(mediator, logger)
{
}
/// <summary>
/// 获取设备序列号(SN)
/// </summary>
/// <returns>设备信息</returns>
[HttpGet("serial-number")]
public async Task<IActionResult> GetSerialNumber()
{
_logger.LogInformation("收到获取设备序列号请求");
var command = new GetSerialNumberCommand();
var result = await _mediator.Send(command);
_logger.LogInformation("成功返回设备序列号: {SerialNumber}", result.Data?.SerialNumber);
return result;
}
}

13
CoreAgent.Application/Commands/System/GetSerialNumberCommand.cs

@ -0,0 +1,13 @@
using CoreAgent.Domain.Models.Common;
using CoreAgent.Domain.Models.System;
using MediatR;
namespace CoreAgent.Application.Commands.System;
/// <summary>
/// 获取设备序列号命令
/// </summary>
public class GetSerialNumberCommand : IRequest<ApiActionResult<DeviceInfo>>
{
// 命令不需要额外参数,直接获取当前设备的序列号
}

5
CoreAgent.Application/Handlers/CellularNetwork/StartCellularNetworkCommandHandler.cs

@ -4,6 +4,7 @@ using CoreAgent.Domain.Models.Common;
using CoreAgent.Domain.Models.Network;
using MediatR;
using Microsoft.Extensions.Logging;
using System.Net;
namespace CoreAgent.Application.Handlers.CellularNetwork;
@ -43,7 +44,7 @@ public class StartCellularNetworkCommandHandler : IRequestHandler<StartCellularN
return ApiActionResult<NetworkStatus>.Error(
result.ErrorMessage,
"NETWORK_START_ERROR",
System.Net.HttpStatusCode.BadRequest);
HttpStatusCode.BadRequest);
}
}
catch (Exception ex)
@ -52,7 +53,7 @@ public class StartCellularNetworkCommandHandler : IRequestHandler<StartCellularN
return ApiActionResult<NetworkStatus>.Error(
$"启动蜂窝网络失败: {ex.Message}",
"INTERNAL_ERROR",
System.Net.HttpStatusCode.InternalServerError);
HttpStatusCode.InternalServerError);
}
}
}

5
CoreAgent.Application/Handlers/CellularNetwork/StopCellularNetworkCommandHandler.cs

@ -3,6 +3,7 @@ using CoreAgent.Domain.Interfaces.Network;
using CoreAgent.Domain.Models.Common;
using MediatR;
using Microsoft.Extensions.Logging;
using System.Net;
namespace CoreAgent.Application.Handlers.CellularNetwork;
@ -42,7 +43,7 @@ public class StopCellularNetworkCommandHandler : IRequestHandler<StopCellularNet
return ApiActionResult<bool>.Error(
result.ErrorMessage,
"NETWORK_STOP_ERROR",
System.Net.HttpStatusCode.BadRequest);
HttpStatusCode.BadRequest);
}
}
catch (Exception ex)
@ -51,7 +52,7 @@ public class StopCellularNetworkCommandHandler : IRequestHandler<StopCellularNet
return ApiActionResult<bool>.Error(
$"停止蜂窝网络失败: {ex.Message}",
"INTERNAL_ERROR",
System.Net.HttpStatusCode.InternalServerError);
HttpStatusCode.InternalServerError);
}
}
}

5
CoreAgent.Application/Handlers/NetworkConfig/Commands/CreateNetworkConfigurationCommandHandler.cs

@ -1,4 +1,5 @@
using System;
using System.Net;
using System.Threading;
using System.Threading.Tasks;
using CoreAgent.Application.Commands.NetworkConfig;
@ -63,7 +64,7 @@ namespace CoreAgent.Application.Handlers.NetworkConfig.Commands
return ApiActionResult<NetworkConfiguration>.Error(
"配置键已存在",
"CONFIG_KEY_EXISTS",
System.Net.HttpStatusCode.Conflict);
HttpStatusCode.Conflict);
}
}
catch (Exception ex)
@ -72,7 +73,7 @@ namespace CoreAgent.Application.Handlers.NetworkConfig.Commands
return ApiActionResult<NetworkConfiguration>.Error(
$"创建网络配置失败: {ex.Message}",
"INTERNAL_ERROR",
System.Net.HttpStatusCode.InternalServerError);
HttpStatusCode.InternalServerError);
}
}
}

5
CoreAgent.Application/Handlers/NetworkConfig/Commands/DeleteNetworkConfigurationCommandHandler.cs

@ -1,4 +1,5 @@
using System;
using System.Net;
using System.Threading;
using System.Threading.Tasks;
using CoreAgent.Application.Commands.NetworkConfig;
@ -55,7 +56,7 @@ namespace CoreAgent.Application.Handlers.NetworkConfig.Commands
return ApiActionResult<bool>.Error(
"未找到要删除的网络配置",
"CONFIG_NOT_FOUND",
System.Net.HttpStatusCode.NotFound);
HttpStatusCode.NotFound);
}
}
catch (Exception ex)
@ -64,7 +65,7 @@ namespace CoreAgent.Application.Handlers.NetworkConfig.Commands
return ApiActionResult<bool>.Error(
$"删除网络配置失败: {ex.Message}",
"INTERNAL_ERROR",
System.Net.HttpStatusCode.InternalServerError);
HttpStatusCode.InternalServerError);
}
}
}

3
CoreAgent.Application/Handlers/NetworkConfig/Commands/GetAllNetworkConfigurationsQueryHandler.cs

@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using System.Net;
using System.Threading;
using System.Threading.Tasks;
using CoreAgent.Application.Commands.NetworkConfig;
@ -55,7 +56,7 @@ namespace CoreAgent.Application.Handlers.NetworkConfig.Commands
return ApiActionResult<List<NetworkConfiguration>>.Error(
$"获取所有网络配置失败: {ex.Message}",
"INTERNAL_ERROR",
System.Net.HttpStatusCode.InternalServerError);
HttpStatusCode.InternalServerError);
}
}
}

5
CoreAgent.Application/Handlers/NetworkConfig/Commands/GetNetworkConfigurationByKeyQueryHandler.cs

@ -1,4 +1,5 @@
using System;
using System.Net;
using System.Threading;
using System.Threading.Tasks;
using CoreAgent.Application.Commands.NetworkConfig;
@ -50,7 +51,7 @@ namespace CoreAgent.Application.Handlers.NetworkConfig.Commands
return ApiActionResult<NetworkConfiguration>.Error(
$"未找到网络配置: {request.ConfigKey}",
"CONFIG_NOT_FOUND",
System.Net.HttpStatusCode.NotFound);
HttpStatusCode.NotFound);
}
_logger.LogInformation("成功获取网络配置: {ConfigKey}", request.ConfigKey);
@ -62,7 +63,7 @@ namespace CoreAgent.Application.Handlers.NetworkConfig.Commands
return ApiActionResult<NetworkConfiguration>.Error(
$"获取网络配置失败: {ex.Message}",
"INTERNAL_ERROR",
System.Net.HttpStatusCode.InternalServerError);
HttpStatusCode.InternalServerError);
}
}
}

51
CoreAgent.Application/Handlers/System/GetSerialNumberCommandHandler.cs

@ -0,0 +1,51 @@
using CoreAgent.Application.Commands.System;
using CoreAgent.Domain.Interfaces.System;
using CoreAgent.Domain.Models.Common;
using CoreAgent.Domain.Models.System;
using MediatR;
using Microsoft.Extensions.Logging;
namespace CoreAgent.Application.Handlers.System;
/// <summary>
/// 获取设备序列号命令处理器
/// </summary>
public class GetSerialNumberCommandHandler : IRequestHandler<GetSerialNumberCommand, ApiActionResult<DeviceInfo>>
{
private readonly IDeviceService _deviceService;
private readonly ILogger<GetSerialNumberCommandHandler> _logger;
public GetSerialNumberCommandHandler(
IDeviceService deviceService,
ILogger<GetSerialNumberCommandHandler> logger)
{
_deviceService = deviceService ?? throw new ArgumentNullException(nameof(deviceService));
_logger = logger ?? throw new ArgumentNullException(nameof(logger));
}
public async Task<ApiActionResult<DeviceInfo>> Handle(GetSerialNumberCommand request, CancellationToken cancellationToken)
{
try
{
_logger.LogInformation("开始处理获取设备序列号命令");
var deviceInfo = await _deviceService.GetSerialNumberAsync();
if (deviceInfo.IsSuccess)
{
_logger.LogInformation("成功获取设备序列号: {SerialNumber}", deviceInfo.SerialNumber);
return ApiActionResult<DeviceInfo>.Ok(deviceInfo, "获取设备序列号成功");
}
else
{
_logger.LogWarning("获取设备序列号失败,返回的序列号: {SerialNumber}", deviceInfo.SerialNumber);
return ApiActionResult<DeviceInfo>.Error("获取设备序列号失败", "DEVICE_SN_NOT_FOUND");
}
}
catch (Exception ex)
{
_logger.LogError(ex, "处理获取设备序列号命令时发生异常");
return ApiActionResult<DeviceInfo>.Error("获取设备序列号失败", "DEVICE_SN_ERROR");
}
}
}

21
CoreAgent.Domain/Interfaces/System/IDeviceService.cs

@ -0,0 +1,21 @@
using CoreAgent.Domain.Models.System;
namespace CoreAgent.Domain.Interfaces.System;
/// <summary>
/// 设备服务接口
/// </summary>
public interface IDeviceService
{
/// <summary>
/// 获取设备序列号(SN)
/// </summary>
/// <returns>设备信息</returns>
Task<DeviceInfo> GetSerialNumberAsync();
/// <summary>
/// 获取设备序列号(SN)- 同步版本
/// </summary>
/// <returns>设备信息</returns>
DeviceInfo GetSerialNumber();
}

22
CoreAgent.Domain/Models/System/DeviceInfo.cs

@ -0,0 +1,22 @@
namespace CoreAgent.Domain.Models.System;
/// <summary>
/// 设备信息模型
/// </summary>
public class DeviceInfo
{
/// <summary>
/// 是否成功获取到序列号
/// </summary>
public bool IsSuccess { get; set; }
/// <summary>
/// 设备序列号(SN)
/// </summary>
public string SerialNumber { get; set; } = string.Empty;
/// <summary>
/// 获取时间
/// </summary>
public DateTime Timestamp { get; set; } = DateTime.UtcNow;
}

5
CoreAgent.Infrastructure/Extensions/ServiceCollection/CommandServiceExtensions.cs

@ -1,11 +1,13 @@
using CoreAgent.Domain.Interfaces;
using CoreAgent.Domain.Interfaces.Network;
using CoreAgent.Domain.Interfaces.System;
using CoreAgent.Domain.Interfaces.System.Command;
using CoreAgent.Infrastructure.Command.Factories;
using CoreAgent.Infrastructure.Contexts;
using CoreAgent.Infrastructure.Repositories;
using CoreAgent.Infrastructure.Services;
using CoreAgent.Infrastructure.Services.Network;
using CoreAgent.Infrastructure.Services.System;
using CoreAgent.ProtocolClient.Interfaces;
using CoreAgent.ProtocolClient.ProtocolEngineCore;
using Microsoft.Extensions.DependencyInjection;
@ -57,6 +59,9 @@ public static class CommandServiceExtensions
services.AddScoped<INetworkInterfaceManager, NetworkInterfaceManager>();
services.AddScoped<INetworkStatusMonitor, NetworkStatusMonitor>();
services.AddScoped<ICellularNetworkService, CellularNetworkService>();
// 注册系统服务
services.AddScoped<IDeviceService, DeviceService>();
return services;
}

2
CoreAgent.Infrastructure/Services/Network/NetworkProtocolLogObserver.cs

@ -50,7 +50,7 @@ namespace CoreAgent.Infrastructure.Services.Network
var webSocketLogs = logList.Select(log => new MessageTransferProtocolLog
{
Id = log.Id,
LayerType = log.LayerType.ToString(),
LayerType = (int)log.LayerType,
MessageDetailJson = log.MessageDetailJson,
CellID = log.CellID,
IMSI = log.IMSI,

217
CoreAgent.Infrastructure/Services/System/DeviceService.cs

@ -0,0 +1,217 @@
using CoreAgent.Domain.Interfaces.System;
using CoreAgent.Domain.Interfaces.System.Command;
using CoreAgent.Domain.Models.System;
using Microsoft.Extensions.Logging;
namespace CoreAgent.Infrastructure.Services.System;
/// <summary>
/// 设备服务实现
/// </summary>
public class DeviceService : IDeviceService
{
private readonly ILogger<DeviceService> _logger;
private readonly ISystemCommandExecutor _commandExecutor;
public DeviceService(
ILogger<DeviceService> logger,
ISystemCommandExecutor commandExecutor)
{
_logger = logger ?? throw new ArgumentNullException(nameof(logger));
_commandExecutor = commandExecutor ?? throw new ArgumentNullException(nameof(commandExecutor));
}
/// <summary>
/// 获取设备序列号(SN)
/// </summary>
/// <returns>设备信息</returns>
public async Task<DeviceInfo> GetSerialNumberAsync()
{
try
{
_logger.LogDebug("开始获取设备序列号");
// 根据操作系统选择不同的命令
string command = GetSerialNumberCommand();
var result = await _commandExecutor.ExecuteCommandAsync(command, new CancellationTokenSource(), 5000);
if (result.IsSuccess)
{
var serialNumber = ParseSerialNumber(result.Output);
if (serialNumber != null)
{
_logger.LogInformation("成功获取设备序列号: {SerialNumber}", serialNumber);
return new DeviceInfo
{
IsSuccess = true,
SerialNumber = serialNumber,
Timestamp = DateTime.UtcNow
};
}
else
{
_logger.LogWarning("解析设备序列号失败,输出内容: {Output}", result.Output);
return new DeviceInfo
{
IsSuccess = false,
SerialNumber = "UNKNOWN",
Timestamp = DateTime.UtcNow
};
}
}
else
{
_logger.LogError("获取设备序列号失败: {Error}", result.Error);
return new DeviceInfo
{
IsSuccess = false,
SerialNumber = "UNKNOWN",
Timestamp = DateTime.UtcNow
};
}
}
catch (Exception ex)
{
_logger.LogError(ex, "获取设备序列号时发生异常");
return new DeviceInfo
{
IsSuccess = false,
SerialNumber = "ERROR",
Timestamp = DateTime.UtcNow
};
}
}
/// <summary>
/// 获取设备序列号(SN)- 同步版本
/// </summary>
/// <returns>设备信息</returns>
public DeviceInfo GetSerialNumber()
{
try
{
_logger.LogDebug("开始获取设备序列号(同步)");
// 根据操作系统选择不同的命令
string command = GetSerialNumberCommand();
// 使用同步方式执行命令
var task = _commandExecutor.ExecuteCommandAsync(command, new CancellationTokenSource(), 5000);
task.Wait();
var result = task.Result;
if (result.IsSuccess)
{
var serialNumber = ParseSerialNumber(result.Output);
if (serialNumber != null)
{
_logger.LogInformation("成功获取设备序列号: {SerialNumber}", serialNumber);
return new DeviceInfo
{
IsSuccess = true,
SerialNumber = serialNumber,
Timestamp = DateTime.UtcNow
};
}
else
{
_logger.LogWarning("解析设备序列号失败,输出内容: {Output}", result.Output);
return new DeviceInfo
{
IsSuccess = false,
SerialNumber = "UNKNOWN",
Timestamp = DateTime.UtcNow
};
}
}
else
{
_logger.LogError("获取设备序列号失败: {Error}", result.Error);
return new DeviceInfo
{
IsSuccess = false,
SerialNumber = "UNKNOWN",
Timestamp = DateTime.UtcNow
};
}
}
catch (Exception ex)
{
_logger.LogError(ex, "获取设备序列号时发生异常");
return new DeviceInfo
{
IsSuccess = false,
SerialNumber = "ERROR",
Timestamp = DateTime.UtcNow
};
}
}
/// <summary>
/// 根据操作系统获取序列号命令
/// </summary>
/// <returns>命令字符串</returns>
private string GetSerialNumberCommand()
{
if (OperatingSystem.IsWindows())
{
// Windows系统获取序列号命令
return "wmic bios get serialnumber /value";
}
else if (OperatingSystem.IsLinux())
{
// Linux系统获取序列号命令
return "smartctl -i /dev/nvme0n1|grep Serial";
}
else
{
// 其他系统使用通用命令
return "echo UNKNOWN";
}
}
/// <summary>
/// 解析序列号输出
/// </summary>
/// <param name="output">命令输出</param>
/// <returns>解析后的序列号,失败时返回null</returns>
private string? ParseSerialNumber(string output)
{
if (string.IsNullOrWhiteSpace(output))
{
return null;
}
// 清理输出内容
var lines = output.Split(new[] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries);
foreach (var line in lines)
{
var trimmedLine = line.Trim();
if (OperatingSystem.IsWindows())
{
// Windows输出格式: SerialNumber=XXXXXXXX
if (trimmedLine.StartsWith("SerialNumber=", StringComparison.OrdinalIgnoreCase))
{
var serialNumber = trimmedLine.Substring("SerialNumber=".Length).Trim();
return string.IsNullOrWhiteSpace(serialNumber) ? null : serialNumber;
}
}
else if (OperatingSystem.IsLinux())
{
// Linux输出格式: Serial Number: xxxxxxxx
if (trimmedLine.StartsWith("Serial Number:", StringComparison.OrdinalIgnoreCase))
{
var serialNumber = trimmedLine.Substring("Serial Number:".Length).Trim();
return string.IsNullOrWhiteSpace(serialNumber) ? null : serialNumber;
}
}
}
return null;
}
}

2
CoreAgent.WebSocketTransport/Models/MessageTransferProtocolLog.cs

@ -21,7 +21,7 @@ namespace CoreAgent.WebSocketTransport.Models
/// <summary>
/// 协议层类型
/// </summary>
public string LayerType { get; set; } = string.Empty;
public int LayerType { get; set; }
/// <summary>
/// 消息详情集合(JSON格式存储)

216
modify.md

@ -2,6 +2,109 @@
## 2024年修改记录
### 创建获取SN接口 - 遵循DDD设计架构
**修改时间**: 2024年
**修改文件**:
- `CoreAgent.Domain/Models/System/DeviceInfo.cs` (新建)
- `CoreAgent.Domain/Interfaces/System/IDeviceService.cs` (新建)
- `CoreAgent.Infrastructure/Services/System/DeviceService.cs` (新建)
- `CoreAgent.Application/Commands/System/GetSerialNumberCommand.cs` (新建)
- `CoreAgent.Application/Handlers/System/GetSerialNumberCommandHandler.cs` (新建)
- `CoreAgent.API/Controllers/SystemController.cs` (新建)
- `CoreAgent.Infrastructure/Extensions/ServiceCollection/CommandServiceExtensions.cs`
**修改内容**:
1. **领域层设计**
- 创建 `DeviceInfo` 模型,包含 `SerialNumber``Timestamp` 字段
- 定义 `IDeviceService` 接口,提供获取SN的异步和同步方法
- 遵循DDD设计原则,接口定义在领域层
2. **基础设施层实现**
- 实现 `DeviceService` 类,使用 `ISystemCommandExecutor` 执行系统命令
- 支持Windows和Linux系统,自动选择对应的命令
- Windows: `wmic bios get serialnumber /value`
- Linux: `cat /sys/class/dmi/id/product_serial`
- 提供完善的错误处理和日志记录
3. **应用层设计**
- 创建 `GetSerialNumberCommand` 命令类,返回 `ApiActionResult<DeviceInfo>`
- 实现 `GetSerialNumberCommandHandler` 处理器,返回包装后的结果
- 使用MediatR模式处理命令
- 在应用层统一处理成功和错误响应
4. **API层设计**
- 创建 `SystemController` 控制器,继承 `BaseApiController`
- 提供 `GET /api/v1/system/serial-number` 接口
- 直接返回应用层的 `ApiActionResult<DeviceInfo>` 结果
- 简化控制器逻辑,错误处理在应用层完成
5. **依赖注入配置**
- 在 `CommandServiceExtensions` 中注册 `IDeviceService`
- 使用作用域生命周期管理
6. **具体实现**:
```csharp
// 领域模型
public class DeviceInfo
{
public string SerialNumber { get; set; } = string.Empty;
public DateTime Timestamp { get; set; } = DateTime.UtcNow;
}
// 领域接口
public interface IDeviceService
{
Task<DeviceInfo> GetSerialNumberAsync();
DeviceInfo GetSerialNumber();
}
// 基础设施实现
public class DeviceService : IDeviceService
{
private readonly ISystemCommandExecutor _commandExecutor;
public async Task<DeviceInfo> GetSerialNumberAsync()
{
string command = GetSerialNumberCommand();
var result = await _commandExecutor.ExecuteCommandAsync(command, new CancellationTokenSource(), 5000);
return ParseSerialNumber(result.Output);
}
}
// 应用层处理器
public async Task<ApiActionResult<DeviceInfo>> Handle(GetSerialNumberCommand request, CancellationToken cancellationToken)
{
var deviceInfo = await _deviceService.GetSerialNumberAsync();
return ApiActionResult<DeviceInfo>.Ok(deviceInfo, "获取设备序列号成功");
}
// API控制器
[HttpGet("serial-number")]
public async Task<IActionResult> GetSerialNumber()
{
var command = new GetSerialNumberCommand();
var result = await _mediator.Send(command);
return result;
}
```
7. **设计优势**:
- **DDD架构**: 严格遵循领域驱动设计的分层架构
- **依赖倒置**: 高层模块依赖抽象,不依赖具体实现
- **单一职责**: 每个类都有明确的职责
- **跨平台支持**: 自动识别操作系统并使用对应命令
- **错误处理**: 完善的异常处理和日志记录
- **可测试性**: 接口抽象便于单元测试
- **可扩展性**: 易于添加新的设备信息获取功能
**影响范围**:
- 新增系统服务模块
- 扩展API接口
- 依赖注入配置更新
- 命令处理流程扩展
### 创建MessageTransferProtocolLog模型解决命名冲突
**修改时间**: 2024年
@ -746,4 +849,115 @@
- 依赖注入容器的服务解析
- 应用程序启动时的服务注册
- 中间件的实例化策略
- 性能和内存使用优化
- 性能和内存使用优化
### DeviceInfo模型添加IsSuccess字段和ParseSerialNumber方法优化
**修改时间**: 2024年
**修改文件**:
- `CoreAgent.Domain/Models/System/DeviceInfo.cs`
- `CoreAgent.Infrastructure/Services/System/DeviceService.cs`
- `CoreAgent.Application/Handlers/System/GetSerialNumberCommandHandler.cs`
**修改内容**:
1. **DeviceInfo模型添加IsSuccess字段**
- 添加 `bool IsSuccess { get; set; }` 属性
- 用于标识是否成功获取到序列号
- 提供更准确的成功/失败状态判断
2. **ParseSerialNumber方法优化**
- 返回类型从 `string` 改为 `string?`(可空字符串)
- 失败时返回 `null` 而不是固定字符串
- 修复Linux系统输出格式解析:`Serial Number: xxxxxxxx`
- 添加更详细的注释说明返回值含义
3. **DeviceService方法更新**
- 修改异步和同步方法中的DeviceInfo创建逻辑
- 根据ParseSerialNumber返回值设置IsSuccess字段
- 成功时设置 `IsSuccess = true`
- 失败时设置 `IsSuccess = false`
- 添加更详细的日志记录
4. **GetSerialNumberCommandHandler优化**
- 在Handle方法中检查 `deviceInfo.IsSuccess` 字段
- 成功时返回 `ApiActionResult<DeviceInfo>.Ok()`
- 失败时返回 `ApiActionResult<DeviceInfo>.Error()` 并设置错误代码 `DEVICE_SN_NOT_FOUND`
- 提供更准确的错误信息
5. **具体实现**:
```csharp
// DeviceInfo模型
public class DeviceInfo
{
public bool IsSuccess { get; set; }
public string SerialNumber { get; set; } = string.Empty;
public DateTime Timestamp { get; set; } = DateTime.UtcNow;
}
// ParseSerialNumber方法
private string? ParseSerialNumber(string output)
{
if (string.IsNullOrWhiteSpace(output))
return null;
foreach (var line in lines)
{
if (OperatingSystem.IsLinux())
{
// Linux输出格式: Serial Number: xxxxxxxx
if (trimmedLine.StartsWith("Serial Number:", StringComparison.OrdinalIgnoreCase))
{
var serialNumber = trimmedLine.Substring("Serial Number:".Length).Trim();
return string.IsNullOrWhiteSpace(serialNumber) ? null : serialNumber;
}
}
}
return null;
}
// DeviceService中的使用
if (serialNumber != null)
{
return new DeviceInfo
{
IsSuccess = true,
SerialNumber = serialNumber,
Timestamp = DateTime.UtcNow
};
}
else
{
return new DeviceInfo
{
IsSuccess = false,
SerialNumber = "UNKNOWN",
Timestamp = DateTime.UtcNow
};
}
// GetSerialNumberCommandHandler中的使用
if (deviceInfo.IsSuccess)
{
return ApiActionResult<DeviceInfo>.Ok(deviceInfo, "获取设备序列号成功");
}
else
{
return ApiActionResult<DeviceInfo>.Error("获取设备序列号失败", "DEVICE_SN_NOT_FOUND");
}
```
6. **设计优势**:
- **准确的状态判断**:通过IsSuccess字段明确标识操作结果
- **更好的错误处理**:区分不同类型的失败情况
- **Linux兼容性**:正确解析Linux系统的序列号输出格式
- **空值安全**:使用可空字符串避免固定错误字符串
- **详细日志**:提供更丰富的日志信息便于调试
- **API一致性**:返回统一的ApiActionResult格式
**影响范围**:
- 设备序列号获取的准确性
- API响应的错误处理
- Linux系统兼容性
- 日志记录的详细程度
- 客户端错误处理逻辑
Loading…
Cancel
Save