Browse Source

test GetNetworkStackConfigsByCodesAsync 问题

feature/x1-web-request
hyh 4 days ago
parent
commit
ad63fb315e
  1. 212
      src/X1.Application/Features/DeviceRuntimes/Commands/StartDeviceRuntime/StartDeviceRuntimeCommandHandler.cs
  2. 4
      src/X1.Domain/Repositories/NetworkProfile/INetworkStackConfigRepository.cs
  3. 48
      src/X1.Infrastructure/Repositories/NetworkProfile/NetworkStackConfigRepository.cs
  4. 24
      src/modify.md

212
src/X1.Application/Features/DeviceRuntimes/Commands/StartDeviceRuntime/StartDeviceRuntimeCommandHandler.cs

@ -6,6 +6,8 @@ using CellularManagement.Domain.Repositories.Device;
using CellularManagement.Domain.Repositories.Base;
using CellularManagement.Domain.Services;
using X1.DynamicClientCore.Features;
using CellularManagement.Domain.Repositories.NetworkProfile;
using X1.DynamicClientCore.Models;
namespace CellularManagement.Application.Features.DeviceRuntimes.Commands.StartDeviceRuntime;
@ -20,11 +22,13 @@ public class StartDeviceRuntimeCommandHandler : IRequestHandler<StartDeviceRunti
private readonly IUnitOfWork _unitOfWork;
private readonly ICurrentUserService _currentUserService;
private readonly IInstrumentProtocolClient _protocolClient;
private readonly INetworkStackConfigRepository _networkStackConfigRepository;
/// <summary>
/// 初始化命令处理器
/// </summary>
public StartDeviceRuntimeCommandHandler(
INetworkStackConfigRepository networkStackConfigRepository,
ICellularDeviceRuntimeRepository deviceRuntimeRepository,
ICellularDeviceRepository deviceRepository,
ILogger<StartDeviceRuntimeCommandHandler> logger,
@ -38,6 +42,7 @@ public class StartDeviceRuntimeCommandHandler : IRequestHandler<StartDeviceRunti
_unitOfWork = unitOfWork;
_currentUserService = currentUserService;
_protocolClient= protocolClient;
_networkStackConfigRepository = networkStackConfigRepository;
}
/// <summary>
@ -64,103 +69,116 @@ public class StartDeviceRuntimeCommandHandler : IRequestHandler<StartDeviceRunti
return OperationResult<StartDeviceRuntimeResponse>.CreateFailure("用户未登录");
}
var deviceResults = new List<DeviceStartResult>();
var successCount = 0;
var failureCount = 0;
// 批量处理设备启动
foreach (var deviceRequest in request.DeviceRequests)
{
try
{
_logger.LogInformation("开始启动设备,设备编号: {DeviceCode}, 网络栈配置编号: {NetworkStackCode}",
deviceRequest.DeviceCode, deviceRequest.NetworkStackCode);
// 获取设备运行时状态
var deviceRuntime = await _deviceRuntimeRepository.GetRuntimeByDeviceCodeAsync(deviceRequest.DeviceCode, cancellationToken);
if (deviceRuntime == null)
{
_logger.LogWarning("设备运行时状态不存在,设备编号: {DeviceCode}", deviceRequest.DeviceCode);
deviceResults.Add(new DeviceStartResult
{
DeviceCode = deviceRequest.DeviceCode,
IsSuccess = false,
ErrorMessage = $"设备编号 {deviceRequest.DeviceCode} 的运行时状态不存在"
});
failureCount++;
continue;
}
// 检查设备是否已经在运行
if (deviceRuntime.RuntimeStatus == DeviceRuntimeStatus.Running)
{
_logger.LogWarning("设备已经在运行中,设备编号: {DeviceCode}", deviceRequest.DeviceCode);
deviceResults.Add(new DeviceStartResult
{
DeviceCode = deviceRequest.DeviceCode,
IsSuccess = false,
ErrorMessage = $"设备编号 {deviceRequest.DeviceCode} 已经在运行中"
});
failureCount++;
continue;
}
// 生成运行编码
var runtimeCode = await GenerateRuntimeCodeAsync(deviceRequest.DeviceCode, cancellationToken);
// 启动设备
deviceRuntime.Start(deviceRequest.NetworkStackCode, runtimeCode);
// 更新到数据库
_deviceRuntimeRepository.UpdateRuntime(deviceRuntime);
_logger.LogInformation("设备启动成功,设备编号: {DeviceCode}, 运行编码: {RuntimeCode}",
deviceRuntime.DeviceCode, deviceRuntime.RuntimeCode);
// 添加到结果列表
deviceResults.Add(new DeviceStartResult
{
DeviceCode = deviceRuntime.DeviceCode,
Id = deviceRuntime.Id,
RuntimeStatus = deviceRuntime.RuntimeStatus.ToString(),
NetworkStackCode = deviceRuntime.NetworkStackCode,
UpdatedAt = deviceRuntime.UpdatedAt ?? DateTime.UtcNow,
IsSuccess = true
});
successCount++;
}
catch (Exception ex)
{
_logger.LogError(ex, "启动设备失败,设备编号: {DeviceCode}", deviceRequest.DeviceCode);
deviceResults.Add(new DeviceStartResult
{
DeviceCode = deviceRequest.DeviceCode,
IsSuccess = false,
ErrorMessage = $"启动设备失败: {ex.Message}"
});
failureCount++;
}
}
// 保存所有更改
await _unitOfWork.SaveChangesAsync(cancellationToken);
// 构建响应
var response = new StartDeviceRuntimeResponse
{
DeviceResults = deviceResults,
Summary = new BatchOperationSummary
{
TotalCount = request.DeviceRequests.Count,
SuccessCount = successCount,
FailureCount = failureCount
}
};
_logger.LogInformation("批量启动设备完成,总数量: {TotalCount}, 成功: {SuccessCount}, 失败: {FailureCount}",
response.Summary.TotalCount, response.Summary.SuccessCount, response.Summary.FailureCount);
return OperationResult<StartDeviceRuntimeResponse>.CreateSuccess(response);
var res = await _networkStackConfigRepository.GetNetworkStackConfigsByCodesAsync(request.DeviceRequests.Select(s => s.NetworkStackCode).ToArray(), cancellationToken);
//List<CellularNetworkConfiguration> Requests = new List<CellularNetworkConfiguration>();
//foreach (var item in res)
//{
// Requests.Add(new CellularNetworkConfiguration
// {
// DeviceCode= item.NetworkStackCode,
// RadioAccessNetworkConfiguration =item.RanName
// });
//}
//var deviceResults = new List<DeviceStartResult>();
//var successCount = 0;
//var failureCount = 0;
//// 批量处理设备启动
//foreach (var deviceRequest in request.DeviceRequests)
//{
// try
// {
// _logger.LogInformation("开始启动设备,设备编号: {DeviceCode}, 网络栈配置编号: {NetworkStackCode}",
// deviceRequest.DeviceCode, deviceRequest.NetworkStackCode);
// // 获取设备运行时状态
// var deviceRuntime = await _deviceRuntimeRepository.GetRuntimeByDeviceCodeAsync(deviceRequest.DeviceCode, cancellationToken);
// if (deviceRuntime == null)
// {
// _logger.LogWarning("设备运行时状态不存在,设备编号: {DeviceCode}", deviceRequest.DeviceCode);
// deviceResults.Add(new DeviceStartResult
// {
// DeviceCode = deviceRequest.DeviceCode,
// IsSuccess = false,
// ErrorMessage = $"设备编号 {deviceRequest.DeviceCode} 的运行时状态不存在"
// });
// failureCount++;
// continue;
// }
// // 检查设备是否已经在运行
// if (deviceRuntime.RuntimeStatus == DeviceRuntimeStatus.Running)
// {
// _logger.LogWarning("设备已经在运行中,设备编号: {DeviceCode}", deviceRequest.DeviceCode);
// deviceResults.Add(new DeviceStartResult
// {
// DeviceCode = deviceRequest.DeviceCode,
// IsSuccess = false,
// ErrorMessage = $"设备编号 {deviceRequest.DeviceCode} 已经在运行中"
// });
// failureCount++;
// continue;
// }
// // 生成运行编码
// var runtimeCode = await GenerateRuntimeCodeAsync(deviceRequest.DeviceCode, cancellationToken);
// // 启动设备
// deviceRuntime.Start(deviceRequest.NetworkStackCode, runtimeCode);
// // 更新到数据库
// _deviceRuntimeRepository.UpdateRuntime(deviceRuntime);
// _logger.LogInformation("设备启动成功,设备编号: {DeviceCode}, 运行编码: {RuntimeCode}",
// deviceRuntime.DeviceCode, deviceRuntime.RuntimeCode);
// // 添加到结果列表
// deviceResults.Add(new DeviceStartResult
// {
// DeviceCode = deviceRuntime.DeviceCode,
// Id = deviceRuntime.Id,
// RuntimeStatus = deviceRuntime.RuntimeStatus.ToString(),
// NetworkStackCode = deviceRuntime.NetworkStackCode,
// UpdatedAt = deviceRuntime.UpdatedAt ?? DateTime.UtcNow,
// IsSuccess = true
// });
// successCount++;
// }
// catch (Exception ex)
// {
// _logger.LogError(ex, "启动设备失败,设备编号: {DeviceCode}", deviceRequest.DeviceCode);
// deviceResults.Add(new DeviceStartResult
// {
// DeviceCode = deviceRequest.DeviceCode,
// IsSuccess = false,
// ErrorMessage = $"启动设备失败: {ex.Message}"
// });
// failureCount++;
// }
//}
//// 保存所有更改
//await _unitOfWork.SaveChangesAsync(cancellationToken);
//// 构建响应
//var response = new StartDeviceRuntimeResponse
//{
// DeviceResults = deviceResults,
// Summary = new BatchOperationSummary
// {
// TotalCount = request.DeviceRequests.Count,
// SuccessCount = successCount,
// FailureCount = failureCount
// }
//};
//_logger.LogInformation("批量启动设备完成,总数量: {TotalCount}, 成功: {SuccessCount}, 失败: {FailureCount}",
// response.Summary.TotalCount, response.Summary.SuccessCount, response.Summary.FailureCount);
return OperationResult<StartDeviceRuntimeResponse>.CreateSuccess(null);
}
catch (Exception ex)
{

4
src/X1.Domain/Repositories/NetworkProfile/INetworkStackConfigRepository.cs

@ -85,6 +85,10 @@ public interface INetworkStackConfigRepository : IBaseRepository<NetworkStackCon
/// 根据ID获取网络栈配置(包含绑定关系和关联配置名称)
/// </summary>
Task<IList<NetworkStackConfigWithBindingNamesDto>> GetNetworkStackConfigByIdWithBindingNamesAsync(string id, CancellationToken cancellationToken = default);
/// <summary>
/// 根据编码数组获取网络栈配置(包含绑定关系和关联配置名称)
/// </summary>
Task<IList<NetworkStackConfigWithBindingNamesDto>> GetNetworkStackConfigsByCodesAsync(string[] networkStackCodes, CancellationToken cancellationToken = default);
/// <summary>
/// 搜索网络栈配置(包含绑定关系和关联配置名称,分页)

48
src/X1.Infrastructure/Repositories/NetworkProfile/NetworkStackConfigRepository.cs

@ -301,6 +301,54 @@ public class NetworkStackConfigRepository : BaseRepository<NetworkStackConfig>,
return results.ToList();
}
public async Task<IList<NetworkStackConfigWithBindingNamesDto>> GetNetworkStackConfigsByCodesAsync(string[] networkStackCodes, CancellationToken cancellationToken = default)
{
if (networkStackCodes == null || !networkStackCodes.Any())
{
return new List<NetworkStackConfigWithBindingNamesDto>();
}
// 构建IN查询的参数占位符
var paramPlaceholders = string.Join(",", networkStackCodes.Select((_, index) => $"@p{index}"));
// 使用原生SQL查询来一次性获取所有需要的数据 - PostgreSQL语法
var sql = $@"
SELECT
nsc.""Id"" AS ""NetworkStackConfigId"",
nsc.""NetworkStackName"",
nsc.""NetworkStackCode"",
nsc.""RanId"",
ran.""Name"" AS ""RanName"",
ran.""ConfigContent"" AS ""RanConfigContent"",
ran.""ConfigContent"" AS ""RanConfigContent"",
ran.""ConfigContent"" AS ""RanConfigContent"",
nsc.""Description"",
nsc.""IsActive"",
nsc.""CreatedAt"",
nsc.""UpdatedAt"",
nsc.""CreatedBy"",
nsc.""UpdatedBy"",
binding.""Id"" AS ""StackCoreIMSBindingId"",
binding.""Index"",
binding.""CnId"" AS ""CoreNetworkConfigId"",
cnc.""Name"" AS ""CoreNetworkConfigName"",
binding.""ImsId"" AS ""IMSConfigId"",
ims.""Name"" AS ""IMSConfigName""
FROM ""NetworkStackConfigs"" nsc
LEFT JOIN ""RAN_Configurations"" ran ON nsc.""RanId"" = ran.""Id""
LEFT JOIN ""Stack_CoreIMS_Bindings"" binding ON nsc.""Id"" = binding.""NetworkStackConfigId""
LEFT JOIN ""CoreNetworkConfigs"" cnc ON binding.""CnId"" = cnc.""Id""
LEFT JOIN ""IMS_Configurations"" ims ON binding.""ImsId"" = ims.""Id""
WHERE nsc.""NetworkStackCode"" IN ({paramPlaceholders})
ORDER BY nsc.""NetworkStackCode"", binding.""Index""";
var parameters = networkStackCodes.Cast<object>().ToArray();
// 执行查询
var results = await ExecuteSqlQueryAsync<NetworkStackConfigWithBindingNamesDto>(sql, parameters, cancellationToken);
return results.ToList();
}
/// <summary>
/// 搜索网络栈配置(包含绑定关系和关联配置名称,分页)
/// </summary>

24
src/modify.md

@ -3985,6 +3985,30 @@ chore: 更新.gitignore忽略日志文件
- 网络连接必须正常才能获取序列号
- 如果获取失败,会返回相应的错误信息
## 2025-01-29 网络栈配置仓储方法重构
**修改时间**: 2025年1月29日
**修改文件**:
- `X1.Domain/Repositories/NetworkProfile/INetworkStackConfigRepository.cs`
- `X1.Infrastructure/Repositories/NetworkProfile/NetworkStackConfigRepository.cs`
**修改内容**:
1. 重命名方法 `GetNetworkStackConfigByNetworkStackCodeWithBindingNamesAsync``GetNetworkStackConfigsByCodesAsync`
2. 修改参数类型从 `string NetworkStackCode` 改为 `string[] networkStackCodes`
3. 更新方法实现以支持多个网络栈编码的查询
4. 添加空数组检查逻辑
5. 使用动态构建的IN查询替代单一条件查询
6. 优化排序逻辑,按网络栈编码和绑定索引排序
**修改原因**:
- 原方法名称过长,不符合命名规范
- 支持批量查询多个网络栈编码,提高查询效率
- 改善代码可读性和维护性
**影响范围**:
- 需要更新所有调用此方法的代码
- 接口签名变更,需要重新编译相关项目
## 2025-07-28 - 修复endpointManager重新添加时机bug
### 修改原因

Loading…
Cancel
Save