track/src/TrackCenter.Application/Rabbit/TrackPushCompletedEventHandler.cs
2026-02-26 15:45:00 +08:00

174 lines
6.5 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using System.Text;
using Fake.UnitOfWork;
using Newtonsoft.Json;
using RabbitMQ.Client.Events;
using TrackCenter.Application.Dtos.TrackPush;
using TrackCenter.Application.Helpers;
using TrackCenter.Application.Services.Broadcasting;
using TrackCenter.Application.Services.Warning.Handlers;
using TrackCenter.Domain.Aggregates.OrderAggregate;
using TrackCenter.Domain.Aggregates.TrackPushAggregate;
namespace TrackCenter.Application.Rabbit;
[ExposeServices(typeof(IRabbitHandler))]
public class TrackPushCompletedEventHandler : ITransientDependency, IRabbitHandler
{
private readonly IOrderRepository _orderRepository;
private readonly ITrackPushRecordEsRepository _trackPushRecordEsRepository;
private readonly BroadcastingService _broadcastingService;
private readonly IReturnWarningHandler _returnWarningHandler;
public TrackPushCompletedEventHandler(IOrderRepository orderRepository,
ITrackPushRecordEsRepository trackPushRecordEsRepository,
BroadcastingService broadcastingService, IReturnWarningHandler returnWarningHandler)
{
_orderRepository = orderRepository;
_trackPushRecordEsRepository = trackPushRecordEsRepository;
_broadcastingService = broadcastingService;
_returnWarningHandler = returnWarningHandler;
}
public bool Enable(ConsumeOptions options)
{
return options.Queue.StartsWith(GlobalConst.TrackPushCompletedSubscribe);
}
[UnitOfWork]
public virtual async Task Handle(BasicDeliverEventArgs args)
{
var msg = string.Empty;
try
{
msg = Encoding.UTF8.GetString(args.Body.ToArray());
var @event = System.Text.Json.JsonSerializer.Deserialize<InterfaceRelayForwardReplayEvent>(msg);
if (@event == null)
{
Log.Warning(
$"rabbit on queue received msg can't convert to {nameof(InterfaceRelayForwardReplayEvent)}");
return;
}
await ConsumerAsync(@event);
}
catch (Exception ex)
{
Log.Error($"TrackPushCompletedEventHandler出错,错误信息:{ex}\r\n-----\r\n消息:{msg}");
}
}
public async Task ConsumerAsync(InterfaceRelayForwardReplayEvent @event)
{
var optionType = Base64Helper.DeSerialize<string>(@event.Attach);
var pushInputs = new List<TrackPushInput>();
var updateInputs = new List<TrackUpdateInput>();
var isAdd = false;
// 有多少个订单推送,就有多少个TrackPushInput/TrackUpdateInput返回
// tips:以下处理认为只处理一个单的这次推送的情况
if (optionType == OptionType.新增.ToString())
{
pushInputs = JsonConvert.DeserializeObject<List<TrackPushInput>>(@event.RequestParams)!;
isAdd = true;
}
else if (optionType == OptionType.修改.ToString())
{
updateInputs = JsonConvert.DeserializeObject<List<TrackUpdateInput>>(@event.RequestParams)!;
}
var logJsons = pushInputs.Count != 0 ? pushInputs.Select(x => x.Log) : updateInputs.Select(x => x.Log);
var logs = new List<TrackPushRecordIndex>(pushInputs.Count + updateInputs.Count);
foreach (var logJson in logJsons)
{
if (logJson.IsNullOrEmpty()) throw new InvalidOperationException();
var log = JsonConvert.DeserializeObject<TrackPushRecordIndex>(logJson!);
if (log == null) throw new BusinessException(message: "轨迹推送返回结果解析异常");
log.IsSuccess = @event.IsSuccess;
log.Message = @event.Message;
log.RequestId = @event.RequestId;
logs.Add(log);
}
// 推送广播
if (logs.First().IsToMq)
_broadcastingService.TrackPushCompletedPublicTopic(logs.Select(log => BuildDto(log, @event.Data)).ToList());
// 写入推送日志
await _trackPushRecordEsRepository.AddManyAsync(logs);
// 同步更新订单主表
await TrackPushAfterUpdateOrderAsync(isAdd, @event.IsSuccess, logs);
// 引发预警计算
await _returnWarningHandler.ReceiveTrackPushRecordHandleAsync(@event.IsSuccess, @event.RequestParams, logs, pushInputs, updateInputs);
}
private async Task TrackPushAfterUpdateOrderAsync(bool isAdd, bool isSuccess, List<TrackPushRecordIndex> logs)
{
// 修改跳过
if (!isAdd) return;
if (!isSuccess)
{
// 最近一条推送失败
var orders = logs.Select(x => new OrderEntity
{
Id = x.OrderId,
QuestionType = TrackProblemType.Error,
LatestPushError = x.Message
}).ToList();
await _orderRepository.UpdateRangeAsync(orders, x => new
{
x.QuestionType,
x.LatestPushError
});
}
else
{
// 还原成正常态
var orders = logs.Select(x => new OrderEntity
{
Id = x.OrderId,
QuestionType = (int) TrackProblemType.None,
LatestPushError = null,
LatestPushTrackCode = x.TrackCode,
LatestPushTime = x.CreateTime,
}).ToList();
await _orderRepository.UpdateRangeAsync(orders, x => new
{
x.QuestionType,
x.LatestPushError,
x.LatestPushTrackCode,
x.LatestPushTime,
});
}
}
private static TrackPushRecordDto BuildDto(TrackPushRecordIndex log, string interfaceRelayData)
{
return new TrackPushRecordDto
{
AppKey = log.AppKey,
RequestId = log.RequestId,
IsSuccess = log.IsSuccess,
Message = log.Message,
OperationMan = log.CreateUser,
PushTime = DateTime.Now,
OptionType = log.OptionType,
IsManualPush = !string.Equals(log.CreateUser, GlobalConst.SystemUser), //操作人不为系统用户,则认为是人推送
PushContent = log.PushContent,
OrderNo = log.OrderNo,
TrackStatus = log.TrackStatus,
TrackContent = log.TrackContent,
TrackTimeZone = log.TrackTimeZone,
TrackTime = log.TrackTime,
TrackPlace = log.TrackPlace,
TrackCode = log.TrackCode,
Extra = log.Extra,
InterfaceRelayData = interfaceRelayData
};
}
}