CreateOrUpdateRobotTaskCommandHandler.cs 5.87 KB
using MassTransit;
using Microsoft.Extensions.Logging;
using Rcs.Application.Common;
using Rcs.Application.MessageBus.Commands;
using Rcs.Domain.Entities;
using Rcs.Domain.Repositories;
using TaskStatus = Rcs.Domain.Entities.TaskStatus;

namespace Rcs.Infrastructure.MessageBus.Handlers.Commands;

/// <summary>
/// 创建或更新任务命令处理器
/// @author zzy
/// </summary>
public class CreateOrUpdateRobotTaskCommandHandler : IConsumer<CreateOrUpdateRobotTaskCommand>
{
    private readonly ILogger<CreateOrUpdateRobotTaskCommandHandler> _logger;
    private readonly IRobotTaskRepository _robotTaskRepository;
    private readonly IRobotRepository _robotRepository;
    private readonly ITaskTemplateRepository _taskTemplateRepository;
    private readonly IStorageLocationRepository _storageLocationRepository;

    public CreateOrUpdateRobotTaskCommandHandler(
        ILogger<CreateOrUpdateRobotTaskCommandHandler> logger,
        IRobotTaskRepository robotTaskRepository,
        IRobotRepository robotRepository,
        ITaskTemplateRepository taskTemplateRepository,
        IStorageLocationRepository storageLocationRepository)
    {
        _logger = logger;
        _robotTaskRepository = robotTaskRepository;
        _robotRepository = robotRepository;
        _taskTemplateRepository = taskTemplateRepository;
        _storageLocationRepository = storageLocationRepository;
    }

    public async Task Consume(ConsumeContext<CreateOrUpdateRobotTaskCommand> context)
    {
        var command = context.Message;
        try
        {
            // 验证机器人(可选)
            Guid? robotId = null;
            if (!string.IsNullOrWhiteSpace(command.RobotId))
            {
                if (!Guid.TryParse(command.RobotId, out Guid parsedRobotId))
                {
                    throw new InvalidOperationException("无效的机器人ID格式");
                }
                var robot = await _robotRepository.GetByIdAsync(parsedRobotId, context.CancellationToken);
                if (robot == null)
                {
                    throw new InvalidOperationException($"机器人ID {command.RobotId} 不存在");
                }
                robotId = parsedRobotId;
            }

            // 验证起点库位(可选)
            Guid? beginLocationId = null;
            if (!string.IsNullOrWhiteSpace(command.BeginLocationId))
            {
                if (!Guid.TryParse(command.BeginLocationId, out Guid parsedBeginLocationId))
                {
                    throw new InvalidOperationException("无效的起点库位ID格式");
                }
                var beginLocation = await _storageLocationRepository.GetByIdAsync(parsedBeginLocationId, context.CancellationToken);
                if (beginLocation == null)
                {
                    throw new InvalidOperationException($"起点库位ID {command.BeginLocationId} 不存在");
                }
                beginLocationId = parsedBeginLocationId;
            }

            // 验证终点库位(可选)
            Guid? endLocationId = null;
            if (!string.IsNullOrWhiteSpace(command.EndLocationId))
            {
                if (!Guid.TryParse(command.EndLocationId, out Guid parsedEndLocationId))
                {
                    throw new InvalidOperationException("无效的终点库位ID格式");
                }
                var endLocation = await _storageLocationRepository.GetByIdAsync(parsedEndLocationId, context.CancellationToken);
                if (endLocation == null)
                {
                    throw new InvalidOperationException($"终点库位ID {command.EndLocationId} 不存在");
                }
                endLocationId = parsedEndLocationId;
            }

            if (!Guid.TryParse(command.TaskId, out Guid taskId))
            {
                // 新建任务
                var existingCode = await _robotTaskRepository.GetByTaskCodeAsync(command.TaskCode, context.CancellationToken);
                if (existingCode != null)
                {
                    throw new InvalidOperationException($"任务编码 {command.TaskCode} 已存在");
                }

                var task = new RobotTask();
                task.Create(
                    command.TaskCode,
                    command.TaskName ?? command.TaskCode,
                    beginLocationId,
                    endLocationId,
                    command.Priority,
                    shelfCode: command.ShelfCode
                );
                if (robotId.HasValue)
                    task.Assign(robotId.Value);
                
                await _robotTaskRepository.AddAsync(task, context.CancellationToken);
            }
            else
            {
                // 更新任务
                var task = await _robotTaskRepository.GetByIdAsync(taskId, context.CancellationToken);
                if (task == null)
                {
                    throw new InvalidOperationException($"未找到任务ID为 {taskId} 的任务");
                }
                if (task.Status != TaskStatus.Pending || task.Status != TaskStatus.Assigned )
                {
                    throw new InvalidOperationException("仅允许更新待处理状态的任务");
                }
                task.RobotId = robotId;
                task.BeginLocationId = beginLocationId;
                task.EndLocationId = endLocationId;
                task.Priority = command.Priority;
                task.ShelfCode = command.ShelfCode;
                task.UpdatedAt = DateTime.Now;

                await _robotTaskRepository.UpdateAsync(task, context.CancellationToken);
            }

            await context.RespondAsync(ApiResponse.Successful());
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "创建或更新任务失败");
            await context.RespondAsync(ApiResponse.Failed(ex.Message));
        }
    }
}