ExecuteRobotSubTaskCommandHandler.cs 4.4 KB
using MassTransit;
using Microsoft.Extensions.Logging;
using Rcs.Application.Common;
using Rcs.Application.Services;
using Rcs.Application.Services.Protocol;
using Rcs.Application.MessageBus.Commands;
using Rcs.Domain.Repositories;
using Rcs.Infrastructure.PathFinding.Services;
using TaskStatus = Rcs.Domain.Entities.TaskStatus;

namespace Rcs.Infrastructure.MessageBus.Handlers.Commands;

/// <summary>
/// 执行子任务命令处理器
/// 处理逻辑与 SubTaskCompletedDomainEventHandler 中前置清理保持一致:
/// 清理 VDA 路径缓存、清空机器人缓存 Path、释放交通控制锁
/// </summary>
public class ExecuteRobotSubTaskCommandHandler : IConsumer<ExecuteRobotSubTaskCommand>
{
    private readonly ILogger<ExecuteRobotSubTaskCommandHandler> _logger;
    private readonly IRobotSubTaskRepository _robotSubTaskRepository;
    private readonly IRobotTaskRepository _robotTaskRepository;
    private readonly IRobotRepository _robotRepository;
    private readonly IRobotCacheService _robotCacheService;
    private readonly AgvPathService _agvPathService;
    private readonly IProtocolServiceFactory _protocolServiceFactory;

    public ExecuteRobotSubTaskCommandHandler(
        ILogger<ExecuteRobotSubTaskCommandHandler> logger,
        IRobotSubTaskRepository robotSubTaskRepository,
        IRobotTaskRepository robotTaskRepository,
        IRobotRepository robotRepository,
        IRobotCacheService robotCacheService,
        AgvPathService agvPathService,
        IProtocolServiceFactory protocolServiceFactory)
    {
        _logger = logger;
        _robotSubTaskRepository = robotSubTaskRepository;
        _robotTaskRepository = robotTaskRepository;
        _robotRepository = robotRepository;
        _robotCacheService = robotCacheService;
        _agvPathService = agvPathService;
        _protocolServiceFactory = protocolServiceFactory;
    }

    public async Task Consume(ConsumeContext<ExecuteRobotSubTaskCommand> context)
    {
        var command = context.Message;
        try
        {
            var subTask = await _robotSubTaskRepository.GetByIdWithDetailsAsync(command.SubTaskId, context.CancellationToken);
            if (subTask == null)
            {
                await context.RespondAsync(ApiResponse.Failed($"未找到子任务ID为 {command.SubTaskId} 的任务"));
                return;
            }

            var robotId = subTask.RobotId ?? Guid.Empty;

            try
            {
                if (robotId != Guid.Empty)
                {
                    var robot = await _robotRepository.GetByIdAsync(robotId, context.CancellationToken);
                    if (robot != null)
                    {
                        var protocolService = _protocolServiceFactory.GetService(robot);
                        await protocolService.CancelRobotTasksAsync(robot);
                    }
                    else
                    {
                        _logger.LogWarning("[执行子任务] 清理VDA路径缓存失败,机器人不存在: RobotId={RobotId}, SubTaskId={SubTaskId}",
                            robotId, command.SubTaskId);
                    }
                }
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "[执行子任务] 清理VDA路径缓存异常: RobotId={RobotId}, SubTaskId={SubTaskId}",
                    robotId, command.SubTaskId);
            }

            // 将当前子任务与父任务恢复为等待中,便于重新调度执行
            subTask.Status = TaskStatus.Pending;
            subTask.UpdatedAt = DateTime.Now;

            // var task = subTask.Task ?? await _robotTaskRepository.GetByIdAsync(subTask.TaskId, context.CancellationToken);
            // if (task != null)
            // {
            //     task.Status = TaskStatus.Pending;
            //     task.UpdatedAt = DateTime.Now;
            //     await _robotTaskRepository.UpdateAsync(task, context.CancellationToken);
            // }

            await _robotSubTaskRepository.UpdateAsync(subTask, context.CancellationToken);
            // await _robotSubTaskRepository.SaveChangesAsync(context.CancellationToken);

            await context.RespondAsync(ApiResponse.Successful("执行成功"));
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "执行子任务失败: SubTaskId={SubTaskId}", command.SubTaskId);
            await context.RespondAsync(ApiResponse.Failed(ex.Message));
        }
    }
}