CreateOrUpdateRobotCommandHandler.cs 6.51 KB
using MassTransit;
using Microsoft.Extensions.Logging;
using Rcs.Application.Common;
using Rcs.Application.MessageBus.Commands;
using Rcs.Domain.Entities;
using Rcs.Domain.Repositories;

namespace Rcs.Infrastructure.MessageBus.Handlers.Commands;

/// <summary>
/// 创建机器人命令处理器
/// @author zzy - 修改为使用ManufacturerId和RobotTypeId
/// </summary>
public class CreateOrUpdateRobotCommandHandler : IConsumer<CreateOrUpdateRobotCommand>
{
    private readonly ILogger<CreateOrUpdateRobotCommandHandler> _logger;
    private readonly IRobotRepository _robotRepository;
    private readonly IMapRepository _mapRepository;

    public CreateOrUpdateRobotCommandHandler(
        ILogger<CreateOrUpdateRobotCommandHandler> logger,
        IRobotRepository robotRepository,
        IMapRepository mapRepository)
    {
        _logger = logger;
        _robotRepository = robotRepository;
        _mapRepository = mapRepository;
    }

    public async Task Consume(ConsumeContext<CreateOrUpdateRobotCommand> context)
    {
        var command = context.Message;
        try
        {
            Map? existingMap = null;
            if (!string.IsNullOrWhiteSpace(command.CurrentMapCode))
            {
                existingMap = await _mapRepository.GetByMapCodeAsync(command.CurrentMapCode, context.CancellationToken);
                if (existingMap == null)
                {
                    throw new InvalidOperationException($"地图编码 {command.CurrentMapCode} 不存在");
                }
            }

            if (!Guid.TryParse(command.RobotId, out Guid robotId))
            {
                // 新建
                var existingCode = await _robotRepository.GetByRobotCodeAsync(command.RobotCode, context.CancellationToken);
                if (existingCode != null)
                {
                    throw new InvalidOperationException($"机器人编码 {command.RobotCode} 已存在");
                }

                var existingBySerial = await _robotRepository.GetBySerialNumberAsync(command.RobotSerialNumber, context.CancellationToken);
                if (existingBySerial != null)
                {
                    throw new InvalidOperationException($"机器人序列号 {command.RobotSerialNumber} 已存在");
                }

                var robot = new Robot
                {
                    RobotId = Guid.NewGuid(),
                    RobotCode = command.RobotCode,
                    RobotName = command.RobotName,
                    RobotVersion = command.RobotVersion,
                    ProtocolName = command.ProtocolName,
                    ProtocolVersion = command.ProtocolVersion,
                    ProtocolType = (ProtocolType)command.ProtocolType,
                    RobotManufacturer = command.RobotManufacturer,
                    RobotSerialNumber = command.RobotSerialNumber,
                    RobotType = (RobotType)command.RobotType,
                    IpAddress = command.IpAddress,
                    NetPort = command.NetPort,
                    MacAddress = command.MacAddress,
                    CoordinateScale = command.CoordinateScale,
                    PayloadCapacity = command.PayloadCapacity,
                    SpeedMax = command.SpeedMax,
                    SpeedMin = command.SpeedMin,
                    AccelerationMax = command.AccelerationMax,
                    DecelerationMax = command.DecelerationMax,
                    HeightMin = command.HeightMin,
                    HeightMax = command.HeightMax,
                    Width = command.Width,
                    Length = command.Length,
                    IsOmnidirectional = command.IsOmnidirectional,
                    Radius = command.Radius,
                    CurrentMapCodeId = existingMap?.MapId,
                    Active = command.Active,
                    MotionCenterToEdge = command.MotionCenterToEdge,
                    RobotModel = command.RobotModel,
                    Status = RobotStatus.Idle,
                    Online = OnlineStatus.Offline,
                    OperatingMode = OperatingMode.Automatic,
                    CreatedAt = DateTime.Now,
                    UpdatedAt = DateTime.Now
                };

                await _robotRepository.AddAsync(robot, context.CancellationToken);
            }
            else
            {
                // 更新
                var robot = await _robotRepository.GetByIdAsync(robotId, context.CancellationToken);
                if (robot == null)
                {
                    throw new InvalidOperationException($"未找到机器人ID为 {robotId} 的机器人");
                }

                robot.RobotCode = command.RobotCode;
                robot.RobotName = command.RobotName;
                robot.RobotVersion = command.RobotVersion;
                robot.ProtocolName = command.ProtocolName;
                robot.ProtocolVersion = command.ProtocolVersion;
                robot.ProtocolType = (ProtocolType)command.ProtocolType;
                robot.RobotManufacturer = command.RobotManufacturer;
                robot.RobotSerialNumber = command.RobotSerialNumber;
                robot.RobotType = (RobotType)command.RobotType;
                robot.IpAddress = command.IpAddress;
                robot.NetPort = command.NetPort;
                robot.MacAddress = command.MacAddress;
                robot.CoordinateScale = command.CoordinateScale;
                robot.PayloadCapacity = command.PayloadCapacity;
                robot.SpeedMax = command.SpeedMax;
                robot.SpeedMin = command.SpeedMin;
                robot.AccelerationMax = command.AccelerationMax;
                robot.DecelerationMax = command.DecelerationMax;
                robot.HeightMin = command.HeightMin;
                robot.HeightMax = command.HeightMax;
                robot.Width = command.Width;
                robot.Length = command.Length;
                robot.IsOmnidirectional = command.IsOmnidirectional;
                robot.Radius = command.Radius;
                robot.CurrentMapCodeId = existingMap?.MapId;
                robot.Active = command.Active;
                robot.MotionCenterToEdge = command.MotionCenterToEdge;
                robot.RobotModel = command.RobotModel;
                robot.UpdatedAt = DateTime.Now;

                await _robotRepository.UpdateAsync(robot, context.CancellationToken);
            }

            await context.RespondAsync(ApiResponse.Successful());
        }
        catch (Exception ex)
        {
            await context.RespondAsync(ApiResponse.Failed(ex.Message));
        }
    }
}