SyncMapResourceCommandHandler.cs 3.99 KB
using MassTransit;
using MassTransit.Mediator;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using Rcs.Application.Common;
using Rcs.Application.MessageBus.Commands;
using Rcs.Application.Shared;
using Rcs.Cyaninetech.Services;
using Rcs.Domain.Extensions;
using Rcs.Domain.Repositories;
using Rcs.Domain.Settings;

namespace Rcs.Infrastructure.MessageBus.Handlers.Commands;

/// <summary>
/// 同步地图资源命令处理器
/// @author zzy
/// </summary>
public class SyncMapResourceCommandHandler : IConsumer<SyncMapResourceCommand>
{
    private readonly ILogger<SyncMapResourceCommandHandler> _logger;
    private readonly IMapRepository _mapRepository;
    private readonly ILanYinService _lanYinService;
    private readonly IHttpClientService _httpClientService;
    private readonly LanYinSettings _lanYinSettings;
    private readonly IMediator _mediator;

    public SyncMapResourceCommandHandler(
        ILogger<SyncMapResourceCommandHandler> logger,
        IMapRepository mapRepository,
        ILanYinService lanYinService,
        IHttpClientService httpClientService,
        IOptions<AppSettings> setting,
        IMediator mediator)
    {
        _logger = logger;
        _mapRepository = mapRepository;
        _lanYinService = lanYinService;
        _httpClientService = httpClientService;
        _lanYinSettings = setting.Value.LanYinSettings;
        _mediator = mediator;
    }

    public async Task Consume(ConsumeContext<SyncMapResourceCommand> context)
    {
        var command = context.Message;

        try
        {
            var map = await _mapRepository.GetByIdAsync(command.MapId, context.CancellationToken);
            if (map == null)
            {
                await context.RespondAsync(ApiResponse.Failed($"未找到ID为 {command.MapId} 的地图"));
                return;
            }

            if (string.IsNullOrWhiteSpace(map.ResourceUrl))
                throw new BusinessException("请先维护资源URL");

            // 获取地图资源信息
            var mapInfo = await _lanYinService.SyncMapResource(map.ResourceUrl);

            // 下载并上传地图图片
            if (!string.IsNullOrWhiteSpace(mapInfo.jpg_url))
            {
                var imageUrl = _lanYinSettings.BaseUrl + mapInfo.jpg_url;
                _logger.LogInformation("开始下载地图图片: {Url}", imageUrl);

                using var imageStream = await _httpClientService.DownloadStreamAsync(imageUrl, null, context.CancellationToken);
                var fileName = Path.GetFileName(mapInfo.jpg_url) ?? $"map_{command.MapId}.jpg";

                // 通过Mediator发送上传命令
                var uploadClient = _mediator.CreateRequestClient<UploadMapFileCommand>();
                var uploadResponse = await uploadClient.GetResponse<ApiResponse>(new UploadMapFileCommand
                {
                    MapId = command.MapId.ToString(),
                    FileStream = imageStream,
                    FileName = fileName,
                    FileSize = imageStream.Length,
                    Scale = (mapInfo?.resolution ?? 1) * 1000,
                    OffsetX = (mapInfo?.origin?.x ?? 0) * 1000,
                    OffsetY = (mapInfo?.origin?.y ?? 0) * 1000,
                    Rotation = mapInfo?.origin?.rad ?? 0,
                }, context.CancellationToken);

                if (!uploadResponse.Message.Success)
                {
                    throw new BusinessException($"上传地图图片失败: {uploadResponse.Message.Message}");
                }

                _logger.LogInformation("地图图片上传成功: MapId={MapId}, FileName={FileName}", command.MapId, fileName);
            }
            
            await context.RespondAsync(ApiResponse.Successful("同步地图资源成功"));
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "同步地图资源失败: MapId={MapId}", command.MapId);
            await context.RespondAsync(ApiResponse.Failed($"同步失败: {ex.Message}"));
        }
    }
}