diff --git a/src/X1.Application/Features/TestCases/Commands/CreateTestCase/CreateTestCaseCommand.cs b/src/X1.Application/Features/TestCases/Commands/CreateTestCase/CreateTestCaseCommand.cs
new file mode 100644
index 0000000..858e3ab
--- /dev/null
+++ b/src/X1.Application/Features/TestCases/Commands/CreateTestCase/CreateTestCaseCommand.cs
@@ -0,0 +1,91 @@
+using CellularManagement.Domain.Common;
+using MediatR;
+using System.ComponentModel.DataAnnotations;
+
+namespace CellularManagement.Application.Features.TestCases.Commands.CreateTestCase;
+
+///
+/// 创建用例命令
+///
+public class CreateTestCaseCommand : IRequest>
+{
+ ///
+ /// 用例编码
+ ///
+ [Required(ErrorMessage = "用例编码不能为空")]
+ [MaxLength(50, ErrorMessage = "用例编码长度不能超过50个字符")]
+ public string Code { get; set; } = null!;
+
+ ///
+ /// 用例名称
+ ///
+ [Required(ErrorMessage = "用例名称不能为空")]
+ [MaxLength(100, ErrorMessage = "用例名称长度不能超过100个字符")]
+ public string Name { get; set; } = null!;
+
+ ///
+ /// 用户数
+ ///
+ [Range(0, int.MaxValue, ErrorMessage = "用户数必须大于等于0")]
+ public int UserCount { get; set; } = 0;
+
+ ///
+ /// 用户信息列表(JSON格式)
+ ///
+ [MaxLength(4000, ErrorMessage = "用户信息列表长度不能超过4000个字符")]
+ public string? UserInfoList { get; set; }
+
+ ///
+ /// 时延阈值数
+ ///
+ [Range(0, int.MaxValue, ErrorMessage = "时延阈值数必须大于等于0")]
+ public int LatencyThresholdCount { get; set; } = 0;
+
+ ///
+ /// 时延阈值列表(JSON格式)
+ ///
+ [MaxLength(2000, ErrorMessage = "时延阈值列表长度不能超过2000个字符")]
+ public string? LatencyThresholdList { get; set; }
+
+ ///
+ /// 吞吐量阈值数
+ ///
+ [Range(0, int.MaxValue, ErrorMessage = "吞吐量阈值数必须大于等于0")]
+ public int ThroughputThresholdCount { get; set; } = 0;
+
+ ///
+ /// 吞吐量阈值列表(JSON格式)
+ ///
+ [MaxLength(2000, ErrorMessage = "吞吐量阈值列表长度不能超过2000个字符")]
+ public string? ThroughputThresholdList { get; set; }
+
+ ///
+ /// 用例说明
+ ///
+ [MaxLength(1000, ErrorMessage = "用例说明长度不能超过1000个字符")]
+ public string? Description { get; set; }
+
+ ///
+ /// 用例版本
+ ///
+ [Required(ErrorMessage = "用例版本不能为空")]
+ [MaxLength(20, ErrorMessage = "用例版本长度不能超过20个字符")]
+ public string Version { get; set; } = null!;
+
+ ///
+ /// 版本更新信息
+ ///
+ [MaxLength(500, ErrorMessage = "版本更新信息长度不能超过500个字符")]
+ public string? VersionUpdateInfo { get; set; }
+
+ ///
+ /// 是否禁用
+ ///
+ public bool IsDisabled { get; set; } = false;
+
+ ///
+ /// 备注
+ ///
+ [MaxLength(1000, ErrorMessage = "备注长度不能超过1000个字符")]
+ public string? Remarks { get; set; }
+}
\ No newline at end of file
diff --git a/src/X1.Application/Features/TestCases/Commands/CreateTestCase/CreateTestCaseCommandHandler.cs b/src/X1.Application/Features/TestCases/Commands/CreateTestCase/CreateTestCaseCommandHandler.cs
new file mode 100644
index 0000000..4774956
--- /dev/null
+++ b/src/X1.Application/Features/TestCases/Commands/CreateTestCase/CreateTestCaseCommandHandler.cs
@@ -0,0 +1,123 @@
+using MediatR;
+using Microsoft.Extensions.Logging;
+using CellularManagement.Domain.Common;
+using CellularManagement.Domain.Entities.Device;
+using CellularManagement.Domain.Repositories.Device;
+using CellularManagement.Domain.Repositories.Base;
+using CellularManagement.Domain.Services;
+
+namespace CellularManagement.Application.Features.TestCases.Commands.CreateTestCase;
+
+///
+/// 创建用例命令处理器
+///
+public class CreateTestCaseCommandHandler : IRequestHandler>
+{
+ private readonly ITestCaseRepository _testCaseRepository;
+ private readonly ILogger _logger;
+ private readonly IUnitOfWork _unitOfWork;
+ private readonly ICurrentUserService _currentUserService;
+
+ ///
+ /// 初始化命令处理器
+ ///
+ public CreateTestCaseCommandHandler(
+ ITestCaseRepository testCaseRepository,
+ ILogger logger,
+ IUnitOfWork unitOfWork,
+ ICurrentUserService currentUserService)
+ {
+ _testCaseRepository = testCaseRepository;
+ _logger = logger;
+ _unitOfWork = unitOfWork;
+ _currentUserService = currentUserService;
+ }
+
+ ///
+ /// 处理创建用例命令
+ ///
+ public async Task> Handle(CreateTestCaseCommand request, CancellationToken cancellationToken)
+ {
+ try
+ {
+ _logger.LogInformation("开始创建用例,用例编码: {Code}, 用例名称: {Name}, 版本: {Version}",
+ request.Code, request.Name, request.Version);
+
+ // 检查用例编码是否已存在
+ if (await _testCaseRepository.CodeExistsAsync(request.Code, cancellationToken))
+ {
+ _logger.LogWarning("用例编码已存在: {Code}", request.Code);
+ return OperationResult.CreateFailure($"用例编码 {request.Code} 已存在");
+ }
+
+ // 检查用例版本是否已存在
+ if (await _testCaseRepository.VersionExistsAsync(request.Version, cancellationToken))
+ {
+ _logger.LogWarning("用例版本已存在: {Version}", request.Version);
+ return OperationResult.CreateFailure($"用例版本 {request.Version} 已存在");
+ }
+
+ // 获取当前用户ID
+ var currentUserId = _currentUserService.GetCurrentUserId();
+ if (string.IsNullOrEmpty(currentUserId))
+ {
+ _logger.LogError("无法获取当前用户ID,用户可能未认证");
+ return OperationResult.CreateFailure("用户未认证,无法创建用例");
+ }
+
+ // 创建用例实体
+ var testCase = TestCase.Create(
+ code: request.Code,
+ name: request.Name,
+ version: request.Version,
+ createdBy: currentUserId,
+ userCount: request.UserCount,
+ userInfoList: request.UserInfoList,
+ latencyThresholdCount: request.LatencyThresholdCount,
+ latencyThresholdList: request.LatencyThresholdList,
+ throughputThresholdCount: request.ThroughputThresholdCount,
+ throughputThresholdList: request.ThroughputThresholdList,
+ description: request.Description,
+ versionUpdateInfo: request.VersionUpdateInfo,
+ isDisabled: request.IsDisabled,
+ remarks: request.Remarks);
+
+ // 保存用例
+ await _testCaseRepository.AddTestCaseAsync(testCase, cancellationToken);
+
+ // 保存更改到数据库
+ await _unitOfWork.SaveChangesAsync(cancellationToken);
+
+ // 构建响应
+ var response = new CreateTestCaseResponse
+ {
+ TestCaseId = testCase.Id,
+ Code = testCase.Code,
+ Name = testCase.Name,
+ UserCount = testCase.UserCount,
+ UserInfoList = testCase.UserInfoList,
+ LatencyThresholdCount = testCase.LatencyThresholdCount,
+ LatencyThresholdList = testCase.LatencyThresholdList,
+ ThroughputThresholdCount = testCase.ThroughputThresholdCount,
+ ThroughputThresholdList = testCase.ThroughputThresholdList,
+ Description = testCase.Description,
+ Version = testCase.Version,
+ VersionUpdateInfo = testCase.VersionUpdateInfo,
+ IsDisabled = testCase.IsDisabled,
+ Remarks = testCase.Remarks,
+ CreatedAt = testCase.CreatedAt,
+ CreatedBy = testCase.CreatedBy
+ };
+
+ _logger.LogInformation("用例创建成功,用例ID: {TestCaseId}, 用例编码: {Code}, 用例名称: {Name}, 版本: {Version}",
+ testCase.Id, testCase.Code, testCase.Name, testCase.Version);
+ return OperationResult.CreateSuccess(response);
+ }
+ catch (Exception ex)
+ {
+ _logger.LogError(ex, "创建用例时发生错误,用例编码: {Code}, 用例名称: {Name}, 版本: {Version}",
+ request.Code, request.Name, request.Version);
+ return OperationResult.CreateFailure($"创建用例时发生错误: {ex.Message}");
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/X1.Application/Features/TestCases/Commands/CreateTestCase/CreateTestCaseResponse.cs b/src/X1.Application/Features/TestCases/Commands/CreateTestCase/CreateTestCaseResponse.cs
new file mode 100644
index 0000000..424cea4
--- /dev/null
+++ b/src/X1.Application/Features/TestCases/Commands/CreateTestCase/CreateTestCaseResponse.cs
@@ -0,0 +1,87 @@
+namespace CellularManagement.Application.Features.TestCases.Commands.CreateTestCase;
+
+///
+/// 创建用例响应
+///
+public class CreateTestCaseResponse
+{
+ ///
+ /// 用例ID
+ ///
+ public string TestCaseId { get; set; } = null!;
+
+ ///
+ /// 用例编码
+ ///
+ public string Code { get; set; } = null!;
+
+ ///
+ /// 用例名称
+ ///
+ public string Name { get; set; } = null!;
+
+ ///
+ /// 用户数
+ ///
+ public int UserCount { get; set; }
+
+ ///
+ /// 用户信息列表
+ ///
+ public string? UserInfoList { get; set; }
+
+ ///
+ /// 时延阈值数
+ ///
+ public int LatencyThresholdCount { get; set; }
+
+ ///
+ /// 时延阈值列表
+ ///
+ public string? LatencyThresholdList { get; set; }
+
+ ///
+ /// 吞吐量阈值数
+ ///
+ public int ThroughputThresholdCount { get; set; }
+
+ ///
+ /// 吞吐量阈值列表
+ ///
+ public string? ThroughputThresholdList { get; set; }
+
+ ///
+ /// 用例说明
+ ///
+ public string? Description { get; set; }
+
+ ///
+ /// 用例版本
+ ///
+ public string Version { get; set; } = null!;
+
+ ///
+ /// 版本更新信息
+ ///
+ public string? VersionUpdateInfo { get; set; }
+
+ ///
+ /// 是否禁用
+ ///
+ public bool IsDisabled { get; set; }
+
+ ///
+ /// 备注
+ ///
+ public string? Remarks { get; set; }
+
+ ///
+ /// 创建时间
+ ///
+ public DateTime CreatedAt { get; set; }
+
+ ///
+ /// 创建人
+ ///
+ public string CreatedBy { get; set; } = null!;
+}
\ No newline at end of file
diff --git a/src/X1.Application/Features/TestCases/Commands/DeleteTestCase/DeleteTestCaseCommand.cs b/src/X1.Application/Features/TestCases/Commands/DeleteTestCase/DeleteTestCaseCommand.cs
new file mode 100644
index 0000000..896b6f6
--- /dev/null
+++ b/src/X1.Application/Features/TestCases/Commands/DeleteTestCase/DeleteTestCaseCommand.cs
@@ -0,0 +1,18 @@
+using CellularManagement.Domain.Common;
+using MediatR;
+using System.ComponentModel.DataAnnotations;
+
+namespace CellularManagement.Application.Features.TestCases.Commands.DeleteTestCase;
+
+///
+/// 删除用例命令
+///
+public class DeleteTestCaseCommand : IRequest>
+{
+ ///
+ /// 用例ID
+ ///
+ [Required(ErrorMessage = "用例ID不能为空")]
+ [MaxLength(50, ErrorMessage = "用例ID长度不能超过50个字符")]
+ public string TestCaseId { get; set; } = null!;
+}
\ No newline at end of file
diff --git a/src/X1.Application/Features/TestCases/Commands/DeleteTestCase/DeleteTestCaseCommandHandler.cs b/src/X1.Application/Features/TestCases/Commands/DeleteTestCase/DeleteTestCaseCommandHandler.cs
new file mode 100644
index 0000000..97a3dd7
--- /dev/null
+++ b/src/X1.Application/Features/TestCases/Commands/DeleteTestCase/DeleteTestCaseCommandHandler.cs
@@ -0,0 +1,102 @@
+using MediatR;
+using Microsoft.Extensions.Logging;
+using CellularManagement.Domain.Common;
+using CellularManagement.Domain.Entities.Device;
+using CellularManagement.Domain.Repositories.Device;
+using CellularManagement.Domain.Repositories.Base;
+using CellularManagement.Domain.Services;
+
+namespace CellularManagement.Application.Features.TestCases.Commands.DeleteTestCase;
+
+///
+/// 删除用例命令处理器
+///
+public class DeleteTestCaseCommandHandler : IRequestHandler>
+{
+ private readonly ITestCaseRepository _testCaseRepository;
+ private readonly ILogger _logger;
+ private readonly IUnitOfWork _unitOfWork;
+ private readonly ICurrentUserService _currentUserService;
+
+ ///
+ /// 初始化命令处理器
+ ///
+ public DeleteTestCaseCommandHandler(
+ ITestCaseRepository testCaseRepository,
+ ILogger logger,
+ IUnitOfWork unitOfWork,
+ ICurrentUserService currentUserService)
+ {
+ _testCaseRepository = testCaseRepository;
+ _logger = logger;
+ _unitOfWork = unitOfWork;
+ _currentUserService = currentUserService;
+ }
+
+ ///
+ /// 处理删除用例命令
+ ///
+ public async Task> Handle(DeleteTestCaseCommand request, CancellationToken cancellationToken)
+ {
+ try
+ {
+ _logger.LogInformation("开始删除用例,用例ID: {TestCaseId}", request.TestCaseId);
+
+ // 检查用例是否存在
+ var existingTestCase = await _testCaseRepository.GetTestCaseByIdAsync(request.TestCaseId, cancellationToken);
+ if (existingTestCase == null)
+ {
+ _logger.LogWarning("用例不存在: {TestCaseId}", request.TestCaseId);
+ return OperationResult.CreateFailure($"用例ID {request.TestCaseId} 不存在");
+ }
+
+ // 检查用例是否已被软删除
+ if (existingTestCase.IsDeleted)
+ {
+ _logger.LogWarning("用例已被删除: {TestCaseId}", request.TestCaseId);
+ return OperationResult.CreateFailure($"用例ID {request.TestCaseId} 已被删除");
+ }
+
+ // 获取当前用户ID
+ var currentUserId = _currentUserService.GetCurrentUserId();
+ if (string.IsNullOrEmpty(currentUserId))
+ {
+ _logger.LogError("无法获取当前用户ID,用户可能未认证");
+ return OperationResult.CreateFailure("用户未认证,无法删除用例");
+ }
+
+ // 软删除用例
+ existingTestCase.SoftDelete();
+ existingTestCase.Update(
+ code: existingTestCase.Code,
+ name: existingTestCase.Name,
+ version: existingTestCase.Version,
+ updatedBy: currentUserId,
+ userCount: existingTestCase.UserCount,
+ userInfoList: existingTestCase.UserInfoList,
+ latencyThresholdCount: existingTestCase.LatencyThresholdCount,
+ latencyThresholdList: existingTestCase.LatencyThresholdList,
+ throughputThresholdCount: existingTestCase.ThroughputThresholdCount,
+ throughputThresholdList: existingTestCase.ThroughputThresholdList,
+ description: existingTestCase.Description,
+ versionUpdateInfo: existingTestCase.VersionUpdateInfo,
+ isDisabled: existingTestCase.IsDisabled,
+ remarks: existingTestCase.Remarks);
+
+ // 保存更改
+ _testCaseRepository.UpdateTestCase(existingTestCase);
+
+ // 保存更改到数据库
+ await _unitOfWork.SaveChangesAsync(cancellationToken);
+
+ _logger.LogInformation("用例删除成功,用例ID: {TestCaseId}, 用例编码: {Code}, 用例名称: {Name}, 版本: {Version}",
+ existingTestCase.Id, existingTestCase.Code, existingTestCase.Name, existingTestCase.Version);
+ return OperationResult.CreateSuccess(true);
+ }
+ catch (Exception ex)
+ {
+ _logger.LogError(ex, "删除用例时发生错误,用例ID: {TestCaseId}", request.TestCaseId);
+ return OperationResult.CreateFailure($"删除用例时发生错误: {ex.Message}");
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/X1.Application/Features/TestCases/Commands/DisableTestCase/DisableTestCaseCommand.cs b/src/X1.Application/Features/TestCases/Commands/DisableTestCase/DisableTestCaseCommand.cs
new file mode 100644
index 0000000..50f2300
--- /dev/null
+++ b/src/X1.Application/Features/TestCases/Commands/DisableTestCase/DisableTestCaseCommand.cs
@@ -0,0 +1,18 @@
+using CellularManagement.Domain.Common;
+using MediatR;
+using System.ComponentModel.DataAnnotations;
+
+namespace CellularManagement.Application.Features.TestCases.Commands.DisableTestCase;
+
+///
+/// 禁用用例命令
+///
+public class DisableTestCaseCommand : IRequest>
+{
+ ///
+ /// 用例ID
+ ///
+ [Required(ErrorMessage = "用例ID不能为空")]
+ [MaxLength(50, ErrorMessage = "用例ID长度不能超过50个字符")]
+ public string TestCaseId { get; set; } = null!;
+}
\ No newline at end of file
diff --git a/src/X1.Application/Features/TestCases/Commands/DisableTestCase/DisableTestCaseCommandHandler.cs b/src/X1.Application/Features/TestCases/Commands/DisableTestCase/DisableTestCaseCommandHandler.cs
new file mode 100644
index 0000000..7938d05
--- /dev/null
+++ b/src/X1.Application/Features/TestCases/Commands/DisableTestCase/DisableTestCaseCommandHandler.cs
@@ -0,0 +1,109 @@
+using MediatR;
+using Microsoft.Extensions.Logging;
+using CellularManagement.Domain.Common;
+using CellularManagement.Domain.Entities.Device;
+using CellularManagement.Domain.Repositories.Device;
+using CellularManagement.Domain.Repositories.Base;
+using CellularManagement.Domain.Services;
+
+namespace CellularManagement.Application.Features.TestCases.Commands.DisableTestCase;
+
+///
+/// 禁用用例命令处理器
+///
+public class DisableTestCaseCommandHandler : IRequestHandler>
+{
+ private readonly ITestCaseRepository _testCaseRepository;
+ private readonly ILogger _logger;
+ private readonly IUnitOfWork _unitOfWork;
+ private readonly ICurrentUserService _currentUserService;
+
+ ///
+ /// 初始化命令处理器
+ ///
+ public DisableTestCaseCommandHandler(
+ ITestCaseRepository testCaseRepository,
+ ILogger logger,
+ IUnitOfWork unitOfWork,
+ ICurrentUserService currentUserService)
+ {
+ _testCaseRepository = testCaseRepository;
+ _logger = logger;
+ _unitOfWork = unitOfWork;
+ _currentUserService = currentUserService;
+ }
+
+ ///
+ /// 处理禁用用例命令
+ ///
+ public async Task> Handle(DisableTestCaseCommand request, CancellationToken cancellationToken)
+ {
+ try
+ {
+ _logger.LogInformation("开始禁用用例,用例ID: {TestCaseId}", request.TestCaseId);
+
+ // 检查用例是否存在
+ var existingTestCase = await _testCaseRepository.GetTestCaseByIdAsync(request.TestCaseId, cancellationToken);
+ if (existingTestCase == null)
+ {
+ _logger.LogWarning("用例不存在: {TestCaseId}", request.TestCaseId);
+ return OperationResult.CreateFailure($"用例ID {request.TestCaseId} 不存在");
+ }
+
+ // 检查用例是否已被软删除
+ if (existingTestCase.IsDeleted)
+ {
+ _logger.LogWarning("用例已被删除: {TestCaseId}", request.TestCaseId);
+ return OperationResult.CreateFailure($"用例ID {request.TestCaseId} 已被删除");
+ }
+
+ // 检查用例是否已经禁用
+ if (existingTestCase.IsDisabled)
+ {
+ _logger.LogWarning("用例已经禁用: {TestCaseId}", request.TestCaseId);
+ return OperationResult.CreateFailure($"用例ID {request.TestCaseId} 已经禁用");
+ }
+
+ // 获取当前用户ID
+ var currentUserId = _currentUserService.GetCurrentUserId();
+ if (string.IsNullOrEmpty(currentUserId))
+ {
+ _logger.LogError("无法获取当前用户ID,用户可能未认证");
+ return OperationResult.CreateFailure("用户未认证,无法禁用用例");
+ }
+
+ // 禁用用例
+ existingTestCase.Disable();
+ existingTestCase.Update(
+ code: existingTestCase.Code,
+ name: existingTestCase.Name,
+ version: existingTestCase.Version,
+ updatedBy: currentUserId,
+ userCount: existingTestCase.UserCount,
+ userInfoList: existingTestCase.UserInfoList,
+ latencyThresholdCount: existingTestCase.LatencyThresholdCount,
+ latencyThresholdList: existingTestCase.LatencyThresholdList,
+ throughputThresholdCount: existingTestCase.ThroughputThresholdCount,
+ throughputThresholdList: existingTestCase.ThroughputThresholdList,
+ description: existingTestCase.Description,
+ versionUpdateInfo: existingTestCase.VersionUpdateInfo,
+ isDisabled: true,
+ remarks: existingTestCase.Remarks);
+
+ // 保存更改
+ _testCaseRepository.UpdateTestCase(existingTestCase);
+
+ // 保存更改到数据库
+ await _unitOfWork.SaveChangesAsync(cancellationToken);
+
+ _logger.LogInformation("用例禁用成功,用例ID: {TestCaseId}, 用例编码: {Code}, 用例名称: {Name}, 版本: {Version}",
+ existingTestCase.Id, existingTestCase.Code, existingTestCase.Name, existingTestCase.Version);
+ return OperationResult.CreateSuccess(true);
+ }
+ catch (Exception ex)
+ {
+ _logger.LogError(ex, "禁用用例时发生错误,用例ID: {TestCaseId}", request.TestCaseId);
+ return OperationResult.CreateFailure($"禁用用例时发生错误: {ex.Message}");
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/X1.Application/Features/TestCases/Commands/EnableTestCase/EnableTestCaseCommand.cs b/src/X1.Application/Features/TestCases/Commands/EnableTestCase/EnableTestCaseCommand.cs
new file mode 100644
index 0000000..4357532
--- /dev/null
+++ b/src/X1.Application/Features/TestCases/Commands/EnableTestCase/EnableTestCaseCommand.cs
@@ -0,0 +1,18 @@
+using CellularManagement.Domain.Common;
+using MediatR;
+using System.ComponentModel.DataAnnotations;
+
+namespace CellularManagement.Application.Features.TestCases.Commands.EnableTestCase;
+
+///
+/// 启用用例命令
+///
+public class EnableTestCaseCommand : IRequest>
+{
+ ///
+ /// 用例ID
+ ///
+ [Required(ErrorMessage = "用例ID不能为空")]
+ [MaxLength(50, ErrorMessage = "用例ID长度不能超过50个字符")]
+ public string TestCaseId { get; set; } = null!;
+}
\ No newline at end of file
diff --git a/src/X1.Application/Features/TestCases/Commands/EnableTestCase/EnableTestCaseCommandHandler.cs b/src/X1.Application/Features/TestCases/Commands/EnableTestCase/EnableTestCaseCommandHandler.cs
new file mode 100644
index 0000000..a5a7e6f
--- /dev/null
+++ b/src/X1.Application/Features/TestCases/Commands/EnableTestCase/EnableTestCaseCommandHandler.cs
@@ -0,0 +1,109 @@
+using MediatR;
+using Microsoft.Extensions.Logging;
+using CellularManagement.Domain.Common;
+using CellularManagement.Domain.Entities.Device;
+using CellularManagement.Domain.Repositories.Device;
+using CellularManagement.Domain.Repositories.Base;
+using CellularManagement.Domain.Services;
+
+namespace CellularManagement.Application.Features.TestCases.Commands.EnableTestCase;
+
+///
+/// 启用用例命令处理器
+///
+public class EnableTestCaseCommandHandler : IRequestHandler>
+{
+ private readonly ITestCaseRepository _testCaseRepository;
+ private readonly ILogger _logger;
+ private readonly IUnitOfWork _unitOfWork;
+ private readonly ICurrentUserService _currentUserService;
+
+ ///
+ /// 初始化命令处理器
+ ///
+ public EnableTestCaseCommandHandler(
+ ITestCaseRepository testCaseRepository,
+ ILogger logger,
+ IUnitOfWork unitOfWork,
+ ICurrentUserService currentUserService)
+ {
+ _testCaseRepository = testCaseRepository;
+ _logger = logger;
+ _unitOfWork = unitOfWork;
+ _currentUserService = currentUserService;
+ }
+
+ ///
+ /// 处理启用用例命令
+ ///
+ public async Task> Handle(EnableTestCaseCommand request, CancellationToken cancellationToken)
+ {
+ try
+ {
+ _logger.LogInformation("开始启用用例,用例ID: {TestCaseId}", request.TestCaseId);
+
+ // 检查用例是否存在
+ var existingTestCase = await _testCaseRepository.GetTestCaseByIdAsync(request.TestCaseId, cancellationToken);
+ if (existingTestCase == null)
+ {
+ _logger.LogWarning("用例不存在: {TestCaseId}", request.TestCaseId);
+ return OperationResult.CreateFailure($"用例ID {request.TestCaseId} 不存在");
+ }
+
+ // 检查用例是否已被软删除
+ if (existingTestCase.IsDeleted)
+ {
+ _logger.LogWarning("用例已被删除: {TestCaseId}", request.TestCaseId);
+ return OperationResult.CreateFailure($"用例ID {request.TestCaseId} 已被删除");
+ }
+
+ // 检查用例是否已经启用
+ if (!existingTestCase.IsDisabled)
+ {
+ _logger.LogWarning("用例已经启用: {TestCaseId}", request.TestCaseId);
+ return OperationResult.CreateFailure($"用例ID {request.TestCaseId} 已经启用");
+ }
+
+ // 获取当前用户ID
+ var currentUserId = _currentUserService.GetCurrentUserId();
+ if (string.IsNullOrEmpty(currentUserId))
+ {
+ _logger.LogError("无法获取当前用户ID,用户可能未认证");
+ return OperationResult.CreateFailure("用户未认证,无法启用用例");
+ }
+
+ // 启用用例
+ existingTestCase.Enable();
+ existingTestCase.Update(
+ code: existingTestCase.Code,
+ name: existingTestCase.Name,
+ version: existingTestCase.Version,
+ updatedBy: currentUserId,
+ userCount: existingTestCase.UserCount,
+ userInfoList: existingTestCase.UserInfoList,
+ latencyThresholdCount: existingTestCase.LatencyThresholdCount,
+ latencyThresholdList: existingTestCase.LatencyThresholdList,
+ throughputThresholdCount: existingTestCase.ThroughputThresholdCount,
+ throughputThresholdList: existingTestCase.ThroughputThresholdList,
+ description: existingTestCase.Description,
+ versionUpdateInfo: existingTestCase.VersionUpdateInfo,
+ isDisabled: false,
+ remarks: existingTestCase.Remarks);
+
+ // 保存更改
+ _testCaseRepository.UpdateTestCase(existingTestCase);
+
+ // 保存更改到数据库
+ await _unitOfWork.SaveChangesAsync(cancellationToken);
+
+ _logger.LogInformation("用例启用成功,用例ID: {TestCaseId}, 用例编码: {Code}, 用例名称: {Name}, 版本: {Version}",
+ existingTestCase.Id, existingTestCase.Code, existingTestCase.Name, existingTestCase.Version);
+ return OperationResult.CreateSuccess(true);
+ }
+ catch (Exception ex)
+ {
+ _logger.LogError(ex, "启用用例时发生错误,用例ID: {TestCaseId}", request.TestCaseId);
+ return OperationResult.CreateFailure($"启用用例时发生错误: {ex.Message}");
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/X1.Application/Features/TestCases/Commands/UpdateTestCase/UpdateTestCaseCommand.cs b/src/X1.Application/Features/TestCases/Commands/UpdateTestCase/UpdateTestCaseCommand.cs
new file mode 100644
index 0000000..df0d27a
--- /dev/null
+++ b/src/X1.Application/Features/TestCases/Commands/UpdateTestCase/UpdateTestCaseCommand.cs
@@ -0,0 +1,98 @@
+using CellularManagement.Domain.Common;
+using MediatR;
+using System.ComponentModel.DataAnnotations;
+
+namespace CellularManagement.Application.Features.TestCases.Commands.UpdateTestCase;
+
+///
+/// 更新用例命令
+///
+public class UpdateTestCaseCommand : IRequest>
+{
+ ///
+ /// 用例ID
+ ///
+ [Required(ErrorMessage = "用例ID不能为空")]
+ [MaxLength(50, ErrorMessage = "用例ID长度不能超过50个字符")]
+ public string TestCaseId { get; set; } = null!;
+
+ ///
+ /// 用例编码
+ ///
+ [Required(ErrorMessage = "用例编码不能为空")]
+ [MaxLength(50, ErrorMessage = "用例编码长度不能超过50个字符")]
+ public string Code { get; set; } = null!;
+
+ ///
+ /// 用例名称
+ ///
+ [Required(ErrorMessage = "用例名称不能为空")]
+ [MaxLength(100, ErrorMessage = "用例名称长度不能超过100个字符")]
+ public string Name { get; set; } = null!;
+
+ ///
+ /// 用户数
+ ///
+ [Range(0, int.MaxValue, ErrorMessage = "用户数必须大于等于0")]
+ public int UserCount { get; set; } = 0;
+
+ ///
+ /// 用户信息列表(JSON格式)
+ ///
+ [MaxLength(4000, ErrorMessage = "用户信息列表长度不能超过4000个字符")]
+ public string? UserInfoList { get; set; }
+
+ ///
+ /// 时延阈值数
+ ///
+ [Range(0, int.MaxValue, ErrorMessage = "时延阈值数必须大于等于0")]
+ public int LatencyThresholdCount { get; set; } = 0;
+
+ ///
+ /// 时延阈值列表(JSON格式)
+ ///
+ [MaxLength(2000, ErrorMessage = "时延阈值列表长度不能超过2000个字符")]
+ public string? LatencyThresholdList { get; set; }
+
+ ///
+ /// 吞吐量阈值数
+ ///
+ [Range(0, int.MaxValue, ErrorMessage = "吞吐量阈值数必须大于等于0")]
+ public int ThroughputThresholdCount { get; set; } = 0;
+
+ ///
+ /// 吞吐量阈值列表(JSON格式)
+ ///
+ [MaxLength(2000, ErrorMessage = "吞吐量阈值列表长度不能超过2000个字符")]
+ public string? ThroughputThresholdList { get; set; }
+
+ ///
+ /// 用例说明
+ ///
+ [MaxLength(1000, ErrorMessage = "用例说明长度不能超过1000个字符")]
+ public string? Description { get; set; }
+
+ ///
+ /// 用例版本
+ ///
+ [Required(ErrorMessage = "用例版本不能为空")]
+ [MaxLength(20, ErrorMessage = "用例版本长度不能超过20个字符")]
+ public string Version { get; set; } = null!;
+
+ ///
+ /// 版本更新信息
+ ///
+ [MaxLength(500, ErrorMessage = "版本更新信息长度不能超过500个字符")]
+ public string? VersionUpdateInfo { get; set; }
+
+ ///
+ /// 是否禁用
+ ///
+ public bool IsDisabled { get; set; } = false;
+
+ ///
+ /// 备注
+ ///
+ [MaxLength(1000, ErrorMessage = "备注长度不能超过1000个字符")]
+ public string? Remarks { get; set; }
+}
\ No newline at end of file
diff --git a/src/X1.Application/Features/TestCases/Commands/UpdateTestCase/UpdateTestCaseCommandHandler.cs b/src/X1.Application/Features/TestCases/Commands/UpdateTestCase/UpdateTestCaseCommandHandler.cs
new file mode 100644
index 0000000..707ebe1
--- /dev/null
+++ b/src/X1.Application/Features/TestCases/Commands/UpdateTestCase/UpdateTestCaseCommandHandler.cs
@@ -0,0 +1,133 @@
+using MediatR;
+using Microsoft.Extensions.Logging;
+using CellularManagement.Domain.Common;
+using CellularManagement.Domain.Entities.Device;
+using CellularManagement.Domain.Repositories.Device;
+using CellularManagement.Domain.Repositories.Base;
+using CellularManagement.Domain.Services;
+
+namespace CellularManagement.Application.Features.TestCases.Commands.UpdateTestCase;
+
+///
+/// 更新用例命令处理器
+///
+public class UpdateTestCaseCommandHandler : IRequestHandler>
+{
+ private readonly ITestCaseRepository _testCaseRepository;
+ private readonly ILogger _logger;
+ private readonly IUnitOfWork _unitOfWork;
+ private readonly ICurrentUserService _currentUserService;
+
+ ///
+ /// 初始化命令处理器
+ ///
+ public UpdateTestCaseCommandHandler(
+ ITestCaseRepository testCaseRepository,
+ ILogger logger,
+ IUnitOfWork unitOfWork,
+ ICurrentUserService currentUserService)
+ {
+ _testCaseRepository = testCaseRepository;
+ _logger = logger;
+ _unitOfWork = unitOfWork;
+ _currentUserService = currentUserService;
+ }
+
+ ///
+ /// 处理更新用例命令
+ ///
+ public async Task> Handle(UpdateTestCaseCommand request, CancellationToken cancellationToken)
+ {
+ try
+ {
+ _logger.LogInformation("开始更新用例,用例ID: {TestCaseId}, 用例编码: {Code}, 用例名称: {Name}, 版本: {Version}",
+ request.TestCaseId, request.Code, request.Name, request.Version);
+
+ // 检查用例是否存在
+ var existingTestCase = await _testCaseRepository.GetTestCaseByIdAsync(request.TestCaseId, cancellationToken);
+ if (existingTestCase == null)
+ {
+ _logger.LogWarning("用例不存在: {TestCaseId}", request.TestCaseId);
+ return OperationResult.CreateFailure($"用例ID {request.TestCaseId} 不存在");
+ }
+
+ // 检查用例编码是否已被其他用例使用
+ var testCaseWithSameCode = await _testCaseRepository.GetTestCaseByCodeAsync(request.Code, cancellationToken);
+ if (testCaseWithSameCode != null && testCaseWithSameCode.Id != request.TestCaseId)
+ {
+ _logger.LogWarning("用例编码已被其他用例使用: {Code}", request.Code);
+ return OperationResult.CreateFailure($"用例编码 {request.Code} 已被其他用例使用");
+ }
+
+ // 检查用例版本是否已被其他用例使用
+ var testCaseWithSameVersion = await _testCaseRepository.GetTestCaseByVersionAsync(request.Version, cancellationToken);
+ if (testCaseWithSameVersion != null && testCaseWithSameVersion.Id != request.TestCaseId)
+ {
+ _logger.LogWarning("用例版本已被其他用例使用: {Version}", request.Version);
+ return OperationResult.CreateFailure($"用例版本 {request.Version} 已被其他用例使用");
+ }
+
+ // 获取当前用户ID
+ var currentUserId = _currentUserService.GetCurrentUserId();
+ if (string.IsNullOrEmpty(currentUserId))
+ {
+ _logger.LogError("无法获取当前用户ID,用户可能未认证");
+ return OperationResult.CreateFailure("用户未认证,无法更新用例");
+ }
+
+ // 更新用例
+ existingTestCase.Update(
+ code: request.Code,
+ name: request.Name,
+ version: request.Version,
+ updatedBy: currentUserId,
+ userCount: request.UserCount,
+ userInfoList: request.UserInfoList,
+ latencyThresholdCount: request.LatencyThresholdCount,
+ latencyThresholdList: request.LatencyThresholdList,
+ throughputThresholdCount: request.ThroughputThresholdCount,
+ throughputThresholdList: request.ThroughputThresholdList,
+ description: request.Description,
+ versionUpdateInfo: request.VersionUpdateInfo,
+ isDisabled: request.IsDisabled,
+ remarks: request.Remarks);
+
+ // 保存更改
+ _testCaseRepository.UpdateTestCase(existingTestCase);
+
+ // 保存更改到数据库
+ await _unitOfWork.SaveChangesAsync(cancellationToken);
+
+ // 构建响应
+ var response = new UpdateTestCaseResponse
+ {
+ TestCaseId = existingTestCase.Id,
+ Code = existingTestCase.Code,
+ Name = existingTestCase.Name,
+ UserCount = existingTestCase.UserCount,
+ UserInfoList = existingTestCase.UserInfoList,
+ LatencyThresholdCount = existingTestCase.LatencyThresholdCount,
+ LatencyThresholdList = existingTestCase.LatencyThresholdList,
+ ThroughputThresholdCount = existingTestCase.ThroughputThresholdCount,
+ ThroughputThresholdList = existingTestCase.ThroughputThresholdList,
+ Description = existingTestCase.Description,
+ Version = existingTestCase.Version,
+ VersionUpdateInfo = existingTestCase.VersionUpdateInfo,
+ IsDisabled = existingTestCase.IsDisabled,
+ Remarks = existingTestCase.Remarks,
+ UpdatedAt = existingTestCase.UpdatedAt,
+ UpdatedBy = existingTestCase.UpdatedBy
+ };
+
+ _logger.LogInformation("用例更新成功,用例ID: {TestCaseId}, 用例编码: {Code}, 用例名称: {Name}, 版本: {Version}",
+ existingTestCase.Id, existingTestCase.Code, existingTestCase.Name, existingTestCase.Version);
+ return OperationResult.CreateSuccess(response);
+ }
+ catch (Exception ex)
+ {
+ _logger.LogError(ex, "更新用例时发生错误,用例ID: {TestCaseId}, 用例编码: {Code}, 用例名称: {Name}, 版本: {Version}",
+ request.TestCaseId, request.Code, request.Name, request.Version);
+ return OperationResult.CreateFailure($"更新用例时发生错误: {ex.Message}");
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/X1.Application/Features/TestCases/Commands/UpdateTestCase/UpdateTestCaseResponse.cs b/src/X1.Application/Features/TestCases/Commands/UpdateTestCase/UpdateTestCaseResponse.cs
new file mode 100644
index 0000000..28273d8
--- /dev/null
+++ b/src/X1.Application/Features/TestCases/Commands/UpdateTestCase/UpdateTestCaseResponse.cs
@@ -0,0 +1,87 @@
+namespace CellularManagement.Application.Features.TestCases.Commands.UpdateTestCase;
+
+///
+/// 更新用例响应
+///
+public class UpdateTestCaseResponse
+{
+ ///
+ /// 用例ID
+ ///
+ public string TestCaseId { get; set; } = null!;
+
+ ///
+ /// 用例编码
+ ///
+ public string Code { get; set; } = null!;
+
+ ///
+ /// 用例名称
+ ///
+ public string Name { get; set; } = null!;
+
+ ///
+ /// 用户数
+ ///
+ public int UserCount { get; set; }
+
+ ///
+ /// 用户信息列表
+ ///
+ public string? UserInfoList { get; set; }
+
+ ///
+ /// 时延阈值数
+ ///
+ public int LatencyThresholdCount { get; set; }
+
+ ///
+ /// 时延阈值列表
+ ///
+ public string? LatencyThresholdList { get; set; }
+
+ ///
+ /// 吞吐量阈值数
+ ///
+ public int ThroughputThresholdCount { get; set; }
+
+ ///
+ /// 吞吐量阈值列表
+ ///
+ public string? ThroughputThresholdList { get; set; }
+
+ ///
+ /// 用例说明
+ ///
+ public string? Description { get; set; }
+
+ ///
+ /// 用例版本
+ ///
+ public string Version { get; set; } = null!;
+
+ ///
+ /// 版本更新信息
+ ///
+ public string? VersionUpdateInfo { get; set; }
+
+ ///
+ /// 是否禁用
+ ///
+ public bool IsDisabled { get; set; }
+
+ ///
+ /// 备注
+ ///
+ public string? Remarks { get; set; }
+
+ ///
+ /// 更新时间
+ ///
+ public DateTime? UpdatedAt { get; set; }
+
+ ///
+ /// 修改人
+ ///
+ public string? UpdatedBy { get; set; }
+}
\ No newline at end of file
diff --git a/src/X1.Application/Features/TestCases/Queries/GetTestCaseById/GetTestCaseByIdQuery.cs b/src/X1.Application/Features/TestCases/Queries/GetTestCaseById/GetTestCaseByIdQuery.cs
new file mode 100644
index 0000000..83f7b0f
--- /dev/null
+++ b/src/X1.Application/Features/TestCases/Queries/GetTestCaseById/GetTestCaseByIdQuery.cs
@@ -0,0 +1,14 @@
+using MediatR;
+
+namespace CellularManagement.Application.Features.TestCases.Queries.GetTestCaseById;
+
+///
+/// 根据ID获取用例查询
+///
+public class GetTestCaseByIdQuery : IRequest
+{
+ ///
+ /// 用例ID
+ ///
+ public string Id { get; set; } = null!;
+}
\ No newline at end of file
diff --git a/src/X1.Application/Features/TestCases/Queries/GetTestCaseById/GetTestCaseByIdQueryHandler.cs b/src/X1.Application/Features/TestCases/Queries/GetTestCaseById/GetTestCaseByIdQueryHandler.cs
new file mode 100644
index 0000000..4be08ff
--- /dev/null
+++ b/src/X1.Application/Features/TestCases/Queries/GetTestCaseById/GetTestCaseByIdQueryHandler.cs
@@ -0,0 +1,76 @@
+using MediatR;
+using Microsoft.Extensions.Logging;
+using CellularManagement.Domain.Repositories.Device;
+
+namespace CellularManagement.Application.Features.TestCases.Queries.GetTestCaseById;
+
+///
+/// 根据ID获取用例查询处理器
+///
+public class GetTestCaseByIdQueryHandler : IRequestHandler
+{
+ private readonly ITestCaseRepository _testCaseRepository;
+ private readonly ILogger _logger;
+
+ ///
+ /// 初始化查询处理器
+ ///
+ public GetTestCaseByIdQueryHandler(
+ ITestCaseRepository testCaseRepository,
+ ILogger logger)
+ {
+ _testCaseRepository = testCaseRepository;
+ _logger = logger;
+ }
+
+ ///
+ /// 处理根据ID获取用例查询
+ ///
+ public async Task Handle(GetTestCaseByIdQuery request, CancellationToken cancellationToken)
+ {
+ try
+ {
+ _logger.LogInformation("开始获取用例详情,用例ID: {TestCaseId}", request.Id);
+
+ // 获取用例
+ var testCase = await _testCaseRepository.GetTestCaseByIdAsync(request.Id, cancellationToken);
+ if (testCase == null)
+ {
+ _logger.LogWarning("用例不存在: {TestCaseId}", request.Id);
+ return null;
+ }
+
+ // 转换为响应
+ var response = new GetTestCaseByIdResponse
+ {
+ Id = testCase.Id,
+ Code = testCase.Code,
+ Name = testCase.Name,
+ UserCount = testCase.UserCount,
+ UserInfoList = testCase.UserInfoList,
+ LatencyThresholdCount = testCase.LatencyThresholdCount,
+ LatencyThresholdList = testCase.LatencyThresholdList,
+ ThroughputThresholdCount = testCase.ThroughputThresholdCount,
+ ThroughputThresholdList = testCase.ThroughputThresholdList,
+ Description = testCase.Description,
+ Version = testCase.Version,
+ VersionUpdateInfo = testCase.VersionUpdateInfo,
+ IsDisabled = testCase.IsDisabled,
+ Remarks = testCase.Remarks,
+ CreatedAt = testCase.CreatedAt,
+ CreatedBy = testCase.CreatedBy,
+ UpdatedAt = testCase.UpdatedAt,
+ UpdatedBy = testCase.UpdatedBy
+ };
+
+ _logger.LogInformation("成功获取用例详情,用例ID: {TestCaseId}, 用例编码: {Code}, 用例名称: {Name}",
+ testCase.Id, testCase.Code, testCase.Name);
+ return response;
+ }
+ catch (Exception ex)
+ {
+ _logger.LogError(ex, "获取用例详情时发生错误,用例ID: {TestCaseId}", request.Id);
+ throw;
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/X1.Application/Features/TestCases/Queries/GetTestCaseById/GetTestCaseByIdResponse.cs b/src/X1.Application/Features/TestCases/Queries/GetTestCaseById/GetTestCaseByIdResponse.cs
new file mode 100644
index 0000000..e020e66
--- /dev/null
+++ b/src/X1.Application/Features/TestCases/Queries/GetTestCaseById/GetTestCaseByIdResponse.cs
@@ -0,0 +1,97 @@
+namespace CellularManagement.Application.Features.TestCases.Queries.GetTestCaseById;
+
+///
+/// 根据ID获取用例响应
+///
+public class GetTestCaseByIdResponse
+{
+ ///
+ /// 用例ID
+ ///
+ public string Id { get; set; } = null!;
+
+ ///
+ /// 用例编码
+ ///
+ public string Code { get; set; } = null!;
+
+ ///
+ /// 用例名称
+ ///
+ public string Name { get; set; } = null!;
+
+ ///
+ /// 用户数
+ ///
+ public int UserCount { get; set; }
+
+ ///
+ /// 用户信息列表
+ ///
+ public string? UserInfoList { get; set; }
+
+ ///
+ /// 时延阈值数
+ ///
+ public int LatencyThresholdCount { get; set; }
+
+ ///
+ /// 时延阈值列表
+ ///
+ public string? LatencyThresholdList { get; set; }
+
+ ///
+ /// 吞吐量阈值数
+ ///
+ public int ThroughputThresholdCount { get; set; }
+
+ ///
+ /// 吞吐量阈值列表
+ ///
+ public string? ThroughputThresholdList { get; set; }
+
+ ///
+ /// 用例说明
+ ///
+ public string? Description { get; set; }
+
+ ///
+ /// 用例版本
+ ///
+ public string Version { get; set; } = null!;
+
+ ///
+ /// 版本更新信息
+ ///
+ public string? VersionUpdateInfo { get; set; }
+
+ ///
+ /// 是否禁用
+ ///
+ public bool IsDisabled { get; set; }
+
+ ///
+ /// 备注
+ ///
+ public string? Remarks { get; set; }
+
+ ///
+ /// 创建时间
+ ///
+ public DateTime CreatedAt { get; set; }
+
+ ///
+ /// 创建人
+ ///
+ public string CreatedBy { get; set; } = null!;
+
+ ///
+ /// 更新时间
+ ///
+ public DateTime? UpdatedAt { get; set; }
+
+ ///
+ /// 修改人
+ ///
+ public string? UpdatedBy { get; set; }
+}
\ No newline at end of file
diff --git a/src/X1.Application/Features/TestCases/Queries/GetTestCases/GetTestCasesQuery.cs b/src/X1.Application/Features/TestCases/Queries/GetTestCases/GetTestCasesQuery.cs
new file mode 100644
index 0000000..0199a61
--- /dev/null
+++ b/src/X1.Application/Features/TestCases/Queries/GetTestCases/GetTestCasesQuery.cs
@@ -0,0 +1,14 @@
+using MediatR;
+
+namespace CellularManagement.Application.Features.TestCases.Queries.GetTestCases;
+
+///
+/// 获取所有用例查询
+///
+public class GetTestCasesQuery : IRequest
+{
+ ///
+ /// 搜索关键词
+ ///
+ public string? Keyword { get; set; }
+}
\ No newline at end of file
diff --git a/src/X1.Application/Features/TestCases/Queries/GetTestCases/GetTestCasesQueryHandler.cs b/src/X1.Application/Features/TestCases/Queries/GetTestCases/GetTestCasesQueryHandler.cs
new file mode 100644
index 0000000..62dd532
--- /dev/null
+++ b/src/X1.Application/Features/TestCases/Queries/GetTestCases/GetTestCasesQueryHandler.cs
@@ -0,0 +1,76 @@
+using MediatR;
+using Microsoft.Extensions.Logging;
+using CellularManagement.Domain.Repositories.Device;
+
+namespace CellularManagement.Application.Features.TestCases.Queries.GetTestCases;
+
+///
+/// 获取所有用例查询处理器
+///
+public class GetTestCasesQueryHandler : IRequestHandler
+{
+ private readonly ITestCaseRepository _testCaseRepository;
+ private readonly ILogger _logger;
+
+ ///
+ /// 初始化查询处理器
+ ///
+ public GetTestCasesQueryHandler(
+ ITestCaseRepository testCaseRepository,
+ ILogger logger)
+ {
+ _testCaseRepository = testCaseRepository;
+ _logger = logger;
+ }
+
+ ///
+ /// 处理获取所有用例查询
+ ///
+ public async Task Handle(GetTestCasesQuery request, CancellationToken cancellationToken)
+ {
+ try
+ {
+ _logger.LogInformation("开始获取用例列表,搜索关键词: {Keyword}", request.Keyword ?? "无");
+
+ // 获取用例列表
+ var testCases = await _testCaseRepository.SearchTestCasesAsync(request.Keyword, cancellationToken);
+
+ // 转换为DTO
+ var testCaseDtos = testCases.Select(tc => new TestCaseDto
+ {
+ Id = tc.Id,
+ Code = tc.Code,
+ Name = tc.Name,
+ UserCount = tc.UserCount,
+ UserInfoList = tc.UserInfoList,
+ LatencyThresholdCount = tc.LatencyThresholdCount,
+ LatencyThresholdList = tc.LatencyThresholdList,
+ ThroughputThresholdCount = tc.ThroughputThresholdCount,
+ ThroughputThresholdList = tc.ThroughputThresholdList,
+ Description = tc.Description,
+ Version = tc.Version,
+ VersionUpdateInfo = tc.VersionUpdateInfo,
+ IsDisabled = tc.IsDisabled,
+ Remarks = tc.Remarks,
+ CreatedAt = tc.CreatedAt,
+ CreatedBy = tc.CreatedBy,
+ UpdatedAt = tc.UpdatedAt,
+ UpdatedBy = tc.UpdatedBy
+ }).ToList();
+
+ var response = new GetTestCasesResponse
+ {
+ TestCases = testCaseDtos,
+ TotalCount = testCaseDtos.Count
+ };
+
+ _logger.LogInformation("成功获取用例列表,总数: {TotalCount}", response.TotalCount);
+ return response;
+ }
+ catch (Exception ex)
+ {
+ _logger.LogError(ex, "获取用例列表时发生错误,搜索关键词: {Keyword}", request.Keyword ?? "无");
+ throw;
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/X1.Application/Features/TestCases/Queries/GetTestCases/GetTestCasesResponse.cs b/src/X1.Application/Features/TestCases/Queries/GetTestCases/GetTestCasesResponse.cs
new file mode 100644
index 0000000..1d590b9
--- /dev/null
+++ b/src/X1.Application/Features/TestCases/Queries/GetTestCases/GetTestCasesResponse.cs
@@ -0,0 +1,113 @@
+namespace CellularManagement.Application.Features.TestCases.Queries.GetTestCases;
+
+///
+/// 获取所有用例响应
+///
+public class GetTestCasesResponse
+{
+ ///
+ /// 用例列表
+ ///
+ public List TestCases { get; set; } = new();
+
+ ///
+ /// 总数
+ ///
+ public int TotalCount { get; set; }
+}
+
+///
+/// 用例数据传输对象
+///
+public class TestCaseDto
+{
+ ///
+ /// 用例ID
+ ///
+ public string Id { get; set; } = null!;
+
+ ///
+ /// 用例编码
+ ///
+ public string Code { get; set; } = null!;
+
+ ///
+ /// 用例名称
+ ///
+ public string Name { get; set; } = null!;
+
+ ///
+ /// 用户数
+ ///
+ public int UserCount { get; set; }
+
+ ///
+ /// 用户信息列表
+ ///
+ public string? UserInfoList { get; set; }
+
+ ///
+ /// 时延阈值数
+ ///
+ public int LatencyThresholdCount { get; set; }
+
+ ///
+ /// 时延阈值列表
+ ///
+ public string? LatencyThresholdList { get; set; }
+
+ ///
+ /// 吞吐量阈值数
+ ///
+ public int ThroughputThresholdCount { get; set; }
+
+ ///
+ /// 吞吐量阈值列表
+ ///
+ public string? ThroughputThresholdList { get; set; }
+
+ ///
+ /// 用例说明
+ ///
+ public string? Description { get; set; }
+
+ ///
+ /// 用例版本
+ ///
+ public string Version { get; set; } = null!;
+
+ ///
+ /// 版本更新信息
+ ///
+ public string? VersionUpdateInfo { get; set; }
+
+ ///
+ /// 是否禁用
+ ///
+ public bool IsDisabled { get; set; }
+
+ ///
+ /// 备注
+ ///
+ public string? Remarks { get; set; }
+
+ ///
+ /// 创建时间
+ ///
+ public DateTime CreatedAt { get; set; }
+
+ ///
+ /// 创建人
+ ///
+ public string CreatedBy { get; set; } = null!;
+
+ ///
+ /// 更新时间
+ ///
+ public DateTime? UpdatedAt { get; set; }
+
+ ///
+ /// 修改人
+ ///
+ public string? UpdatedBy { get; set; }
+}
\ No newline at end of file
diff --git a/src/X1.Domain/Entities/Device/TestCase.cs b/src/X1.Domain/Entities/Device/TestCase.cs
new file mode 100644
index 0000000..6b7adc0
--- /dev/null
+++ b/src/X1.Domain/Entities/Device/TestCase.cs
@@ -0,0 +1,205 @@
+using System.ComponentModel.DataAnnotations;
+using CellularManagement.Domain.Entities.Common;
+
+namespace CellularManagement.Domain.Entities.Device;
+
+///
+/// 用例实体
+///
+public class TestCase : AuditableEntity
+{
+ private TestCase() { }
+
+ ///
+ /// 用例编码
+ ///
+ [Required]
+ [MaxLength(50)]
+ public string Code { get; private set; } = null!;
+
+ ///
+ /// 用例名称
+ ///
+ [Required]
+ [MaxLength(100)]
+ public string Name { get; private set; } = null!;
+
+ ///
+ /// 用户数
+ ///
+ public int UserCount { get; private set; } = 0;
+
+ ///
+ /// 用户信息列表(JSON格式存储)
+ ///
+ [MaxLength(4000)]
+ public string? UserInfoList { get; private set; }
+
+ ///
+ /// 时延阈值数
+ ///
+ public int LatencyThresholdCount { get; private set; } = 0;
+
+ ///
+ /// 时延阈值列表(JSON格式存储)
+ ///
+ [MaxLength(2000)]
+ public string? LatencyThresholdList { get; private set; }
+
+ ///
+ /// 吞吐量阈值数
+ ///
+ public int ThroughputThresholdCount { get; private set; } = 0;
+
+ ///
+ /// 吞吐量阈值列表(JSON格式存储)
+ ///
+ [MaxLength(2000)]
+ public string? ThroughputThresholdList { get; private set; }
+
+ ///
+ /// 用例说明
+ ///
+ [MaxLength(1000)]
+ public string? Description { get; private set; }
+
+ ///
+ /// 用例版本
+ ///
+ [Required]
+ [MaxLength(20)]
+ public string Version { get; private set; } = null!;
+
+ ///
+ /// 版本更新信息
+ ///
+ [MaxLength(500)]
+ public string? VersionUpdateInfo { get; private set; }
+
+ ///
+ /// 是否禁用
+ ///
+ public bool IsDisabled { get; private set; } = false;
+
+ ///
+ /// 备注
+ ///
+ [MaxLength(1000)]
+ public string? Remarks { get; private set; }
+
+ ///
+ /// 创建用例
+ ///
+ public static TestCase Create(
+ string code,
+ string name,
+ string version,
+ string createdBy,
+ int userCount = 0,
+ string? userInfoList = null,
+ int latencyThresholdCount = 0,
+ string? latencyThresholdList = null,
+ int throughputThresholdCount = 0,
+ string? throughputThresholdList = null,
+ string? description = null,
+ string? versionUpdateInfo = null,
+ bool isDisabled = false,
+ string? remarks = null)
+ {
+ var testCase = new TestCase
+ {
+ Id = Guid.NewGuid().ToString(),
+ Code = code,
+ Name = name,
+ Version = version,
+ UserCount = userCount,
+ UserInfoList = userInfoList,
+ LatencyThresholdCount = latencyThresholdCount,
+ LatencyThresholdList = latencyThresholdList,
+ ThroughputThresholdCount = throughputThresholdCount,
+ ThroughputThresholdList = throughputThresholdList,
+ Description = description,
+ VersionUpdateInfo = versionUpdateInfo,
+ IsDisabled = isDisabled,
+ Remarks = remarks,
+ CreatedAt = DateTime.UtcNow,
+ UpdatedAt = DateTime.UtcNow,
+ CreatedBy = createdBy,
+ UpdatedBy = createdBy
+ };
+
+ return testCase;
+ }
+
+ ///
+ /// 更新用例
+ ///
+ public void Update(
+ string code,
+ string name,
+ string version,
+ string updatedBy,
+ int userCount = 0,
+ string? userInfoList = null,
+ int latencyThresholdCount = 0,
+ string? latencyThresholdList = null,
+ int throughputThresholdCount = 0,
+ string? throughputThresholdList = null,
+ string? description = null,
+ string? versionUpdateInfo = null,
+ bool isDisabled = false,
+ string? remarks = null)
+ {
+ Code = code;
+ Name = name;
+ Version = version;
+ UserCount = userCount;
+ UserInfoList = userInfoList;
+ LatencyThresholdCount = latencyThresholdCount;
+ LatencyThresholdList = latencyThresholdList;
+ ThroughputThresholdCount = throughputThresholdCount;
+ ThroughputThresholdList = throughputThresholdList;
+ Description = description;
+ VersionUpdateInfo = versionUpdateInfo;
+ IsDisabled = isDisabled;
+ Remarks = remarks;
+ UpdatedAt = DateTime.UtcNow;
+ UpdatedBy = updatedBy;
+ }
+
+ ///
+ /// 启用用例
+ ///
+ public void Enable()
+ {
+ IsDisabled = false;
+ UpdatedAt = DateTime.UtcNow;
+ }
+
+ ///
+ /// 禁用用例
+ ///
+ public void Disable()
+ {
+ IsDisabled = true;
+ UpdatedAt = DateTime.UtcNow;
+ }
+
+ ///
+ /// 软删除用例
+ ///
+ public void SoftDelete()
+ {
+ IsDeleted = true;
+ UpdatedAt = DateTime.UtcNow;
+ }
+
+ ///
+ /// 恢复用例
+ ///
+ public void Restore()
+ {
+ IsDeleted = false;
+ UpdatedAt = DateTime.UtcNow;
+ }
+}
\ No newline at end of file
diff --git a/src/X1.Domain/Repositories/Device/ITestCaseRepository.cs b/src/X1.Domain/Repositories/Device/ITestCaseRepository.cs
new file mode 100644
index 0000000..e7e088b
--- /dev/null
+++ b/src/X1.Domain/Repositories/Device/ITestCaseRepository.cs
@@ -0,0 +1,73 @@
+using CellularManagement.Domain.Entities;
+using CellularManagement.Domain.Entities.Device;
+using CellularManagement.Domain.Repositories.Base;
+
+namespace CellularManagement.Domain.Repositories.Device;
+
+///
+/// 用例仓储接口
+///
+public interface ITestCaseRepository : IBaseRepository
+{
+ ///
+ /// 添加用例
+ ///
+ Task AddTestCaseAsync(TestCase testCase, CancellationToken cancellationToken = default);
+
+ ///
+ /// 更新用例
+ ///
+ void UpdateTestCase(TestCase testCase);
+
+ ///
+ /// 删除用例
+ ///
+ Task DeleteTestCaseAsync(string id, CancellationToken cancellationToken = default);
+
+ ///
+ /// 获取所有用例
+ ///
+ Task> GetAllTestCasesAsync(CancellationToken cancellationToken = default);
+
+ ///
+ /// 根据ID获取用例
+ ///
+ Task GetTestCaseByIdAsync(string id, CancellationToken cancellationToken = default);
+
+ ///
+ /// 根据编码获取用例
+ ///
+ Task GetTestCaseByCodeAsync(string code, CancellationToken cancellationToken = default);
+
+ ///
+ /// 根据版本获取用例
+ ///
+ Task GetTestCaseByVersionAsync(string version, CancellationToken cancellationToken = default);
+
+ ///
+ /// 搜索用例
+ ///
+ Task> SearchTestCasesAsync(
+ string? keyword,
+ CancellationToken cancellationToken = default);
+
+ ///
+ /// 检查用例是否存在
+ ///
+ Task ExistsAsync(string id, CancellationToken cancellationToken = default);
+
+ ///
+ /// 检查编码是否存在
+ ///
+ Task CodeExistsAsync(string code, CancellationToken cancellationToken = default);
+
+ ///
+ /// 检查版本是否存在
+ ///
+ Task VersionExistsAsync(string version, CancellationToken cancellationToken = default);
+
+ ///
+ /// 获取启用的用例
+ ///
+ Task> GetEnabledTestCasesAsync(CancellationToken cancellationToken = default);
+}
\ No newline at end of file
diff --git a/src/X1.Infrastructure/Configurations/Device/TestCaseConfiguration.cs b/src/X1.Infrastructure/Configurations/Device/TestCaseConfiguration.cs
new file mode 100644
index 0000000..221803b
--- /dev/null
+++ b/src/X1.Infrastructure/Configurations/Device/TestCaseConfiguration.cs
@@ -0,0 +1,94 @@
+using Microsoft.EntityFrameworkCore;
+using Microsoft.EntityFrameworkCore.Metadata.Builders;
+using CellularManagement.Domain.Entities.Device;
+
+namespace CellularManagement.Infrastructure.Configurations.Device;
+
+///
+/// 用例数据库配置
+///
+public class TestCaseConfiguration : IEntityTypeConfiguration
+{
+ ///
+ /// 配置用例实体
+ ///
+ public void Configure(EntityTypeBuilder builder)
+ {
+ // 表名
+ builder.ToTable("TestCases");
+
+ // 主键
+ builder.HasKey(x => x.Id);
+
+ // 属性配置
+ builder.Property(x => x.Id)
+ .HasMaxLength(50)
+ .IsRequired();
+
+ builder.Property(x => x.Code)
+ .HasMaxLength(50)
+ .IsRequired();
+
+ builder.Property(x => x.Name)
+ .HasMaxLength(100)
+ .IsRequired();
+
+ builder.Property(x => x.UserCount)
+ .IsRequired()
+ .HasDefaultValue(0);
+
+ builder.Property(x => x.UserInfoList)
+ .HasMaxLength(4000);
+
+ builder.Property(x => x.LatencyThresholdCount)
+ .IsRequired()
+ .HasDefaultValue(0);
+
+ builder.Property(x => x.LatencyThresholdList)
+ .HasMaxLength(2000);
+
+ builder.Property(x => x.ThroughputThresholdCount)
+ .IsRequired()
+ .HasDefaultValue(0);
+
+ builder.Property(x => x.ThroughputThresholdList)
+ .HasMaxLength(2000);
+
+ builder.Property(x => x.Description)
+ .HasMaxLength(1000);
+
+ builder.Property(x => x.Version)
+ .HasMaxLength(20)
+ .IsRequired();
+
+ builder.Property(x => x.VersionUpdateInfo)
+ .HasMaxLength(500);
+
+ builder.Property(x => x.IsDisabled)
+ .IsRequired()
+ .HasDefaultValue(false);
+
+ builder.Property(x => x.Remarks)
+ .HasMaxLength(1000);
+
+ // 索引
+ builder.HasIndex(x => x.Code)
+ .IsUnique()
+ .HasFilter("\"IsDeleted\" = false");
+
+ builder.HasIndex(x => x.Version)
+ .HasFilter("\"IsDeleted\" = false");
+
+ builder.HasIndex(x => x.Name)
+ .HasFilter("\"IsDeleted\" = false");
+
+ builder.HasIndex(x => x.IsDisabled)
+ .HasFilter("\"IsDeleted\" = false");
+
+ builder.HasIndex(x => x.CreatedAt)
+ .HasFilter("\"IsDeleted\" = false");
+
+ // 软删除过滤器
+ builder.HasQueryFilter(x => !x.IsDeleted);
+ }
+}
\ No newline at end of file
diff --git a/src/X1.Infrastructure/Context/AppDbContext.cs b/src/X1.Infrastructure/Context/AppDbContext.cs
index 5481590..7235fab 100644
--- a/src/X1.Infrastructure/Context/AppDbContext.cs
+++ b/src/X1.Infrastructure/Context/AppDbContext.cs
@@ -61,6 +61,11 @@ public class AppDbContext : IdentityDbContext
///
public DbSet TestCaseSets { get; set; } = null!;
+ ///
+ /// 用例集合
+ ///
+ public DbSet TestCases { get; set; } = null!;
+
///
/// 初始化数据库上下文
///
diff --git a/src/X1.Infrastructure/DependencyInjection.cs b/src/X1.Infrastructure/DependencyInjection.cs
index 0dccb9e..369dd5e 100644
--- a/src/X1.Infrastructure/DependencyInjection.cs
+++ b/src/X1.Infrastructure/DependencyInjection.cs
@@ -177,6 +177,7 @@ public static class DependencyInjection
services.AddScoped();
services.AddScoped();
services.AddScoped();
+ services.AddScoped();
return services;
}
diff --git a/src/X1.Infrastructure/Repositories/Device/TestCaseRepository.cs b/src/X1.Infrastructure/Repositories/Device/TestCaseRepository.cs
new file mode 100644
index 0000000..aa58f5e
--- /dev/null
+++ b/src/X1.Infrastructure/Repositories/Device/TestCaseRepository.cs
@@ -0,0 +1,149 @@
+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 TestCaseRepository : BaseRepository, ITestCaseRepository
+{
+ private readonly ILogger _logger;
+
+ ///
+ /// 初始化仓储
+ ///
+ public TestCaseRepository(
+ ICommandRepository commandRepository,
+ IQueryRepository queryRepository,
+ ILogger logger)
+ : base(commandRepository, queryRepository, logger)
+ {
+ _logger = logger;
+ }
+
+ ///
+ /// 添加用例
+ ///
+ public async Task AddTestCaseAsync(TestCase testCase, CancellationToken cancellationToken = default)
+ {
+ var result = await CommandRepository.AddAsync(testCase, cancellationToken);
+ return result;
+ }
+
+ ///
+ /// 更新用例
+ ///
+ public void UpdateTestCase(TestCase testCase)
+ {
+ CommandRepository.Update(testCase);
+ }
+
+ ///
+ /// 删除用例
+ ///
+ public async Task DeleteTestCaseAsync(string id, CancellationToken cancellationToken = default)
+ {
+ await CommandRepository.DeleteByIdAsync(id, cancellationToken);
+ }
+
+ ///
+ /// 获取所有用例
+ ///
+ public async Task> GetAllTestCasesAsync(CancellationToken cancellationToken = default)
+ {
+ var testCases = await QueryRepository.GetAllAsync(cancellationToken: cancellationToken);
+ return testCases.ToList();
+ }
+
+ ///
+ /// 根据ID获取用例
+ ///
+ public async Task GetTestCaseByIdAsync(string id, CancellationToken cancellationToken = default)
+ {
+ return await QueryRepository.GetByIdAsync(id, cancellationToken: cancellationToken);
+ }
+
+ ///
+ /// 根据编码获取用例
+ ///
+ public async Task GetTestCaseByCodeAsync(string code, CancellationToken cancellationToken = default)
+ {
+ return await QueryRepository.FirstOrDefaultAsync(tc => tc.Code == code, cancellationToken: cancellationToken);
+ }
+
+ ///
+ /// 根据版本获取用例
+ ///
+ public async Task GetTestCaseByVersionAsync(string version, CancellationToken cancellationToken = default)
+ {
+ return await QueryRepository.FirstOrDefaultAsync(tc => tc.Version == version, cancellationToken: cancellationToken);
+ }
+
+ ///
+ /// 搜索用例
+ ///
+ public async Task> SearchTestCasesAsync(
+ string? keyword,
+ CancellationToken cancellationToken = default)
+ {
+ var query = await QueryRepository.FindAsync(tc => true, cancellationToken: cancellationToken);
+
+ if (!string.IsNullOrWhiteSpace(keyword))
+ {
+ query = query.Where(tc =>
+ tc.Name.Contains(keyword) ||
+ tc.Code.Contains(keyword) ||
+ tc.Version.Contains(keyword) ||
+ (tc.Description != null && tc.Description.Contains(keyword)) ||
+ (tc.VersionUpdateInfo != null && tc.VersionUpdateInfo.Contains(keyword)) ||
+ (tc.Remarks != null && tc.Remarks.Contains(keyword)));
+ }
+
+ var testCases = query;
+ return testCases.ToList();
+ }
+
+ ///
+ /// 检查用例是否存在
+ ///
+ public async Task ExistsAsync(string id, CancellationToken cancellationToken = default)
+ {
+ return await QueryRepository.AnyAsync(tc => tc.Id == id, cancellationToken: cancellationToken);
+ }
+
+ ///
+ /// 检查编码是否存在
+ ///
+ public async Task CodeExistsAsync(string code, CancellationToken cancellationToken = default)
+ {
+ return await QueryRepository.AnyAsync(tc => tc.Code == code, cancellationToken: cancellationToken);
+ }
+
+ ///
+ /// 检查版本是否存在
+ ///
+ public async Task VersionExistsAsync(string version, CancellationToken cancellationToken = default)
+ {
+ return await QueryRepository.AnyAsync(tc => tc.Version == version, cancellationToken: cancellationToken);
+ }
+
+ ///
+ /// 获取启用的用例
+ ///
+ public async Task> GetEnabledTestCasesAsync(CancellationToken cancellationToken = default)
+ {
+ var testCases = await QueryRepository.FindAsync(tc => !tc.IsDisabled, cancellationToken: cancellationToken);
+ return testCases.ToList();
+ }
+}
\ No newline at end of file
diff --git a/src/X1.Presentation/Controllers/TestCasesController.cs b/src/X1.Presentation/Controllers/TestCasesController.cs
new file mode 100644
index 0000000..4a79ed3
--- /dev/null
+++ b/src/X1.Presentation/Controllers/TestCasesController.cs
@@ -0,0 +1,169 @@
+using CellularManagement.Application.Features.TestCases.Commands.CreateTestCase;
+using CellularManagement.Application.Features.TestCases.Commands.DeleteTestCase;
+using CellularManagement.Application.Features.TestCases.Commands.DisableTestCase;
+using CellularManagement.Application.Features.TestCases.Commands.EnableTestCase;
+using CellularManagement.Application.Features.TestCases.Commands.UpdateTestCase;
+using CellularManagement.Application.Features.TestCases.Queries.GetTestCaseById;
+using CellularManagement.Application.Features.TestCases.Queries.GetTestCases;
+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;
+
+///
+/// 用例控制器
+///
+[ApiController]
+[Route("api/[controller]")]
+[Authorize]
+public class TestCasesController : ApiController
+{
+ private readonly ILogger _logger;
+
+ ///
+ /// 初始化控制器
+ ///
+ public TestCasesController(IMediator mediator, ILogger logger)
+ : base(mediator)
+ {
+ _logger = logger;
+ }
+
+ ///
+ /// 获取用例列表
+ ///
+ [HttpGet]
+ public async Task GetList([FromQuery] string? keyword)
+ {
+ _logger.LogInformation("开始获取用例列表,搜索关键词: {Keyword}", keyword ?? "无");
+
+ var result = await mediator.Send(new GetTestCasesQuery { Keyword = keyword });
+
+ _logger.LogInformation("成功获取用例列表,总数: {TotalCount}", result.TotalCount);
+ return result;
+ }
+
+ ///
+ /// 获取用例详情
+ ///
+ [HttpGet("{id}")]
+ public async Task GetById(string id)
+ {
+ _logger.LogInformation("开始获取用例详情,用例ID: {TestCaseId}", id);
+
+ var result = await mediator.Send(new GetTestCaseByIdQuery { Id = id });
+ if (result == null)
+ {
+ _logger.LogWarning("用例不存在: {TestCaseId}", id);
+ return null;
+ }
+
+ _logger.LogInformation("成功获取用例详情,用例ID: {TestCaseId}", id);
+ return result;
+ }
+
+ ///
+ /// 创建用例
+ ///
+ [HttpPost]
+ public async Task> Create([FromBody] CreateTestCaseCommand command)
+ {
+ _logger.LogInformation("开始创建用例,用例编码: {Code}, 用例名称: {Name}, 版本: {Version}", command.Code, command.Name, command.Version);
+
+ var result = await mediator.Send(command);
+ if (!result.IsSuccess)
+ {
+ _logger.LogWarning("创建用例失败: {Message}", result.ErrorMessages);
+ return result;
+ }
+
+ _logger.LogInformation("成功创建用例,用例ID: {TestCaseId}", result.Data?.TestCaseId);
+ return result;
+ }
+
+ ///
+ /// 更新用例
+ ///
+ [HttpPut("{id}")]
+ public async Task> Update(string id, [FromBody] UpdateTestCaseCommand command)
+ {
+ _logger.LogInformation("开始更新用例,用例ID: {TestCaseId}", id);
+
+ if (id != command.TestCaseId)
+ {
+ _logger.LogWarning("用例ID不匹配,路径ID: {PathId}, 命令ID: {CommandId}", id, command.TestCaseId);
+ return OperationResult.CreateFailure("用例ID不匹配");
+ }
+
+ var result = await mediator.Send(command);
+ if (!result.IsSuccess)
+ {
+ _logger.LogWarning("更新用例失败: {Message}", result.ErrorMessages);
+ return result;
+ }
+
+ _logger.LogInformation("成功更新用例,用例ID: {TestCaseId}", id);
+ return result;
+ }
+
+ ///
+ /// 删除用例
+ ///
+ [HttpDelete("{id}")]
+ public async Task> Delete(string id)
+ {
+ _logger.LogInformation("开始删除用例,用例ID: {TestCaseId}", id);
+
+ var result = await mediator.Send(new DeleteTestCaseCommand { TestCaseId = id });
+ if (!result.IsSuccess)
+ {
+ _logger.LogWarning("删除用例失败: {Message}", result.ErrorMessages);
+ return result;
+ }
+
+ _logger.LogInformation("成功删除用例,用例ID: {TestCaseId}", id);
+ return result;
+ }
+
+ ///
+ /// 启用用例
+ ///
+ [HttpPost("{id}/enable")]
+ public async Task> Enable(string id)
+ {
+ _logger.LogInformation("开始启用用例,用例ID: {TestCaseId}", id);
+
+ var result = await mediator.Send(new EnableTestCaseCommand { TestCaseId = id });
+ if (!result.IsSuccess)
+ {
+ _logger.LogWarning("启用用例失败: {Message}", result.ErrorMessages);
+ return result;
+ }
+
+ _logger.LogInformation("成功启用用例,用例ID: {TestCaseId}", id);
+ return result;
+ }
+
+ ///
+ /// 禁用用例
+ ///
+ [HttpPost("{id}/disable")]
+ public async Task> Disable(string id)
+ {
+ _logger.LogInformation("开始禁用用例,用例ID: {TestCaseId}", id);
+
+ var result = await mediator.Send(new DisableTestCaseCommand { TestCaseId = id });
+ if (!result.IsSuccess)
+ {
+ _logger.LogWarning("禁用用例失败: {Message}", result.ErrorMessages);
+ return result;
+ }
+
+ _logger.LogInformation("成功禁用用例,用例ID: {TestCaseId}", id);
+ return result;
+ }
+}
\ No newline at end of file