CreateOrUpdateActionConfigurationCommandHandler.cs 8.64 KB
using MassTransit;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Logging;
using Rcs.Application.Common;
using Rcs.Application.MessageBus.Commands;
using Rcs.Domain.Entities;
using Rcs.Domain.Enums;
using Rcs.Domain.Repositories;

namespace Rcs.Infrastructure.MessageBus.Handlers.Commands;

public class CreateOrUpdateActionConfigurationCommandHandler : IConsumer<CreateOrUpdateActionConfigurationCommand>
{
    private readonly ILogger<CreateOrUpdateActionConfigurationCommandHandler> _logger;
    private readonly IActionConfigurationRepository _repository;

    public CreateOrUpdateActionConfigurationCommandHandler(
        ILogger<CreateOrUpdateActionConfigurationCommandHandler> logger,
        IActionConfigurationRepository repository)
    {
        _logger = logger;
        _repository = repository;
    }

    public async Task Consume(ConsumeContext<CreateOrUpdateActionConfigurationCommand> context)
    {
        var command = context.Message;
        try
        {
            if (!Guid.TryParse(command.ActionConfigId, out Guid actionConfigId))
            {
                var existing = await _repository.GetByActionNameAsync(command.ActionName, context.CancellationToken);
                if (existing != null)
                {
                    throw new InvalidOperationException($"动作名称 {command.ActionName} 已存在");
                }

                var entity = new ActionConfiguration
                {
                    ActionConfigId = Guid.NewGuid(),
                    ActionCategory = (ActionCategory)command.ActionCategory,
                    ActionCategoryName = command.ActionCategoryName,
                    Manufacturer = command.Manufacturer,
                    RobotType = (RobotType)command.RobotType,
                    ActionName = command.ActionName,
                    ActionDescription = command.ActionDescription,
                    ExecutionScope = command.ExecutionScope,
                    BlockingType = (ActionBlockType)command.BlockingType,
                    IsEnabled = command.IsEnabled,
                    SortOrder = command.SortOrder,
                    Remarks = command.Remarks,
                    CreatedAt = DateTime.Now,
                    UpdatedAt = DateTime.Now
                };

                if (command.Parameters != null && command.Parameters.Count > 0)
                {
                    foreach (var paramDto in command.Parameters)
                    {
                        var param = new ActionParameterDefinition
                        {
                            ParamId = Guid.NewGuid(),
                            ActionConfigId = entity.ActionConfigId,
                            ParameterName = paramDto.ParameterName,
                            ParameterValueType = (ParameterValueType)paramDto.ParameterValueType,
                            ParameterDescription = paramDto.ParameterDescription,
                            IsMandatory = paramDto.IsMandatory,
                            DefaultValue = paramDto.DefaultValue,
                            ParameterSourceType = paramDto.ParameterSourceType.HasValue ? (ParameterSourceType)paramDto.ParameterSourceType.Value : null,
                            ParameterSourcePath = paramDto.ParameterSourcePath,
                            ValueConstraints = paramDto.ValueConstraints,
                            Remarks = paramDto.Remarks,
                            SortOrder = paramDto.SortOrder,
                            CreatedAt = DateTime.Now,
                            UpdatedAt = DateTime.Now
                        };
                        entity.Parameters.Add(param);
                    }
                }

                await _repository.AddAsync(entity, context.CancellationToken);
            }
            else
            {
                var entity = await _repository.GetWithParametersAsync(actionConfigId, context.CancellationToken);
                
                if (entity == null)
                {
                    throw new InvalidOperationException($"未找到ID为 {actionConfigId} 的动作配置");
                }

                entity.ActionCategory = (ActionCategory)command.ActionCategory;
                entity.ActionCategoryName = command.ActionCategoryName;
                entity.Manufacturer = command.Manufacturer;
                entity.RobotType = (RobotType)command.RobotType;
                entity.ActionName = command.ActionName;
                entity.ActionDescription = command.ActionDescription;
                entity.ExecutionScope = command.ExecutionScope;
                entity.BlockingType = (ActionBlockType)command.BlockingType;
                entity.IsEnabled = command.IsEnabled;
                entity.SortOrder = command.SortOrder;
                entity.Remarks = command.Remarks;
                entity.UpdatedAt = DateTime.Now;

                var existingParams = entity.Parameters.ToList();
                var commandParamIds = command.Parameters?
                    .Where(p => !string.IsNullOrEmpty(p.ParamId) && Guid.TryParse(p.ParamId, out _))
                    .Select(p => Guid.Parse(p.ParamId!))
                    .ToHashSet() ?? new HashSet<Guid>();

                foreach (var existingParam in existingParams)
                {
                    if (!commandParamIds.Contains(existingParam.ParamId))
                    {
                        entity.Parameters.Remove(existingParam);
                    }
                }

                if (command.Parameters != null)
                {
                    foreach (var paramDto in command.Parameters)
                    {
                        if (string.IsNullOrEmpty(paramDto.ParamId) || !Guid.TryParse(paramDto.ParamId, out Guid paramId))
                        {
                            var newParam = new ActionParameterDefinition
                            {
                                ParamId = Guid.NewGuid(),
                                ActionConfigId = entity.ActionConfigId,
                                ParameterName = paramDto.ParameterName,
                                ParameterValueType = (ParameterValueType)paramDto.ParameterValueType,
                                ParameterDescription = paramDto.ParameterDescription,
                                IsMandatory = paramDto.IsMandatory,
                                DefaultValue = paramDto.DefaultValue,
                                ParameterSourceType = paramDto.ParameterSourceType.HasValue ? (ParameterSourceType)paramDto.ParameterSourceType.Value : null,
                                ParameterSourcePath = paramDto.ParameterSourcePath,
                                ValueConstraints = paramDto.ValueConstraints,
                                Remarks = paramDto.Remarks,
                                SortOrder = paramDto.SortOrder,
                                CreatedAt = DateTime.Now,
                                UpdatedAt = DateTime.Now
                            };
                            entity.Parameters.Add(newParam);
                        }
                        else
                        {
                            var existingParam = entity.Parameters.FirstOrDefault(p => p.ParamId == paramId);
                            if (existingParam != null)
                            {
                                existingParam.ParameterName = paramDto.ParameterName;
                                existingParam.ParameterValueType = (ParameterValueType)paramDto.ParameterValueType;
                                existingParam.ParameterDescription = paramDto.ParameterDescription;
                                existingParam.IsMandatory = paramDto.IsMandatory;
                                existingParam.DefaultValue = paramDto.DefaultValue;
                                existingParam.ParameterSourceType = paramDto.ParameterSourceType.HasValue ? (ParameterSourceType)paramDto.ParameterSourceType.Value : null;
                                existingParam.ParameterSourcePath = paramDto.ParameterSourcePath;
                                existingParam.ValueConstraints = paramDto.ValueConstraints;
                                existingParam.Remarks = paramDto.Remarks;
                                existingParam.SortOrder = paramDto.SortOrder;
                                existingParam.UpdatedAt = DateTime.Now;
                            }
                        }
                    }
                }

                await _repository.UpdateAsync(entity, context.CancellationToken);
            }

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