519 lines
24 KiB
C#
519 lines
24 KiB
C#
using DotNetCore.CAP;
|
||
using Fake.DependencyInjection;
|
||
using InterfaceForward.Domain.Shared.Helpers;
|
||
using Microsoft.Extensions.Logging;
|
||
using TrackCenter.Application.Events;
|
||
using TrackCenter.Application.Kafka;
|
||
using TrackCenter.Application.Queries;
|
||
using TrackCenter.Application.Services.Broadcasting;
|
||
using TrackCenter.Application.Services.Warning.Signals;
|
||
using TrackCenter.Domain.Aggregates.OrderAggregate;
|
||
using TrackCenter.Domain.Aggregates.TrackDetailsAggregate;
|
||
using TrackCenter.Domain.Dtos.TrackContents;
|
||
using TrackCenter.Domain.Enums;
|
||
using TrackCenter.Domain.Extensions;
|
||
using TrackCenter.Repository.Aggregates.OrderAggregate;
|
||
using OrderIdentifier = TrackCenter.Application.Events.OrderIdentifier;
|
||
|
||
namespace TrackCenter.Application.CAP.EventHandlers;
|
||
|
||
public class TrackUpsertEventHandler : ITransientDependency, ICapSubscribe
|
||
{
|
||
private readonly ICapPublisher _capPublisher;
|
||
private readonly IOrderRepository _orderRepository;
|
||
private readonly ProvideQueries _provideQueries;
|
||
private readonly ITrackDetailsEsRepository _trackDetailsEsRepository;
|
||
private readonly BroadcastingService _broadcastingService;
|
||
private readonly ILogger<TrackUpsertEventHandler> _logger;
|
||
private readonly IOrderOperationRecordEsRepository _orderOperationRecordEsRepository;
|
||
private readonly WarningSignalPublisher _warningSignalPublisher;
|
||
|
||
public TrackUpsertEventHandler(
|
||
IOrderRepository orderRepository,
|
||
ICapPublisher capPublisher,
|
||
ProvideQueries provideQueries,
|
||
ITrackDetailsEsRepository trackDetailsEsRepository,
|
||
IOrderOperationRecordEsRepository orderOperationRecordEsRepository,
|
||
BroadcastingService broadcastingService,
|
||
ILogger<TrackUpsertEventHandler> logger,
|
||
WarningSignalPublisher warningSignalPublisher
|
||
)
|
||
{
|
||
_orderRepository = orderRepository;
|
||
_capPublisher = capPublisher;
|
||
_provideQueries = provideQueries;
|
||
_trackDetailsEsRepository = trackDetailsEsRepository;
|
||
_orderOperationRecordEsRepository = orderOperationRecordEsRepository;
|
||
_broadcastingService = broadcastingService;
|
||
_logger = logger;
|
||
_warningSignalPublisher = warningSignalPublisher;
|
||
}
|
||
|
||
[CapSubscribe(GlobalConst.TrackUpsertSubscribe, Group = GlobalConst.TrackUpsertSubscribe)]
|
||
[CapSubscribe(GlobalConst.TrackUpsertForRefreshSubscribe, Group = GlobalConst.TrackUpsertForRefreshSubscribe)]
|
||
public async Task ConsumerAsync(TrackUpsertEvent @event)
|
||
{
|
||
if (!CanDelete(@event)) return;
|
||
|
||
var canNextOrderIds = new List<int>();
|
||
|
||
var content = await HandleTrackAsync(@event, canNextOrderIds);
|
||
|
||
// 处理广播事件
|
||
if (content != null && (content.IsToMq || @event.IsToMq))
|
||
_ = EnsureWriteAfterPublicTopicAsync(@event, content.IsExternal, content.SubSystemCode, content.TrackStatusCode);
|
||
|
||
if (canNextOrderIds.Count == 0) return;
|
||
// 根据订单关联关系异步向下刷(异步)
|
||
await DownByOrderLink(@event, canNextOrderIds);
|
||
}
|
||
|
||
private async Task DownByOrderLink(TrackUpsertEvent @event, List<int> canNextOrderIds)
|
||
{
|
||
// 根据订单关联关系异步向下刷(异步)
|
||
var linkedOrders = await _orderRepository.GetLinkedOrdersAsync(canNextOrderIds.ToArray());
|
||
foreach (var order in @event.OrderIdentifiers)
|
||
{
|
||
// 理论上小包在这不会分组
|
||
foreach (var group in linkedOrders.Where(x => x.OwnerOrderId == order.OrderId)
|
||
.GroupBy(x => new
|
||
{
|
||
x.SubSystemId,
|
||
x.CustomId // 这里按客户分组是为了后续的推送方便
|
||
}))
|
||
{
|
||
var nextEvent = @event.DeepCopy();
|
||
nextEvent.Visited.AddRange(canNextOrderIds);
|
||
nextEvent.SubSystemId = group.Key.SubSystemId;
|
||
nextEvent.CustomId = group.Key.CustomId;
|
||
nextEvent.TrackRefreshData = new TrackRefreshStruct
|
||
{
|
||
ServiceProviderCode = @event.TrackRefreshData.ServiceProviderCode,
|
||
OriginTrackContent = @event.TrackRefreshData.OriginTrackContent,
|
||
OriginTrackDataHash = @event.TrackRefreshData.OriginTrackDataHash,
|
||
};
|
||
|
||
// 不同子系统需要做内容映射
|
||
if (@event.SubSystemId != nextEvent.SubSystemId)
|
||
{
|
||
var mapCode = (await _provideQueries.MapTrackCodesAsync(@event.SubSystemId, nextEvent.SubSystemId, @event.TrackCode))
|
||
.FirstOrDefault();
|
||
|
||
if (mapCode == null)
|
||
{
|
||
// 跨子系统没做映射的轨迹不处理
|
||
continue;
|
||
}
|
||
|
||
nextEvent.TrackCode = mapCode;
|
||
}
|
||
|
||
var identifiers = group.Select(x => new OrderIdentifier
|
||
{
|
||
OrderId = x.OrderId,
|
||
OrderNo = x.OrderNo,
|
||
OrderType = x.OrderType,
|
||
}).ToList();
|
||
var idx = 0;
|
||
while (idx < identifiers.Count)
|
||
{
|
||
var subEvent = nextEvent.DeepCopy();
|
||
var cnt = idx + GlobalConst.ChunkSize > identifiers.Count
|
||
? identifiers.Count - idx
|
||
: GlobalConst.ChunkSize;
|
||
subEvent.OrderIdentifiers = identifiers.GetRange(idx, cnt).ToArray();
|
||
idx += GlobalConst.ChunkSize;
|
||
|
||
await _capPublisher.PublishAsync(GlobalConst.TrackUpsertSubscribe, subEvent);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
private static bool CanDelete(TrackUpsertEvent @event)
|
||
{
|
||
// 系统创建的轨迹不允许修改
|
||
if (@event.Visited.IsNullOrEmpty() && @event is { OperationMan: GlobalConst.SystemUser, IsAdd: false })
|
||
{
|
||
LogHelper.Warn($"系统创建的轨迹不允许被修改:{@event}", true);
|
||
return false;
|
||
}
|
||
|
||
var orderIds = @event.OrderIdentifiers.Select(x => x.OrderId).ToArray();
|
||
|
||
var dup = @event.Visited.Intersect(orderIds).ToArray();
|
||
if (dup.Any())
|
||
{
|
||
LogHelper.Warn($"{(@event.IsAdd ? "添加" : "修改")}轨迹时,发现循环依赖:{dup.JoinAsString(",")}", true);
|
||
return false;
|
||
}
|
||
|
||
return true;
|
||
}
|
||
|
||
private async Task<TrackContentVO?> HandleTrackAsync(TrackUpsertEvent @event, List<int> canNextOrderIds)
|
||
{
|
||
var trackContent = await _provideQueries.GetTrackContentAsync(@event.SubSystemId, @event.TrackCode);
|
||
|
||
if (trackContent == null)
|
||
{
|
||
// 找不到轨迹内容,直接结束
|
||
LogHelper.Warn($"找不到轨迹内容:{@event}", true);
|
||
return null;
|
||
}
|
||
|
||
//#7001:未来潜在需求,当轨迹内容匹配预设,记录一个标记,保证下刷过程都是使用预设内容
|
||
//虽然在引发事件之前做了判断,引发之后并不一定立即处理,在此过程中轨迹内容仍然可能被修改,所以要二次进行判断。
|
||
//通过来源指示是否为手动操作
|
||
var manualOperation = @event.Source == (int) TrackSourceEnum.Artificial;
|
||
//轨迹内容标识不允许手动创建的
|
||
if (manualOperation && @event.IsAdd && trackContent.IsAllowManuallyCreate == false) return trackContent;
|
||
//轨迹内容标识不允许手动更新的
|
||
if (manualOperation && !@event.IsAdd && trackContent.IsAllowManuallyUpdate == false) return trackContent;
|
||
|
||
// k:[orderId] v:[k:EsId,v:Version]
|
||
var orderIdEsIdVersionDict = new Dictionary<int, KeyValuePair<string, long>>();
|
||
|
||
var insertTracks = await UpsertTrackAsync(@event, canNextOrderIds, trackContent, orderIdEsIdVersionDict);
|
||
|
||
if (canNextOrderIds.Count == 0) return trackContent;
|
||
|
||
if (insertTracks.Any())
|
||
{
|
||
// 批量add to es tips:注意副作用填充版本号
|
||
await _trackDetailsEsRepository.AddManyAsync(insertTracks);
|
||
|
||
// es新增后填充版本号字典
|
||
insertTracks.ForEach(t => orderIdEsIdVersionDict.Add(t.OrderId, KeyValuePair.Create(t.Id, t.Version)));
|
||
|
||
//批量写入订单操作日志
|
||
_ = _orderOperationRecordEsRepository.AddManyAsync(insertTracks.Select(t => BuildOrderOperationRecord(@event, t, new OrderIdentifier
|
||
{
|
||
OrderNo = t.OrderNo,
|
||
OrderId = t.OrderId
|
||
})).ToList());
|
||
|
||
// 添加轨迹触发订单拉取状态更新
|
||
await _orderRepository.UpdatePullStatusToSilenceAsync(insertTracks.Select(x => x.OrderId).ToList(),
|
||
@event.TrackCode);
|
||
|
||
// todo:引发预警计算 改MQ批量+分流
|
||
WarningCalc_AddedTrack(insertTracks);
|
||
|
||
// 添加轨迹触发预警计算(异步)todo:弃用
|
||
// await _capPublisher.PublishAsync(GlobalConst.TrackWarningCalcSubscribe, new TrackWarningCalcEvent
|
||
// {
|
||
// SubSystemId = @event.SubSystemId,
|
||
// CustomId = @event.CustomId,
|
||
// OrderIds = insertTracks.Select(x => x.OrderId).ToArray(),
|
||
// TrackStatusId = trackContent.TrackStatusId,
|
||
// TrackTime = @event.TrackTime,
|
||
// });
|
||
}
|
||
|
||
// 触发订单主表更新事件(异步)
|
||
await _capPublisher.PublishAsync(GlobalConst.TrackChangeAfterUpdateOrderSubscribe,
|
||
new TrackChangeAfterUpdateOrderEvent
|
||
{
|
||
OrderIds = canNextOrderIds.ToArray(),
|
||
IsCompleted = trackContent.IsCompleted,
|
||
TrackStatus = trackContent.TrackStatus,
|
||
TrackContent = trackContent.TrackContent,
|
||
TrackEnContent = trackContent.TrackEnContent,
|
||
TrackPlace = @event.TrackPlace,
|
||
TrackTime = @event.NewTrackTime ?? @event.TrackTime,
|
||
TrackTimeZone = @event.TrackTimeZone,
|
||
DestinationTimeZone = @event.DestinationTimeZone,
|
||
EstimatedDeliveryDate = @event.EstimatedDeliveryDate
|
||
});
|
||
|
||
// 触发轨迹推送事件(异步)
|
||
// tips:同一个轨迹内容,多个订单多条轨迹
|
||
var trackPushEvent = new TrackPushEvent
|
||
{
|
||
OptionType = @event.IsAdd ? OptionType.新增 : OptionType.修改,
|
||
SubSystemId = @event.SubSystemId,
|
||
SubSystemCode = trackContent.SubSystemCode,
|
||
CustomId = @event.CustomId,
|
||
OrderIdEsIdVersionDict = orderIdEsIdVersionDict,
|
||
TrackCode = @event.TrackCode,
|
||
SystemPushInfo = new SystemPushStruct
|
||
{
|
||
TrackStatusId = trackContent.TrackStatusId,
|
||
TrackStatus = trackContent.TrackStatus,
|
||
TrackContentId = trackContent.TrackContentId,
|
||
TrackContent = trackContent.TrackContent,
|
||
TrackPlace = @event.TrackPlace,
|
||
TrackTime = @event.NewTrackTime ?? @event.TrackTime,
|
||
TrackTimeZone = @event.TrackTimeZone,
|
||
CompareFields = @event.CompareFields,
|
||
Extra = @event.NewExtra ?? @event.Extra
|
||
},
|
||
ForcedPush = @event.ForcedPush,
|
||
IsToMq = (trackContent.IsToMq || @event.IsToMq)
|
||
};
|
||
await _capPublisher.PublishAsync(GlobalConst.TrackPushSubscribe, trackPushEvent);
|
||
|
||
return trackContent;
|
||
}
|
||
|
||
private async Task<List<TrackDetailsIndex>> UpsertTrackAsync(
|
||
TrackUpsertEvent @event,
|
||
List<int> canNextOrderIds,
|
||
TrackContentVO trackContent,
|
||
Dictionary<int, KeyValuePair<string, long>> orderIdEsIdVersionDict
|
||
)
|
||
{
|
||
var orderIds = @event.OrderIdentifiers.Select(x => x.OrderId).ToArray();
|
||
|
||
// important:轨迹code相同,时间、发生地不同的,可能存在多条!!
|
||
var tracks = await _trackDetailsEsRepository.GetListAsync(orderIds, @event.TrackCode, true);
|
||
|
||
var insertTracks = new List<TrackDetailsIndex>();
|
||
var updateTracks = new List<TrackDetailsIndex>();
|
||
var operationRecords = new List<OrderOperationRecordIndex>();
|
||
var traceLog = new Dictionary<string, object>
|
||
{
|
||
{ "@event", @event.ToJson() }
|
||
};
|
||
foreach (var order in @event.OrderIdentifiers)
|
||
{
|
||
// fast path: by update with es id case
|
||
if (!@event.IsAdd && !string.IsNullOrWhiteSpace(@event.EsId))
|
||
{
|
||
var trackById = tracks.FirstOrDefault(x => x.Id == @event.EsId);
|
||
if (trackById != null)
|
||
{
|
||
updateTracks.Add(BuiltUpdateTrack(@event, trackById, order, trackContent));
|
||
}
|
||
|
||
continue;
|
||
}
|
||
|
||
var existTracks = tracks.Where(x => x.OrderId == order.OrderId).ToList();
|
||
|
||
// tips:如果没传时区则使用+8兜底进行过滤
|
||
var timezone = Math.Abs(@event.TrackTimeZone - GlobalConst.NoneTrackTimeZone) < 0.01f ? 8.0f : @event.TrackTimeZone;
|
||
|
||
// todo-remove:为了照顾FBA老逻辑,暂时特殊处理一下
|
||
var trackFirst = tracks.FirstOrDefault();
|
||
if (trackFirst?.SubSystemId == 9517)
|
||
{
|
||
existTracks = @event.IsAdd
|
||
? tracks.Where(x => x.TrackTime == (@event.NewTrackTime ?? @event.TrackTime)).ToList()
|
||
: tracks.Where(x =>
|
||
x.TrackTime == @event.TrackTime
|
||
// 修改了时间,要校验修改后的时间是否存在
|
||
|| (@event.NewTrackTime != null && x.TrackTime == @event.NewTrackTime)
|
||
).ToList();
|
||
}
|
||
else
|
||
{
|
||
// 根据时间过滤
|
||
existTracks = @event.IsAdd
|
||
? existTracks.Where(x => x.GetUtc0TrackTime() == (@event.NewTrackTime ?? @event.TrackTime).Subtract(TimeSpan.FromHours(timezone))).ToList()
|
||
: existTracks.Where(x =>
|
||
x.GetUtc0TrackTime() == @event.TrackTime.Subtract(TimeSpan.FromHours(timezone))
|
||
// 修改了时间,要校验修改后的时间是否存在
|
||
|| (@event.NewTrackTime != null && x.GetUtc0TrackTime() == @event.NewTrackTime.Value.Subtract(TimeSpan.FromHours(timezone)))
|
||
).ToList();
|
||
}
|
||
|
||
// 根据扩展信息过滤
|
||
existTracks = @event.IsAdd
|
||
? existTracks.Where(x => x.Extra == (@event.NewExtra ?? @event.Extra)).ToList()
|
||
: existTracks.Where(x =>
|
||
x.Extra == @event.Extra
|
||
// 修改了extra,要校验修改后的extra是否存在
|
||
|| (!string.IsNullOrWhiteSpace(@event.NewExtra) && x.Extra == @event.NewExtra)).ToList();
|
||
|
||
if (@event.IsAdd)
|
||
{
|
||
if (existTracks.Count > 0)
|
||
{
|
||
_logger.LogInformation("订单已经存在不允许重复的轨迹,不允许重复添加:{@event}", @event);
|
||
traceLog.Add($"OrderNo-{order.OrderNo}", "订单已经存在不允许重复的轨迹,不允许重复添加");
|
||
continue;
|
||
}
|
||
|
||
insertTracks.Add(BuiltNewTrack(@event, order, trackContent));
|
||
}
|
||
else
|
||
{
|
||
// 不存在不让改
|
||
if (existTracks.Count == 0)
|
||
{
|
||
_logger.LogInformation("订单不存在轨迹,不允许修改:{@event}", @event);
|
||
traceLog.Add($"OrderNo-{order.OrderNo}", "订单不存在轨迹,不允许修改");
|
||
continue;
|
||
}
|
||
|
||
if (existTracks.Count > 1)
|
||
{
|
||
_logger.LogInformation("订单存在多条轨迹不允许修改:{@event}", @event);
|
||
traceLog.Add($"OrderNo-{order.OrderNo}", "订单存在多条轨迹不允许修改");
|
||
continue;
|
||
}
|
||
|
||
var track = existTracks.First();
|
||
updateTracks.Add(BuiltUpdateTrack(@event, track, order, trackContent));
|
||
operationRecords.Add(BuildOrderOperationRecord(@event, track, order));
|
||
}
|
||
|
||
|
||
canNextOrderIds.Add(order.OrderId);
|
||
}
|
||
|
||
ActivityHelper.StartSpanActivity("UpsertTrackAsync", traceLog);
|
||
|
||
if (updateTracks.Any())
|
||
{
|
||
// 批量差异化更新轨迹
|
||
await _trackDetailsEsRepository.BulkUpdateAsync(updateTracks);
|
||
// 获取更新后的版本号
|
||
updateTracks.ForEach(x => orderIdEsIdVersionDict.Add(x.OrderId, KeyValuePair.Create(x.Id, x.Version)));
|
||
// 批量写入操作日志
|
||
_ = _orderOperationRecordEsRepository.AddManyAsync(operationRecords);
|
||
|
||
// todo:引发预警计算 改MQ批量+分流
|
||
WarningCalc_UpdatedTrack(updateTracks);
|
||
}
|
||
|
||
return insertTracks;
|
||
}
|
||
|
||
|
||
private static TrackDetailsIndex BuiltUpdateTrack(TrackUpsertEvent @event, TrackDetailsIndex track, OrderIdentifier order,
|
||
TrackContentVO trackContent)
|
||
{
|
||
//外部轨迹,轨迹发生地,轨迹发生时间,轨迹发生时区,不允许更改
|
||
if (track.Source != (int) TrackSourceEnum.ExternalServiceProvide)
|
||
{
|
||
track.TrackPlace = @event.TrackPlace;
|
||
track.TrackTime = @event.NewTrackTime ?? @event.TrackTime;
|
||
track.TrackTimeZone = @event.TrackTimeZone;
|
||
}
|
||
|
||
track.ZeroTrackTime = Math.Abs(track.TrackTimeZone - GlobalConst.NoneTrackTimeZone) < 1
|
||
? track.TrackTime
|
||
: track.TrackTime.Subtract(TimeSpan.FromHours(track.TrackTimeZone));
|
||
track.UpdateUser = @event.OperationMan ?? GlobalConst.SystemUser;
|
||
track.UpdateTime = DateTime.Now;
|
||
|
||
//允许二次修改,在修改了轨迹内容后进行修改轨迹操作,如果输入的轨迹内容则以输入为准
|
||
//跨子系统?
|
||
track.TrackContent = string.IsNullOrWhiteSpace(@event.Content) ? trackContent.TrackContent : @event.Content;
|
||
track.TrackEnContent = string.IsNullOrWhiteSpace(@event.EnStatus) ? trackContent.TrackEnContent : @event.EnStatus;
|
||
//当传入的IsExternal为空,则使用轨迹内容中的IsExternal
|
||
track.IsExternal = @event.IsExternal ?? trackContent.IsExternal;
|
||
track.Remarks = @event.Remarks ?? GlobalConst.EmptyString;
|
||
track.Files = @event.Files?.Select(x => new FileItem
|
||
{
|
||
OssKey = x.OssKey,
|
||
FileName = x.FileName
|
||
}).ToList();
|
||
track.TrackPlaceCity = @event.TrackPlaceCity ?? GlobalConst.EmptyString;
|
||
track.TrackPlaceCityId = @event.TrackPlaceCityId ?? GlobalConst.NotExistId;
|
||
track.TrackPlaceProvince = @event.TrackPlaceProvince ?? GlobalConst.EmptyString;
|
||
track.TrackPlaceProvinceId = @event.TrackPlaceProvinceId ?? GlobalConst.NotExistId;
|
||
track.TrackPlaceNation = @event.TrackPlaceNation ?? GlobalConst.EmptyString;
|
||
track.TrackPlaceNationId = @event.TrackPlaceNationId ?? GlobalConst.NotExistId;
|
||
track.TrackPlacePostcode = @event.TrackPlacePostcode ?? GlobalConst.EmptyString;
|
||
track.DestinationTimeZone = @event.DestinationTimeZone;
|
||
track.EstimatedDeliveryDate = @event.EstimatedDeliveryDate;
|
||
track.Extra = @event.NewExtra ?? @event.Extra;
|
||
|
||
return track;
|
||
}
|
||
|
||
private static TrackDetailsIndex BuiltNewTrack(TrackUpsertEvent @event, OrderIdentifier order, TrackContentVO trackContent)
|
||
{
|
||
var track = new TrackDetailsIndex
|
||
{
|
||
SubSystemId = @event.SubSystemId,
|
||
OrderId = order.OrderId,
|
||
OrderNo = order.OrderNo,
|
||
OrderType = order.OrderType,
|
||
TrackCode = @event.TrackCode,
|
||
TrackPlace = @event.TrackPlace,
|
||
TrackTime = @event.NewTrackTime ?? @event.TrackTime,
|
||
TrackTimeZone = @event.TrackTimeZone,
|
||
ServiceProviderCode = @event.TrackRefreshData.ServiceProviderCode ?? GlobalConst.EmptyString,
|
||
OriginTrackContent = @event.TrackRefreshData.OriginTrackContent ?? GlobalConst.EmptyString,
|
||
OriginTrackDataHash = @event.TrackRefreshData.OriginTrackDataHash ?? GlobalConst.EmptyString,
|
||
CreateUser = @event.OperationMan ?? GlobalConst.SystemUser,
|
||
CreateTime = DateTime.Now,
|
||
//来源轨迹内容,第一次新增的时候使用轨迹内容表提供的
|
||
TrackStatusId = trackContent.TrackStatusId,
|
||
TrackStatus = trackContent.TrackStatus,
|
||
TrackStatusCode = trackContent.TrackStatusCode,
|
||
//跨子系统?
|
||
TrackContentId = trackContent.TrackContentId,
|
||
TrackContent = string.IsNullOrWhiteSpace(@event.Content) ? trackContent.TrackContent : @event.Content,
|
||
TrackEnContent = string.IsNullOrWhiteSpace(@event.EnStatus) ? trackContent.TrackEnContent : @event.EnStatus,
|
||
//当传入的IsExternal为空,则使用轨迹内容中的IsExternal
|
||
IsExternal = @event.IsExternal ?? trackContent.IsExternal,
|
||
Source = @event.Source,
|
||
Remarks = @event.Remarks ?? GlobalConst.EmptyString,
|
||
Files = @event.Files?.Select(x => new FileItem
|
||
{
|
||
OssKey = x.OssKey,
|
||
FileName = x.FileName
|
||
}).ToList(),
|
||
TrackPlaceCity = @event.TrackPlaceCity ?? GlobalConst.EmptyString,
|
||
TrackPlaceCityId = @event.TrackPlaceCityId ?? GlobalConst.NotExistId,
|
||
TrackPlaceProvince = @event.TrackPlaceProvince ?? GlobalConst.EmptyString,
|
||
TrackPlaceProvinceId = @event.TrackPlaceProvinceId ?? GlobalConst.NotExistId,
|
||
TrackPlaceNation = @event.TrackPlaceNation ?? GlobalConst.EmptyString,
|
||
TrackPlaceNationId = @event.TrackPlaceNationId ?? GlobalConst.NotExistId,
|
||
TrackPlacePostcode = @event.TrackPlacePostcode ?? GlobalConst.EmptyString,
|
||
DestinationTimeZone = @event.DestinationTimeZone,
|
||
EstimatedDeliveryDate = @event.EstimatedDeliveryDate,
|
||
Extra = @event.NewExtra ?? @event.Extra,
|
||
};
|
||
|
||
track.ZeroTrackTime = Math.Abs(track.TrackTimeZone - GlobalConst.NoneTrackTimeZone) < 1
|
||
? track.TrackTime
|
||
: track.TrackTime.Subtract(TimeSpan.FromHours(track.TrackTimeZone));
|
||
|
||
return track;
|
||
}
|
||
|
||
private static OrderOperationRecordIndex BuildOrderOperationRecord(TrackUpsertEvent @event, TrackDetailsIndex track, OrderIdentifier order)
|
||
{
|
||
return new OrderOperationRecordIndex
|
||
{
|
||
OrderId = order.OrderId,
|
||
OrderNo = order.OrderNo,
|
||
OptionType = @event.IsAdd ? OrderOperationType.创建轨迹.ToString() : OrderOperationType.修改轨迹.ToString(),
|
||
Content = track.ToJson(),
|
||
CreateUserId = @event.OperationManId,
|
||
CreateUserName = @event.OperationMan ?? "",
|
||
CreateTime = DateTime.Now
|
||
};
|
||
}
|
||
|
||
private async Task EnsureWriteAfterPublicTopicAsync(TrackUpsertEvent @event, bool contentIsExternal, string subSystemCode, string statusCode)
|
||
{
|
||
//理想情况在写入之后1s会刷盘 https://www.elastic.co/guide/en/elasticsearch/reference/master/indices-refresh.html
|
||
//增加一个版本号来确定是否真的变更了
|
||
//没有刷盘成功事件回调
|
||
//方案1:!!【轮询等待静默刷盘】查出版本号确实发生了变更在发送广播
|
||
//方案2:考虑强制刷盘(对es压力大)后发送
|
||
//方案3:采用一个较大延时,不查询直接发
|
||
await Task.Delay(1000);
|
||
_broadcastingService.TrackChangePublicTopic(@event, contentIsExternal, subSystemCode, statusCode);
|
||
}
|
||
|
||
private void WarningCalc_AddedTrack(List<TrackDetailsIndex> tracks)
|
||
{
|
||
_warningSignalPublisher.PublishSignal(WarningSignalType.轨迹新增, tracks);
|
||
}
|
||
|
||
|
||
private void WarningCalc_UpdatedTrack(List<TrackDetailsIndex> tracks)
|
||
{
|
||
_warningSignalPublisher.PublishSignal(WarningSignalType.轨迹更新, tracks);
|
||
}
|
||
}
|