using MediatR; using Microsoft.Extensions.Logging; using X1.Application.Features.TaskExecution.Events.NodeExecutionEvents; using X1.Domain.Events; using X1.Domain.Entities.TestCase; namespace X1.Application.Features.TaskExecution.Events.ControllerHandlers; /// /// 启动流程控制器处理器 /// 处理测试流程启动相关的节点执行事件 /// public class StartFlowControllerHandler : INotificationHandler { private readonly IMediator _mediator; private readonly ILogger _logger; /// /// 初始化启动流程控制器处理器 /// /// MediatR 中介者 /// 日志记录器 public StartFlowControllerHandler(IMediator mediator, ILogger logger) { _mediator = mediator; _logger = logger; } /// /// 处理启动流程节点执行事件 /// /// 节点执行事件 /// 取消令牌 /// 处理任务 public async Task Handle(StartFlowExecutionEvent notification, CancellationToken cancellationToken) { _logger.LogInformation("开始执行启动流程,任务执行ID: {TaskExecutionId}, 节点ID: {NodeId}, 运行时编码: {RuntimeCode}", notification.TaskExecutionId, notification.NodeId, notification.RuntimeCode); try { // 1. 更新节点状态为运行中 await UpdateNodeStatusAsync(notification.NodeId, NodeExecutionStatus.Running); // 2. 执行启动流程业务逻辑 var result = await ExecuteStartFlowAsync(notification, cancellationToken); // 3. 创建执行结果 var executionResult = new NodeExecutionResult { TaskExecutionId = notification.TaskExecutionId, NodeId = notification.NodeId, StepMapping = StepMapping.StartFlow, Status = NodeExecutionStatus.Completed, IsSuccess = true, ResultData = result, ExecutorId = notification.ExecutorId, RuntimeCode = notification.RuntimeCode, CreatedAt = DateTime.UtcNow }; // 4. 发布完成事件 await PublishCompletedEventAsync(notification, executionResult, cancellationToken); _logger.LogInformation("启动流程执行成功,任务执行ID: {TaskExecutionId}, 节点ID: {NodeId}", notification.TaskExecutionId, notification.NodeId); } catch (Exception ex) { _logger.LogError(ex, "启动流程执行失败,任务执行ID: {TaskExecutionId}, 节点ID: {NodeId}", notification.TaskExecutionId, notification.NodeId); // 发布失败事件 await PublishFailedEventAsync(notification, ex.Message, cancellationToken); } } /// /// 执行启动流程业务逻辑 /// /// 事件通知 /// 取消令牌 /// 执行结果 private async Task ExecuteStartFlowAsync(StartFlowExecutionEvent notification, CancellationToken cancellationToken) { // TODO: 实现具体的启动流程逻辑 // 这里应该调用实际的启动流程服务 _logger.LogInformation("正在执行启动流程,运行时编码: {RuntimeCode}", notification.RuntimeCode); // 模拟异步操作 await Task.Delay(500, cancellationToken); // 模拟成功结果 var result = new { Status = "Success", Message = "测试流程启动成功", Timestamp = DateTime.UtcNow, RuntimeCode = notification.RuntimeCode, FlowInitialized = true }; return System.Text.Json.JsonSerializer.Serialize(result); } /// /// 更新节点状态 /// /// 节点ID /// 新状态 /// 更新任务 private async Task UpdateNodeStatusAsync(string nodeId, NodeExecutionStatus status) { // TODO: 实现节点状态更新逻辑 // 这里应该更新数据库中的节点状态 _logger.LogInformation("更新节点状态,节点ID: {NodeId}, 新状态: {Status}", nodeId, status); // 模拟异步操作 await Task.CompletedTask; } /// /// 发布完成事件 /// /// 原始事件 /// 执行结果 /// 取消令牌 /// 发布任务 private async Task PublishCompletedEventAsync(StartFlowExecutionEvent notification, NodeExecutionResult result, CancellationToken cancellationToken) { var completedEvent = new NodeExecutionCompletedEvent { TaskExecutionId = notification.TaskExecutionId, NodeId = notification.NodeId, StepMapping = StepMapping.StartFlow, ExecutorId = notification.ExecutorId, RuntimeCode = notification.RuntimeCode, ScenarioCode = notification.ScenarioCode, ScenarioId = notification.ScenarioId, FlowName = notification.FlowName, FlowId = notification.FlowId, Result = result, Timestamp = DateTime.UtcNow }; await _mediator.Publish(completedEvent, cancellationToken); } /// /// 发布失败事件 /// /// 原始事件 /// 错误消息 /// 取消令牌 /// 发布任务 private async Task PublishFailedEventAsync(StartFlowExecutionEvent notification, string errorMessage, CancellationToken cancellationToken) { var failedEvent = new NodeExecutionFailedEvent { TaskExecutionId = notification.TaskExecutionId, NodeId = notification.NodeId, StepMapping = StepMapping.StartFlow, ExecutorId = notification.ExecutorId, RuntimeCode = notification.RuntimeCode, ScenarioCode = notification.ScenarioCode, ScenarioId = notification.ScenarioId, FlowName = notification.FlowName, FlowId = notification.FlowId, ErrorMessage = errorMessage, ErrorCode = "START_FLOW_ERROR", Timestamp = DateTime.UtcNow }; await _mediator.Publish(failedEvent, cancellationToken); } }