From 6f493e78eb8a9cbf19ab040af69058c706b8d35c Mon Sep 17 00:00:00 2001 From: root <295172551@qq.com> Date: Sun, 27 Jul 2025 21:46:19 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E5=AE=9E=E7=8E=B0=E5=AE=8C=E6=95=B4?= =?UTF-8?q?=E7=9A=84=E7=BD=91=E7=BB=9C=E9=85=8D=E7=BD=AE=E7=AE=A1=E7=90=86?= =?UTF-8?q?=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 重构 NetworkConfigs 为 CoreNetworkConfigs,避免命名冲突 - 新增 IMSConfiguration Features 实现 - 新增 NetworkStackConfigs Features 实现 - 新增 StackCoreIMSBindings Features 实现 - 新增 RANConfiguration Features 实现 - 创建对应的控制器:CoreNetworkConfigsController, IMSConfigurationController, NetworkStackConfigsController, StackCoreIMSBindingsController, RANConfigurationController - 更新数据库上下文和依赖注入配置 - 添加完整的仓储接口和实现 - 添加 EF Core 配置类 - 修复 Devices Features 中的命名问题 --- .../CreateCoreNetworkConfigCommand.cs | 35 + .../CreateCoreNetworkConfigCommandHandler.cs | 95 +++ .../CreateCoreNetworkConfigResponse.cs | 37 ++ .../DeleteCoreNetworkConfigCommand.cs | 17 + .../DeleteCoreNetworkConfigCommandHandler.cs | 64 ++ .../UpdateCoreNetworkConfigCommand.cs | 41 ++ .../UpdateCoreNetworkConfigCommandHandler.cs | 102 +++ .../UpdateCoreNetworkConfigResponse.cs | 37 ++ .../GetCoreNetworkConfigByIdQuery.cs | 17 + .../GetCoreNetworkConfigByIdQueryHandler.cs | 68 ++ .../GetCoreNetworkConfigByIdResponse.cs} | 28 +- .../GetCoreNetworkConfigsQuery.cs | 34 + .../GetCoreNetworkConfigsQueryHandler.cs | 78 +++ .../GetCoreNetworkConfigsResponse.cs} | 80 +-- .../CreateDevice/CreateDeviceCommand.cs | 6 +- .../CreateDeviceCommandHandler.cs | 10 +- .../CreateDevice/CreateDeviceResponse.cs | 5 +- .../UpdateDevice/UpdateDeviceCommand.cs | 6 +- .../UpdateDeviceCommandHandler.cs | 10 +- .../UpdateDevice/UpdateDeviceResponse.cs | 5 +- .../GetDeviceByIdQueryHandler.cs | 9 +- .../GetDeviceById/GetDeviceByIdResponse.cs | 5 +- .../GetDevices/GetDevicesQueryHandler.cs | 7 +- .../CreateIMS_ConfigurationCommand.cs | 35 + .../CreateIMS_ConfigurationCommandHandler.cs | 95 +++ .../CreateIMS_ConfigurationResponse.cs | 37 ++ .../DeleteIMS_ConfigurationCommand.cs | 17 + .../DeleteIMS_ConfigurationCommandHandler.cs | 64 ++ .../UpdateIMS_ConfigurationCommand.cs} | 28 +- .../UpdateIMS_ConfigurationCommandHandler.cs | 102 +++ .../UpdateIMS_ConfigurationResponse.cs | 37 ++ .../GetIMS_ConfigurationByIdQuery.cs | 17 + .../GetIMS_ConfigurationByIdQueryHandler.cs | 68 ++ .../GetIMS_ConfigurationByIdResponse.cs | 52 ++ .../GetIMS_ConfigurationsQuery.cs | 34 + .../GetIMS_ConfigurationsQueryHandler.cs | 78 +++ .../GetIMS_ConfigurationsResponse.cs | 83 +++ .../CreateNetworkConfigCommandHandler.cs | 85 --- .../CreateNetworkConfigResponse.cs | 22 - .../DeleteNetworkConfigCommand.cs | 17 - .../DeleteNetworkConfigCommandHandler.cs | 50 -- .../UpdateNetworkConfigCommandHandler.cs | 91 --- .../UpdateNetworkConfigResponse.cs | 22 - .../GetNetworkConfigByIdQuery.cs | 17 - .../GetNetworkConfigByIdQueryHandler.cs | 63 -- .../GetNetworkConfigsQuery.cs | 46 -- .../GetNetworkConfigsQueryHandler.cs | 106 --- .../CreateNetworkStackConfigCommand.cs | 35 + .../CreateNetworkStackConfigCommandHandler.cs | 95 +++ .../CreateNetworkStackConfigResponse.cs | 37 ++ .../DeleteNetworkStackConfigCommand.cs | 17 + .../DeleteNetworkStackConfigCommandHandler.cs | 64 ++ .../UpdateNetworkStackConfigCommand.cs | 34 + .../UpdateNetworkStackConfigCommandHandler.cs | 93 +++ .../UpdateNetworkStackConfigResponse.cs | 37 ++ .../GetNetworkStackConfigByIdQuery.cs | 17 + .../GetNetworkStackConfigByIdQueryHandler.cs | 68 ++ .../GetNetworkStackConfigByIdResponse.cs | 52 ++ .../GetNetworkStackConfigsQuery.cs | 40 ++ .../GetNetworkStackConfigsQueryHandler.cs | 96 +++ .../GetNetworkStackConfigsResponse.cs | 93 +++ .../CreateProtocolVersionCommand.cs | 7 + .../CreateProtocolVersionCommandHandler.cs | 2 + .../CreateProtocolVersionResponse.cs | 5 + .../UpdateProtocolVersionCommand.cs | 7 + .../UpdateProtocolVersionCommandHandler.cs | 2 + .../UpdateProtocolVersionResponse.cs | 5 + .../GetProtocolVersionByIdQueryHandler.cs | 1 + .../GetProtocolVersionByIdResponse.cs | 5 + .../GetProtocolVersionsQueryHandler.cs | 1 + .../CreateRAN_ConfigurationCommand.cs | 35 + .../CreateRAN_ConfigurationCommandHandler.cs | 95 +++ .../CreateRAN_ConfigurationResponse.cs | 37 ++ .../DeleteRAN_ConfigurationCommand.cs | 17 + .../DeleteRAN_ConfigurationCommandHandler.cs | 63 ++ .../UpdateRAN_ConfigurationCommand.cs} | 27 +- .../UpdateRAN_ConfigurationCommandHandler.cs | 107 ++++ .../UpdateRAN_ConfigurationResponse.cs | 37 ++ .../GetRAN_ConfigurationByIdQuery.cs | 17 + .../GetRAN_ConfigurationByIdQueryHandler.cs | 65 ++ .../GetRAN_ConfigurationByIdResponse.cs | 42 ++ .../GetRAN_ConfigurationsQuery.cs | 34 + .../GetRAN_ConfigurationsQueryHandler.cs | 100 +++ .../GetRAN_ConfigurationsResponse.cs | 46 ++ .../CreateStackCoreIMSBindingCommand.cs | 39 ++ ...CreateStackCoreIMSBindingCommandHandler.cs | 95 +++ .../CreateStackCoreIMSBindingResponse.cs | 37 ++ .../DeleteStackCoreIMSBindingCommand.cs | 17 + ...DeleteStackCoreIMSBindingCommandHandler.cs | 64 ++ .../UpdateStackCoreIMSBindingCommand.cs | 38 ++ ...UpdateStackCoreIMSBindingCommandHandler.cs | 103 +++ .../UpdateStackCoreIMSBindingResponse.cs | 37 ++ .../GetStackCoreIMSBindingByIdQuery.cs | 17 + .../GetStackCoreIMSBindingByIdQueryHandler.cs | 68 ++ .../GetStackCoreIMSBindingByIdResponse.cs | 52 ++ .../GetStackCoreIMSBindingsQuery.cs | 41 ++ .../GetStackCoreIMSBindingsQueryHandler.cs | 80 +++ .../GetStackCoreIMSBindingsResponse.cs | 83 +++ .../Entities/Device/CellularDevice.cs | 15 +- .../Entities/Device/NetworkConfig.cs | 173 ----- .../Entities/Device/ProtocolVersion.cs | 11 + .../NetworkProfile/CoreNetworkConfig.cs | 98 +++ .../NetworkProfile/IMS_Configuration.cs | 98 +++ .../NetworkProfile/NetworkStackConfig.cs | 101 +++ .../NetworkProfile/RAN_Configuration.cs | 98 +++ .../NetworkProfile/Stack_CoreIMS_Binding.cs | 96 +++ .../Device/ICellularDeviceRepository.cs | 4 +- .../Device/INetworkConfigRepository.cs | 78 --- .../ICoreNetworkConfigRepository.cs | 66 ++ .../IIMS_ConfigurationRepository.cs | 66 ++ .../INetworkStackConfigRepository.cs | 76 +++ .../IRAN_ConfigurationRepository.cs | 66 ++ .../IStack_CoreIMS_BindingRepository.cs | 85 +++ .../Specifications/NetworkConfigSamples.json | 226 ------- .../Specifications/NetworkConfig_README.md | 191 ------ .../Specifications/NetworkConfig_Test.http | 90 --- .../Device/CellularDeviceConfiguration.cs | 15 +- .../Device/NetworkConfigConfiguration.cs | 88 --- .../Device/ProtocolVersionConfiguration.cs | 4 +- .../CoreNetworkConfigConfiguration.cs | 26 + .../IMS_ConfigurationConfiguration.cs | 26 + .../NetworkStackConfigConfiguration.cs | 42 ++ .../RAN_ConfigurationConfiguration.cs | 27 + .../Stack_CoreIMS_BindingConfiguration.cs | 47 ++ src/X1.Infrastructure/Context/AppDbContext.cs | 27 +- src/X1.Infrastructure/DependencyInjection.cs | 8 +- .../Device/CellularDeviceRepository.cs | 9 +- .../Device/NetworkConfigRepository.cs | 168 ----- .../CoreNetworkConfigRepository.cs | 138 ++++ .../IMS_ConfigurationRepository.cs | 138 ++++ .../NetworkStackConfigRepository.cs | 156 +++++ .../RAN_ConfigurationRepository.cs | 138 ++++ .../Stack_CoreIMS_BindingRepository.cs | 188 ++++++ .../CoreNetworkConfigsController.cs | 135 ++++ .../Controllers/IMSConfigurationController.cs | 135 ++++ .../Controllers/NetworkConfigsController.cs | 289 --------- .../NetworkStackConfigsController.cs | 135 ++++ .../Controllers/RANConfigurationController.cs | 135 ++++ .../StackCoreIMSBindingsController.cs | 136 ++++ src/X1.WebAPI/logs/app-20250727.log | 604 ++++++++++++++++++ src/X1.WebAPI/logs/error-20250727.log | 20 + 141 files changed, 6838 insertions(+), 2002 deletions(-) create mode 100644 src/X1.Application/Features/CoreNetworkConfigs/Commands/CreateCoreNetworkConfig/CreateCoreNetworkConfigCommand.cs create mode 100644 src/X1.Application/Features/CoreNetworkConfigs/Commands/CreateCoreNetworkConfig/CreateCoreNetworkConfigCommandHandler.cs create mode 100644 src/X1.Application/Features/CoreNetworkConfigs/Commands/CreateCoreNetworkConfig/CreateCoreNetworkConfigResponse.cs create mode 100644 src/X1.Application/Features/CoreNetworkConfigs/Commands/DeleteCoreNetworkConfig/DeleteCoreNetworkConfigCommand.cs create mode 100644 src/X1.Application/Features/CoreNetworkConfigs/Commands/DeleteCoreNetworkConfig/DeleteCoreNetworkConfigCommandHandler.cs create mode 100644 src/X1.Application/Features/CoreNetworkConfigs/Commands/UpdateCoreNetworkConfig/UpdateCoreNetworkConfigCommand.cs create mode 100644 src/X1.Application/Features/CoreNetworkConfigs/Commands/UpdateCoreNetworkConfig/UpdateCoreNetworkConfigCommandHandler.cs create mode 100644 src/X1.Application/Features/CoreNetworkConfigs/Commands/UpdateCoreNetworkConfig/UpdateCoreNetworkConfigResponse.cs create mode 100644 src/X1.Application/Features/CoreNetworkConfigs/Queries/GetCoreNetworkConfigById/GetCoreNetworkConfigByIdQuery.cs create mode 100644 src/X1.Application/Features/CoreNetworkConfigs/Queries/GetCoreNetworkConfigById/GetCoreNetworkConfigByIdQueryHandler.cs rename src/X1.Application/Features/{NetworkConfigs/Queries/GetNetworkConfigById/GetNetworkConfigByIdResponse.cs => CoreNetworkConfigs/Queries/GetCoreNetworkConfigById/GetCoreNetworkConfigByIdResponse.cs} (58%) create mode 100644 src/X1.Application/Features/CoreNetworkConfigs/Queries/GetCoreNetworkConfigs/GetCoreNetworkConfigsQuery.cs create mode 100644 src/X1.Application/Features/CoreNetworkConfigs/Queries/GetCoreNetworkConfigs/GetCoreNetworkConfigsQueryHandler.cs rename src/X1.Application/Features/{NetworkConfigs/Queries/GetNetworkConfigs/GetNetworkConfigsResponse.cs => CoreNetworkConfigs/Queries/GetCoreNetworkConfigs/GetCoreNetworkConfigsResponse.cs} (65%) create mode 100644 src/X1.Application/Features/IMSConfiguration/Commands/CreateIMS_Configuration/CreateIMS_ConfigurationCommand.cs create mode 100644 src/X1.Application/Features/IMSConfiguration/Commands/CreateIMS_Configuration/CreateIMS_ConfigurationCommandHandler.cs create mode 100644 src/X1.Application/Features/IMSConfiguration/Commands/CreateIMS_Configuration/CreateIMS_ConfigurationResponse.cs create mode 100644 src/X1.Application/Features/IMSConfiguration/Commands/DeleteIMS_Configuration/DeleteIMS_ConfigurationCommand.cs create mode 100644 src/X1.Application/Features/IMSConfiguration/Commands/DeleteIMS_Configuration/DeleteIMS_ConfigurationCommandHandler.cs rename src/X1.Application/Features/{NetworkConfigs/Commands/CreateNetworkConfig/CreateNetworkConfigCommand.cs => IMSConfiguration/Commands/UpdateIMS_Configuration/UpdateIMS_ConfigurationCommand.cs} (50%) create mode 100644 src/X1.Application/Features/IMSConfiguration/Commands/UpdateIMS_Configuration/UpdateIMS_ConfigurationCommandHandler.cs create mode 100644 src/X1.Application/Features/IMSConfiguration/Commands/UpdateIMS_Configuration/UpdateIMS_ConfigurationResponse.cs create mode 100644 src/X1.Application/Features/IMSConfiguration/Queries/GetIMS_ConfigurationById/GetIMS_ConfigurationByIdQuery.cs create mode 100644 src/X1.Application/Features/IMSConfiguration/Queries/GetIMS_ConfigurationById/GetIMS_ConfigurationByIdQueryHandler.cs create mode 100644 src/X1.Application/Features/IMSConfiguration/Queries/GetIMS_ConfigurationById/GetIMS_ConfigurationByIdResponse.cs create mode 100644 src/X1.Application/Features/IMSConfiguration/Queries/GetIMS_Configurations/GetIMS_ConfigurationsQuery.cs create mode 100644 src/X1.Application/Features/IMSConfiguration/Queries/GetIMS_Configurations/GetIMS_ConfigurationsQueryHandler.cs create mode 100644 src/X1.Application/Features/IMSConfiguration/Queries/GetIMS_Configurations/GetIMS_ConfigurationsResponse.cs delete mode 100644 src/X1.Application/Features/NetworkConfigs/Commands/CreateNetworkConfig/CreateNetworkConfigCommandHandler.cs delete mode 100644 src/X1.Application/Features/NetworkConfigs/Commands/CreateNetworkConfig/CreateNetworkConfigResponse.cs delete mode 100644 src/X1.Application/Features/NetworkConfigs/Commands/DeleteNetworkConfig/DeleteNetworkConfigCommand.cs delete mode 100644 src/X1.Application/Features/NetworkConfigs/Commands/DeleteNetworkConfig/DeleteNetworkConfigCommandHandler.cs delete mode 100644 src/X1.Application/Features/NetworkConfigs/Commands/UpdateNetworkConfig/UpdateNetworkConfigCommandHandler.cs delete mode 100644 src/X1.Application/Features/NetworkConfigs/Commands/UpdateNetworkConfig/UpdateNetworkConfigResponse.cs delete mode 100644 src/X1.Application/Features/NetworkConfigs/Queries/GetNetworkConfigById/GetNetworkConfigByIdQuery.cs delete mode 100644 src/X1.Application/Features/NetworkConfigs/Queries/GetNetworkConfigById/GetNetworkConfigByIdQueryHandler.cs delete mode 100644 src/X1.Application/Features/NetworkConfigs/Queries/GetNetworkConfigs/GetNetworkConfigsQuery.cs delete mode 100644 src/X1.Application/Features/NetworkConfigs/Queries/GetNetworkConfigs/GetNetworkConfigsQueryHandler.cs create mode 100644 src/X1.Application/Features/NetworkStackConfigs/Commands/CreateNetworkStackConfig/CreateNetworkStackConfigCommand.cs create mode 100644 src/X1.Application/Features/NetworkStackConfigs/Commands/CreateNetworkStackConfig/CreateNetworkStackConfigCommandHandler.cs create mode 100644 src/X1.Application/Features/NetworkStackConfigs/Commands/CreateNetworkStackConfig/CreateNetworkStackConfigResponse.cs create mode 100644 src/X1.Application/Features/NetworkStackConfigs/Commands/DeleteNetworkStackConfig/DeleteNetworkStackConfigCommand.cs create mode 100644 src/X1.Application/Features/NetworkStackConfigs/Commands/DeleteNetworkStackConfig/DeleteNetworkStackConfigCommandHandler.cs create mode 100644 src/X1.Application/Features/NetworkStackConfigs/Commands/UpdateNetworkStackConfig/UpdateNetworkStackConfigCommand.cs create mode 100644 src/X1.Application/Features/NetworkStackConfigs/Commands/UpdateNetworkStackConfig/UpdateNetworkStackConfigCommandHandler.cs create mode 100644 src/X1.Application/Features/NetworkStackConfigs/Commands/UpdateNetworkStackConfig/UpdateNetworkStackConfigResponse.cs create mode 100644 src/X1.Application/Features/NetworkStackConfigs/Queries/GetNetworkStackConfigById/GetNetworkStackConfigByIdQuery.cs create mode 100644 src/X1.Application/Features/NetworkStackConfigs/Queries/GetNetworkStackConfigById/GetNetworkStackConfigByIdQueryHandler.cs create mode 100644 src/X1.Application/Features/NetworkStackConfigs/Queries/GetNetworkStackConfigById/GetNetworkStackConfigByIdResponse.cs create mode 100644 src/X1.Application/Features/NetworkStackConfigs/Queries/GetNetworkStackConfigs/GetNetworkStackConfigsQuery.cs create mode 100644 src/X1.Application/Features/NetworkStackConfigs/Queries/GetNetworkStackConfigs/GetNetworkStackConfigsQueryHandler.cs create mode 100644 src/X1.Application/Features/NetworkStackConfigs/Queries/GetNetworkStackConfigs/GetNetworkStackConfigsResponse.cs create mode 100644 src/X1.Application/Features/RANConfiguration/Commands/CreateRAN_Configuration/CreateRAN_ConfigurationCommand.cs create mode 100644 src/X1.Application/Features/RANConfiguration/Commands/CreateRAN_Configuration/CreateRAN_ConfigurationCommandHandler.cs create mode 100644 src/X1.Application/Features/RANConfiguration/Commands/CreateRAN_Configuration/CreateRAN_ConfigurationResponse.cs create mode 100644 src/X1.Application/Features/RANConfiguration/Commands/DeleteRAN_Configuration/DeleteRAN_ConfigurationCommand.cs create mode 100644 src/X1.Application/Features/RANConfiguration/Commands/DeleteRAN_Configuration/DeleteRAN_ConfigurationCommandHandler.cs rename src/X1.Application/Features/{NetworkConfigs/Commands/UpdateNetworkConfig/UpdateNetworkConfigCommand.cs => RANConfiguration/Commands/UpdateRAN_Configuration/UpdateRAN_ConfigurationCommand.cs} (50%) create mode 100644 src/X1.Application/Features/RANConfiguration/Commands/UpdateRAN_Configuration/UpdateRAN_ConfigurationCommandHandler.cs create mode 100644 src/X1.Application/Features/RANConfiguration/Commands/UpdateRAN_Configuration/UpdateRAN_ConfigurationResponse.cs create mode 100644 src/X1.Application/Features/RANConfiguration/Queries/GetRAN_ConfigurationById/GetRAN_ConfigurationByIdQuery.cs create mode 100644 src/X1.Application/Features/RANConfiguration/Queries/GetRAN_ConfigurationById/GetRAN_ConfigurationByIdQueryHandler.cs create mode 100644 src/X1.Application/Features/RANConfiguration/Queries/GetRAN_ConfigurationById/GetRAN_ConfigurationByIdResponse.cs create mode 100644 src/X1.Application/Features/RANConfiguration/Queries/GetRAN_Configurations/GetRAN_ConfigurationsQuery.cs create mode 100644 src/X1.Application/Features/RANConfiguration/Queries/GetRAN_Configurations/GetRAN_ConfigurationsQueryHandler.cs create mode 100644 src/X1.Application/Features/RANConfiguration/Queries/GetRAN_Configurations/GetRAN_ConfigurationsResponse.cs create mode 100644 src/X1.Application/Features/StackCoreIMSBindings/Commands/CreateStackCoreIMSBinding/CreateStackCoreIMSBindingCommand.cs create mode 100644 src/X1.Application/Features/StackCoreIMSBindings/Commands/CreateStackCoreIMSBinding/CreateStackCoreIMSBindingCommandHandler.cs create mode 100644 src/X1.Application/Features/StackCoreIMSBindings/Commands/CreateStackCoreIMSBinding/CreateStackCoreIMSBindingResponse.cs create mode 100644 src/X1.Application/Features/StackCoreIMSBindings/Commands/DeleteStackCoreIMSBinding/DeleteStackCoreIMSBindingCommand.cs create mode 100644 src/X1.Application/Features/StackCoreIMSBindings/Commands/DeleteStackCoreIMSBinding/DeleteStackCoreIMSBindingCommandHandler.cs create mode 100644 src/X1.Application/Features/StackCoreIMSBindings/Commands/UpdateStackCoreIMSBinding/UpdateStackCoreIMSBindingCommand.cs create mode 100644 src/X1.Application/Features/StackCoreIMSBindings/Commands/UpdateStackCoreIMSBinding/UpdateStackCoreIMSBindingCommandHandler.cs create mode 100644 src/X1.Application/Features/StackCoreIMSBindings/Commands/UpdateStackCoreIMSBinding/UpdateStackCoreIMSBindingResponse.cs create mode 100644 src/X1.Application/Features/StackCoreIMSBindings/Queries/GetStackCoreIMSBindingById/GetStackCoreIMSBindingByIdQuery.cs create mode 100644 src/X1.Application/Features/StackCoreIMSBindings/Queries/GetStackCoreIMSBindingById/GetStackCoreIMSBindingByIdQueryHandler.cs create mode 100644 src/X1.Application/Features/StackCoreIMSBindings/Queries/GetStackCoreIMSBindingById/GetStackCoreIMSBindingByIdResponse.cs create mode 100644 src/X1.Application/Features/StackCoreIMSBindings/Queries/GetStackCoreIMSBindings/GetStackCoreIMSBindingsQuery.cs create mode 100644 src/X1.Application/Features/StackCoreIMSBindings/Queries/GetStackCoreIMSBindings/GetStackCoreIMSBindingsQueryHandler.cs create mode 100644 src/X1.Application/Features/StackCoreIMSBindings/Queries/GetStackCoreIMSBindings/GetStackCoreIMSBindingsResponse.cs delete mode 100644 src/X1.Domain/Entities/Device/NetworkConfig.cs create mode 100644 src/X1.Domain/Entities/NetworkProfile/CoreNetworkConfig.cs create mode 100644 src/X1.Domain/Entities/NetworkProfile/IMS_Configuration.cs create mode 100644 src/X1.Domain/Entities/NetworkProfile/NetworkStackConfig.cs create mode 100644 src/X1.Domain/Entities/NetworkProfile/RAN_Configuration.cs create mode 100644 src/X1.Domain/Entities/NetworkProfile/Stack_CoreIMS_Binding.cs delete mode 100644 src/X1.Domain/Repositories/Device/INetworkConfigRepository.cs create mode 100644 src/X1.Domain/Repositories/NetworkProfile/ICoreNetworkConfigRepository.cs create mode 100644 src/X1.Domain/Repositories/NetworkProfile/IIMS_ConfigurationRepository.cs create mode 100644 src/X1.Domain/Repositories/NetworkProfile/INetworkStackConfigRepository.cs create mode 100644 src/X1.Domain/Repositories/NetworkProfile/IRAN_ConfigurationRepository.cs create mode 100644 src/X1.Domain/Repositories/NetworkProfile/IStack_CoreIMS_BindingRepository.cs delete mode 100644 src/X1.Domain/Specifications/NetworkConfigSamples.json delete mode 100644 src/X1.Domain/Specifications/NetworkConfig_README.md delete mode 100644 src/X1.Domain/Specifications/NetworkConfig_Test.http delete mode 100644 src/X1.Infrastructure/Configurations/Device/NetworkConfigConfiguration.cs create mode 100644 src/X1.Infrastructure/Configurations/NetworkProfile/CoreNetworkConfigConfiguration.cs create mode 100644 src/X1.Infrastructure/Configurations/NetworkProfile/IMS_ConfigurationConfiguration.cs create mode 100644 src/X1.Infrastructure/Configurations/NetworkProfile/NetworkStackConfigConfiguration.cs create mode 100644 src/X1.Infrastructure/Configurations/NetworkProfile/RAN_ConfigurationConfiguration.cs create mode 100644 src/X1.Infrastructure/Configurations/NetworkProfile/Stack_CoreIMS_BindingConfiguration.cs delete mode 100644 src/X1.Infrastructure/Repositories/Device/NetworkConfigRepository.cs create mode 100644 src/X1.Infrastructure/Repositories/NetworkProfile/CoreNetworkConfigRepository.cs create mode 100644 src/X1.Infrastructure/Repositories/NetworkProfile/IMS_ConfigurationRepository.cs create mode 100644 src/X1.Infrastructure/Repositories/NetworkProfile/NetworkStackConfigRepository.cs create mode 100644 src/X1.Infrastructure/Repositories/NetworkProfile/RAN_ConfigurationRepository.cs create mode 100644 src/X1.Infrastructure/Repositories/NetworkProfile/Stack_CoreIMS_BindingRepository.cs create mode 100644 src/X1.Presentation/Controllers/CoreNetworkConfigsController.cs create mode 100644 src/X1.Presentation/Controllers/IMSConfigurationController.cs delete mode 100644 src/X1.Presentation/Controllers/NetworkConfigsController.cs create mode 100644 src/X1.Presentation/Controllers/NetworkStackConfigsController.cs create mode 100644 src/X1.Presentation/Controllers/RANConfigurationController.cs create mode 100644 src/X1.Presentation/Controllers/StackCoreIMSBindingsController.cs create mode 100644 src/X1.WebAPI/logs/app-20250727.log create mode 100644 src/X1.WebAPI/logs/error-20250727.log diff --git a/src/X1.Application/Features/CoreNetworkConfigs/Commands/CreateCoreNetworkConfig/CreateCoreNetworkConfigCommand.cs b/src/X1.Application/Features/CoreNetworkConfigs/Commands/CreateCoreNetworkConfig/CreateCoreNetworkConfigCommand.cs new file mode 100644 index 0000000..2119f72 --- /dev/null +++ b/src/X1.Application/Features/CoreNetworkConfigs/Commands/CreateCoreNetworkConfig/CreateCoreNetworkConfigCommand.cs @@ -0,0 +1,35 @@ +using CellularManagement.Domain.Common; +using MediatR; +using System.ComponentModel.DataAnnotations; + +namespace CellularManagement.Application.Features.CoreNetworkConfigs.Commands.CreateCoreNetworkConfig; + +/// +/// 创建核心网配置命令 +/// +public class CreateCoreNetworkConfigCommand : IRequest> +{ + /// + /// 配置名称 + /// + [Required(ErrorMessage = "配置名称不能为空")] + [MaxLength(100, ErrorMessage = "配置名称不能超过100个字符")] + public string Name { get; set; } = null!; + + /// + /// 配置内容(JSON格式) + /// + [Required(ErrorMessage = "配置内容不能为空")] + public string ConfigContent { get; set; } = null!; + + /// + /// 配置描述 + /// + [MaxLength(500, ErrorMessage = "配置描述不能超过500个字符")] + public string? Description { get; set; } + + /// + /// 是否禁用 + /// + public bool IsDisabled { get; set; } = false; +} \ No newline at end of file diff --git a/src/X1.Application/Features/CoreNetworkConfigs/Commands/CreateCoreNetworkConfig/CreateCoreNetworkConfigCommandHandler.cs b/src/X1.Application/Features/CoreNetworkConfigs/Commands/CreateCoreNetworkConfig/CreateCoreNetworkConfigCommandHandler.cs new file mode 100644 index 0000000..f5f6e2c --- /dev/null +++ b/src/X1.Application/Features/CoreNetworkConfigs/Commands/CreateCoreNetworkConfig/CreateCoreNetworkConfigCommandHandler.cs @@ -0,0 +1,95 @@ +using MediatR; +using Microsoft.Extensions.Logging; +using CellularManagement.Domain.Common; +using CellularManagement.Domain.Repositories.NetworkProfile; +using CellularManagement.Domain.Repositories.Base; +using CellularManagement.Domain.Services; +using CellularManagement.Domain.Entities.NetworkProfile; + +namespace CellularManagement.Application.Features.CoreNetworkConfigs.Commands.CreateCoreNetworkConfig; + +/// +/// 创建核心网配置命令处理器 +/// +public class CreateCoreNetworkConfigCommandHandler : IRequestHandler> +{ + private readonly ICoreNetworkConfigRepository _coreNetworkConfigRepository; + private readonly ILogger _logger; + private readonly IUnitOfWork _unitOfWork; + private readonly ICurrentUserService _currentUserService; + + /// + /// 初始化命令处理器 + /// + public CreateCoreNetworkConfigCommandHandler( + ICoreNetworkConfigRepository coreNetworkConfigRepository, + ILogger logger, + IUnitOfWork unitOfWork, + ICurrentUserService currentUserService) + { + _coreNetworkConfigRepository = coreNetworkConfigRepository; + _logger = logger; + _unitOfWork = unitOfWork; + _currentUserService = currentUserService; + } + + /// + /// 处理创建核心网配置命令 + /// + public async Task> Handle(CreateCoreNetworkConfigCommand request, CancellationToken cancellationToken) + { + try + { + _logger.LogInformation("开始创建核心网配置,配置名称: {Name}", request.Name); + + // 检查配置名称是否已存在 + if (await _coreNetworkConfigRepository.NameExistsAsync(request.Name, cancellationToken)) + { + _logger.LogWarning("核心网配置名称已存在: {Name}", request.Name); + return OperationResult.CreateFailure($"核心网配置名称 {request.Name} 已存在"); + } + + // 获取当前用户ID + var currentUserId = _currentUserService.GetCurrentUserId(); + if (string.IsNullOrEmpty(currentUserId)) + { + _logger.LogError("无法获取当前用户ID,用户可能未认证"); + return OperationResult.CreateFailure("用户未认证,无法创建核心网配置"); + } + + // 创建核心网配置实体 + var coreNetworkConfig = CoreNetworkConfig.Create( + name: request.Name, + configContent: request.ConfigContent, + createdBy: currentUserId, + description: request.Description, + isDisabled: request.IsDisabled); + + // 保存核心网配置 + await _coreNetworkConfigRepository.AddCoreNetworkConfigAsync(coreNetworkConfig, cancellationToken); + + // 保存更改到数据库 + await _unitOfWork.SaveChangesAsync(cancellationToken); + + // 构建响应 + var response = new CreateCoreNetworkConfigResponse + { + CoreNetworkConfigId = coreNetworkConfig.Id, + Name = coreNetworkConfig.Name, + ConfigContent = coreNetworkConfig.ConfigContent, + Description = coreNetworkConfig.Description, + IsDisabled = coreNetworkConfig.IsDisabled, + CreatedAt = coreNetworkConfig.CreatedAt + }; + + _logger.LogInformation("核心网配置创建成功,配置ID: {CoreNetworkConfigId}, 配置名称: {Name}", + coreNetworkConfig.Id, coreNetworkConfig.Name); + return OperationResult.CreateSuccess(response); + } + catch (Exception ex) + { + _logger.LogError(ex, "创建核心网配置时发生错误,配置名称: {Name}", request.Name); + return OperationResult.CreateFailure($"创建核心网配置时发生错误: {ex.Message}"); + } + } +} \ No newline at end of file diff --git a/src/X1.Application/Features/CoreNetworkConfigs/Commands/CreateCoreNetworkConfig/CreateCoreNetworkConfigResponse.cs b/src/X1.Application/Features/CoreNetworkConfigs/Commands/CreateCoreNetworkConfig/CreateCoreNetworkConfigResponse.cs new file mode 100644 index 0000000..2d34fbe --- /dev/null +++ b/src/X1.Application/Features/CoreNetworkConfigs/Commands/CreateCoreNetworkConfig/CreateCoreNetworkConfigResponse.cs @@ -0,0 +1,37 @@ +namespace CellularManagement.Application.Features.CoreNetworkConfigs.Commands.CreateCoreNetworkConfig; + +/// +/// 创建核心网配置响应 +/// +public class CreateCoreNetworkConfigResponse +{ + /// + /// 核心网配置ID + /// + public string CoreNetworkConfigId { get; set; } = null!; + + /// + /// 配置名称 + /// + public string Name { get; set; } = null!; + + /// + /// 配置内容(JSON格式) + /// + public string ConfigContent { get; set; } = null!; + + /// + /// 配置描述 + /// + public string? Description { get; set; } + + /// + /// 是否禁用 + /// + public bool IsDisabled { get; set; } + + /// + /// 创建时间 + /// + public DateTime CreatedAt { get; set; } +} \ No newline at end of file diff --git a/src/X1.Application/Features/CoreNetworkConfigs/Commands/DeleteCoreNetworkConfig/DeleteCoreNetworkConfigCommand.cs b/src/X1.Application/Features/CoreNetworkConfigs/Commands/DeleteCoreNetworkConfig/DeleteCoreNetworkConfigCommand.cs new file mode 100644 index 0000000..96b14d1 --- /dev/null +++ b/src/X1.Application/Features/CoreNetworkConfigs/Commands/DeleteCoreNetworkConfig/DeleteCoreNetworkConfigCommand.cs @@ -0,0 +1,17 @@ +using CellularManagement.Domain.Common; +using MediatR; +using System.ComponentModel.DataAnnotations; + +namespace CellularManagement.Application.Features.CoreNetworkConfigs.Commands.DeleteCoreNetworkConfig; + +/// +/// 删除核心网配置命令 +/// +public class DeleteCoreNetworkConfigCommand : IRequest> +{ + /// + /// 核心网配置ID + /// + [Required] + public string CoreNetworkConfigId { get; set; } = null!; +} \ No newline at end of file diff --git a/src/X1.Application/Features/CoreNetworkConfigs/Commands/DeleteCoreNetworkConfig/DeleteCoreNetworkConfigCommandHandler.cs b/src/X1.Application/Features/CoreNetworkConfigs/Commands/DeleteCoreNetworkConfig/DeleteCoreNetworkConfigCommandHandler.cs new file mode 100644 index 0000000..993218e --- /dev/null +++ b/src/X1.Application/Features/CoreNetworkConfigs/Commands/DeleteCoreNetworkConfig/DeleteCoreNetworkConfigCommandHandler.cs @@ -0,0 +1,64 @@ +using MediatR; +using Microsoft.Extensions.Logging; +using CellularManagement.Domain.Common; +using CellularManagement.Domain.Repositories.NetworkProfile; +using CellularManagement.Domain.Repositories.Base; + +namespace CellularManagement.Application.Features.CoreNetworkConfigs.Commands.DeleteCoreNetworkConfig; + +/// +/// 删除核心网配置命令处理器 +/// +public class DeleteCoreNetworkConfigCommandHandler : IRequestHandler> +{ + private readonly ICoreNetworkConfigRepository _coreNetworkConfigRepository; + private readonly ILogger _logger; + private readonly IUnitOfWork _unitOfWork; + + /// + /// 初始化命令处理器 + /// + public DeleteCoreNetworkConfigCommandHandler( + ICoreNetworkConfigRepository coreNetworkConfigRepository, + ILogger logger, + IUnitOfWork unitOfWork) + { + _coreNetworkConfigRepository = coreNetworkConfigRepository; + _logger = logger; + _unitOfWork = unitOfWork; + } + + /// + /// 处理删除核心网配置命令 + /// + public async Task> Handle(DeleteCoreNetworkConfigCommand request, CancellationToken cancellationToken) + { + try + { + _logger.LogInformation("开始删除核心网配置,配置ID: {CoreNetworkConfigId}", request.CoreNetworkConfigId); + + // 检查核心网配置是否存在 + var existingConfig = await _coreNetworkConfigRepository.GetCoreNetworkConfigByIdAsync(request.CoreNetworkConfigId, cancellationToken); + if (existingConfig == null) + { + _logger.LogWarning("核心网配置不存在: {CoreNetworkConfigId}", request.CoreNetworkConfigId); + return OperationResult.CreateFailure($"核心网配置 {request.CoreNetworkConfigId} 不存在"); + } + + // 删除核心网配置 + await _coreNetworkConfigRepository.DeleteCoreNetworkConfigAsync(request.CoreNetworkConfigId, cancellationToken); + + // 保存更改到数据库 + await _unitOfWork.SaveChangesAsync(cancellationToken); + + _logger.LogInformation("核心网配置删除成功,配置ID: {CoreNetworkConfigId}, 配置名称: {Name}", + request.CoreNetworkConfigId, existingConfig.Name); + return OperationResult.CreateSuccess(true); + } + catch (Exception ex) + { + _logger.LogError(ex, "删除核心网配置时发生错误,配置ID: {CoreNetworkConfigId}", request.CoreNetworkConfigId); + return OperationResult.CreateFailure($"删除核心网配置时发生错误: {ex.Message}"); + } + } +} \ No newline at end of file diff --git a/src/X1.Application/Features/CoreNetworkConfigs/Commands/UpdateCoreNetworkConfig/UpdateCoreNetworkConfigCommand.cs b/src/X1.Application/Features/CoreNetworkConfigs/Commands/UpdateCoreNetworkConfig/UpdateCoreNetworkConfigCommand.cs new file mode 100644 index 0000000..8c8cd26 --- /dev/null +++ b/src/X1.Application/Features/CoreNetworkConfigs/Commands/UpdateCoreNetworkConfig/UpdateCoreNetworkConfigCommand.cs @@ -0,0 +1,41 @@ +using CellularManagement.Domain.Common; +using MediatR; +using System.ComponentModel.DataAnnotations; + +namespace CellularManagement.Application.Features.CoreNetworkConfigs.Commands.UpdateCoreNetworkConfig; + +/// +/// 更新核心网配置命令 +/// +public class UpdateCoreNetworkConfigCommand : IRequest> +{ + /// + /// 核心网配置ID + /// + [Required] + public string CoreNetworkConfigId { get; set; } = null!; + + /// + /// 配置名称 + /// + [Required(ErrorMessage = "配置名称不能为空")] + [MaxLength(100, ErrorMessage = "配置名称不能超过100个字符")] + public string Name { get; set; } = null!; + + /// + /// 配置内容(JSON格式) + /// + [Required(ErrorMessage = "配置内容不能为空")] + public string ConfigContent { get; set; } = null!; + + /// + /// 配置描述 + /// + [MaxLength(500, ErrorMessage = "配置描述不能超过500个字符")] + public string? Description { get; set; } + + /// + /// 是否禁用 + /// + public bool IsDisabled { get; set; } = false; +} \ No newline at end of file diff --git a/src/X1.Application/Features/CoreNetworkConfigs/Commands/UpdateCoreNetworkConfig/UpdateCoreNetworkConfigCommandHandler.cs b/src/X1.Application/Features/CoreNetworkConfigs/Commands/UpdateCoreNetworkConfig/UpdateCoreNetworkConfigCommandHandler.cs new file mode 100644 index 0000000..f7537c7 --- /dev/null +++ b/src/X1.Application/Features/CoreNetworkConfigs/Commands/UpdateCoreNetworkConfig/UpdateCoreNetworkConfigCommandHandler.cs @@ -0,0 +1,102 @@ +using MediatR; +using Microsoft.Extensions.Logging; +using CellularManagement.Domain.Common; +using CellularManagement.Domain.Repositories.NetworkProfile; +using CellularManagement.Domain.Repositories.Base; +using CellularManagement.Domain.Services; +using CellularManagement.Domain.Entities.NetworkProfile; + +namespace CellularManagement.Application.Features.CoreNetworkConfigs.Commands.UpdateCoreNetworkConfig; + +/// +/// 更新核心网配置命令处理器 +/// +public class UpdateCoreNetworkConfigCommandHandler : IRequestHandler> +{ + private readonly ICoreNetworkConfigRepository _coreNetworkConfigRepository; + private readonly ILogger _logger; + private readonly IUnitOfWork _unitOfWork; + private readonly ICurrentUserService _currentUserService; + + /// + /// 初始化命令处理器 + /// + public UpdateCoreNetworkConfigCommandHandler( + ICoreNetworkConfigRepository coreNetworkConfigRepository, + ILogger logger, + IUnitOfWork unitOfWork, + ICurrentUserService currentUserService) + { + _coreNetworkConfigRepository = coreNetworkConfigRepository; + _logger = logger; + _unitOfWork = unitOfWork; + _currentUserService = currentUserService; + } + + /// + /// 处理更新核心网配置命令 + /// + public async Task> Handle(UpdateCoreNetworkConfigCommand request, CancellationToken cancellationToken) + { + try + { + _logger.LogInformation("开始更新核心网配置,配置ID: {CoreNetworkConfigId}", request.CoreNetworkConfigId); + + // 检查核心网配置是否存在 + var existingConfig = await _coreNetworkConfigRepository.GetCoreNetworkConfigByIdAsync(request.CoreNetworkConfigId, cancellationToken); + if (existingConfig == null) + { + _logger.LogWarning("核心网配置不存在: {CoreNetworkConfigId}", request.CoreNetworkConfigId); + return OperationResult.CreateFailure($"核心网配置 {request.CoreNetworkConfigId} 不存在"); + } + + // 检查新名称是否与其他配置冲突 + var configWithSameName = await _coreNetworkConfigRepository.GetCoreNetworkConfigByNameAsync(request.Name, cancellationToken); + if (configWithSameName != null && configWithSameName.Id != request.CoreNetworkConfigId) + { + _logger.LogWarning("核心网配置名称已存在: {Name}", request.Name); + return OperationResult.CreateFailure($"核心网配置名称 {request.Name} 已存在"); + } + + // 获取当前用户ID + var currentUserId = _currentUserService.GetCurrentUserId(); + if (string.IsNullOrEmpty(currentUserId)) + { + _logger.LogError("无法获取当前用户ID,用户可能未认证"); + return OperationResult.CreateFailure("用户未认证,无法更新核心网配置"); + } + + // 更新核心网配置 + existingConfig.Update( + name: request.Name, + configContent: request.ConfigContent, + updatedBy: currentUserId, + description: request.Description, + isDisabled: request.IsDisabled); + + // 保存更改 + _coreNetworkConfigRepository.UpdateCoreNetworkConfig(existingConfig); + await _unitOfWork.SaveChangesAsync(cancellationToken); + + // 构建响应 + var response = new UpdateCoreNetworkConfigResponse + { + CoreNetworkConfigId = existingConfig.Id, + Name = existingConfig.Name, + ConfigContent = existingConfig.ConfigContent, + Description = existingConfig.Description, + IsDisabled = existingConfig.IsDisabled, + UpdatedAt = existingConfig.UpdatedAt + }; + + _logger.LogInformation("核心网配置更新成功,配置ID: {CoreNetworkConfigId}, 配置名称: {Name}", + existingConfig.Id, existingConfig.Name); + return OperationResult.CreateSuccess(response); + } + catch (Exception ex) + { + _logger.LogError(ex, "更新核心网配置时发生错误,配置ID: {CoreNetworkConfigId}", request.CoreNetworkConfigId); + return OperationResult.CreateFailure($"更新核心网配置时发生错误: {ex.Message}"); + } + } +} \ No newline at end of file diff --git a/src/X1.Application/Features/CoreNetworkConfigs/Commands/UpdateCoreNetworkConfig/UpdateCoreNetworkConfigResponse.cs b/src/X1.Application/Features/CoreNetworkConfigs/Commands/UpdateCoreNetworkConfig/UpdateCoreNetworkConfigResponse.cs new file mode 100644 index 0000000..3cf86c7 --- /dev/null +++ b/src/X1.Application/Features/CoreNetworkConfigs/Commands/UpdateCoreNetworkConfig/UpdateCoreNetworkConfigResponse.cs @@ -0,0 +1,37 @@ +namespace CellularManagement.Application.Features.CoreNetworkConfigs.Commands.UpdateCoreNetworkConfig; + +/// +/// 更新核心网配置响应 +/// +public class UpdateCoreNetworkConfigResponse +{ + /// + /// 核心网配置ID + /// + public string CoreNetworkConfigId { get; set; } = null!; + + /// + /// 配置名称 + /// + public string Name { get; set; } = null!; + + /// + /// 配置内容(JSON格式) + /// + public string ConfigContent { get; set; } = null!; + + /// + /// 配置描述 + /// + public string? Description { get; set; } + + /// + /// 是否禁用 + /// + public bool IsDisabled { get; set; } + + /// + /// 更新时间 + /// + public DateTime? UpdatedAt { get; set; } +} \ No newline at end of file diff --git a/src/X1.Application/Features/CoreNetworkConfigs/Queries/GetCoreNetworkConfigById/GetCoreNetworkConfigByIdQuery.cs b/src/X1.Application/Features/CoreNetworkConfigs/Queries/GetCoreNetworkConfigById/GetCoreNetworkConfigByIdQuery.cs new file mode 100644 index 0000000..750a7e3 --- /dev/null +++ b/src/X1.Application/Features/CoreNetworkConfigs/Queries/GetCoreNetworkConfigById/GetCoreNetworkConfigByIdQuery.cs @@ -0,0 +1,17 @@ +using CellularManagement.Domain.Common; +using MediatR; +using System.ComponentModel.DataAnnotations; + +namespace CellularManagement.Application.Features.CoreNetworkConfigs.Queries.GetCoreNetworkConfigById; + +/// +/// 根据ID获取核心网配置查询 +/// +public class GetCoreNetworkConfigByIdQuery : IRequest> +{ + /// + /// 核心网配置ID + /// + [Required] + public string CoreNetworkConfigId { get; set; } = null!; +} \ No newline at end of file diff --git a/src/X1.Application/Features/CoreNetworkConfigs/Queries/GetCoreNetworkConfigById/GetCoreNetworkConfigByIdQueryHandler.cs b/src/X1.Application/Features/CoreNetworkConfigs/Queries/GetCoreNetworkConfigById/GetCoreNetworkConfigByIdQueryHandler.cs new file mode 100644 index 0000000..db2f2fc --- /dev/null +++ b/src/X1.Application/Features/CoreNetworkConfigs/Queries/GetCoreNetworkConfigById/GetCoreNetworkConfigByIdQueryHandler.cs @@ -0,0 +1,68 @@ +using MediatR; +using Microsoft.Extensions.Logging; +using CellularManagement.Domain.Common; +using CellularManagement.Domain.Repositories.NetworkProfile; + +namespace CellularManagement.Application.Features.CoreNetworkConfigs.Queries.GetCoreNetworkConfigById; + +/// +/// 根据ID获取核心网配置查询处理器 +/// +public class GetCoreNetworkConfigByIdQueryHandler : IRequestHandler> +{ + private readonly ICoreNetworkConfigRepository _coreNetworkConfigRepository; + private readonly ILogger _logger; + + /// + /// 初始化查询处理器 + /// + public GetCoreNetworkConfigByIdQueryHandler( + ICoreNetworkConfigRepository coreNetworkConfigRepository, + ILogger logger) + { + _coreNetworkConfigRepository = coreNetworkConfigRepository; + _logger = logger; + } + + /// + /// 处理根据ID获取核心网配置查询 + /// + public async Task> Handle(GetCoreNetworkConfigByIdQuery request, CancellationToken cancellationToken) + { + try + { + _logger.LogInformation("开始获取核心网配置,配置ID: {CoreNetworkConfigId}", request.CoreNetworkConfigId); + + // 获取核心网配置 + var coreNetworkConfig = await _coreNetworkConfigRepository.GetCoreNetworkConfigByIdAsync(request.CoreNetworkConfigId, cancellationToken); + if (coreNetworkConfig == null) + { + _logger.LogWarning("核心网配置不存在: {CoreNetworkConfigId}", request.CoreNetworkConfigId); + return OperationResult.CreateFailure($"核心网配置 {request.CoreNetworkConfigId} 不存在"); + } + + // 构建响应 + var response = new GetCoreNetworkConfigByIdResponse + { + CoreNetworkConfigId = coreNetworkConfig.Id, + Name = coreNetworkConfig.Name, + ConfigContent = coreNetworkConfig.ConfigContent, + Description = coreNetworkConfig.Description, + IsDisabled = coreNetworkConfig.IsDisabled, + CreatedAt = coreNetworkConfig.CreatedAt, + UpdatedAt = coreNetworkConfig.UpdatedAt, + CreatedBy = coreNetworkConfig.CreatedBy, + UpdatedBy = coreNetworkConfig.UpdatedBy + }; + + _logger.LogInformation("成功获取核心网配置,配置ID: {CoreNetworkConfigId}, 配置名称: {Name}", + coreNetworkConfig.Id, coreNetworkConfig.Name); + return OperationResult.CreateSuccess(response); + } + catch (Exception ex) + { + _logger.LogError(ex, "获取核心网配置时发生错误,配置ID: {CoreNetworkConfigId}", request.CoreNetworkConfigId); + return OperationResult.CreateFailure($"获取核心网配置时发生错误: {ex.Message}"); + } + } +} \ No newline at end of file diff --git a/src/X1.Application/Features/NetworkConfigs/Queries/GetNetworkConfigById/GetNetworkConfigByIdResponse.cs b/src/X1.Application/Features/CoreNetworkConfigs/Queries/GetCoreNetworkConfigById/GetCoreNetworkConfigByIdResponse.cs similarity index 58% rename from src/X1.Application/Features/NetworkConfigs/Queries/GetNetworkConfigById/GetNetworkConfigByIdResponse.cs rename to src/X1.Application/Features/CoreNetworkConfigs/Queries/GetCoreNetworkConfigById/GetCoreNetworkConfigByIdResponse.cs index f75761d..e0435bd 100644 --- a/src/X1.Application/Features/NetworkConfigs/Queries/GetNetworkConfigById/GetNetworkConfigByIdResponse.cs +++ b/src/X1.Application/Features/CoreNetworkConfigs/Queries/GetCoreNetworkConfigById/GetCoreNetworkConfigByIdResponse.cs @@ -1,21 +1,14 @@ -using CellularManagement.Domain.Entities.Device; - -namespace CellularManagement.Application.Features.NetworkConfigs.Queries.GetNetworkConfigById; +namespace CellularManagement.Application.Features.CoreNetworkConfigs.Queries.GetCoreNetworkConfigById; /// -/// 根据ID获取网络配置响应 +/// 根据ID获取核心网配置响应 /// -public class GetNetworkConfigByIdResponse +public class GetCoreNetworkConfigByIdResponse { /// - /// 配置ID - /// - public string Id { get; set; } = null!; - - /// - /// 配置类型 + /// 核心网配置ID /// - public NetworkConfigType ConfigType { get; set; } + public string CoreNetworkConfigId { get; set; } = null!; /// /// 配置名称 @@ -23,17 +16,12 @@ public class GetNetworkConfigByIdResponse public string Name { get; set; } = null!; /// - /// PLMN字段 - /// - public string? Plmn { get; set; } - - /// - /// 配置内容 + /// 配置内容(JSON格式) /// public string ConfigContent { get; set; } = null!; /// - /// 配置说明 + /// 配置描述 /// public string? Description { get; set; } @@ -60,5 +48,5 @@ public class GetNetworkConfigByIdResponse /// /// 更新者 /// - public string? UpdatedBy { get; set; } = null!; + public string UpdatedBy { get; set; } = null!; } \ No newline at end of file diff --git a/src/X1.Application/Features/CoreNetworkConfigs/Queries/GetCoreNetworkConfigs/GetCoreNetworkConfigsQuery.cs b/src/X1.Application/Features/CoreNetworkConfigs/Queries/GetCoreNetworkConfigs/GetCoreNetworkConfigsQuery.cs new file mode 100644 index 0000000..f9ecd14 --- /dev/null +++ b/src/X1.Application/Features/CoreNetworkConfigs/Queries/GetCoreNetworkConfigs/GetCoreNetworkConfigsQuery.cs @@ -0,0 +1,34 @@ +using CellularManagement.Domain.Common; +using MediatR; +using System.ComponentModel.DataAnnotations; + +namespace CellularManagement.Application.Features.CoreNetworkConfigs.Queries.GetCoreNetworkConfigs; + +/// +/// 获取核心网配置列表查询 +/// +public class GetCoreNetworkConfigsQuery : IRequest> +{ + /// + /// 页码 + /// + [Range(1, int.MaxValue, ErrorMessage = "页码必须大于0")] + public int PageNumber { get; set; } = 1; + + /// + /// 每页数量 + /// + [Range(1, 100, ErrorMessage = "每页数量必须在1-100之间")] + public int PageSize { get; set; } = 10; + + /// + /// 搜索关键词 + /// + [MaxLength(100)] + public string? SearchTerm { get; set; } + + /// + /// 是否只获取未禁用的配置 + /// + public bool? IsDisabled { get; set; } +} \ No newline at end of file diff --git a/src/X1.Application/Features/CoreNetworkConfigs/Queries/GetCoreNetworkConfigs/GetCoreNetworkConfigsQueryHandler.cs b/src/X1.Application/Features/CoreNetworkConfigs/Queries/GetCoreNetworkConfigs/GetCoreNetworkConfigsQueryHandler.cs new file mode 100644 index 0000000..0a8d598 --- /dev/null +++ b/src/X1.Application/Features/CoreNetworkConfigs/Queries/GetCoreNetworkConfigs/GetCoreNetworkConfigsQueryHandler.cs @@ -0,0 +1,78 @@ +using MediatR; +using Microsoft.Extensions.Logging; +using CellularManagement.Domain.Common; +using CellularManagement.Domain.Repositories.NetworkProfile; + +namespace CellularManagement.Application.Features.CoreNetworkConfigs.Queries.GetCoreNetworkConfigs; + +/// +/// 获取核心网配置列表查询处理器 +/// +public class GetCoreNetworkConfigsQueryHandler : IRequestHandler> +{ + private readonly ICoreNetworkConfigRepository _coreNetworkConfigRepository; + private readonly ILogger _logger; + + /// + /// 初始化查询处理器 + /// + public GetCoreNetworkConfigsQueryHandler( + ICoreNetworkConfigRepository coreNetworkConfigRepository, + ILogger logger) + { + _coreNetworkConfigRepository = coreNetworkConfigRepository; + _logger = logger; + } + + /// + /// 处理获取核心网配置列表查询 + /// + public async Task> Handle(GetCoreNetworkConfigsQuery request, CancellationToken cancellationToken) + { + try + { + _logger.LogInformation("开始获取核心网配置列表,页码: {PageNumber}, 每页数量: {PageSize}, 搜索关键词: {SearchTerm}", + request.PageNumber, request.PageSize, request.SearchTerm ?? "无"); + + // 获取核心网配置列表 + var (totalCount, items) = await _coreNetworkConfigRepository.SearchCoreNetworkConfigsAsync( + request.SearchTerm, + request.PageNumber, + request.PageSize, + cancellationToken); + + // 计算总页数 + var totalPages = (int)Math.Ceiling((double)totalCount / request.PageSize); + + // 构建响应 + var response = new GetCoreNetworkConfigsResponse + { + TotalCount = totalCount, + PageNumber = request.PageNumber, + PageSize = request.PageSize, + TotalPages = totalPages, + Items = items.Select(item => new CoreNetworkConfigDto + { + CoreNetworkConfigId = item.Id, + Name = item.Name, + ConfigContent = item.ConfigContent, + Description = item.Description, + IsDisabled = item.IsDisabled, + CreatedAt = item.CreatedAt, + UpdatedAt = item.UpdatedAt, + CreatedBy = item.CreatedBy, + UpdatedBy = item.UpdatedBy + }).ToList() + }; + + _logger.LogInformation("成功获取核心网配置列表,总数量: {TotalCount}, 当前页数量: {ItemCount}", + totalCount, items.Count); + return OperationResult.CreateSuccess(response); + } + catch (Exception ex) + { + _logger.LogError(ex, "获取核心网配置列表时发生错误"); + return OperationResult.CreateFailure($"获取核心网配置列表时发生错误: {ex.Message}"); + } + } +} \ No newline at end of file diff --git a/src/X1.Application/Features/NetworkConfigs/Queries/GetNetworkConfigs/GetNetworkConfigsResponse.cs b/src/X1.Application/Features/CoreNetworkConfigs/Queries/GetCoreNetworkConfigs/GetCoreNetworkConfigsResponse.cs similarity index 65% rename from src/X1.Application/Features/NetworkConfigs/Queries/GetNetworkConfigs/GetNetworkConfigsResponse.cs rename to src/X1.Application/Features/CoreNetworkConfigs/Queries/GetCoreNetworkConfigs/GetCoreNetworkConfigsResponse.cs index cd0ee0e..ac4dbf7 100644 --- a/src/X1.Application/Features/NetworkConfigs/Queries/GetNetworkConfigs/GetNetworkConfigsResponse.cs +++ b/src/X1.Application/Features/CoreNetworkConfigs/Queries/GetCoreNetworkConfigs/GetCoreNetworkConfigsResponse.cs @@ -1,39 +1,58 @@ -using CellularManagement.Domain.Entities.Device; - -namespace CellularManagement.Application.Features.NetworkConfigs.Queries.GetNetworkConfigs; +namespace CellularManagement.Application.Features.CoreNetworkConfigs.Queries.GetCoreNetworkConfigs; /// -/// 网络配置信息 +/// 获取核心网配置列表响应 /// -public class NetworkConfigDto +public class GetCoreNetworkConfigsResponse { /// - /// 配置ID + /// 总数量 /// - public string Id { get; set; } = null!; + public int TotalCount { get; set; } /// - /// 配置类型 + /// 当前页码 /// - public NetworkConfigType ConfigType { get; set; } + public int PageNumber { get; set; } /// - /// 配置名称 + /// 每页数量 /// - public string Name { get; set; } = null!; + public int PageSize { get; set; } + + /// + /// 总页数 + /// + public int TotalPages { get; set; } /// - /// PLMN字段 + /// 核心网配置列表 /// - public string? Plmn { get; set; } + public List Items { get; set; } = new(); +} +/// +/// 核心网配置数据传输对象 +/// +public class CoreNetworkConfigDto +{ /// - /// 配置内容 + /// 核心网配置ID + /// + public string CoreNetworkConfigId { get; set; } = null!; + + /// + /// 配置名称 + /// + public string Name { get; set; } = null!; + + /// + /// 配置内容(JSON格式) /// public string ConfigContent { get; set; } = null!; /// - /// 配置说明 + /// 配置描述 /// public string? Description { get; set; } @@ -61,35 +80,4 @@ public class NetworkConfigDto /// 更新者 /// public string UpdatedBy { get; set; } = null!; -} - -/// -/// 获取网络配置列表响应 -/// -public class GetNetworkConfigsResponse -{ - /// - /// 网络配置列表 - /// - public List NetworkConfigs { get; set; } = new(); - - /// - /// 总数 - /// - public int TotalCount { get; set; } - - /// - /// 当前页码 - /// - public int PageNumber { get; set; } - - /// - /// 每页数量 - /// - public int PageSize { get; set; } - - /// - /// 总页数 - /// - public int TotalPages { get; set; } } \ No newline at end of file diff --git a/src/X1.Application/Features/Devices/Commands/CreateDevice/CreateDeviceCommand.cs b/src/X1.Application/Features/Devices/Commands/CreateDevice/CreateDeviceCommand.cs index a26c849..86634c1 100644 --- a/src/X1.Application/Features/Devices/Commands/CreateDevice/CreateDeviceCommand.cs +++ b/src/X1.Application/Features/Devices/Commands/CreateDevice/CreateDeviceCommand.cs @@ -30,11 +30,7 @@ public class CreateDeviceCommand : IRequest - /// 协议版本ID - /// - [Required(ErrorMessage = "协议版本不能为空")] - public string ProtocolVersionId { get; set; } + /// /// IP地址 /// diff --git a/src/X1.Application/Features/Devices/Commands/CreateDevice/CreateDeviceCommandHandler.cs b/src/X1.Application/Features/Devices/Commands/CreateDevice/CreateDeviceCommandHandler.cs index 2e89723..16f53be 100644 --- a/src/X1.Application/Features/Devices/Commands/CreateDevice/CreateDeviceCommandHandler.cs +++ b/src/X1.Application/Features/Devices/Commands/CreateDevice/CreateDeviceCommandHandler.cs @@ -15,7 +15,6 @@ namespace CellularManagement.Application.Features.Devices.Commands.CreateDevice; public class CreateDeviceCommandHandler : IRequestHandler> { private readonly ICellularDeviceRepository _deviceRepository; - private readonly IProtocolVersionRepository _protocolVersionRepository; private readonly ILogger _logger; private readonly IUnitOfWork _unitOfWork; private readonly ICurrentUserService _currentUserService; @@ -25,13 +24,11 @@ public class CreateDeviceCommandHandler : IRequestHandler public CreateDeviceCommandHandler( ICellularDeviceRepository deviceRepository, - IProtocolVersionRepository protocolVersionRepository, ILogger logger, IUnitOfWork unitOfWork, ICurrentUserService currentUserService) { _deviceRepository = deviceRepository; - _protocolVersionRepository = protocolVersionRepository; _logger = logger; _unitOfWork = unitOfWork; _currentUserService = currentUserService; @@ -67,7 +64,6 @@ public class CreateDeviceCommandHandler : IRequestHandler.CreateFailure($"创建设备时发生错误: {ex.Message}"); } } + + } \ No newline at end of file diff --git a/src/X1.Application/Features/Devices/Commands/CreateDevice/CreateDeviceResponse.cs b/src/X1.Application/Features/Devices/Commands/CreateDevice/CreateDeviceResponse.cs index 935556a..c74c029 100644 --- a/src/X1.Application/Features/Devices/Commands/CreateDevice/CreateDeviceResponse.cs +++ b/src/X1.Application/Features/Devices/Commands/CreateDevice/CreateDeviceResponse.cs @@ -25,10 +25,7 @@ public class CreateDeviceResponse /// public string Description { get; set; } - /// - /// 协议版本 - /// - public string ProtocolVersion { get; set; } + /// /// Agent端口 diff --git a/src/X1.Application/Features/Devices/Commands/UpdateDevice/UpdateDeviceCommand.cs b/src/X1.Application/Features/Devices/Commands/UpdateDevice/UpdateDeviceCommand.cs index 964a8e7..d7716c9 100644 --- a/src/X1.Application/Features/Devices/Commands/UpdateDevice/UpdateDeviceCommand.cs +++ b/src/X1.Application/Features/Devices/Commands/UpdateDevice/UpdateDeviceCommand.cs @@ -36,11 +36,7 @@ public class UpdateDeviceCommand : IRequest - /// 协议版本ID - /// - [Required] - public string ProtocolVersionId { get; set; } + /// /// IP地址 /// diff --git a/src/X1.Application/Features/Devices/Commands/UpdateDevice/UpdateDeviceCommandHandler.cs b/src/X1.Application/Features/Devices/Commands/UpdateDevice/UpdateDeviceCommandHandler.cs index 71c6465..f470c8e 100644 --- a/src/X1.Application/Features/Devices/Commands/UpdateDevice/UpdateDeviceCommandHandler.cs +++ b/src/X1.Application/Features/Devices/Commands/UpdateDevice/UpdateDeviceCommandHandler.cs @@ -17,7 +17,6 @@ namespace CellularManagement.Application.Features.Devices.Commands.UpdateDevice; public class UpdateDeviceCommandHandler : IRequestHandler> { private readonly ICellularDeviceRepository _deviceRepository; - private readonly IProtocolVersionRepository _protocolVersionRepository; private readonly ILogger _logger; private readonly IUnitOfWork _unitOfWork; private readonly ICurrentUserService _currentUserService; @@ -27,13 +26,11 @@ public class UpdateDeviceCommandHandler : IRequestHandler public UpdateDeviceCommandHandler( ICellularDeviceRepository deviceRepository, - IProtocolVersionRepository protocolVersionRepository, ILogger logger, IUnitOfWork unitOfWork, ICurrentUserService currentUserService) { _deviceRepository = deviceRepository; - _protocolVersionRepository = protocolVersionRepository; _logger = logger; _unitOfWork = unitOfWork; _currentUserService = currentUserService; @@ -80,7 +77,6 @@ public class UpdateDeviceCommandHandler : IRequestHandler.CreateFailure($"更新设备时发生错误: {ex.Message}"); } } + + } \ No newline at end of file diff --git a/src/X1.Application/Features/Devices/Commands/UpdateDevice/UpdateDeviceResponse.cs b/src/X1.Application/Features/Devices/Commands/UpdateDevice/UpdateDeviceResponse.cs index 32914e6..27d5c3b 100644 --- a/src/X1.Application/Features/Devices/Commands/UpdateDevice/UpdateDeviceResponse.cs +++ b/src/X1.Application/Features/Devices/Commands/UpdateDevice/UpdateDeviceResponse.cs @@ -25,10 +25,7 @@ public class UpdateDeviceResponse /// public string Description { get; set; } - /// - /// 协议版本 - /// - public string ProtocolVersion { get; set; } + /// /// Agent端口 diff --git a/src/X1.Application/Features/Devices/Queries/GetDeviceById/GetDeviceByIdQueryHandler.cs b/src/X1.Application/Features/Devices/Queries/GetDeviceById/GetDeviceByIdQueryHandler.cs index b912242..e13f42f 100644 --- a/src/X1.Application/Features/Devices/Queries/GetDeviceById/GetDeviceByIdQueryHandler.cs +++ b/src/X1.Application/Features/Devices/Queries/GetDeviceById/GetDeviceByIdQueryHandler.cs @@ -13,7 +13,6 @@ namespace CellularManagement.Application.Features.Devices.Queries.GetDeviceById; public class GetDeviceByIdQueryHandler : IRequestHandler> { private readonly ICellularDeviceRepository _deviceRepository; - private readonly IProtocolVersionRepository _protocolVersionRepository; private readonly ILogger _logger; /// @@ -21,11 +20,9 @@ public class GetDeviceByIdQueryHandler : IRequestHandler public GetDeviceByIdQueryHandler( ICellularDeviceRepository deviceRepository, - IProtocolVersionRepository protocolVersionRepository, ILogger logger) { _deviceRepository = deviceRepository; - _protocolVersionRepository = protocolVersionRepository; _logger = logger; } @@ -46,16 +43,12 @@ public class GetDeviceByIdQueryHandler : IRequestHandler.CreateFailure($"未找到ID为 {request.DeviceId} 的设备"); } - // 获取协议版本信息 - var protocolVersion = await _protocolVersionRepository.GetProtocolVersionByIdAsync(device.ProtocolVersionId, cancellationToken); - var response = new GetDeviceByIdResponse { DeviceId = device.Id, DeviceName = device.Name, SerialNumber = device.SerialNumber, Description = device.Description, - ProtocolVersion = protocolVersion?.Version ?? "未知", AgentPort = device.AgentPort, IsEnabled = device.IsEnabled, IsRunning = device.IsRunning, @@ -71,4 +64,6 @@ public class GetDeviceByIdQueryHandler : IRequestHandler.CreateFailure($"查询设备时发生错误: {ex.Message}"); } } + + } \ No newline at end of file diff --git a/src/X1.Application/Features/Devices/Queries/GetDeviceById/GetDeviceByIdResponse.cs b/src/X1.Application/Features/Devices/Queries/GetDeviceById/GetDeviceByIdResponse.cs index 4136111..1535e53 100644 --- a/src/X1.Application/Features/Devices/Queries/GetDeviceById/GetDeviceByIdResponse.cs +++ b/src/X1.Application/Features/Devices/Queries/GetDeviceById/GetDeviceByIdResponse.cs @@ -25,10 +25,7 @@ public class GetDeviceByIdResponse /// public string Description { get; set; } - /// - /// 协议版本 - /// - public string ProtocolVersion { get; set; } + /// /// Agent端口 diff --git a/src/X1.Application/Features/Devices/Queries/GetDevices/GetDevicesQueryHandler.cs b/src/X1.Application/Features/Devices/Queries/GetDevices/GetDevicesQueryHandler.cs index 463d83c..554e82e 100644 --- a/src/X1.Application/Features/Devices/Queries/GetDevices/GetDevicesQueryHandler.cs +++ b/src/X1.Application/Features/Devices/Queries/GetDevices/GetDevicesQueryHandler.cs @@ -49,8 +49,8 @@ public class GetDevicesQueryHandler : IRequestHandler.CreateFailure($"获取设备列表时发生错误: {ex.Message}"); } } + + } \ No newline at end of file diff --git a/src/X1.Application/Features/IMSConfiguration/Commands/CreateIMS_Configuration/CreateIMS_ConfigurationCommand.cs b/src/X1.Application/Features/IMSConfiguration/Commands/CreateIMS_Configuration/CreateIMS_ConfigurationCommand.cs new file mode 100644 index 0000000..82dbc13 --- /dev/null +++ b/src/X1.Application/Features/IMSConfiguration/Commands/CreateIMS_Configuration/CreateIMS_ConfigurationCommand.cs @@ -0,0 +1,35 @@ +using CellularManagement.Domain.Common; +using MediatR; +using System.ComponentModel.DataAnnotations; + +namespace CellularManagement.Application.Features.IMSConfiguration.Commands.CreateIMS_Configuration; + +/// +/// 创建IMS配置命令 +/// +public class CreateIMS_ConfigurationCommand : IRequest> +{ + /// + /// 配置名称 + /// + [Required(ErrorMessage = "配置名称不能为空")] + [MaxLength(100, ErrorMessage = "配置名称不能超过100个字符")] + public string Name { get; set; } = null!; + + /// + /// 配置内容(JSON格式) + /// + [Required(ErrorMessage = "配置内容不能为空")] + public string ConfigContent { get; set; } = null!; + + /// + /// 配置描述 + /// + [MaxLength(500, ErrorMessage = "配置描述不能超过500个字符")] + public string? Description { get; set; } + + /// + /// 是否禁用 + /// + public bool IsDisabled { get; set; } = false; +} \ No newline at end of file diff --git a/src/X1.Application/Features/IMSConfiguration/Commands/CreateIMS_Configuration/CreateIMS_ConfigurationCommandHandler.cs b/src/X1.Application/Features/IMSConfiguration/Commands/CreateIMS_Configuration/CreateIMS_ConfigurationCommandHandler.cs new file mode 100644 index 0000000..1fb7793 --- /dev/null +++ b/src/X1.Application/Features/IMSConfiguration/Commands/CreateIMS_Configuration/CreateIMS_ConfigurationCommandHandler.cs @@ -0,0 +1,95 @@ +using MediatR; +using Microsoft.Extensions.Logging; +using CellularManagement.Domain.Common; +using CellularManagement.Domain.Repositories.NetworkProfile; +using CellularManagement.Domain.Repositories.Base; +using CellularManagement.Domain.Services; +using CellularManagement.Domain.Entities.NetworkProfile; + +namespace CellularManagement.Application.Features.IMSConfiguration.Commands.CreateIMS_Configuration; + +/// +/// 创建IMS配置命令处理器 +/// +public class CreateIMS_ConfigurationCommandHandler : IRequestHandler> +{ + private readonly IIMS_ConfigurationRepository _imsConfigurationRepository; + private readonly ILogger _logger; + private readonly IUnitOfWork _unitOfWork; + private readonly ICurrentUserService _currentUserService; + + /// + /// 初始化命令处理器 + /// + public CreateIMS_ConfigurationCommandHandler( + IIMS_ConfigurationRepository imsConfigurationRepository, + ILogger logger, + IUnitOfWork unitOfWork, + ICurrentUserService currentUserService) + { + _imsConfigurationRepository = imsConfigurationRepository; + _logger = logger; + _unitOfWork = unitOfWork; + _currentUserService = currentUserService; + } + + /// + /// 处理创建IMS配置命令 + /// + public async Task> Handle(CreateIMS_ConfigurationCommand request, CancellationToken cancellationToken) + { + try + { + _logger.LogInformation("开始创建IMS配置,配置名称: {Name}", request.Name); + + // 检查配置名称是否已存在 + if (await _imsConfigurationRepository.NameExistsAsync(request.Name, cancellationToken)) + { + _logger.LogWarning("IMS配置名称已存在: {Name}", request.Name); + return OperationResult.CreateFailure($"IMS配置名称 {request.Name} 已存在"); + } + + // 获取当前用户ID + var currentUserId = _currentUserService.GetCurrentUserId(); + if (string.IsNullOrEmpty(currentUserId)) + { + _logger.LogError("无法获取当前用户ID,用户可能未认证"); + return OperationResult.CreateFailure("用户未认证,无法创建IMS配置"); + } + + // 创建IMS配置实体 + var imsConfiguration = IMS_Configuration.Create( + name: request.Name, + configContent: request.ConfigContent, + createdBy: currentUserId, + description: request.Description, + isDisabled: request.IsDisabled); + + // 保存IMS配置 + await _imsConfigurationRepository.AddIMS_ConfigurationAsync(imsConfiguration, cancellationToken); + + // 保存更改到数据库 + await _unitOfWork.SaveChangesAsync(cancellationToken); + + // 构建响应 + var response = new CreateIMS_ConfigurationResponse + { + IMS_ConfigurationId = imsConfiguration.Id, + Name = imsConfiguration.Name, + ConfigContent = imsConfiguration.ConfigContent, + Description = imsConfiguration.Description, + IsDisabled = imsConfiguration.IsDisabled, + CreatedAt = imsConfiguration.CreatedAt + }; + + _logger.LogInformation("IMS配置创建成功,配置ID: {IMS_ConfigurationId}, 配置名称: {Name}", + imsConfiguration.Id, imsConfiguration.Name); + return OperationResult.CreateSuccess(response); + } + catch (Exception ex) + { + _logger.LogError(ex, "创建IMS配置时发生错误,配置名称: {Name}", request.Name); + return OperationResult.CreateFailure($"创建IMS配置时发生错误: {ex.Message}"); + } + } +} \ No newline at end of file diff --git a/src/X1.Application/Features/IMSConfiguration/Commands/CreateIMS_Configuration/CreateIMS_ConfigurationResponse.cs b/src/X1.Application/Features/IMSConfiguration/Commands/CreateIMS_Configuration/CreateIMS_ConfigurationResponse.cs new file mode 100644 index 0000000..c72a6ac --- /dev/null +++ b/src/X1.Application/Features/IMSConfiguration/Commands/CreateIMS_Configuration/CreateIMS_ConfigurationResponse.cs @@ -0,0 +1,37 @@ +namespace CellularManagement.Application.Features.IMSConfiguration.Commands.CreateIMS_Configuration; + +/// +/// 创建IMS配置响应 +/// +public class CreateIMS_ConfigurationResponse +{ + /// + /// IMS配置ID + /// + public string IMS_ConfigurationId { get; set; } = null!; + + /// + /// 配置名称 + /// + public string Name { get; set; } = null!; + + /// + /// 配置内容(JSON格式) + /// + public string ConfigContent { get; set; } = null!; + + /// + /// 配置描述 + /// + public string? Description { get; set; } + + /// + /// 是否禁用 + /// + public bool IsDisabled { get; set; } + + /// + /// 创建时间 + /// + public DateTime CreatedAt { get; set; } +} \ No newline at end of file diff --git a/src/X1.Application/Features/IMSConfiguration/Commands/DeleteIMS_Configuration/DeleteIMS_ConfigurationCommand.cs b/src/X1.Application/Features/IMSConfiguration/Commands/DeleteIMS_Configuration/DeleteIMS_ConfigurationCommand.cs new file mode 100644 index 0000000..85b9e41 --- /dev/null +++ b/src/X1.Application/Features/IMSConfiguration/Commands/DeleteIMS_Configuration/DeleteIMS_ConfigurationCommand.cs @@ -0,0 +1,17 @@ +using CellularManagement.Domain.Common; +using MediatR; +using System.ComponentModel.DataAnnotations; + +namespace CellularManagement.Application.Features.IMSConfiguration.Commands.DeleteIMS_Configuration; + +/// +/// 删除IMS配置命令 +/// +public class DeleteIMS_ConfigurationCommand : IRequest> +{ + /// + /// IMS配置ID + /// + [Required] + public string IMS_ConfigurationId { get; set; } = null!; +} \ No newline at end of file diff --git a/src/X1.Application/Features/IMSConfiguration/Commands/DeleteIMS_Configuration/DeleteIMS_ConfigurationCommandHandler.cs b/src/X1.Application/Features/IMSConfiguration/Commands/DeleteIMS_Configuration/DeleteIMS_ConfigurationCommandHandler.cs new file mode 100644 index 0000000..9c22949 --- /dev/null +++ b/src/X1.Application/Features/IMSConfiguration/Commands/DeleteIMS_Configuration/DeleteIMS_ConfigurationCommandHandler.cs @@ -0,0 +1,64 @@ +using MediatR; +using Microsoft.Extensions.Logging; +using CellularManagement.Domain.Common; +using CellularManagement.Domain.Repositories.NetworkProfile; +using CellularManagement.Domain.Repositories.Base; + +namespace CellularManagement.Application.Features.IMSConfiguration.Commands.DeleteIMS_Configuration; + +/// +/// 删除IMS配置命令处理器 +/// +public class DeleteIMS_ConfigurationCommandHandler : IRequestHandler> +{ + private readonly IIMS_ConfigurationRepository _imsConfigurationRepository; + private readonly ILogger _logger; + private readonly IUnitOfWork _unitOfWork; + + /// + /// 初始化命令处理器 + /// + public DeleteIMS_ConfigurationCommandHandler( + IIMS_ConfigurationRepository imsConfigurationRepository, + ILogger logger, + IUnitOfWork unitOfWork) + { + _imsConfigurationRepository = imsConfigurationRepository; + _logger = logger; + _unitOfWork = unitOfWork; + } + + /// + /// 处理删除IMS配置命令 + /// + public async Task> Handle(DeleteIMS_ConfigurationCommand request, CancellationToken cancellationToken) + { + try + { + _logger.LogInformation("开始删除IMS配置,配置ID: {IMS_ConfigurationId}", request.IMS_ConfigurationId); + + // 检查IMS配置是否存在 + var existingConfig = await _imsConfigurationRepository.GetIMS_ConfigurationByIdAsync(request.IMS_ConfigurationId, cancellationToken); + if (existingConfig == null) + { + _logger.LogWarning("IMS配置不存在: {IMS_ConfigurationId}", request.IMS_ConfigurationId); + return OperationResult.CreateFailure($"IMS配置 {request.IMS_ConfigurationId} 不存在"); + } + + // 删除IMS配置 + await _imsConfigurationRepository.DeleteIMS_ConfigurationAsync(request.IMS_ConfigurationId, cancellationToken); + + // 保存更改到数据库 + await _unitOfWork.SaveChangesAsync(cancellationToken); + + _logger.LogInformation("IMS配置删除成功,配置ID: {IMS_ConfigurationId}, 配置名称: {Name}", + request.IMS_ConfigurationId, existingConfig.Name); + return OperationResult.CreateSuccess(true); + } + catch (Exception ex) + { + _logger.LogError(ex, "删除IMS配置时发生错误,配置ID: {IMS_ConfigurationId}", request.IMS_ConfigurationId); + return OperationResult.CreateFailure($"删除IMS配置时发生错误: {ex.Message}"); + } + } +} \ No newline at end of file diff --git a/src/X1.Application/Features/NetworkConfigs/Commands/CreateNetworkConfig/CreateNetworkConfigCommand.cs b/src/X1.Application/Features/IMSConfiguration/Commands/UpdateIMS_Configuration/UpdateIMS_ConfigurationCommand.cs similarity index 50% rename from src/X1.Application/Features/NetworkConfigs/Commands/CreateNetworkConfig/CreateNetworkConfigCommand.cs rename to src/X1.Application/Features/IMSConfiguration/Commands/UpdateIMS_Configuration/UpdateIMS_ConfigurationCommand.cs index 29f73d2..68b9343 100644 --- a/src/X1.Application/Features/NetworkConfigs/Commands/CreateNetworkConfig/CreateNetworkConfigCommand.cs +++ b/src/X1.Application/Features/IMSConfiguration/Commands/UpdateIMS_Configuration/UpdateIMS_ConfigurationCommand.cs @@ -1,43 +1,37 @@ using CellularManagement.Domain.Common; using MediatR; -using CellularManagement.Domain.Entities.Device; using System.ComponentModel.DataAnnotations; -namespace CellularManagement.Application.Features.NetworkConfigs.Commands.CreateNetworkConfig; +namespace CellularManagement.Application.Features.IMSConfiguration.Commands.UpdateIMS_Configuration; /// -/// 创建网络配置命令 +/// 更新IMS配置命令 /// -public class CreateNetworkConfigCommand : IRequest> +public class UpdateIMS_ConfigurationCommand : IRequest> { /// - /// 配置类型 + /// IMS配置ID /// - public NetworkConfigType ConfigType { get; set; } + [Required] + public string IMS_ConfigurationId { get; set; } = null!; /// /// 配置名称 /// - [Required] - [MaxLength(100)] + [Required(ErrorMessage = "配置名称不能为空")] + [MaxLength(100, ErrorMessage = "配置名称不能超过100个字符")] public string Name { get; set; } = null!; - /// - /// PLMN字段(移动国家代码+移动网络代码) - /// - [MaxLength(10)] - public string? Plmn { get; set; } - /// /// 配置内容(JSON格式) /// - [Required] + [Required(ErrorMessage = "配置内容不能为空")] public string ConfigContent { get; set; } = null!; /// - /// 配置说明 + /// 配置描述 /// - [MaxLength(500)] + [MaxLength(500, ErrorMessage = "配置描述不能超过500个字符")] public string? Description { get; set; } /// diff --git a/src/X1.Application/Features/IMSConfiguration/Commands/UpdateIMS_Configuration/UpdateIMS_ConfigurationCommandHandler.cs b/src/X1.Application/Features/IMSConfiguration/Commands/UpdateIMS_Configuration/UpdateIMS_ConfigurationCommandHandler.cs new file mode 100644 index 0000000..09dd54b --- /dev/null +++ b/src/X1.Application/Features/IMSConfiguration/Commands/UpdateIMS_Configuration/UpdateIMS_ConfigurationCommandHandler.cs @@ -0,0 +1,102 @@ +using MediatR; +using Microsoft.Extensions.Logging; +using CellularManagement.Domain.Common; +using CellularManagement.Domain.Repositories.NetworkProfile; +using CellularManagement.Domain.Repositories.Base; +using CellularManagement.Domain.Services; +using CellularManagement.Domain.Entities.NetworkProfile; + +namespace CellularManagement.Application.Features.IMSConfiguration.Commands.UpdateIMS_Configuration; + +/// +/// 更新IMS配置命令处理器 +/// +public class UpdateIMS_ConfigurationCommandHandler : IRequestHandler> +{ + private readonly IIMS_ConfigurationRepository _imsConfigurationRepository; + private readonly ILogger _logger; + private readonly IUnitOfWork _unitOfWork; + private readonly ICurrentUserService _currentUserService; + + /// + /// 初始化命令处理器 + /// + public UpdateIMS_ConfigurationCommandHandler( + IIMS_ConfigurationRepository imsConfigurationRepository, + ILogger logger, + IUnitOfWork unitOfWork, + ICurrentUserService currentUserService) + { + _imsConfigurationRepository = imsConfigurationRepository; + _logger = logger; + _unitOfWork = unitOfWork; + _currentUserService = currentUserService; + } + + /// + /// 处理更新IMS配置命令 + /// + public async Task> Handle(UpdateIMS_ConfigurationCommand request, CancellationToken cancellationToken) + { + try + { + _logger.LogInformation("开始更新IMS配置,配置ID: {IMS_ConfigurationId}", request.IMS_ConfigurationId); + + // 检查IMS配置是否存在 + var existingConfig = await _imsConfigurationRepository.GetIMS_ConfigurationByIdAsync(request.IMS_ConfigurationId, cancellationToken); + if (existingConfig == null) + { + _logger.LogWarning("IMS配置不存在: {IMS_ConfigurationId}", request.IMS_ConfigurationId); + return OperationResult.CreateFailure($"IMS配置 {request.IMS_ConfigurationId} 不存在"); + } + + // 检查新名称是否与其他配置冲突 + var configWithSameName = await _imsConfigurationRepository.GetIMS_ConfigurationByNameAsync(request.Name, cancellationToken); + if (configWithSameName != null && configWithSameName.Id != request.IMS_ConfigurationId) + { + _logger.LogWarning("IMS配置名称已存在: {Name}", request.Name); + return OperationResult.CreateFailure($"IMS配置名称 {request.Name} 已存在"); + } + + // 获取当前用户ID + var currentUserId = _currentUserService.GetCurrentUserId(); + if (string.IsNullOrEmpty(currentUserId)) + { + _logger.LogError("无法获取当前用户ID,用户可能未认证"); + return OperationResult.CreateFailure("用户未认证,无法更新IMS配置"); + } + + // 更新IMS配置 + existingConfig.Update( + name: request.Name, + configContent: request.ConfigContent, + updatedBy: currentUserId, + description: request.Description, + isDisabled: request.IsDisabled); + + // 保存更改 + _imsConfigurationRepository.UpdateIMS_Configuration(existingConfig); + await _unitOfWork.SaveChangesAsync(cancellationToken); + + // 构建响应 + var response = new UpdateIMS_ConfigurationResponse + { + IMS_ConfigurationId = existingConfig.Id, + Name = existingConfig.Name, + ConfigContent = existingConfig.ConfigContent, + Description = existingConfig.Description, + IsDisabled = existingConfig.IsDisabled, + UpdatedAt = existingConfig.UpdatedAt + }; + + _logger.LogInformation("IMS配置更新成功,配置ID: {IMS_ConfigurationId}, 配置名称: {Name}", + existingConfig.Id, existingConfig.Name); + return OperationResult.CreateSuccess(response); + } + catch (Exception ex) + { + _logger.LogError(ex, "更新IMS配置时发生错误,配置ID: {IMS_ConfigurationId}", request.IMS_ConfigurationId); + return OperationResult.CreateFailure($"更新IMS配置时发生错误: {ex.Message}"); + } + } +} \ No newline at end of file diff --git a/src/X1.Application/Features/IMSConfiguration/Commands/UpdateIMS_Configuration/UpdateIMS_ConfigurationResponse.cs b/src/X1.Application/Features/IMSConfiguration/Commands/UpdateIMS_Configuration/UpdateIMS_ConfigurationResponse.cs new file mode 100644 index 0000000..0a2bbde --- /dev/null +++ b/src/X1.Application/Features/IMSConfiguration/Commands/UpdateIMS_Configuration/UpdateIMS_ConfigurationResponse.cs @@ -0,0 +1,37 @@ +namespace CellularManagement.Application.Features.IMSConfiguration.Commands.UpdateIMS_Configuration; + +/// +/// 更新IMS配置响应 +/// +public class UpdateIMS_ConfigurationResponse +{ + /// + /// IMS配置ID + /// + public string IMS_ConfigurationId { get; set; } = null!; + + /// + /// 配置名称 + /// + public string Name { get; set; } = null!; + + /// + /// 配置内容(JSON格式) + /// + public string ConfigContent { get; set; } = null!; + + /// + /// 配置描述 + /// + public string? Description { get; set; } + + /// + /// 是否禁用 + /// + public bool IsDisabled { get; set; } + + /// + /// 更新时间 + /// + public DateTime? UpdatedAt { get; set; } +} \ No newline at end of file diff --git a/src/X1.Application/Features/IMSConfiguration/Queries/GetIMS_ConfigurationById/GetIMS_ConfigurationByIdQuery.cs b/src/X1.Application/Features/IMSConfiguration/Queries/GetIMS_ConfigurationById/GetIMS_ConfigurationByIdQuery.cs new file mode 100644 index 0000000..b38a7ed --- /dev/null +++ b/src/X1.Application/Features/IMSConfiguration/Queries/GetIMS_ConfigurationById/GetIMS_ConfigurationByIdQuery.cs @@ -0,0 +1,17 @@ +using CellularManagement.Domain.Common; +using MediatR; +using System.ComponentModel.DataAnnotations; + +namespace CellularManagement.Application.Features.IMSConfiguration.Queries.GetIMS_ConfigurationById; + +/// +/// 根据ID获取IMS配置查询 +/// +public class GetIMS_ConfigurationByIdQuery : IRequest> +{ + /// + /// IMS配置ID + /// + [Required] + public string IMS_ConfigurationId { get; set; } = null!; +} \ No newline at end of file diff --git a/src/X1.Application/Features/IMSConfiguration/Queries/GetIMS_ConfigurationById/GetIMS_ConfigurationByIdQueryHandler.cs b/src/X1.Application/Features/IMSConfiguration/Queries/GetIMS_ConfigurationById/GetIMS_ConfigurationByIdQueryHandler.cs new file mode 100644 index 0000000..1dfffaf --- /dev/null +++ b/src/X1.Application/Features/IMSConfiguration/Queries/GetIMS_ConfigurationById/GetIMS_ConfigurationByIdQueryHandler.cs @@ -0,0 +1,68 @@ +using MediatR; +using Microsoft.Extensions.Logging; +using CellularManagement.Domain.Common; +using CellularManagement.Domain.Repositories.NetworkProfile; + +namespace CellularManagement.Application.Features.IMSConfiguration.Queries.GetIMS_ConfigurationById; + +/// +/// 根据ID获取IMS配置查询处理器 +/// +public class GetIMS_ConfigurationByIdQueryHandler : IRequestHandler> +{ + private readonly IIMS_ConfigurationRepository _imsConfigurationRepository; + private readonly ILogger _logger; + + /// + /// 初始化查询处理器 + /// + public GetIMS_ConfigurationByIdQueryHandler( + IIMS_ConfigurationRepository imsConfigurationRepository, + ILogger logger) + { + _imsConfigurationRepository = imsConfigurationRepository; + _logger = logger; + } + + /// + /// 处理根据ID获取IMS配置查询 + /// + public async Task> Handle(GetIMS_ConfigurationByIdQuery request, CancellationToken cancellationToken) + { + try + { + _logger.LogInformation("开始获取IMS配置,配置ID: {IMS_ConfigurationId}", request.IMS_ConfigurationId); + + // 获取IMS配置 + var imsConfiguration = await _imsConfigurationRepository.GetIMS_ConfigurationByIdAsync(request.IMS_ConfigurationId, cancellationToken); + if (imsConfiguration == null) + { + _logger.LogWarning("IMS配置不存在: {IMS_ConfigurationId}", request.IMS_ConfigurationId); + return OperationResult.CreateFailure($"IMS配置 {request.IMS_ConfigurationId} 不存在"); + } + + // 构建响应 + var response = new GetIMS_ConfigurationByIdResponse + { + IMS_ConfigurationId = imsConfiguration.Id, + Name = imsConfiguration.Name, + ConfigContent = imsConfiguration.ConfigContent, + Description = imsConfiguration.Description, + IsDisabled = imsConfiguration.IsDisabled, + CreatedAt = imsConfiguration.CreatedAt, + UpdatedAt = imsConfiguration.UpdatedAt, + CreatedBy = imsConfiguration.CreatedBy, + UpdatedBy = imsConfiguration.UpdatedBy + }; + + _logger.LogInformation("成功获取IMS配置,配置ID: {IMS_ConfigurationId}, 配置名称: {Name}", + imsConfiguration.Id, imsConfiguration.Name); + return OperationResult.CreateSuccess(response); + } + catch (Exception ex) + { + _logger.LogError(ex, "获取IMS配置时发生错误,配置ID: {IMS_ConfigurationId}", request.IMS_ConfigurationId); + return OperationResult.CreateFailure($"获取IMS配置时发生错误: {ex.Message}"); + } + } +} \ No newline at end of file diff --git a/src/X1.Application/Features/IMSConfiguration/Queries/GetIMS_ConfigurationById/GetIMS_ConfigurationByIdResponse.cs b/src/X1.Application/Features/IMSConfiguration/Queries/GetIMS_ConfigurationById/GetIMS_ConfigurationByIdResponse.cs new file mode 100644 index 0000000..81aae3c --- /dev/null +++ b/src/X1.Application/Features/IMSConfiguration/Queries/GetIMS_ConfigurationById/GetIMS_ConfigurationByIdResponse.cs @@ -0,0 +1,52 @@ +namespace CellularManagement.Application.Features.IMSConfiguration.Queries.GetIMS_ConfigurationById; + +/// +/// 根据ID获取IMS配置响应 +/// +public class GetIMS_ConfigurationByIdResponse +{ + /// + /// IMS配置ID + /// + public string IMS_ConfigurationId { get; set; } = null!; + + /// + /// 配置名称 + /// + public string Name { get; set; } = null!; + + /// + /// 配置内容(JSON格式) + /// + public string ConfigContent { get; set; } = null!; + + /// + /// 配置描述 + /// + public string? Description { get; set; } + + /// + /// 是否禁用 + /// + public bool IsDisabled { get; set; } + + /// + /// 创建时间 + /// + public DateTime CreatedAt { get; set; } + + /// + /// 更新时间 + /// + public DateTime? UpdatedAt { get; set; } + + /// + /// 创建者 + /// + public string CreatedBy { get; set; } = null!; + + /// + /// 更新者 + /// + public string UpdatedBy { get; set; } = null!; +} \ No newline at end of file diff --git a/src/X1.Application/Features/IMSConfiguration/Queries/GetIMS_Configurations/GetIMS_ConfigurationsQuery.cs b/src/X1.Application/Features/IMSConfiguration/Queries/GetIMS_Configurations/GetIMS_ConfigurationsQuery.cs new file mode 100644 index 0000000..0a6af1a --- /dev/null +++ b/src/X1.Application/Features/IMSConfiguration/Queries/GetIMS_Configurations/GetIMS_ConfigurationsQuery.cs @@ -0,0 +1,34 @@ +using CellularManagement.Domain.Common; +using MediatR; +using System.ComponentModel.DataAnnotations; + +namespace CellularManagement.Application.Features.IMSConfiguration.Queries.GetIMS_Configurations; + +/// +/// 获取IMS配置列表查询 +/// +public class GetIMS_ConfigurationsQuery : IRequest> +{ + /// + /// 页码 + /// + [Range(1, int.MaxValue, ErrorMessage = "页码必须大于0")] + public int PageNumber { get; set; } = 1; + + /// + /// 每页数量 + /// + [Range(1, 100, ErrorMessage = "每页数量必须在1-100之间")] + public int PageSize { get; set; } = 10; + + /// + /// 搜索关键词 + /// + [MaxLength(100)] + public string? SearchTerm { get; set; } + + /// + /// 是否只获取未禁用的配置 + /// + public bool? IsDisabled { get; set; } +} \ No newline at end of file diff --git a/src/X1.Application/Features/IMSConfiguration/Queries/GetIMS_Configurations/GetIMS_ConfigurationsQueryHandler.cs b/src/X1.Application/Features/IMSConfiguration/Queries/GetIMS_Configurations/GetIMS_ConfigurationsQueryHandler.cs new file mode 100644 index 0000000..a6d8eff --- /dev/null +++ b/src/X1.Application/Features/IMSConfiguration/Queries/GetIMS_Configurations/GetIMS_ConfigurationsQueryHandler.cs @@ -0,0 +1,78 @@ +using MediatR; +using Microsoft.Extensions.Logging; +using CellularManagement.Domain.Common; +using CellularManagement.Domain.Repositories.NetworkProfile; + +namespace CellularManagement.Application.Features.IMSConfiguration.Queries.GetIMS_Configurations; + +/// +/// 获取IMS配置列表查询处理器 +/// +public class GetIMS_ConfigurationsQueryHandler : IRequestHandler> +{ + private readonly IIMS_ConfigurationRepository _imsConfigurationRepository; + private readonly ILogger _logger; + + /// + /// 初始化查询处理器 + /// + public GetIMS_ConfigurationsQueryHandler( + IIMS_ConfigurationRepository imsConfigurationRepository, + ILogger logger) + { + _imsConfigurationRepository = imsConfigurationRepository; + _logger = logger; + } + + /// + /// 处理获取IMS配置列表查询 + /// + public async Task> Handle(GetIMS_ConfigurationsQuery request, CancellationToken cancellationToken) + { + try + { + _logger.LogInformation("开始获取IMS配置列表,页码: {PageNumber}, 每页数量: {PageSize}, 搜索关键词: {SearchTerm}", + request.PageNumber, request.PageSize, request.SearchTerm ?? "无"); + + // 获取IMS配置列表 + var (totalCount, items) = await _imsConfigurationRepository.SearchIMS_ConfigurationsAsync( + request.SearchTerm, + request.PageNumber, + request.PageSize, + cancellationToken); + + // 计算总页数 + var totalPages = (int)Math.Ceiling((double)totalCount / request.PageSize); + + // 构建响应 + var response = new GetIMS_ConfigurationsResponse + { + TotalCount = totalCount, + PageNumber = request.PageNumber, + PageSize = request.PageSize, + TotalPages = totalPages, + Items = items.Select(item => new IMS_ConfigurationDto + { + IMS_ConfigurationId = item.Id, + Name = item.Name, + ConfigContent = item.ConfigContent, + Description = item.Description, + IsDisabled = item.IsDisabled, + CreatedAt = item.CreatedAt, + UpdatedAt = item.UpdatedAt, + CreatedBy = item.CreatedBy, + UpdatedBy = item.UpdatedBy + }).ToList() + }; + + _logger.LogInformation("成功获取IMS配置列表,总数量: {TotalCount}, 当前页数量: {ItemCount}", + totalCount, items.Count); + return OperationResult.CreateSuccess(response); + } + catch (Exception ex) + { + _logger.LogError(ex, "获取IMS配置列表时发生错误"); + return OperationResult.CreateFailure($"获取IMS配置列表时发生错误: {ex.Message}"); + } + } +} \ No newline at end of file diff --git a/src/X1.Application/Features/IMSConfiguration/Queries/GetIMS_Configurations/GetIMS_ConfigurationsResponse.cs b/src/X1.Application/Features/IMSConfiguration/Queries/GetIMS_Configurations/GetIMS_ConfigurationsResponse.cs new file mode 100644 index 0000000..8936ea0 --- /dev/null +++ b/src/X1.Application/Features/IMSConfiguration/Queries/GetIMS_Configurations/GetIMS_ConfigurationsResponse.cs @@ -0,0 +1,83 @@ +namespace CellularManagement.Application.Features.IMSConfiguration.Queries.GetIMS_Configurations; + +/// +/// 获取IMS配置列表响应 +/// +public class GetIMS_ConfigurationsResponse +{ + /// + /// 总数量 + /// + public int TotalCount { get; set; } + + /// + /// 当前页码 + /// + public int PageNumber { get; set; } + + /// + /// 每页数量 + /// + public int PageSize { get; set; } + + /// + /// 总页数 + /// + public int TotalPages { get; set; } + + /// + /// IMS配置列表 + /// + public List Items { get; set; } = new(); +} + +/// +/// IMS配置数据传输对象 +/// +public class IMS_ConfigurationDto +{ + /// + /// IMS配置ID + /// + public string IMS_ConfigurationId { get; set; } = null!; + + /// + /// 配置名称 + /// + public string Name { get; set; } = null!; + + /// + /// 配置内容(JSON格式) + /// + public string ConfigContent { get; set; } = null!; + + /// + /// 配置描述 + /// + public string? Description { get; set; } + + /// + /// 是否禁用 + /// + public bool IsDisabled { get; set; } + + /// + /// 创建时间 + /// + public DateTime CreatedAt { get; set; } + + /// + /// 更新时间 + /// + public DateTime ?UpdatedAt { get; set; } + + /// + /// 创建者 + /// + public string CreatedBy { get; set; } = null!; + + /// + /// 更新者 + /// + public string UpdatedBy { get; set; } = null!; +} \ No newline at end of file diff --git a/src/X1.Application/Features/NetworkConfigs/Commands/CreateNetworkConfig/CreateNetworkConfigCommandHandler.cs b/src/X1.Application/Features/NetworkConfigs/Commands/CreateNetworkConfig/CreateNetworkConfigCommandHandler.cs deleted file mode 100644 index 7fcf13e..0000000 --- a/src/X1.Application/Features/NetworkConfigs/Commands/CreateNetworkConfig/CreateNetworkConfigCommandHandler.cs +++ /dev/null @@ -1,85 +0,0 @@ -using CellularManagement.Domain.Common; -using MediatR; -using CellularManagement.Domain.Entities.Device; -using CellularManagement.Domain.Repositories.Device; -using CellularManagement.Domain.Services; -using Microsoft.Extensions.Logging; - -namespace CellularManagement.Application.Features.NetworkConfigs.Commands.CreateNetworkConfig; - -/// -/// 创建网络配置命令处理器 -/// -public class CreateNetworkConfigCommandHandler : IRequestHandler> -{ - private readonly INetworkConfigRepository _networkConfigRepository; - private readonly ICurrentUserService _currentUserService; - - private readonly ILogger _logger; - - public CreateNetworkConfigCommandHandler( - INetworkConfigRepository networkConfigRepository, - ICurrentUserService currentUserService, - ILogger logger) - { - _networkConfigRepository = networkConfigRepository; - _currentUserService = currentUserService; - _logger = logger; - } - - public async Task> Handle(CreateNetworkConfigCommand request, CancellationToken cancellationToken) - { - _logger.LogInformation("开始创建网络配置,配置名称: {Name}, 配置类型: {ConfigType}", request.Name, request.ConfigType); - - try - { - // 检查配置名称是否已存在 - if (await _networkConfigRepository.NameExistsAsync(request.Name, cancellationToken)) - { - _logger.LogWarning("配置名称已存在: {Name}", request.Name); - return OperationResult.CreateFailure($"配置名称 '{request.Name}' 已存在"); - } - - // 获取当前用户 - var currentUser = _currentUserService.GetCurrentUserId(); - if (string.IsNullOrEmpty(currentUser)) - { - _logger.LogWarning("用户未认证"); - return OperationResult.CreateFailure("用户未认证"); - } - - // 创建网络配置 - var networkConfig = NetworkConfig.Create( - request.ConfigType, - request.Name, - request.ConfigContent, - currentUser, - request.Plmn, - request.Description, - request.IsDisabled); - - // 保存到数据库 - await _networkConfigRepository.AddNetworkConfigAsync(networkConfig, cancellationToken); - - var response = new CreateNetworkConfigResponse - { - NetworkConfigId = networkConfig.Id, - Name = networkConfig.Name, - ConfigType = (int)networkConfig.ConfigType - }; - - _logger.LogInformation("成功创建网络配置,配置ID: {NetworkConfigId}", response.NetworkConfigId); - return OperationResult.CreateSuccess("网络配置创建成功", response); - } - catch (ArgumentException ex) - { - _logger.LogWarning("创建网络配置参数错误: {Message}", ex.Message); - return OperationResult.CreateFailure(ex.Message); - } - catch (Exception ex) - { - _logger.LogError(ex, "创建网络配置失败: {Message}", ex.Message); - return OperationResult.CreateFailure($"创建网络配置失败: {ex.Message}"); - } - } -} \ No newline at end of file diff --git a/src/X1.Application/Features/NetworkConfigs/Commands/CreateNetworkConfig/CreateNetworkConfigResponse.cs b/src/X1.Application/Features/NetworkConfigs/Commands/CreateNetworkConfig/CreateNetworkConfigResponse.cs deleted file mode 100644 index 3bdd0d7..0000000 --- a/src/X1.Application/Features/NetworkConfigs/Commands/CreateNetworkConfig/CreateNetworkConfigResponse.cs +++ /dev/null @@ -1,22 +0,0 @@ -namespace CellularManagement.Application.Features.NetworkConfigs.Commands.CreateNetworkConfig; - -/// -/// 创建网络配置响应 -/// -public class CreateNetworkConfigResponse -{ - /// - /// 配置ID - /// - public string NetworkConfigId { get; set; } = null!; - - /// - /// 配置名称 - /// - public string Name { get; set; } = null!; - - /// - /// 配置类型 - /// - public int ConfigType { get; set; } -} \ No newline at end of file diff --git a/src/X1.Application/Features/NetworkConfigs/Commands/DeleteNetworkConfig/DeleteNetworkConfigCommand.cs b/src/X1.Application/Features/NetworkConfigs/Commands/DeleteNetworkConfig/DeleteNetworkConfigCommand.cs deleted file mode 100644 index d880316..0000000 --- a/src/X1.Application/Features/NetworkConfigs/Commands/DeleteNetworkConfig/DeleteNetworkConfigCommand.cs +++ /dev/null @@ -1,17 +0,0 @@ -using CellularManagement.Domain.Common; -using MediatR; -using System.ComponentModel.DataAnnotations; - -namespace CellularManagement.Application.Features.NetworkConfigs.Commands.DeleteNetworkConfig; - -/// -/// 删除网络配置命令 -/// -public class DeleteNetworkConfigCommand : IRequest> -{ - /// - /// 网络配置ID - /// - [Required] - public string NetworkConfigId { get; set; } = null!; -} \ No newline at end of file diff --git a/src/X1.Application/Features/NetworkConfigs/Commands/DeleteNetworkConfig/DeleteNetworkConfigCommandHandler.cs b/src/X1.Application/Features/NetworkConfigs/Commands/DeleteNetworkConfig/DeleteNetworkConfigCommandHandler.cs deleted file mode 100644 index a61891e..0000000 --- a/src/X1.Application/Features/NetworkConfigs/Commands/DeleteNetworkConfig/DeleteNetworkConfigCommandHandler.cs +++ /dev/null @@ -1,50 +0,0 @@ -using CellularManagement.Domain.Common; -using MediatR; -using CellularManagement.Domain.Repositories.Device; -using Microsoft.Extensions.Logging; - -namespace CellularManagement.Application.Features.NetworkConfigs.Commands.DeleteNetworkConfig; - -/// -/// 删除网络配置命令处理器 -/// -public class DeleteNetworkConfigCommandHandler : IRequestHandler> -{ - private readonly INetworkConfigRepository _networkConfigRepository; - private readonly ILogger _logger; - - public DeleteNetworkConfigCommandHandler( - INetworkConfigRepository networkConfigRepository, - ILogger logger) - { - _networkConfigRepository = networkConfigRepository; - _logger = logger; - } - - public async Task> Handle(DeleteNetworkConfigCommand request, CancellationToken cancellationToken) - { - _logger.LogInformation("开始删除网络配置,配置ID: {NetworkConfigId}", request.NetworkConfigId); - - try - { - // 检查配置是否存在 - var existingConfig = await _networkConfigRepository.GetNetworkConfigByIdAsync(request.NetworkConfigId, cancellationToken); - if (existingConfig == null) - { - _logger.LogWarning("网络配置不存在,配置ID: {NetworkConfigId}", request.NetworkConfigId); - return OperationResult.CreateFailure("网络配置不存在"); - } - - // 删除网络配置 - await _networkConfigRepository.DeleteNetworkConfigAsync(request.NetworkConfigId, cancellationToken); - - _logger.LogInformation("成功删除网络配置,配置ID: {NetworkConfigId}", request.NetworkConfigId); - return OperationResult.CreateSuccess("网络配置删除成功", true); - } - catch (Exception ex) - { - _logger.LogError(ex, "删除网络配置失败,配置ID: {NetworkConfigId}, 错误: {Message}", request.NetworkConfigId, ex.Message); - return OperationResult.CreateFailure($"删除网络配置失败: {ex.Message}"); - } - } -} \ No newline at end of file diff --git a/src/X1.Application/Features/NetworkConfigs/Commands/UpdateNetworkConfig/UpdateNetworkConfigCommandHandler.cs b/src/X1.Application/Features/NetworkConfigs/Commands/UpdateNetworkConfig/UpdateNetworkConfigCommandHandler.cs deleted file mode 100644 index a953b5a..0000000 --- a/src/X1.Application/Features/NetworkConfigs/Commands/UpdateNetworkConfig/UpdateNetworkConfigCommandHandler.cs +++ /dev/null @@ -1,91 +0,0 @@ -using CellularManagement.Domain.Common; -using MediatR; -using CellularManagement.Domain.Entities.Device; -using CellularManagement.Domain.Repositories.Device; -using CellularManagement.Domain.Services; -using Microsoft.Extensions.Logging; - -namespace CellularManagement.Application.Features.NetworkConfigs.Commands.UpdateNetworkConfig; - -/// -/// 更新网络配置命令处理器 -/// -public class UpdateNetworkConfigCommandHandler : IRequestHandler> -{ - private readonly INetworkConfigRepository _networkConfigRepository; - private readonly ICurrentUserService _currentUserService; - private readonly ILogger _logger; - - public UpdateNetworkConfigCommandHandler( - INetworkConfigRepository networkConfigRepository, - ICurrentUserService currentUserService, - ILogger logger) - { - _networkConfigRepository = networkConfigRepository; - _currentUserService = currentUserService; - _logger = logger; - } - - public async Task> Handle(UpdateNetworkConfigCommand request, CancellationToken cancellationToken) - { - _logger.LogInformation("开始更新网络配置,配置ID: {NetworkConfigId}", request.NetworkConfigId); - - try - { - // 检查配置是否存在 - var existingConfig = await _networkConfigRepository.GetNetworkConfigByIdAsync(request.NetworkConfigId, cancellationToken); - if (existingConfig == null) - { - _logger.LogWarning("网络配置不存在,配置ID: {NetworkConfigId}", request.NetworkConfigId); - return OperationResult.CreateFailure("网络配置不存在"); - } - - // 检查配置名称是否已存在(排除当前配置) - if (await _networkConfigRepository.NameExistsAsync(request.Name, request.NetworkConfigId, cancellationToken)) - { - _logger.LogWarning("配置名称已存在: {Name}", request.Name); - return OperationResult.CreateFailure($"配置名称 '{request.Name}' 已存在"); - } - - // 获取当前用户 - var currentUser = _currentUserService.GetCurrentUserId(); - if (string.IsNullOrEmpty(currentUser)) - { - _logger.LogWarning("用户未认证"); - return OperationResult.CreateFailure("用户未认证"); - } - - // 更新网络配置 - existingConfig.Update( - request.Name, - request.ConfigContent, - currentUser, - request.Plmn, - request.Description, - request.IsDisabled); - - // 保存到数据库 - _networkConfigRepository.UpdateNetworkConfig(existingConfig); - - var response = new UpdateNetworkConfigResponse - { - NetworkConfigId = existingConfig.Id, - Name = existingConfig.Name, - ConfigType = (int)existingConfig.ConfigType - }; - - _logger.LogInformation("成功更新网络配置,配置ID: {NetworkConfigId}", response.NetworkConfigId); - return OperationResult.CreateSuccess("网络配置更新成功", response); - } - catch (ArgumentException ex) - { - _logger.LogWarning("更新网络配置参数错误: {Message}", ex.Message); - return OperationResult.CreateFailure(ex.Message); - } - catch (Exception ex) - { - _logger.LogError(ex, "更新网络配置失败: {Message}", ex.Message); - return OperationResult.CreateFailure($"更新网络配置失败: {ex.Message}"); - } - } -} \ No newline at end of file diff --git a/src/X1.Application/Features/NetworkConfigs/Commands/UpdateNetworkConfig/UpdateNetworkConfigResponse.cs b/src/X1.Application/Features/NetworkConfigs/Commands/UpdateNetworkConfig/UpdateNetworkConfigResponse.cs deleted file mode 100644 index 9dd40a3..0000000 --- a/src/X1.Application/Features/NetworkConfigs/Commands/UpdateNetworkConfig/UpdateNetworkConfigResponse.cs +++ /dev/null @@ -1,22 +0,0 @@ -namespace CellularManagement.Application.Features.NetworkConfigs.Commands.UpdateNetworkConfig; - -/// -/// 更新网络配置响应 -/// -public class UpdateNetworkConfigResponse -{ - /// - /// 配置ID - /// - public string NetworkConfigId { get; set; } = null!; - - /// - /// 配置名称 - /// - public string Name { get; set; } = null!; - - /// - /// 配置类型 - /// - public int ConfigType { get; set; } -} \ No newline at end of file diff --git a/src/X1.Application/Features/NetworkConfigs/Queries/GetNetworkConfigById/GetNetworkConfigByIdQuery.cs b/src/X1.Application/Features/NetworkConfigs/Queries/GetNetworkConfigById/GetNetworkConfigByIdQuery.cs deleted file mode 100644 index 3bc40c2..0000000 --- a/src/X1.Application/Features/NetworkConfigs/Queries/GetNetworkConfigById/GetNetworkConfigByIdQuery.cs +++ /dev/null @@ -1,17 +0,0 @@ -using CellularManagement.Domain.Common; -using MediatR; -using System.ComponentModel.DataAnnotations; - -namespace CellularManagement.Application.Features.NetworkConfigs.Queries.GetNetworkConfigById; - -/// -/// 根据ID获取网络配置查询 -/// -public class GetNetworkConfigByIdQuery : IRequest> -{ - /// - /// 网络配置ID - /// - [Required] - public string NetworkConfigId { get; set; } = null!; -} \ No newline at end of file diff --git a/src/X1.Application/Features/NetworkConfigs/Queries/GetNetworkConfigById/GetNetworkConfigByIdQueryHandler.cs b/src/X1.Application/Features/NetworkConfigs/Queries/GetNetworkConfigById/GetNetworkConfigByIdQueryHandler.cs deleted file mode 100644 index c069dbf..0000000 --- a/src/X1.Application/Features/NetworkConfigs/Queries/GetNetworkConfigById/GetNetworkConfigByIdQueryHandler.cs +++ /dev/null @@ -1,63 +0,0 @@ -using CellularManagement.Domain.Common; -using MediatR; -using CellularManagement.Domain.Entities.Device; -using CellularManagement.Domain.Repositories.Device; -using Microsoft.Extensions.Logging; - -namespace CellularManagement.Application.Features.NetworkConfigs.Queries.GetNetworkConfigById; - -/// -/// 根据ID获取网络配置查询处理器 -/// -public class GetNetworkConfigByIdQueryHandler : IRequestHandler> -{ - private readonly INetworkConfigRepository _networkConfigRepository; - private readonly ILogger _logger; - - public GetNetworkConfigByIdQueryHandler( - INetworkConfigRepository networkConfigRepository, - ILogger logger) - { - _networkConfigRepository = networkConfigRepository; - _logger = logger; - } - - public async Task> Handle(GetNetworkConfigByIdQuery request, CancellationToken cancellationToken) - { - _logger.LogInformation("开始获取网络配置详情,配置ID: {NetworkConfigId}", request.NetworkConfigId); - - try - { - var networkConfig = await _networkConfigRepository.GetNetworkConfigByIdAsync(request.NetworkConfigId, cancellationToken); - - if (networkConfig == null) - { - _logger.LogWarning("网络配置不存在,配置ID: {NetworkConfigId}", request.NetworkConfigId); - return OperationResult.CreateFailure("网络配置不存在"); - } - - var response = new GetNetworkConfigByIdResponse - { - Id = networkConfig.Id, - ConfigType = networkConfig.ConfigType, - Name = networkConfig.Name, - Plmn = networkConfig.Plmn, - ConfigContent = networkConfig.ConfigContent, - Description = networkConfig.Description, - IsDisabled = networkConfig.IsDisabled, - CreatedAt = networkConfig.CreatedAt, - UpdatedAt = networkConfig.UpdatedAt, - CreatedBy = networkConfig.CreatedBy, - UpdatedBy = networkConfig.UpdatedBy - }; - - _logger.LogInformation("成功获取网络配置详情,配置ID: {NetworkConfigId}", request.NetworkConfigId); - return OperationResult.CreateSuccess("获取网络配置详情成功", response); - } - catch (Exception ex) - { - _logger.LogError(ex, "获取网络配置详情失败,配置ID: {NetworkConfigId}, 错误: {Message}", request.NetworkConfigId, ex.Message); - return OperationResult.CreateFailure($"获取网络配置详情失败: {ex.Message}"); - } - } -} \ No newline at end of file diff --git a/src/X1.Application/Features/NetworkConfigs/Queries/GetNetworkConfigs/GetNetworkConfigsQuery.cs b/src/X1.Application/Features/NetworkConfigs/Queries/GetNetworkConfigs/GetNetworkConfigsQuery.cs deleted file mode 100644 index 201473c..0000000 --- a/src/X1.Application/Features/NetworkConfigs/Queries/GetNetworkConfigs/GetNetworkConfigsQuery.cs +++ /dev/null @@ -1,46 +0,0 @@ -using CellularManagement.Domain.Common; -using MediatR; -using CellularManagement.Domain.Entities.Device; -using System.ComponentModel.DataAnnotations; - -namespace CellularManagement.Application.Features.NetworkConfigs.Queries.GetNetworkConfigs; - -/// -/// 获取网络配置列表查询 -/// -public class GetNetworkConfigsQuery : IRequest> -{ - /// - /// 页码 - /// - [Range(1, int.MaxValue, ErrorMessage = "页码必须大于0")] - public int PageNumber { get; set; } = 1; - - /// - /// 每页数量 - /// - [Range(1, 100, ErrorMessage = "每页数量必须在1-100之间")] - public int PageSize { get; set; } = 10; - - /// - /// 配置类型(可选) - /// - public NetworkConfigType? ConfigType { get; set; } - - /// - /// PLMN(可选) - /// - [MaxLength(10)] - public string? Plmn { get; set; } - - /// - /// 是否只获取启用的配置 - /// - public bool? OnlyEnabled { get; set; } - - /// - /// 搜索关键词 - /// - [MaxLength(100)] - public string? Keyword { get; set; } -} \ No newline at end of file diff --git a/src/X1.Application/Features/NetworkConfigs/Queries/GetNetworkConfigs/GetNetworkConfigsQueryHandler.cs b/src/X1.Application/Features/NetworkConfigs/Queries/GetNetworkConfigs/GetNetworkConfigsQueryHandler.cs deleted file mode 100644 index aae0746..0000000 --- a/src/X1.Application/Features/NetworkConfigs/Queries/GetNetworkConfigs/GetNetworkConfigsQueryHandler.cs +++ /dev/null @@ -1,106 +0,0 @@ -using CellularManagement.Domain.Common; -using MediatR; -using CellularManagement.Domain.Entities.Device; -using CellularManagement.Domain.Repositories.Device; -using Microsoft.Extensions.Logging; - -namespace CellularManagement.Application.Features.NetworkConfigs.Queries.GetNetworkConfigs; - -/// -/// 获取网络配置列表查询处理器 -/// -public class GetNetworkConfigsQueryHandler : IRequestHandler> -{ - private readonly INetworkConfigRepository _networkConfigRepository; - - private readonly ILogger _logger; - - public GetNetworkConfigsQueryHandler( - INetworkConfigRepository networkConfigRepository, - ILogger logger) - { - _networkConfigRepository = networkConfigRepository; - _logger = logger; - } - - public async Task> Handle(GetNetworkConfigsQuery request, CancellationToken cancellationToken) - { - _logger.LogInformation("开始获取网络配置列表,页码: {PageNumber}, 每页数量: {PageSize}, 搜索关键词: {Keyword}, 配置类型: {ConfigType}, PLMN: {Plmn}, 是否启用: {OnlyEnabled}", - request.PageNumber, request.PageSize, request.Keyword, request.ConfigType, request.Plmn, request.OnlyEnabled); - - try - { - IList networkConfigs; - - // 根据查询条件获取配置 - if (!string.IsNullOrWhiteSpace(request.Keyword)) - { - // 使用搜索功能 - networkConfigs = await _networkConfigRepository.SearchNetworkConfigsAsync( - request.Keyword, request.ConfigType, request.Plmn, cancellationToken); - } - else if (request.OnlyEnabled == true) - { - networkConfigs = await _networkConfigRepository.GetEnabledNetworkConfigsAsync(cancellationToken); - } - else if (request.ConfigType.HasValue && !string.IsNullOrEmpty(request.Plmn)) - { - networkConfigs = await _networkConfigRepository.GetNetworkConfigsByTypeAndPlmnAsync( - request.ConfigType.Value, request.Plmn, cancellationToken); - } - else if (request.ConfigType.HasValue) - { - networkConfigs = await _networkConfigRepository.GetNetworkConfigsByTypeAsync( - request.ConfigType.Value, cancellationToken); - } - else if (!string.IsNullOrEmpty(request.Plmn)) - { - networkConfigs = await _networkConfigRepository.GetNetworkConfigsByPlmnAsync( - request.Plmn, cancellationToken); - } - else - { - networkConfigs = await _networkConfigRepository.GetAllNetworkConfigsAsync(cancellationToken); - } - - // 转换为DTO - var networkConfigDtos = networkConfigs.Select(config => new NetworkConfigDto - { - Id = config.Id, - ConfigType = config.ConfigType, - Name = config.Name, - Plmn = config.Plmn, - ConfigContent = config.ConfigContent, - Description = config.Description, - IsDisabled = config.IsDisabled, - CreatedAt = config.CreatedAt, - UpdatedAt = config.UpdatedAt, - CreatedBy = config.CreatedBy, - UpdatedBy = config.UpdatedBy - }).ToList(); - - // 计算分页信息 - var totalCount = networkConfigDtos.Count; - var totalPages = (int)Math.Ceiling((double)totalCount / request.PageSize); - var skip = (request.PageNumber - 1) * request.PageSize; - var pagedConfigs = networkConfigDtos.Skip(skip).Take(request.PageSize).ToList(); - - var response = new GetNetworkConfigsResponse - { - NetworkConfigs = pagedConfigs, - TotalCount = totalCount, - PageNumber = request.PageNumber, - PageSize = request.PageSize, - TotalPages = totalPages - }; - - _logger.LogInformation("成功获取网络配置列表,共 {Count} 条记录", totalCount); - return OperationResult.CreateSuccess("获取网络配置列表成功", response); - } - catch (Exception ex) - { - _logger.LogError(ex, "获取网络配置列表失败: {Message}", ex.Message); - return OperationResult.CreateFailure($"获取网络配置列表失败: {ex.Message}"); - } - } -} \ No newline at end of file diff --git a/src/X1.Application/Features/NetworkStackConfigs/Commands/CreateNetworkStackConfig/CreateNetworkStackConfigCommand.cs b/src/X1.Application/Features/NetworkStackConfigs/Commands/CreateNetworkStackConfig/CreateNetworkStackConfigCommand.cs new file mode 100644 index 0000000..a3ca6e5 --- /dev/null +++ b/src/X1.Application/Features/NetworkStackConfigs/Commands/CreateNetworkStackConfig/CreateNetworkStackConfigCommand.cs @@ -0,0 +1,35 @@ +using CellularManagement.Domain.Common; +using MediatR; +using System.ComponentModel.DataAnnotations; + +namespace CellularManagement.Application.Features.NetworkStackConfigs.Commands.CreateNetworkStackConfig; + +/// +/// 创建网络栈配置命令 +/// +public class CreateNetworkStackConfigCommand : IRequest> +{ + /// + /// 栈ID(主键) + /// + [Required(ErrorMessage = "栈ID不能为空")] + [MaxLength(50, ErrorMessage = "栈ID不能超过50个字符")] + public string StackId { get; set; } = null!; + + /// + /// RAN配置ID(外键,可为空) + /// + [MaxLength(50, ErrorMessage = "RAN配置ID不能超过50个字符")] + public string? RanId { get; set; } + + /// + /// 描述 + /// + [MaxLength(500, ErrorMessage = "描述不能超过500个字符")] + public string? Description { get; set; } + + /// + /// 是否激活 + /// + public bool IsActive { get; set; } = true; +} \ No newline at end of file diff --git a/src/X1.Application/Features/NetworkStackConfigs/Commands/CreateNetworkStackConfig/CreateNetworkStackConfigCommandHandler.cs b/src/X1.Application/Features/NetworkStackConfigs/Commands/CreateNetworkStackConfig/CreateNetworkStackConfigCommandHandler.cs new file mode 100644 index 0000000..ec69f6a --- /dev/null +++ b/src/X1.Application/Features/NetworkStackConfigs/Commands/CreateNetworkStackConfig/CreateNetworkStackConfigCommandHandler.cs @@ -0,0 +1,95 @@ +using MediatR; +using Microsoft.Extensions.Logging; +using CellularManagement.Domain.Common; +using CellularManagement.Domain.Repositories.NetworkProfile; +using CellularManagement.Domain.Repositories.Base; +using CellularManagement.Domain.Services; +using CellularManagement.Domain.Entities.NetworkProfile; + +namespace CellularManagement.Application.Features.NetworkStackConfigs.Commands.CreateNetworkStackConfig; + +/// +/// 创建网络栈配置命令处理器 +/// +public class CreateNetworkStackConfigCommandHandler : IRequestHandler> +{ + private readonly INetworkStackConfigRepository _networkStackConfigRepository; + private readonly ILogger _logger; + private readonly IUnitOfWork _unitOfWork; + private readonly ICurrentUserService _currentUserService; + + /// + /// 初始化命令处理器 + /// + public CreateNetworkStackConfigCommandHandler( + INetworkStackConfigRepository networkStackConfigRepository, + ILogger logger, + IUnitOfWork unitOfWork, + ICurrentUserService currentUserService) + { + _networkStackConfigRepository = networkStackConfigRepository; + _logger = logger; + _unitOfWork = unitOfWork; + _currentUserService = currentUserService; + } + + /// + /// 处理创建网络栈配置命令 + /// + public async Task> Handle(CreateNetworkStackConfigCommand request, CancellationToken cancellationToken) + { + try + { + _logger.LogInformation("开始创建网络栈配置,栈ID: {StackId}", request.StackId); + + // 检查栈ID是否已存在 + if (await _networkStackConfigRepository.StackIdExistsAsync(request.StackId, cancellationToken)) + { + _logger.LogWarning("网络栈配置栈ID已存在: {StackId}", request.StackId); + return OperationResult.CreateFailure($"网络栈配置栈ID {request.StackId} 已存在"); + } + + // 获取当前用户ID + var currentUserId = _currentUserService.GetCurrentUserId(); + if (string.IsNullOrEmpty(currentUserId)) + { + _logger.LogError("无法获取当前用户ID,用户可能未认证"); + return OperationResult.CreateFailure("用户未认证,无法创建网络栈配置"); + } + + // 创建网络栈配置实体 + var networkStackConfig = NetworkStackConfig.Create( + stackId: request.StackId, + createdBy: currentUserId, + ranId: request.RanId, + description: request.Description, + isActive: request.IsActive); + + // 保存网络栈配置 + await _networkStackConfigRepository.AddNetworkStackConfigAsync(networkStackConfig, cancellationToken); + + // 保存更改到数据库 + await _unitOfWork.SaveChangesAsync(cancellationToken); + + // 构建响应 + var response = new CreateNetworkStackConfigResponse + { + NetworkStackConfigId = networkStackConfig.Id, + StackId = networkStackConfig.StackId, + RanId = networkStackConfig.RanId, + Description = networkStackConfig.Description, + IsActive = networkStackConfig.IsActive, + CreatedAt = networkStackConfig.CreatedAt + }; + + _logger.LogInformation("网络栈配置创建成功,配置ID: {NetworkStackConfigId}, 栈ID: {StackId}", + networkStackConfig.Id, networkStackConfig.StackId); + return OperationResult.CreateSuccess(response); + } + catch (Exception ex) + { + _logger.LogError(ex, "创建网络栈配置时发生错误,栈ID: {StackId}", request.StackId); + return OperationResult.CreateFailure($"创建网络栈配置时发生错误: {ex.Message}"); + } + } +} \ No newline at end of file diff --git a/src/X1.Application/Features/NetworkStackConfigs/Commands/CreateNetworkStackConfig/CreateNetworkStackConfigResponse.cs b/src/X1.Application/Features/NetworkStackConfigs/Commands/CreateNetworkStackConfig/CreateNetworkStackConfigResponse.cs new file mode 100644 index 0000000..fecf189 --- /dev/null +++ b/src/X1.Application/Features/NetworkStackConfigs/Commands/CreateNetworkStackConfig/CreateNetworkStackConfigResponse.cs @@ -0,0 +1,37 @@ +namespace CellularManagement.Application.Features.NetworkStackConfigs.Commands.CreateNetworkStackConfig; + +/// +/// 创建网络栈配置响应 +/// +public class CreateNetworkStackConfigResponse +{ + /// + /// 网络栈配置ID + /// + public string NetworkStackConfigId { get; set; } = null!; + + /// + /// 栈ID(主键) + /// + public string StackId { get; set; } = null!; + + /// + /// RAN配置ID(外键,可为空) + /// + public string? RanId { get; set; } + + /// + /// 描述 + /// + public string? Description { get; set; } + + /// + /// 是否激活 + /// + public bool IsActive { get; set; } + + /// + /// 创建时间 + /// + public DateTime CreatedAt { get; set; } +} \ No newline at end of file diff --git a/src/X1.Application/Features/NetworkStackConfigs/Commands/DeleteNetworkStackConfig/DeleteNetworkStackConfigCommand.cs b/src/X1.Application/Features/NetworkStackConfigs/Commands/DeleteNetworkStackConfig/DeleteNetworkStackConfigCommand.cs new file mode 100644 index 0000000..3b96c53 --- /dev/null +++ b/src/X1.Application/Features/NetworkStackConfigs/Commands/DeleteNetworkStackConfig/DeleteNetworkStackConfigCommand.cs @@ -0,0 +1,17 @@ +using CellularManagement.Domain.Common; +using MediatR; +using System.ComponentModel.DataAnnotations; + +namespace CellularManagement.Application.Features.NetworkStackConfigs.Commands.DeleteNetworkStackConfig; + +/// +/// 删除网络栈配置命令 +/// +public class DeleteNetworkStackConfigCommand : IRequest> +{ + /// + /// 网络栈配置ID + /// + [Required] + public string NetworkStackConfigId { get; set; } = null!; +} \ No newline at end of file diff --git a/src/X1.Application/Features/NetworkStackConfigs/Commands/DeleteNetworkStackConfig/DeleteNetworkStackConfigCommandHandler.cs b/src/X1.Application/Features/NetworkStackConfigs/Commands/DeleteNetworkStackConfig/DeleteNetworkStackConfigCommandHandler.cs new file mode 100644 index 0000000..be020c9 --- /dev/null +++ b/src/X1.Application/Features/NetworkStackConfigs/Commands/DeleteNetworkStackConfig/DeleteNetworkStackConfigCommandHandler.cs @@ -0,0 +1,64 @@ +using MediatR; +using Microsoft.Extensions.Logging; +using CellularManagement.Domain.Common; +using CellularManagement.Domain.Repositories.NetworkProfile; +using CellularManagement.Domain.Repositories.Base; + +namespace CellularManagement.Application.Features.NetworkStackConfigs.Commands.DeleteNetworkStackConfig; + +/// +/// 删除网络栈配置命令处理器 +/// +public class DeleteNetworkStackConfigCommandHandler : IRequestHandler> +{ + private readonly INetworkStackConfigRepository _networkStackConfigRepository; + private readonly ILogger _logger; + private readonly IUnitOfWork _unitOfWork; + + /// + /// 初始化命令处理器 + /// + public DeleteNetworkStackConfigCommandHandler( + INetworkStackConfigRepository networkStackConfigRepository, + ILogger logger, + IUnitOfWork unitOfWork) + { + _networkStackConfigRepository = networkStackConfigRepository; + _logger = logger; + _unitOfWork = unitOfWork; + } + + /// + /// 处理删除网络栈配置命令 + /// + public async Task> Handle(DeleteNetworkStackConfigCommand request, CancellationToken cancellationToken) + { + try + { + _logger.LogInformation("开始删除网络栈配置,配置ID: {NetworkStackConfigId}", request.NetworkStackConfigId); + + // 检查网络栈配置是否存在 + var existingConfig = await _networkStackConfigRepository.GetNetworkStackConfigByIdAsync(request.NetworkStackConfigId, cancellationToken); + if (existingConfig == null) + { + _logger.LogWarning("网络栈配置不存在: {NetworkStackConfigId}", request.NetworkStackConfigId); + return OperationResult.CreateFailure($"网络栈配置 {request.NetworkStackConfigId} 不存在"); + } + + // 删除网络栈配置 + await _networkStackConfigRepository.DeleteNetworkStackConfigAsync(request.NetworkStackConfigId, cancellationToken); + + // 保存更改到数据库 + await _unitOfWork.SaveChangesAsync(cancellationToken); + + _logger.LogInformation("网络栈配置删除成功,配置ID: {NetworkStackConfigId}, 栈ID: {StackId}", + request.NetworkStackConfigId, existingConfig.StackId); + return OperationResult.CreateSuccess(true); + } + catch (Exception ex) + { + _logger.LogError(ex, "删除网络栈配置时发生错误,配置ID: {NetworkStackConfigId}", request.NetworkStackConfigId); + return OperationResult.CreateFailure($"删除网络栈配置时发生错误: {ex.Message}"); + } + } +} \ No newline at end of file diff --git a/src/X1.Application/Features/NetworkStackConfigs/Commands/UpdateNetworkStackConfig/UpdateNetworkStackConfigCommand.cs b/src/X1.Application/Features/NetworkStackConfigs/Commands/UpdateNetworkStackConfig/UpdateNetworkStackConfigCommand.cs new file mode 100644 index 0000000..386e618 --- /dev/null +++ b/src/X1.Application/Features/NetworkStackConfigs/Commands/UpdateNetworkStackConfig/UpdateNetworkStackConfigCommand.cs @@ -0,0 +1,34 @@ +using CellularManagement.Domain.Common; +using MediatR; +using System.ComponentModel.DataAnnotations; + +namespace CellularManagement.Application.Features.NetworkStackConfigs.Commands.UpdateNetworkStackConfig; + +/// +/// 更新网络栈配置命令 +/// +public class UpdateNetworkStackConfigCommand : IRequest> +{ + /// + /// 网络栈配置ID + /// + [Required] + public string NetworkStackConfigId { get; set; } = null!; + + /// + /// RAN配置ID(外键,可为空) + /// + [MaxLength(50, ErrorMessage = "RAN配置ID不能超过50个字符")] + public string? RanId { get; set; } + + /// + /// 描述 + /// + [MaxLength(500, ErrorMessage = "描述不能超过500个字符")] + public string? Description { get; set; } + + /// + /// 是否激活 + /// + public bool IsActive { get; set; } = true; +} \ No newline at end of file diff --git a/src/X1.Application/Features/NetworkStackConfigs/Commands/UpdateNetworkStackConfig/UpdateNetworkStackConfigCommandHandler.cs b/src/X1.Application/Features/NetworkStackConfigs/Commands/UpdateNetworkStackConfig/UpdateNetworkStackConfigCommandHandler.cs new file mode 100644 index 0000000..e2c4b45 --- /dev/null +++ b/src/X1.Application/Features/NetworkStackConfigs/Commands/UpdateNetworkStackConfig/UpdateNetworkStackConfigCommandHandler.cs @@ -0,0 +1,93 @@ +using MediatR; +using Microsoft.Extensions.Logging; +using CellularManagement.Domain.Common; +using CellularManagement.Domain.Repositories.NetworkProfile; +using CellularManagement.Domain.Repositories.Base; +using CellularManagement.Domain.Services; +using CellularManagement.Domain.Entities.NetworkProfile; + +namespace CellularManagement.Application.Features.NetworkStackConfigs.Commands.UpdateNetworkStackConfig; + +/// +/// 更新网络栈配置命令处理器 +/// +public class UpdateNetworkStackConfigCommandHandler : IRequestHandler> +{ + private readonly INetworkStackConfigRepository _networkStackConfigRepository; + private readonly ILogger _logger; + private readonly IUnitOfWork _unitOfWork; + private readonly ICurrentUserService _currentUserService; + + /// + /// 初始化命令处理器 + /// + public UpdateNetworkStackConfigCommandHandler( + INetworkStackConfigRepository networkStackConfigRepository, + ILogger logger, + IUnitOfWork unitOfWork, + ICurrentUserService currentUserService) + { + _networkStackConfigRepository = networkStackConfigRepository; + _logger = logger; + _unitOfWork = unitOfWork; + _currentUserService = currentUserService; + } + + /// + /// 处理更新网络栈配置命令 + /// + public async Task> Handle(UpdateNetworkStackConfigCommand request, CancellationToken cancellationToken) + { + try + { + _logger.LogInformation("开始更新网络栈配置,配置ID: {NetworkStackConfigId}", request.NetworkStackConfigId); + + // 检查网络栈配置是否存在 + var existingConfig = await _networkStackConfigRepository.GetNetworkStackConfigByIdAsync(request.NetworkStackConfigId, cancellationToken); + if (existingConfig == null) + { + _logger.LogWarning("网络栈配置不存在: {NetworkStackConfigId}", request.NetworkStackConfigId); + return OperationResult.CreateFailure($"网络栈配置 {request.NetworkStackConfigId} 不存在"); + } + + // 获取当前用户ID + var currentUserId = _currentUserService.GetCurrentUserId(); + if (string.IsNullOrEmpty(currentUserId)) + { + _logger.LogError("无法获取当前用户ID,用户可能未认证"); + return OperationResult.CreateFailure("用户未认证,无法更新网络栈配置"); + } + + // 更新网络栈配置 + existingConfig.Update( + updatedBy: currentUserId, + ranId: request.RanId, + description: request.Description, + isActive: request.IsActive); + + // 保存更改 + _networkStackConfigRepository.UpdateNetworkStackConfig(existingConfig); + await _unitOfWork.SaveChangesAsync(cancellationToken); + + // 构建响应 + var response = new UpdateNetworkStackConfigResponse + { + NetworkStackConfigId = existingConfig.Id, + StackId = existingConfig.StackId, + RanId = existingConfig.RanId, + Description = existingConfig.Description, + IsActive = existingConfig.IsActive, + UpdatedAt = existingConfig.UpdatedAt + }; + + _logger.LogInformation("网络栈配置更新成功,配置ID: {NetworkStackConfigId}, 栈ID: {StackId}", + existingConfig.Id, existingConfig.StackId); + return OperationResult.CreateSuccess(response); + } + catch (Exception ex) + { + _logger.LogError(ex, "更新网络栈配置时发生错误,配置ID: {NetworkStackConfigId}", request.NetworkStackConfigId); + return OperationResult.CreateFailure($"更新网络栈配置时发生错误: {ex.Message}"); + } + } +} \ No newline at end of file diff --git a/src/X1.Application/Features/NetworkStackConfigs/Commands/UpdateNetworkStackConfig/UpdateNetworkStackConfigResponse.cs b/src/X1.Application/Features/NetworkStackConfigs/Commands/UpdateNetworkStackConfig/UpdateNetworkStackConfigResponse.cs new file mode 100644 index 0000000..3b601bd --- /dev/null +++ b/src/X1.Application/Features/NetworkStackConfigs/Commands/UpdateNetworkStackConfig/UpdateNetworkStackConfigResponse.cs @@ -0,0 +1,37 @@ +namespace CellularManagement.Application.Features.NetworkStackConfigs.Commands.UpdateNetworkStackConfig; + +/// +/// 更新网络栈配置响应 +/// +public class UpdateNetworkStackConfigResponse +{ + /// + /// 网络栈配置ID + /// + public string NetworkStackConfigId { get; set; } = null!; + + /// + /// 栈ID(主键) + /// + public string StackId { get; set; } = null!; + + /// + /// RAN配置ID(外键,可为空) + /// + public string? RanId { get; set; } + + /// + /// 描述 + /// + public string? Description { get; set; } + + /// + /// 是否激活 + /// + public bool IsActive { get; set; } + + /// + /// 更新时间 + /// + public DateTime? UpdatedAt { get; set; } +} \ No newline at end of file diff --git a/src/X1.Application/Features/NetworkStackConfigs/Queries/GetNetworkStackConfigById/GetNetworkStackConfigByIdQuery.cs b/src/X1.Application/Features/NetworkStackConfigs/Queries/GetNetworkStackConfigById/GetNetworkStackConfigByIdQuery.cs new file mode 100644 index 0000000..734c71c --- /dev/null +++ b/src/X1.Application/Features/NetworkStackConfigs/Queries/GetNetworkStackConfigById/GetNetworkStackConfigByIdQuery.cs @@ -0,0 +1,17 @@ +using CellularManagement.Domain.Common; +using MediatR; +using System.ComponentModel.DataAnnotations; + +namespace CellularManagement.Application.Features.NetworkStackConfigs.Queries.GetNetworkStackConfigById; + +/// +/// 根据ID获取网络栈配置查询 +/// +public class GetNetworkStackConfigByIdQuery : IRequest> +{ + /// + /// 网络栈配置ID + /// + [Required] + public string NetworkStackConfigId { get; set; } = null!; +} \ No newline at end of file diff --git a/src/X1.Application/Features/NetworkStackConfigs/Queries/GetNetworkStackConfigById/GetNetworkStackConfigByIdQueryHandler.cs b/src/X1.Application/Features/NetworkStackConfigs/Queries/GetNetworkStackConfigById/GetNetworkStackConfigByIdQueryHandler.cs new file mode 100644 index 0000000..b0f2ac1 --- /dev/null +++ b/src/X1.Application/Features/NetworkStackConfigs/Queries/GetNetworkStackConfigById/GetNetworkStackConfigByIdQueryHandler.cs @@ -0,0 +1,68 @@ +using MediatR; +using Microsoft.Extensions.Logging; +using CellularManagement.Domain.Common; +using CellularManagement.Domain.Repositories.NetworkProfile; + +namespace CellularManagement.Application.Features.NetworkStackConfigs.Queries.GetNetworkStackConfigById; + +/// +/// 根据ID获取网络栈配置查询处理器 +/// +public class GetNetworkStackConfigByIdQueryHandler : IRequestHandler> +{ + private readonly INetworkStackConfigRepository _networkStackConfigRepository; + private readonly ILogger _logger; + + /// + /// 初始化查询处理器 + /// + public GetNetworkStackConfigByIdQueryHandler( + INetworkStackConfigRepository networkStackConfigRepository, + ILogger logger) + { + _networkStackConfigRepository = networkStackConfigRepository; + _logger = logger; + } + + /// + /// 处理根据ID获取网络栈配置查询 + /// + public async Task> Handle(GetNetworkStackConfigByIdQuery request, CancellationToken cancellationToken) + { + try + { + _logger.LogInformation("开始获取网络栈配置,配置ID: {NetworkStackConfigId}", request.NetworkStackConfigId); + + // 获取网络栈配置 + var networkStackConfig = await _networkStackConfigRepository.GetNetworkStackConfigByIdAsync(request.NetworkStackConfigId, cancellationToken); + if (networkStackConfig == null) + { + _logger.LogWarning("网络栈配置不存在: {NetworkStackConfigId}", request.NetworkStackConfigId); + return OperationResult.CreateFailure($"网络栈配置 {request.NetworkStackConfigId} 不存在"); + } + + // 构建响应 + var response = new GetNetworkStackConfigByIdResponse + { + NetworkStackConfigId = networkStackConfig.Id, + StackId = networkStackConfig.StackId, + RanId = networkStackConfig.RanId, + Description = networkStackConfig.Description, + IsActive = networkStackConfig.IsActive, + CreatedAt = networkStackConfig.CreatedAt, + UpdatedAt = networkStackConfig.UpdatedAt, + CreatedBy = networkStackConfig.CreatedBy, + UpdatedBy = networkStackConfig.UpdatedBy + }; + + _logger.LogInformation("成功获取网络栈配置,配置ID: {NetworkStackConfigId}, 栈ID: {StackId}", + networkStackConfig.Id, networkStackConfig.StackId); + return OperationResult.CreateSuccess(response); + } + catch (Exception ex) + { + _logger.LogError(ex, "获取网络栈配置时发生错误,配置ID: {NetworkStackConfigId}", request.NetworkStackConfigId); + return OperationResult.CreateFailure($"获取网络栈配置时发生错误: {ex.Message}"); + } + } +} \ No newline at end of file diff --git a/src/X1.Application/Features/NetworkStackConfigs/Queries/GetNetworkStackConfigById/GetNetworkStackConfigByIdResponse.cs b/src/X1.Application/Features/NetworkStackConfigs/Queries/GetNetworkStackConfigById/GetNetworkStackConfigByIdResponse.cs new file mode 100644 index 0000000..42bcdec --- /dev/null +++ b/src/X1.Application/Features/NetworkStackConfigs/Queries/GetNetworkStackConfigById/GetNetworkStackConfigByIdResponse.cs @@ -0,0 +1,52 @@ +namespace CellularManagement.Application.Features.NetworkStackConfigs.Queries.GetNetworkStackConfigById; + +/// +/// 根据ID获取网络栈配置响应 +/// +public class GetNetworkStackConfigByIdResponse +{ + /// + /// 网络栈配置ID + /// + public string NetworkStackConfigId { get; set; } = null!; + + /// + /// 栈ID(主键) + /// + public string StackId { get; set; } = null!; + + /// + /// RAN配置ID(外键,可为空) + /// + public string? RanId { get; set; } + + /// + /// 描述 + /// + public string? Description { get; set; } + + /// + /// 是否激活 + /// + public bool IsActive { get; set; } + + /// + /// 创建时间 + /// + public DateTime CreatedAt { get; set; } + + /// + /// 更新时间 + /// + public DateTime? UpdatedAt { get; set; } + + /// + /// 创建者 + /// + public string CreatedBy { get; set; } = null!; + + /// + /// 更新者 + /// + public string? UpdatedBy { get; set; } +} \ No newline at end of file diff --git a/src/X1.Application/Features/NetworkStackConfigs/Queries/GetNetworkStackConfigs/GetNetworkStackConfigsQuery.cs b/src/X1.Application/Features/NetworkStackConfigs/Queries/GetNetworkStackConfigs/GetNetworkStackConfigsQuery.cs new file mode 100644 index 0000000..51ed5eb --- /dev/null +++ b/src/X1.Application/Features/NetworkStackConfigs/Queries/GetNetworkStackConfigs/GetNetworkStackConfigsQuery.cs @@ -0,0 +1,40 @@ +using CellularManagement.Domain.Common; +using MediatR; +using System.ComponentModel.DataAnnotations; + +namespace CellularManagement.Application.Features.NetworkStackConfigs.Queries.GetNetworkStackConfigs; + +/// +/// 获取网络栈配置列表查询 +/// +public class GetNetworkStackConfigsQuery : IRequest> +{ + /// + /// 页码 + /// + [Range(1, int.MaxValue, ErrorMessage = "页码必须大于0")] + public int PageNumber { get; set; } = 1; + + /// + /// 每页大小 + /// + [Range(1, 100, ErrorMessage = "每页大小必须在1-100之间")] + public int PageSize { get; set; } = 10; + + /// + /// 搜索关键词(栈ID或描述) + /// + [MaxLength(100, ErrorMessage = "搜索关键词不能超过100个字符")] + public string? SearchTerm { get; set; } + + /// + /// 是否激活过滤 + /// + public bool? IsActive { get; set; } + + /// + /// RAN配置ID过滤 + /// + [MaxLength(50, ErrorMessage = "RAN配置ID不能超过50个字符")] + public string? RanId { get; set; } +} \ No newline at end of file diff --git a/src/X1.Application/Features/NetworkStackConfigs/Queries/GetNetworkStackConfigs/GetNetworkStackConfigsQueryHandler.cs b/src/X1.Application/Features/NetworkStackConfigs/Queries/GetNetworkStackConfigs/GetNetworkStackConfigsQueryHandler.cs new file mode 100644 index 0000000..7b58447 --- /dev/null +++ b/src/X1.Application/Features/NetworkStackConfigs/Queries/GetNetworkStackConfigs/GetNetworkStackConfigsQueryHandler.cs @@ -0,0 +1,96 @@ +using MediatR; +using Microsoft.Extensions.Logging; +using CellularManagement.Domain.Common; +using CellularManagement.Domain.Repositories.NetworkProfile; + +namespace CellularManagement.Application.Features.NetworkStackConfigs.Queries.GetNetworkStackConfigs; + +/// +/// 获取网络栈配置列表查询处理器 +/// +public class GetNetworkStackConfigsQueryHandler : IRequestHandler> +{ + private readonly INetworkStackConfigRepository _networkStackConfigRepository; + private readonly ILogger _logger; + + /// + /// 初始化查询处理器 + /// + public GetNetworkStackConfigsQueryHandler( + INetworkStackConfigRepository networkStackConfigRepository, + ILogger logger) + { + _networkStackConfigRepository = networkStackConfigRepository; + _logger = logger; + } + + /// + /// 处理获取网络栈配置列表查询 + /// + public async Task> Handle(GetNetworkStackConfigsQuery request, CancellationToken cancellationToken) + { + try + { + _logger.LogInformation("开始获取网络栈配置列表,页码: {PageNumber}, 每页大小: {PageSize}", + request.PageNumber, request.PageSize); + + // 搜索网络栈配置 + var (totalCount, networkStackConfigs) = await _networkStackConfigRepository.SearchNetworkStackConfigsAsync( + keyword: request.SearchTerm, + pageNumber: request.PageNumber, + pageSize: request.PageSize, + cancellationToken); + + // 应用额外的过滤条件 + if (request.IsActive.HasValue) + { + networkStackConfigs = networkStackConfigs.Where(config => config.IsActive == request.IsActive.Value).ToList(); + } + + if (!string.IsNullOrEmpty(request.RanId)) + { + networkStackConfigs = networkStackConfigs.Where(config => config.RanId == request.RanId).ToList(); + } + + // 计算分页信息 + var totalPages = (int)Math.Ceiling((double)totalCount / request.PageSize); + var hasPreviousPage = request.PageNumber > 1; + var hasNextPage = request.PageNumber < totalPages; + + // 构建DTO列表 + var networkStackConfigDtos = networkStackConfigs.Select(config => new NetworkStackConfigDto + { + NetworkStackConfigId = config.Id, + StackId = config.StackId, + RanId = config.RanId, + Description = config.Description, + IsActive = config.IsActive, + CreatedAt = config.CreatedAt, + UpdatedAt = config.UpdatedAt, + CreatedBy = config.CreatedBy, + UpdatedBy = config.UpdatedBy + }).ToList(); + + // 构建响应 + var response = new GetNetworkStackConfigsResponse + { + NetworkStackConfigs = networkStackConfigDtos, + TotalCount = totalCount, + TotalPages = totalPages, + PageNumber = request.PageNumber, + PageSize = request.PageSize, + HasPreviousPage = hasPreviousPage, + HasNextPage = hasNextPage + }; + + _logger.LogInformation("成功获取网络栈配置列表,总数: {TotalCount}, 当前页: {PageNumber}/{TotalPages}", + totalCount, request.PageNumber, totalPages); + return OperationResult.CreateSuccess(response); + } + catch (Exception ex) + { + _logger.LogError(ex, "获取网络栈配置列表时发生错误"); + return OperationResult.CreateFailure($"获取网络栈配置列表时发生错误: {ex.Message}"); + } + } +} \ No newline at end of file diff --git a/src/X1.Application/Features/NetworkStackConfigs/Queries/GetNetworkStackConfigs/GetNetworkStackConfigsResponse.cs b/src/X1.Application/Features/NetworkStackConfigs/Queries/GetNetworkStackConfigs/GetNetworkStackConfigsResponse.cs new file mode 100644 index 0000000..f637302 --- /dev/null +++ b/src/X1.Application/Features/NetworkStackConfigs/Queries/GetNetworkStackConfigs/GetNetworkStackConfigsResponse.cs @@ -0,0 +1,93 @@ +namespace CellularManagement.Application.Features.NetworkStackConfigs.Queries.GetNetworkStackConfigs; + +/// +/// 获取网络栈配置列表响应 +/// +public class GetNetworkStackConfigsResponse +{ + /// + /// 网络栈配置列表 + /// + public List NetworkStackConfigs { get; set; } = new(); + + /// + /// 总记录数 + /// + public int TotalCount { get; set; } + + /// + /// 总页数 + /// + public int TotalPages { get; set; } + + /// + /// 当前页码 + /// + public int PageNumber { get; set; } + + /// + /// 每页大小 + /// + public int PageSize { get; set; } + + /// + /// 是否有上一页 + /// + public bool HasPreviousPage { get; set; } + + /// + /// 是否有下一页 + /// + public bool HasNextPage { get; set; } +} + +/// +/// 网络栈配置DTO +/// +public class NetworkStackConfigDto +{ + /// + /// 网络栈配置ID + /// + public string NetworkStackConfigId { get; set; } = null!; + + /// + /// 栈ID(主键) + /// + public string StackId { get; set; } = null!; + + /// + /// RAN配置ID(外键,可为空) + /// + public string? RanId { get; set; } + + /// + /// 描述 + /// + public string? Description { get; set; } + + /// + /// 是否激活 + /// + public bool IsActive { get; set; } + + /// + /// 创建时间 + /// + public DateTime CreatedAt { get; set; } + + /// + /// 更新时间 + /// + public DateTime? UpdatedAt { get; set; } + + /// + /// 创建者 + /// + public string CreatedBy { get; set; } = null!; + + /// + /// 更新者 + /// + public string? UpdatedBy { get; set; } +} \ No newline at end of file diff --git a/src/X1.Application/Features/ProtocolVersions/Commands/CreateProtocolVersion/CreateProtocolVersionCommand.cs b/src/X1.Application/Features/ProtocolVersions/Commands/CreateProtocolVersion/CreateProtocolVersionCommand.cs index 765cf26..687a3fe 100644 --- a/src/X1.Application/Features/ProtocolVersions/Commands/CreateProtocolVersion/CreateProtocolVersionCommand.cs +++ b/src/X1.Application/Features/ProtocolVersions/Commands/CreateProtocolVersion/CreateProtocolVersionCommand.cs @@ -46,4 +46,11 @@ public class CreateProtocolVersionCommand : IRequest [MaxLength(20)] public string? MinimumSupportedVersion { get; set; } + + /// + /// 设备序列号 + /// + [Required(ErrorMessage = "设备序列号不能为空")] + [MaxLength(50, ErrorMessage = "设备序列号不能超过50个字符")] + public string SerialNumber { get; set; } = null!; } \ No newline at end of file diff --git a/src/X1.Application/Features/ProtocolVersions/Commands/CreateProtocolVersion/CreateProtocolVersionCommandHandler.cs b/src/X1.Application/Features/ProtocolVersions/Commands/CreateProtocolVersion/CreateProtocolVersionCommandHandler.cs index 5f5a22f..e7cc698 100644 --- a/src/X1.Application/Features/ProtocolVersions/Commands/CreateProtocolVersion/CreateProtocolVersionCommandHandler.cs +++ b/src/X1.Application/Features/ProtocolVersions/Commands/CreateProtocolVersion/CreateProtocolVersionCommandHandler.cs @@ -62,6 +62,7 @@ public class CreateProtocolVersionCommandHandler : IRequestHandler public string? MinimumSupportedVersion { get; set; } + /// + /// 设备序列号 + /// + public string SerialNumber { get; set; } = null!; + /// /// 创建时间 /// diff --git a/src/X1.Application/Features/ProtocolVersions/Commands/UpdateProtocolVersion/UpdateProtocolVersionCommand.cs b/src/X1.Application/Features/ProtocolVersions/Commands/UpdateProtocolVersion/UpdateProtocolVersionCommand.cs index 78163d1..872683d 100644 --- a/src/X1.Application/Features/ProtocolVersions/Commands/UpdateProtocolVersion/UpdateProtocolVersionCommand.cs +++ b/src/X1.Application/Features/ProtocolVersions/Commands/UpdateProtocolVersion/UpdateProtocolVersionCommand.cs @@ -52,4 +52,11 @@ public class UpdateProtocolVersionCommand : IRequest [MaxLength(20)] public string? MinimumSupportedVersion { get; set; } + + /// + /// 设备序列号 + /// + [Required(ErrorMessage = "设备序列号不能为空")] + [MaxLength(50, ErrorMessage = "设备序列号不能超过50个字符")] + public string SerialNumber { get; set; } = null!; } \ No newline at end of file diff --git a/src/X1.Application/Features/ProtocolVersions/Commands/UpdateProtocolVersion/UpdateProtocolVersionCommandHandler.cs b/src/X1.Application/Features/ProtocolVersions/Commands/UpdateProtocolVersion/UpdateProtocolVersionCommandHandler.cs index a1c4fe6..115a885 100644 --- a/src/X1.Application/Features/ProtocolVersions/Commands/UpdateProtocolVersion/UpdateProtocolVersionCommandHandler.cs +++ b/src/X1.Application/Features/ProtocolVersions/Commands/UpdateProtocolVersion/UpdateProtocolVersionCommandHandler.cs @@ -73,6 +73,7 @@ public class UpdateProtocolVersionCommandHandler : IRequestHandler public string? MinimumSupportedVersion { get; set; } + /// + /// 设备序列号 + /// + public string SerialNumber { get; set; } = null!; + /// /// 更新时间 /// diff --git a/src/X1.Application/Features/ProtocolVersions/Queries/GetProtocolVersionById/GetProtocolVersionByIdQueryHandler.cs b/src/X1.Application/Features/ProtocolVersions/Queries/GetProtocolVersionById/GetProtocolVersionByIdQueryHandler.cs index 84ba21f..9b689e9 100644 --- a/src/X1.Application/Features/ProtocolVersions/Queries/GetProtocolVersionById/GetProtocolVersionByIdQueryHandler.cs +++ b/src/X1.Application/Features/ProtocolVersions/Queries/GetProtocolVersionById/GetProtocolVersionByIdQueryHandler.cs @@ -51,6 +51,7 @@ public class GetProtocolVersionByIdQueryHandler : IRequestHandler public string? MinimumSupportedVersion { get; set; } + /// + /// 设备序列号 + /// + public string SerialNumber { get; set; } = null!; + /// /// 创建时间 /// diff --git a/src/X1.Application/Features/ProtocolVersions/Queries/GetProtocolVersions/GetProtocolVersionsQueryHandler.cs b/src/X1.Application/Features/ProtocolVersions/Queries/GetProtocolVersions/GetProtocolVersionsQueryHandler.cs index 4af8074..bb078f6 100644 --- a/src/X1.Application/Features/ProtocolVersions/Queries/GetProtocolVersions/GetProtocolVersionsQueryHandler.cs +++ b/src/X1.Application/Features/ProtocolVersions/Queries/GetProtocolVersions/GetProtocolVersionsQueryHandler.cs @@ -85,6 +85,7 @@ public class GetProtocolVersionsQueryHandler : IRequestHandler +/// 创建RAN配置命令 +/// +public class CreateRAN_ConfigurationCommand : IRequest> +{ + /// + /// 配置名称 + /// + [Required(ErrorMessage = "配置名称不能为空")] + [MaxLength(100, ErrorMessage = "配置名称不能超过100个字符")] + public string Name { get; set; } = null!; + + /// + /// 配置内容(JSON格式) + /// + [Required(ErrorMessage = "配置内容不能为空")] + public string ConfigContent { get; set; } = null!; + + /// + /// 配置描述 + /// + [MaxLength(500, ErrorMessage = "配置描述不能超过500个字符")] + public string? Description { get; set; } + + /// + /// 是否禁用 + /// + public bool IsDisabled { get; set; } = false; +} \ No newline at end of file diff --git a/src/X1.Application/Features/RANConfiguration/Commands/CreateRAN_Configuration/CreateRAN_ConfigurationCommandHandler.cs b/src/X1.Application/Features/RANConfiguration/Commands/CreateRAN_Configuration/CreateRAN_ConfigurationCommandHandler.cs new file mode 100644 index 0000000..bccc0f3 --- /dev/null +++ b/src/X1.Application/Features/RANConfiguration/Commands/CreateRAN_Configuration/CreateRAN_ConfigurationCommandHandler.cs @@ -0,0 +1,95 @@ +using MediatR; +using Microsoft.Extensions.Logging; +using CellularManagement.Domain.Common; +using CellularManagement.Domain.Repositories.NetworkProfile; +using CellularManagement.Domain.Repositories.Base; +using CellularManagement.Domain.Services; +using CellularManagement.Domain.Entities.NetworkProfile; + +namespace CellularManagement.Application.Features.RANConfiguration.Commands.CreateRAN_Configuration; + +/// +/// 创建RAN配置命令处理器 +/// +public class CreateRAN_ConfigurationCommandHandler : IRequestHandler> +{ + private readonly IRAN_ConfigurationRepository _ranConfigurationRepository; + private readonly ILogger _logger; + private readonly IUnitOfWork _unitOfWork; + private readonly ICurrentUserService _currentUserService; + + /// + /// 初始化命令处理器 + /// + public CreateRAN_ConfigurationCommandHandler( + IRAN_ConfigurationRepository ranConfigurationRepository, + ILogger logger, + IUnitOfWork unitOfWork, + ICurrentUserService currentUserService) + { + _ranConfigurationRepository = ranConfigurationRepository; + _logger = logger; + _unitOfWork = unitOfWork; + _currentUserService = currentUserService; + } + + /// + /// 处理创建RAN配置命令 + /// + public async Task> Handle(CreateRAN_ConfigurationCommand request, CancellationToken cancellationToken) + { + try + { + _logger.LogInformation("开始创建RAN配置,配置名称: {Name}", request.Name); + + // 检查配置名称是否已存在 + if (await _ranConfigurationRepository.NameExistsAsync(request.Name, cancellationToken)) + { + _logger.LogWarning("RAN配置名称已存在: {Name}", request.Name); + return OperationResult.CreateFailure($"RAN配置名称 {request.Name} 已存在"); + } + + // 获取当前用户ID + var currentUserId = _currentUserService.GetCurrentUserId(); + if (string.IsNullOrEmpty(currentUserId)) + { + _logger.LogError("无法获取当前用户ID,用户可能未认证"); + return OperationResult.CreateFailure("用户未认证,无法创建RAN配置"); + } + + // 创建RAN配置实体 + var ranConfiguration = RAN_Configuration.Create( + name: request.Name, + configContent: request.ConfigContent, + createdBy: currentUserId, + description: request.Description, + isDisabled: request.IsDisabled); + + // 保存RAN配置 + await _ranConfigurationRepository.AddRAN_ConfigurationAsync(ranConfiguration, cancellationToken); + + // 保存更改到数据库 + await _unitOfWork.SaveChangesAsync(cancellationToken); + + // 构建响应 + var response = new CreateRAN_ConfigurationResponse + { + RAN_ConfigurationId = ranConfiguration.Id, + Name = ranConfiguration.Name, + ConfigContent = ranConfiguration.ConfigContent, + Description = ranConfiguration.Description, + IsDisabled = ranConfiguration.IsDisabled, + CreatedAt = ranConfiguration.CreatedAt + }; + + _logger.LogInformation("RAN配置创建成功,配置ID: {RAN_ConfigurationId}, 配置名称: {Name}", + ranConfiguration.Id, ranConfiguration.Name); + return OperationResult.CreateSuccess(response); + } + catch (Exception ex) + { + _logger.LogError(ex, "创建RAN配置时发生错误,配置名称: {Name}", request.Name); + return OperationResult.CreateFailure($"创建RAN配置时发生错误: {ex.Message}"); + } + } +} \ No newline at end of file diff --git a/src/X1.Application/Features/RANConfiguration/Commands/CreateRAN_Configuration/CreateRAN_ConfigurationResponse.cs b/src/X1.Application/Features/RANConfiguration/Commands/CreateRAN_Configuration/CreateRAN_ConfigurationResponse.cs new file mode 100644 index 0000000..aaa22b0 --- /dev/null +++ b/src/X1.Application/Features/RANConfiguration/Commands/CreateRAN_Configuration/CreateRAN_ConfigurationResponse.cs @@ -0,0 +1,37 @@ +namespace CellularManagement.Application.Features.RANConfiguration.Commands.CreateRAN_Configuration; + +/// +/// 创建RAN配置响应 +/// +public class CreateRAN_ConfigurationResponse +{ + /// + /// RAN配置ID + /// + public string RAN_ConfigurationId { get; set; } = null!; + + /// + /// 配置名称 + /// + public string Name { get; set; } = null!; + + /// + /// 配置内容(JSON格式) + /// + public string ConfigContent { get; set; } = null!; + + /// + /// 配置描述 + /// + public string? Description { get; set; } + + /// + /// 是否禁用 + /// + public bool IsDisabled { get; set; } + + /// + /// 创建时间 + /// + public DateTime CreatedAt { get; set; } +} \ No newline at end of file diff --git a/src/X1.Application/Features/RANConfiguration/Commands/DeleteRAN_Configuration/DeleteRAN_ConfigurationCommand.cs b/src/X1.Application/Features/RANConfiguration/Commands/DeleteRAN_Configuration/DeleteRAN_ConfigurationCommand.cs new file mode 100644 index 0000000..4fd7910 --- /dev/null +++ b/src/X1.Application/Features/RANConfiguration/Commands/DeleteRAN_Configuration/DeleteRAN_ConfigurationCommand.cs @@ -0,0 +1,17 @@ +using CellularManagement.Domain.Common; +using MediatR; +using System.ComponentModel.DataAnnotations; + +namespace CellularManagement.Application.Features.RANConfiguration.Commands.DeleteRAN_Configuration; + +/// +/// 删除RAN配置命令 +/// +public class DeleteRAN_ConfigurationCommand : IRequest> +{ + /// + /// RAN配置ID + /// + [Required] + public string RAN_ConfigurationId { get; set; } = null!; +} \ No newline at end of file diff --git a/src/X1.Application/Features/RANConfiguration/Commands/DeleteRAN_Configuration/DeleteRAN_ConfigurationCommandHandler.cs b/src/X1.Application/Features/RANConfiguration/Commands/DeleteRAN_Configuration/DeleteRAN_ConfigurationCommandHandler.cs new file mode 100644 index 0000000..1d6ffb4 --- /dev/null +++ b/src/X1.Application/Features/RANConfiguration/Commands/DeleteRAN_Configuration/DeleteRAN_ConfigurationCommandHandler.cs @@ -0,0 +1,63 @@ +using MediatR; +using Microsoft.Extensions.Logging; +using CellularManagement.Domain.Common; +using CellularManagement.Domain.Repositories.NetworkProfile; +using CellularManagement.Domain.Repositories.Base; + +namespace CellularManagement.Application.Features.RANConfiguration.Commands.DeleteRAN_Configuration; + +/// +/// 删除RAN配置命令处理器 +/// +public class DeleteRAN_ConfigurationCommandHandler : IRequestHandler> +{ + private readonly IRAN_ConfigurationRepository _ranConfigurationRepository; + private readonly ILogger _logger; + private readonly IUnitOfWork _unitOfWork; + + /// + /// 初始化删除RAN配置命令处理器 + /// + public DeleteRAN_ConfigurationCommandHandler( + IRAN_ConfigurationRepository ranConfigurationRepository, + ILogger logger, + IUnitOfWork unitOfWork) + { + _ranConfigurationRepository = ranConfigurationRepository; + _logger = logger; + _unitOfWork = unitOfWork; + } + + /// + /// 处理删除RAN配置命令 + /// + public async Task> Handle(DeleteRAN_ConfigurationCommand request, CancellationToken cancellationToken) + { + try + { + _logger.LogInformation("开始处理删除RAN配置命令,配置ID: {RAN_ConfigurationId}", request.RAN_ConfigurationId); + + // 检查RAN配置是否存在 + var ranConfiguration = await _ranConfigurationRepository.GetRAN_ConfigurationByIdAsync(request.RAN_ConfigurationId, cancellationToken); + if (ranConfiguration == null) + { + _logger.LogWarning("未找到RAN配置,配置ID: {RAN_ConfigurationId}", request.RAN_ConfigurationId); + return OperationResult.CreateFailure($"未找到ID为 {request.RAN_ConfigurationId} 的RAN配置"); + } + + // 删除RAN配置 + await _ranConfigurationRepository.DeleteRAN_ConfigurationAsync(request.RAN_ConfigurationId, cancellationToken); + + // 保存更改到数据库 + await _unitOfWork.SaveChangesAsync(cancellationToken); + + _logger.LogInformation("RAN配置删除成功,配置ID: {RAN_ConfigurationId}", request.RAN_ConfigurationId); + return OperationResult.CreateSuccess("RAN配置删除成功", true); + } + catch (Exception ex) + { + _logger.LogError(ex, "删除RAN配置时发生错误,配置ID: {RAN_ConfigurationId}", request.RAN_ConfigurationId); + return OperationResult.CreateFailure($"删除RAN配置时发生错误: {ex.Message}"); + } + } +} \ No newline at end of file diff --git a/src/X1.Application/Features/NetworkConfigs/Commands/UpdateNetworkConfig/UpdateNetworkConfigCommand.cs b/src/X1.Application/Features/RANConfiguration/Commands/UpdateRAN_Configuration/UpdateRAN_ConfigurationCommand.cs similarity index 50% rename from src/X1.Application/Features/NetworkConfigs/Commands/UpdateNetworkConfig/UpdateNetworkConfigCommand.cs rename to src/X1.Application/Features/RANConfiguration/Commands/UpdateRAN_Configuration/UpdateRAN_ConfigurationCommand.cs index 3041af1..997787e 100644 --- a/src/X1.Application/Features/NetworkConfigs/Commands/UpdateNetworkConfig/UpdateNetworkConfigCommand.cs +++ b/src/X1.Application/Features/RANConfiguration/Commands/UpdateRAN_Configuration/UpdateRAN_ConfigurationCommand.cs @@ -1,44 +1,37 @@ using CellularManagement.Domain.Common; using MediatR; -using CellularManagement.Domain.Entities.Device; using System.ComponentModel.DataAnnotations; -namespace CellularManagement.Application.Features.NetworkConfigs.Commands.UpdateNetworkConfig; +namespace CellularManagement.Application.Features.RANConfiguration.Commands.UpdateRAN_Configuration; /// -/// 更新网络配置命令 +/// 更新RAN配置命令 /// -public class UpdateNetworkConfigCommand : IRequest> +public class UpdateRAN_ConfigurationCommand : IRequest> { /// - /// 网络配置ID + /// RAN配置ID /// [Required] - public string NetworkConfigId { get; set; } = null!; + public string RAN_ConfigurationId { get; set; } = null!; /// /// 配置名称 /// - [Required] - [MaxLength(100)] + [Required(ErrorMessage = "配置名称不能为空")] + [MaxLength(100, ErrorMessage = "配置名称不能超过100个字符")] public string Name { get; set; } = null!; - /// - /// PLMN字段(移动国家代码+移动网络代码) - /// - [MaxLength(10)] - public string? Plmn { get; set; } - /// /// 配置内容(JSON格式) /// - [Required] + [Required(ErrorMessage = "配置内容不能为空")] public string ConfigContent { get; set; } = null!; /// - /// 配置说明 + /// 配置描述 /// - [MaxLength(500)] + [MaxLength(500, ErrorMessage = "配置描述不能超过500个字符")] public string? Description { get; set; } /// diff --git a/src/X1.Application/Features/RANConfiguration/Commands/UpdateRAN_Configuration/UpdateRAN_ConfigurationCommandHandler.cs b/src/X1.Application/Features/RANConfiguration/Commands/UpdateRAN_Configuration/UpdateRAN_ConfigurationCommandHandler.cs new file mode 100644 index 0000000..bf94556 --- /dev/null +++ b/src/X1.Application/Features/RANConfiguration/Commands/UpdateRAN_Configuration/UpdateRAN_ConfigurationCommandHandler.cs @@ -0,0 +1,107 @@ +using MediatR; +using Microsoft.Extensions.Logging; +using CellularManagement.Domain.Common; +using CellularManagement.Domain.Entities.NetworkProfile; +using CellularManagement.Domain.Repositories.NetworkProfile; +using CellularManagement.Domain.Repositories.Base; +using CellularManagement.Domain.Services; + +namespace CellularManagement.Application.Features.RANConfiguration.Commands.UpdateRAN_Configuration; + +/// +/// 更新RAN配置命令处理器 +/// +public class UpdateRAN_ConfigurationCommandHandler : IRequestHandler> +{ + private readonly IRAN_ConfigurationRepository _ranConfigurationRepository; + private readonly ILogger _logger; + private readonly IUnitOfWork _unitOfWork; + private readonly ICurrentUserService _currentUserService; + + /// + /// 初始化命令处理器 + /// + public UpdateRAN_ConfigurationCommandHandler( + IRAN_ConfigurationRepository ranConfigurationRepository, + ILogger logger, + IUnitOfWork unitOfWork, + ICurrentUserService currentUserService) + { + _ranConfigurationRepository = ranConfigurationRepository; + _logger = logger; + _unitOfWork = unitOfWork; + _currentUserService = currentUserService; + } + + /// + /// 处理更新RAN配置命令 + /// + public async Task> Handle(UpdateRAN_ConfigurationCommand request, CancellationToken cancellationToken) + { + try + { + _logger.LogInformation("开始更新RAN配置,配置ID: {RAN_ConfigurationId}, 配置名称: {Name}", + request.RAN_ConfigurationId, request.Name); + + // 检查RAN配置是否存在 + var existingRanConfiguration = await _ranConfigurationRepository.GetRAN_ConfigurationByIdAsync(request.RAN_ConfigurationId, cancellationToken); + if (existingRanConfiguration == null) + { + _logger.LogWarning("未找到RAN配置,配置ID: {RAN_ConfigurationId}", request.RAN_ConfigurationId); + return OperationResult.CreateFailure($"未找到ID为 {request.RAN_ConfigurationId} 的RAN配置"); + } + + // 如果配置名称发生变化,检查新配置名称是否已存在 + if (existingRanConfiguration.Name != request.Name) + { + if (await _ranConfigurationRepository.NameExistsAsync(request.Name, cancellationToken)) + { + _logger.LogWarning("RAN配置名称已存在: {Name}", request.Name); + return OperationResult.CreateFailure($"RAN配置名称 {request.Name} 已存在"); + } + } + + // 获取当前用户ID + var currentUserId = _currentUserService.GetCurrentUserId(); + if (string.IsNullOrEmpty(currentUserId)) + { + _logger.LogError("无法获取当前用户ID,用户可能未认证"); + return OperationResult.CreateFailure("用户未认证,无法更新RAN配置"); + } + + // 更新RAN配置属性 + existingRanConfiguration.Update( + name: request.Name, + configContent: request.ConfigContent, + updatedBy: currentUserId, + description: request.Description, + isDisabled: request.IsDisabled); + + _ranConfigurationRepository.UpdateRAN_Configuration(existingRanConfiguration); + + // 保存更改到数据库 + await _unitOfWork.SaveChangesAsync(cancellationToken); + + // 构建响应 + var response = new UpdateRAN_ConfigurationResponse + { + RAN_ConfigurationId = existingRanConfiguration.Id, + Name = existingRanConfiguration.Name, + ConfigContent = existingRanConfiguration.ConfigContent, + Description = existingRanConfiguration.Description, + IsDisabled = existingRanConfiguration.IsDisabled, + UpdatedAt = existingRanConfiguration.UpdatedAt + }; + + _logger.LogInformation("RAN配置更新成功,配置ID: {RAN_ConfigurationId}, 配置名称: {Name}", + existingRanConfiguration.Id, existingRanConfiguration.Name); + return OperationResult.CreateSuccess(response); + } + catch (Exception ex) + { + _logger.LogError(ex, "更新RAN配置时发生错误,配置ID: {RAN_ConfigurationId}, 配置名称: {Name}", + request.RAN_ConfigurationId, request.Name); + return OperationResult.CreateFailure($"更新RAN配置时发生错误: {ex.Message}"); + } + } +} \ No newline at end of file diff --git a/src/X1.Application/Features/RANConfiguration/Commands/UpdateRAN_Configuration/UpdateRAN_ConfigurationResponse.cs b/src/X1.Application/Features/RANConfiguration/Commands/UpdateRAN_Configuration/UpdateRAN_ConfigurationResponse.cs new file mode 100644 index 0000000..ddf4450 --- /dev/null +++ b/src/X1.Application/Features/RANConfiguration/Commands/UpdateRAN_Configuration/UpdateRAN_ConfigurationResponse.cs @@ -0,0 +1,37 @@ +namespace CellularManagement.Application.Features.RANConfiguration.Commands.UpdateRAN_Configuration; + +/// +/// 更新RAN配置响应 +/// +public class UpdateRAN_ConfigurationResponse +{ + /// + /// RAN配置ID + /// + public string RAN_ConfigurationId { get; set; } = null!; + + /// + /// 配置名称 + /// + public string Name { get; set; } = null!; + + /// + /// 配置内容(JSON格式) + /// + public string ConfigContent { get; set; } = null!; + + /// + /// 配置描述 + /// + public string? Description { get; set; } + + /// + /// 是否禁用 + /// + public bool IsDisabled { get; set; } + + /// + /// 更新时间 + /// + public DateTime? UpdatedAt { get; set; } +} \ No newline at end of file diff --git a/src/X1.Application/Features/RANConfiguration/Queries/GetRAN_ConfigurationById/GetRAN_ConfigurationByIdQuery.cs b/src/X1.Application/Features/RANConfiguration/Queries/GetRAN_ConfigurationById/GetRAN_ConfigurationByIdQuery.cs new file mode 100644 index 0000000..66657a0 --- /dev/null +++ b/src/X1.Application/Features/RANConfiguration/Queries/GetRAN_ConfigurationById/GetRAN_ConfigurationByIdQuery.cs @@ -0,0 +1,17 @@ +using CellularManagement.Domain.Common; +using MediatR; +using System.ComponentModel.DataAnnotations; + +namespace CellularManagement.Application.Features.RANConfiguration.Queries.GetRAN_ConfigurationById; + +/// +/// 根据ID获取RAN配置查询 +/// +public class GetRAN_ConfigurationByIdQuery : IRequest> +{ + /// + /// RAN配置ID + /// + [Required] + public string RAN_ConfigurationId { get; set; } = null!; +} \ No newline at end of file diff --git a/src/X1.Application/Features/RANConfiguration/Queries/GetRAN_ConfigurationById/GetRAN_ConfigurationByIdQueryHandler.cs b/src/X1.Application/Features/RANConfiguration/Queries/GetRAN_ConfigurationById/GetRAN_ConfigurationByIdQueryHandler.cs new file mode 100644 index 0000000..b711376 --- /dev/null +++ b/src/X1.Application/Features/RANConfiguration/Queries/GetRAN_ConfigurationById/GetRAN_ConfigurationByIdQueryHandler.cs @@ -0,0 +1,65 @@ +using CellularManagement.Domain.Common; +using CellularManagement.Domain.Entities.NetworkProfile; +using CellularManagement.Domain.Repositories.NetworkProfile; +using MediatR; +using Microsoft.Extensions.Logging; + +namespace CellularManagement.Application.Features.RANConfiguration.Queries.GetRAN_ConfigurationById; + +/// +/// 根据ID获取RAN配置查询处理器 +/// +public class GetRAN_ConfigurationByIdQueryHandler : IRequestHandler> +{ + private readonly IRAN_ConfigurationRepository _ranConfigurationRepository; + private readonly ILogger _logger; + + /// + /// 初始化查询处理器 + /// + public GetRAN_ConfigurationByIdQueryHandler( + IRAN_ConfigurationRepository ranConfigurationRepository, + ILogger logger) + { + _ranConfigurationRepository = ranConfigurationRepository; + _logger = logger; + } + + /// + /// 处理查询请求 + /// + public async Task> Handle(GetRAN_ConfigurationByIdQuery request, CancellationToken cancellationToken) + { + try + { + _logger.LogInformation("开始查询RAN配置,配置ID: {RAN_ConfigurationId}", request.RAN_ConfigurationId); + + var ranConfiguration = await _ranConfigurationRepository.GetRAN_ConfigurationByIdAsync(request.RAN_ConfigurationId, cancellationToken); + + if (ranConfiguration == null) + { + _logger.LogWarning("未找到RAN配置,配置ID: {RAN_ConfigurationId}", request.RAN_ConfigurationId); + return OperationResult.CreateFailure($"未找到ID为 {request.RAN_ConfigurationId} 的RAN配置"); + } + + var response = new GetRAN_ConfigurationByIdResponse + { + RAN_ConfigurationId = ranConfiguration.Id, + Name = ranConfiguration.Name, + ConfigContent = ranConfiguration.ConfigContent, + Description = ranConfiguration.Description, + IsDisabled = ranConfiguration.IsDisabled, + CreatedAt = ranConfiguration.CreatedAt, + UpdatedAt = ranConfiguration.UpdatedAt + }; + + _logger.LogInformation("成功查询到RAN配置,配置ID: {RAN_ConfigurationId}", request.RAN_ConfigurationId); + return OperationResult.CreateSuccess(response); + } + catch (Exception ex) + { + _logger.LogError(ex, "查询RAN配置时发生错误,配置ID: {RAN_ConfigurationId}", request.RAN_ConfigurationId); + return OperationResult.CreateFailure($"查询RAN配置时发生错误: {ex.Message}"); + } + } +} \ No newline at end of file diff --git a/src/X1.Application/Features/RANConfiguration/Queries/GetRAN_ConfigurationById/GetRAN_ConfigurationByIdResponse.cs b/src/X1.Application/Features/RANConfiguration/Queries/GetRAN_ConfigurationById/GetRAN_ConfigurationByIdResponse.cs new file mode 100644 index 0000000..8e2dc49 --- /dev/null +++ b/src/X1.Application/Features/RANConfiguration/Queries/GetRAN_ConfigurationById/GetRAN_ConfigurationByIdResponse.cs @@ -0,0 +1,42 @@ +namespace CellularManagement.Application.Features.RANConfiguration.Queries.GetRAN_ConfigurationById; + +/// +/// 根据ID获取RAN配置响应 +/// +public class GetRAN_ConfigurationByIdResponse +{ + /// + /// RAN配置ID + /// + public string RAN_ConfigurationId { get; set; } = null!; + + /// + /// 配置名称 + /// + public string Name { get; set; } = null!; + + /// + /// 配置内容(JSON格式) + /// + public string ConfigContent { get; set; } = null!; + + /// + /// 配置描述 + /// + public string? Description { get; set; } + + /// + /// 是否禁用 + /// + public bool IsDisabled { get; set; } + + /// + /// 创建时间 + /// + public DateTime CreatedAt { get; set; } + + /// + /// 更新时间 + /// + public DateTime? UpdatedAt { get; set; } +} \ No newline at end of file diff --git a/src/X1.Application/Features/RANConfiguration/Queries/GetRAN_Configurations/GetRAN_ConfigurationsQuery.cs b/src/X1.Application/Features/RANConfiguration/Queries/GetRAN_Configurations/GetRAN_ConfigurationsQuery.cs new file mode 100644 index 0000000..60d1030 --- /dev/null +++ b/src/X1.Application/Features/RANConfiguration/Queries/GetRAN_Configurations/GetRAN_ConfigurationsQuery.cs @@ -0,0 +1,34 @@ +using CellularManagement.Domain.Common; +using MediatR; +using System.ComponentModel.DataAnnotations; + +namespace CellularManagement.Application.Features.RANConfiguration.Queries.GetRAN_Configurations; + +/// +/// 获取RAN配置列表查询 +/// +public class GetRAN_ConfigurationsQuery : IRequest> +{ + /// + /// 页码 + /// + [Range(1, int.MaxValue, ErrorMessage = "页码必须大于0")] + public int PageNumber { get; set; } = 1; + + /// + /// 每页数量 + /// + [Range(1, 100, ErrorMessage = "每页数量必须在1-100之间")] + public int PageSize { get; set; } = 10; + + /// + /// 搜索关键词 + /// + [MaxLength(100)] + public string? SearchTerm { get; set; } + + /// + /// 是否只获取未禁用的配置 + /// + public bool? IsDisabled { get; set; } +} \ No newline at end of file diff --git a/src/X1.Application/Features/RANConfiguration/Queries/GetRAN_Configurations/GetRAN_ConfigurationsQueryHandler.cs b/src/X1.Application/Features/RANConfiguration/Queries/GetRAN_Configurations/GetRAN_ConfigurationsQueryHandler.cs new file mode 100644 index 0000000..db8badd --- /dev/null +++ b/src/X1.Application/Features/RANConfiguration/Queries/GetRAN_Configurations/GetRAN_ConfigurationsQueryHandler.cs @@ -0,0 +1,100 @@ +using MediatR; +using Microsoft.Extensions.Logging; +using CellularManagement.Domain.Common; +using CellularManagement.Domain.Entities.NetworkProfile; +using CellularManagement.Domain.Repositories; +using System.ComponentModel.DataAnnotations; +using System.Linq; +using CellularManagement.Application.Features.RANConfiguration.Queries.GetRAN_ConfigurationById; +using CellularManagement.Domain.Repositories.NetworkProfile; + +namespace CellularManagement.Application.Features.RANConfiguration.Queries.GetRAN_Configurations; + +/// +/// 获取RAN配置列表查询处理器 +/// +public class GetRAN_ConfigurationsQueryHandler : IRequestHandler> +{ + private readonly IRAN_ConfigurationRepository _ranConfigurationRepository; + private readonly ILogger _logger; + + /// + /// 初始化查询处理器 + /// + public GetRAN_ConfigurationsQueryHandler( + IRAN_ConfigurationRepository ranConfigurationRepository, + ILogger logger) + { + _ranConfigurationRepository = ranConfigurationRepository; + _logger = logger; + } + + /// + /// 处理获取RAN配置列表查询 + /// + public async Task> Handle(GetRAN_ConfigurationsQuery request, CancellationToken cancellationToken) + { + try + { + // 验证请求参数 + var validationContext = new ValidationContext(request); + var validationResults = new List(); + if (!Validator.TryValidateObject(request, validationContext, validationResults, true)) + { + var errorMessages = validationResults.Select(r => r.ErrorMessage).ToList(); + _logger.LogWarning("请求参数无效: {Errors}", string.Join(", ", errorMessages)); + return OperationResult.CreateFailure(errorMessages); + } + + _logger.LogInformation("开始获取RAN配置列表,页码: {PageNumber}, 每页数量: {PageSize}, 搜索关键词: {SearchTerm}, 是否禁用: {IsDisabled}", + request.PageNumber, request.PageSize, request.SearchTerm, request.IsDisabled); + + // 获取RAN配置数据 + var ranConfigurations = await _ranConfigurationRepository.SearchRAN_ConfigurationsAsync( + request.SearchTerm, + cancellationToken); + + // 如果指定了禁用状态过滤 + if (request.IsDisabled.HasValue) + { + ranConfigurations = ranConfigurations.Where(rc => rc.IsDisabled == request.IsDisabled.Value).ToList(); + } + + // 计算分页 + int totalCount = ranConfigurations.Count(); + var items = ranConfigurations + .Skip((request.PageNumber - 1) * request.PageSize) + .Take(request.PageSize) + .ToList(); + + // 构建响应 + var response = new GetRAN_ConfigurationsResponse + { + TotalCount = totalCount, + PageNumber = request.PageNumber, + PageSize = request.PageSize, + TotalPages = (int)Math.Ceiling(totalCount / (double)request.PageSize), + HasPreviousPage = request.PageNumber > 1, + HasNextPage = request.PageNumber < (int)Math.Ceiling(totalCount / (double)request.PageSize), + Items = items.Select(rc => new GetRAN_ConfigurationByIdResponse + { + RAN_ConfigurationId = rc.Id, + Name = rc.Name, + ConfigContent = rc.ConfigContent, + Description = rc.Description, + IsDisabled = rc.IsDisabled, + CreatedAt = rc.CreatedAt, + UpdatedAt = rc.UpdatedAt + }).ToList() + }; + + _logger.LogInformation("成功获取RAN配置列表,共 {Count} 条记录", items.Count); + return OperationResult.CreateSuccess(response); + } + catch (Exception ex) + { + _logger.LogError(ex, "获取RAN配置列表时发生错误"); + return OperationResult.CreateFailure($"获取RAN配置列表时发生错误: {ex.Message}"); + } + } +} \ No newline at end of file diff --git a/src/X1.Application/Features/RANConfiguration/Queries/GetRAN_Configurations/GetRAN_ConfigurationsResponse.cs b/src/X1.Application/Features/RANConfiguration/Queries/GetRAN_Configurations/GetRAN_ConfigurationsResponse.cs new file mode 100644 index 0000000..ad96394 --- /dev/null +++ b/src/X1.Application/Features/RANConfiguration/Queries/GetRAN_Configurations/GetRAN_ConfigurationsResponse.cs @@ -0,0 +1,46 @@ + + +using CellularManagement.Application.Features.RANConfiguration.Queries.GetRAN_ConfigurationById; + +namespace CellularManagement.Application.Features.RANConfiguration.Queries.GetRAN_Configurations; + +/// +/// 获取RAN配置列表响应 +/// +public class GetRAN_ConfigurationsResponse +{ + /// + /// 总数量 + /// + public int TotalCount { get; set; } + + /// + /// 当前页码 + /// + public int PageNumber { get; set; } + + /// + /// 每页数量 + /// + public int PageSize { get; set; } + + /// + /// 总页数 + /// + public int TotalPages { get; set; } + + /// + /// 是否有上一页 + /// + public bool HasPreviousPage { get; set; } + + /// + /// 是否有下一页 + /// + public bool HasNextPage { get; set; } + + /// + /// RAN配置列表 + /// + public List Items { get; set; } = new(); +} \ No newline at end of file diff --git a/src/X1.Application/Features/StackCoreIMSBindings/Commands/CreateStackCoreIMSBinding/CreateStackCoreIMSBindingCommand.cs b/src/X1.Application/Features/StackCoreIMSBindings/Commands/CreateStackCoreIMSBinding/CreateStackCoreIMSBindingCommand.cs new file mode 100644 index 0000000..be2f39b --- /dev/null +++ b/src/X1.Application/Features/StackCoreIMSBindings/Commands/CreateStackCoreIMSBinding/CreateStackCoreIMSBindingCommand.cs @@ -0,0 +1,39 @@ +using CellularManagement.Domain.Common; +using MediatR; +using System.ComponentModel.DataAnnotations; + +namespace CellularManagement.Application.Features.StackCoreIMSBindings.Commands.CreateStackCoreIMSBinding; + +/// +/// 创建栈与核心网/IMS绑定关系命令 +/// +public class CreateStackCoreIMSBindingCommand : IRequest> +{ + /// + /// 栈ID(外键) + /// + [Required(ErrorMessage = "栈ID不能为空")] + [MaxLength(50, ErrorMessage = "栈ID不能超过50个字符")] + public string StackId { get; set; } = null!; + + /// + /// 索引(主键的一部分) + /// + [Required(ErrorMessage = "索引不能为空")] + [Range(0, int.MaxValue, ErrorMessage = "索引必须大于等于0")] + public int Index { get; set; } + + /// + /// 核心网配置ID(外键) + /// + [Required(ErrorMessage = "核心网配置ID不能为空")] + [MaxLength(50, ErrorMessage = "核心网配置ID不能超过50个字符")] + public string CnId { get; set; } = null!; + + /// + /// IMS配置ID(外键) + /// + [Required(ErrorMessage = "IMS配置ID不能为空")] + [MaxLength(50, ErrorMessage = "IMS配置ID不能超过50个字符")] + public string ImsId { get; set; } = null!; +} \ No newline at end of file diff --git a/src/X1.Application/Features/StackCoreIMSBindings/Commands/CreateStackCoreIMSBinding/CreateStackCoreIMSBindingCommandHandler.cs b/src/X1.Application/Features/StackCoreIMSBindings/Commands/CreateStackCoreIMSBinding/CreateStackCoreIMSBindingCommandHandler.cs new file mode 100644 index 0000000..d4f3a1d --- /dev/null +++ b/src/X1.Application/Features/StackCoreIMSBindings/Commands/CreateStackCoreIMSBinding/CreateStackCoreIMSBindingCommandHandler.cs @@ -0,0 +1,95 @@ +using MediatR; +using Microsoft.Extensions.Logging; +using CellularManagement.Domain.Common; +using CellularManagement.Domain.Repositories.NetworkProfile; +using CellularManagement.Domain.Repositories.Base; +using CellularManagement.Domain.Services; +using CellularManagement.Domain.Entities.NetworkProfile; + +namespace CellularManagement.Application.Features.StackCoreIMSBindings.Commands.CreateStackCoreIMSBinding; + +/// +/// 创建栈与核心网/IMS绑定关系命令处理器 +/// +public class CreateStackCoreIMSBindingCommandHandler : IRequestHandler> +{ + private readonly IStack_CoreIMS_BindingRepository _stackCoreIMSBindingRepository; + private readonly ILogger _logger; + private readonly IUnitOfWork _unitOfWork; + private readonly ICurrentUserService _currentUserService; + + /// + /// 初始化命令处理器 + /// + public CreateStackCoreIMSBindingCommandHandler( + IStack_CoreIMS_BindingRepository stackCoreIMSBindingRepository, + ILogger logger, + IUnitOfWork unitOfWork, + ICurrentUserService currentUserService) + { + _stackCoreIMSBindingRepository = stackCoreIMSBindingRepository; + _logger = logger; + _unitOfWork = unitOfWork; + _currentUserService = currentUserService; + } + + /// + /// 处理创建栈与核心网/IMS绑定关系命令 + /// + public async Task> Handle(CreateStackCoreIMSBindingCommand request, CancellationToken cancellationToken) + { + try + { + _logger.LogInformation("开始创建栈与核心网/IMS绑定关系,栈ID: {StackId}, 索引: {Index}", request.StackId, request.Index); + + // 检查绑定关系是否已存在 + if (await _stackCoreIMSBindingRepository.StackIdAndIndexExistsAsync(request.StackId, request.Index, cancellationToken)) + { + _logger.LogWarning("栈与核心网/IMS绑定关系已存在,栈ID: {StackId}, 索引: {Index}", request.StackId, request.Index); + return OperationResult.CreateFailure($"栈与核心网/IMS绑定关系已存在,栈ID: {request.StackId}, 索引: {request.Index}"); + } + + // 获取当前用户ID + var currentUserId = _currentUserService.GetCurrentUserId(); + if (string.IsNullOrEmpty(currentUserId)) + { + _logger.LogError("无法获取当前用户ID,用户可能未认证"); + return OperationResult.CreateFailure("用户未认证,无法创建栈与核心网/IMS绑定关系"); + } + + // 创建栈与核心网/IMS绑定关系实体 + var binding = Stack_CoreIMS_Binding.Create( + stackId: request.StackId, + index: request.Index, + cnId: request.CnId, + imsId: request.ImsId, + createdBy: currentUserId); + + // 保存绑定关系 + await _stackCoreIMSBindingRepository.AddBindingAsync(binding, cancellationToken); + + // 保存更改到数据库 + await _unitOfWork.SaveChangesAsync(cancellationToken); + + // 构建响应 + var response = new CreateStackCoreIMSBindingResponse + { + StackCoreIMSBindingId = binding.Id, + StackId = binding.StackId, + Index = binding.Index, + CnId = binding.CnId, + ImsId = binding.ImsId, + CreatedAt = binding.CreatedAt + }; + + _logger.LogInformation("栈与核心网/IMS绑定关系创建成功,绑定ID: {BindingId}, 栈ID: {StackId}, 索引: {Index}", + binding.Id, binding.StackId, binding.Index); + return OperationResult.CreateSuccess(response); + } + catch (Exception ex) + { + _logger.LogError(ex, "创建栈与核心网/IMS绑定关系时发生错误,栈ID: {StackId}, 索引: {Index}", request.StackId, request.Index); + return OperationResult.CreateFailure($"创建栈与核心网/IMS绑定关系时发生错误: {ex.Message}"); + } + } +} \ No newline at end of file diff --git a/src/X1.Application/Features/StackCoreIMSBindings/Commands/CreateStackCoreIMSBinding/CreateStackCoreIMSBindingResponse.cs b/src/X1.Application/Features/StackCoreIMSBindings/Commands/CreateStackCoreIMSBinding/CreateStackCoreIMSBindingResponse.cs new file mode 100644 index 0000000..79419d3 --- /dev/null +++ b/src/X1.Application/Features/StackCoreIMSBindings/Commands/CreateStackCoreIMSBinding/CreateStackCoreIMSBindingResponse.cs @@ -0,0 +1,37 @@ +namespace CellularManagement.Application.Features.StackCoreIMSBindings.Commands.CreateStackCoreIMSBinding; + +/// +/// 创建栈与核心网/IMS绑定关系响应 +/// +public class CreateStackCoreIMSBindingResponse +{ + /// + /// 绑定关系ID + /// + public string StackCoreIMSBindingId { get; set; } = null!; + + /// + /// 栈ID(外键) + /// + public string StackId { get; set; } = null!; + + /// + /// 索引(主键的一部分) + /// + public int Index { get; set; } + + /// + /// 核心网配置ID(外键) + /// + public string CnId { get; set; } = null!; + + /// + /// IMS配置ID(外键) + /// + public string ImsId { get; set; } = null!; + + /// + /// 创建时间 + /// + public DateTime CreatedAt { get; set; } +} \ No newline at end of file diff --git a/src/X1.Application/Features/StackCoreIMSBindings/Commands/DeleteStackCoreIMSBinding/DeleteStackCoreIMSBindingCommand.cs b/src/X1.Application/Features/StackCoreIMSBindings/Commands/DeleteStackCoreIMSBinding/DeleteStackCoreIMSBindingCommand.cs new file mode 100644 index 0000000..0bbde24 --- /dev/null +++ b/src/X1.Application/Features/StackCoreIMSBindings/Commands/DeleteStackCoreIMSBinding/DeleteStackCoreIMSBindingCommand.cs @@ -0,0 +1,17 @@ +using CellularManagement.Domain.Common; +using MediatR; +using System.ComponentModel.DataAnnotations; + +namespace CellularManagement.Application.Features.StackCoreIMSBindings.Commands.DeleteStackCoreIMSBinding; + +/// +/// 删除栈与核心网/IMS绑定关系命令 +/// +public class DeleteStackCoreIMSBindingCommand : IRequest> +{ + /// + /// 绑定关系ID + /// + [Required] + public string StackCoreIMSBindingId { get; set; } = null!; +} \ No newline at end of file diff --git a/src/X1.Application/Features/StackCoreIMSBindings/Commands/DeleteStackCoreIMSBinding/DeleteStackCoreIMSBindingCommandHandler.cs b/src/X1.Application/Features/StackCoreIMSBindings/Commands/DeleteStackCoreIMSBinding/DeleteStackCoreIMSBindingCommandHandler.cs new file mode 100644 index 0000000..1535ec8 --- /dev/null +++ b/src/X1.Application/Features/StackCoreIMSBindings/Commands/DeleteStackCoreIMSBinding/DeleteStackCoreIMSBindingCommandHandler.cs @@ -0,0 +1,64 @@ +using MediatR; +using Microsoft.Extensions.Logging; +using CellularManagement.Domain.Common; +using CellularManagement.Domain.Repositories.NetworkProfile; +using CellularManagement.Domain.Repositories.Base; + +namespace CellularManagement.Application.Features.StackCoreIMSBindings.Commands.DeleteStackCoreIMSBinding; + +/// +/// 删除栈与核心网/IMS绑定关系命令处理器 +/// +public class DeleteStackCoreIMSBindingCommandHandler : IRequestHandler> +{ + private readonly IStack_CoreIMS_BindingRepository _stackCoreIMSBindingRepository; + private readonly ILogger _logger; + private readonly IUnitOfWork _unitOfWork; + + /// + /// 初始化命令处理器 + /// + public DeleteStackCoreIMSBindingCommandHandler( + IStack_CoreIMS_BindingRepository stackCoreIMSBindingRepository, + ILogger logger, + IUnitOfWork unitOfWork) + { + _stackCoreIMSBindingRepository = stackCoreIMSBindingRepository; + _logger = logger; + _unitOfWork = unitOfWork; + } + + /// + /// 处理删除栈与核心网/IMS绑定关系命令 + /// + public async Task> Handle(DeleteStackCoreIMSBindingCommand request, CancellationToken cancellationToken) + { + try + { + _logger.LogInformation("开始删除栈与核心网/IMS绑定关系,绑定ID: {StackCoreIMSBindingId}", request.StackCoreIMSBindingId); + + // 检查绑定关系是否存在 + var existingBinding = await _stackCoreIMSBindingRepository.GetBindingByIdAsync(request.StackCoreIMSBindingId, cancellationToken); + if (existingBinding == null) + { + _logger.LogWarning("栈与核心网/IMS绑定关系不存在: {StackCoreIMSBindingId}", request.StackCoreIMSBindingId); + return OperationResult.CreateFailure($"栈与核心网/IMS绑定关系 {request.StackCoreIMSBindingId} 不存在"); + } + + // 删除绑定关系 + await _stackCoreIMSBindingRepository.DeleteBindingAsync(request.StackCoreIMSBindingId, cancellationToken); + + // 保存更改到数据库 + await _unitOfWork.SaveChangesAsync(cancellationToken); + + _logger.LogInformation("栈与核心网/IMS绑定关系删除成功,绑定ID: {StackCoreIMSBindingId}, 栈ID: {StackId}, 索引: {Index}", + request.StackCoreIMSBindingId, existingBinding.StackId, existingBinding.Index); + return OperationResult.CreateSuccess(true); + } + catch (Exception ex) + { + _logger.LogError(ex, "删除栈与核心网/IMS绑定关系时发生错误,绑定ID: {StackCoreIMSBindingId}", request.StackCoreIMSBindingId); + return OperationResult.CreateFailure($"删除栈与核心网/IMS绑定关系时发生错误: {ex.Message}"); + } + } +} \ No newline at end of file diff --git a/src/X1.Application/Features/StackCoreIMSBindings/Commands/UpdateStackCoreIMSBinding/UpdateStackCoreIMSBindingCommand.cs b/src/X1.Application/Features/StackCoreIMSBindings/Commands/UpdateStackCoreIMSBinding/UpdateStackCoreIMSBindingCommand.cs new file mode 100644 index 0000000..84e1587 --- /dev/null +++ b/src/X1.Application/Features/StackCoreIMSBindings/Commands/UpdateStackCoreIMSBinding/UpdateStackCoreIMSBindingCommand.cs @@ -0,0 +1,38 @@ +using CellularManagement.Domain.Common; +using MediatR; +using System.ComponentModel.DataAnnotations; + +namespace CellularManagement.Application.Features.StackCoreIMSBindings.Commands.UpdateStackCoreIMSBinding; + +/// +/// 更新栈与核心网/IMS绑定关系命令 +/// +public class UpdateStackCoreIMSBindingCommand : IRequest> +{ + /// + /// 绑定关系ID + /// + [Required] + public string StackCoreIMSBindingId { get; set; } = null!; + + /// + /// 索引(主键的一部分) + /// + [Required(ErrorMessage = "索引不能为空")] + [Range(0, int.MaxValue, ErrorMessage = "索引必须大于等于0")] + public int Index { get; set; } + + /// + /// 核心网配置ID(外键) + /// + [Required(ErrorMessage = "核心网配置ID不能为空")] + [MaxLength(50, ErrorMessage = "核心网配置ID不能超过50个字符")] + public string CnId { get; set; } = null!; + + /// + /// IMS配置ID(外键) + /// + [Required(ErrorMessage = "IMS配置ID不能为空")] + [MaxLength(50, ErrorMessage = "IMS配置ID不能超过50个字符")] + public string ImsId { get; set; } = null!; +} \ No newline at end of file diff --git a/src/X1.Application/Features/StackCoreIMSBindings/Commands/UpdateStackCoreIMSBinding/UpdateStackCoreIMSBindingCommandHandler.cs b/src/X1.Application/Features/StackCoreIMSBindings/Commands/UpdateStackCoreIMSBinding/UpdateStackCoreIMSBindingCommandHandler.cs new file mode 100644 index 0000000..5ea7652 --- /dev/null +++ b/src/X1.Application/Features/StackCoreIMSBindings/Commands/UpdateStackCoreIMSBinding/UpdateStackCoreIMSBindingCommandHandler.cs @@ -0,0 +1,103 @@ +using MediatR; +using Microsoft.Extensions.Logging; +using CellularManagement.Domain.Common; +using CellularManagement.Domain.Repositories.NetworkProfile; +using CellularManagement.Domain.Repositories.Base; +using CellularManagement.Domain.Services; +using CellularManagement.Domain.Entities.NetworkProfile; + +namespace CellularManagement.Application.Features.StackCoreIMSBindings.Commands.UpdateStackCoreIMSBinding; + +/// +/// 更新栈与核心网/IMS绑定关系命令处理器 +/// +public class UpdateStackCoreIMSBindingCommandHandler : IRequestHandler> +{ + private readonly IStack_CoreIMS_BindingRepository _stackCoreIMSBindingRepository; + private readonly ILogger _logger; + private readonly IUnitOfWork _unitOfWork; + private readonly ICurrentUserService _currentUserService; + + /// + /// 初始化命令处理器 + /// + public UpdateStackCoreIMSBindingCommandHandler( + IStack_CoreIMS_BindingRepository stackCoreIMSBindingRepository, + ILogger logger, + IUnitOfWork unitOfWork, + ICurrentUserService currentUserService) + { + _stackCoreIMSBindingRepository = stackCoreIMSBindingRepository; + _logger = logger; + _unitOfWork = unitOfWork; + _currentUserService = currentUserService; + } + + /// + /// 处理更新栈与核心网/IMS绑定关系命令 + /// + public async Task> Handle(UpdateStackCoreIMSBindingCommand request, CancellationToken cancellationToken) + { + try + { + _logger.LogInformation("开始更新栈与核心网/IMS绑定关系,绑定ID: {StackCoreIMSBindingId}", request.StackCoreIMSBindingId); + + // 检查绑定关系是否存在 + var existingBinding = await _stackCoreIMSBindingRepository.GetBindingByIdAsync(request.StackCoreIMSBindingId, cancellationToken); + if (existingBinding == null) + { + _logger.LogWarning("栈与核心网/IMS绑定关系不存在: {StackCoreIMSBindingId}", request.StackCoreIMSBindingId); + return OperationResult.CreateFailure($"栈与核心网/IMS绑定关系 {request.StackCoreIMSBindingId} 不存在"); + } + + // 检查新索引是否与其他绑定关系冲突 + if (request.Index != existingBinding.Index) + { + if (await _stackCoreIMSBindingRepository.StackIdAndIndexExistsAsync(existingBinding.StackId, request.Index, cancellationToken)) + { + _logger.LogWarning("栈与核心网/IMS绑定关系索引已存在,栈ID: {StackId}, 索引: {Index}", existingBinding.StackId, request.Index); + return OperationResult.CreateFailure($"栈与核心网/IMS绑定关系索引已存在,栈ID: {existingBinding.StackId}, 索引: {request.Index}"); + } + } + + // 获取当前用户ID + var currentUserId = _currentUserService.GetCurrentUserId(); + if (string.IsNullOrEmpty(currentUserId)) + { + _logger.LogError("无法获取当前用户ID,用户可能未认证"); + return OperationResult.CreateFailure("用户未认证,无法更新栈与核心网/IMS绑定关系"); + } + + // 更新绑定关系 + existingBinding.Update( + index: request.Index, + cnId: request.CnId, + imsId: request.ImsId, + updatedBy: currentUserId); + + // 保存更改 + _stackCoreIMSBindingRepository.UpdateBinding(existingBinding); + await _unitOfWork.SaveChangesAsync(cancellationToken); + + // 构建响应 + var response = new UpdateStackCoreIMSBindingResponse + { + StackCoreIMSBindingId = existingBinding.Id, + StackId = existingBinding.StackId, + Index = existingBinding.Index, + CnId = existingBinding.CnId, + ImsId = existingBinding.ImsId, + UpdatedAt = existingBinding.UpdatedAt + }; + + _logger.LogInformation("栈与核心网/IMS绑定关系更新成功,绑定ID: {BindingId}, 栈ID: {StackId}, 索引: {Index}", + existingBinding.Id, existingBinding.StackId, existingBinding.Index); + return OperationResult.CreateSuccess(response); + } + catch (Exception ex) + { + _logger.LogError(ex, "更新栈与核心网/IMS绑定关系时发生错误,绑定ID: {StackCoreIMSBindingId}", request.StackCoreIMSBindingId); + return OperationResult.CreateFailure($"更新栈与核心网/IMS绑定关系时发生错误: {ex.Message}"); + } + } +} \ No newline at end of file diff --git a/src/X1.Application/Features/StackCoreIMSBindings/Commands/UpdateStackCoreIMSBinding/UpdateStackCoreIMSBindingResponse.cs b/src/X1.Application/Features/StackCoreIMSBindings/Commands/UpdateStackCoreIMSBinding/UpdateStackCoreIMSBindingResponse.cs new file mode 100644 index 0000000..311e9b7 --- /dev/null +++ b/src/X1.Application/Features/StackCoreIMSBindings/Commands/UpdateStackCoreIMSBinding/UpdateStackCoreIMSBindingResponse.cs @@ -0,0 +1,37 @@ +namespace CellularManagement.Application.Features.StackCoreIMSBindings.Commands.UpdateStackCoreIMSBinding; + +/// +/// 更新栈与核心网/IMS绑定关系响应 +/// +public class UpdateStackCoreIMSBindingResponse +{ + /// + /// 绑定关系ID + /// + public string StackCoreIMSBindingId { get; set; } = null!; + + /// + /// 栈ID(外键) + /// + public string StackId { get; set; } = null!; + + /// + /// 索引(主键的一部分) + /// + public int Index { get; set; } + + /// + /// 核心网配置ID(外键) + /// + public string CnId { get; set; } = null!; + + /// + /// IMS配置ID(外键) + /// + public string ImsId { get; set; } = null!; + + /// + /// 更新时间 + /// + public DateTime? UpdatedAt { get; set; } +} \ No newline at end of file diff --git a/src/X1.Application/Features/StackCoreIMSBindings/Queries/GetStackCoreIMSBindingById/GetStackCoreIMSBindingByIdQuery.cs b/src/X1.Application/Features/StackCoreIMSBindings/Queries/GetStackCoreIMSBindingById/GetStackCoreIMSBindingByIdQuery.cs new file mode 100644 index 0000000..979c0e8 --- /dev/null +++ b/src/X1.Application/Features/StackCoreIMSBindings/Queries/GetStackCoreIMSBindingById/GetStackCoreIMSBindingByIdQuery.cs @@ -0,0 +1,17 @@ +using CellularManagement.Domain.Common; +using MediatR; +using System.ComponentModel.DataAnnotations; + +namespace CellularManagement.Application.Features.StackCoreIMSBindings.Queries.GetStackCoreIMSBindingById; + +/// +/// 根据ID获取栈与核心网/IMS绑定关系查询 +/// +public class GetStackCoreIMSBindingByIdQuery : IRequest> +{ + /// + /// 绑定关系ID + /// + [Required] + public string StackCoreIMSBindingId { get; set; } = null!; +} \ No newline at end of file diff --git a/src/X1.Application/Features/StackCoreIMSBindings/Queries/GetStackCoreIMSBindingById/GetStackCoreIMSBindingByIdQueryHandler.cs b/src/X1.Application/Features/StackCoreIMSBindings/Queries/GetStackCoreIMSBindingById/GetStackCoreIMSBindingByIdQueryHandler.cs new file mode 100644 index 0000000..9f87728 --- /dev/null +++ b/src/X1.Application/Features/StackCoreIMSBindings/Queries/GetStackCoreIMSBindingById/GetStackCoreIMSBindingByIdQueryHandler.cs @@ -0,0 +1,68 @@ +using MediatR; +using Microsoft.Extensions.Logging; +using CellularManagement.Domain.Common; +using CellularManagement.Domain.Repositories.NetworkProfile; + +namespace CellularManagement.Application.Features.StackCoreIMSBindings.Queries.GetStackCoreIMSBindingById; + +/// +/// 根据ID获取栈与核心网/IMS绑定关系查询处理器 +/// +public class GetStackCoreIMSBindingByIdQueryHandler : IRequestHandler> +{ + private readonly IStack_CoreIMS_BindingRepository _stackCoreIMSBindingRepository; + private readonly ILogger _logger; + + /// + /// 初始化查询处理器 + /// + public GetStackCoreIMSBindingByIdQueryHandler( + IStack_CoreIMS_BindingRepository stackCoreIMSBindingRepository, + ILogger logger) + { + _stackCoreIMSBindingRepository = stackCoreIMSBindingRepository; + _logger = logger; + } + + /// + /// 处理根据ID获取栈与核心网/IMS绑定关系查询 + /// + public async Task> Handle(GetStackCoreIMSBindingByIdQuery request, CancellationToken cancellationToken) + { + try + { + _logger.LogInformation("开始获取栈与核心网/IMS绑定关系,绑定ID: {StackCoreIMSBindingId}", request.StackCoreIMSBindingId); + + // 获取绑定关系 + var binding = await _stackCoreIMSBindingRepository.GetBindingByIdAsync(request.StackCoreIMSBindingId, cancellationToken); + if (binding == null) + { + _logger.LogWarning("栈与核心网/IMS绑定关系不存在: {StackCoreIMSBindingId}", request.StackCoreIMSBindingId); + return OperationResult.CreateFailure($"栈与核心网/IMS绑定关系 {request.StackCoreIMSBindingId} 不存在"); + } + + // 构建响应 + var response = new GetStackCoreIMSBindingByIdResponse + { + StackCoreIMSBindingId = binding.Id, + StackId = binding.StackId, + Index = binding.Index, + CnId = binding.CnId, + ImsId = binding.ImsId, + CreatedAt = binding.CreatedAt, + UpdatedAt = binding.UpdatedAt, + CreatedBy = binding.CreatedBy, + UpdatedBy = binding.UpdatedBy + }; + + _logger.LogInformation("成功获取栈与核心网/IMS绑定关系,绑定ID: {StackCoreIMSBindingId}, 栈ID: {StackId}, 索引: {Index}", + binding.Id, binding.StackId, binding.Index); + return OperationResult.CreateSuccess(response); + } + catch (Exception ex) + { + _logger.LogError(ex, "获取栈与核心网/IMS绑定关系时发生错误,绑定ID: {StackCoreIMSBindingId}", request.StackCoreIMSBindingId); + return OperationResult.CreateFailure($"获取栈与核心网/IMS绑定关系时发生错误: {ex.Message}"); + } + } +} \ No newline at end of file diff --git a/src/X1.Application/Features/StackCoreIMSBindings/Queries/GetStackCoreIMSBindingById/GetStackCoreIMSBindingByIdResponse.cs b/src/X1.Application/Features/StackCoreIMSBindings/Queries/GetStackCoreIMSBindingById/GetStackCoreIMSBindingByIdResponse.cs new file mode 100644 index 0000000..7f7fa14 --- /dev/null +++ b/src/X1.Application/Features/StackCoreIMSBindings/Queries/GetStackCoreIMSBindingById/GetStackCoreIMSBindingByIdResponse.cs @@ -0,0 +1,52 @@ +namespace CellularManagement.Application.Features.StackCoreIMSBindings.Queries.GetStackCoreIMSBindingById; + +/// +/// 根据ID获取栈与核心网/IMS绑定关系响应 +/// +public class GetStackCoreIMSBindingByIdResponse +{ + /// + /// 绑定关系ID + /// + public string StackCoreIMSBindingId { get; set; } = null!; + + /// + /// 栈ID(外键) + /// + public string StackId { get; set; } = null!; + + /// + /// 索引(主键的一部分) + /// + public int Index { get; set; } + + /// + /// 核心网配置ID(外键) + /// + public string CnId { get; set; } = null!; + + /// + /// IMS配置ID(外键) + /// + public string ImsId { get; set; } = null!; + + /// + /// 创建时间 + /// + public DateTime CreatedAt { get; set; } + + /// + /// 更新时间 + /// + public DateTime? UpdatedAt { get; set; } + + /// + /// 创建者 + /// + public string CreatedBy { get; set; } = null!; + + /// + /// 更新者 + /// + public string UpdatedBy { get; set; } = null!; +} \ No newline at end of file diff --git a/src/X1.Application/Features/StackCoreIMSBindings/Queries/GetStackCoreIMSBindings/GetStackCoreIMSBindingsQuery.cs b/src/X1.Application/Features/StackCoreIMSBindings/Queries/GetStackCoreIMSBindings/GetStackCoreIMSBindingsQuery.cs new file mode 100644 index 0000000..da7dc78 --- /dev/null +++ b/src/X1.Application/Features/StackCoreIMSBindings/Queries/GetStackCoreIMSBindings/GetStackCoreIMSBindingsQuery.cs @@ -0,0 +1,41 @@ +using CellularManagement.Domain.Common; +using MediatR; +using System.ComponentModel.DataAnnotations; + +namespace CellularManagement.Application.Features.StackCoreIMSBindings.Queries.GetStackCoreIMSBindings; + +/// +/// 获取栈与核心网/IMS绑定关系列表查询 +/// +public class GetStackCoreIMSBindingsQuery : IRequest> +{ + /// + /// 页码 + /// + [Range(1, int.MaxValue, ErrorMessage = "页码必须大于0")] + public int PageNumber { get; set; } = 1; + + /// + /// 每页数量 + /// + [Range(1, 100, ErrorMessage = "每页数量必须在1-100之间")] + public int PageSize { get; set; } = 10; + + /// + /// 栈ID(可选过滤条件) + /// + [MaxLength(50)] + public string? StackId { get; set; } + + /// + /// 核心网配置ID(可选过滤条件) + /// + [MaxLength(50)] + public string? CnId { get; set; } + + /// + /// IMS配置ID(可选过滤条件) + /// + [MaxLength(50)] + public string? ImsId { get; set; } +} \ No newline at end of file diff --git a/src/X1.Application/Features/StackCoreIMSBindings/Queries/GetStackCoreIMSBindings/GetStackCoreIMSBindingsQueryHandler.cs b/src/X1.Application/Features/StackCoreIMSBindings/Queries/GetStackCoreIMSBindings/GetStackCoreIMSBindingsQueryHandler.cs new file mode 100644 index 0000000..0d3d8e9 --- /dev/null +++ b/src/X1.Application/Features/StackCoreIMSBindings/Queries/GetStackCoreIMSBindings/GetStackCoreIMSBindingsQueryHandler.cs @@ -0,0 +1,80 @@ +using MediatR; +using Microsoft.Extensions.Logging; +using CellularManagement.Domain.Common; +using CellularManagement.Domain.Repositories.NetworkProfile; + +namespace CellularManagement.Application.Features.StackCoreIMSBindings.Queries.GetStackCoreIMSBindings; + +/// +/// 获取栈与核心网/IMS绑定关系列表查询处理器 +/// +public class GetStackCoreIMSBindingsQueryHandler : IRequestHandler> +{ + private readonly IStack_CoreIMS_BindingRepository _stackCoreIMSBindingRepository; + private readonly ILogger _logger; + + /// + /// 初始化查询处理器 + /// + public GetStackCoreIMSBindingsQueryHandler( + IStack_CoreIMS_BindingRepository stackCoreIMSBindingRepository, + ILogger logger) + { + _stackCoreIMSBindingRepository = stackCoreIMSBindingRepository; + _logger = logger; + } + + /// + /// 处理获取栈与核心网/IMS绑定关系列表查询 + /// + public async Task> Handle(GetStackCoreIMSBindingsQuery request, CancellationToken cancellationToken) + { + try + { + _logger.LogInformation("开始获取栈与核心网/IMS绑定关系列表,页码: {PageNumber}, 每页数量: {PageSize}, 栈ID: {StackId}, 核心网配置ID: {CnId}, IMS配置ID: {ImsId}", + request.PageNumber, request.PageSize, request.StackId ?? "无", request.CnId ?? "无", request.ImsId ?? "无"); + + // 获取绑定关系列表 + var (totalCount, items) = await _stackCoreIMSBindingRepository.SearchBindingsAsync( + request.StackId, + request.CnId, + request.ImsId, + request.PageNumber, + request.PageSize, + cancellationToken); + + // 计算总页数 + var totalPages = (int)Math.Ceiling((double)totalCount / request.PageSize); + + // 构建响应 + var response = new GetStackCoreIMSBindingsResponse + { + TotalCount = totalCount, + PageNumber = request.PageNumber, + PageSize = request.PageSize, + TotalPages = totalPages, + Items = items.Select(item => new StackCoreIMSBindingDto + { + StackCoreIMSBindingId = item.Id, + StackId = item.StackId, + Index = item.Index, + CnId = item.CnId, + ImsId = item.ImsId, + CreatedAt = item.CreatedAt, + UpdatedAt = item.UpdatedAt, + CreatedBy = item.CreatedBy, + UpdatedBy = item.UpdatedBy + }).ToList() + }; + + _logger.LogInformation("成功获取栈与核心网/IMS绑定关系列表,总数量: {TotalCount}, 当前页数量: {ItemCount}", + totalCount, items.Count); + return OperationResult.CreateSuccess(response); + } + catch (Exception ex) + { + _logger.LogError(ex, "获取栈与核心网/IMS绑定关系列表时发生错误"); + return OperationResult.CreateFailure($"获取栈与核心网/IMS绑定关系列表时发生错误: {ex.Message}"); + } + } +} \ No newline at end of file diff --git a/src/X1.Application/Features/StackCoreIMSBindings/Queries/GetStackCoreIMSBindings/GetStackCoreIMSBindingsResponse.cs b/src/X1.Application/Features/StackCoreIMSBindings/Queries/GetStackCoreIMSBindings/GetStackCoreIMSBindingsResponse.cs new file mode 100644 index 0000000..12ae98b --- /dev/null +++ b/src/X1.Application/Features/StackCoreIMSBindings/Queries/GetStackCoreIMSBindings/GetStackCoreIMSBindingsResponse.cs @@ -0,0 +1,83 @@ +namespace CellularManagement.Application.Features.StackCoreIMSBindings.Queries.GetStackCoreIMSBindings; + +/// +/// 获取栈与核心网/IMS绑定关系列表响应 +/// +public class GetStackCoreIMSBindingsResponse +{ + /// + /// 总数量 + /// + public int TotalCount { get; set; } + + /// + /// 当前页码 + /// + public int PageNumber { get; set; } + + /// + /// 每页数量 + /// + public int PageSize { get; set; } + + /// + /// 总页数 + /// + public int TotalPages { get; set; } + + /// + /// 栈与核心网/IMS绑定关系列表 + /// + public List Items { get; set; } = new(); +} + +/// +/// 栈与核心网/IMS绑定关系数据传输对象 +/// +public class StackCoreIMSBindingDto +{ + /// + /// 绑定关系ID + /// + public string StackCoreIMSBindingId { get; set; } = null!; + + /// + /// 栈ID(外键) + /// + public string StackId { get; set; } = null!; + + /// + /// 索引(主键的一部分) + /// + public int Index { get; set; } + + /// + /// 核心网配置ID(外键) + /// + public string CnId { get; set; } = null!; + + /// + /// IMS配置ID(外键) + /// + public string ImsId { get; set; } = null!; + + /// + /// 创建时间 + /// + public DateTime CreatedAt { get; set; } + + /// + /// 更新时间 + /// + public DateTime? UpdatedAt { get; set; } + + /// + /// 创建者 + /// + public string CreatedBy { get; set; } = null!; + + /// + /// 更新者 + /// + public string UpdatedBy { get; set; } = null!; +} \ No newline at end of file diff --git a/src/X1.Domain/Entities/Device/CellularDevice.cs b/src/X1.Domain/Entities/Device/CellularDevice.cs index 79d8b27..6caa921 100644 --- a/src/X1.Domain/Entities/Device/CellularDevice.cs +++ b/src/X1.Domain/Entities/Device/CellularDevice.cs @@ -32,16 +32,11 @@ public class CellularDevice : AuditableEntity public string Description { get; private set; } /// - /// 协议版本ID + /// 协议版本集合 /// - [Required] - public string ProtocolVersionId { get; private set; } + public virtual ICollection ProtocolVersions { get; private set; } = new List(); + - /// - /// 协议版本 - /// - [ForeignKey(nameof(ProtocolVersionId))] - public virtual ProtocolVersion ProtocolVersion { get; private set; } = null!; /// /// Agent端口 @@ -73,7 +68,6 @@ public class CellularDevice : AuditableEntity string name, string serialNumber, string description, - string protocolVersionId, int agentPort, string ipAddress, string createdBy, @@ -86,7 +80,6 @@ public class CellularDevice : AuditableEntity Name = name, SerialNumber = serialNumber, Description = description, - ProtocolVersionId = protocolVersionId, AgentPort = agentPort, IpAddress = ipAddress, IsEnabled = isEnabled, @@ -107,7 +100,6 @@ public class CellularDevice : AuditableEntity string name, string serialNumber, string description, - string protocolVersionId, int agentPort, string ipAddress, string updatedBy, @@ -117,7 +109,6 @@ public class CellularDevice : AuditableEntity Name = name; SerialNumber = serialNumber; Description = description; - ProtocolVersionId = protocolVersionId; AgentPort = agentPort; IpAddress = ipAddress; IsEnabled = isEnabled; diff --git a/src/X1.Domain/Entities/Device/NetworkConfig.cs b/src/X1.Domain/Entities/Device/NetworkConfig.cs deleted file mode 100644 index d425f83..0000000 --- a/src/X1.Domain/Entities/Device/NetworkConfig.cs +++ /dev/null @@ -1,173 +0,0 @@ -using System.ComponentModel.DataAnnotations; -using CellularManagement.Domain.Entities.Common; - -namespace CellularManagement.Domain.Entities.Device; - -/// -/// 网络配置类型枚举 -/// -public enum NetworkConfigType -{ - /// - /// RAN配置 - /// - RAN = 1, - - /// - /// IMS配置 - /// - IMS = 2, - - /// - /// MME配置 - /// - MME = 3 -} - -/// -/// 网络配置实体 -/// -public class NetworkConfig : AuditableEntity -{ - private NetworkConfig() { } - - /// - /// 配置类型 - /// - [Required] - public NetworkConfigType ConfigType { get; private set; } - - /// - /// 配置名称 - /// - [Required] - [MaxLength(100)] - public string Name { get; private set; } = null!; - - /// - /// PLMN字段(移动国家代码+移动网络代码) - /// - [MaxLength(10)] - public string? Plmn { get; private set; } - - /// - /// 配置内容(JSON格式) - /// - [Required] - public string ConfigContent { get; private set; } = null!; - - /// - /// 配置说明 - /// - [MaxLength(500)] - public string? Description { get; private set; } - - /// - /// 是否禁用 - /// - public bool IsDisabled { get; private set; } = false; - - /// - /// 创建网络配置 - /// - public static NetworkConfig Create( - NetworkConfigType configType, - string name, - string configContent, - string createdBy, - string? plmn = null, - string? description = null, - bool isDisabled = false) - { - // 验证业务规则 - ValidateCreateParameters(configType, plmn); - - var networkConfig = new NetworkConfig - { - Id = Guid.NewGuid().ToString(), - ConfigType = configType, - Name = name, - Plmn = plmn, - ConfigContent = configContent, - Description = description, - IsDisabled = isDisabled, - CreatedAt = DateTime.UtcNow, - UpdatedAt = DateTime.UtcNow, - CreatedBy = createdBy, - UpdatedBy = createdBy - }; - - return networkConfig; - } - - /// - /// 更新网络配置 - /// - public void Update( - string name, - string configContent, - string updatedBy, - string? plmn = null, - string? description = null, - bool isDisabled = false) - { - // 验证业务规则 - ValidateUpdateParameters(ConfigType, plmn); - - Name = name; - Plmn = plmn; - ConfigContent = configContent; - Description = description; - IsDisabled = isDisabled; - UpdatedAt = DateTime.UtcNow; - UpdatedBy = updatedBy; - } - - /// - /// 启用配置 - /// - public void Enable() - { - IsDisabled = false; - UpdatedAt = DateTime.UtcNow; - } - - /// - /// 禁用配置 - /// - public void Disable() - { - IsDisabled = true; - UpdatedAt = DateTime.UtcNow; - } - - /// - /// 验证创建参数 - /// - private static void ValidateCreateParameters(NetworkConfigType configType, string? plmn) - { - // 验证PLMN字段的必填性 - if (configType == NetworkConfigType.IMS || configType == NetworkConfigType.MME) - { - if (string.IsNullOrWhiteSpace(plmn)) - { - throw new ArgumentException($"PLMN字段对于{configType}类型是必填的"); - } - } - } - - /// - /// 验证更新参数 - /// - private static void ValidateUpdateParameters(NetworkConfigType configType, string? plmn) - { - // 验证PLMN字段的必填性 - if (configType == NetworkConfigType.IMS || configType == NetworkConfigType.MME) - { - if (string.IsNullOrWhiteSpace(plmn)) - { - throw new ArgumentException($"PLMN字段对于{configType}类型是必填的"); - } - } - } -} \ No newline at end of file diff --git a/src/X1.Domain/Entities/Device/ProtocolVersion.cs b/src/X1.Domain/Entities/Device/ProtocolVersion.cs index d4794ba..c06443c 100644 --- a/src/X1.Domain/Entities/Device/ProtocolVersion.cs +++ b/src/X1.Domain/Entities/Device/ProtocolVersion.cs @@ -48,12 +48,20 @@ public class ProtocolVersion : AuditableEntity [MaxLength(20)] public string? MinimumSupportedVersion { get; private set; } + /// + /// 设备序列号(外键) + /// + [Required] + [MaxLength(50)] + public string SerialNumber { get; private set; } = null!; + /// /// 创建协议版本 /// public static ProtocolVersion Create( string name, string version, + string serialNumber, string createdBy, string? description = null, bool isEnabled = true, @@ -65,6 +73,7 @@ public class ProtocolVersion : AuditableEntity Id = Guid.NewGuid().ToString(), Name = name, Version = version, + SerialNumber = serialNumber, Description = description, IsEnabled = isEnabled, ReleaseDate = releaseDate?.Kind == DateTimeKind.Utc ? releaseDate : releaseDate?.ToUniversalTime(), @@ -84,6 +93,7 @@ public class ProtocolVersion : AuditableEntity public void Update( string name, string version, + string serialNumber, string updatedBy, string? description = null, bool isEnabled = true, @@ -92,6 +102,7 @@ public class ProtocolVersion : AuditableEntity { Name = name; Version = version; + SerialNumber = serialNumber; Description = description; IsEnabled = isEnabled; ReleaseDate = releaseDate?.Kind == DateTimeKind.Utc ? releaseDate : releaseDate?.ToUniversalTime(); diff --git a/src/X1.Domain/Entities/NetworkProfile/CoreNetworkConfig.cs b/src/X1.Domain/Entities/NetworkProfile/CoreNetworkConfig.cs new file mode 100644 index 0000000..c0641e3 --- /dev/null +++ b/src/X1.Domain/Entities/NetworkProfile/CoreNetworkConfig.cs @@ -0,0 +1,98 @@ +using System.ComponentModel.DataAnnotations; +using CellularManagement.Domain.Entities.Common; + +namespace CellularManagement.Domain.Entities.NetworkProfile; + +/// +/// 核心网配置实体 +/// +public class CoreNetworkConfig : AuditableEntity +{ + private CoreNetworkConfig() { } + + /// + /// 配置名称 + /// + [Required] + [MaxLength(100)] + public string Name { get; private set; } = null!; + + /// + /// 配置内容(JSON格式) + /// + [Required] + public string ConfigContent { get; private set; } = null!; + + /// + /// 配置描述 + /// + [MaxLength(500)] + public string Description { get; private set; } + + /// + /// 是否禁用 + /// + public bool IsDisabled { get; private set; } = false; + + /// + /// 创建核心网配置 + /// + public static CoreNetworkConfig Create( + string name, + string configContent, + string createdBy, + string description = "", + bool isDisabled = false) + { + var coreNetworkConfig = new CoreNetworkConfig + { + Id = Guid.NewGuid().ToString(), + Name = name, + ConfigContent = configContent, + Description = description, + IsDisabled = isDisabled, + CreatedAt = DateTime.UtcNow, + UpdatedAt = DateTime.UtcNow, + CreatedBy = createdBy, + UpdatedBy = createdBy + }; + + return coreNetworkConfig; + } + + /// + /// 更新核心网配置 + /// + public void Update( + string name, + string configContent, + string updatedBy, + string description = "", + bool isDisabled = false) + { + Name = name; + ConfigContent = configContent; + Description = description; + IsDisabled = isDisabled; + UpdatedAt = DateTime.UtcNow; + UpdatedBy = updatedBy; + } + + /// + /// 启用配置 + /// + public void Enable() + { + IsDisabled = false; + UpdatedAt = DateTime.UtcNow; + } + + /// + /// 禁用配置 + /// + public void Disable() + { + IsDisabled = true; + UpdatedAt = DateTime.UtcNow; + } +} \ No newline at end of file diff --git a/src/X1.Domain/Entities/NetworkProfile/IMS_Configuration.cs b/src/X1.Domain/Entities/NetworkProfile/IMS_Configuration.cs new file mode 100644 index 0000000..da174ab --- /dev/null +++ b/src/X1.Domain/Entities/NetworkProfile/IMS_Configuration.cs @@ -0,0 +1,98 @@ +using System.ComponentModel.DataAnnotations; +using CellularManagement.Domain.Entities.Common; + +namespace CellularManagement.Domain.Entities.NetworkProfile; + +/// +/// IMS配置实体 +/// +public class IMS_Configuration : AuditableEntity +{ + private IMS_Configuration() { } + + /// + /// 配置名称 + /// + [Required] + [MaxLength(100)] + public string Name { get; private set; } = null!; + + /// + /// 配置内容(JSON格式) + /// + [Required] + public string ConfigContent { get; private set; } = null!; + + /// + /// 配置描述 + /// + [MaxLength(500)] + public string Description { get; private set; } + + /// + /// 是否禁用 + /// + public bool IsDisabled { get; private set; } = false; + + /// + /// 创建IMS配置 + /// + public static IMS_Configuration Create( + string name, + string configContent, + string createdBy, + string description = "", + bool isDisabled = false) + { + var imsConfig = new IMS_Configuration + { + Id = Guid.NewGuid().ToString(), + Name = name, + ConfigContent = configContent, + Description = description, + IsDisabled = isDisabled, + CreatedAt = DateTime.UtcNow, + UpdatedAt = DateTime.UtcNow, + CreatedBy = createdBy, + UpdatedBy = createdBy + }; + + return imsConfig; + } + + /// + /// 更新IMS配置 + /// + public void Update( + string name, + string configContent, + string updatedBy, + string description = "", + bool isDisabled = false) + { + Name = name; + ConfigContent = configContent; + Description = description; + IsDisabled = isDisabled; + UpdatedAt = DateTime.UtcNow; + UpdatedBy = updatedBy; + } + + /// + /// 启用配置 + /// + public void Enable() + { + IsDisabled = false; + UpdatedAt = DateTime.UtcNow; + } + + /// + /// 禁用配置 + /// + public void Disable() + { + IsDisabled = true; + UpdatedAt = DateTime.UtcNow; + } +} \ No newline at end of file diff --git a/src/X1.Domain/Entities/NetworkProfile/NetworkStackConfig.cs b/src/X1.Domain/Entities/NetworkProfile/NetworkStackConfig.cs new file mode 100644 index 0000000..9d8d3ac --- /dev/null +++ b/src/X1.Domain/Entities/NetworkProfile/NetworkStackConfig.cs @@ -0,0 +1,101 @@ +using System.ComponentModel.DataAnnotations; +using CellularManagement.Domain.Entities.Common; + +namespace CellularManagement.Domain.Entities.NetworkProfile; + +/// +/// 网络栈配置实体 +/// +public class NetworkStackConfig : AuditableEntity +{ + private NetworkStackConfig() { } + + /// + /// 栈ID(主键) + /// + [Required] + [MaxLength(50)] + public string StackId { get; private set; } = null!; + + /// + /// RAN配置ID(外键,可为空) + /// + [MaxLength(50)] + public string? RanId { get; private set; } + + /// + /// 描述 + /// + [MaxLength(500)] + public string? Description { get; private set; } + + /// + /// 是否激活 + /// + public bool IsActive { get; private set; } = true; + + /// + /// 栈与核心网/IMS绑定关系集合 + /// + public virtual ICollection StackCoreIMSBindings { get; private set; } = new List(); + + /// + /// 创建网络栈配置 + /// + public static NetworkStackConfig Create( + string stackId, + string createdBy, + string? ranId = null, + string? description = null, + bool isActive = true) + { + var networkStackConfig = new NetworkStackConfig + { + Id = Guid.NewGuid().ToString(), + StackId = stackId, + RanId = ranId, + Description = description, + IsActive = isActive, + CreatedAt = DateTime.UtcNow, + UpdatedAt = DateTime.UtcNow, + CreatedBy = createdBy, + UpdatedBy = createdBy + }; + + return networkStackConfig; + } + + /// + /// 更新网络栈配置 + /// + public void Update( + string updatedBy, + string? ranId = null, + string? description = null, + bool isActive = true) + { + RanId = ranId; + Description = description; + IsActive = isActive; + UpdatedAt = DateTime.UtcNow; + UpdatedBy = updatedBy; + } + + /// + /// 激活配置 + /// + public void Activate() + { + IsActive = true; + UpdatedAt = DateTime.UtcNow; + } + + /// + /// 停用配置 + /// + public void Deactivate() + { + IsActive = false; + UpdatedAt = DateTime.UtcNow; + } +} \ No newline at end of file diff --git a/src/X1.Domain/Entities/NetworkProfile/RAN_Configuration.cs b/src/X1.Domain/Entities/NetworkProfile/RAN_Configuration.cs new file mode 100644 index 0000000..01cac30 --- /dev/null +++ b/src/X1.Domain/Entities/NetworkProfile/RAN_Configuration.cs @@ -0,0 +1,98 @@ +using System.ComponentModel.DataAnnotations; +using CellularManagement.Domain.Entities.Common; + +namespace CellularManagement.Domain.Entities.NetworkProfile; + +/// +/// RAN配置实体 +/// +public class RAN_Configuration : AuditableEntity +{ + private RAN_Configuration() { } + + /// + /// 配置名称 + /// + [Required] + [MaxLength(100)] + public string Name { get; private set; } = null!; + + /// + /// 配置内容(JSON格式) + /// + [Required] + public string ConfigContent { get; private set; } = null!; + + /// + /// 配置描述 + /// + [MaxLength(500)] + public string Description { get; private set; } + + /// + /// 是否禁用 + /// + public bool IsDisabled { get; private set; } = false; + + /// + /// 创建RAN配置 + /// + public static RAN_Configuration Create( + string name, + string configContent, + string createdBy, + string description = "", + bool isDisabled = false) + { + var ranConfig = new RAN_Configuration + { + Id = Guid.NewGuid().ToString(), + Name = name, + ConfigContent = configContent, + Description = description, + IsDisabled = isDisabled, + CreatedAt = DateTime.UtcNow, + UpdatedAt = DateTime.UtcNow, + CreatedBy = createdBy, + UpdatedBy = createdBy + }; + + return ranConfig; + } + + /// + /// 更新RAN配置 + /// + public void Update( + string name, + string configContent, + string updatedBy, + string description = "", + bool isDisabled = false) + { + Name = name; + ConfigContent = configContent; + Description = description; + IsDisabled = isDisabled; + UpdatedAt = DateTime.UtcNow; + UpdatedBy = updatedBy; + } + + /// + /// 启用配置 + /// + public void Enable() + { + IsDisabled = false; + UpdatedAt = DateTime.UtcNow; + } + + /// + /// 禁用配置 + /// + public void Disable() + { + IsDisabled = true; + UpdatedAt = DateTime.UtcNow; + } +} \ No newline at end of file diff --git a/src/X1.Domain/Entities/NetworkProfile/Stack_CoreIMS_Binding.cs b/src/X1.Domain/Entities/NetworkProfile/Stack_CoreIMS_Binding.cs new file mode 100644 index 0000000..c0be6cb --- /dev/null +++ b/src/X1.Domain/Entities/NetworkProfile/Stack_CoreIMS_Binding.cs @@ -0,0 +1,96 @@ +using System.ComponentModel.DataAnnotations; +using CellularManagement.Domain.Entities.Common; + +namespace CellularManagement.Domain.Entities.NetworkProfile; + +/// +/// 栈与核心网/IMS绑定关系实体 +/// +public class Stack_CoreIMS_Binding : AuditableEntity +{ + private Stack_CoreIMS_Binding() { } + + /// + /// 栈ID(外键) + /// + [Required] + [MaxLength(50)] + public string StackId { get; private set; } = null!; + + /// + /// 索引(主键的一部分) + /// + [Required] + public int Index { get; private set; } + + /// + /// 核心网配置ID(外键) + /// + [Required] + [MaxLength(50)] + public string CnId { get; private set; } = null!; + + /// + /// IMS配置ID(外键) + /// + [Required] + [MaxLength(50)] + public string ImsId { get; private set; } = null!; + + /// + /// 网络栈配置(导航属性) + /// + public virtual NetworkStackConfig NetworkStackConfig { get; private set; } = null!; + + /// + /// 核心网配置(导航属性) + /// + public virtual CoreNetworkConfig CoreNetworkConfig { get; private set; } = null!; + + /// + /// IMS配置(导航属性) + /// + public virtual IMS_Configuration IMSConfiguration { get; private set; } = null!; + + /// + /// 创建栈与核心网/IMS绑定关系 + /// + public static Stack_CoreIMS_Binding Create( + string stackId, + int index, + string cnId, + string imsId, + string createdBy) + { + var binding = new Stack_CoreIMS_Binding + { + Id = Guid.NewGuid().ToString(), + StackId = stackId, + Index = index, + CnId = cnId, + ImsId = imsId, + CreatedAt = DateTime.UtcNow, + UpdatedAt = DateTime.UtcNow, + CreatedBy = createdBy, + UpdatedBy = createdBy + }; + + return binding; + } + + /// + /// 更新绑定关系 + /// + public void Update( + int index, + string cnId, + string imsId, + string updatedBy) + { + Index = index; + CnId = cnId; + ImsId = imsId; + UpdatedAt = DateTime.UtcNow; + UpdatedBy = updatedBy; + } +} \ No newline at end of file diff --git a/src/X1.Domain/Repositories/Device/ICellularDeviceRepository.cs b/src/X1.Domain/Repositories/Device/ICellularDeviceRepository.cs index 90c3516..dd7ac86 100644 --- a/src/X1.Domain/Repositories/Device/ICellularDeviceRepository.cs +++ b/src/X1.Domain/Repositories/Device/ICellularDeviceRepository.cs @@ -48,9 +48,9 @@ public interface ICellularDeviceRepository : IBaseRepository CancellationToken cancellationToken = default); /// - /// 搜索蜂窝设备(包含协议版本导航属性) + /// 搜索蜂窝设备 /// - Task<(int TotalCount, IList Items)> SearchDevicesWithProtocolVersionAsync( + Task<(int TotalCount, IList Items)> SearchDevicesAsync( string? keyword, int pageNumber, int pageSize, diff --git a/src/X1.Domain/Repositories/Device/INetworkConfigRepository.cs b/src/X1.Domain/Repositories/Device/INetworkConfigRepository.cs deleted file mode 100644 index bb14467..0000000 --- a/src/X1.Domain/Repositories/Device/INetworkConfigRepository.cs +++ /dev/null @@ -1,78 +0,0 @@ -using CellularManagement.Domain.Entities.Device; - -namespace CellularManagement.Domain.Repositories.Device; - -/// -/// 网络配置仓储接口 -/// -public interface INetworkConfigRepository -{ - /// - /// 根据ID获取网络配置 - /// - Task GetNetworkConfigByIdAsync(string id, CancellationToken cancellationToken = default); - - /// - /// 根据配置类型获取网络配置列表 - /// - Task> GetNetworkConfigsByTypeAsync(NetworkConfigType configType, CancellationToken cancellationToken = default); - - /// - /// 根据PLMN获取网络配置列表 - /// - Task> GetNetworkConfigsByPlmnAsync(string plmn, CancellationToken cancellationToken = default); - - /// - /// 根据配置类型和PLMN获取网络配置列表 - /// - Task> GetNetworkConfigsByTypeAndPlmnAsync(NetworkConfigType configType, string plmn, CancellationToken cancellationToken = default); - - /// - /// 获取启用的网络配置 - /// - Task> GetEnabledNetworkConfigsAsync(CancellationToken cancellationToken = default); - - /// - /// 获取所有网络配置 - /// - Task> GetAllNetworkConfigsAsync(CancellationToken cancellationToken = default); - - /// - /// 添加网络配置 - /// - Task AddNetworkConfigAsync(NetworkConfig networkConfig, CancellationToken cancellationToken = default); - - /// - /// 更新网络配置 - /// - void UpdateNetworkConfig(NetworkConfig networkConfig); - - /// - /// 删除网络配置 - /// - Task DeleteNetworkConfigAsync(string id, CancellationToken cancellationToken = default); - - /// - /// 搜索网络配置 - /// - Task> SearchNetworkConfigsAsync( - string? keyword, - NetworkConfigType? configType = null, - string? plmn = null, - CancellationToken cancellationToken = default); - - /// - /// 检查网络配置是否存在 - /// - Task ExistsAsync(string id, CancellationToken cancellationToken = default); - - /// - /// 检查配置名称是否存在 - /// - Task NameExistsAsync(string name, CancellationToken cancellationToken = default); - - /// - /// 检查配置名称是否存在(排除指定ID) - /// - Task NameExistsAsync(string name, string excludeId, CancellationToken cancellationToken = default); -} \ No newline at end of file diff --git a/src/X1.Domain/Repositories/NetworkProfile/ICoreNetworkConfigRepository.cs b/src/X1.Domain/Repositories/NetworkProfile/ICoreNetworkConfigRepository.cs new file mode 100644 index 0000000..d4754b6 --- /dev/null +++ b/src/X1.Domain/Repositories/NetworkProfile/ICoreNetworkConfigRepository.cs @@ -0,0 +1,66 @@ +using CellularManagement.Domain.Entities.NetworkProfile; +using CellularManagement.Domain.Repositories.Base; + +namespace CellularManagement.Domain.Repositories.NetworkProfile; + +/// +/// 核心网配置仓储接口 +/// +public interface ICoreNetworkConfigRepository : IBaseRepository +{ + /// + /// 添加核心网配置 + /// + Task AddCoreNetworkConfigAsync(CoreNetworkConfig coreNetworkConfig, CancellationToken cancellationToken = default); + + /// + /// 更新核心网配置 + /// + void UpdateCoreNetworkConfig(CoreNetworkConfig coreNetworkConfig); + + /// + /// 删除核心网配置 + /// + Task DeleteCoreNetworkConfigAsync(string id, CancellationToken cancellationToken = default); + + /// + /// 获取所有核心网配置 + /// + Task> GetAllCoreNetworkConfigsAsync(CancellationToken cancellationToken = default); + + /// + /// 根据ID获取核心网配置 + /// + Task GetCoreNetworkConfigByIdAsync(string id, CancellationToken cancellationToken = default); + + /// + /// 根据名称获取核心网配置 + /// + Task GetCoreNetworkConfigByNameAsync(string name, CancellationToken cancellationToken = default); + + /// + /// 搜索核心网配置 + /// + Task> SearchCoreNetworkConfigsAsync( + string? keyword, + CancellationToken cancellationToken = default); + + /// + /// 搜索核心网配置(分页) + /// + Task<(int TotalCount, IList Items)> SearchCoreNetworkConfigsAsync( + string? keyword, + int pageNumber, + int pageSize, + CancellationToken cancellationToken = default); + + /// + /// 检查核心网配置是否存在 + /// + Task ExistsAsync(string id, CancellationToken cancellationToken = default); + + /// + /// 检查配置名称是否存在 + /// + Task NameExistsAsync(string name, CancellationToken cancellationToken = default); +} \ No newline at end of file diff --git a/src/X1.Domain/Repositories/NetworkProfile/IIMS_ConfigurationRepository.cs b/src/X1.Domain/Repositories/NetworkProfile/IIMS_ConfigurationRepository.cs new file mode 100644 index 0000000..2d4f1e6 --- /dev/null +++ b/src/X1.Domain/Repositories/NetworkProfile/IIMS_ConfigurationRepository.cs @@ -0,0 +1,66 @@ +using CellularManagement.Domain.Entities.NetworkProfile; +using CellularManagement.Domain.Repositories.Base; + +namespace CellularManagement.Domain.Repositories.NetworkProfile; + +/// +/// IMS配置仓储接口 +/// +public interface IIMS_ConfigurationRepository : IBaseRepository +{ + /// + /// 添加IMS配置 + /// + Task AddIMS_ConfigurationAsync(IMS_Configuration imsConfig, CancellationToken cancellationToken = default); + + /// + /// 更新IMS配置 + /// + void UpdateIMS_Configuration(IMS_Configuration imsConfig); + + /// + /// 删除IMS配置 + /// + Task DeleteIMS_ConfigurationAsync(string id, CancellationToken cancellationToken = default); + + /// + /// 获取所有IMS配置 + /// + Task> GetAllIMS_ConfigurationsAsync(CancellationToken cancellationToken = default); + + /// + /// 根据ID获取IMS配置 + /// + Task GetIMS_ConfigurationByIdAsync(string id, CancellationToken cancellationToken = default); + + /// + /// 根据名称获取IMS配置 + /// + Task GetIMS_ConfigurationByNameAsync(string name, CancellationToken cancellationToken = default); + + /// + /// 搜索IMS配置 + /// + Task> SearchIMS_ConfigurationsAsync( + string? keyword, + CancellationToken cancellationToken = default); + + /// + /// 搜索IMS配置(分页) + /// + Task<(int TotalCount, IList Items)> SearchIMS_ConfigurationsAsync( + string? keyword, + int pageNumber, + int pageSize, + CancellationToken cancellationToken = default); + + /// + /// 检查IMS配置是否存在 + /// + Task ExistsAsync(string id, CancellationToken cancellationToken = default); + + /// + /// 检查配置名称是否存在 + /// + Task NameExistsAsync(string name, CancellationToken cancellationToken = default); +} \ No newline at end of file diff --git a/src/X1.Domain/Repositories/NetworkProfile/INetworkStackConfigRepository.cs b/src/X1.Domain/Repositories/NetworkProfile/INetworkStackConfigRepository.cs new file mode 100644 index 0000000..326afdb --- /dev/null +++ b/src/X1.Domain/Repositories/NetworkProfile/INetworkStackConfigRepository.cs @@ -0,0 +1,76 @@ +using CellularManagement.Domain.Entities.NetworkProfile; +using CellularManagement.Domain.Repositories.Base; + +namespace CellularManagement.Domain.Repositories.NetworkProfile; + +/// +/// 网络栈配置仓储接口 +/// +public interface INetworkStackConfigRepository : IBaseRepository +{ + /// + /// 添加网络栈配置 + /// + Task AddNetworkStackConfigAsync(NetworkStackConfig networkStackConfig, CancellationToken cancellationToken = default); + + /// + /// 更新网络栈配置 + /// + void UpdateNetworkStackConfig(NetworkStackConfig networkStackConfig); + + /// + /// 删除网络栈配置 + /// + Task DeleteNetworkStackConfigAsync(string id, CancellationToken cancellationToken = default); + + /// + /// 获取所有网络栈配置 + /// + Task> GetAllNetworkStackConfigsAsync(CancellationToken cancellationToken = default); + + /// + /// 根据ID获取网络栈配置 + /// + Task GetNetworkStackConfigByIdAsync(string id, CancellationToken cancellationToken = default); + + /// + /// 根据栈ID获取网络栈配置 + /// + Task GetNetworkStackConfigByStackIdAsync(string stackId, CancellationToken cancellationToken = default); + + /// + /// 根据RAN ID获取网络栈配置 + /// + Task> GetNetworkStackConfigsByRanIdAsync(string ranId, CancellationToken cancellationToken = default); + + /// + /// 获取激活的网络栈配置 + /// + Task> GetActiveNetworkStackConfigsAsync(CancellationToken cancellationToken = default); + + /// + /// 搜索网络栈配置 + /// + Task> SearchNetworkStackConfigsAsync( + string? keyword, + CancellationToken cancellationToken = default); + + /// + /// 搜索网络栈配置(分页) + /// + Task<(int TotalCount, IList Items)> SearchNetworkStackConfigsAsync( + string? keyword, + int pageNumber, + int pageSize, + CancellationToken cancellationToken = default); + + /// + /// 检查网络栈配置是否存在 + /// + Task ExistsAsync(string id, CancellationToken cancellationToken = default); + + /// + /// 检查栈ID是否存在 + /// + Task StackIdExistsAsync(string stackId, CancellationToken cancellationToken = default); +} \ No newline at end of file diff --git a/src/X1.Domain/Repositories/NetworkProfile/IRAN_ConfigurationRepository.cs b/src/X1.Domain/Repositories/NetworkProfile/IRAN_ConfigurationRepository.cs new file mode 100644 index 0000000..f7e8118 --- /dev/null +++ b/src/X1.Domain/Repositories/NetworkProfile/IRAN_ConfigurationRepository.cs @@ -0,0 +1,66 @@ +using CellularManagement.Domain.Entities.NetworkProfile; +using CellularManagement.Domain.Repositories.Base; + +namespace CellularManagement.Domain.Repositories.NetworkProfile; + +/// +/// RAN配置仓储接口 +/// +public interface IRAN_ConfigurationRepository : IBaseRepository +{ + /// + /// 添加RAN配置 + /// + Task AddRAN_ConfigurationAsync(RAN_Configuration ranConfig, CancellationToken cancellationToken = default); + + /// + /// 更新RAN配置 + /// + void UpdateRAN_Configuration(RAN_Configuration ranConfig); + + /// + /// 删除RAN配置 + /// + Task DeleteRAN_ConfigurationAsync(string id, CancellationToken cancellationToken = default); + + /// + /// 获取所有RAN配置 + /// + Task> GetAllRAN_ConfigurationsAsync(CancellationToken cancellationToken = default); + + /// + /// 根据ID获取RAN配置 + /// + Task GetRAN_ConfigurationByIdAsync(string id, CancellationToken cancellationToken = default); + + /// + /// 根据名称获取RAN配置 + /// + Task GetRAN_ConfigurationByNameAsync(string name, CancellationToken cancellationToken = default); + + /// + /// 搜索RAN配置 + /// + Task> SearchRAN_ConfigurationsAsync( + string? keyword, + CancellationToken cancellationToken = default); + + /// + /// 搜索RAN配置(分页) + /// + Task<(int TotalCount, IList Items)> SearchRAN_ConfigurationsAsync( + string? keyword, + int pageNumber, + int pageSize, + CancellationToken cancellationToken = default); + + /// + /// 检查RAN配置是否存在 + /// + Task ExistsAsync(string id, CancellationToken cancellationToken = default); + + /// + /// 检查配置名称是否存在 + /// + Task NameExistsAsync(string name, CancellationToken cancellationToken = default); +} \ No newline at end of file diff --git a/src/X1.Domain/Repositories/NetworkProfile/IStack_CoreIMS_BindingRepository.cs b/src/X1.Domain/Repositories/NetworkProfile/IStack_CoreIMS_BindingRepository.cs new file mode 100644 index 0000000..ced0e59 --- /dev/null +++ b/src/X1.Domain/Repositories/NetworkProfile/IStack_CoreIMS_BindingRepository.cs @@ -0,0 +1,85 @@ +using CellularManagement.Domain.Entities.NetworkProfile; +using CellularManagement.Domain.Repositories.Base; + +namespace CellularManagement.Domain.Repositories.NetworkProfile; + +/// +/// 栈与核心网/IMS绑定关系仓储接口 +/// +public interface IStack_CoreIMS_BindingRepository : IBaseRepository +{ + /// + /// 添加绑定关系 + /// + Task AddBindingAsync(Stack_CoreIMS_Binding binding, CancellationToken cancellationToken = default); + + /// + /// 更新绑定关系 + /// + void UpdateBinding(Stack_CoreIMS_Binding binding); + + /// + /// 删除绑定关系 + /// + Task DeleteBindingAsync(string id, CancellationToken cancellationToken = default); + + /// + /// 获取所有绑定关系 + /// + Task> GetAllBindingsAsync(CancellationToken cancellationToken = default); + + /// + /// 根据ID获取绑定关系 + /// + Task GetBindingByIdAsync(string id, CancellationToken cancellationToken = default); + + /// + /// 根据栈ID获取绑定关系 + /// + Task> GetBindingsByStackIdAsync(string stackId, CancellationToken cancellationToken = default); + + /// + /// 根据核心网配置ID获取绑定关系 + /// + Task> GetBindingsByCnIdAsync(string cnId, CancellationToken cancellationToken = default); + + /// + /// 根据IMS配置ID获取绑定关系 + /// + Task> GetBindingsByImsIdAsync(string imsId, CancellationToken cancellationToken = default); + + /// + /// 根据栈ID和索引获取绑定关系 + /// + Task GetBindingByStackIdAndIndexAsync(string stackId, int index, CancellationToken cancellationToken = default); + + /// + /// 搜索绑定关系 + /// + Task> SearchBindingsAsync( + string? stackId = null, + string? cnId = null, + string? imsId = null, + CancellationToken cancellationToken = default); + + /// + /// 搜索绑定关系(分页) + /// + Task<(int TotalCount, IList Items)> SearchBindingsAsync( + string? stackId = null, + string? cnId = null, + string? imsId = null, + int pageNumber = 1, + int pageSize = 10, + CancellationToken cancellationToken = default); + + /// + /// 检查绑定关系是否存在 + /// + Task ExistsAsync(string id, CancellationToken cancellationToken = default); + + /// + /// 检查栈ID和索引的组合是否存在 + /// + Task StackIdAndIndexExistsAsync(string stackId, int index, CancellationToken cancellationToken = default); +} \ No newline at end of file diff --git a/src/X1.Domain/Specifications/NetworkConfigSamples.json b/src/X1.Domain/Specifications/NetworkConfigSamples.json deleted file mode 100644 index 235dc43..0000000 --- a/src/X1.Domain/Specifications/NetworkConfigSamples.json +++ /dev/null @@ -1,226 +0,0 @@ -{ - "networkConfigs": [ - { - "configType": "RAN", - "name": "RAN_Config_Default", - "plmn": null, - "configContent": { - "frequencyBands": ["B1", "B3", "B5", "B8"], - "bandwidth": "20MHz", - "powerControl": { - "maxPower": 43, - "minPower": 23, - "powerStep": 1 - }, - "antennaConfig": { - "antennaCount": 4, - "mimoMode": "4x4", - "beamforming": true - }, - "scheduling": { - "schedulerType": "ProportionalFair", - "qosEnabled": true, - "priorityLevels": 8 - } - }, - "description": "默认RAN配置,支持多频段和4x4 MIMO", - "isDisabled": false - }, - { - "configType": "IMS", - "name": "IMS_Config_ChinaMobile", - "plmn": "46000", - "configContent": { - "pCscfServers": [ - { - "address": "10.1.1.100", - "port": 5060, - "transport": "UDP" - }, - { - "address": "10.1.1.101", - "port": 5060, - "transport": "UDP" - } - ], - "sCscfServers": [ - { - "address": "10.2.1.100", - "port": 5060, - "transport": "UDP" - } - ], - "iCscfServers": [ - { - "address": "10.3.1.100", - "port": 5060, - "transport": "UDP" - } - ], - "hssServers": [ - { - "address": "10.4.1.100", - "port": 3868, - "transport": "SCTP" - } - ], - "dnsServers": [ - "8.8.8.8", - "114.114.114.114" - ], - "qosSettings": { - "qci": 5, - "arp": { - "priority": 1, - "preemptionCapability": false, - "preemptionVulnerability": false - } - } - }, - "description": "中国移动IMS配置,包含完整的IMS核心网服务器配置", - "isDisabled": false - }, - { - "configType": "IMS", - "name": "IMS_Config_ChinaUnicom", - "plmn": "46001", - "configContent": { - "pCscfServers": [ - { - "address": "10.1.2.100", - "port": 5060, - "transport": "UDP" - } - ], - "sCscfServers": [ - { - "address": "10.2.2.100", - "port": 5060, - "transport": "UDP" - } - ], - "iCscfServers": [ - { - "address": "10.3.2.100", - "port": 5060, - "transport": "UDP" - } - ], - "hssServers": [ - { - "address": "10.4.2.100", - "port": 3868, - "transport": "SCTP" - } - ], - "dnsServers": [ - "8.8.8.8", - "223.5.5.5" - ], - "qosSettings": { - "qci": 5, - "arp": { - "priority": 1, - "preemptionCapability": false, - "preemptionVulnerability": false - } - } - }, - "description": "中国联通IMS配置", - "isDisabled": false - }, - { - "configType": "MME", - "name": "MME_Config_Primary", - "plmn": "46000", - "configContent": { - "mmeCode": "001", - "mmeGroupId": "001", - "tacList": ["0001", "0002", "0003"], - "servingGwList": [ - { - "address": "10.5.1.100", - "weight": 100 - }, - { - "address": "10.5.1.101", - "weight": 100 - } - ], - "pdnGwList": [ - { - "address": "10.6.1.100", - "weight": 100 - } - ], - "hssServers": [ - { - "address": "10.4.1.100", - "port": 3868, - "transport": "SCTP" - } - ], - "sgsnServers": [ - { - "address": "10.7.1.100", - "port": 2123, - "transport": "SCTP" - } - ], - "securitySettings": { - "integrityAlgorithm": ["EIA1", "EIA2", "EIA3"], - "cipheringAlgorithm": ["EEA1", "EEA2", "EEA3"], - "authenticationAlgorithm": "MILENAGE" - }, - "loadBalancing": { - "enabled": true, - "algorithm": "RoundRobin", - "maxLoad": 80 - } - }, - "description": "主MME配置,支持负载均衡和多种安全算法", - "isDisabled": false - }, - { - "configType": "MME", - "name": "MME_Config_Secondary", - "plmn": "46000", - "configContent": { - "mmeCode": "002", - "mmeGroupId": "001", - "tacList": ["0004", "0005", "0006"], - "servingGwList": [ - { - "address": "10.5.2.100", - "weight": 100 - } - ], - "pdnGwList": [ - { - "address": "10.6.2.100", - "weight": 100 - } - ], - "hssServers": [ - { - "address": "10.4.1.100", - "port": 3868, - "transport": "SCTP" - } - ], - "securitySettings": { - "integrityAlgorithm": ["EIA1", "EIA2", "EIA3"], - "cipheringAlgorithm": ["EEA1", "EEA2", "EEA3"], - "authenticationAlgorithm": "MILENAGE" - }, - "loadBalancing": { - "enabled": true, - "algorithm": "RoundRobin", - "maxLoad": 80 - } - }, - "description": "备用MME配置,与主MME形成冗余", - "isDisabled": false - } - ] -} \ No newline at end of file diff --git a/src/X1.Domain/Specifications/NetworkConfig_README.md b/src/X1.Domain/Specifications/NetworkConfig_README.md deleted file mode 100644 index c55e3af..0000000 --- a/src/X1.Domain/Specifications/NetworkConfig_README.md +++ /dev/null @@ -1,191 +0,0 @@ -# 网络配置管理功能 - -## 概述 - -网络配置管理功能提供了对RAN、IMS、MME三种网络配置的统一管理,支持配置的创建、查询、更新和删除操作。 - -## 配置类型 - -### 1. RAN配置 (Radio Access Network) -- **用途**: 无线接入网络配置 -- **特点**: - - 不需要PLMN字段 - - 不需要配置索引 - - 包含频段、带宽、功率控制、天线配置等参数 - -### 2. IMS配置 (IP Multimedia Subsystem) -- **用途**: IP多媒体子系统配置 -- **特点**: - - 必须提供PLMN字段 - - 必须提供配置索引(可等于0) - - 包含P-CSCF、S-CSCF、I-CSCF、HSS等服务器配置 - -### 3. MME配置 (Mobility Management Entity) -- **用途**: 移动性管理实体配置 -- **特点**: - - 必须提供PLMN字段 - - 必须提供配置索引(可等于0) - - 包含MME代码、TAC列表、网关配置等参数 - -## 数据库设计 - -### 表结构 -```sql -CREATE TABLE "NetworkConfigs" ( - "Id" character varying(450) NOT NULL, - "ConfigType" integer NOT NULL, - "Name" character varying(100) NOT NULL, - "ConfigIndex" integer, - "Plmn" character varying(10), - "ConfigContent" jsonb NOT NULL, - "Description" character varying(500), - "IsDisabled" boolean NOT NULL DEFAULT false, - "CreatedAt" timestamp with time zone NOT NULL, - "UpdatedAt" timestamp with time zone NOT NULL, - "CreatedBy" character varying(450) NOT NULL, - "UpdatedBy" character varying(450) NOT NULL, - "IsDeleted" boolean NOT NULL DEFAULT false, - CONSTRAINT "PK_NetworkConfigs" PRIMARY KEY ("Id") -); -``` - -### 索引 -- `IX_NetworkConfigs_ConfigType` - 配置类型索引 -- `IX_NetworkConfigs_Name` - 名称唯一索引 -- `IX_NetworkConfigs_Plmn` - PLMN索引 -- `IX_NetworkConfigs_ConfigIndex` - 配置索引 -- `IX_NetworkConfigs_IsDisabled` - 禁用状态索引 -- `IX_NetworkConfigs_ConfigType_Plmn` - 配置类型和PLMN复合索引 -- `IX_NetworkConfigs_ConfigType_ConfigIndex` - 配置类型和索引复合索引 - -### 约束 -- `CK_NetworkConfigs_ConfigIndex_RAN` - RAN类型不能有配置索引 -- `CK_NetworkConfigs_ConfigIndex_IMS_MME` - IMS/MME类型必须有配置索引 -- `CK_NetworkConfigs_Plmn_IMS_MME` - IMS/MME类型必须有PLMN - -## API接口 - -### 1. 创建网络配置 -```http -POST /api/NetworkConfigs -Content-Type: application/json - -{ - "configType": 1, - "name": "RAN_Config_Default", - "configIndex": null, - "plmn": null, - "configContent": "{\"frequencyBands\":[\"B1\",\"B3\"]}", - "description": "默认RAN配置", - "isDisabled": false -} -``` - -### 2. 获取网络配置列表 -```http -GET /api/NetworkConfigs?configType=1&onlyEnabled=true -``` - -### 3. 根据类型获取配置 -```http -GET /api/NetworkConfigs/type/1 -``` - -### 4. 根据PLMN获取配置 -```http -GET /api/NetworkConfigs/plmn/46000 -``` - -### 5. 搜索网络配置 -```http -GET /api/NetworkConfigs/search?keyword=RAN&configType=1 -``` - -## 使用示例 - -### 创建RAN配置 -```csharp -var command = new CreateNetworkConfigCommand -{ - ConfigType = NetworkConfigType.RAN, - Name = "RAN_Config_Default", - ConfigContent = JsonSerializer.Serialize(new - { - frequencyBands = new[] { "B1", "B3", "B5", "B8" }, - bandwidth = "20MHz", - powerControl = new - { - maxPower = 43, - minPower = 23, - powerStep = 1 - } - }), - Description = "默认RAN配置" -}; - -var result = await mediator.Send(command); -``` - -### 创建IMS配置 -```csharp -var command = new CreateNetworkConfigCommand -{ - ConfigType = NetworkConfigType.IMS, - Name = "IMS_Config_ChinaMobile", - ConfigIndex = 0, - Plmn = "46000", - ConfigContent = JsonSerializer.Serialize(new - { - pCscfServers = new[] - { - new { address = "10.1.1.100", port = 5060, transport = "UDP" } - }, - sCscfServers = new[] - { - new { address = "10.2.1.100", port = 5060, transport = "UDP" } - } - }), - Description = "中国移动IMS配置" -}; - -var result = await mediator.Send(command); -``` - -### 查询配置 -```csharp -// 获取所有启用的配置 -var query = new GetNetworkConfigsQuery { OnlyEnabled = true }; -var result = await mediator.Send(query); - -// 根据类型和PLMN查询 -var query = new GetNetworkConfigsQuery -{ - ConfigType = NetworkConfigType.IMS, - Plmn = "46000" -}; -var result = await mediator.Send(query); -``` - -## 业务规则 - -1. **配置名称唯一性**: 所有配置的名称必须唯一 -2. **RAN配置规则**: - - 不能有配置索引 - - 不能有PLMN字段 -3. **IMS/MME配置规则**: - - 必须有PLMN字段 - - 必须有配置索引(可等于0) -4. **配置内容**: 必须为有效的JSON格式 -5. **软删除**: 支持软删除,删除后数据仍保留但不可见 - -## 性能优化 - -1. **JSONB索引**: 对ConfigContent字段使用JSONB类型,支持高效的JSON查询 -2. **复合索引**: 针对常用查询场景创建复合索引 -3. **查询优化**: 使用仓储模式,支持灵活的查询条件组合 - -## 扩展性 - -1. **配置类型扩展**: 可以通过添加新的枚举值来支持更多配置类型 -2. **字段扩展**: 可以在ConfigContent中添加新的配置参数 -3. **验证规则扩展**: 可以为不同配置类型添加特定的验证规则 \ No newline at end of file diff --git a/src/X1.Domain/Specifications/NetworkConfig_Test.http b/src/X1.Domain/Specifications/NetworkConfig_Test.http deleted file mode 100644 index 3c98dc8..0000000 --- a/src/X1.Domain/Specifications/NetworkConfig_Test.http +++ /dev/null @@ -1,90 +0,0 @@ -### 网络配置管理API测试 - -### 1. 创建RAN配置 -POST {{baseUrl}}/api/networkconfigs -Content-Type: application/json -Authorization: Bearer {{token}} - -{ - "configType": 1, - "name": "RAN_Config_Test", - "plmn": null, - "configContent": "{\"frequencyBands\":[\"B1\",\"B3\"],\"bandwidth\":\"20MHz\",\"powerControl\":{\"maxPower\":43,\"minPower\":23}}", - "description": "测试RAN配置", - "isDisabled": false -} - -### 2. 创建IMS配置 -POST {{baseUrl}}/api/networkconfigs -Content-Type: application/json -Authorization: Bearer {{token}} - -{ - "configType": 2, - "name": "IMS_Config_Test", - "plmn": "46000", - "configContent": "{\"pCscfServers\":[{\"address\":\"10.1.1.100\",\"port\":5060,\"transport\":\"UDP\"}],\"sCscfServers\":[{\"address\":\"10.2.1.100\",\"port\":5060,\"transport\":\"UDP\"}]}", - "description": "测试IMS配置", - "isDisabled": false -} - -### 3. 创建MME配置 -POST {{baseUrl}}/api/networkconfigs -Content-Type: application/json -Authorization: Bearer {{token}} - -{ - "configType": 3, - "name": "MME_Config_Test", - "plmn": "46000", - "configContent": "{\"mmeCode\":\"001\",\"mmeGroupId\":\"001\",\"tacList\":[\"0001\",\"0002\"],\"servingGwList\":[{\"address\":\"10.5.1.100\",\"weight\":100}]}", - "description": "测试MME配置", - "isDisabled": false -} - -### 4. 获取网络配置列表 -GET {{baseUrl}}/api/networkconfigs?pageNumber=1&pageSize=10 -Authorization: Bearer {{token}} - -### 5. 根据配置类型获取 -GET {{baseUrl}}/api/networkconfigs?configType=1&pageNumber=1&pageSize=10 -Authorization: Bearer {{token}} - -### 6. 根据PLMN获取 -GET {{baseUrl}}/api/networkconfigs?plmn=46000&pageNumber=1&pageSize=10 -Authorization: Bearer {{token}} - -### 7. 搜索配置 -GET {{baseUrl}}/api/networkconfigs?keyword=Test&pageNumber=1&pageSize=10 -Authorization: Bearer {{token}} - -### 8. 获取启用的配置 -GET {{baseUrl}}/api/networkconfigs?onlyEnabled=true&pageNumber=1&pageSize=10 -Authorization: Bearer {{token}} - -### 9. 获取配置详情 -GET {{baseUrl}}/api/networkconfigs/{{networkConfigId}} -Authorization: Bearer {{token}} - -### 10. 更新配置 -PUT {{baseUrl}}/api/networkconfigs/{{networkConfigId}} -Content-Type: application/json -Authorization: Bearer {{token}} - -{ - "networkConfigId": "{{networkConfigId}}", - "name": "RAN_Config_Updated", - "plmn": null, - "configContent": "{\"frequencyBands\":[\"B1\",\"B3\",\"B5\"],\"bandwidth\":\"40MHz\",\"powerControl\":{\"maxPower\":46,\"minPower\":20}}", - "description": "更新后的RAN配置", - "isDisabled": false -} - -### 11. 删除配置 -DELETE {{baseUrl}}/api/networkconfigs/{{networkConfigId}} -Authorization: Bearer {{token}} - -### 环境变量设置 -# baseUrl: http://localhost:5000 -# token: your_jwt_token_here -# networkConfigId: your_network_config_id_here \ No newline at end of file diff --git a/src/X1.Infrastructure/Configurations/Device/CellularDeviceConfiguration.cs b/src/X1.Infrastructure/Configurations/Device/CellularDeviceConfiguration.cs index 7b1970a..c230ad1 100644 --- a/src/X1.Infrastructure/Configurations/Device/CellularDeviceConfiguration.cs +++ b/src/X1.Infrastructure/Configurations/Device/CellularDeviceConfiguration.cs @@ -13,25 +13,24 @@ public class CellularDeviceConfiguration : IEntityTypeConfiguration d.SerialNumber).IsUnique().HasDatabaseName("IX_CellularDevices_SerialNumber"); - builder.HasIndex(d => d.ProtocolVersionId).HasDatabaseName("IX_CellularDevices_ProtocolVersionId"); // 配置属性 builder.Property(d => d.Id).HasComment("设备ID"); builder.Property(d => d.Name).IsRequired().HasMaxLength(100).HasComment("设备名称"); builder.Property(d => d.SerialNumber).IsRequired().HasMaxLength(50).HasComment("序列号"); builder.Property(d => d.Description).HasMaxLength(500).HasComment("设备描述"); - builder.Property(d => d.ProtocolVersionId).IsRequired().HasMaxLength(50).HasComment("协议版本ID"); builder.Property(d => d.AgentPort).IsRequired().HasComment("Agent端口"); builder.Property(d => d.IpAddress).IsRequired().HasMaxLength(45).HasComment("IP地址"); builder.Property(d => d.IsEnabled).IsRequired().HasComment("是否启用"); builder.Property(d => d.IsRunning).IsRequired().HasComment("设备状态(启动/未启动)"); builder.Property(d => d.CreatedAt).IsRequired().HasColumnType("timestamp with time zone").HasComment("创建时间"); - builder.Property(d => d.UpdatedAt).IsRequired().HasColumnType("timestamp with time zone").HasComment("更新时间"); + builder.Property(d => d.UpdatedAt).IsRequired().HasColumnType("timestamp with time zone").HasComment("更新时间"); - // 配置关系 - builder.HasOne(d => d.ProtocolVersion) - .WithMany() - .HasForeignKey(d => d.ProtocolVersionId) - .OnDelete(DeleteBehavior.Restrict); + // 配置一对多关系:一个设备可以有多个协议版本 + builder.HasMany(d => d.ProtocolVersions) + .WithOne() + .HasForeignKey(pv => pv.SerialNumber) + .HasPrincipalKey(d => d.SerialNumber) + .OnDelete(DeleteBehavior.Cascade); } } \ No newline at end of file diff --git a/src/X1.Infrastructure/Configurations/Device/NetworkConfigConfiguration.cs b/src/X1.Infrastructure/Configurations/Device/NetworkConfigConfiguration.cs deleted file mode 100644 index 8612221..0000000 --- a/src/X1.Infrastructure/Configurations/Device/NetworkConfigConfiguration.cs +++ /dev/null @@ -1,88 +0,0 @@ -using CellularManagement.Domain.Entities.Device; -using Microsoft.EntityFrameworkCore; -using Microsoft.EntityFrameworkCore.Metadata.Builders; - -namespace CellularManagement.Infrastructure.Configurations.Device; - -/// -/// 网络配置实体配置 -/// -public class NetworkConfigConfiguration : IEntityTypeConfiguration -{ - public void Configure(EntityTypeBuilder builder) - { - // 表名 - builder.ToTable("NetworkConfigs"); - - // 主键 - builder.HasKey(x => x.Id); - - // 属性配置 - builder.Property(x => x.Id) - .HasMaxLength(450) - .IsRequired(); - - builder.Property(x => x.ConfigType) - .HasConversion() - .IsRequired(); - - builder.Property(x => x.Name) - .HasMaxLength(100) - .IsRequired(); - - builder.Property(x => x.Plmn) - .HasMaxLength(10) - .IsRequired(false); - - builder.Property(x => x.ConfigContent) - .HasColumnType("jsonb") - .IsRequired(); - - builder.Property(x => x.Description) - .HasMaxLength(500) - .IsRequired(false); - - builder.Property(x => x.IsDisabled) - .HasDefaultValue(false); - - // 审计字段 - builder.Property(x => x.CreatedAt) - .IsRequired(); - - builder.Property(x => x.UpdatedAt) - .IsRequired(); - - builder.Property(x => x.CreatedBy) - .HasMaxLength(450) - .IsRequired(); - - builder.Property(x => x.UpdatedBy) - .HasMaxLength(450) - .IsRequired(); - - // 索引配置 - builder.HasIndex(x => x.ConfigType) - .HasDatabaseName("IX_NetworkConfigs_ConfigType"); - - builder.HasIndex(x => x.Name) - .HasDatabaseName("IX_NetworkConfigs_Name") - .IsUnique(); - - builder.HasIndex(x => x.Plmn) - .HasDatabaseName("IX_NetworkConfigs_Plmn"); - - builder.HasIndex(x => x.IsDisabled) - .HasDatabaseName("IX_NetworkConfigs_IsDisabled"); - - // 复合索引 - builder.HasIndex(x => new { x.ConfigType, x.Plmn }) - .HasDatabaseName("IX_NetworkConfigs_ConfigType_Plmn"); - - // 约束配置 - builder.HasCheckConstraint("CK_NetworkConfigs_Plmn_IMS_MME", - "NOT (\"ConfigType\" IN (2, 3) AND \"Plmn\" IS NULL)"); - - // 软删除过滤器 - builder.HasQueryFilter(x => !x.IsDeleted); - } -} \ No newline at end of file diff --git a/src/X1.Infrastructure/Configurations/Device/ProtocolVersionConfiguration.cs b/src/X1.Infrastructure/Configurations/Device/ProtocolVersionConfiguration.cs index f5c8e87..a7c87ed 100644 --- a/src/X1.Infrastructure/Configurations/Device/ProtocolVersionConfiguration.cs +++ b/src/X1.Infrastructure/Configurations/Device/ProtocolVersionConfiguration.cs @@ -12,7 +12,8 @@ public class ProtocolVersionConfiguration : IEntityTypeConfiguration v.Id); // 配置索引 - builder.HasIndex(v => v.Version).IsUnique().HasDatabaseName("IX_ProtocolVersions_Version"); + builder.HasIndex(v => v.Version).HasDatabaseName("IX_ProtocolVersions_Version"); + builder.HasIndex(v => v.SerialNumber).HasDatabaseName("IX_ProtocolVersions_SerialNumber"); // 配置属性 builder.Property(v => v.Id).HasComment("版本ID"); @@ -22,6 +23,7 @@ public class ProtocolVersionConfiguration : IEntityTypeConfiguration v.IsEnabled).IsRequired().HasComment("是否启用"); builder.Property(v => v.ReleaseDate).HasColumnType("timestamp with time zone").HasComment("发布日期"); builder.Property(v => v.MinimumSupportedVersion).HasMaxLength(20).HasComment("最低支持版本"); + builder.Property(v => v.SerialNumber).IsRequired().HasMaxLength(50).HasComment("设备序列号"); builder.Property(v => v.CreatedAt).IsRequired().HasColumnType("timestamp with time zone").HasComment("创建时间"); builder.Property(v => v.UpdatedAt).IsRequired().HasColumnType("timestamp with time zone").HasComment("更新时间"); } diff --git a/src/X1.Infrastructure/Configurations/NetworkProfile/CoreNetworkConfigConfiguration.cs b/src/X1.Infrastructure/Configurations/NetworkProfile/CoreNetworkConfigConfiguration.cs new file mode 100644 index 0000000..b557969 --- /dev/null +++ b/src/X1.Infrastructure/Configurations/NetworkProfile/CoreNetworkConfigConfiguration.cs @@ -0,0 +1,26 @@ +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Metadata.Builders; +using CellularManagement.Domain.Entities.NetworkProfile; + +namespace CellularManagement.Infrastructure.Configurations.NetworkProfile; + +public class CoreNetworkConfigConfiguration : IEntityTypeConfiguration +{ + public void Configure(EntityTypeBuilder builder) + { + builder.ToTable("CoreNetworkConfigs", t => t.HasComment("核心网配置表")); + builder.HasKey(cnc => cnc.Id); + + // 配置索引 + builder.HasIndex(cnc => cnc.Name).HasDatabaseName("IX_CoreNetworkConfigs_Name"); + + // 配置属性 + builder.Property(cnc => cnc.Id).HasComment("配置ID"); + builder.Property(cnc => cnc.Name).IsRequired().HasMaxLength(100).HasComment("配置名称"); + builder.Property(cnc => cnc.ConfigContent).IsRequired().HasColumnType("text").HasComment("配置内容(JSON格式)"); + builder.Property(cnc => cnc.Description).HasMaxLength(500).HasComment("配置描述"); + builder.Property(cnc => cnc.IsDisabled).IsRequired().HasComment("是否禁用"); + builder.Property(cnc => cnc.CreatedAt).IsRequired().HasColumnType("timestamp with time zone").HasComment("创建时间"); + builder.Property(cnc => cnc.UpdatedAt).IsRequired().HasColumnType("timestamp with time zone").HasComment("更新时间"); + } +} \ No newline at end of file diff --git a/src/X1.Infrastructure/Configurations/NetworkProfile/IMS_ConfigurationConfiguration.cs b/src/X1.Infrastructure/Configurations/NetworkProfile/IMS_ConfigurationConfiguration.cs new file mode 100644 index 0000000..eb389e7 --- /dev/null +++ b/src/X1.Infrastructure/Configurations/NetworkProfile/IMS_ConfigurationConfiguration.cs @@ -0,0 +1,26 @@ +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Metadata.Builders; +using CellularManagement.Domain.Entities.NetworkProfile; + +namespace CellularManagement.Infrastructure.Configurations.NetworkProfile; + +public class IMS_ConfigurationConfiguration : IEntityTypeConfiguration +{ + public void Configure(EntityTypeBuilder builder) + { + builder.ToTable("IMS_Configurations", t => t.HasComment("IMS配置表")); + builder.HasKey(ic => ic.Id); + + // 配置索引 + builder.HasIndex(ic => ic.Name).HasDatabaseName("IX_IMS_Configurations_Name"); + + // 配置属性 + builder.Property(ic => ic.Id).HasComment("配置ID"); + builder.Property(ic => ic.Name).IsRequired().HasMaxLength(100).HasComment("配置名称"); + builder.Property(ic => ic.ConfigContent).IsRequired().HasColumnType("text").HasComment("配置内容(JSON格式)"); + builder.Property(ic => ic.Description).HasMaxLength(500).HasComment("配置描述"); + builder.Property(ic => ic.IsDisabled).IsRequired().HasComment("是否禁用"); + builder.Property(ic => ic.CreatedAt).IsRequired().HasColumnType("timestamp with time zone").HasComment("创建时间"); + builder.Property(ic => ic.UpdatedAt).IsRequired().HasColumnType("timestamp with time zone").HasComment("更新时间"); + } +} \ No newline at end of file diff --git a/src/X1.Infrastructure/Configurations/NetworkProfile/NetworkStackConfigConfiguration.cs b/src/X1.Infrastructure/Configurations/NetworkProfile/NetworkStackConfigConfiguration.cs new file mode 100644 index 0000000..d1b2d8a --- /dev/null +++ b/src/X1.Infrastructure/Configurations/NetworkProfile/NetworkStackConfigConfiguration.cs @@ -0,0 +1,42 @@ +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Metadata.Builders; +using CellularManagement.Domain.Entities.NetworkProfile; + +namespace CellularManagement.Infrastructure.Configurations.NetworkProfile; + +public class NetworkStackConfigConfiguration : IEntityTypeConfiguration +{ + public void Configure(EntityTypeBuilder builder) + { + builder.ToTable("NetworkStackConfigs", t => t.HasComment("网络栈配置表")); + builder.HasKey(nsc => nsc.Id); + + // 配置索引 + builder.HasIndex(nsc => nsc.StackId).IsUnique().HasDatabaseName("IX_NetworkStackConfigs_StackId"); + builder.HasIndex(nsc => nsc.RanId).HasDatabaseName("IX_NetworkStackConfigs_RanId"); + builder.HasIndex(nsc => nsc.IsActive).HasDatabaseName("IX_NetworkStackConfigs_IsActive"); + + // 配置属性 + builder.Property(nsc => nsc.Id).HasComment("配置ID"); + builder.Property(nsc => nsc.StackId).IsRequired().HasMaxLength(50).HasComment("栈ID"); + builder.Property(nsc => nsc.RanId).HasMaxLength(50).HasComment("RAN配置ID"); + builder.Property(nsc => nsc.Description).HasMaxLength(500).HasComment("描述"); + builder.Property(nsc => nsc.IsActive).IsRequired().HasComment("是否激活"); + builder.Property(nsc => nsc.CreatedAt).IsRequired().HasColumnType("timestamp with time zone").HasComment("创建时间"); + builder.Property(nsc => nsc.UpdatedAt).IsRequired().HasColumnType("timestamp with time zone").HasComment("更新时间"); + + // 配置与RAN_Configuration的关系 + builder.HasOne() + .WithMany() + .HasForeignKey(nsc => nsc.RanId) + .HasPrincipalKey(rc => rc.Id) + .OnDelete(DeleteBehavior.SetNull); + + // 配置与Stack_CoreIMS_Binding的一对多关系 + builder.HasMany(nsc => nsc.StackCoreIMSBindings) + .WithOne(binding => binding.NetworkStackConfig) + .HasForeignKey(binding => binding.StackId) + .HasPrincipalKey(nsc => nsc.StackId) + .OnDelete(DeleteBehavior.Cascade); + } +} \ No newline at end of file diff --git a/src/X1.Infrastructure/Configurations/NetworkProfile/RAN_ConfigurationConfiguration.cs b/src/X1.Infrastructure/Configurations/NetworkProfile/RAN_ConfigurationConfiguration.cs new file mode 100644 index 0000000..95fd374 --- /dev/null +++ b/src/X1.Infrastructure/Configurations/NetworkProfile/RAN_ConfigurationConfiguration.cs @@ -0,0 +1,27 @@ +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Metadata.Builders; +using CellularManagement.Domain.Entities.Device; +using CellularManagement.Domain.Entities.NetworkProfile; + +namespace CellularManagement.Infrastructure.Configurations.Device; + +public class RAN_ConfigurationConfiguration : IEntityTypeConfiguration +{ + public void Configure(EntityTypeBuilder builder) + { + builder.ToTable("RAN_Configurations", t => t.HasComment("RAN配置表")); + builder.HasKey(rc => rc.Id); + + // 配置索引 + builder.HasIndex(rc => rc.Name).HasDatabaseName("IX_RAN_Configurations_Name"); + + // 配置属性 + builder.Property(rc => rc.Id).HasComment("配置ID"); + builder.Property(rc => rc.Name).IsRequired().HasMaxLength(100).HasComment("配置名称"); + builder.Property(rc => rc.ConfigContent).IsRequired().HasColumnType("text").HasComment("配置内容(JSON格式)"); + builder.Property(rc => rc.Description).HasMaxLength(500).HasComment("配置描述"); + builder.Property(rc => rc.IsDisabled).IsRequired().HasComment("是否禁用"); + builder.Property(rc => rc.CreatedAt).IsRequired().HasColumnType("timestamp with time zone").HasComment("创建时间"); + builder.Property(rc => rc.UpdatedAt).IsRequired().HasColumnType("timestamp with time zone").HasComment("更新时间"); + } +} \ No newline at end of file diff --git a/src/X1.Infrastructure/Configurations/NetworkProfile/Stack_CoreIMS_BindingConfiguration.cs b/src/X1.Infrastructure/Configurations/NetworkProfile/Stack_CoreIMS_BindingConfiguration.cs new file mode 100644 index 0000000..9501899 --- /dev/null +++ b/src/X1.Infrastructure/Configurations/NetworkProfile/Stack_CoreIMS_BindingConfiguration.cs @@ -0,0 +1,47 @@ +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Metadata.Builders; +using CellularManagement.Domain.Entities.NetworkProfile; + +namespace CellularManagement.Infrastructure.Configurations.NetworkProfile; + +public class Stack_CoreIMS_BindingConfiguration : IEntityTypeConfiguration +{ + public void Configure(EntityTypeBuilder builder) + { + builder.ToTable("Stack_CoreIMS_Bindings", t => t.HasComment("栈与核心网/IMS绑定关系表")); + builder.HasKey(binding => binding.Id); + + // 配置复合唯一索引:StackId + Index + builder.HasIndex(binding => new { binding.StackId, binding.Index }) + .IsUnique() + .HasDatabaseName("IX_Stack_CoreIMS_Bindings_StackId_Index"); + + // 配置索引 + builder.HasIndex(binding => binding.StackId).HasDatabaseName("IX_Stack_CoreIMS_Bindings_StackId"); + builder.HasIndex(binding => binding.CnId).HasDatabaseName("IX_Stack_CoreIMS_Bindings_CnId"); + builder.HasIndex(binding => binding.ImsId).HasDatabaseName("IX_Stack_CoreIMS_Bindings_ImsId"); + + // 配置属性 + builder.Property(binding => binding.Id).HasComment("绑定关系ID"); + builder.Property(binding => binding.StackId).IsRequired().HasMaxLength(50).HasComment("栈ID"); + builder.Property(binding => binding.Index).IsRequired().HasComment("索引"); + builder.Property(binding => binding.CnId).IsRequired().HasMaxLength(50).HasComment("核心网配置ID"); + builder.Property(binding => binding.ImsId).IsRequired().HasMaxLength(50).HasComment("IMS配置ID"); + builder.Property(binding => binding.CreatedAt).IsRequired().HasColumnType("timestamp with time zone").HasComment("创建时间"); + builder.Property(binding => binding.UpdatedAt).IsRequired().HasColumnType("timestamp with time zone").HasComment("更新时间"); + + // 配置与CoreNetworkConfig的关系 + builder.HasOne(binding => binding.CoreNetworkConfig) + .WithMany() + .HasForeignKey(binding => binding.CnId) + .HasPrincipalKey(cnc => cnc.Id) + .OnDelete(DeleteBehavior.Cascade); + + // 配置与IMS_Configuration的关系 + builder.HasOne(binding => binding.IMSConfiguration) + .WithMany() + .HasForeignKey(binding => binding.ImsId) + .HasPrincipalKey(ic => ic.Id) + .OnDelete(DeleteBehavior.Cascade); + } +} \ No newline at end of file diff --git a/src/X1.Infrastructure/Context/AppDbContext.cs b/src/X1.Infrastructure/Context/AppDbContext.cs index 264d3e4..127bc15 100644 --- a/src/X1.Infrastructure/Context/AppDbContext.cs +++ b/src/X1.Infrastructure/Context/AppDbContext.cs @@ -5,6 +5,7 @@ using Microsoft.AspNetCore.Identity; using CellularManagement.Domain.Entities; using CellularManagement.Domain.Entities.Logging; using CellularManagement.Domain.Entities.Device; +using CellularManagement.Domain.Entities.NetworkProfile; namespace CellularManagement.Infrastructure.Context; @@ -46,10 +47,32 @@ public class AppDbContext : IdentityDbContext /// public DbSet ProtocolVersions { get; set; } = null!; + + + /// + /// RAN配置集合 + /// + public DbSet RAN_Configurations { get; set; } = null!; + + /// + /// 核心网配置集合 + /// + public DbSet CoreNetworkConfigs { get; set; } = null!; + + /// + /// IMS配置集合 + /// + public DbSet IMS_Configurations { get; set; } = null!; + + /// + /// 网络栈配置集合 + /// + public DbSet NetworkStackConfigs { get; set; } = null!; + /// - /// 网络配置集合 + /// 栈与核心网/IMS绑定关系集合 /// - public DbSet NetworkConfigs { get; set; } = null!; + public DbSet Stack_CoreIMS_Bindings { get; set; } = null!; /// /// 初始化数据库上下文 diff --git a/src/X1.Infrastructure/DependencyInjection.cs b/src/X1.Infrastructure/DependencyInjection.cs index d4824dc..550efc6 100644 --- a/src/X1.Infrastructure/DependencyInjection.cs +++ b/src/X1.Infrastructure/DependencyInjection.cs @@ -24,7 +24,9 @@ using CellularManagement.Infrastructure.Services.Infrastructure; using CellularManagement.Infrastructure.Services.Security; using CellularManagement.Infrastructure.Services.UserManagement; using CellularManagement.Domain.Repositories.Device; +using CellularManagement.Domain.Repositories.NetworkProfile; using CellularManagement.Infrastructure.Repositories.Device; +using CellularManagement.Infrastructure.Repositories.NetworkProfile; namespace CellularManagement.Infrastructure; @@ -174,7 +176,11 @@ public static class DependencyInjection // 注册设备相关仓储 services.AddScoped(); services.AddScoped(); - services.AddScoped(); + services.AddScoped(); + services.AddScoped(); + services.AddScoped(); + services.AddScoped(); + services.AddScoped(); return services; } diff --git a/src/X1.Infrastructure/Repositories/Device/CellularDeviceRepository.cs b/src/X1.Infrastructure/Repositories/Device/CellularDeviceRepository.cs index b303a23..712c9ea 100644 --- a/src/X1.Infrastructure/Repositories/Device/CellularDeviceRepository.cs +++ b/src/X1.Infrastructure/Repositories/Device/CellularDeviceRepository.cs @@ -105,9 +105,9 @@ public class CellularDeviceRepository : BaseRepository, ICellula } /// - /// 搜索蜂窝设备(包含协议版本导航属性) + /// 搜索蜂窝设备 /// - public async Task<(int TotalCount, IList Items)> SearchDevicesWithProtocolVersionAsync( + public async Task<(int TotalCount, IList Items)> SearchDevicesAsync( string? keyword, int pageNumber, int pageSize, @@ -123,11 +123,8 @@ public class CellularDeviceRepository : BaseRepository, ICellula d.Description.Contains(keyword); } - // 使用导航属性包含ProtocolVersion - var include = (IQueryable query) => query.Include(d => d.ProtocolVersion); - // 执行分页查询 - var result = await QueryRepository.GetPagedAsync(predicate, pageNumber, pageSize, include, cancellationToken); + var result = await QueryRepository.GetPagedAsync(predicate, pageNumber, pageSize, null, cancellationToken); return (result.TotalCount, result.Items.ToList()); } diff --git a/src/X1.Infrastructure/Repositories/Device/NetworkConfigRepository.cs b/src/X1.Infrastructure/Repositories/Device/NetworkConfigRepository.cs deleted file mode 100644 index f593625..0000000 --- a/src/X1.Infrastructure/Repositories/Device/NetworkConfigRepository.cs +++ /dev/null @@ -1,168 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Threading; -using System.Threading.Tasks; -using System.Linq; -using Microsoft.Extensions.Logging; -using CellularManagement.Domain.Entities; -using CellularManagement.Domain.Repositories; -using CellularManagement.Infrastructure.Repositories.Base; -using CellularManagement.Domain.Entities.Device; -using CellularManagement.Domain.Repositories.Base; -using CellularManagement.Domain.Repositories.Device; - -namespace CellularManagement.Infrastructure.Repositories.Device; - -/// -/// 网络配置仓储实现类 -/// -public class NetworkConfigRepository : BaseRepository, INetworkConfigRepository -{ - private readonly ILogger _logger; - - /// - /// 初始化仓储 - /// - public NetworkConfigRepository( - ICommandRepository commandRepository, - IQueryRepository queryRepository, - ILogger logger) - : base(commandRepository, queryRepository, logger) - { - _logger = logger; - } - - /// - /// 添加网络配置 - /// - public async Task AddNetworkConfigAsync(NetworkConfig networkConfig, CancellationToken cancellationToken = default) - { - var result = await CommandRepository.AddAsync(networkConfig, cancellationToken); - return result; - } - - /// - /// 更新网络配置 - /// - public void UpdateNetworkConfig(NetworkConfig networkConfig) - { - CommandRepository.Update(networkConfig); - } - - /// - /// 删除网络配置 - /// - public async Task DeleteNetworkConfigAsync(string id, CancellationToken cancellationToken = default) - { - await CommandRepository.DeleteByIdAsync(id, cancellationToken); - } - - /// - /// 获取所有网络配置 - /// - public async Task> GetAllNetworkConfigsAsync(CancellationToken cancellationToken = default) - { - var networkConfigs = await QueryRepository.GetAllAsync(cancellationToken: cancellationToken); - return networkConfigs.OrderBy(x => x.ConfigType).ThenBy(x => x.Name).ToList(); - } - - /// - /// 根据ID获取网络配置 - /// - public async Task GetNetworkConfigByIdAsync(string id, CancellationToken cancellationToken = default) - { - return await QueryRepository.GetByIdAsync(id, cancellationToken: cancellationToken); - } - - /// - /// 根据配置类型获取网络配置列表 - /// - public async Task> GetNetworkConfigsByTypeAsync(NetworkConfigType configType, CancellationToken cancellationToken = default) - { - var networkConfigs = await QueryRepository.FindAsync(x => x.ConfigType == configType, cancellationToken: cancellationToken); - return networkConfigs.OrderBy(x => x.Name).ToList(); - } - - /// - /// 根据PLMN获取网络配置列表 - /// - public async Task> GetNetworkConfigsByPlmnAsync(string plmn, CancellationToken cancellationToken = default) - { - var networkConfigs = await QueryRepository.FindAsync(x => x.Plmn == plmn, cancellationToken: cancellationToken); - return networkConfigs.OrderBy(x => x.ConfigType).ThenBy(x => x.Name).ToList(); - } - - /// - /// 根据配置类型和PLMN获取网络配置列表 - /// - public async Task> GetNetworkConfigsByTypeAndPlmnAsync(NetworkConfigType configType, string plmn, CancellationToken cancellationToken = default) - { - var networkConfigs = await QueryRepository.FindAsync(x => x.ConfigType == configType && x.Plmn == plmn, cancellationToken: cancellationToken); - return networkConfigs.OrderBy(x => x.Name).ToList(); - } - - /// - /// 获取启用的网络配置 - /// - public async Task> GetEnabledNetworkConfigsAsync(CancellationToken cancellationToken = default) - { - var networkConfigs = await QueryRepository.FindAsync(x => !x.IsDisabled, cancellationToken: cancellationToken); - return networkConfigs.OrderBy(x => x.ConfigType).ThenBy(x => x.Name).ToList(); - } - - /// - /// 搜索网络配置 - /// - public async Task> SearchNetworkConfigsAsync( - string? keyword, - NetworkConfigType? configType = null, - string? plmn = null, - CancellationToken cancellationToken = default) - { - var query = await QueryRepository.FindAsync(x => true, cancellationToken: cancellationToken); - - if (!string.IsNullOrWhiteSpace(keyword)) - { - query = query.Where(x => - x.Name.Contains(keyword) || - x.Description.Contains(keyword) || - x.Plmn.Contains(keyword)); - } - - if (configType.HasValue) - { - query = query.Where(x => x.ConfigType == configType.Value); - } - - if (!string.IsNullOrWhiteSpace(plmn)) - { - query = query.Where(x => x.Plmn == plmn); - } - - return query.OrderBy(x => x.ConfigType).ThenBy(x => x.Name).ToList(); - } - - /// - /// 检查网络配置是否存在 - /// - public async Task ExistsAsync(string id, CancellationToken cancellationToken = default) - { - return await QueryRepository.AnyAsync(x => x.Id == id, cancellationToken: cancellationToken); - } - - /// - /// 检查配置名称是否存在 - /// - public async Task NameExistsAsync(string name, CancellationToken cancellationToken = default) - { - return await QueryRepository.AnyAsync(x => x.Name == name, cancellationToken: cancellationToken); - } - - /// - /// 检查配置名称是否存在(排除指定ID) - /// - public async Task NameExistsAsync(string name, string excludeId, CancellationToken cancellationToken = default) - { - return await QueryRepository.AnyAsync(x => x.Name == name && x.Id != excludeId, cancellationToken: cancellationToken); - } -} \ No newline at end of file diff --git a/src/X1.Infrastructure/Repositories/NetworkProfile/CoreNetworkConfigRepository.cs b/src/X1.Infrastructure/Repositories/NetworkProfile/CoreNetworkConfigRepository.cs new file mode 100644 index 0000000..408837c --- /dev/null +++ b/src/X1.Infrastructure/Repositories/NetworkProfile/CoreNetworkConfigRepository.cs @@ -0,0 +1,138 @@ +using System.Linq.Expressions; +using Microsoft.Extensions.Logging; +using CellularManagement.Domain.Entities.NetworkProfile; +using CellularManagement.Domain.Repositories.Base; +using CellularManagement.Domain.Repositories.NetworkProfile; +using CellularManagement.Infrastructure.Repositories.Base; + +namespace CellularManagement.Infrastructure.Repositories.NetworkProfile; + +/// +/// 核心网配置仓储实现 +/// +public class CoreNetworkConfigRepository : BaseRepository, ICoreNetworkConfigRepository +{ + private readonly ILogger _logger; + + /// + /// 初始化仓储 + /// + public CoreNetworkConfigRepository( + ICommandRepository commandRepository, + IQueryRepository queryRepository, + ILogger logger) + : base(commandRepository, queryRepository, logger) + { + _logger = logger; + } + + /// + /// 添加核心网配置 + /// + public async Task AddCoreNetworkConfigAsync(CoreNetworkConfig coreNetworkConfig, CancellationToken cancellationToken = default) + { + await CommandRepository.AddAsync(coreNetworkConfig, cancellationToken); + return coreNetworkConfig; + } + + /// + /// 更新核心网配置 + /// + public void UpdateCoreNetworkConfig(CoreNetworkConfig coreNetworkConfig) + { + CommandRepository.Update(coreNetworkConfig); + } + + /// + /// 删除核心网配置 + /// + public async Task DeleteCoreNetworkConfigAsync(string id, CancellationToken cancellationToken = default) + { + await CommandRepository.DeleteByIdAsync(id, cancellationToken); + } + + /// + /// 获取所有核心网配置 + /// + public async Task> GetAllCoreNetworkConfigsAsync(CancellationToken cancellationToken = default) + { + var configs = await QueryRepository.GetAllAsync(cancellationToken: cancellationToken); + return configs.ToList(); + } + + /// + /// 根据ID获取核心网配置 + /// + public async Task GetCoreNetworkConfigByIdAsync(string id, CancellationToken cancellationToken = default) + { + return await QueryRepository.GetByIdAsync(id, cancellationToken: cancellationToken); + } + + /// + /// 根据名称获取核心网配置 + /// + public async Task GetCoreNetworkConfigByNameAsync(string name, CancellationToken cancellationToken = default) + { + return await QueryRepository.FirstOrDefaultAsync(cnc => cnc.Name == name, cancellationToken: cancellationToken); + } + + /// + /// 搜索核心网配置 + /// + public async Task> SearchCoreNetworkConfigsAsync( + string? keyword, + CancellationToken cancellationToken = default) + { + var query = await QueryRepository.FindAsync(cnc => true, cancellationToken: cancellationToken); + + if (!string.IsNullOrWhiteSpace(keyword)) + { + query = query.Where(cnc => + cnc.Name.Contains(keyword) || + cnc.Description.Contains(keyword)); + } + + var configs = query; + return configs.ToList(); + } + + /// + /// 搜索核心网配置(分页) + /// + public async Task<(int TotalCount, IList Items)> SearchCoreNetworkConfigsAsync( + string? keyword, + int pageNumber, + int pageSize, + CancellationToken cancellationToken = default) + { + // 构建查询条件 + Expression> predicate = cnc => true; + + if (!string.IsNullOrWhiteSpace(keyword)) + { + predicate = cnc => cnc.Name.Contains(keyword) || + cnc.Description.Contains(keyword); + } + + // 执行分页查询 + var result = await QueryRepository.GetPagedAsync(predicate, pageNumber, pageSize, null, cancellationToken); + + return (result.TotalCount, result.Items.ToList()); + } + + /// + /// 检查核心网配置是否存在 + /// + public async Task ExistsAsync(string id, CancellationToken cancellationToken = default) + { + return await QueryRepository.AnyAsync(cnc => cnc.Id == id, cancellationToken: cancellationToken); + } + + /// + /// 检查配置名称是否存在 + /// + public async Task NameExistsAsync(string name, CancellationToken cancellationToken = default) + { + return await QueryRepository.AnyAsync(cnc => cnc.Name == name, cancellationToken: cancellationToken); + } +} \ No newline at end of file diff --git a/src/X1.Infrastructure/Repositories/NetworkProfile/IMS_ConfigurationRepository.cs b/src/X1.Infrastructure/Repositories/NetworkProfile/IMS_ConfigurationRepository.cs new file mode 100644 index 0000000..4e8205e --- /dev/null +++ b/src/X1.Infrastructure/Repositories/NetworkProfile/IMS_ConfigurationRepository.cs @@ -0,0 +1,138 @@ +using System.Linq.Expressions; +using Microsoft.Extensions.Logging; +using CellularManagement.Domain.Entities.NetworkProfile; +using CellularManagement.Domain.Repositories.Base; +using CellularManagement.Domain.Repositories.NetworkProfile; +using CellularManagement.Infrastructure.Repositories.Base; + +namespace CellularManagement.Infrastructure.Repositories.NetworkProfile; + +/// +/// IMS配置仓储实现 +/// +public class IMS_ConfigurationRepository : BaseRepository, IIMS_ConfigurationRepository +{ + private readonly ILogger _logger; + + /// + /// 初始化仓储 + /// + public IMS_ConfigurationRepository( + ICommandRepository commandRepository, + IQueryRepository queryRepository, + ILogger logger) + : base(commandRepository, queryRepository, logger) + { + _logger = logger; + } + + /// + /// 添加IMS配置 + /// + public async Task AddIMS_ConfigurationAsync(IMS_Configuration imsConfig, CancellationToken cancellationToken = default) + { + await CommandRepository.AddAsync(imsConfig, cancellationToken); + return imsConfig; + } + + /// + /// 更新IMS配置 + /// + public void UpdateIMS_Configuration(IMS_Configuration imsConfig) + { + CommandRepository.Update(imsConfig); + } + + /// + /// 删除IMS配置 + /// + public async Task DeleteIMS_ConfigurationAsync(string id, CancellationToken cancellationToken = default) + { + await CommandRepository.DeleteByIdAsync(id, cancellationToken); + } + + /// + /// 获取所有IMS配置 + /// + public async Task> GetAllIMS_ConfigurationsAsync(CancellationToken cancellationToken = default) + { + var configs = await QueryRepository.GetAllAsync(cancellationToken: cancellationToken); + return configs.ToList(); + } + + /// + /// 根据ID获取IMS配置 + /// + public async Task GetIMS_ConfigurationByIdAsync(string id, CancellationToken cancellationToken = default) + { + return await QueryRepository.GetByIdAsync(id, cancellationToken: cancellationToken); + } + + /// + /// 根据名称获取IMS配置 + /// + public async Task GetIMS_ConfigurationByNameAsync(string name, CancellationToken cancellationToken = default) + { + return await QueryRepository.FirstOrDefaultAsync(ic => ic.Name == name, cancellationToken: cancellationToken); + } + + /// + /// 搜索IMS配置 + /// + public async Task> SearchIMS_ConfigurationsAsync( + string? keyword, + CancellationToken cancellationToken = default) + { + var query = await QueryRepository.FindAsync(ic => true, cancellationToken: cancellationToken); + + if (!string.IsNullOrWhiteSpace(keyword)) + { + query = query.Where(ic => + ic.Name.Contains(keyword) || + ic.Description.Contains(keyword)); + } + + var configs = query; + return configs.ToList(); + } + + /// + /// 搜索IMS配置(分页) + /// + public async Task<(int TotalCount, IList Items)> SearchIMS_ConfigurationsAsync( + string? keyword, + int pageNumber, + int pageSize, + CancellationToken cancellationToken = default) + { + // 构建查询条件 + Expression> predicate = ic => true; + + if (!string.IsNullOrWhiteSpace(keyword)) + { + predicate = ic => ic.Name.Contains(keyword) || + ic.Description.Contains(keyword); + } + + // 执行分页查询 + var result = await QueryRepository.GetPagedAsync(predicate, pageNumber, pageSize, null, cancellationToken); + + return (result.TotalCount, result.Items.ToList()); + } + + /// + /// 检查IMS配置是否存在 + /// + public async Task ExistsAsync(string id, CancellationToken cancellationToken = default) + { + return await QueryRepository.AnyAsync(ic => ic.Id == id, cancellationToken: cancellationToken); + } + + /// + /// 检查配置名称是否存在 + /// + public async Task NameExistsAsync(string name, CancellationToken cancellationToken = default) + { + return await QueryRepository.AnyAsync(ic => ic.Name == name, cancellationToken: cancellationToken); + } +} \ No newline at end of file diff --git a/src/X1.Infrastructure/Repositories/NetworkProfile/NetworkStackConfigRepository.cs b/src/X1.Infrastructure/Repositories/NetworkProfile/NetworkStackConfigRepository.cs new file mode 100644 index 0000000..3635510 --- /dev/null +++ b/src/X1.Infrastructure/Repositories/NetworkProfile/NetworkStackConfigRepository.cs @@ -0,0 +1,156 @@ +using System.Linq.Expressions; +using Microsoft.Extensions.Logging; +using CellularManagement.Domain.Entities.NetworkProfile; +using CellularManagement.Domain.Repositories.Base; +using CellularManagement.Domain.Repositories.NetworkProfile; +using CellularManagement.Infrastructure.Repositories.Base; + +namespace CellularManagement.Infrastructure.Repositories.NetworkProfile; + +/// +/// 网络栈配置仓储实现 +/// +public class NetworkStackConfigRepository : BaseRepository, INetworkStackConfigRepository +{ + private readonly ILogger _logger; + + /// + /// 初始化仓储 + /// + public NetworkStackConfigRepository( + ICommandRepository commandRepository, + IQueryRepository queryRepository, + ILogger logger) + : base(commandRepository, queryRepository, logger) + { + _logger = logger; + } + + /// + /// 添加网络栈配置 + /// + public async Task AddNetworkStackConfigAsync(NetworkStackConfig networkStackConfig, CancellationToken cancellationToken = default) + { + await CommandRepository.AddAsync(networkStackConfig, cancellationToken); + return networkStackConfig; + } + + /// + /// 更新网络栈配置 + /// + public void UpdateNetworkStackConfig(NetworkStackConfig networkStackConfig) + { + CommandRepository.Update(networkStackConfig); + } + + /// + /// 删除网络栈配置 + /// + public async Task DeleteNetworkStackConfigAsync(string id, CancellationToken cancellationToken = default) + { + await CommandRepository.DeleteByIdAsync(id, cancellationToken); + } + + /// + /// 获取所有网络栈配置 + /// + public async Task> GetAllNetworkStackConfigsAsync(CancellationToken cancellationToken = default) + { + var configs = await QueryRepository.GetAllAsync(cancellationToken: cancellationToken); + return configs.OrderBy(x => x.StackId).ToList(); + } + + /// + /// 根据ID获取网络栈配置 + /// + public async Task GetNetworkStackConfigByIdAsync(string id, CancellationToken cancellationToken = default) + { + return await QueryRepository.GetByIdAsync(id, cancellationToken: cancellationToken); + } + + /// + /// 根据栈ID获取网络栈配置 + /// + public async Task GetNetworkStackConfigByStackIdAsync(string stackId, CancellationToken cancellationToken = default) + { + return await QueryRepository.FirstOrDefaultAsync(nsc => nsc.StackId == stackId, cancellationToken: cancellationToken); + } + + /// + /// 根据RAN ID获取网络栈配置 + /// + public async Task> GetNetworkStackConfigsByRanIdAsync(string ranId, CancellationToken cancellationToken = default) + { + var configs = await QueryRepository.FindAsync(nsc => nsc.RanId == ranId, cancellationToken: cancellationToken); + return configs.OrderBy(x => x.StackId).ToList(); + } + + /// + /// 获取激活的网络栈配置 + /// + public async Task> GetActiveNetworkStackConfigsAsync(CancellationToken cancellationToken = default) + { + var configs = await QueryRepository.FindAsync(nsc => nsc.IsActive, cancellationToken: cancellationToken); + return configs.OrderBy(x => x.StackId).ToList(); + } + + /// + /// 搜索网络栈配置 + /// + public async Task> SearchNetworkStackConfigsAsync( + string? keyword, + CancellationToken cancellationToken = default) + { + var query = await QueryRepository.FindAsync(nsc => true, cancellationToken: cancellationToken); + + if (!string.IsNullOrWhiteSpace(keyword)) + { + query = query.Where(nsc => + nsc.StackId.Contains(keyword) || + nsc.Description.Contains(keyword)); + } + + var configs = query; + return configs.OrderBy(x => x.StackId).ToList(); + } + + /// + /// 搜索网络栈配置(分页) + /// + public async Task<(int TotalCount, IList Items)> SearchNetworkStackConfigsAsync( + string? keyword, + int pageNumber, + int pageSize, + CancellationToken cancellationToken = default) + { + // 构建查询条件 + Expression> predicate = nsc => true; + + if (!string.IsNullOrWhiteSpace(keyword)) + { + predicate = nsc => nsc.StackId.Contains(keyword) || + nsc.Description.Contains(keyword); + } + + // 执行分页查询 + var result = await QueryRepository.GetPagedAsync(predicate, pageNumber, pageSize, null, cancellationToken); + + return (result.TotalCount, result.Items.OrderBy(x => x.StackId).ToList()); + } + + /// + /// 检查网络栈配置是否存在 + /// + public async Task ExistsAsync(string id, CancellationToken cancellationToken = default) + { + return await QueryRepository.AnyAsync(nsc => nsc.Id == id, cancellationToken: cancellationToken); + } + + /// + /// 检查栈ID是否存在 + /// + public async Task StackIdExistsAsync(string stackId, CancellationToken cancellationToken = default) + { + return await QueryRepository.AnyAsync(nsc => nsc.StackId == stackId, cancellationToken: cancellationToken); + } +} \ No newline at end of file diff --git a/src/X1.Infrastructure/Repositories/NetworkProfile/RAN_ConfigurationRepository.cs b/src/X1.Infrastructure/Repositories/NetworkProfile/RAN_ConfigurationRepository.cs new file mode 100644 index 0000000..1c31f2a --- /dev/null +++ b/src/X1.Infrastructure/Repositories/NetworkProfile/RAN_ConfigurationRepository.cs @@ -0,0 +1,138 @@ +using System.Linq.Expressions; +using Microsoft.Extensions.Logging; +using CellularManagement.Domain.Entities.NetworkProfile; +using CellularManagement.Domain.Repositories.Base; +using CellularManagement.Domain.Repositories.NetworkProfile; +using CellularManagement.Infrastructure.Repositories.Base; + +namespace CellularManagement.Infrastructure.Repositories.NetworkProfile; + +/// +/// RAN配置仓储实现 +/// +public class RAN_ConfigurationRepository : BaseRepository, IRAN_ConfigurationRepository +{ + private readonly ILogger _logger; + + /// + /// 初始化仓储 + /// + public RAN_ConfigurationRepository( + ICommandRepository commandRepository, + IQueryRepository queryRepository, + ILogger logger) + : base(commandRepository, queryRepository, logger) + { + _logger = logger; + } + + /// + /// 添加RAN配置 + /// + public async Task AddRAN_ConfigurationAsync(RAN_Configuration ranConfig, CancellationToken cancellationToken = default) + { + await CommandRepository.AddAsync(ranConfig, cancellationToken); + return ranConfig; + } + + /// + /// 更新RAN配置 + /// + public void UpdateRAN_Configuration(RAN_Configuration ranConfig) + { + CommandRepository.Update(ranConfig); + } + + /// + /// 删除RAN配置 + /// + public async Task DeleteRAN_ConfigurationAsync(string id, CancellationToken cancellationToken = default) + { + await CommandRepository.DeleteByIdAsync(id, cancellationToken); + } + + /// + /// 获取所有RAN配置 + /// + public async Task> GetAllRAN_ConfigurationsAsync(CancellationToken cancellationToken = default) + { + var configs = await QueryRepository.GetAllAsync(cancellationToken: cancellationToken); + return configs.ToList(); + } + + /// + /// 根据ID获取RAN配置 + /// + public async Task GetRAN_ConfigurationByIdAsync(string id, CancellationToken cancellationToken = default) + { + return await QueryRepository.GetByIdAsync(id, cancellationToken: cancellationToken); + } + + /// + /// 根据名称获取RAN配置 + /// + public async Task GetRAN_ConfigurationByNameAsync(string name, CancellationToken cancellationToken = default) + { + return await QueryRepository.FirstOrDefaultAsync(rc => rc.Name == name, cancellationToken: cancellationToken); + } + + /// + /// 搜索RAN配置 + /// + public async Task> SearchRAN_ConfigurationsAsync( + string? keyword, + CancellationToken cancellationToken = default) + { + var query = await QueryRepository.FindAsync(rc => true, cancellationToken: cancellationToken); + + if (!string.IsNullOrWhiteSpace(keyword)) + { + query = query.Where(rc => + rc.Name.Contains(keyword) || + rc.Description.Contains(keyword)); + } + + var configs = query; + return configs.ToList(); + } + + /// + /// 搜索RAN配置(分页) + /// + public async Task<(int TotalCount, IList Items)> SearchRAN_ConfigurationsAsync( + string? keyword, + int pageNumber, + int pageSize, + CancellationToken cancellationToken = default) + { + // 构建查询条件 + Expression> predicate = rc => true; + + if (!string.IsNullOrWhiteSpace(keyword)) + { + predicate = rc => rc.Name.Contains(keyword) || + rc.Description.Contains(keyword); + } + + // 执行分页查询 + var result = await QueryRepository.GetPagedAsync(predicate, pageNumber, pageSize, null, cancellationToken); + + return (result.TotalCount, result.Items.ToList()); + } + + /// + /// 检查RAN配置是否存在 + /// + public async Task ExistsAsync(string id, CancellationToken cancellationToken = default) + { + return await QueryRepository.AnyAsync(rc => rc.Id == id, cancellationToken: cancellationToken); + } + + /// + /// 检查配置名称是否存在 + /// + public async Task NameExistsAsync(string name, CancellationToken cancellationToken = default) + { + return await QueryRepository.AnyAsync(rc => rc.Name == name, cancellationToken: cancellationToken); + } +} \ No newline at end of file diff --git a/src/X1.Infrastructure/Repositories/NetworkProfile/Stack_CoreIMS_BindingRepository.cs b/src/X1.Infrastructure/Repositories/NetworkProfile/Stack_CoreIMS_BindingRepository.cs new file mode 100644 index 0000000..4d5095f --- /dev/null +++ b/src/X1.Infrastructure/Repositories/NetworkProfile/Stack_CoreIMS_BindingRepository.cs @@ -0,0 +1,188 @@ +using System.Linq.Expressions; +using Microsoft.Extensions.Logging; +using CellularManagement.Domain.Entities.NetworkProfile; +using CellularManagement.Domain.Repositories.Base; +using CellularManagement.Domain.Repositories.NetworkProfile; +using CellularManagement.Infrastructure.Repositories.Base; + +namespace CellularManagement.Infrastructure.Repositories.NetworkProfile; + +/// +/// 栈与核心网/IMS绑定关系仓储实现 +/// +public class Stack_CoreIMS_BindingRepository : BaseRepository, IStack_CoreIMS_BindingRepository +{ + private readonly ILogger _logger; + + /// + /// 初始化仓储 + /// + public Stack_CoreIMS_BindingRepository( + ICommandRepository commandRepository, + IQueryRepository queryRepository, + ILogger logger) + : base(commandRepository, queryRepository, logger) + { + _logger = logger; + } + + /// + /// 添加绑定关系 + /// + public async Task AddBindingAsync(Stack_CoreIMS_Binding binding, CancellationToken cancellationToken = default) + { + await CommandRepository.AddAsync(binding, cancellationToken); + return binding; + } + + /// + /// 更新绑定关系 + /// + public void UpdateBinding(Stack_CoreIMS_Binding binding) + { + CommandRepository.Update(binding); + } + + /// + /// 删除绑定关系 + /// + public async Task DeleteBindingAsync(string id, CancellationToken cancellationToken = default) + { + await CommandRepository.DeleteByIdAsync(id, cancellationToken); + } + + /// + /// 获取所有绑定关系 + /// + public async Task> GetAllBindingsAsync(CancellationToken cancellationToken = default) + { + var bindings = await QueryRepository.GetAllAsync(cancellationToken: cancellationToken); + return bindings.OrderBy(x => x.StackId).ThenBy(x => x.Index).ToList(); + } + + /// + /// 根据ID获取绑定关系 + /// + public async Task GetBindingByIdAsync(string id, CancellationToken cancellationToken = default) + { + return await QueryRepository.GetByIdAsync(id, cancellationToken: cancellationToken); + } + + /// + /// 根据栈ID获取绑定关系 + /// + public async Task> GetBindingsByStackIdAsync(string stackId, CancellationToken cancellationToken = default) + { + var bindings = await QueryRepository.FindAsync(binding => binding.StackId == stackId, cancellationToken: cancellationToken); + return bindings.OrderBy(x => x.Index).ToList(); + } + + /// + /// 根据核心网配置ID获取绑定关系 + /// + public async Task> GetBindingsByCnIdAsync(string cnId, CancellationToken cancellationToken = default) + { + var bindings = await QueryRepository.FindAsync(binding => binding.CnId == cnId, cancellationToken: cancellationToken); + return bindings.OrderBy(x => x.StackId).ThenBy(x => x.Index).ToList(); + } + + /// + /// 根据IMS配置ID获取绑定关系 + /// + public async Task> GetBindingsByImsIdAsync(string imsId, CancellationToken cancellationToken = default) + { + var bindings = await QueryRepository.FindAsync(binding => binding.ImsId == imsId, cancellationToken: cancellationToken); + return bindings.OrderBy(x => x.StackId).ThenBy(x => x.Index).ToList(); + } + + /// + /// 根据栈ID和索引获取绑定关系 + /// + public async Task GetBindingByStackIdAndIndexAsync(string stackId, int index, CancellationToken cancellationToken = default) + { + return await QueryRepository.FirstOrDefaultAsync(binding => binding.StackId == stackId && binding.Index == index, cancellationToken: cancellationToken); + } + + /// + /// 搜索绑定关系 + /// + public async Task> SearchBindingsAsync( + string? stackId = null, + string? cnId = null, + string? imsId = null, + CancellationToken cancellationToken = default) + { + var query = await QueryRepository.FindAsync(binding => true, cancellationToken: cancellationToken); + + if (!string.IsNullOrWhiteSpace(stackId)) + { + query = query.Where(binding => binding.StackId == stackId); + } + + if (!string.IsNullOrWhiteSpace(cnId)) + { + query = query.Where(binding => binding.CnId == cnId); + } + + if (!string.IsNullOrWhiteSpace(imsId)) + { + query = query.Where(binding => binding.ImsId == imsId); + } + + var bindings = query; + return bindings.OrderBy(x => x.StackId).ThenBy(x => x.Index).ToList(); + } + + /// + /// 搜索绑定关系(分页) + /// + public async Task<(int TotalCount, IList Items)> SearchBindingsAsync( + string? stackId = null, + string? cnId = null, + string? imsId = null, + int pageNumber = 1, + int pageSize = 10, + CancellationToken cancellationToken = default) + { + // 构建查询条件 + Expression> predicate = binding => true; + + if (!string.IsNullOrWhiteSpace(stackId)) + { + predicate = binding => binding.StackId == stackId; + } + + if (!string.IsNullOrWhiteSpace(cnId)) + { + var originalPredicate = predicate; + predicate = binding => originalPredicate.Compile()(binding) && binding.CnId == cnId; + } + + if (!string.IsNullOrWhiteSpace(imsId)) + { + var originalPredicate = predicate; + predicate = binding => originalPredicate.Compile()(binding) && binding.ImsId == imsId; + } + + // 执行分页查询 + var result = await QueryRepository.GetPagedAsync(predicate, pageNumber, pageSize, null, cancellationToken); + + return (result.TotalCount, result.Items.OrderBy(x => x.StackId).ThenBy(x => x.Index).ToList()); + } + + /// + /// 检查绑定关系是否存在 + /// + public async Task ExistsAsync(string id, CancellationToken cancellationToken = default) + { + return await QueryRepository.AnyAsync(binding => binding.Id == id, cancellationToken: cancellationToken); + } + + /// + /// 检查栈ID和索引的组合是否存在 + /// + public async Task StackIdAndIndexExistsAsync(string stackId, int index, CancellationToken cancellationToken = default) + { + return await QueryRepository.AnyAsync(binding => binding.StackId == stackId && binding.Index == index, cancellationToken: cancellationToken); + } +} \ No newline at end of file diff --git a/src/X1.Presentation/Controllers/CoreNetworkConfigsController.cs b/src/X1.Presentation/Controllers/CoreNetworkConfigsController.cs new file mode 100644 index 0000000..c8c7bac --- /dev/null +++ b/src/X1.Presentation/Controllers/CoreNetworkConfigsController.cs @@ -0,0 +1,135 @@ +using CellularManagement.Application.Features.CoreNetworkConfigs.Commands.CreateCoreNetworkConfig; +using CellularManagement.Application.Features.CoreNetworkConfigs.Commands.DeleteCoreNetworkConfig; +using CellularManagement.Application.Features.CoreNetworkConfigs.Commands.UpdateCoreNetworkConfig; +using CellularManagement.Application.Features.CoreNetworkConfigs.Queries.GetCoreNetworkConfigById; +using CellularManagement.Application.Features.CoreNetworkConfigs.Queries.GetCoreNetworkConfigs; +using CellularManagement.Domain.Common; +using CellularManagement.Presentation.Abstractions; +using MediatR; +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Mvc; +using Microsoft.Extensions.Logging; + +namespace CellularManagement.Presentation.Controllers; + +/// +/// 核心网络配置管理控制器 +/// +[Route("api/corenetworkconfigs")] +[ApiController] +[Authorize] +public class CoreNetworkConfigsController : ApiController +{ + private readonly ILogger _logger; + + /// + /// 初始化核心网络配置控制器 + /// + public CoreNetworkConfigsController(IMediator mediator, ILogger logger) + : base(mediator) + { + _logger = logger; + } + + /// + /// 获取核心网络配置列表 + /// + [HttpGet] + public async Task> GetAll([FromQuery] GetCoreNetworkConfigsQuery query) + { + _logger.LogInformation("开始获取核心网络配置列表,页码: {PageNumber}, 每页数量: {PageSize}, 搜索关键词: {SearchTerm}, 是否禁用: {IsDisabled}", + query.PageNumber, query.PageSize, query.SearchTerm, query.IsDisabled); + + var result = await mediator.Send(query); + if (!result.IsSuccess) + { + _logger.LogWarning("获取核心网络配置列表失败: {Message}", result.ErrorMessages); + return result; + } + + _logger.LogInformation("成功获取核心网络配置列表,共 {Count} 条记录", result.Data?.TotalCount ?? 0); + return result; + } + + /// + /// 获取核心网络配置详情 + /// + [HttpGet("{id}")] + public async Task> GetById(string id) + { + _logger.LogInformation("开始获取核心网络配置详情,配置ID: {CoreNetworkConfigId}", id); + + var result = await mediator.Send(new GetCoreNetworkConfigByIdQuery { CoreNetworkConfigId = id }); + if (!result.IsSuccess) + { + _logger.LogWarning("获取核心网络配置详情失败: {Message}", result.ErrorMessages); + return result; + } + + _logger.LogInformation("成功获取核心网络配置详情,配置ID: {CoreNetworkConfigId}", id); + return result; + } + + /// + /// 创建核心网络配置 + /// + [HttpPost] + public async Task> Create([FromBody] CreateCoreNetworkConfigCommand command) + { + _logger.LogInformation("开始创建核心网络配置,配置名称: {Name}", command.Name); + + var result = await mediator.Send(command); + if (!result.IsSuccess) + { + _logger.LogWarning("创建核心网络配置失败: {Message}", result.ErrorMessages); + return result; + } + + _logger.LogInformation("成功创建核心网络配置,配置ID: {CoreNetworkConfigId}", result.Data?.CoreNetworkConfigId); + return result; + } + + /// + /// 更新核心网络配置 + /// + [HttpPut("{id}")] + public async Task> Update(string id, [FromBody] UpdateCoreNetworkConfigCommand command) + { + _logger.LogInformation("开始更新核心网络配置,配置ID: {CoreNetworkConfigId}", id); + + if (id != command.CoreNetworkConfigId) + { + _logger.LogWarning("核心网络配置ID不匹配,路径ID: {PathId}, 命令ID: {CommandId}", id, command.CoreNetworkConfigId); + return OperationResult.CreateFailure("核心网络配置ID不匹配"); + } + + var result = await mediator.Send(command); + if (!result.IsSuccess) + { + _logger.LogWarning("更新核心网络配置失败: {Message}", result.ErrorMessages); + return result; + } + + _logger.LogInformation("成功更新核心网络配置,配置ID: {CoreNetworkConfigId}", id); + return result; + } + + /// + /// 删除核心网络配置 + /// + [HttpDelete("{id}")] + public async Task> Delete(string id) + { + _logger.LogInformation("开始删除核心网络配置,配置ID: {CoreNetworkConfigId}", id); + + var result = await mediator.Send(new DeleteCoreNetworkConfigCommand { CoreNetworkConfigId = id }); + if (!result.IsSuccess) + { + _logger.LogWarning("删除核心网络配置失败: {Message}", result.ErrorMessages); + return result; + } + + _logger.LogInformation("成功删除核心网络配置,配置ID: {CoreNetworkConfigId}", id); + return result; + } +} \ No newline at end of file diff --git a/src/X1.Presentation/Controllers/IMSConfigurationController.cs b/src/X1.Presentation/Controllers/IMSConfigurationController.cs new file mode 100644 index 0000000..432d1d5 --- /dev/null +++ b/src/X1.Presentation/Controllers/IMSConfigurationController.cs @@ -0,0 +1,135 @@ +using CellularManagement.Application.Features.IMSConfiguration.Commands.CreateIMS_Configuration; +using CellularManagement.Application.Features.IMSConfiguration.Commands.DeleteIMS_Configuration; +using CellularManagement.Application.Features.IMSConfiguration.Commands.UpdateIMS_Configuration; +using CellularManagement.Application.Features.IMSConfiguration.Queries.GetIMS_ConfigurationById; +using CellularManagement.Application.Features.IMSConfiguration.Queries.GetIMS_Configurations; +using CellularManagement.Domain.Common; +using CellularManagement.Presentation.Abstractions; +using MediatR; +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Mvc; +using Microsoft.Extensions.Logging; + +namespace CellularManagement.Presentation.Controllers; + +/// +/// IMS配置管理控制器 +/// +[Route("api/imsconfigurations")] +[ApiController] +[Authorize] +public class IMSConfigurationController : ApiController +{ + private readonly ILogger _logger; + + /// + /// 初始化IMS配置控制器 + /// + public IMSConfigurationController(IMediator mediator, ILogger logger) + : base(mediator) + { + _logger = logger; + } + + /// + /// 获取IMS配置列表 + /// + [HttpGet] + public async Task> GetAll([FromQuery] GetIMS_ConfigurationsQuery query) + { + _logger.LogInformation("开始获取IMS配置列表,页码: {PageNumber}, 每页数量: {PageSize}, 搜索关键词: {SearchTerm}, 是否禁用: {IsDisabled}", + query.PageNumber, query.PageSize, query.SearchTerm, query.IsDisabled); + + var result = await mediator.Send(query); + if (!result.IsSuccess) + { + _logger.LogWarning("获取IMS配置列表失败: {Message}", result.ErrorMessages); + return result; + } + + _logger.LogInformation("成功获取IMS配置列表,共 {Count} 条记录", result.Data?.TotalCount ?? 0); + return result; + } + + /// + /// 获取IMS配置详情 + /// + [HttpGet("{id}")] + public async Task> GetById(string id) + { + _logger.LogInformation("开始获取IMS配置详情,配置ID: {IMSConfigurationId}", id); + + var result = await mediator.Send(new GetIMS_ConfigurationByIdQuery { IMS_ConfigurationId = id }); + if (!result.IsSuccess) + { + _logger.LogWarning("获取IMS配置详情失败: {Message}", result.ErrorMessages); + return result; + } + + _logger.LogInformation("成功获取IMS配置详情,配置ID: {IMSConfigurationId}", id); + return result; + } + + /// + /// 创建IMS配置 + /// + [HttpPost] + public async Task> Create([FromBody] CreateIMS_ConfigurationCommand command) + { + _logger.LogInformation("开始创建IMS配置,配置名称: {Name}", command.Name); + + var result = await mediator.Send(command); + if (!result.IsSuccess) + { + _logger.LogWarning("创建IMS配置失败: {Message}", result.ErrorMessages); + return result; + } + + _logger.LogInformation("成功创建IMS配置,配置ID: {IMSConfigurationId}", result.Data?.IMS_ConfigurationId); + return result; + } + + /// + /// 更新IMS配置 + /// + [HttpPut("{id}")] + public async Task> Update(string id, [FromBody] UpdateIMS_ConfigurationCommand command) + { + _logger.LogInformation("开始更新IMS配置,配置ID: {IMSConfigurationId}", id); + + if (id != command.IMS_ConfigurationId) + { + _logger.LogWarning("IMS配置ID不匹配,路径ID: {PathId}, 命令ID: {CommandId}", id, command.IMS_ConfigurationId); + return OperationResult.CreateFailure("IMS配置ID不匹配"); + } + + var result = await mediator.Send(command); + if (!result.IsSuccess) + { + _logger.LogWarning("更新IMS配置失败: {Message}", result.ErrorMessages); + return result; + } + + _logger.LogInformation("成功更新IMS配置,配置ID: {IMSConfigurationId}", id); + return result; + } + + /// + /// 删除IMS配置 + /// + [HttpDelete("{id}")] + public async Task> Delete(string id) + { + _logger.LogInformation("开始删除IMS配置,配置ID: {IMSConfigurationId}", id); + + var result = await mediator.Send(new DeleteIMS_ConfigurationCommand { IMS_ConfigurationId = id }); + if (!result.IsSuccess) + { + _logger.LogWarning("删除IMS配置失败: {Message}", result.ErrorMessages); + return result; + } + + _logger.LogInformation("成功删除IMS配置,配置ID: {IMSConfigurationId}", id); + return result; + } +} \ No newline at end of file diff --git a/src/X1.Presentation/Controllers/NetworkConfigsController.cs b/src/X1.Presentation/Controllers/NetworkConfigsController.cs deleted file mode 100644 index 258479c..0000000 --- a/src/X1.Presentation/Controllers/NetworkConfigsController.cs +++ /dev/null @@ -1,289 +0,0 @@ -using Microsoft.AspNetCore.Authorization; -using Microsoft.AspNetCore.Mvc; -using MediatR; -using CellularManagement.Application.Features.NetworkConfigs.Commands.CreateNetworkConfig; -using CellularManagement.Application.Features.NetworkConfigs.Commands.DeleteNetworkConfig; -using CellularManagement.Application.Features.NetworkConfigs.Commands.UpdateNetworkConfig; -using CellularManagement.Application.Features.NetworkConfigs.Queries.GetNetworkConfigById; -using CellularManagement.Application.Features.NetworkConfigs.Queries.GetNetworkConfigs; -using CellularManagement.Application.Common; -using Microsoft.Extensions.Logging; -using Microsoft.AspNetCore.Http; -using CellularManagement.Presentation.Abstractions; -using CellularManagement.Domain.Common; - -namespace CellularManagement.Presentation.Controllers; - -/// -/// 网络配置管理控制器 -/// 提供网络配置管理相关的 API 接口,包括创建、更新、删除和查询网络配置功能 -/// -[Route("api/networkconfigs")] -[ApiController] -[Authorize(Roles = "Admin")] // 只有管理员可以访问 -public class NetworkConfigsController : ApiController -{ - private readonly ILogger _logger; - - /// - /// 初始化网络配置控制器 - /// - /// MediatR 中介者,用于处理命令和查询 - /// 日志记录器 - public NetworkConfigsController( - IMediator mediator, - ILogger logger) : base(mediator) - { - _logger = logger; - } - - /// - /// 获取网络配置列表 - /// - /// - /// 示例请求: - /// - /// GET /api/networkconfigs?pageNumber=1&pageSize=10&configType=1&plmn=46000&onlyEnabled=true&keyword=RAN - /// - /// - /// 查询参数,包含分页、过滤和搜索条件 - /// - /// 查询结果,包含: - /// - 成功:返回网络配置列表和分页信息 - /// - 失败:返回错误信息 - /// - /// 查询成功,返回网络配置列表 - /// 查询失败,返回错误信息 - [HttpGet] - [ProducesResponseType(typeof(OperationResult), StatusCodes.Status200OK)] - [ProducesResponseType(typeof(OperationResult), StatusCodes.Status400BadRequest)] - public async Task> GetNetworkConfigs([FromQuery] GetNetworkConfigsQuery query) - { - try - { - var result = await mediator.Send(query); - - if (result.IsSuccess) - { - _logger.LogInformation("网络配置列表查询成功,共 {Count} 条记录", result.Data?.TotalCount ?? 0); - } - else - { - _logger.LogWarning("网络配置列表查询失败: {Error}", - result.ErrorMessages?.FirstOrDefault()); - } - - return result; - } - catch (Exception ex) - { - _logger.LogError(ex, "查询网络配置列表时发生异常"); - return OperationResult.CreateFailure("系统错误,请稍后重试"); - } - } - - /// - /// 获取网络配置详情 - /// - /// - /// 示例请求: - /// - /// GET /api/networkconfigs/{id} - /// - /// - /// 网络配置ID - /// - /// 查询结果,包含: - /// - 成功:返回网络配置详情 - /// - 失败:返回错误信息 - /// - /// 查询成功,返回网络配置详情 - /// 查询失败,返回错误信息 - [HttpGet("{id}")] - [ProducesResponseType(typeof(OperationResult), StatusCodes.Status200OK)] - [ProducesResponseType(typeof(OperationResult), StatusCodes.Status400BadRequest)] - public async Task> GetNetworkConfigById(string id) - { - try - { - var result = await mediator.Send(new GetNetworkConfigByIdQuery { NetworkConfigId = id }); - - if (result.IsSuccess) - { - _logger.LogInformation("网络配置 {ConfigId} 详情查询成功", id); - } - else - { - _logger.LogWarning("网络配置 {ConfigId} 详情查询失败: {Error}", - id, - result.ErrorMessages?.FirstOrDefault()); - } - - return result; - } - catch (Exception ex) - { - _logger.LogError(ex, "查询网络配置 {ConfigId} 详情时发生异常", id); - return OperationResult.CreateFailure("系统错误,请稍后重试"); - } - } - - /// - /// 创建新网络配置 - /// - /// - /// 示例请求: - /// - /// POST /api/networkconfigs - /// { - /// "configType": 1, - /// "name": "RAN_Config_Default", - /// "plmn": null, - /// "configContent": "{\"frequencyBands\":[\"B1\",\"B3\"]}", - /// "description": "默认RAN配置", - /// "isDisabled": false - /// } - /// - /// - /// 创建网络配置命令,包含配置类型、名称、内容等信息 - /// - /// 创建结果,包含: - /// - 成功:返回网络配置ID - /// - 失败:返回错误信息 - /// - /// 创建成功,返回网络配置ID - /// 创建失败,返回错误信息 - [HttpPost] - [ProducesResponseType(typeof(OperationResult), StatusCodes.Status200OK)] - [ProducesResponseType(typeof(OperationResult), StatusCodes.Status400BadRequest)] - public async Task> CreateNetworkConfig([FromBody] CreateNetworkConfigCommand command) - { - try - { - var result = await mediator.Send(command); - - if (result.IsSuccess) - { - _logger.LogInformation("网络配置 {ConfigName} 创建成功", command.Name); - } - else - { - _logger.LogWarning("网络配置 {ConfigName} 创建失败: {Error}", - command.Name, - result.ErrorMessages?.FirstOrDefault()); - } - - return result; - } - catch (Exception ex) - { - _logger.LogError(ex, "创建网络配置 {ConfigName} 时发生异常", command.Name); - return OperationResult.CreateFailure("系统错误,请稍后重试"); - } - } - - /// - /// 更新网络配置 - /// - /// - /// 示例请求: - /// - /// PUT /api/networkconfigs/{id} - /// { - /// "networkConfigId": "config-id", - /// "name": "RAN_Config_Updated", - /// "configContent": "{\"frequencyBands\":[\"B1\",\"B3\",\"B5\"]}", - /// "description": "更新后的RAN配置" - /// } - /// - /// - /// 网络配置ID - /// 更新网络配置命令 - /// - /// 更新结果,包含: - /// - 成功:返回更新后的网络配置信息 - /// - 失败:返回错误信息 - /// - /// 更新成功,返回网络配置信息 - /// 更新失败,返回错误信息 - [HttpPut("{id}")] - [ProducesResponseType(typeof(OperationResult), StatusCodes.Status200OK)] - [ProducesResponseType(typeof(OperationResult), StatusCodes.Status400BadRequest)] - public async Task> UpdateNetworkConfig(string id, [FromBody] UpdateNetworkConfigCommand command) - { - try - { - if (id != command.NetworkConfigId) - { - _logger.LogWarning("网络配置ID不匹配,路径ID: {PathId}, 命令ID: {CommandId}", id, command.NetworkConfigId); - return OperationResult.CreateFailure("网络配置ID不匹配"); - } - - var result = await mediator.Send(command); - - if (result.IsSuccess) - { - _logger.LogInformation("网络配置 {ConfigId} 更新成功", id); - } - else - { - _logger.LogWarning("网络配置 {ConfigId} 更新失败: {Error}", - id, - result.ErrorMessages?.FirstOrDefault()); - } - - return result; - } - catch (Exception ex) - { - _logger.LogError(ex, "更新网络配置 {ConfigId} 时发生异常", id); - return OperationResult.CreateFailure("系统错误,请稍后重试"); - } - } - - /// - /// 删除网络配置 - /// - /// - /// 示例请求: - /// - /// DELETE /api/networkconfigs/{id} - /// - /// - /// 网络配置ID - /// - /// 删除结果,包含: - /// - 成功:返回删除成功标志 - /// - 失败:返回错误信息 - /// - /// 删除成功 - /// 删除失败,返回错误信息 - [HttpDelete("{id}")] - [ProducesResponseType(typeof(OperationResult), StatusCodes.Status200OK)] - [ProducesResponseType(typeof(OperationResult), StatusCodes.Status400BadRequest)] - public async Task> DeleteNetworkConfig(string id) - { - try - { - var result = await mediator.Send(new DeleteNetworkConfigCommand { NetworkConfigId = id }); - - if (result.IsSuccess) - { - _logger.LogInformation("网络配置 {ConfigId} 删除成功", id); - } - else - { - _logger.LogWarning("网络配置 {ConfigId} 删除失败: {Error}", - id, - result.ErrorMessages?.FirstOrDefault()); - } - - return result; - } - catch (Exception ex) - { - _logger.LogError(ex, "删除网络配置 {ConfigId} 时发生异常", id); - return OperationResult.CreateFailure("系统错误,请稍后重试"); - } - } -} \ No newline at end of file diff --git a/src/X1.Presentation/Controllers/NetworkStackConfigsController.cs b/src/X1.Presentation/Controllers/NetworkStackConfigsController.cs new file mode 100644 index 0000000..78f111e --- /dev/null +++ b/src/X1.Presentation/Controllers/NetworkStackConfigsController.cs @@ -0,0 +1,135 @@ +using CellularManagement.Application.Features.NetworkStackConfigs.Commands.CreateNetworkStackConfig; +using CellularManagement.Application.Features.NetworkStackConfigs.Commands.DeleteNetworkStackConfig; +using CellularManagement.Application.Features.NetworkStackConfigs.Commands.UpdateNetworkStackConfig; +using CellularManagement.Application.Features.NetworkStackConfigs.Queries.GetNetworkStackConfigById; +using CellularManagement.Application.Features.NetworkStackConfigs.Queries.GetNetworkStackConfigs; +using CellularManagement.Domain.Common; +using CellularManagement.Presentation.Abstractions; +using MediatR; +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Mvc; +using Microsoft.Extensions.Logging; + +namespace CellularManagement.Presentation.Controllers; + +/// +/// 网络栈配置管理控制器 +/// +[Route("api/networkstackconfigs")] +[ApiController] +[Authorize] +public class NetworkStackConfigsController : ApiController +{ + private readonly ILogger _logger; + + /// + /// 初始化网络栈配置控制器 + /// + public NetworkStackConfigsController(IMediator mediator, ILogger logger) + : base(mediator) + { + _logger = logger; + } + + /// + /// 获取网络栈配置列表 + /// + [HttpGet] + public async Task> GetAll([FromQuery] GetNetworkStackConfigsQuery query) + { + _logger.LogInformation("开始获取网络栈配置列表,页码: {PageNumber}, 每页数量: {PageSize}, 搜索关键词: {SearchTerm}, 是否激活: {IsActive}, RAN ID: {RanId}", + query.PageNumber, query.PageSize, query.SearchTerm, query.IsActive, query.RanId); + + var result = await mediator.Send(query); + if (!result.IsSuccess) + { + _logger.LogWarning("获取网络栈配置列表失败: {Message}", result.ErrorMessages); + return result; + } + + _logger.LogInformation("成功获取网络栈配置列表,共 {Count} 条记录", result.Data?.TotalCount ?? 0); + return result; + } + + /// + /// 获取网络栈配置详情 + /// + [HttpGet("{id}")] + public async Task> GetById(string id) + { + _logger.LogInformation("开始获取网络栈配置详情,配置ID: {NetworkStackConfigId}", id); + + var result = await mediator.Send(new GetNetworkStackConfigByIdQuery { NetworkStackConfigId = id }); + if (!result.IsSuccess) + { + _logger.LogWarning("获取网络栈配置详情失败: {Message}", result.ErrorMessages); + return result; + } + + _logger.LogInformation("成功获取网络栈配置详情,配置ID: {NetworkStackConfigId}", id); + return result; + } + + /// + /// 创建网络栈配置 + /// + [HttpPost] + public async Task> Create([FromBody] CreateNetworkStackConfigCommand command) + { + _logger.LogInformation("开始创建网络栈配置,栈ID: {StackId}", command.StackId); + + var result = await mediator.Send(command); + if (!result.IsSuccess) + { + _logger.LogWarning("创建网络栈配置失败: {Message}", result.ErrorMessages); + return result; + } + + _logger.LogInformation("成功创建网络栈配置,配置ID: {NetworkStackConfigId}", result.Data?.NetworkStackConfigId); + return result; + } + + /// + /// 更新网络栈配置 + /// + [HttpPut("{id}")] + public async Task> Update(string id, [FromBody] UpdateNetworkStackConfigCommand command) + { + _logger.LogInformation("开始更新网络栈配置,配置ID: {NetworkStackConfigId}", id); + + if (id != command.NetworkStackConfigId) + { + _logger.LogWarning("网络栈配置ID不匹配,路径ID: {PathId}, 命令ID: {CommandId}", id, command.NetworkStackConfigId); + return OperationResult.CreateFailure("网络栈配置ID不匹配"); + } + + var result = await mediator.Send(command); + if (!result.IsSuccess) + { + _logger.LogWarning("更新网络栈配置失败: {Message}", result.ErrorMessages); + return result; + } + + _logger.LogInformation("成功更新网络栈配置,配置ID: {NetworkStackConfigId}", id); + return result; + } + + /// + /// 删除网络栈配置 + /// + [HttpDelete("{id}")] + public async Task> Delete(string id) + { + _logger.LogInformation("开始删除网络栈配置,配置ID: {NetworkStackConfigId}", id); + + var result = await mediator.Send(new DeleteNetworkStackConfigCommand { NetworkStackConfigId = id }); + if (!result.IsSuccess) + { + _logger.LogWarning("删除网络栈配置失败: {Message}", result.ErrorMessages); + return result; + } + + _logger.LogInformation("成功删除网络栈配置,配置ID: {NetworkStackConfigId}", id); + return result; + } +} \ No newline at end of file diff --git a/src/X1.Presentation/Controllers/RANConfigurationController.cs b/src/X1.Presentation/Controllers/RANConfigurationController.cs new file mode 100644 index 0000000..8b18994 --- /dev/null +++ b/src/X1.Presentation/Controllers/RANConfigurationController.cs @@ -0,0 +1,135 @@ +using CellularManagement.Application.Features.RANConfiguration.Commands.CreateRAN_Configuration; +using CellularManagement.Application.Features.RANConfiguration.Commands.DeleteRAN_Configuration; +using CellularManagement.Application.Features.RANConfiguration.Commands.UpdateRAN_Configuration; +using CellularManagement.Application.Features.RANConfiguration.Queries.GetRAN_ConfigurationById; +using CellularManagement.Application.Features.RANConfiguration.Queries.GetRAN_Configurations; +using CellularManagement.Domain.Common; +using CellularManagement.Presentation.Abstractions; +using MediatR; +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Mvc; +using Microsoft.Extensions.Logging; + +namespace CellularManagement.Presentation.Controllers; + +/// +/// RAN配置管理控制器 +/// +[Route("api/ranconfigurations")] +[ApiController] +[Authorize] +public class RANConfigurationController : ApiController +{ + private readonly ILogger _logger; + + /// + /// 初始化RAN配置控制器 + /// + public RANConfigurationController(IMediator mediator, ILogger logger) + : base(mediator) + { + _logger = logger; + } + + /// + /// 获取RAN配置列表 + /// + [HttpGet] + public async Task> GetAll([FromQuery] GetRAN_ConfigurationsQuery query) + { + _logger.LogInformation("开始获取RAN配置列表,页码: {PageNumber}, 每页数量: {PageSize}, 搜索关键词: {SearchTerm}, 是否禁用: {IsDisabled}", + query.PageNumber, query.PageSize, query.SearchTerm, query.IsDisabled); + + var result = await mediator.Send(query); + if (!result.IsSuccess) + { + _logger.LogWarning("获取RAN配置列表失败: {Message}", result.ErrorMessages); + return result; + } + + _logger.LogInformation("成功获取RAN配置列表,共 {Count} 条记录", result.Data?.TotalCount ?? 0); + return result; + } + + /// + /// 获取RAN配置详情 + /// + [HttpGet("{id}")] + public async Task> GetById(string id) + { + _logger.LogInformation("开始获取RAN配置详情,配置ID: {RANConfigurationId}", id); + + var result = await mediator.Send(new GetRAN_ConfigurationByIdQuery { RAN_ConfigurationId = id }); + if (!result.IsSuccess) + { + _logger.LogWarning("获取RAN配置详情失败: {Message}", result.ErrorMessages); + return result; + } + + _logger.LogInformation("成功获取RAN配置详情,配置ID: {RANConfigurationId}", id); + return result; + } + + /// + /// 创建RAN配置 + /// + [HttpPost] + public async Task> Create([FromBody] CreateRAN_ConfigurationCommand command) + { + _logger.LogInformation("开始创建RAN配置,配置名称: {Name}", command.Name); + + var result = await mediator.Send(command); + if (!result.IsSuccess) + { + _logger.LogWarning("创建RAN配置失败: {Message}", result.ErrorMessages); + return result; + } + + _logger.LogInformation("成功创建RAN配置,配置ID: {RANConfigurationId}", result.Data?.RAN_ConfigurationId); + return result; + } + + /// + /// 更新RAN配置 + /// + [HttpPut("{id}")] + public async Task> Update(string id, [FromBody] UpdateRAN_ConfigurationCommand command) + { + _logger.LogInformation("开始更新RAN配置,配置ID: {RANConfigurationId}", id); + + if (id != command.RAN_ConfigurationId) + { + _logger.LogWarning("RAN配置ID不匹配,路径ID: {PathId}, 命令ID: {CommandId}", id, command.RAN_ConfigurationId); + return OperationResult.CreateFailure("RAN配置ID不匹配"); + } + + var result = await mediator.Send(command); + if (!result.IsSuccess) + { + _logger.LogWarning("更新RAN配置失败: {Message}", result.ErrorMessages); + return result; + } + + _logger.LogInformation("成功更新RAN配置,配置ID: {RANConfigurationId}", id); + return result; + } + + /// + /// 删除RAN配置 + /// + [HttpDelete("{id}")] + public async Task> Delete(string id) + { + _logger.LogInformation("开始删除RAN配置,配置ID: {RANConfigurationId}", id); + + var result = await mediator.Send(new DeleteRAN_ConfigurationCommand { RAN_ConfigurationId = id }); + if (!result.IsSuccess) + { + _logger.LogWarning("删除RAN配置失败: {Message}", result.ErrorMessages); + return result; + } + + _logger.LogInformation("成功删除RAN配置,配置ID: {RANConfigurationId}", id); + return result; + } +} \ No newline at end of file diff --git a/src/X1.Presentation/Controllers/StackCoreIMSBindingsController.cs b/src/X1.Presentation/Controllers/StackCoreIMSBindingsController.cs new file mode 100644 index 0000000..b3e1fc5 --- /dev/null +++ b/src/X1.Presentation/Controllers/StackCoreIMSBindingsController.cs @@ -0,0 +1,136 @@ +using CellularManagement.Application.Features.StackCoreIMSBindings.Commands.CreateStackCoreIMSBinding; +using CellularManagement.Application.Features.StackCoreIMSBindings.Commands.DeleteStackCoreIMSBinding; +using CellularManagement.Application.Features.StackCoreIMSBindings.Commands.UpdateStackCoreIMSBinding; +using CellularManagement.Application.Features.StackCoreIMSBindings.Queries.GetStackCoreIMSBindingById; +using CellularManagement.Application.Features.StackCoreIMSBindings.Queries.GetStackCoreIMSBindings; +using CellularManagement.Domain.Common; +using CellularManagement.Presentation.Abstractions; +using MediatR; +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Mvc; +using Microsoft.Extensions.Logging; + +namespace CellularManagement.Presentation.Controllers; + +/// +/// 栈核心网IMS绑定管理控制器 +/// +[Route("api/stackcoreimsbindings")] +[ApiController] +[Authorize] +public class StackCoreIMSBindingsController : ApiController +{ + private readonly ILogger _logger; + + /// + /// 初始化栈核心网IMS绑定控制器 + /// + public StackCoreIMSBindingsController(IMediator mediator, ILogger logger) + : base(mediator) + { + _logger = logger; + } + + /// + /// 获取栈核心网IMS绑定列表 + /// + [HttpGet] + public async Task> GetAll([FromQuery] GetStackCoreIMSBindingsQuery query) + { + _logger.LogInformation("开始获取栈核心网IMS绑定列表,页码: {PageNumber}, 每页数量: {PageSize}, 栈ID: {StackId}, 核心网ID: {CnId}, IMS ID: {ImsId}", + query.PageNumber, query.PageSize, query.StackId, query.CnId, query.ImsId); + + var result = await mediator.Send(query); + if (!result.IsSuccess) + { + _logger.LogWarning("获取栈核心网IMS绑定列表失败: {Message}", result.ErrorMessages); + return result; + } + + _logger.LogInformation("成功获取栈核心网IMS绑定列表,共 {Count} 条记录", result.Data?.TotalCount ?? 0); + return result; + } + + /// + /// 获取栈核心网IMS绑定详情 + /// + [HttpGet("{id}")] + public async Task> GetById(string id) + { + _logger.LogInformation("开始获取栈核心网IMS绑定详情,绑定ID: {StackCoreIMSBindingId}", id); + + var result = await mediator.Send(new GetStackCoreIMSBindingByIdQuery { StackCoreIMSBindingId = id }); + if (!result.IsSuccess) + { + _logger.LogWarning("获取栈核心网IMS绑定详情失败: {Message}", result.ErrorMessages); + return result; + } + + _logger.LogInformation("成功获取栈核心网IMS绑定详情,绑定ID: {StackCoreIMSBindingId}", id); + return result; + } + + /// + /// 创建栈核心网IMS绑定 + /// + [HttpPost] + public async Task> Create([FromBody] CreateStackCoreIMSBindingCommand command) + { + _logger.LogInformation("开始创建栈核心网IMS绑定,栈ID: {StackId}, 索引: {Index}, 核心网ID: {CnId}, IMS ID: {ImsId}", + command.StackId, command.Index, command.CnId, command.ImsId); + + var result = await mediator.Send(command); + if (!result.IsSuccess) + { + _logger.LogWarning("创建栈核心网IMS绑定失败: {Message}", result.ErrorMessages); + return result; + } + + _logger.LogInformation("成功创建栈核心网IMS绑定,绑定ID: {StackCoreIMSBindingId}", result.Data?.StackCoreIMSBindingId); + return result; + } + + /// + /// 更新栈核心网IMS绑定 + /// + [HttpPut("{id}")] + public async Task> Update(string id, [FromBody] UpdateStackCoreIMSBindingCommand command) + { + _logger.LogInformation("开始更新栈核心网IMS绑定,绑定ID: {StackCoreIMSBindingId}", id); + + if (id != command.StackCoreIMSBindingId) + { + _logger.LogWarning("栈核心网IMS绑定ID不匹配,路径ID: {PathId}, 命令ID: {CommandId}", id, command.StackCoreIMSBindingId); + return OperationResult.CreateFailure("栈核心网IMS绑定ID不匹配"); + } + + var result = await mediator.Send(command); + if (!result.IsSuccess) + { + _logger.LogWarning("更新栈核心网IMS绑定失败: {Message}", result.ErrorMessages); + return result; + } + + _logger.LogInformation("成功更新栈核心网IMS绑定,绑定ID: {StackCoreIMSBindingId}", id); + return result; + } + + /// + /// 删除栈核心网IMS绑定 + /// + [HttpDelete("{id}")] + public async Task> Delete(string id) + { + _logger.LogInformation("开始删除栈核心网IMS绑定,绑定ID: {StackCoreIMSBindingId}", id); + + var result = await mediator.Send(new DeleteStackCoreIMSBindingCommand { StackCoreIMSBindingId = id }); + if (!result.IsSuccess) + { + _logger.LogWarning("删除栈核心网IMS绑定失败: {Message}", result.ErrorMessages); + return result; + } + + _logger.LogInformation("成功删除栈核心网IMS绑定,绑定ID: {StackCoreIMSBindingId}", id); + return result; + } +} \ No newline at end of file diff --git a/src/X1.WebAPI/logs/app-20250727.log b/src/X1.WebAPI/logs/app-20250727.log new file mode 100644 index 0000000..0777321 --- /dev/null +++ b/src/X1.WebAPI/logs/app-20250727.log @@ -0,0 +1,604 @@ +2025-07-27 15:50:01.121 +08:00 [INF] DESKTOP-1Q3GI6C [1] 数据库配置验证通过 +2025-07-27 15:50:01.147 +08:00 [INF] DESKTOP-1Q3GI6C [1] JWT配置验证通过 +2025-07-27 15:50:01.149 +08:00 [INF] DESKTOP-1Q3GI6C [1] 邮件配置验证通过 +2025-07-27 15:50:03.702 +08:00 [INF] DESKTOP-1Q3GI6C [1] 初始化 WebSocket 连接管理器 +2025-07-27 15:50:03.736 +08:00 [INF] DESKTOP-1Q3GI6C [1] 创建消息队列完成,入站队列大小:10000,出站队列大小:10000 +2025-07-27 15:50:03.928 +08:00 [INF] DESKTOP-1Q3GI6C [1] 生成新密钥成功,密钥长度: 88 +2025-07-27 15:50:03.931 +08:00 [INF] DESKTOP-1Q3GI6C [1] 密钥Base64验证通过,字节长度: 64 +2025-07-27 15:50:03.934 +08:00 [INF] DESKTOP-1Q3GI6C [1] 密钥熵值: 5.447845823084413 +2025-07-27 15:50:03.941 +08:00 [INF] DESKTOP-1Q3GI6C [1] 初始化连接管理协调器,最大并发处理数:100 +2025-07-27 15:50:03.943 +08:00 [INF] DESKTOP-1Q3GI6C [1] 初始化 WebSocket 消息服务 +2025-07-27 15:50:03.949 +08:00 [INF] DESKTOP-1Q3GI6C [1] 注册消息处理器,消息类型:chat +2025-07-27 15:50:03.952 +08:00 [DBG] DESKTOP-1Q3GI6C [11] 处理器健康检查通过,处理器:ChatMessageHandler +2025-07-27 15:50:03.953 +08:00 [INF] DESKTOP-1Q3GI6C [1] 注册处理器,消息类型:chat,处理器:ChatMessageHandler,池大小:1 +2025-07-27 15:50:03.956 +08:00 [DBG] DESKTOP-1Q3GI6C [1] 处理器注册完成,当前处理器数量:1 +2025-07-27 15:50:03.957 +08:00 [INF] DESKTOP-1Q3GI6C [1] 注册消息处理器,消息类型:heartbeat +2025-07-27 15:50:03.959 +08:00 [DBG] DESKTOP-1Q3GI6C [11] 处理器健康检查通过,处理器:HeartbeatHandlerManager +2025-07-27 15:50:03.959 +08:00 [INF] DESKTOP-1Q3GI6C [1] 注册处理器,消息类型:heartbeat,处理器:HeartbeatHandlerManager,池大小:1 +2025-07-27 15:50:03.961 +08:00 [DBG] DESKTOP-1Q3GI6C [1] 处理器注册完成,当前处理器数量:1 +2025-07-27 15:50:03.962 +08:00 [INF] DESKTOP-1Q3GI6C [1] 注册消息处理器,消息类型:notification +2025-07-27 15:50:03.964 +08:00 [INF] DESKTOP-1Q3GI6C [1] 注册处理器,消息类型:notification,处理器:NotificationMessageHandler,池大小:1 +2025-07-27 15:50:03.964 +08:00 [DBG] DESKTOP-1Q3GI6C [11] 处理器健康检查通过,处理器:NotificationMessageHandler +2025-07-27 15:50:03.966 +08:00 [DBG] DESKTOP-1Q3GI6C [1] 处理器注册完成,当前处理器数量:1 +2025-07-27 15:50:03.968 +08:00 [INF] DESKTOP-1Q3GI6C [1] 注册消息处理器,消息类型:Protocol +2025-07-27 15:50:03.969 +08:00 [INF] DESKTOP-1Q3GI6C [1] 注册处理器,消息类型:Protocol,处理器:ProtocolMessageHandler,池大小:1 +2025-07-27 15:50:03.969 +08:00 [DBG] DESKTOP-1Q3GI6C [11] 处理器健康检查通过,处理器:ProtocolMessageHandler +2025-07-27 15:50:03.971 +08:00 [DBG] DESKTOP-1Q3GI6C [1] 处理器注册完成,当前处理器数量:1 +2025-07-27 15:50:03.975 +08:00 [INF] DESKTOP-1Q3GI6C [1] 初始化管道构建器,输入类型:WebSocketMessage,输出类型:WebSocketMessage +2025-07-27 15:50:03.977 +08:00 [INF] DESKTOP-1Q3GI6C [1] 添加处理步骤,步骤类型:MessageValidationStep +2025-07-27 15:50:03.980 +08:00 [INF] DESKTOP-1Q3GI6C [1] 初始化消息路由步骤,默认超时时间:"00:00:30",最大重试次数:3 +2025-07-27 15:50:03.983 +08:00 [INF] DESKTOP-1Q3GI6C [1] 添加处理步骤,步骤类型:MessageRoutingStep +2025-07-27 15:50:03.985 +08:00 [INF] DESKTOP-1Q3GI6C [1] 开始构建处理管道,步骤数量:2 +2025-07-27 15:50:03.986 +08:00 [DBG] DESKTOP-1Q3GI6C [1] 连接处理步骤:MessageValidationStep -> MessageRoutingStep +2025-07-27 15:50:03.988 +08:00 [DBG] DESKTOP-1Q3GI6C [1] 创建链式处理步骤,第一步:MessageValidationStep,第二步:MessageRoutingStep +2025-07-27 15:50:03.990 +08:00 [INF] DESKTOP-1Q3GI6C [1] 处理管道构建完成,总步骤数:2 +2025-07-27 15:50:03.991 +08:00 [INF] DESKTOP-1Q3GI6C [1] 初始化入站消息处理器,最大并发处理数:10 +2025-07-27 15:50:03.992 +08:00 [INF] DESKTOP-1Q3GI6C [1] WebSocket 消息服务初始化完成 +2025-07-27 15:50:03.995 +08:00 [INF] DESKTOP-1Q3GI6C [1] 初始化连接健康检查服务,检查间隔:30秒,超时时间:120秒 +2025-07-27 15:50:04.023 +08:00 [INF] DESKTOP-1Q3GI6C [1] 密钥Base64验证通过,字节长度: 64 +2025-07-27 15:50:04.024 +08:00 [INF] DESKTOP-1Q3GI6C [1] 密钥熵值: 5.389670647189372 +2025-07-27 15:50:04.026 +08:00 [INF] DESKTOP-1Q3GI6C [1] 密钥轮换服务初始化完成 +2025-07-27 15:50:04.030 +08:00 [INF] DESKTOP-1Q3GI6C [1] WebSocket 消息服务开始运行 +2025-07-27 15:50:04.033 +08:00 [INF] DESKTOP-1Q3GI6C [1] 入站消息处理服务开始运行 +2025-07-27 15:50:04.039 +08:00 [DBG] DESKTOP-1Q3GI6C [1] 开始读取出站消息 +2025-07-27 15:50:04.042 +08:00 [INF] DESKTOP-1Q3GI6C [1] 连接健康检查服务开始运行 +2025-07-27 15:50:04.045 +08:00 [DBG] DESKTOP-1Q3GI6C [1] 获取所有连接,当前连接数:0 +2025-07-27 15:50:04.046 +08:00 [INF] DESKTOP-1Q3GI6C [1] 连接健康检查完成,检查连接数:0,清理连接数:0,检查时间:2025-07-27 07:50:04 +2025-07-27 15:50:34.058 +08:00 [DBG] DESKTOP-1Q3GI6C [10] 获取所有连接,当前连接数:0 +2025-07-27 15:50:34.060 +08:00 [INF] DESKTOP-1Q3GI6C [10] 连接健康检查完成,检查连接数:0,清理连接数:0,检查时间:2025-07-27 07:50:34 +2025-07-27 15:51:03.952 +08:00 [DBG] DESKTOP-1Q3GI6C [10] 处理器健康检查通过,处理器:ChatMessageHandler +2025-07-27 15:51:03.973 +08:00 [DBG] DESKTOP-1Q3GI6C [10] 处理器健康检查通过,处理器:HeartbeatHandlerManager +2025-07-27 15:51:03.974 +08:00 [DBG] DESKTOP-1Q3GI6C [16] 处理器健康检查通过,处理器:ProtocolMessageHandler +2025-07-27 15:51:03.973 +08:00 [DBG] DESKTOP-1Q3GI6C [17] 处理器健康检查通过,处理器:NotificationMessageHandler +2025-07-27 15:51:04.075 +08:00 [DBG] DESKTOP-1Q3GI6C [17] 获取所有连接,当前连接数:0 +2025-07-27 15:51:04.076 +08:00 [INF] DESKTOP-1Q3GI6C [17] 连接健康检查完成,检查连接数:0,清理连接数:0,检查时间:2025-07-27 07:51:04 +2025-07-27 15:51:29.932 +08:00 [INF] DESKTOP-1Q3GI6C [21] Failed to validate the token. +Microsoft.IdentityModel.Tokens.SecurityTokenExpiredException: IDX10223: Lifetime validation failed. The token is expired. ValidTo (UTC): '07/09/2025 14:03:11', Current time (UTC): '07/27/2025 07:51:29'. + at Microsoft.IdentityModel.Tokens.Validators.ValidateLifetime(Nullable`1 notBefore, Nullable`1 expires, SecurityToken securityToken, TokenValidationParameters validationParameters) + at Microsoft.IdentityModel.JsonWebTokens.JsonWebTokenHandler.ValidateTokenPayloadAsync(JsonWebToken jsonWebToken, TokenValidationParameters validationParameters, BaseConfiguration configuration) + at Microsoft.IdentityModel.JsonWebTokens.JsonWebTokenHandler.ValidateJWSAsync(JsonWebToken jsonWebToken, TokenValidationParameters validationParameters, BaseConfiguration configuration) +2025-07-27 15:51:29.932 +08:00 [INF] DESKTOP-1Q3GI6C [19] Failed to validate the token. +Microsoft.IdentityModel.Tokens.SecurityTokenExpiredException: IDX10223: Lifetime validation failed. The token is expired. ValidTo (UTC): '07/09/2025 14:03:11', Current time (UTC): '07/27/2025 07:51:29'. + at Microsoft.IdentityModel.Tokens.Validators.ValidateLifetime(Nullable`1 notBefore, Nullable`1 expires, SecurityToken securityToken, TokenValidationParameters validationParameters) + at Microsoft.IdentityModel.JsonWebTokens.JsonWebTokenHandler.ValidateTokenPayloadAsync(JsonWebToken jsonWebToken, TokenValidationParameters validationParameters, BaseConfiguration configuration) + at Microsoft.IdentityModel.JsonWebTokens.JsonWebTokenHandler.ValidateJWSAsync(JsonWebToken jsonWebToken, TokenValidationParameters validationParameters, BaseConfiguration configuration) +2025-07-27 15:51:29.955 +08:00 [INF] DESKTOP-1Q3GI6C [21] Bearer was not authenticated. Failure message: IDX10223: Lifetime validation failed. The token is expired. ValidTo (UTC): '07/09/2025 14:03:11', Current time (UTC): '07/27/2025 07:51:29'. +2025-07-27 15:51:29.956 +08:00 [INF] DESKTOP-1Q3GI6C [19] Bearer was not authenticated. Failure message: IDX10223: Lifetime validation failed. The token is expired. ValidTo (UTC): '07/09/2025 14:03:11', Current time (UTC): '07/27/2025 07:51:29'. +2025-07-27 15:51:30.808 +08:00 [WRN] DESKTOP-1Q3GI6C [21] The entity type 'IdentityUserLogin' was first mapped explicitly and then ignored. Consider not mapping the entity type in the first place. +2025-07-27 15:51:30.814 +08:00 [WRN] DESKTOP-1Q3GI6C [21] The entity type 'IdentityRoleClaim' was first mapped explicitly and then ignored. Consider not mapping the entity type in the first place. +2025-07-27 15:51:30.815 +08:00 [WRN] DESKTOP-1Q3GI6C [21] The entity type 'IdentityUserClaim' was first mapped explicitly and then ignored. Consider not mapping the entity type in the first place. +2025-07-27 15:51:30.816 +08:00 [WRN] DESKTOP-1Q3GI6C [21] The entity type 'IdentityUserToken' was first mapped explicitly and then ignored. Consider not mapping the entity type in the first place. +2025-07-27 15:51:30.817 +08:00 [WRN] DESKTOP-1Q3GI6C [21] The entity type 'IdentityUserRole' was first mapped explicitly and then ignored. Consider not mapping the entity type in the first place. +2025-07-27 15:51:30.880 +08:00 [WRN] DESKTOP-1Q3GI6C [21] Entity 'AppUser' has a global query filter defined and is the required end of a relationship with the entity 'UserRole'. This may lead to unexpected results when the required entity is filtered out. Either configure the navigation as optional, or define matching query filters for both entities in the navigation. See https://go.microsoft.com/fwlink/?linkid=2131316 for more information. +2025-07-27 15:51:30.892 +08:00 [WRN] DESKTOP-1Q3GI6C [21] Sensitive data logging is enabled. Log entries and exception messages may include sensitive application data; this mode should only be enabled during development. +2025-07-27 15:51:31.002 +08:00 [INF] DESKTOP-1Q3GI6C [19] 开始处理刷新令牌请求 +2025-07-27 15:51:31.002 +08:00 [INF] DESKTOP-1Q3GI6C [21] 开始处理刷新令牌请求 +2025-07-27 15:51:31.005 +08:00 [INF] DESKTOP-1Q3GI6C [21] 开始验证令牌: eyJhbGciOiJIUzUxMiIsInR5cCI6IkpXVCJ9.eyJuYW1laWQiOiJmNGJmOGNkZC0xYWI2LTQwMzItOTgzNy04OTAxYjI5N2Q5NTciLCJ1bmlxdWVfbmFtZSI6Imh5aCIsImVtYWlsIjoiMjk1MTcyNTUxQHFxLmNvbSIsIkxhc3RMb2dpblRpbWUiOiIyMDI1LTA3LTA5VDEzOjQ4OjEwLjg3NzU2NThaIiwicm9sZSI6IjMxNWExNWI0LTlmZjUtNGQ4OS1hMDJjLTJjYWFlZjdmYjY1MyIsInRva2VuX3R5cGUiOiJyZWZyZXNoX3Rva2VuIiwibmJmIjoxNzUyMDY4ODkxLCJleHAiOjE3NTI2NzM2OTEsImlhdCI6MTc1MjA2ODg5MSwiaXNzIjoiWDEiLCJhdWQiOiJYMS5XZWJBUEkifQ.0hYJmZOMlZVAW_g5WvbbtuiMrJtXg7MTlRycgkI-mr9aCY36a1-JMm2Gdfv814XyqD1cG6I4MKl8p9gl3HG87A +2025-07-27 15:51:31.005 +08:00 [INF] DESKTOP-1Q3GI6C [19] 开始验证令牌: eyJhbGciOiJIUzUxMiIsInR5cCI6IkpXVCJ9.eyJuYW1laWQiOiJmNGJmOGNkZC0xYWI2LTQwMzItOTgzNy04OTAxYjI5N2Q5NTciLCJ1bmlxdWVfbmFtZSI6Imh5aCIsImVtYWlsIjoiMjk1MTcyNTUxQHFxLmNvbSIsIkxhc3RMb2dpblRpbWUiOiIyMDI1LTA3LTA5VDEzOjQ4OjEwLjg3NzU2NThaIiwicm9sZSI6IjMxNWExNWI0LTlmZjUtNGQ4OS1hMDJjLTJjYWFlZjdmYjY1MyIsInRva2VuX3R5cGUiOiJyZWZyZXNoX3Rva2VuIiwibmJmIjoxNzUyMDY4ODkxLCJleHAiOjE3NTI2NzM2OTEsImlhdCI6MTc1MjA2ODg5MSwiaXNzIjoiWDEiLCJhdWQiOiJYMS5XZWJBUEkifQ.0hYJmZOMlZVAW_g5WvbbtuiMrJtXg7MTlRycgkI-mr9aCY36a1-JMm2Gdfv814XyqD1cG6I4MKl8p9gl3HG87A +2025-07-27 15:51:31.007 +08:00 [INF] DESKTOP-1Q3GI6C [21] 尝试从缓存获取密钥,缓存键: JwtKey_Current +2025-07-27 15:51:31.007 +08:00 [INF] DESKTOP-1Q3GI6C [19] 尝试从缓存获取密钥,缓存键: JwtKey_Current +2025-07-27 15:51:31.008 +08:00 [INF] DESKTOP-1Q3GI6C [21] 缓存中未找到密钥,从KeyRotationService获取 +2025-07-27 15:51:31.008 +08:00 [INF] DESKTOP-1Q3GI6C [19] 缓存中未找到密钥,从KeyRotationService获取 +2025-07-27 15:51:31.009 +08:00 [INF] DESKTOP-1Q3GI6C [21] 获取当前密钥 +2025-07-27 15:51:31.012 +08:00 [INF] DESKTOP-1Q3GI6C [21] 密钥Base64验证通过,字节长度: 64 +2025-07-27 15:51:31.010 +08:00 [INF] DESKTOP-1Q3GI6C [19] 获取当前密钥 +2025-07-27 15:51:31.018 +08:00 [INF] DESKTOP-1Q3GI6C [21] 密钥熵值: 5.389670647189372 +2025-07-27 15:51:31.021 +08:00 [INF] DESKTOP-1Q3GI6C [19] 密钥Base64验证通过,字节长度: 64 +2025-07-27 15:51:31.023 +08:00 [INF] DESKTOP-1Q3GI6C [21] 当前密钥验证通过,密钥长度: 88 +2025-07-27 15:51:31.025 +08:00 [INF] DESKTOP-1Q3GI6C [19] 密钥熵值: 5.389670647189372 +2025-07-27 15:51:31.028 +08:00 [INF] DESKTOP-1Q3GI6C [21] 从KeyRotationService获取到密钥,密钥长度: 88 +2025-07-27 15:51:31.029 +08:00 [INF] DESKTOP-1Q3GI6C [19] 当前密钥验证通过,密钥长度: 88 +2025-07-27 15:51:31.031 +08:00 [INF] DESKTOP-1Q3GI6C [21] 密钥编码成功,字节长度: 88 +2025-07-27 15:51:31.032 +08:00 [INF] DESKTOP-1Q3GI6C [19] 从KeyRotationService获取到密钥,密钥长度: 88 +2025-07-27 15:51:31.033 +08:00 [INF] DESKTOP-1Q3GI6C [21] 密钥已缓存,过期时间: "2025-07-27T07:56:31.0333700Z" +2025-07-27 15:51:31.033 +08:00 [INF] DESKTOP-1Q3GI6C [19] 密钥编码成功,字节长度: 88 +2025-07-27 15:51:31.034 +08:00 [INF] DESKTOP-1Q3GI6C [21] 验证令牌使用的密钥: a1mrtIiQN+AEmxE4WKFmKocGtrs3nrQaEbjzQgKp1XZWq8jP9HqzsjVgMKt3kAaCmTNaI9B9/YoaGMOY0sy8DQ== +2025-07-27 15:51:31.034 +08:00 [INF] DESKTOP-1Q3GI6C [19] 密钥已缓存,过期时间: "2025-07-27T07:56:31.0349335Z" +2025-07-27 15:51:31.036 +08:00 [INF] DESKTOP-1Q3GI6C [19] 验证令牌使用的密钥: a1mrtIiQN+AEmxE4WKFmKocGtrs3nrQaEbjzQgKp1XZWq8jP9HqzsjVgMKt3kAaCmTNaI9B9/YoaGMOY0sy8DQ== +2025-07-27 15:51:31.042 +08:00 [INF] DESKTOP-1Q3GI6C [21] 令牌算法: HS512 +2025-07-27 15:51:31.042 +08:00 [INF] DESKTOP-1Q3GI6C [19] 令牌算法: HS512 +2025-07-27 15:51:31.043 +08:00 [INF] DESKTOP-1Q3GI6C [21] 密钥解码成功,字节长度: 64 +2025-07-27 15:51:31.043 +08:00 [INF] DESKTOP-1Q3GI6C [19] 密钥解码成功,字节长度: 64 +2025-07-27 15:51:31.051 +08:00 [INF] DESKTOP-1Q3GI6C [21] 令牌验证参数: {"ValidateIssuer":true,"ValidIssuer":"X1","ValidateAudience":true,"ValidAudience":"X1.WebAPI","ValidateLifetime":true,"ClockSkew":"00:05:00","RequireExpirationTime":true,"RequireSignedTokens":true,"RequireAudience":true,"Algorithm":"HS512","KeyLength":64} +2025-07-27 15:51:31.051 +08:00 [INF] DESKTOP-1Q3GI6C [19] 令牌验证参数: {"ValidateIssuer":true,"ValidIssuer":"X1","ValidateAudience":true,"ValidAudience":"X1.WebAPI","ValidateLifetime":true,"ClockSkew":"00:05:00","RequireExpirationTime":true,"RequireSignedTokens":true,"RequireAudience":true,"Algorithm":"HS512","KeyLength":64} +2025-07-27 15:51:31.156 +08:00 [ERR] DESKTOP-1Q3GI6C [19] 令牌已过期: IDX10223: Lifetime validation failed. The token is expired. ValidTo (UTC): '07/16/2025 13:48:11', Current time (UTC): '07/27/2025 07:51:31'. +Microsoft.IdentityModel.Tokens.SecurityTokenExpiredException: IDX10223: Lifetime validation failed. The token is expired. ValidTo (UTC): '07/16/2025 13:48:11', Current time (UTC): '07/27/2025 07:51:31'. + at Microsoft.IdentityModel.Tokens.Validators.ValidateLifetime(Nullable`1 notBefore, Nullable`1 expires, SecurityToken securityToken, TokenValidationParameters validationParameters) + at System.IdentityModel.Tokens.Jwt.JwtSecurityTokenHandler.ValidateLifetime(Nullable`1 notBefore, Nullable`1 expires, JwtSecurityToken jwtToken, TokenValidationParameters validationParameters) + at System.IdentityModel.Tokens.Jwt.JwtSecurityTokenHandler.ValidateTokenPayload(JwtSecurityToken jwtToken, TokenValidationParameters validationParameters, BaseConfiguration configuration) + at System.IdentityModel.Tokens.Jwt.JwtSecurityTokenHandler.ValidateJWS(String token, TokenValidationParameters validationParameters, BaseConfiguration currentConfiguration, SecurityToken& signatureValidatedToken, ExceptionDispatchInfo& exceptionThrown) +--- End of stack trace from previous location --- + at System.IdentityModel.Tokens.Jwt.JwtSecurityTokenHandler.ValidateToken(String token, JwtSecurityToken outerToken, TokenValidationParameters validationParameters, SecurityToken& signatureValidatedToken) + at System.IdentityModel.Tokens.Jwt.JwtSecurityTokenHandler.ValidateToken(String token, TokenValidationParameters validationParameters, SecurityToken& validatedToken) + at CellularManagement.Infrastructure.Services.Authentication.JwtProvider.ValidateToken(String token) in D:\HistoryCode\CellularManagementAPI\CellularManagement\src\X1.Infrastructure\Services\Authentication\JwtProvider.cs:line 151 +2025-07-27 15:51:31.156 +08:00 [ERR] DESKTOP-1Q3GI6C [21] 令牌已过期: IDX10223: Lifetime validation failed. The token is expired. ValidTo (UTC): '07/16/2025 13:48:11', Current time (UTC): '07/27/2025 07:51:31'. +Microsoft.IdentityModel.Tokens.SecurityTokenExpiredException: IDX10223: Lifetime validation failed. The token is expired. ValidTo (UTC): '07/16/2025 13:48:11', Current time (UTC): '07/27/2025 07:51:31'. + at Microsoft.IdentityModel.Tokens.Validators.ValidateLifetime(Nullable`1 notBefore, Nullable`1 expires, SecurityToken securityToken, TokenValidationParameters validationParameters) + at System.IdentityModel.Tokens.Jwt.JwtSecurityTokenHandler.ValidateLifetime(Nullable`1 notBefore, Nullable`1 expires, JwtSecurityToken jwtToken, TokenValidationParameters validationParameters) + at System.IdentityModel.Tokens.Jwt.JwtSecurityTokenHandler.ValidateTokenPayload(JwtSecurityToken jwtToken, TokenValidationParameters validationParameters, BaseConfiguration configuration) + at System.IdentityModel.Tokens.Jwt.JwtSecurityTokenHandler.ValidateJWS(String token, TokenValidationParameters validationParameters, BaseConfiguration currentConfiguration, SecurityToken& signatureValidatedToken, ExceptionDispatchInfo& exceptionThrown) +--- End of stack trace from previous location --- + at System.IdentityModel.Tokens.Jwt.JwtSecurityTokenHandler.ValidateToken(String token, JwtSecurityToken outerToken, TokenValidationParameters validationParameters, SecurityToken& signatureValidatedToken) + at System.IdentityModel.Tokens.Jwt.JwtSecurityTokenHandler.ValidateToken(String token, TokenValidationParameters validationParameters, SecurityToken& validatedToken) + at CellularManagement.Infrastructure.Services.Authentication.JwtProvider.ValidateToken(String token) in D:\HistoryCode\CellularManagementAPI\CellularManagement\src\X1.Infrastructure\Services\Authentication\JwtProvider.cs:line 151 +2025-07-27 15:51:31.165 +08:00 [WRN] DESKTOP-1Q3GI6C [19] 刷新令牌验证失败 +2025-07-27 15:51:31.165 +08:00 [WRN] DESKTOP-1Q3GI6C [21] 刷新令牌验证失败 +2025-07-27 15:51:31.166 +08:00 [WRN] DESKTOP-1Q3GI6C [19] 令牌刷新失败: 无效的刷新令牌 +2025-07-27 15:51:31.166 +08:00 [WRN] DESKTOP-1Q3GI6C [21] 令牌刷新失败: 无效的刷新令牌 +2025-07-27 15:51:33.473 +08:00 [INF] DESKTOP-1Q3GI6C [17] Failed to validate the token. +Microsoft.IdentityModel.Tokens.SecurityTokenExpiredException: IDX10223: Lifetime validation failed. The token is expired. ValidTo (UTC): '07/09/2025 14:03:11', Current time (UTC): '07/27/2025 07:51:33'. + at Microsoft.IdentityModel.Tokens.Validators.ValidateLifetime(Nullable`1 notBefore, Nullable`1 expires, SecurityToken securityToken, TokenValidationParameters validationParameters) + at Microsoft.IdentityModel.JsonWebTokens.JsonWebTokenHandler.ValidateTokenPayloadAsync(JsonWebToken jsonWebToken, TokenValidationParameters validationParameters, BaseConfiguration configuration) + at Microsoft.IdentityModel.JsonWebTokens.JsonWebTokenHandler.ValidateJWSAsync(JsonWebToken jsonWebToken, TokenValidationParameters validationParameters, BaseConfiguration configuration) +2025-07-27 15:51:33.476 +08:00 [INF] DESKTOP-1Q3GI6C [17] Bearer was not authenticated. Failure message: IDX10223: Lifetime validation failed. The token is expired. ValidTo (UTC): '07/09/2025 14:03:11', Current time (UTC): '07/27/2025 07:51:33'. +2025-07-27 15:51:34.086 +08:00 [DBG] DESKTOP-1Q3GI6C [22] 获取所有连接,当前连接数:0 +2025-07-27 15:51:34.087 +08:00 [INF] DESKTOP-1Q3GI6C [22] 连接健康检查完成,检查连接数:0,清理连接数:0,检查时间:2025-07-27 07:51:34 +2025-07-27 15:51:34.100 +08:00 [INF] DESKTOP-1Q3GI6C [22] Executed DbCommand (62ms) [Parameters=[@__ipAddress_0='::1', @__windowStart_1='2025-07-27T07:21:33.6720416Z' (DbType = DateTime)], CommandType='"Text"', CommandTimeout='30'] +SELECT count(*)::int +FROM "LoginLogs" AS l +WHERE l."IpAddress" = @__ipAddress_0 AND NOT (l."IsSuccess") AND l."LoginTime" >= @__windowStart_1 +2025-07-27 15:51:34.223 +08:00 [INF] DESKTOP-1Q3GI6C [22] Executed DbCommand (21ms) [Parameters=[@__normalizedUserName_0='HYH'], CommandType='"Text"', CommandTimeout='30'] +SELECT u."Id", u."AccessFailedCount", u."ConcurrencyStamp", u."CreatedTime", u."Email", u."EmailConfirmed", u."IsActive", u."IsDeleted", u."LastLoginTime", u."LockoutEnabled", u."LockoutEnd", u."ModifiedTime", u."NormalizedEmail", u."NormalizedUserName", u."PasswordHash", u."PhoneNumber", u."PhoneNumberConfirmed", u."RealName", u."SecurityStamp", u."TwoFactorEnabled", u."UserName" +FROM "Users" AS u +WHERE NOT (u."IsDeleted") AND u."NormalizedUserName" = @__normalizedUserName_0 +LIMIT 1 +2025-07-27 15:51:34.362 +08:00 [INF] DESKTOP-1Q3GI6C [17] Executed DbCommand (22ms) [Parameters=[@__normalizedUserName_0='HYH'], CommandType='"Text"', CommandTimeout='30'] +SELECT u."Id", u."AccessFailedCount", u."ConcurrencyStamp", u."CreatedTime", u."Email", u."EmailConfirmed", u."IsActive", u."IsDeleted", u."LastLoginTime", u."LockoutEnabled", u."LockoutEnd", u."ModifiedTime", u."NormalizedEmail", u."NormalizedUserName", u."PasswordHash", u."PhoneNumber", u."PhoneNumberConfirmed", u."RealName", u."SecurityStamp", u."TwoFactorEnabled", u."UserName" +FROM "Users" AS u +WHERE NOT (u."IsDeleted") AND u."NormalizedUserName" = @__normalizedUserName_0 +LIMIT 1 +2025-07-27 15:51:34.473 +08:00 [INF] DESKTOP-1Q3GI6C [17] Executed DbCommand (18ms) [Parameters=[@p20='f4bf8cdd-1ab6-4032-9837-8901b297d957' (Nullable = false), @p0='0', @p1='91c53a77-9f60-4a53-a5b4-a8af7b11d79e', @p21='5d5626dd-5eea-4849-9288-c0be4790b767', @p2='2025-07-05T18:18:17.2254030Z' (DbType = DateTime), @p3='295172551@qq.com' (Nullable = false), @p4='False', @p5='True', @p6='False', @p7='2025-07-27T07:51:34.3353806Z' (Nullable = true) (DbType = DateTime), @p8='True', @p9=NULL (DbType = DateTime), @p10=NULL (DbType = DateTime), @p11='295172551@QQ.COM', @p12='HYH', @p13='AQAAAAIAAYagAAAAEFAQultUYv7OdZI4JnURtlHK68b60bgxQdQ938fMqqEXcu1f0QcWl4873JKGP0Nc/w==', @p14='18162486289' (Nullable = false), @p15='False', @p16='hongenen', @p17='IRRDDR2ICCZ5M6HA667X2DZMYBOHE7QK', @p18='False', @p19='hyh' (Nullable = false)], CommandType='"Text"', CommandTimeout='30'] +UPDATE "Users" SET "AccessFailedCount" = @p0, "ConcurrencyStamp" = @p1, "CreatedTime" = @p2, "Email" = @p3, "EmailConfirmed" = @p4, "IsActive" = @p5, "IsDeleted" = @p6, "LastLoginTime" = @p7, "LockoutEnabled" = @p8, "LockoutEnd" = @p9, "ModifiedTime" = @p10, "NormalizedEmail" = @p11, "NormalizedUserName" = @p12, "PasswordHash" = @p13, "PhoneNumber" = @p14, "PhoneNumberConfirmed" = @p15, "RealName" = @p16, "SecurityStamp" = @p17, "TwoFactorEnabled" = @p18, "UserName" = @p19 +WHERE "Id" = @p20 AND "ConcurrencyStamp" = @p21; +2025-07-27 15:51:34.548 +08:00 [INF] DESKTOP-1Q3GI6C [10] Executed DbCommand (17ms) [Parameters=[@__userId_0='f4bf8cdd-1ab6-4032-9837-8901b297d957'], CommandType='"Text"', CommandTimeout='30'] +SELECT u."UserId", u."RoleId" +FROM "UserRoles" AS u +WHERE u."UserId" = @__userId_0 +2025-07-27 15:51:34.584 +08:00 [INF] DESKTOP-1Q3GI6C [10] Executed DbCommand (17ms) [Parameters=[@__roleId_0='315a15b4-9ff5-4d89-a02c-2caaef7fb653'], CommandType='"Text"', CommandTimeout='30'] +SELECT r."RoleId", r."PermissionId", r."CreatedAt" +FROM "RolePermissions" AS r +WHERE r."RoleId" = @__roleId_0 +2025-07-27 15:51:34.590 +08:00 [INF] DESKTOP-1Q3GI6C [10] 尝试从缓存获取密钥,缓存键: JwtKey_Current +2025-07-27 15:51:34.591 +08:00 [INF] DESKTOP-1Q3GI6C [10] 从缓存获取到密钥,密钥长度: 88 +2025-07-27 15:51:34.592 +08:00 [INF] DESKTOP-1Q3GI6C [10] 生成令牌使用的密钥: a1mrtIiQN+AEmxE4WKFmKocGtrs3nrQaEbjzQgKp1XZWq8jP9HqzsjVgMKt3kAaCmTNaI9B9/YoaGMOY0sy8DQ== +2025-07-27 15:51:34.593 +08:00 [INF] DESKTOP-1Q3GI6C [10] 密钥解码成功,字节长度: 64 +2025-07-27 15:51:34.595 +08:00 [INF] DESKTOP-1Q3GI6C [10] 令牌签名算法: HS512 +2025-07-27 15:51:34.607 +08:00 [INF] DESKTOP-1Q3GI6C [10] 生成的令牌信息: {"TokenType":"access_token","Expires":"2025-07-27T08:06:34.5971924Z","Issuer":"X1","Audience":"X1.WebAPI","IssuedAt":"2025-07-27T07:51:34.597343Z","NotBefore":"2025-07-27T07:51:34.5973801Z","Algorithm":"HS512","KeyLength":64} +2025-07-27 15:51:34.608 +08:00 [INF] DESKTOP-1Q3GI6C [10] 尝试从缓存获取密钥,缓存键: JwtKey_Current +2025-07-27 15:51:34.610 +08:00 [INF] DESKTOP-1Q3GI6C [10] 从缓存获取到密钥,密钥长度: 88 +2025-07-27 15:51:34.611 +08:00 [INF] DESKTOP-1Q3GI6C [10] 生成令牌使用的密钥: a1mrtIiQN+AEmxE4WKFmKocGtrs3nrQaEbjzQgKp1XZWq8jP9HqzsjVgMKt3kAaCmTNaI9B9/YoaGMOY0sy8DQ== +2025-07-27 15:51:34.612 +08:00 [INF] DESKTOP-1Q3GI6C [10] 密钥解码成功,字节长度: 64 +2025-07-27 15:51:34.613 +08:00 [INF] DESKTOP-1Q3GI6C [10] 令牌签名算法: HS512 +2025-07-27 15:51:34.614 +08:00 [INF] DESKTOP-1Q3GI6C [10] 生成的令牌信息: {"TokenType":"refresh_token","Expires":"2025-08-03T07:51:34.6140086Z","Issuer":"X1","Audience":"X1.WebAPI","IssuedAt":"2025-07-27T07:51:34.614011Z","NotBefore":"2025-07-27T07:51:34.6140111Z","Algorithm":"HS512","KeyLength":64} +2025-07-27 15:51:34.685 +08:00 [INF] DESKTOP-1Q3GI6C [21] Executed DbCommand (21ms) [Parameters=[@p0='0ed101cc-1bc3-4f22-81fd-72e900a9f0c6' (Nullable = false), @p1='Chrome 138.0.0', @p2='2025-07-27T07:51:34.6158493Z' (DbType = DateTime), @p3=NULL, @p4='::1' (Nullable = false), @p5='False', @p6='True', @p7=NULL, @p8='Web' (Nullable = false), @p9='2025-07-27T07:51:34.6158489Z' (DbType = DateTime), @p10='Password' (Nullable = false), @p11='Windows 10', @p12=NULL, @p13=NULL (DbType = DateTime), @p14='Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36 Edg/138.0.0.0' (Nullable = false), @p15='f4bf8cdd-1ab6-4032-9837-8901b297d957' (Nullable = false)], CommandType='"Text"', CommandTimeout='30'] +INSERT INTO "LoginLogs" ("Id", "Browser", "CreatedAt", "FailureReason", "IpAddress", "IsDeleted", "IsSuccess", "Location", "LoginSource", "LoginTime", "LoginType", "OperatingSystem", "SessionId", "UpdatedAt", "UserAgent", "UserId") +VALUES (@p0, @p1, @p2, @p3, @p4, @p5, @p6, @p7, @p8, @p9, @p10, @p11, @p12, @p13, @p14, @p15); +2025-07-27 15:51:34.689 +08:00 [INF] DESKTOP-1Q3GI6C [21] 用户 hyh 认证成功 +2025-07-27 15:51:34.691 +08:00 [INF] DESKTOP-1Q3GI6C [21] 账号 hyh 登录成功 +2025-07-27 15:51:34.693 +08:00 [WRN] DESKTOP-1Q3GI6C [21] Bearer eyJhbGciOiJIUzUxMiIsInR5cCI6IkpXVCJ9.eyJuYW1laWQiOiJmNGJmOGNkZC0xYWI2LTQwMzItOTgzNy04OTAxYjI5N2Q5NTciLCJ1bmlxdWVfbmFtZSI6Imh5aCIsImVtYWlsIjoiMjk1MTcyNTUxQHFxLmNvbSIsIkxhc3RMb2dpblRpbWUiOiIyMDI1LTA3LTI3VDA3OjUxOjM0LjMzNTM4MDZaIiwicm9sZSI6IjMxNWExNWI0LTlmZjUtNGQ4OS1hMDJjLTJjYWFlZjdmYjY1MyIsInRva2VuX3R5cGUiOiJhY2Nlc3NfdG9rZW4iLCJuYmYiOjE3NTM2MDI2OTQsImV4cCI6MTc1MzYwMzU5NCwiaWF0IjoxNzUzNjAyNjk0LCJpc3MiOiJYMSIsImF1ZCI6IlgxLldlYkFQSSJ9.vM2IyoORFgbs-tEeguQCHmuQVV9mx7epoeY3oO6PUu7NmrHFODVia5AUda_nJkF5QgzHF3fx4a8O9rq8fNqPfA +2025-07-27 15:51:39.407 +08:00 [DBG] DESKTOP-1Q3GI6C [17] Successfully validated the token. +2025-07-27 15:51:39.410 +08:00 [DBG] DESKTOP-1Q3GI6C [17] AuthenticationScheme: Bearer was successfully authenticated. +2025-07-27 15:51:39.415 +08:00 [DBG] DESKTOP-1Q3GI6C [17] Authorization was successful. +2025-07-27 15:51:39.453 +08:00 [INF] DESKTOP-1Q3GI6C [17] Executed DbCommand (18ms) [Parameters=[], CommandType='"Text"', CommandTimeout='30'] +SELECT count(*)::int +FROM "Users" AS u +WHERE NOT (u."IsDeleted") +2025-07-27 15:51:39.458 +08:00 [WRN] DESKTOP-1Q3GI6C [17] The query uses a row limiting operator ('Skip'/'Take') without an 'OrderBy' operator. This may lead to unpredictable results. If the 'Distinct' operator is used after 'OrderBy', then make sure to use the 'OrderBy' operator after 'Distinct' as the ordering would otherwise get erased. +2025-07-27 15:51:39.460 +08:00 [WRN] DESKTOP-1Q3GI6C [17] The query uses a row limiting operator ('Skip'/'Take') without an 'OrderBy' operator. This may lead to unpredictable results. If the 'Distinct' operator is used after 'OrderBy', then make sure to use the 'OrderBy' operator after 'Distinct' as the ordering would otherwise get erased. +2025-07-27 15:51:39.483 +08:00 [INF] DESKTOP-1Q3GI6C [17] Executed DbCommand (18ms) [Parameters=[@__p_1='10', @__p_0='0'], CommandType='"Text"', CommandTimeout='30'] +SELECT u."Id", u."AccessFailedCount", u."ConcurrencyStamp", u."CreatedTime", u."Email", u."EmailConfirmed", u."IsActive", u."IsDeleted", u."LastLoginTime", u."LockoutEnabled", u."LockoutEnd", u."ModifiedTime", u."NormalizedEmail", u."NormalizedUserName", u."PasswordHash", u."PhoneNumber", u."PhoneNumberConfirmed", u."RealName", u."SecurityStamp", u."TwoFactorEnabled", u."UserName" +FROM "Users" AS u +WHERE NOT (u."IsDeleted") +LIMIT @__p_1 OFFSET @__p_0 +2025-07-27 15:51:39.487 +08:00 [INF] DESKTOP-1Q3GI6C [17] 获取用户列表成功,共 1 条记录,当前第 1 页 +2025-07-27 15:51:39.495 +08:00 [DBG] DESKTOP-1Q3GI6C [21] Successfully validated the token. +2025-07-27 15:51:39.497 +08:00 [DBG] DESKTOP-1Q3GI6C [21] AuthenticationScheme: Bearer was successfully authenticated. +2025-07-27 15:51:39.499 +08:00 [DBG] DESKTOP-1Q3GI6C [21] Authorization was successful. +2025-07-27 15:51:39.522 +08:00 [INF] DESKTOP-1Q3GI6C [21] Executed DbCommand (17ms) [Parameters=[], CommandType='"Text"', CommandTimeout='30'] +SELECT count(*)::int +FROM "Users" AS u +WHERE NOT (u."IsDeleted") +2025-07-27 15:51:39.541 +08:00 [INF] DESKTOP-1Q3GI6C [21] Executed DbCommand (15ms) [Parameters=[@__p_1='10', @__p_0='0'], CommandType='"Text"', CommandTimeout='30'] +SELECT u."Id", u."AccessFailedCount", u."ConcurrencyStamp", u."CreatedTime", u."Email", u."EmailConfirmed", u."IsActive", u."IsDeleted", u."LastLoginTime", u."LockoutEnabled", u."LockoutEnd", u."ModifiedTime", u."NormalizedEmail", u."NormalizedUserName", u."PasswordHash", u."PhoneNumber", u."PhoneNumberConfirmed", u."RealName", u."SecurityStamp", u."TwoFactorEnabled", u."UserName" +FROM "Users" AS u +WHERE NOT (u."IsDeleted") +LIMIT @__p_1 OFFSET @__p_0 +2025-07-27 15:51:39.543 +08:00 [INF] DESKTOP-1Q3GI6C [21] 获取用户列表成功,共 1 条记录,当前第 1 页 +2025-07-27 15:51:44.810 +08:00 [DBG] DESKTOP-1Q3GI6C [20] Successfully validated the token. +2025-07-27 15:51:44.811 +08:00 [DBG] DESKTOP-1Q3GI6C [20] AuthenticationScheme: Bearer was successfully authenticated. +2025-07-27 15:51:44.840 +08:00 [INF] DESKTOP-1Q3GI6C [22] Executed DbCommand (17ms) [Parameters=[], CommandType='"Text"', CommandTimeout='30'] +SELECT count(*)::int +FROM "Roles" AS r +2025-07-27 15:51:44.843 +08:00 [WRN] DESKTOP-1Q3GI6C [22] The query uses a row limiting operator ('Skip'/'Take') without an 'OrderBy' operator. This may lead to unpredictable results. If the 'Distinct' operator is used after 'OrderBy', then make sure to use the 'OrderBy' operator after 'Distinct' as the ordering would otherwise get erased. +2025-07-27 15:51:44.845 +08:00 [WRN] DESKTOP-1Q3GI6C [22] The query uses a row limiting operator ('Skip'/'Take') without an 'OrderBy' operator. This may lead to unpredictable results. If the 'Distinct' operator is used after 'OrderBy', then make sure to use the 'OrderBy' operator after 'Distinct' as the ordering would otherwise get erased. +2025-07-27 15:51:44.864 +08:00 [INF] DESKTOP-1Q3GI6C [22] Executed DbCommand (16ms) [Parameters=[@__p_1='10', @__p_0='0'], CommandType='"Text"', CommandTimeout='30'] +SELECT r."Id", r."ConcurrencyStamp", r."CreatedAt", r."Description", r."Name", r."NormalizedName", r."UpdatedAt" +FROM "Roles" AS r +LIMIT @__p_1 OFFSET @__p_0 +2025-07-27 15:51:44.877 +08:00 [INF] DESKTOP-1Q3GI6C [22] 成功获取所有角色,共 1 个 +2025-07-27 15:51:44.879 +08:00 [INF] DESKTOP-1Q3GI6C [22] 获取所有角色成功,共 1 个角色 +2025-07-27 15:51:44.885 +08:00 [DBG] DESKTOP-1Q3GI6C [22] Successfully validated the token. +2025-07-27 15:51:44.886 +08:00 [DBG] DESKTOP-1Q3GI6C [22] AuthenticationScheme: Bearer was successfully authenticated. +2025-07-27 15:51:44.905 +08:00 [INF] DESKTOP-1Q3GI6C [22] Executed DbCommand (16ms) [Parameters=[], CommandType='"Text"', CommandTimeout='30'] +SELECT count(*)::int +FROM "Roles" AS r +2025-07-27 15:51:44.925 +08:00 [INF] DESKTOP-1Q3GI6C [20] Executed DbCommand (16ms) [Parameters=[@__p_1='10', @__p_0='0'], CommandType='"Text"', CommandTimeout='30'] +SELECT r."Id", r."ConcurrencyStamp", r."CreatedAt", r."Description", r."Name", r."NormalizedName", r."UpdatedAt" +FROM "Roles" AS r +LIMIT @__p_1 OFFSET @__p_0 +2025-07-27 15:51:44.930 +08:00 [INF] DESKTOP-1Q3GI6C [20] 成功获取所有角色,共 1 个 +2025-07-27 15:51:44.932 +08:00 [INF] DESKTOP-1Q3GI6C [20] 获取所有角色成功,共 1 个角色 +2025-07-27 15:51:49.133 +08:00 [DBG] DESKTOP-1Q3GI6C [21] Successfully validated the token. +2025-07-27 15:51:49.134 +08:00 [DBG] DESKTOP-1Q3GI6C [21] AuthenticationScheme: Bearer was successfully authenticated. +2025-07-27 15:51:49.138 +08:00 [DBG] DESKTOP-1Q3GI6C [21] Authorization was successful. +2025-07-27 15:51:49.144 +08:00 [INF] DESKTOP-1Q3GI6C [21] 开始获取设备列表,页码: 1, 每页数量: 10, 搜索关键词: null +2025-07-27 15:51:49.150 +08:00 [INF] DESKTOP-1Q3GI6C [21] 开始获取设备列表,页码: 1, 每页数量: 10, 搜索关键词: null +2025-07-27 15:51:49.178 +08:00 [INF] DESKTOP-1Q3GI6C [21] Executed DbCommand (18ms) [Parameters=[], CommandType='"Text"', CommandTimeout='30'] +SELECT count(*)::int +FROM "CellularDevices" AS c +2025-07-27 15:51:49.188 +08:00 [WRN] DESKTOP-1Q3GI6C [21] The query uses a row limiting operator ('Skip'/'Take') without an 'OrderBy' operator. This may lead to unpredictable results. If the 'Distinct' operator is used after 'OrderBy', then make sure to use the 'OrderBy' operator after 'Distinct' as the ordering would otherwise get erased. +2025-07-27 15:51:49.189 +08:00 [WRN] DESKTOP-1Q3GI6C [21] The query uses a row limiting operator ('Skip'/'Take') without an 'OrderBy' operator. This may lead to unpredictable results. If the 'Distinct' operator is used after 'OrderBy', then make sure to use the 'OrderBy' operator after 'Distinct' as the ordering would otherwise get erased. +2025-07-27 15:51:49.241 +08:00 [INF] DESKTOP-1Q3GI6C [21] Executed DbCommand (18ms) [Parameters=[@__p_1='10', @__p_0='0'], CommandType='"Text"', CommandTimeout='30'] +SELECT t."Id", t."AgentPort", t."CreatedAt", t."CreatedBy", t."Description", t."IpAddress", t."IsDeleted", t."IsEnabled", t."IsRunning", t."Name", t."ProtocolVersionId", t."SerialNumber", t."UpdatedAt", t."UpdatedBy", p."Id", p."CreatedAt", p."CreatedBy", p."Description", p."IsDeleted", p."IsEnabled", p."MinimumSupportedVersion", p."Name", p."ReleaseDate", p."UpdatedAt", p."UpdatedBy", p."Version" +FROM ( + SELECT c."Id", c."AgentPort", c."CreatedAt", c."CreatedBy", c."Description", c."IpAddress", c."IsDeleted", c."IsEnabled", c."IsRunning", c."Name", c."ProtocolVersionId", c."SerialNumber", c."UpdatedAt", c."UpdatedBy" + FROM "CellularDevices" AS c + LIMIT @__p_1 OFFSET @__p_0 +) AS t +INNER JOIN "ProtocolVersions" AS p ON t."ProtocolVersionId" = p."Id" +2025-07-27 15:51:49.275 +08:00 [INF] DESKTOP-1Q3GI6C [21] 成功获取设备列表,共 3 条记录 +2025-07-27 15:51:49.276 +08:00 [INF] DESKTOP-1Q3GI6C [21] 成功获取设备列表,共 3 条记录 +2025-07-27 15:51:49.282 +08:00 [DBG] DESKTOP-1Q3GI6C [20] Successfully validated the token. +2025-07-27 15:51:49.283 +08:00 [DBG] DESKTOP-1Q3GI6C [20] AuthenticationScheme: Bearer was successfully authenticated. +2025-07-27 15:51:49.284 +08:00 [DBG] DESKTOP-1Q3GI6C [20] Authorization was successful. +2025-07-27 15:51:49.285 +08:00 [INF] DESKTOP-1Q3GI6C [20] 开始获取设备列表,页码: 1, 每页数量: 10, 搜索关键词: null +2025-07-27 15:51:49.288 +08:00 [INF] DESKTOP-1Q3GI6C [20] 开始获取设备列表,页码: 1, 每页数量: 10, 搜索关键词: null +2025-07-27 15:51:49.306 +08:00 [INF] DESKTOP-1Q3GI6C [10] Executed DbCommand (17ms) [Parameters=[], CommandType='"Text"', CommandTimeout='30'] +SELECT count(*)::int +FROM "CellularDevices" AS c +2025-07-27 15:51:49.327 +08:00 [INF] DESKTOP-1Q3GI6C [16] Executed DbCommand (17ms) [Parameters=[@__p_1='10', @__p_0='0'], CommandType='"Text"', CommandTimeout='30'] +SELECT t."Id", t."AgentPort", t."CreatedAt", t."CreatedBy", t."Description", t."IpAddress", t."IsDeleted", t."IsEnabled", t."IsRunning", t."Name", t."ProtocolVersionId", t."SerialNumber", t."UpdatedAt", t."UpdatedBy", p."Id", p."CreatedAt", p."CreatedBy", p."Description", p."IsDeleted", p."IsEnabled", p."MinimumSupportedVersion", p."Name", p."ReleaseDate", p."UpdatedAt", p."UpdatedBy", p."Version" +FROM ( + SELECT c."Id", c."AgentPort", c."CreatedAt", c."CreatedBy", c."Description", c."IpAddress", c."IsDeleted", c."IsEnabled", c."IsRunning", c."Name", c."ProtocolVersionId", c."SerialNumber", c."UpdatedAt", c."UpdatedBy" + FROM "CellularDevices" AS c + LIMIT @__p_1 OFFSET @__p_0 +) AS t +INNER JOIN "ProtocolVersions" AS p ON t."ProtocolVersionId" = p."Id" +2025-07-27 15:51:49.330 +08:00 [INF] DESKTOP-1Q3GI6C [16] 成功获取设备列表,共 3 条记录 +2025-07-27 15:51:49.332 +08:00 [INF] DESKTOP-1Q3GI6C [16] 成功获取设备列表,共 3 条记录 +2025-07-27 15:52:03.948 +08:00 [DBG] DESKTOP-1Q3GI6C [22] 处理器健康检查通过,处理器:ChatMessageHandler +2025-07-27 15:52:03.963 +08:00 [DBG] DESKTOP-1Q3GI6C [19] 处理器健康检查通过,处理器:NotificationMessageHandler +2025-07-27 15:52:03.963 +08:00 [DBG] DESKTOP-1Q3GI6C [22] 处理器健康检查通过,处理器:HeartbeatHandlerManager +2025-07-27 15:52:03.963 +08:00 [DBG] DESKTOP-1Q3GI6C [21] 处理器健康检查通过,处理器:ProtocolMessageHandler +2025-07-27 15:52:04.090 +08:00 [DBG] DESKTOP-1Q3GI6C [21] 获取所有连接,当前连接数:0 +2025-07-27 15:52:04.093 +08:00 [INF] DESKTOP-1Q3GI6C [21] 连接健康检查完成,检查连接数:0,清理连接数:0,检查时间:2025-07-27 07:52:04 +2025-07-27 15:52:16.160 +08:00 [DBG] DESKTOP-1Q3GI6C [21] Successfully validated the token. +2025-07-27 15:52:16.161 +08:00 [DBG] DESKTOP-1Q3GI6C [21] AuthenticationScheme: Bearer was successfully authenticated. +2025-07-27 15:52:16.163 +08:00 [DBG] DESKTOP-1Q3GI6C [21] Authorization was successful. +2025-07-27 15:52:16.168 +08:00 [INF] DESKTOP-1Q3GI6C [21] 开始获取协议版本列表,页码: 1, 每页数量: 10, 搜索关键词: null, 是否启用: null +2025-07-27 15:52:16.173 +08:00 [INF] DESKTOP-1Q3GI6C [21] 开始获取协议版本列表,页码: 1, 每页数量: 10, 搜索关键词: null, 是否启用: null +2025-07-27 15:52:16.196 +08:00 [INF] DESKTOP-1Q3GI6C [21] Executed DbCommand (15ms) [Parameters=[], CommandType='"Text"', CommandTimeout='30'] +SELECT p."Id", p."CreatedAt", p."CreatedBy", p."Description", p."IsDeleted", p."IsEnabled", p."MinimumSupportedVersion", p."Name", p."ReleaseDate", p."UpdatedAt", p."UpdatedBy", p."Version" +FROM "ProtocolVersions" AS p +2025-07-27 15:52:16.200 +08:00 [INF] DESKTOP-1Q3GI6C [21] 成功获取协议版本列表,共 3 条记录 +2025-07-27 15:52:16.201 +08:00 [INF] DESKTOP-1Q3GI6C [21] 成功获取协议版本列表,共 3 条记录 +2025-07-27 15:52:16.208 +08:00 [DBG] DESKTOP-1Q3GI6C [16] Successfully validated the token. +2025-07-27 15:52:16.209 +08:00 [DBG] DESKTOP-1Q3GI6C [16] AuthenticationScheme: Bearer was successfully authenticated. +2025-07-27 15:52:16.211 +08:00 [DBG] DESKTOP-1Q3GI6C [16] Authorization was successful. +2025-07-27 15:52:16.212 +08:00 [INF] DESKTOP-1Q3GI6C [16] 开始获取协议版本列表,页码: 1, 每页数量: 10, 搜索关键词: null, 是否启用: null +2025-07-27 15:52:16.215 +08:00 [INF] DESKTOP-1Q3GI6C [16] 开始获取协议版本列表,页码: 1, 每页数量: 10, 搜索关键词: null, 是否启用: null +2025-07-27 15:52:16.232 +08:00 [INF] DESKTOP-1Q3GI6C [17] Executed DbCommand (16ms) [Parameters=[], CommandType='"Text"', CommandTimeout='30'] +SELECT p."Id", p."CreatedAt", p."CreatedBy", p."Description", p."IsDeleted", p."IsEnabled", p."MinimumSupportedVersion", p."Name", p."ReleaseDate", p."UpdatedAt", p."UpdatedBy", p."Version" +FROM "ProtocolVersions" AS p +2025-07-27 15:52:16.235 +08:00 [INF] DESKTOP-1Q3GI6C [17] 成功获取协议版本列表,共 3 条记录 +2025-07-27 15:52:16.236 +08:00 [INF] DESKTOP-1Q3GI6C [17] 成功获取协议版本列表,共 3 条记录 +2025-07-27 15:52:21.319 +08:00 [DBG] DESKTOP-1Q3GI6C [20] Successfully validated the token. +2025-07-27 15:52:21.321 +08:00 [DBG] DESKTOP-1Q3GI6C [20] AuthenticationScheme: Bearer was successfully authenticated. +2025-07-27 15:52:21.333 +08:00 [DBG] DESKTOP-1Q3GI6C [20] Successfully validated the token. +2025-07-27 15:52:21.335 +08:00 [DBG] DESKTOP-1Q3GI6C [20] AuthenticationScheme: Bearer was successfully authenticated. +2025-07-27 15:52:22.338 +08:00 [DBG] DESKTOP-1Q3GI6C [16] Successfully validated the token. +2025-07-27 15:52:22.345 +08:00 [DBG] DESKTOP-1Q3GI6C [16] AuthenticationScheme: Bearer was successfully authenticated. +2025-07-27 15:52:22.348 +08:00 [DBG] DESKTOP-1Q3GI6C [16] Successfully validated the token. +2025-07-27 15:52:22.353 +08:00 [DBG] DESKTOP-1Q3GI6C [16] AuthenticationScheme: Bearer was successfully authenticated. +2025-07-27 15:52:23.354 +08:00 [DBG] DESKTOP-1Q3GI6C [20] Successfully validated the token. +2025-07-27 15:52:23.357 +08:00 [DBG] DESKTOP-1Q3GI6C [20] AuthenticationScheme: Bearer was successfully authenticated. +2025-07-27 15:52:23.361 +08:00 [DBG] DESKTOP-1Q3GI6C [16] Successfully validated the token. +2025-07-27 15:52:23.370 +08:00 [DBG] DESKTOP-1Q3GI6C [16] AuthenticationScheme: Bearer was successfully authenticated. +2025-07-27 15:52:24.362 +08:00 [DBG] DESKTOP-1Q3GI6C [20] Successfully validated the token. +2025-07-27 15:52:24.364 +08:00 [DBG] DESKTOP-1Q3GI6C [20] AuthenticationScheme: Bearer was successfully authenticated. +2025-07-27 15:52:24.379 +08:00 [DBG] DESKTOP-1Q3GI6C [21] Successfully validated the token. +2025-07-27 15:52:24.380 +08:00 [DBG] DESKTOP-1Q3GI6C [21] AuthenticationScheme: Bearer was successfully authenticated. +2025-07-27 15:52:27.106 +08:00 [DBG] DESKTOP-1Q3GI6C [22] Successfully validated the token. +2025-07-27 15:52:27.108 +08:00 [DBG] DESKTOP-1Q3GI6C [22] AuthenticationScheme: Bearer was successfully authenticated. +2025-07-27 15:52:27.110 +08:00 [DBG] DESKTOP-1Q3GI6C [22] Authorization was successful. +2025-07-27 15:52:27.111 +08:00 [INF] DESKTOP-1Q3GI6C [22] 开始获取设备列表,页码: 1, 每页数量: 10, 搜索关键词: null +2025-07-27 15:52:27.116 +08:00 [INF] DESKTOP-1Q3GI6C [22] 开始获取设备列表,页码: 1, 每页数量: 10, 搜索关键词: null +2025-07-27 15:52:27.134 +08:00 [INF] DESKTOP-1Q3GI6C [22] Executed DbCommand (16ms) [Parameters=[], CommandType='"Text"', CommandTimeout='30'] +SELECT count(*)::int +FROM "CellularDevices" AS c +2025-07-27 15:52:27.156 +08:00 [INF] DESKTOP-1Q3GI6C [22] Executed DbCommand (18ms) [Parameters=[@__p_1='10', @__p_0='0'], CommandType='"Text"', CommandTimeout='30'] +SELECT t."Id", t."AgentPort", t."CreatedAt", t."CreatedBy", t."Description", t."IpAddress", t."IsDeleted", t."IsEnabled", t."IsRunning", t."Name", t."ProtocolVersionId", t."SerialNumber", t."UpdatedAt", t."UpdatedBy", p."Id", p."CreatedAt", p."CreatedBy", p."Description", p."IsDeleted", p."IsEnabled", p."MinimumSupportedVersion", p."Name", p."ReleaseDate", p."UpdatedAt", p."UpdatedBy", p."Version" +FROM ( + SELECT c."Id", c."AgentPort", c."CreatedAt", c."CreatedBy", c."Description", c."IpAddress", c."IsDeleted", c."IsEnabled", c."IsRunning", c."Name", c."ProtocolVersionId", c."SerialNumber", c."UpdatedAt", c."UpdatedBy" + FROM "CellularDevices" AS c + LIMIT @__p_1 OFFSET @__p_0 +) AS t +INNER JOIN "ProtocolVersions" AS p ON t."ProtocolVersionId" = p."Id" +2025-07-27 15:52:27.159 +08:00 [INF] DESKTOP-1Q3GI6C [22] 成功获取设备列表,共 3 条记录 +2025-07-27 15:52:27.161 +08:00 [INF] DESKTOP-1Q3GI6C [22] 成功获取设备列表,共 3 条记录 +2025-07-27 15:52:27.164 +08:00 [DBG] DESKTOP-1Q3GI6C [20] Successfully validated the token. +2025-07-27 15:52:27.165 +08:00 [DBG] DESKTOP-1Q3GI6C [20] AuthenticationScheme: Bearer was successfully authenticated. +2025-07-27 15:52:27.166 +08:00 [DBG] DESKTOP-1Q3GI6C [20] Authorization was successful. +2025-07-27 15:52:27.166 +08:00 [INF] DESKTOP-1Q3GI6C [20] 开始获取设备列表,页码: 1, 每页数量: 10, 搜索关键词: null +2025-07-27 15:52:27.168 +08:00 [INF] DESKTOP-1Q3GI6C [20] 开始获取设备列表,页码: 1, 每页数量: 10, 搜索关键词: null +2025-07-27 15:52:27.186 +08:00 [INF] DESKTOP-1Q3GI6C [10] Executed DbCommand (16ms) [Parameters=[], CommandType='"Text"', CommandTimeout='30'] +SELECT count(*)::int +FROM "CellularDevices" AS c +2025-07-27 15:52:27.207 +08:00 [INF] DESKTOP-1Q3GI6C [10] Executed DbCommand (18ms) [Parameters=[@__p_1='10', @__p_0='0'], CommandType='"Text"', CommandTimeout='30'] +SELECT t."Id", t."AgentPort", t."CreatedAt", t."CreatedBy", t."Description", t."IpAddress", t."IsDeleted", t."IsEnabled", t."IsRunning", t."Name", t."ProtocolVersionId", t."SerialNumber", t."UpdatedAt", t."UpdatedBy", p."Id", p."CreatedAt", p."CreatedBy", p."Description", p."IsDeleted", p."IsEnabled", p."MinimumSupportedVersion", p."Name", p."ReleaseDate", p."UpdatedAt", p."UpdatedBy", p."Version" +FROM ( + SELECT c."Id", c."AgentPort", c."CreatedAt", c."CreatedBy", c."Description", c."IpAddress", c."IsDeleted", c."IsEnabled", c."IsRunning", c."Name", c."ProtocolVersionId", c."SerialNumber", c."UpdatedAt", c."UpdatedBy" + FROM "CellularDevices" AS c + LIMIT @__p_1 OFFSET @__p_0 +) AS t +INNER JOIN "ProtocolVersions" AS p ON t."ProtocolVersionId" = p."Id" +2025-07-27 15:52:27.211 +08:00 [INF] DESKTOP-1Q3GI6C [10] 成功获取设备列表,共 3 条记录 +2025-07-27 15:52:27.212 +08:00 [INF] DESKTOP-1Q3GI6C [10] 成功获取设备列表,共 3 条记录 +2025-07-27 15:52:34.097 +08:00 [DBG] DESKTOP-1Q3GI6C [17] 获取所有连接,当前连接数:0 +2025-07-27 15:52:34.101 +08:00 [INF] DESKTOP-1Q3GI6C [17] 连接健康检查完成,检查连接数:0,清理连接数:0,检查时间:2025-07-27 07:52:34 +2025-07-27 15:52:53.265 +08:00 [DBG] DESKTOP-1Q3GI6C [20] Successfully validated the token. +2025-07-27 15:52:53.267 +08:00 [DBG] DESKTOP-1Q3GI6C [20] AuthenticationScheme: Bearer was successfully authenticated. +2025-07-27 15:52:53.269 +08:00 [DBG] DESKTOP-1Q3GI6C [20] Authorization was successful. +2025-07-27 15:52:53.271 +08:00 [INF] DESKTOP-1Q3GI6C [20] 开始获取协议版本列表,页码: 1, 每页数量: 10, 搜索关键词: null, 是否启用: null +2025-07-27 15:52:53.276 +08:00 [INF] DESKTOP-1Q3GI6C [20] 开始获取协议版本列表,页码: 1, 每页数量: 10, 搜索关键词: null, 是否启用: null +2025-07-27 15:52:53.297 +08:00 [INF] DESKTOP-1Q3GI6C [20] Executed DbCommand (19ms) [Parameters=[], CommandType='"Text"', CommandTimeout='30'] +SELECT p."Id", p."CreatedAt", p."CreatedBy", p."Description", p."IsDeleted", p."IsEnabled", p."MinimumSupportedVersion", p."Name", p."ReleaseDate", p."UpdatedAt", p."UpdatedBy", p."Version" +FROM "ProtocolVersions" AS p +2025-07-27 15:52:53.300 +08:00 [INF] DESKTOP-1Q3GI6C [20] 成功获取协议版本列表,共 3 条记录 +2025-07-27 15:52:53.301 +08:00 [INF] DESKTOP-1Q3GI6C [20] 成功获取协议版本列表,共 3 条记录 +2025-07-27 15:52:53.304 +08:00 [DBG] DESKTOP-1Q3GI6C [10] Successfully validated the token. +2025-07-27 15:52:53.305 +08:00 [DBG] DESKTOP-1Q3GI6C [10] AuthenticationScheme: Bearer was successfully authenticated. +2025-07-27 15:52:53.306 +08:00 [DBG] DESKTOP-1Q3GI6C [10] Authorization was successful. +2025-07-27 15:52:53.307 +08:00 [INF] DESKTOP-1Q3GI6C [10] 开始获取协议版本列表,页码: 1, 每页数量: 10, 搜索关键词: null, 是否启用: null +2025-07-27 15:52:53.310 +08:00 [INF] DESKTOP-1Q3GI6C [10] 开始获取协议版本列表,页码: 1, 每页数量: 10, 搜索关键词: null, 是否启用: null +2025-07-27 15:52:53.328 +08:00 [INF] DESKTOP-1Q3GI6C [16] Executed DbCommand (16ms) [Parameters=[], CommandType='"Text"', CommandTimeout='30'] +SELECT p."Id", p."CreatedAt", p."CreatedBy", p."Description", p."IsDeleted", p."IsEnabled", p."MinimumSupportedVersion", p."Name", p."ReleaseDate", p."UpdatedAt", p."UpdatedBy", p."Version" +FROM "ProtocolVersions" AS p +2025-07-27 15:52:53.331 +08:00 [INF] DESKTOP-1Q3GI6C [16] 成功获取协议版本列表,共 3 条记录 +2025-07-27 15:52:53.333 +08:00 [INF] DESKTOP-1Q3GI6C [16] 成功获取协议版本列表,共 3 条记录 +2025-07-27 15:53:03.947 +08:00 [DBG] DESKTOP-1Q3GI6C [21] 处理器健康检查通过,处理器:ChatMessageHandler +2025-07-27 15:53:03.963 +08:00 [DBG] DESKTOP-1Q3GI6C [21] 处理器健康检查通过,处理器:HeartbeatHandlerManager +2025-07-27 15:53:03.963 +08:00 [DBG] DESKTOP-1Q3GI6C [22] 处理器健康检查通过,处理器:ProtocolMessageHandler +2025-07-27 15:53:03.963 +08:00 [DBG] DESKTOP-1Q3GI6C [20] 处理器健康检查通过,处理器:NotificationMessageHandler +2025-07-27 15:53:04.106 +08:00 [DBG] DESKTOP-1Q3GI6C [20] 获取所有连接,当前连接数:0 +2025-07-27 15:53:04.112 +08:00 [INF] DESKTOP-1Q3GI6C [20] 连接健康检查完成,检查连接数:0,清理连接数:0,检查时间:2025-07-27 07:53:04 +2025-07-27 15:53:34.121 +08:00 [DBG] DESKTOP-1Q3GI6C [22] 获取所有连接,当前连接数:0 +2025-07-27 15:53:34.124 +08:00 [INF] DESKTOP-1Q3GI6C [22] 连接健康检查完成,检查连接数:0,清理连接数:0,检查时间:2025-07-27 07:53:34 +2025-07-27 15:54:03.946 +08:00 [DBG] DESKTOP-1Q3GI6C [21] 处理器健康检查通过,处理器:ChatMessageHandler +2025-07-27 15:54:03.967 +08:00 [DBG] DESKTOP-1Q3GI6C [21] 处理器健康检查通过,处理器:HeartbeatHandlerManager +2025-07-27 15:54:03.967 +08:00 [DBG] DESKTOP-1Q3GI6C [22] 处理器健康检查通过,处理器:NotificationMessageHandler +2025-07-27 15:54:03.967 +08:00 [DBG] DESKTOP-1Q3GI6C [20] 处理器健康检查通过,处理器:ProtocolMessageHandler +2025-07-27 15:54:04.126 +08:00 [DBG] DESKTOP-1Q3GI6C [20] 获取所有连接,当前连接数:0 +2025-07-27 15:54:04.128 +08:00 [INF] DESKTOP-1Q3GI6C [20] 连接健康检查完成,检查连接数:0,清理连接数:0,检查时间:2025-07-27 07:54:04 +2025-07-27 15:54:34.132 +08:00 [DBG] DESKTOP-1Q3GI6C [20] 获取所有连接,当前连接数:0 +2025-07-27 15:54:34.137 +08:00 [INF] DESKTOP-1Q3GI6C [20] 连接健康检查完成,检查连接数:0,清理连接数:0,检查时间:2025-07-27 07:54:34 +2025-07-27 15:55:03.947 +08:00 [DBG] DESKTOP-1Q3GI6C [21] 处理器健康检查通过,处理器:ChatMessageHandler +2025-07-27 15:55:03.964 +08:00 [DBG] DESKTOP-1Q3GI6C [20] 处理器健康检查通过,处理器:ProtocolMessageHandler +2025-07-27 15:55:03.963 +08:00 [DBG] DESKTOP-1Q3GI6C [3] 处理器健康检查通过,处理器:HeartbeatHandlerManager +2025-07-27 15:55:03.963 +08:00 [DBG] DESKTOP-1Q3GI6C [23] 处理器健康检查通过,处理器:NotificationMessageHandler +2025-07-27 15:55:04.141 +08:00 [DBG] DESKTOP-1Q3GI6C [20] 获取所有连接,当前连接数:0 +2025-07-27 15:55:04.144 +08:00 [INF] DESKTOP-1Q3GI6C [20] 连接健康检查完成,检查连接数:0,清理连接数:0,检查时间:2025-07-27 07:55:04 +2025-07-27 15:55:34.145 +08:00 [DBG] DESKTOP-1Q3GI6C [24] 获取所有连接,当前连接数:0 +2025-07-27 15:55:34.162 +08:00 [INF] DESKTOP-1Q3GI6C [24] 连接健康检查完成,检查连接数:0,清理连接数:0,检查时间:2025-07-27 07:55:34 +2025-07-27 15:56:03.955 +08:00 [DBG] DESKTOP-1Q3GI6C [23] 处理器健康检查通过,处理器:ChatMessageHandler +2025-07-27 15:56:03.955 +08:00 [DBG] DESKTOP-1Q3GI6C [3] 处理器健康检查通过,处理器:HeartbeatHandlerManager +2025-07-27 15:56:03.977 +08:00 [DBG] DESKTOP-1Q3GI6C [24] 处理器健康检查通过,处理器:NotificationMessageHandler +2025-07-27 15:56:03.978 +08:00 [DBG] DESKTOP-1Q3GI6C [25] 处理器健康检查通过,处理器:ProtocolMessageHandler +2025-07-27 15:56:04.192 +08:00 [DBG] DESKTOP-1Q3GI6C [24] 获取所有连接,当前连接数:0 +2025-07-27 15:56:04.199 +08:00 [INF] DESKTOP-1Q3GI6C [24] 连接健康检查完成,检查连接数:0,清理连接数:0,检查时间:2025-07-27 07:56:04 +2025-07-27 15:56:34.192 +08:00 [DBG] DESKTOP-1Q3GI6C [24] 获取所有连接,当前连接数:0 +2025-07-27 15:56:34.194 +08:00 [INF] DESKTOP-1Q3GI6C [24] 连接健康检查完成,检查连接数:0,清理连接数:0,检查时间:2025-07-27 07:56:34 +2025-07-27 15:57:03.947 +08:00 [DBG] DESKTOP-1Q3GI6C [25] 处理器健康检查通过,处理器:ChatMessageHandler +2025-07-27 15:57:03.964 +08:00 [DBG] DESKTOP-1Q3GI6C [25] 处理器健康检查通过,处理器:HeartbeatHandlerManager +2025-07-27 15:57:03.964 +08:00 [DBG] DESKTOP-1Q3GI6C [23] 处理器健康检查通过,处理器:ProtocolMessageHandler +2025-07-27 15:57:03.964 +08:00 [DBG] DESKTOP-1Q3GI6C [24] 处理器健康检查通过,处理器:NotificationMessageHandler +2025-07-27 15:57:04.206 +08:00 [DBG] DESKTOP-1Q3GI6C [23] 获取所有连接,当前连接数:0 +2025-07-27 15:57:04.222 +08:00 [INF] DESKTOP-1Q3GI6C [23] 连接健康检查完成,检查连接数:0,清理连接数:0,检查时间:2025-07-27 07:57:04 +2025-07-27 15:57:34.228 +08:00 [DBG] DESKTOP-1Q3GI6C [27] 获取所有连接,当前连接数:0 +2025-07-27 15:57:34.233 +08:00 [INF] DESKTOP-1Q3GI6C [27] 连接健康检查完成,检查连接数:0,清理连接数:0,检查时间:2025-07-27 07:57:34 +2025-07-27 15:58:03.959 +08:00 [DBG] DESKTOP-1Q3GI6C [25] 处理器健康检查通过,处理器:HeartbeatHandlerManager +2025-07-27 15:58:03.959 +08:00 [DBG] DESKTOP-1Q3GI6C [27] 处理器健康检查通过,处理器:ChatMessageHandler +2025-07-27 15:58:03.966 +08:00 [DBG] DESKTOP-1Q3GI6C [23] 处理器健康检查通过,处理器:NotificationMessageHandler +2025-07-27 15:58:03.966 +08:00 [DBG] DESKTOP-1Q3GI6C [25] 处理器健康检查通过,处理器:ProtocolMessageHandler +2025-07-27 15:58:04.249 +08:00 [DBG] DESKTOP-1Q3GI6C [25] 获取所有连接,当前连接数:0 +2025-07-27 15:58:04.250 +08:00 [INF] DESKTOP-1Q3GI6C [25] 连接健康检查完成,检查连接数:0,清理连接数:0,检查时间:2025-07-27 07:58:04 +2025-07-27 15:58:34.268 +08:00 [DBG] DESKTOP-1Q3GI6C [23] 获取所有连接,当前连接数:0 +2025-07-27 15:58:34.269 +08:00 [INF] DESKTOP-1Q3GI6C [23] 连接健康检查完成,检查连接数:0,清理连接数:0,检查时间:2025-07-27 07:58:34 +2025-07-27 15:59:03.945 +08:00 [DBG] DESKTOP-1Q3GI6C [27] 处理器健康检查通过,处理器:ChatMessageHandler +2025-07-27 15:59:03.964 +08:00 [DBG] DESKTOP-1Q3GI6C [27] 处理器健康检查通过,处理器:HeartbeatHandlerManager +2025-07-27 15:59:03.965 +08:00 [DBG] DESKTOP-1Q3GI6C [23] 处理器健康检查通过,处理器:ProtocolMessageHandler +2025-07-27 15:59:03.964 +08:00 [DBG] DESKTOP-1Q3GI6C [28] 处理器健康检查通过,处理器:NotificationMessageHandler +2025-07-27 15:59:04.281 +08:00 [DBG] DESKTOP-1Q3GI6C [28] 获取所有连接,当前连接数:0 +2025-07-27 15:59:04.284 +08:00 [INF] DESKTOP-1Q3GI6C [28] 连接健康检查完成,检查连接数:0,清理连接数:0,检查时间:2025-07-27 07:59:04 +2025-07-27 15:59:34.291 +08:00 [DBG] DESKTOP-1Q3GI6C [28] 获取所有连接,当前连接数:0 +2025-07-27 15:59:34.323 +08:00 [INF] DESKTOP-1Q3GI6C [28] 连接健康检查完成,检查连接数:0,清理连接数:0,检查时间:2025-07-27 07:59:34 +2025-07-27 16:00:03.947 +08:00 [DBG] DESKTOP-1Q3GI6C [27] 处理器健康检查通过,处理器:ChatMessageHandler +2025-07-27 16:00:03.963 +08:00 [DBG] DESKTOP-1Q3GI6C [23] 处理器健康检查通过,处理器:NotificationMessageHandler +2025-07-27 16:00:03.963 +08:00 [DBG] DESKTOP-1Q3GI6C [27] 处理器健康检查通过,处理器:HeartbeatHandlerManager +2025-07-27 16:00:03.963 +08:00 [DBG] DESKTOP-1Q3GI6C [28] 处理器健康检查通过,处理器:ProtocolMessageHandler +2025-07-27 16:00:04.363 +08:00 [DBG] DESKTOP-1Q3GI6C [28] 获取所有连接,当前连接数:0 +2025-07-27 16:00:04.364 +08:00 [INF] DESKTOP-1Q3GI6C [28] 连接健康检查完成,检查连接数:0,清理连接数:0,检查时间:2025-07-27 08:00:04 +2025-07-27 16:00:34.377 +08:00 [DBG] DESKTOP-1Q3GI6C [30] 获取所有连接,当前连接数:0 +2025-07-27 16:00:34.378 +08:00 [INF] DESKTOP-1Q3GI6C [30] 连接健康检查完成,检查连接数:0,清理连接数:0,检查时间:2025-07-27 08:00:34 +2025-07-27 16:01:03.945 +08:00 [DBG] DESKTOP-1Q3GI6C [27] 处理器健康检查通过,处理器:ChatMessageHandler +2025-07-27 16:01:03.960 +08:00 [DBG] DESKTOP-1Q3GI6C [27] 处理器健康检查通过,处理器:HeartbeatHandlerManager +2025-07-27 16:01:03.975 +08:00 [DBG] DESKTOP-1Q3GI6C [27] 处理器健康检查通过,处理器:NotificationMessageHandler +2025-07-27 16:01:03.975 +08:00 [DBG] DESKTOP-1Q3GI6C [28] 处理器健康检查通过,处理器:ProtocolMessageHandler +2025-07-27 16:01:04.396 +08:00 [DBG] DESKTOP-1Q3GI6C [27] 获取所有连接,当前连接数:0 +2025-07-27 16:01:04.401 +08:00 [INF] DESKTOP-1Q3GI6C [27] 连接健康检查完成,检查连接数:0,清理连接数:0,检查时间:2025-07-27 08:01:04 +2025-07-27 16:01:34.411 +08:00 [DBG] DESKTOP-1Q3GI6C [30] 获取所有连接,当前连接数:0 +2025-07-27 16:01:34.419 +08:00 [INF] DESKTOP-1Q3GI6C [30] 连接健康检查完成,检查连接数:0,清理连接数:0,检查时间:2025-07-27 08:01:34 +2025-07-27 16:02:03.946 +08:00 [DBG] DESKTOP-1Q3GI6C [30] 处理器健康检查通过,处理器:ChatMessageHandler +2025-07-27 16:02:03.962 +08:00 [DBG] DESKTOP-1Q3GI6C [31] 处理器健康检查通过,处理器:ProtocolMessageHandler +2025-07-27 16:02:03.962 +08:00 [DBG] DESKTOP-1Q3GI6C [32] 处理器健康检查通过,处理器:NotificationMessageHandler +2025-07-27 16:02:03.962 +08:00 [DBG] DESKTOP-1Q3GI6C [30] 处理器健康检查通过,处理器:HeartbeatHandlerManager +2025-07-27 16:02:04.438 +08:00 [DBG] DESKTOP-1Q3GI6C [30] 获取所有连接,当前连接数:0 +2025-07-27 16:02:04.440 +08:00 [INF] DESKTOP-1Q3GI6C [30] 连接健康检查完成,检查连接数:0,清理连接数:0,检查时间:2025-07-27 08:02:04 +2025-07-27 16:02:34.448 +08:00 [DBG] DESKTOP-1Q3GI6C [31] 获取所有连接,当前连接数:0 +2025-07-27 16:02:34.450 +08:00 [INF] DESKTOP-1Q3GI6C [31] 连接健康检查完成,检查连接数:0,清理连接数:0,检查时间:2025-07-27 08:02:34 +2025-07-27 16:03:03.955 +08:00 [DBG] DESKTOP-1Q3GI6C [32] 处理器健康检查通过,处理器:HeartbeatHandlerManager +2025-07-27 16:03:03.963 +08:00 [DBG] DESKTOP-1Q3GI6C [28] 处理器健康检查通过,处理器:NotificationMessageHandler +2025-07-27 16:03:03.955 +08:00 [DBG] DESKTOP-1Q3GI6C [31] 处理器健康检查通过,处理器:ChatMessageHandler +2025-07-27 16:03:03.963 +08:00 [DBG] DESKTOP-1Q3GI6C [33] 处理器健康检查通过,处理器:ProtocolMessageHandler +2025-07-27 16:03:04.455 +08:00 [DBG] DESKTOP-1Q3GI6C [28] 获取所有连接,当前连接数:0 +2025-07-27 16:03:04.457 +08:00 [INF] DESKTOP-1Q3GI6C [28] 连接健康检查完成,检查连接数:0,清理连接数:0,检查时间:2025-07-27 08:03:04 +2025-07-27 16:03:34.462 +08:00 [DBG] DESKTOP-1Q3GI6C [31] 获取所有连接,当前连接数:0 +2025-07-27 16:03:34.463 +08:00 [INF] DESKTOP-1Q3GI6C [31] 连接健康检查完成,检查连接数:0,清理连接数:0,检查时间:2025-07-27 08:03:34 +2025-07-27 16:03:58.900 +08:00 [DBG] DESKTOP-1Q3GI6C [36] Successfully validated the token. +2025-07-27 16:03:58.901 +08:00 [DBG] DESKTOP-1Q3GI6C [36] AuthenticationScheme: Bearer was successfully authenticated. +2025-07-27 16:03:58.902 +08:00 [DBG] DESKTOP-1Q3GI6C [36] Authorization was successful. +2025-07-27 16:03:58.903 +08:00 [INF] DESKTOP-1Q3GI6C [36] 开始获取协议版本列表,页码: 1, 每页数量: 10, 搜索关键词: null, 是否启用: null +2025-07-27 16:03:58.906 +08:00 [INF] DESKTOP-1Q3GI6C [36] 开始获取协议版本列表,页码: 1, 每页数量: 10, 搜索关键词: null, 是否启用: null +2025-07-27 16:03:58.979 +08:00 [INF] DESKTOP-1Q3GI6C [33] Executed DbCommand (11ms) [Parameters=[], CommandType='"Text"', CommandTimeout='30'] +SELECT p."Id", p."CreatedAt", p."CreatedBy", p."Description", p."IsDeleted", p."IsEnabled", p."MinimumSupportedVersion", p."Name", p."ReleaseDate", p."UpdatedAt", p."UpdatedBy", p."Version" +FROM "ProtocolVersions" AS p +2025-07-27 16:03:58.989 +08:00 [INF] DESKTOP-1Q3GI6C [33] 成功获取协议版本列表,共 0 条记录 +2025-07-27 16:03:58.992 +08:00 [INF] DESKTOP-1Q3GI6C [33] 成功获取协议版本列表,共 0 条记录 +2025-07-27 16:04:00.258 +08:00 [DBG] DESKTOP-1Q3GI6C [36] Successfully validated the token. +2025-07-27 16:04:00.260 +08:00 [DBG] DESKTOP-1Q3GI6C [36] AuthenticationScheme: Bearer was successfully authenticated. +2025-07-27 16:04:00.262 +08:00 [DBG] DESKTOP-1Q3GI6C [36] Authorization was successful. +2025-07-27 16:04:00.263 +08:00 [INF] DESKTOP-1Q3GI6C [36] 开始获取设备列表,页码: 1, 每页数量: 10, 搜索关键词: null +2025-07-27 16:04:00.264 +08:00 [INF] DESKTOP-1Q3GI6C [36] 开始获取设备列表,页码: 1, 每页数量: 10, 搜索关键词: null +2025-07-27 16:04:00.278 +08:00 [INF] DESKTOP-1Q3GI6C [36] Executed DbCommand (11ms) [Parameters=[], CommandType='"Text"', CommandTimeout='30'] +SELECT count(*)::int +FROM "CellularDevices" AS c +2025-07-27 16:04:00.293 +08:00 [INF] DESKTOP-1Q3GI6C [36] Executed DbCommand (12ms) [Parameters=[@__p_1='10', @__p_0='0'], CommandType='"Text"', CommandTimeout='30'] +SELECT t."Id", t."AgentPort", t."CreatedAt", t."CreatedBy", t."Description", t."IpAddress", t."IsDeleted", t."IsEnabled", t."IsRunning", t."Name", t."ProtocolVersionId", t."SerialNumber", t."UpdatedAt", t."UpdatedBy", p."Id", p."CreatedAt", p."CreatedBy", p."Description", p."IsDeleted", p."IsEnabled", p."MinimumSupportedVersion", p."Name", p."ReleaseDate", p."UpdatedAt", p."UpdatedBy", p."Version" +FROM ( + SELECT c."Id", c."AgentPort", c."CreatedAt", c."CreatedBy", c."Description", c."IpAddress", c."IsDeleted", c."IsEnabled", c."IsRunning", c."Name", c."ProtocolVersionId", c."SerialNumber", c."UpdatedAt", c."UpdatedBy" + FROM "CellularDevices" AS c + LIMIT @__p_1 OFFSET @__p_0 +) AS t +INNER JOIN "ProtocolVersions" AS p ON t."ProtocolVersionId" = p."Id" +2025-07-27 16:04:00.295 +08:00 [INF] DESKTOP-1Q3GI6C [36] 成功获取设备列表,共 0 条记录 +2025-07-27 16:04:00.296 +08:00 [INF] DESKTOP-1Q3GI6C [36] 成功获取设备列表,共 0 条记录 +2025-07-27 16:04:00.299 +08:00 [DBG] DESKTOP-1Q3GI6C [31] Successfully validated the token. +2025-07-27 16:04:00.300 +08:00 [DBG] DESKTOP-1Q3GI6C [31] AuthenticationScheme: Bearer was successfully authenticated. +2025-07-27 16:04:00.302 +08:00 [DBG] DESKTOP-1Q3GI6C [31] Authorization was successful. +2025-07-27 16:04:00.303 +08:00 [INF] DESKTOP-1Q3GI6C [31] 开始获取设备列表,页码: 1, 每页数量: 10, 搜索关键词: null +2025-07-27 16:04:00.304 +08:00 [INF] DESKTOP-1Q3GI6C [31] 开始获取设备列表,页码: 1, 每页数量: 10, 搜索关键词: null +2025-07-27 16:04:00.317 +08:00 [INF] DESKTOP-1Q3GI6C [33] Executed DbCommand (10ms) [Parameters=[], CommandType='"Text"', CommandTimeout='30'] +SELECT count(*)::int +FROM "CellularDevices" AS c +2025-07-27 16:04:00.332 +08:00 [INF] DESKTOP-1Q3GI6C [33] Executed DbCommand (12ms) [Parameters=[@__p_1='10', @__p_0='0'], CommandType='"Text"', CommandTimeout='30'] +SELECT t."Id", t."AgentPort", t."CreatedAt", t."CreatedBy", t."Description", t."IpAddress", t."IsDeleted", t."IsEnabled", t."IsRunning", t."Name", t."ProtocolVersionId", t."SerialNumber", t."UpdatedAt", t."UpdatedBy", p."Id", p."CreatedAt", p."CreatedBy", p."Description", p."IsDeleted", p."IsEnabled", p."MinimumSupportedVersion", p."Name", p."ReleaseDate", p."UpdatedAt", p."UpdatedBy", p."Version" +FROM ( + SELECT c."Id", c."AgentPort", c."CreatedAt", c."CreatedBy", c."Description", c."IpAddress", c."IsDeleted", c."IsEnabled", c."IsRunning", c."Name", c."ProtocolVersionId", c."SerialNumber", c."UpdatedAt", c."UpdatedBy" + FROM "CellularDevices" AS c + LIMIT @__p_1 OFFSET @__p_0 +) AS t +INNER JOIN "ProtocolVersions" AS p ON t."ProtocolVersionId" = p."Id" +2025-07-27 16:04:00.334 +08:00 [INF] DESKTOP-1Q3GI6C [33] 成功获取设备列表,共 0 条记录 +2025-07-27 16:04:00.335 +08:00 [INF] DESKTOP-1Q3GI6C [33] 成功获取设备列表,共 0 条记录 +2025-07-27 16:04:01.336 +08:00 [DBG] DESKTOP-1Q3GI6C [32] Successfully validated the token. +2025-07-27 16:04:01.337 +08:00 [DBG] DESKTOP-1Q3GI6C [32] AuthenticationScheme: Bearer was successfully authenticated. +2025-07-27 16:04:01.338 +08:00 [DBG] DESKTOP-1Q3GI6C [32] Authorization was successful. +2025-07-27 16:04:01.340 +08:00 [INF] DESKTOP-1Q3GI6C [32] 开始获取设备列表,页码: 1, 每页数量: 10, 搜索关键词: null +2025-07-27 16:04:01.342 +08:00 [INF] DESKTOP-1Q3GI6C [32] 开始获取设备列表,页码: 1, 每页数量: 10, 搜索关键词: null +2025-07-27 16:04:01.355 +08:00 [INF] DESKTOP-1Q3GI6C [33] Executed DbCommand (11ms) [Parameters=[], CommandType='"Text"', CommandTimeout='30'] +SELECT count(*)::int +FROM "CellularDevices" AS c +2025-07-27 16:04:01.369 +08:00 [INF] DESKTOP-1Q3GI6C [36] Executed DbCommand (11ms) [Parameters=[@__p_1='10', @__p_0='0'], CommandType='"Text"', CommandTimeout='30'] +SELECT t."Id", t."AgentPort", t."CreatedAt", t."CreatedBy", t."Description", t."IpAddress", t."IsDeleted", t."IsEnabled", t."IsRunning", t."Name", t."ProtocolVersionId", t."SerialNumber", t."UpdatedAt", t."UpdatedBy", p."Id", p."CreatedAt", p."CreatedBy", p."Description", p."IsDeleted", p."IsEnabled", p."MinimumSupportedVersion", p."Name", p."ReleaseDate", p."UpdatedAt", p."UpdatedBy", p."Version" +FROM ( + SELECT c."Id", c."AgentPort", c."CreatedAt", c."CreatedBy", c."Description", c."IpAddress", c."IsDeleted", c."IsEnabled", c."IsRunning", c."Name", c."ProtocolVersionId", c."SerialNumber", c."UpdatedAt", c."UpdatedBy" + FROM "CellularDevices" AS c + LIMIT @__p_1 OFFSET @__p_0 +) AS t +INNER JOIN "ProtocolVersions" AS p ON t."ProtocolVersionId" = p."Id" +2025-07-27 16:04:01.372 +08:00 [INF] DESKTOP-1Q3GI6C [36] 成功获取设备列表,共 0 条记录 +2025-07-27 16:04:01.374 +08:00 [INF] DESKTOP-1Q3GI6C [36] 成功获取设备列表,共 0 条记录 +2025-07-27 16:04:02.597 +08:00 [DBG] DESKTOP-1Q3GI6C [32] Successfully validated the token. +2025-07-27 16:04:02.598 +08:00 [DBG] DESKTOP-1Q3GI6C [32] AuthenticationScheme: Bearer was successfully authenticated. +2025-07-27 16:04:02.602 +08:00 [DBG] DESKTOP-1Q3GI6C [31] Successfully validated the token. +2025-07-27 16:04:02.603 +08:00 [DBG] DESKTOP-1Q3GI6C [31] AuthenticationScheme: Bearer was successfully authenticated. +2025-07-27 16:04:03.610 +08:00 [DBG] DESKTOP-1Q3GI6C [31] Successfully validated the token. +2025-07-27 16:04:03.611 +08:00 [DBG] DESKTOP-1Q3GI6C [31] AuthenticationScheme: Bearer was successfully authenticated. +2025-07-27 16:04:03.614 +08:00 [DBG] DESKTOP-1Q3GI6C [33] Successfully validated the token. +2025-07-27 16:04:03.615 +08:00 [DBG] DESKTOP-1Q3GI6C [33] AuthenticationScheme: Bearer was successfully authenticated. +2025-07-27 16:04:03.947 +08:00 [DBG] DESKTOP-1Q3GI6C [33] 处理器健康检查通过,处理器:ChatMessageHandler +2025-07-27 16:04:03.962 +08:00 [DBG] DESKTOP-1Q3GI6C [33] 处理器健康检查通过,处理器:HeartbeatHandlerManager +2025-07-27 16:04:03.962 +08:00 [DBG] DESKTOP-1Q3GI6C [36] 处理器健康检查通过,处理器:NotificationMessageHandler +2025-07-27 16:04:03.962 +08:00 [DBG] DESKTOP-1Q3GI6C [32] 处理器健康检查通过,处理器:ProtocolMessageHandler +2025-07-27 16:04:04.468 +08:00 [DBG] DESKTOP-1Q3GI6C [36] 获取所有连接,当前连接数:0 +2025-07-27 16:04:04.469 +08:00 [INF] DESKTOP-1Q3GI6C [36] 连接健康检查完成,检查连接数:0,清理连接数:0,检查时间:2025-07-27 08:04:04 +2025-07-27 16:04:04.617 +08:00 [DBG] DESKTOP-1Q3GI6C [36] Successfully validated the token. +2025-07-27 16:04:04.618 +08:00 [DBG] DESKTOP-1Q3GI6C [36] AuthenticationScheme: Bearer was successfully authenticated. +2025-07-27 16:04:04.622 +08:00 [DBG] DESKTOP-1Q3GI6C [36] Successfully validated the token. +2025-07-27 16:04:04.622 +08:00 [DBG] DESKTOP-1Q3GI6C [36] AuthenticationScheme: Bearer was successfully authenticated. +2025-07-27 16:04:05.626 +08:00 [DBG] DESKTOP-1Q3GI6C [36] Successfully validated the token. +2025-07-27 16:04:05.627 +08:00 [DBG] DESKTOP-1Q3GI6C [36] AuthenticationScheme: Bearer was successfully authenticated. +2025-07-27 16:04:05.630 +08:00 [DBG] DESKTOP-1Q3GI6C [33] Successfully validated the token. +2025-07-27 16:04:05.632 +08:00 [DBG] DESKTOP-1Q3GI6C [33] AuthenticationScheme: Bearer was successfully authenticated. +2025-07-27 16:04:07.738 +08:00 [DBG] DESKTOP-1Q3GI6C [37] Successfully validated the token. +2025-07-27 16:04:07.740 +08:00 [DBG] DESKTOP-1Q3GI6C [37] AuthenticationScheme: Bearer was successfully authenticated. +2025-07-27 16:04:07.741 +08:00 [DBG] DESKTOP-1Q3GI6C [37] Authorization was successful. +2025-07-27 16:04:07.743 +08:00 [INF] DESKTOP-1Q3GI6C [37] 开始获取设备列表,页码: 1, 每页数量: 10, 搜索关键词: null +2025-07-27 16:04:07.745 +08:00 [INF] DESKTOP-1Q3GI6C [37] 开始获取设备列表,页码: 1, 每页数量: 10, 搜索关键词: null +2025-07-27 16:04:07.758 +08:00 [INF] DESKTOP-1Q3GI6C [37] Executed DbCommand (11ms) [Parameters=[], CommandType='"Text"', CommandTimeout='30'] +SELECT count(*)::int +FROM "CellularDevices" AS c +2025-07-27 16:04:07.771 +08:00 [INF] DESKTOP-1Q3GI6C [33] Executed DbCommand (11ms) [Parameters=[@__p_1='10', @__p_0='0'], CommandType='"Text"', CommandTimeout='30'] +SELECT t."Id", t."AgentPort", t."CreatedAt", t."CreatedBy", t."Description", t."IpAddress", t."IsDeleted", t."IsEnabled", t."IsRunning", t."Name", t."ProtocolVersionId", t."SerialNumber", t."UpdatedAt", t."UpdatedBy", p."Id", p."CreatedAt", p."CreatedBy", p."Description", p."IsDeleted", p."IsEnabled", p."MinimumSupportedVersion", p."Name", p."ReleaseDate", p."UpdatedAt", p."UpdatedBy", p."Version" +FROM ( + SELECT c."Id", c."AgentPort", c."CreatedAt", c."CreatedBy", c."Description", c."IpAddress", c."IsDeleted", c."IsEnabled", c."IsRunning", c."Name", c."ProtocolVersionId", c."SerialNumber", c."UpdatedAt", c."UpdatedBy" + FROM "CellularDevices" AS c + LIMIT @__p_1 OFFSET @__p_0 +) AS t +INNER JOIN "ProtocolVersions" AS p ON t."ProtocolVersionId" = p."Id" +2025-07-27 16:04:07.774 +08:00 [INF] DESKTOP-1Q3GI6C [33] 成功获取设备列表,共 0 条记录 +2025-07-27 16:04:07.775 +08:00 [INF] DESKTOP-1Q3GI6C [33] 成功获取设备列表,共 0 条记录 +2025-07-27 16:04:07.778 +08:00 [DBG] DESKTOP-1Q3GI6C [36] Successfully validated the token. +2025-07-27 16:04:07.779 +08:00 [DBG] DESKTOP-1Q3GI6C [36] AuthenticationScheme: Bearer was successfully authenticated. +2025-07-27 16:04:07.780 +08:00 [DBG] DESKTOP-1Q3GI6C [36] Authorization was successful. +2025-07-27 16:04:07.781 +08:00 [INF] DESKTOP-1Q3GI6C [36] 开始获取设备列表,页码: 1, 每页数量: 10, 搜索关键词: null +2025-07-27 16:04:07.783 +08:00 [INF] DESKTOP-1Q3GI6C [36] 开始获取设备列表,页码: 1, 每页数量: 10, 搜索关键词: null +2025-07-27 16:04:07.796 +08:00 [INF] DESKTOP-1Q3GI6C [37] Executed DbCommand (11ms) [Parameters=[], CommandType='"Text"', CommandTimeout='30'] +SELECT count(*)::int +FROM "CellularDevices" AS c +2025-07-27 16:04:07.821 +08:00 [INF] DESKTOP-1Q3GI6C [37] Executed DbCommand (22ms) [Parameters=[@__p_1='10', @__p_0='0'], CommandType='"Text"', CommandTimeout='30'] +SELECT t."Id", t."AgentPort", t."CreatedAt", t."CreatedBy", t."Description", t."IpAddress", t."IsDeleted", t."IsEnabled", t."IsRunning", t."Name", t."ProtocolVersionId", t."SerialNumber", t."UpdatedAt", t."UpdatedBy", p."Id", p."CreatedAt", p."CreatedBy", p."Description", p."IsDeleted", p."IsEnabled", p."MinimumSupportedVersion", p."Name", p."ReleaseDate", p."UpdatedAt", p."UpdatedBy", p."Version" +FROM ( + SELECT c."Id", c."AgentPort", c."CreatedAt", c."CreatedBy", c."Description", c."IpAddress", c."IsDeleted", c."IsEnabled", c."IsRunning", c."Name", c."ProtocolVersionId", c."SerialNumber", c."UpdatedAt", c."UpdatedBy" + FROM "CellularDevices" AS c + LIMIT @__p_1 OFFSET @__p_0 +) AS t +INNER JOIN "ProtocolVersions" AS p ON t."ProtocolVersionId" = p."Id" +2025-07-27 16:04:07.824 +08:00 [INF] DESKTOP-1Q3GI6C [37] 成功获取设备列表,共 0 条记录 +2025-07-27 16:04:07.825 +08:00 [INF] DESKTOP-1Q3GI6C [37] 成功获取设备列表,共 0 条记录 +2025-07-27 16:04:34.481 +08:00 [DBG] DESKTOP-1Q3GI6C [31] 获取所有连接,当前连接数:0 +2025-07-27 16:04:34.483 +08:00 [INF] DESKTOP-1Q3GI6C [31] 连接健康检查完成,检查连接数:0,清理连接数:0,检查时间:2025-07-27 08:04:34 +2025-07-27 16:05:03.955 +08:00 [DBG] DESKTOP-1Q3GI6C [37] 处理器健康检查通过,处理器:ChatMessageHandler +2025-07-27 16:05:03.955 +08:00 [DBG] DESKTOP-1Q3GI6C [36] 处理器健康检查通过,处理器:HeartbeatHandlerManager +2025-07-27 16:05:03.970 +08:00 [DBG] DESKTOP-1Q3GI6C [36] 处理器健康检查通过,处理器:NotificationMessageHandler +2025-07-27 16:05:03.970 +08:00 [DBG] DESKTOP-1Q3GI6C [37] 处理器健康检查通过,处理器:ProtocolMessageHandler +2025-07-27 16:05:04.486 +08:00 [DBG] DESKTOP-1Q3GI6C [35] 获取所有连接,当前连接数:0 +2025-07-27 16:05:04.487 +08:00 [INF] DESKTOP-1Q3GI6C [35] 连接健康检查完成,检查连接数:0,清理连接数:0,检查时间:2025-07-27 08:05:04 +2025-07-27 16:05:34.502 +08:00 [DBG] DESKTOP-1Q3GI6C [37] 获取所有连接,当前连接数:0 +2025-07-27 16:05:34.505 +08:00 [INF] DESKTOP-1Q3GI6C [37] 连接健康检查完成,检查连接数:0,清理连接数:0,检查时间:2025-07-27 08:05:34 +2025-07-27 16:06:03.945 +08:00 [DBG] DESKTOP-1Q3GI6C [37] 处理器健康检查通过,处理器:ChatMessageHandler +2025-07-27 16:06:03.955 +08:00 [DBG] DESKTOP-1Q3GI6C [37] 处理器健康检查通过,处理器:HeartbeatHandlerManager +2025-07-27 16:06:03.963 +08:00 [DBG] DESKTOP-1Q3GI6C [35] 处理器健康检查通过,处理器:ProtocolMessageHandler +2025-07-27 16:06:03.963 +08:00 [DBG] DESKTOP-1Q3GI6C [37] 处理器健康检查通过,处理器:NotificationMessageHandler +2025-07-27 16:06:04.504 +08:00 [DBG] DESKTOP-1Q3GI6C [35] 获取所有连接,当前连接数:0 +2025-07-27 16:06:04.506 +08:00 [INF] DESKTOP-1Q3GI6C [35] 连接健康检查完成,检查连接数:0,清理连接数:0,检查时间:2025-07-27 08:06:04 +2025-07-27 16:06:34.515 +08:00 [DBG] DESKTOP-1Q3GI6C [31] 获取所有连接,当前连接数:0 +2025-07-27 16:06:34.517 +08:00 [INF] DESKTOP-1Q3GI6C [31] 连接健康检查完成,检查连接数:0,清理连接数:0,检查时间:2025-07-27 08:06:34 +2025-07-27 16:07:03.958 +08:00 [DBG] DESKTOP-1Q3GI6C [31] 处理器健康检查通过,处理器:HeartbeatHandlerManager +2025-07-27 16:07:03.958 +08:00 [DBG] DESKTOP-1Q3GI6C [40] 处理器健康检查通过,处理器:ChatMessageHandler +2025-07-27 16:07:03.974 +08:00 [DBG] DESKTOP-1Q3GI6C [40] 处理器健康检查通过,处理器:NotificationMessageHandler +2025-07-27 16:07:03.974 +08:00 [DBG] DESKTOP-1Q3GI6C [38] 处理器健康检查通过,处理器:ProtocolMessageHandler +2025-07-27 16:07:04.522 +08:00 [DBG] DESKTOP-1Q3GI6C [40] 获取所有连接,当前连接数:0 +2025-07-27 16:07:04.524 +08:00 [INF] DESKTOP-1Q3GI6C [40] 连接健康检查完成,检查连接数:0,清理连接数:0,检查时间:2025-07-27 08:07:04 +2025-07-27 16:07:34.533 +08:00 [DBG] DESKTOP-1Q3GI6C [31] 获取所有连接,当前连接数:0 +2025-07-27 16:07:34.536 +08:00 [INF] DESKTOP-1Q3GI6C [31] 连接健康检查完成,检查连接数:0,清理连接数:0,检查时间:2025-07-27 08:07:34 diff --git a/src/X1.WebAPI/logs/error-20250727.log b/src/X1.WebAPI/logs/error-20250727.log new file mode 100644 index 0000000..065ec98 --- /dev/null +++ b/src/X1.WebAPI/logs/error-20250727.log @@ -0,0 +1,20 @@ +2025-07-27 15:51:31.156 +08:00 [ERR] DESKTOP-1Q3GI6C [19] 令牌已过期: IDX10223: Lifetime validation failed. The token is expired. ValidTo (UTC): '07/16/2025 13:48:11', Current time (UTC): '07/27/2025 07:51:31'. +Microsoft.IdentityModel.Tokens.SecurityTokenExpiredException: IDX10223: Lifetime validation failed. The token is expired. ValidTo (UTC): '07/16/2025 13:48:11', Current time (UTC): '07/27/2025 07:51:31'. + at Microsoft.IdentityModel.Tokens.Validators.ValidateLifetime(Nullable`1 notBefore, Nullable`1 expires, SecurityToken securityToken, TokenValidationParameters validationParameters) + at System.IdentityModel.Tokens.Jwt.JwtSecurityTokenHandler.ValidateLifetime(Nullable`1 notBefore, Nullable`1 expires, JwtSecurityToken jwtToken, TokenValidationParameters validationParameters) + at System.IdentityModel.Tokens.Jwt.JwtSecurityTokenHandler.ValidateTokenPayload(JwtSecurityToken jwtToken, TokenValidationParameters validationParameters, BaseConfiguration configuration) + at System.IdentityModel.Tokens.Jwt.JwtSecurityTokenHandler.ValidateJWS(String token, TokenValidationParameters validationParameters, BaseConfiguration currentConfiguration, SecurityToken& signatureValidatedToken, ExceptionDispatchInfo& exceptionThrown) +--- End of stack trace from previous location --- + at System.IdentityModel.Tokens.Jwt.JwtSecurityTokenHandler.ValidateToken(String token, JwtSecurityToken outerToken, TokenValidationParameters validationParameters, SecurityToken& signatureValidatedToken) + at System.IdentityModel.Tokens.Jwt.JwtSecurityTokenHandler.ValidateToken(String token, TokenValidationParameters validationParameters, SecurityToken& validatedToken) + at CellularManagement.Infrastructure.Services.Authentication.JwtProvider.ValidateToken(String token) in D:\HistoryCode\CellularManagementAPI\CellularManagement\src\X1.Infrastructure\Services\Authentication\JwtProvider.cs:line 151 +2025-07-27 15:51:31.156 +08:00 [ERR] DESKTOP-1Q3GI6C [21] 令牌已过期: IDX10223: Lifetime validation failed. The token is expired. ValidTo (UTC): '07/16/2025 13:48:11', Current time (UTC): '07/27/2025 07:51:31'. +Microsoft.IdentityModel.Tokens.SecurityTokenExpiredException: IDX10223: Lifetime validation failed. The token is expired. ValidTo (UTC): '07/16/2025 13:48:11', Current time (UTC): '07/27/2025 07:51:31'. + at Microsoft.IdentityModel.Tokens.Validators.ValidateLifetime(Nullable`1 notBefore, Nullable`1 expires, SecurityToken securityToken, TokenValidationParameters validationParameters) + at System.IdentityModel.Tokens.Jwt.JwtSecurityTokenHandler.ValidateLifetime(Nullable`1 notBefore, Nullable`1 expires, JwtSecurityToken jwtToken, TokenValidationParameters validationParameters) + at System.IdentityModel.Tokens.Jwt.JwtSecurityTokenHandler.ValidateTokenPayload(JwtSecurityToken jwtToken, TokenValidationParameters validationParameters, BaseConfiguration configuration) + at System.IdentityModel.Tokens.Jwt.JwtSecurityTokenHandler.ValidateJWS(String token, TokenValidationParameters validationParameters, BaseConfiguration currentConfiguration, SecurityToken& signatureValidatedToken, ExceptionDispatchInfo& exceptionThrown) +--- End of stack trace from previous location --- + at System.IdentityModel.Tokens.Jwt.JwtSecurityTokenHandler.ValidateToken(String token, JwtSecurityToken outerToken, TokenValidationParameters validationParameters, SecurityToken& signatureValidatedToken) + at System.IdentityModel.Tokens.Jwt.JwtSecurityTokenHandler.ValidateToken(String token, TokenValidationParameters validationParameters, SecurityToken& validatedToken) + at CellularManagement.Infrastructure.Services.Authentication.JwtProvider.ValidateToken(String token) in D:\HistoryCode\CellularManagementAPI\CellularManagement\src\X1.Infrastructure\Services\Authentication\JwtProvider.cs:line 151