217 lines
7.8 KiB
C#
217 lines
7.8 KiB
C#
using System.Text;
|
||
using BSI.Stack.Rabbit;
|
||
using BSI.Stack.Rabbit.Handler;
|
||
using Newtonsoft.Json;
|
||
using RabbitMQ.Client.Events;
|
||
using SJZY.Expand.ABP.Core.Logger;
|
||
using SJZY.InterfaceRelay.Application.Contracts;
|
||
using SJZY.Track.Application.Contract.Dtos.TrackPush;
|
||
using SJZY.Track.Application.Contract.Services;
|
||
using SJZY.Track.Application.Helpers;
|
||
using SJZY.Track.Application.Services.Warning.Handlers;
|
||
using SJZY.Track.Domain.Aggregates.OrderAggregate;
|
||
using SJZY.Track.Domain.Aggregates.TrackPushAggregate;
|
||
using SJZY.Track.Domain.Enums;
|
||
using Volo.Abp.DependencyInjection;
|
||
|
||
namespace SJZY.Track.Application.Rabbit;
|
||
|
||
public class TrackPushCompletedEventHandler : ITransientDependency, IRabbitHandler
|
||
{
|
||
private readonly IOrderRepository _orderRepository;
|
||
private readonly ITrackPushRecordEsRepository _trackPushRecordEsRepository;
|
||
private readonly IBroadcastingService _broadcastingService;
|
||
private readonly IReturnWarningHandler _returnWarningHandler;
|
||
|
||
public TrackPushCompletedEventHandler(IOrderRepository orderRepository,
|
||
ITrackPushRecordEsRepository trackPushRecordEsRepository,
|
||
IBroadcastingService broadcastingService, IReturnWarningHandler returnWarningHandler)
|
||
{
|
||
_orderRepository = orderRepository;
|
||
_trackPushRecordEsRepository = trackPushRecordEsRepository;
|
||
_broadcastingService = broadcastingService;
|
||
_returnWarningHandler = returnWarningHandler;
|
||
}
|
||
|
||
public ConsumeOptions Options()
|
||
{
|
||
return new ConsumeOptions
|
||
{
|
||
Queue = GlobalConst.TrackPushCompletedSubscribe
|
||
};
|
||
}
|
||
|
||
public async Task Handle(IServiceProvider sp, BasicDeliverEventArgs args, ConsumeOptions options)
|
||
{
|
||
var msg = Encoding.UTF8.GetString(args.Body.ToArray());
|
||
var @event = System.Text.Json.JsonSerializer.Deserialize<InterfaceRelayForwardReplayEvent>(msg);
|
||
if (@event == null)
|
||
{
|
||
LogHelper.Warn(
|
||
$"rabbit on queue({options.Queue}) received msg can't convert to {nameof(InterfaceRelayForwardReplayEvent)}");
|
||
return;
|
||
}
|
||
|
||
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)
|
||
logs.ForEach(log => _broadcastingService.TrackPushCompletedPublicTopic(BuildDto(log)));
|
||
|
||
// 写入推送日志
|
||
await _trackPushRecordEsRepository.AddManyAsync(logs);
|
||
|
||
// 同步更新订单主表
|
||
await TrackPushAfterUpdateOrderAsync(isAdd, @event.IsSuccess, logs);
|
||
|
||
// todo:引发预警计算 改MQ批量+分流
|
||
await _returnWarningHandler.ReceiveTrackPushRecordHandleAsync(@event.IsSuccess, @event.RequestParams, logs, pushInputs, updateInputs);
|
||
|
||
// // 推送广播
|
||
// if (log.IsToMq)
|
||
// _broadcastingService.TrackPushCompletedPublicTopic(BuildDto(log));
|
||
//
|
||
// // 往es 写推送日志
|
||
// await _trackPushRecordEsRepository.AddAsync(log);
|
||
//
|
||
// // 同步去更新订单主表
|
||
// await TrackPushAfterUpdateOrderAsync(log);
|
||
}
|
||
|
||
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 = (int) 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 async Task TrackPushAfterUpdateOrderAsync(TrackPushRecordIndex log)
|
||
{
|
||
// tips:只有新增会影响推送进度?
|
||
if (log.OptionType != OptionType.新增.ToString()) return;
|
||
|
||
var order = new OrderEntity
|
||
{
|
||
Id = log.OrderId
|
||
};
|
||
|
||
/*
|
||
* 异常:最近一条推送是失败
|
||
*/
|
||
if (!log.IsSuccess)
|
||
{
|
||
order.QuestionType = (int) TrackProblemType.Error;
|
||
order.LatestPushError = log.Message;
|
||
await _orderRepository.UpdateColumnAsync(order, x => new
|
||
{
|
||
x.QuestionType,
|
||
x.LatestPushError
|
||
});
|
||
}
|
||
else
|
||
{
|
||
// 还原成正常态
|
||
order.QuestionType = (int) TrackProblemType.None;
|
||
order.LatestPushError = null;
|
||
order.LatestPushTrackCode = log.TrackCode;
|
||
order.LatestPushTime = log.CreateTime;
|
||
await _orderRepository.UpdateColumnAsync(order,
|
||
x => new
|
||
{
|
||
x.LatestPushTrackCode,
|
||
x.LatestPushTime,
|
||
x.QuestionType,
|
||
x.LatestPushError
|
||
});
|
||
}
|
||
}
|
||
|
||
private TrackPushRecordDto BuildDto(TrackPushRecordIndex log)
|
||
{
|
||
return new TrackPushRecordDto
|
||
{
|
||
SubSystemCode = log.SubSystemCode,
|
||
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
|
||
};
|
||
}
|
||
}
|