Merge branch 'S06' into test
This commit is contained in:
commit
63ec1e06ca
@ -120,6 +120,11 @@ public class BatchUpsertTrackInput : OrderNosInfo
|
|||||||
[Range(-12, 12)]
|
[Range(-12, 12)]
|
||||||
public float? DestinationTimeZone { get; set; }
|
public float? DestinationTimeZone { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 重复的情况下,用什么比较
|
||||||
|
/// </summary>
|
||||||
|
public string? CompareFields { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 扩展信息字段,用与轨迹推送的附加字段
|
/// 扩展信息字段,用与轨迹推送的附加字段
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
@ -129,6 +129,11 @@ public class UpsertTrackInput : OrderNoInfo
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public int OptionUserId { get; set; }
|
public int OptionUserId { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 重复的情况下,用什么比较
|
||||||
|
/// </summary>
|
||||||
|
public string? CompareFields { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 扩展信息字段,用与轨迹推送的附加字段
|
/// 扩展信息字段,用与轨迹推送的附加字段
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
@ -44,10 +44,15 @@ public class EditTrackPushConfigInput
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public bool? IsAllPush { get; set; }
|
public bool? IsAllPush { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 是否全量推送
|
||||||
|
/// </summary>
|
||||||
|
public bool? IsAllPushWithLatest { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 时间格式枚举
|
/// 时间格式枚举
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public int DateTimeFormatType { get; set; }
|
public int? DateTimeFormatType { get; set; } = 0;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 日期时间格式模板
|
/// 日期时间格式模板
|
||||||
|
|||||||
@ -17,6 +17,11 @@ public class TrackPushContentConfigDto
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public bool IsAllPush { get; set; }
|
public bool IsAllPush { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 是否全量推送(最新轨迹)
|
||||||
|
/// </summary>
|
||||||
|
public bool IsAllPushWithLatest { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 是否支持删除
|
/// 是否支持删除
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
@ -19,15 +19,3 @@ public class TrackUpdateInput
|
|||||||
|
|
||||||
public string Log { get; set; }
|
public string Log { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public class TrackItem
|
|
||||||
{
|
|
||||||
public string Location { get; set; } = null!;
|
|
||||||
public string Date { get; set; }
|
|
||||||
public double TimeZone { get; set; }
|
|
||||||
public string? Description { get; set; }
|
|
||||||
public string? DescriptionCn { get; set; }
|
|
||||||
public string? Code { get; set; }
|
|
||||||
public string? Status { get; set; }
|
|
||||||
public string? Extra { get; set; }
|
|
||||||
}
|
|
||||||
|
|||||||
@ -29,8 +29,9 @@ public class TrackPushRecordDto
|
|||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 接口通请求Id
|
/// 接口通请求Id
|
||||||
|
/// 在请求接口通前被拦截,就不会有请求Id
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public Guid RequestId { get; set; }
|
public Guid? RequestId { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 信息
|
/// 信息
|
||||||
|
|||||||
@ -27,8 +27,9 @@ public class TrackPushCompletedEvent
|
|||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 接口通请求Id
|
/// 接口通请求Id
|
||||||
|
/// 在请求接口通前被拦截,就不会有请求Id
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public Guid RequestId { get; set; }
|
public Guid? RequestId { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 信息
|
/// 信息
|
||||||
|
|||||||
@ -80,6 +80,11 @@ public struct SystemPushStruct
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public float TrackTimeZone { get; set; }
|
public float TrackTimeZone { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 重复的情况下,用什么比较
|
||||||
|
/// </summary>
|
||||||
|
public string? CompareFields { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 扩展信息字段,用与轨迹推送的附加字段
|
/// 扩展信息字段,用与轨迹推送的附加字段
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
@ -146,6 +146,11 @@ public class TrackUpsertEvent
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public float? DestinationTimeZone { get; set; }
|
public float? DestinationTimeZone { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 重复的情况下,用什么比较
|
||||||
|
/// </summary>
|
||||||
|
public string? CompareFields { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 扩展信息字段,用与轨迹推送的附加字段
|
/// 扩展信息字段,用与轨迹推送的附加字段
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
@ -5,7 +5,7 @@
|
|||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFramework>net7.0</TargetFramework>
|
<TargetFramework>net7.0</TargetFramework>
|
||||||
<GenerateDocumentationFile>True</GenerateDocumentationFile>
|
<GenerateDocumentationFile>True</GenerateDocumentationFile>
|
||||||
<Version>7.0.12</Version>
|
<Version>7.0.14</Version>
|
||||||
<GenerateDocumentationFile>True</GenerateDocumentationFile>
|
<GenerateDocumentationFile>True</GenerateDocumentationFile>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
|||||||
@ -26,5 +26,11 @@ public interface IBroadcastingService : ITransientDependency
|
|||||||
/// 轨迹推送完成广播(推送完成回调)
|
/// 轨迹推送完成广播(推送完成回调)
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="log"></param>
|
/// <param name="log"></param>
|
||||||
void TrackPushCompletedPublicTopicAsync(TrackPushRecordDto log);
|
void TrackPushCompletedPublicTopic(TrackPushRecordDto log);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 轨迹推送失败广播(推送前置被拦截,或调用接口通失败)
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="log"></param>
|
||||||
|
void TrackPushFailedPubilcTopic(TrackPushRecordDto log);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -158,6 +158,7 @@ public class TrackDeleteEventHandler : ITransientDependency, ICapSubscribe
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// todo:多个相同code的轨迹删除,也需要考虑??
|
||||||
private async Task<List<TrackDetailsIndex>> DeleteTrackAsync(TrackDeleteEvent @event)
|
private async Task<List<TrackDetailsIndex>> DeleteTrackAsync(TrackDeleteEvent @event)
|
||||||
{
|
{
|
||||||
List<int> orderIds;
|
List<int> orderIds;
|
||||||
|
|||||||
@ -1,3 +1,4 @@
|
|||||||
|
using System.Text.Json;
|
||||||
using DotNetCore.CAP;
|
using DotNetCore.CAP;
|
||||||
using Microsoft.Extensions.Options;
|
using Microsoft.Extensions.Options;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
@ -10,7 +11,6 @@ using SJZY.Track.Application.Helpers;
|
|||||||
using SJZY.Track.Application.Options;
|
using SJZY.Track.Application.Options;
|
||||||
using SJZY.Track.Application.Track2InterfaceRelay;
|
using SJZY.Track.Application.Track2InterfaceRelay;
|
||||||
using SJZY.Track.Domain.Aggregates.OrderAggregate;
|
using SJZY.Track.Domain.Aggregates.OrderAggregate;
|
||||||
using SJZY.Track.Domain.Aggregates.TrackDetailsAggregate;
|
|
||||||
using SJZY.Track.Domain.Aggregates.TrackPushAggregate;
|
using SJZY.Track.Domain.Aggregates.TrackPushAggregate;
|
||||||
using SJZY.Track.Domain.Enums;
|
using SJZY.Track.Domain.Enums;
|
||||||
using Volo.Abp.DependencyInjection;
|
using Volo.Abp.DependencyInjection;
|
||||||
@ -23,23 +23,25 @@ public class TrackPushEventHandler : ITransientDependency, ICapSubscribe
|
|||||||
private readonly IHttpClientProxy<IInterfaceForwardServiceV2> _httpClientProxy;
|
private readonly IHttpClientProxy<IInterfaceForwardServiceV2> _httpClientProxy;
|
||||||
private readonly IOptionsMonitor<InterfaceRelayParamsConfigOptions> _options;
|
private readonly IOptionsMonitor<InterfaceRelayParamsConfigOptions> _options;
|
||||||
private readonly IOrderRepository _orderRepository;
|
private readonly IOrderRepository _orderRepository;
|
||||||
private readonly ITrackDetailsEsRepository _trackDetailsEsRepository;
|
|
||||||
private readonly ITrackPushCacheService _trackPushCacheService;
|
private readonly ITrackPushCacheService _trackPushCacheService;
|
||||||
private readonly ITrackPushRecordEsRepository _trackPushRecordEsRepository;
|
private readonly ITrackPushRecordEsRepository _trackPushRecordEsRepository;
|
||||||
|
private readonly IBroadcastingService _broadcastingService;
|
||||||
private List<OrderEntity> _orders = null!;
|
private List<OrderEntity> _orders = null!;
|
||||||
private List<TrackPushContentConfigDto> _pushConfigs = null!;
|
private List<TrackPushContentConfigDto> _pushConfigs = null!;
|
||||||
|
|
||||||
public TrackPushEventHandler(IHttpClientProxy<IInterfaceForwardServiceV2> httpClientProxy,
|
public TrackPushEventHandler(IHttpClientProxy<IInterfaceForwardServiceV2> httpClientProxy,
|
||||||
IOrderRepository orderRepository, ITrackPushCacheService trackPushCacheService,
|
IOrderRepository orderRepository,
|
||||||
ITrackDetailsEsRepository trackDetailsEsRepository, ITrackPushRecordEsRepository trackPushRecordEsRepository,
|
ITrackPushCacheService trackPushCacheService,
|
||||||
IOptionsMonitor<InterfaceRelayParamsConfigOptions> options)
|
ITrackPushRecordEsRepository trackPushRecordEsRepository,
|
||||||
|
IOptionsMonitor<InterfaceRelayParamsConfigOptions> options,
|
||||||
|
IBroadcastingService broadcastingService)
|
||||||
{
|
{
|
||||||
_httpClientProxy = httpClientProxy;
|
_httpClientProxy = httpClientProxy;
|
||||||
_orderRepository = orderRepository;
|
_orderRepository = orderRepository;
|
||||||
_trackPushCacheService = trackPushCacheService;
|
_trackPushCacheService = trackPushCacheService;
|
||||||
_trackDetailsEsRepository = trackDetailsEsRepository;
|
|
||||||
_trackPushRecordEsRepository = trackPushRecordEsRepository;
|
_trackPushRecordEsRepository = trackPushRecordEsRepository;
|
||||||
_options = options;
|
_options = options;
|
||||||
|
_broadcastingService = broadcastingService;
|
||||||
}
|
}
|
||||||
|
|
||||||
[CapSubscribe(GlobalConst.TrackPushSubscribe, Group = GlobalConst.TrackPushSubscribe)]
|
[CapSubscribe(GlobalConst.TrackPushSubscribe, Group = GlobalConst.TrackPushSubscribe)]
|
||||||
@ -93,25 +95,50 @@ public class TrackPushEventHandler : ITransientDependency, ICapSubscribe
|
|||||||
|
|
||||||
private async Task DoPushAsync(TrackPushEvent @event)
|
private async Task DoPushAsync(TrackPushEvent @event)
|
||||||
{
|
{
|
||||||
|
// todo: 轨迹中台推送逻辑致使的未推送,也需要广播到mq,告知业务系统缘故
|
||||||
var items = new List<TrackPushInput>();
|
var items = new List<TrackPushInput>();
|
||||||
TrackPushContentConfigDto? config;
|
TrackPushContentConfigDto? config;
|
||||||
var isSystemPush = @event.OperationMan == null;
|
var isSystemPush = @event.OperationMan == null;
|
||||||
if (isSystemPush && !@event.ForcedPush)
|
if (isSystemPush && !@event.ForcedPush)
|
||||||
{
|
{
|
||||||
|
config = _pushConfigs.FirstOrDefault(x => x.TrackCode == @event.TrackCode);
|
||||||
foreach (var order in _orders)
|
foreach (var order in _orders)
|
||||||
{
|
{
|
||||||
if (order.QuestionType == (int) TrackProblemType.Error) continue; // 系统不推异常单,只能人工操作
|
if (config == null)
|
||||||
// 强制推送只需直接查出配置
|
{
|
||||||
if (@event.ForcedPush)
|
TrackPushFailedPublicTopic($"没有在推送映射配置中找到关于轨迹代码[{@event.TrackCode}]的配置", @event, order);
|
||||||
config = _pushConfigs.FirstOrDefault(x => x.TrackCode == @event.TrackCode);
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 系统不推异常单,只能人工操作
|
||||||
|
if (order.QuestionType == (int) TrackProblemType.Error)
|
||||||
|
{
|
||||||
|
TrackPushFailedPublicTopic("系统不推异常单,只能人工操作", @event, order);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
// 推送新增,需要根据上一次的推送 推断 本次推送 是否可行,为了约束顺序
|
// 推送新增,需要根据上一次的推送 推断 本次推送 是否可行,为了约束顺序
|
||||||
else
|
var (resultConfig, nextCode) = GetValidPushConfigAsync(_pushConfigs, order.LatestPushTrackCode, @event.TrackCode);
|
||||||
config = GetValidPushConfigAsync(_pushConfigs, order.LatestPushTrackCode, @event.TrackCode);
|
if (resultConfig == null)
|
||||||
if (config == null) continue;
|
{
|
||||||
|
TrackPushFailedPublicTopic($"推送顺序异常,下一个要推送的应为[{nextCode}]", @event, order);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
config = resultConfig;
|
||||||
|
|
||||||
// 是否自动推送
|
// 是否自动推送
|
||||||
if (!config.IsAutoPush) continue;
|
if (!config.IsAutoPush)
|
||||||
|
{
|
||||||
|
TrackPushFailedPublicTopic($"没有设置为自动推送,如果要推送请手动推送", @event, order);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
// 配置的类型如何和订单类型不一致则不允许推送
|
// 配置的类型如何和订单类型不一致则不允许推送
|
||||||
if (config.OrderType != order.OrderType) continue;
|
if (config.OrderType != order.OrderType)
|
||||||
|
{
|
||||||
|
TrackPushFailedPublicTopic($"订单类型{order.OrderType}和配置中的订单类型[{config.OrderType}]不一致,不能推送", @event, order);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
var log = new TrackPushRecordIndex
|
var log = new TrackPushRecordIndex
|
||||||
{
|
{
|
||||||
@ -129,33 +156,49 @@ public class TrackPushEventHandler : ITransientDependency, ICapSubscribe
|
|||||||
IsToMq = @event.IsToMq,
|
IsToMq = @event.IsToMq,
|
||||||
Extra = @event.SystemPushInfo.Extra
|
Extra = @event.SystemPushInfo.Extra
|
||||||
};
|
};
|
||||||
var item = await BuiltPushItem(config, log, @event.SystemPushInfo.Extra);
|
var item = await BuiltPushItem(config, log, @event.SystemPushInfo.CompareFields);
|
||||||
item.Log = JsonConvert.SerializeObject(log);
|
item.Log = JsonConvert.SerializeObject(log);
|
||||||
items.Add(item);
|
items.Add(item);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// 手工或强制推送,不会校验已推和顺序问题,因为可能是更新
|
// 手工或强制推送,不会校验已推和顺序问题,因为可能是更新
|
||||||
else
|
else
|
||||||
|
|
||||||
{
|
{
|
||||||
config = _pushConfigs.FirstOrDefault(x => x.TrackCode == @event.TrackCode);
|
config = _pushConfigs.FirstOrDefault(x => x.TrackCode == @event.TrackCode);
|
||||||
if (config == null) return;
|
|
||||||
|
|
||||||
foreach (var order in _orders)
|
foreach (var order in _orders)
|
||||||
{
|
{
|
||||||
if (config is { IsAllPush: true })
|
if (config == null)
|
||||||
{
|
{
|
||||||
// 强制推送只需直接查出配置
|
TrackPushFailedPublicTopic($"没有在推送映射配置中找到关于轨迹代码[{@event.TrackCode}]的配置", @event, order);
|
||||||
if (@event.ForcedPush)
|
return;
|
||||||
config = _pushConfigs.FirstOrDefault(x => x.TrackCode == @event.TrackCode);
|
}
|
||||||
// 推断 本次推送 是否可行
|
|
||||||
else
|
if (config is { IsAllPush: true })
|
||||||
config = GetValidPushConfigAsync(_pushConfigs, order.LatestPushTrackCode, @event.TrackCode);
|
{
|
||||||
|
// 非强制推送需要 推断 本次推送 是否可行
|
||||||
|
if (!@event.ForcedPush)
|
||||||
|
{
|
||||||
|
var (resultConfig, nextCode) = GetValidPushConfigAsync(_pushConfigs, order.LatestPushTrackCode, @event.TrackCode);
|
||||||
|
if (resultConfig == null)
|
||||||
|
{
|
||||||
|
TrackPushFailedPublicTopic($"推送顺序异常,下一个要推送的应为[{nextCode}]", @event, order);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
config = resultConfig;
|
||||||
|
}
|
||||||
|
|
||||||
|
// tips:强制推送直接使用配置
|
||||||
}
|
}
|
||||||
|
|
||||||
if (config == null) continue;
|
|
||||||
|
|
||||||
//配置的类型如何和订单类型不一致则不允许推送
|
//配置的类型如何和订单类型不一致则不允许推送
|
||||||
if (config.OrderType != order.OrderType) continue;
|
if (config.OrderType != order.OrderType)
|
||||||
|
{
|
||||||
|
TrackPushFailedPublicTopic($"订单类型{order.OrderType}和配置中的订单类型[{config.OrderType}]不一致,不能推送", @event, order);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
var log = new TrackPushRecordIndex
|
var log = new TrackPushRecordIndex
|
||||||
{
|
{
|
||||||
@ -173,7 +216,7 @@ public class TrackPushEventHandler : ITransientDependency, ICapSubscribe
|
|||||||
IsToMq = @event.IsToMq,
|
IsToMq = @event.IsToMq,
|
||||||
Extra = @event.SystemPushInfo.Extra
|
Extra = @event.SystemPushInfo.Extra
|
||||||
};
|
};
|
||||||
var item = await BuiltPushItem(config, log, @event.SystemPushInfo.Extra);
|
var item = await BuiltPushItem(config, log, @event.SystemPushInfo.CompareFields);
|
||||||
item.Log = JsonConvert.SerializeObject(log);
|
item.Log = JsonConvert.SerializeObject(log);
|
||||||
items.Add(item);
|
items.Add(item);
|
||||||
}
|
}
|
||||||
@ -193,6 +236,7 @@ public class TrackPushEventHandler : ITransientDependency, ICapSubscribe
|
|||||||
|
|
||||||
if (r.Code != GlobalConst.SuccessCode)
|
if (r.Code != GlobalConst.SuccessCode)
|
||||||
{
|
{
|
||||||
|
TrackPushFailedPublicTopic($"轨迹中台调用接口通失败,RequestId: {r.RequestId}; Msg: {r.Msg}", @event, r.RequestId, items.Cast<dynamic>().ToList());
|
||||||
throw new BusinessException(message: $"requestId: {r.RequestId}; serviceProviderCode:{serviceProviderCode} Msg: {r.Msg}");
|
throw new BusinessException(message: $"requestId: {r.RequestId}; serviceProviderCode:{serviceProviderCode} Msg: {r.Msg}");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -207,7 +251,11 @@ public class TrackPushEventHandler : ITransientDependency, ICapSubscribe
|
|||||||
foreach (var order in _orders)
|
foreach (var order in _orders)
|
||||||
{
|
{
|
||||||
//配置的类型如何和订单类型不一致则不允许推送
|
//配置的类型如何和订单类型不一致则不允许推送
|
||||||
if (config.OrderType != order.OrderType) continue;
|
if (config.OrderType != order.OrderType)
|
||||||
|
{
|
||||||
|
TrackPushFailedPublicTopic($"订单类型{order.OrderType}和配置中的订单类型[{config.OrderType}]不一致,不能推送", @event, order);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
var log = new TrackPushRecordIndex
|
var log = new TrackPushRecordIndex
|
||||||
{
|
{
|
||||||
@ -225,7 +273,7 @@ public class TrackPushEventHandler : ITransientDependency, ICapSubscribe
|
|||||||
IsToMq = @event.IsToMq,
|
IsToMq = @event.IsToMq,
|
||||||
Extra = @event.SystemPushInfo.Extra
|
Extra = @event.SystemPushInfo.Extra
|
||||||
};
|
};
|
||||||
var item = BuiltUpdateItem(config, log, @event.SystemPushInfo.Extra);
|
var item = BuiltUpdateItem(config, log);
|
||||||
item.Log = JsonConvert.SerializeObject(log);
|
item.Log = JsonConvert.SerializeObject(log);
|
||||||
items.Add(item);
|
items.Add(item);
|
||||||
}
|
}
|
||||||
@ -244,12 +292,13 @@ public class TrackPushEventHandler : ITransientDependency, ICapSubscribe
|
|||||||
|
|
||||||
if (r.Code != GlobalConst.SuccessCode)
|
if (r.Code != GlobalConst.SuccessCode)
|
||||||
{
|
{
|
||||||
|
TrackPushFailedPublicTopic($"轨迹中台调用接口通失败,RequestId: {r.RequestId}; Msg: {r.Msg}", @event, r.RequestId, items.Cast<dynamic>().ToList());
|
||||||
throw new BusinessException(message: $"requestId: {r.RequestId}; serviceProviderCode:{serviceProviderCode} Msg: {r.Msg}");
|
throw new BusinessException(message: $"requestId: {r.RequestId}; serviceProviderCode:{serviceProviderCode} Msg: {r.Msg}");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private TrackUpdateInput BuiltUpdateItem(TrackPushContentConfigDto config, TrackPushRecordIndex log, string? extraJson)
|
private TrackUpdateInput BuiltUpdateItem(TrackPushContentConfigDto config, TrackPushRecordIndex log)
|
||||||
{
|
{
|
||||||
var trackDatetime = log.TrackTime.AddHours(config.TrackTimeZone ?? log.TrackTimeZone - log.TrackTimeZone);
|
var trackDatetime = log.TrackTime.AddHours(config.TrackTimeZone ?? log.TrackTimeZone - log.TrackTimeZone);
|
||||||
var trackDateStr = DateTimeFormat(trackDatetime, config.TrackTimeZone ?? log.TrackTimeZone, config);
|
var trackDateStr = DateTimeFormat(trackDatetime, config.TrackTimeZone ?? log.TrackTimeZone, config);
|
||||||
@ -268,7 +317,7 @@ public class TrackPushEventHandler : ITransientDependency, ICapSubscribe
|
|||||||
{ "descriptionCn", config.TrackContentValue },
|
{ "descriptionCn", config.TrackContentValue },
|
||||||
{ "code", config.TrackContentCodeValue },
|
{ "code", config.TrackContentCodeValue },
|
||||||
{ "status", config.TrackStatusValue },
|
{ "status", config.TrackStatusValue },
|
||||||
{ "extra", DeserializeForTextJson<object>(extraJson) }
|
{ "extra", DeserializeForTextJson<object>(log.Extra) }
|
||||||
};
|
};
|
||||||
body.Data.Add(dict);
|
body.Data.Add(dict);
|
||||||
log.PushContent = body.ToJson();
|
log.PushContent = body.ToJson();
|
||||||
@ -276,7 +325,8 @@ public class TrackPushEventHandler : ITransientDependency, ICapSubscribe
|
|||||||
return body;
|
return body;
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task<TrackPushInput> BuiltPushItem(TrackPushContentConfigDto config, TrackPushRecordIndex log, string? extraJson)
|
private async Task<TrackPushInput> BuiltPushItem(TrackPushContentConfigDto config, TrackPushRecordIndex log,
|
||||||
|
string? compareFields)
|
||||||
{
|
{
|
||||||
var trackDatetime = log.TrackTime.AddHours(config.TrackTimeZone ?? log.TrackTimeZone - log.TrackTimeZone);
|
var trackDatetime = log.TrackTime.AddHours(config.TrackTimeZone ?? log.TrackTimeZone - log.TrackTimeZone);
|
||||||
var trackDateStr = DateTimeFormat(trackDatetime, config.TrackTimeZone ?? log.TrackTimeZone, config);
|
var trackDateStr = DateTimeFormat(trackDatetime, config.TrackTimeZone ?? log.TrackTimeZone, config);
|
||||||
@ -285,7 +335,7 @@ public class TrackPushEventHandler : ITransientDependency, ICapSubscribe
|
|||||||
{
|
{
|
||||||
OrderNo = log.OrderNo,
|
OrderNo = log.OrderNo,
|
||||||
};
|
};
|
||||||
var dict = new Dictionary<string, object?>()
|
var cur = new Dictionary<string, object?>
|
||||||
{
|
{
|
||||||
// 推真实的发生地和发生时间(时间是计算后的)
|
// 推真实的发生地和发生时间(时间是计算后的)
|
||||||
{ "location", log.TrackPlace },
|
{ "location", log.TrackPlace },
|
||||||
@ -295,9 +345,9 @@ public class TrackPushEventHandler : ITransientDependency, ICapSubscribe
|
|||||||
{ "descriptionCn", config.TrackContentValue },
|
{ "descriptionCn", config.TrackContentValue },
|
||||||
{ "code", config.TrackContentCodeValue },
|
{ "code", config.TrackContentCodeValue },
|
||||||
{ "status", config.TrackStatusValue },
|
{ "status", config.TrackStatusValue },
|
||||||
{ "extra", DeserializeForTextJson<object>(extraJson) }
|
{ "extra", DeserializeForTextJson<object>(log.Extra) }
|
||||||
};
|
};
|
||||||
body.Data.Add(dict);
|
body.Data.Add(cur);
|
||||||
|
|
||||||
if (config.IsAllPush)
|
if (config.IsAllPush)
|
||||||
{
|
{
|
||||||
@ -305,7 +355,23 @@ public class TrackPushEventHandler : ITransientDependency, ICapSubscribe
|
|||||||
if (history != default)
|
if (history != default)
|
||||||
{
|
{
|
||||||
body = DeserializeForTextJson<TrackPushInput>(history.PushContent);
|
body = DeserializeForTextJson<TrackPushInput>(history.PushContent);
|
||||||
body!.Data.Add(dict);
|
if (config.IsAllPushWithLatest)
|
||||||
|
{
|
||||||
|
var old = body!.Data
|
||||||
|
.Where(x => x["code"] == cur["code"])
|
||||||
|
.WhereIf(!compareFields.IsNullOrWhiteSpace(), x =>
|
||||||
|
{
|
||||||
|
if (x["extra"] == null || log.Extra == null) return false;
|
||||||
|
return EqExtraByFieldForTextJson(x["extra"]!, DeserializeForTextJson<JsonElement>(log.Extra)!, compareFields!);
|
||||||
|
})
|
||||||
|
.FirstOrDefault();
|
||||||
|
if (old != null)
|
||||||
|
{
|
||||||
|
body.Data.Remove(old);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
body!.Data.Add(cur);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -318,7 +384,7 @@ public class TrackPushEventHandler : ITransientDependency, ICapSubscribe
|
|||||||
/// 根据轨迹代码推断下一个(升序)要推送的内容,如果找不到或者已经是最后一个了
|
/// 根据轨迹代码推断下一个(升序)要推送的内容,如果找不到或者已经是最后一个了
|
||||||
/// 则查询有没有可交换的推送,没有就返回null
|
/// 则查询有没有可交换的推送,没有就返回null
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private static TrackPushContentConfigDto? GetValidPushConfigAsync(List<TrackPushContentConfigDto> cache,
|
private static (TrackPushContentConfigDto? config, string nextCode) GetValidPushConfigAsync(List<TrackPushContentConfigDto> cache,
|
||||||
string? latestPushTrackCode, string? trackCode)
|
string? latestPushTrackCode, string? trackCode)
|
||||||
{
|
{
|
||||||
var idx = cache.FindIndex(x => x.TrackCode == latestPushTrackCode);
|
var idx = cache.FindIndex(x => x.TrackCode == latestPushTrackCode);
|
||||||
@ -332,7 +398,10 @@ public class TrackPushEventHandler : ITransientDependency, ICapSubscribe
|
|||||||
// find swap
|
// find swap
|
||||||
cache.FirstOrDefault(x => x.TrackCode == cache[idx + 1].SwapTrackCode);
|
cache.FirstOrDefault(x => x.TrackCode == cache[idx + 1].SwapTrackCode);
|
||||||
|
|
||||||
return matched != null && matched.TrackCode == trackCode ? matched : default;
|
//没推完,可能不符合推送顺序
|
||||||
|
return matched != null && matched.TrackCode == trackCode
|
||||||
|
? (matched, matched.TrackCode)
|
||||||
|
: (default, matched?.TrackCode ?? cache[idx + 1].TrackCode);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -364,4 +433,79 @@ public class TrackPushEventHandler : ITransientDependency, ICapSubscribe
|
|||||||
{
|
{
|
||||||
return string.IsNullOrWhiteSpace(json) ? default : System.Text.Json.JsonSerializer.Deserialize<T>(json);
|
return string.IsNullOrWhiteSpace(json) ? default : System.Text.Json.JsonSerializer.Deserialize<T>(json);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//比较扩展中的某个字段的相等性
|
||||||
|
private bool EqExtraByFieldForTextJson(object a, object b, string fieldName)
|
||||||
|
{
|
||||||
|
if (a is not JsonElement aJsonElement || b is not JsonElement bJsonElement)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (aJsonElement.TryGetProperty(fieldName, out var aValue)
|
||||||
|
&& bJsonElement.TryGetProperty(fieldName, out var bValue))
|
||||||
|
{
|
||||||
|
return aValue.ToString() == bValue.ToString();
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
//轨迹推送失败(被拦截)
|
||||||
|
private void TrackPushFailedPublicTopic(
|
||||||
|
string failedMessage,
|
||||||
|
TrackPushEvent @event,
|
||||||
|
OrderEntity order)
|
||||||
|
{
|
||||||
|
_broadcastingService.TrackPushFailedPubilcTopic(new TrackPushRecordDto
|
||||||
|
{
|
||||||
|
//还没请求接口通
|
||||||
|
RequestId = null,
|
||||||
|
IsSuccess = false,
|
||||||
|
Message = failedMessage,
|
||||||
|
OperationMan = @event.OperationMan,
|
||||||
|
PushTime = DateTime.Now,
|
||||||
|
OptionType = @event.OptionType.ToString(),
|
||||||
|
IsManualPush = @event.OperationMan != null,
|
||||||
|
//还没到构建推送内容那一步就被拦截
|
||||||
|
PushContent = string.Empty,
|
||||||
|
OrderNo = order.OrderNo,
|
||||||
|
TrackStatus = @event.SystemPushInfo.TrackStatus,
|
||||||
|
TrackContent = @event.SystemPushInfo.TrackStatus,
|
||||||
|
TrackTimeZone = @event.SystemPushInfo.TrackTimeZone,
|
||||||
|
TrackTime = @event.SystemPushInfo.TrackTime,
|
||||||
|
TrackPlace = @event.SystemPushInfo.TrackPlace,
|
||||||
|
TrackCode = @event.TrackCode,
|
||||||
|
Extra = @event.SystemPushInfo.Extra,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
//轨迹推送失败(请求接口通)
|
||||||
|
private void TrackPushFailedPublicTopic(
|
||||||
|
string failedMessage,
|
||||||
|
TrackPushEvent @event,
|
||||||
|
Guid requestId,
|
||||||
|
List<dynamic> pushOrUpdateInputs)
|
||||||
|
{
|
||||||
|
foreach (var pushInput in pushOrUpdateInputs)
|
||||||
|
{
|
||||||
|
_broadcastingService.TrackPushFailedPubilcTopic(new TrackPushRecordDto
|
||||||
|
{
|
||||||
|
RequestId = requestId,
|
||||||
|
IsSuccess = false,
|
||||||
|
Message = failedMessage,
|
||||||
|
OperationMan = @event.OperationMan,
|
||||||
|
PushTime = DateTime.Now,
|
||||||
|
OptionType = @event.OptionType.ToString(),
|
||||||
|
IsManualPush = @event.OperationMan != null,
|
||||||
|
PushContent = SerializeForTextJson(pushInput),
|
||||||
|
OrderNo = pushInput.OrderNo,
|
||||||
|
TrackStatus = @event.SystemPushInfo.TrackStatus,
|
||||||
|
TrackContent = @event.SystemPushInfo.TrackStatus,
|
||||||
|
TrackTimeZone = @event.SystemPushInfo.TrackTimeZone,
|
||||||
|
TrackTime = @event.SystemPushInfo.TrackTime,
|
||||||
|
TrackPlace = @event.SystemPushInfo.TrackPlace,
|
||||||
|
TrackCode = @event.TrackCode,
|
||||||
|
Extra = @event.SystemPushInfo.Extra,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,4 +1,7 @@
|
|||||||
|
using System.Diagnostics;
|
||||||
|
using System.Text.Json;
|
||||||
using DotNetCore.CAP;
|
using DotNetCore.CAP;
|
||||||
|
using Microsoft.Extensions.Logging;
|
||||||
using SJZY.Expand.ABP.Core.Logger;
|
using SJZY.Expand.ABP.Core.Logger;
|
||||||
using SJZY.Expand.ABP.Core.PublicMethords;
|
using SJZY.Expand.ABP.Core.PublicMethords;
|
||||||
using SJZY.Track.Application.Contract.Events;
|
using SJZY.Track.Application.Contract.Events;
|
||||||
@ -20,6 +23,7 @@ public class TrackUpsertEventHandler : ITransientDependency, ICapSubscribe
|
|||||||
private readonly IProvideQueries _provideQueries;
|
private readonly IProvideQueries _provideQueries;
|
||||||
private readonly ITrackDetailsEsRepository _trackDetailsEsRepository;
|
private readonly ITrackDetailsEsRepository _trackDetailsEsRepository;
|
||||||
private readonly IBroadcastingService _broadcastingService;
|
private readonly IBroadcastingService _broadcastingService;
|
||||||
|
private readonly ILogger<TrackUpsertEventHandler> _logger;
|
||||||
private readonly IOrderOperationRecordEsRepository _orderOperationRecordEsRepository;
|
private readonly IOrderOperationRecordEsRepository _orderOperationRecordEsRepository;
|
||||||
|
|
||||||
public TrackUpsertEventHandler(
|
public TrackUpsertEventHandler(
|
||||||
@ -28,7 +32,8 @@ public class TrackUpsertEventHandler : ITransientDependency, ICapSubscribe
|
|||||||
IProvideQueries provideQueries,
|
IProvideQueries provideQueries,
|
||||||
ITrackDetailsEsRepository trackDetailsEsRepository,
|
ITrackDetailsEsRepository trackDetailsEsRepository,
|
||||||
IOrderOperationRecordEsRepository orderOperationRecordEsRepository,
|
IOrderOperationRecordEsRepository orderOperationRecordEsRepository,
|
||||||
IBroadcastingService broadcastingService)
|
IBroadcastingService broadcastingService,
|
||||||
|
ILogger<TrackUpsertEventHandler> logger)
|
||||||
{
|
{
|
||||||
_orderRepository = orderRepository;
|
_orderRepository = orderRepository;
|
||||||
_capPublisher = capPublisher;
|
_capPublisher = capPublisher;
|
||||||
@ -36,6 +41,7 @@ public class TrackUpsertEventHandler : ITransientDependency, ICapSubscribe
|
|||||||
_trackDetailsEsRepository = trackDetailsEsRepository;
|
_trackDetailsEsRepository = trackDetailsEsRepository;
|
||||||
_orderOperationRecordEsRepository = orderOperationRecordEsRepository;
|
_orderOperationRecordEsRepository = orderOperationRecordEsRepository;
|
||||||
_broadcastingService = broadcastingService;
|
_broadcastingService = broadcastingService;
|
||||||
|
_logger = logger;
|
||||||
}
|
}
|
||||||
|
|
||||||
[CapSubscribe(GlobalConst.TrackUpsertSubscribe, Group = GlobalConst.TrackUpsertSubscribe)]
|
[CapSubscribe(GlobalConst.TrackUpsertSubscribe, Group = GlobalConst.TrackUpsertSubscribe)]
|
||||||
@ -216,6 +222,7 @@ public class TrackUpsertEventHandler : ITransientDependency, ICapSubscribe
|
|||||||
TrackPlace = @event.TrackPlace,
|
TrackPlace = @event.TrackPlace,
|
||||||
TrackTime = @event.NewTrackTime ?? @event.TrackTime,
|
TrackTime = @event.NewTrackTime ?? @event.TrackTime,
|
||||||
TrackTimeZone = @event.TrackTimeZone,
|
TrackTimeZone = @event.TrackTimeZone,
|
||||||
|
CompareFields = @event.CompareFields,
|
||||||
Extra = @event.Extra
|
Extra = @event.Extra
|
||||||
},
|
},
|
||||||
ForcedPush = @event.ForcedPush,
|
ForcedPush = @event.ForcedPush,
|
||||||
@ -232,76 +239,149 @@ public class TrackUpsertEventHandler : ITransientDependency, ICapSubscribe
|
|||||||
var orderIds = @event.OrderIdentifiers.Select(x => x.OrderId).ToArray();
|
var orderIds = @event.OrderIdentifiers.Select(x => x.OrderId).ToArray();
|
||||||
|
|
||||||
// important:轨迹code相同,时间、发生地不同的,可能存在多条!!
|
// important:轨迹code相同,时间、发生地不同的,可能存在多条!!
|
||||||
var tracks = await _trackDetailsEsRepository.GetListAsync(orderIds, @event.TrackCode, false);
|
var tracks = await _trackDetailsEsRepository.GetListAsync(orderIds, @event.TrackCode, true);
|
||||||
|
|
||||||
var insertTracks = new List<TrackDetailsIndex>();
|
var insertTracks = new List<TrackDetailsIndex>();
|
||||||
var updateTracks = new List<TrackDetailsIndex>();
|
var updateTracks = new List<TrackDetailsIndex>();
|
||||||
|
|
||||||
foreach (var order in @event.OrderIdentifiers)
|
foreach (var order in @event.OrderIdentifiers)
|
||||||
{
|
{
|
||||||
TrackDetailsIndex? track;
|
// fast path: by update with es id case
|
||||||
if (!@event.IsAdd)
|
if (!@event.IsAdd && !string.IsNullOrWhiteSpace(@event.EsId))
|
||||||
{
|
{
|
||||||
//如果命中了esId
|
var trackById = tracks.FirstOrDefault(x => x.Id == @event.EsId);
|
||||||
track = string.IsNullOrWhiteSpace(@event.EsId)
|
if (trackById != null)
|
||||||
? null
|
{
|
||||||
: tracks.FirstOrDefault(x => x.Id == @event.EsId);
|
updateTracks.Add(BuiltUpdateTrack(@event, trackById, order, trackContent));
|
||||||
if (track != null) goto TipEsIdTrack;
|
}
|
||||||
|
|
||||||
//同一订单同轨迹code同一轨迹时间如果有多条轨迹明细则不允许修改
|
|
||||||
var existTracks = tracks.Where(x => x.OrderId == order.OrderId
|
|
||||||
&& x.TrackTime == @event.TrackTime).ToArray();
|
|
||||||
if (existTracks.Length > 1)
|
|
||||||
{
|
|
||||||
// 修改轨迹时,订单存在多条轨迹不允许修改
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
track = existTracks.FirstOrDefault();
|
var existTracks = tracks.Where(x => x.OrderId == order.OrderId).ToList();
|
||||||
|
|
||||||
if (track == null) continue; // 不存在不让改
|
if (@event.CompareFields.IsNullOrEmpty())
|
||||||
|
{
|
||||||
|
existTracks = existTracks.Where(x => x.TrackTime == @event.TrackTime).ToList();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// 【批量新增】所有可能遇到的场景
|
Debug.Assert(@event.CompareFields != null, "@event.CompareFields != null");
|
||||||
// 标识:允许重复,不允许重复,零条,一条,多条;
|
var extraDict = GetExtraDictForTextJson(@event.Extra);
|
||||||
// 场景A:允许重复,零条 => 新增
|
if (extraDict == null || !extraDict.TryGetValue(@event.CompareFields, out var compareValue))
|
||||||
// 场景B:允许重复,一条 => 新增(约束受限新增,否则跳过新增)
|
{
|
||||||
// 场景C:允许重复,多条 => 新增(约束受限新增,否则跳过新增)
|
throw new BusinessException(message: $"请检查拓展字段,为什么找不到比较字段:{@event.CompareFields}");
|
||||||
// 场景D:不允许重复,零条 => 新增
|
}
|
||||||
// 场景E:不允许重复,一条 => 跳过
|
|
||||||
// 场景F:不允许重复,(理想不会出现多条) => 跳过
|
|
||||||
var existTracks = tracks.Where(x => x.OrderId == order.OrderId).ToArray();
|
|
||||||
track = existTracks.FirstOrDefault();
|
|
||||||
|
|
||||||
//覆盖场景:B,C
|
existTracks = existTracks.Where(x =>
|
||||||
if (trackContent.IsRepeatable && existTracks.Length >= 1)
|
|
||||||
{
|
{
|
||||||
if (existTracks.Any(x => x.TrackTime == @event.TrackTime))
|
var oldExtraDict = GetExtraDictForTextJson(x.Extra);
|
||||||
|
// tips:注意兼容性,历史轨迹的字段可能为空
|
||||||
|
if (oldExtraDict == null|| !oldExtraDict.TryGetValue(@event.CompareFields, out var oldValue))
|
||||||
{
|
{
|
||||||
//TrackCode TrackTime联合不能重复
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return EqJsonElementObject(oldValue, compareValue);
|
||||||
|
}).ToList();
|
||||||
|
}
|
||||||
|
|
||||||
|
var track = existTracks.FirstOrDefault();
|
||||||
|
|
||||||
|
if (!@event.IsAdd)
|
||||||
|
{
|
||||||
|
if (existTracks.Count > 1)
|
||||||
|
{
|
||||||
|
// todo: 所有的event handle 多写log,取缔注释,特别是continue,return,这种跳出的地方,方便排查问题
|
||||||
|
_logger.LogInformation("订单存在多条轨迹不允许修改:{@event}", @event);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 设置null后面执行新增逻辑
|
// todo:例如这里
|
||||||
track = null;
|
if (track == null) continue; // 不存在不让改
|
||||||
}
|
|
||||||
|
|
||||||
//不允许重复,并且记录大于等于一条,跳过
|
updateTracks.Add(BuiltUpdateTrack(@event, track, order, trackContent));
|
||||||
//覆盖场景:E,F
|
}
|
||||||
if (!trackContent.IsRepeatable && existTracks.Length >= 1)
|
else
|
||||||
{
|
{
|
||||||
continue;
|
// 不允许重复轨迹,跳过
|
||||||
|
if (!trackContent.IsRepeatable && existTracks.Count > 0) continue;
|
||||||
|
|
||||||
|
insertTracks.Add(BuiltNewTrack(@event, order, trackContent));
|
||||||
}
|
}
|
||||||
|
|
||||||
//其余情况:A,D都为新增操作,无需检查数量,track为null执行新增操作
|
canNextOrderIds.Add(order.OrderId);
|
||||||
}
|
}
|
||||||
|
|
||||||
//通过esId命中了轨迹
|
if (updateTracks.Any())
|
||||||
TipEsIdTrack:
|
|
||||||
if (track == default)
|
|
||||||
{
|
{
|
||||||
track = new TrackDetailsIndex
|
//批量差异化更新轨迹
|
||||||
|
await _trackDetailsEsRepository.BulkUpdateAsync(updateTracks);
|
||||||
|
}
|
||||||
|
|
||||||
|
return insertTracks;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private 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 = @event.Content ?? trackContent.TrackContent;
|
||||||
|
track.TrackEnContent = @event.EnStatus ?? trackContent.TrackEnContent;
|
||||||
|
//S06新增
|
||||||
|
track.IsVisibility = @event.IsVisibility;
|
||||||
|
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.Extra;
|
||||||
|
|
||||||
|
// todo:如果后面写es异常了,这里日志不就不准了,这里应该和写轨迹一样,做成批量的,放到写完轨迹只会写日志
|
||||||
|
// 写入操作日志
|
||||||
|
_ = _orderOperationRecordEsRepository.AddAsync(new OrderOperationRecordIndex
|
||||||
|
{
|
||||||
|
OrderId = order.OrderId,
|
||||||
|
OrderNo = order.OrderNo,
|
||||||
|
OptionType = OrderOperationType.修改轨迹.ToString(),
|
||||||
|
Content = track.ToJson(),
|
||||||
|
CreateUserId = @event.OperationManId,
|
||||||
|
CreateUserName = @event.OperationMan ?? "",
|
||||||
|
CreateTime = DateTime.Now
|
||||||
|
});
|
||||||
|
|
||||||
|
return track;
|
||||||
|
}
|
||||||
|
|
||||||
|
private TrackDetailsIndex BuiltNewTrack(TrackUpsertEvent @event, OrderIdentifier order, TrackContentVO trackContent)
|
||||||
|
{
|
||||||
|
var track = new TrackDetailsIndex
|
||||||
{
|
{
|
||||||
SubSystemId = @event.SubSystemId,
|
SubSystemId = @event.SubSystemId,
|
||||||
OrderId = order.OrderId,
|
OrderId = order.OrderId,
|
||||||
@ -348,8 +428,8 @@ public class TrackUpsertEventHandler : ITransientDependency, ICapSubscribe
|
|||||||
track.ZeroTrackTime = Math.Abs(track.TrackTimeZone - GlobalConst.NoneTrackTimeZone) < 1
|
track.ZeroTrackTime = Math.Abs(track.TrackTimeZone - GlobalConst.NoneTrackTimeZone) < 1
|
||||||
? track.TrackTime
|
? track.TrackTime
|
||||||
: track.TrackTime.Subtract(TimeSpan.FromHours(track.TrackTimeZone));
|
: track.TrackTime.Subtract(TimeSpan.FromHours(track.TrackTimeZone));
|
||||||
insertTracks.Add(track);
|
|
||||||
|
|
||||||
|
// todo:如果后面写es异常了,这里日志不就不准了,这里应该和写轨迹一样,做成批量的,放到写完轨迹只会写日志
|
||||||
// 写入操作日志
|
// 写入操作日志
|
||||||
_ = _orderOperationRecordEsRepository.AddAsync(new OrderOperationRecordIndex
|
_ = _orderOperationRecordEsRepository.AddAsync(new OrderOperationRecordIndex
|
||||||
{
|
{
|
||||||
@ -361,70 +441,24 @@ public class TrackUpsertEventHandler : ITransientDependency, ICapSubscribe
|
|||||||
CreateUserName = @event.OperationMan ?? "",
|
CreateUserName = @event.OperationMan ?? "",
|
||||||
CreateTime = DateTime.Now
|
CreateTime = DateTime.Now
|
||||||
});
|
});
|
||||||
}
|
|
||||||
else
|
return track;
|
||||||
{
|
|
||||||
//外部轨迹,轨迹发生地,轨迹发生时间,轨迹发生时区,不允许更改
|
|
||||||
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
|
private Dictionary<string, object?>? GetExtraDictForTextJson(string? extraStr)
|
||||||
? track.TrackTime
|
|
||||||
: track.TrackTime.Subtract(TimeSpan.FromHours(track.TrackTimeZone));
|
|
||||||
track.UpdateUser = @event.OperationMan ?? GlobalConst.SystemUser;
|
|
||||||
track.UpdateTime = DateTime.Now;
|
|
||||||
|
|
||||||
//允许二次修改,在修改了轨迹内容后进行修改轨迹操作,如果输入的轨迹内容则以输入为准
|
|
||||||
//跨子系统?
|
|
||||||
track.TrackContent = @event.Content ?? trackContent.TrackContent;
|
|
||||||
track.TrackEnContent = @event.EnStatus ?? trackContent.TrackEnContent;
|
|
||||||
//S06新增
|
|
||||||
track.IsVisibility = @event.IsVisibility;
|
|
||||||
track.Remarks = @event.Remarks ?? GlobalConst.EmptyString;
|
|
||||||
track.Files = @event.Files?.Select(x => new FileItem
|
|
||||||
{
|
{
|
||||||
OssKey = x.OssKey,
|
return string.IsNullOrWhiteSpace(extraStr)
|
||||||
FileName = x.FileName
|
? null
|
||||||
}).ToList();
|
: System.Text.Json.JsonSerializer.Deserialize<Dictionary<string, object?>>(extraStr);
|
||||||
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.Extra;
|
|
||||||
|
|
||||||
updateTracks.Add(track);
|
|
||||||
|
|
||||||
// 写入操作日志
|
|
||||||
_ = _orderOperationRecordEsRepository.AddAsync(new OrderOperationRecordIndex
|
|
||||||
{
|
|
||||||
OrderId = order.OrderId,
|
|
||||||
OrderNo = order.OrderNo,
|
|
||||||
OptionType = OrderOperationType.修改轨迹.ToString(),
|
|
||||||
Content = track.ToJson(),
|
|
||||||
CreateUserId = @event.OperationManId,
|
|
||||||
CreateUserName = @event.OperationMan ?? "",
|
|
||||||
CreateTime = DateTime.Now
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
canNextOrderIds.Add(order.OrderId);
|
private bool EqJsonElementObject(object? a, object? b)
|
||||||
}
|
|
||||||
|
|
||||||
if (updateTracks.Any())
|
|
||||||
{
|
{
|
||||||
//批量差异化更新轨迹
|
if (a is JsonElement aJsonElement && b is JsonElement bJsonElement)
|
||||||
await _trackDetailsEsRepository.BulkUpdateAsync(updateTracks);
|
{
|
||||||
|
return aJsonElement.ToString() == bJsonElement.ToString();
|
||||||
}
|
}
|
||||||
|
|
||||||
return insertTracks;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -70,7 +70,7 @@ public class TrackPushCompletedEventHandler : ITransientDependency, IRabbitHandl
|
|||||||
|
|
||||||
// 推送广播
|
// 推送广播
|
||||||
if (log.IsToMq)
|
if (log.IsToMq)
|
||||||
_broadcastingService.TrackPushCompletedPublicTopicAsync(BuildDto(log));
|
_broadcastingService.TrackPushCompletedPublicTopic(BuildDto(log));
|
||||||
|
|
||||||
// 往es 写推送日志
|
// 往es 写推送日志
|
||||||
await _trackPushRecordEsRepository.AddAsync(log);
|
await _trackPushRecordEsRepository.AddAsync(log);
|
||||||
|
|||||||
@ -86,7 +86,7 @@ public class BroadcastingService : IBroadcastingService
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="log"></param>
|
/// <param name="log"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public void TrackPushCompletedPublicTopicAsync(TrackPushRecordDto log)
|
public void TrackPushCompletedPublicTopic(TrackPushRecordDto log)
|
||||||
{
|
{
|
||||||
var data = new TrackPushCompletedEvent
|
var data = new TrackPushCompletedEvent
|
||||||
{
|
{
|
||||||
@ -111,4 +111,10 @@ public class BroadcastingService : IBroadcastingService
|
|||||||
_rabbitClientBus.Publish(GlobalConst.TrackPushExchange, $"TrackPush.{log.SubSystemCode}",
|
_rabbitClientBus.Publish(GlobalConst.TrackPushExchange, $"TrackPush.{log.SubSystemCode}",
|
||||||
Encoding.UTF8.GetBytes(data.ToJson()));
|
Encoding.UTF8.GetBytes(data.ToJson()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void TrackPushFailedPubilcTopic(TrackPushRecordDto log)
|
||||||
|
{
|
||||||
|
//暂时使用推送完成模型,后续可能会出现有区分度的模型
|
||||||
|
TrackPushCompletedPublicTopic(log);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -117,6 +117,7 @@ public class TrackPushService : ApplicationService, ITrackPushService
|
|||||||
TrackPlace = track.TrackPlace,
|
TrackPlace = track.TrackPlace,
|
||||||
TrackTime = track.TrackTime,
|
TrackTime = track.TrackTime,
|
||||||
TrackTimeZone = track.TrackTimeZone,
|
TrackTimeZone = track.TrackTimeZone,
|
||||||
|
// todo: 这里也要改,重复code问题,到底推哪个
|
||||||
Extra = track.Extra
|
Extra = track.Extra
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@ -240,6 +240,8 @@ public partial class TrackService : ApplicationService, ITrackService
|
|||||||
throw new BusinessException(message: "存在来源于外部服务商的轨迹,不允许删除");
|
throw new BusinessException(message: "存在来源于外部服务商的轨迹,不允许删除");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// todo:非必须不用goto,除非是在写算法,业务逻辑理论上都能通过if和方法规避
|
||||||
NO_DELETE_TRACK:
|
NO_DELETE_TRACK:
|
||||||
if (tracks.Count == 0)
|
if (tracks.Count == 0)
|
||||||
{
|
{
|
||||||
@ -357,6 +359,9 @@ public partial class TrackService : ApplicationService, ITrackService
|
|||||||
return new UnifyResultDto(true, true);
|
return new UnifyResultDto(true, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// todo:代码封装性太差了,拆小一点
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 批量新增、更新轨迹
|
/// 批量新增、更新轨迹
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -436,6 +441,7 @@ public partial class TrackService : ApplicationService, ITrackService
|
|||||||
.Where(x => x.TrackTime == input.TrackTime)
|
.Where(x => x.TrackTime == input.TrackTime)
|
||||||
.ToList();
|
.ToList();
|
||||||
|
|
||||||
|
// todo:这块代码抽出去
|
||||||
//当为更新操作时发现更新的数目为0进行重试操作
|
//当为更新操作时发现更新的数目为0进行重试操作
|
||||||
if (!input.IsAdd && tracks.Count == 0)
|
if (!input.IsAdd && tracks.Count == 0)
|
||||||
{
|
{
|
||||||
@ -513,6 +519,7 @@ public partial class TrackService : ApplicationService, ITrackService
|
|||||||
TrackPlacePostcode = input.TrackPlacePostcode,
|
TrackPlacePostcode = input.TrackPlacePostcode,
|
||||||
EstimatedDeliveryDate = input.EstimatedDeliveryDate,
|
EstimatedDeliveryDate = input.EstimatedDeliveryDate,
|
||||||
DestinationTimeZone = input.DestinationTimeZone,
|
DestinationTimeZone = input.DestinationTimeZone,
|
||||||
|
CompareFields = input.CompareFields,
|
||||||
Extra = input.Extra,
|
Extra = input.Extra,
|
||||||
ForcedPush = input.ForcedPush,
|
ForcedPush = input.ForcedPush,
|
||||||
IsToMq = input.IsToMq,
|
IsToMq = input.IsToMq,
|
||||||
|
|||||||
@ -51,6 +51,7 @@ public class TrackPushCacheService : ITrackPushCacheService, ITransientDependenc
|
|||||||
x.Id,
|
x.Id,
|
||||||
x.IsAutoPush,
|
x.IsAutoPush,
|
||||||
x.IsAllPush,
|
x.IsAllPush,
|
||||||
|
x.IsAllPushWithLatest,
|
||||||
x.IsCanDelete,
|
x.IsCanDelete,
|
||||||
x.IsCanUpdate,
|
x.IsCanUpdate,
|
||||||
x.SubSystemId,
|
x.SubSystemId,
|
||||||
@ -76,6 +77,7 @@ public class TrackPushCacheService : ITrackPushCacheService, ITransientDependenc
|
|||||||
IsAutoPush = trackPushConfig.IsAutoPush,
|
IsAutoPush = trackPushConfig.IsAutoPush,
|
||||||
IsCanUpdate = trackPushConfig.IsCanUpdate,
|
IsCanUpdate = trackPushConfig.IsCanUpdate,
|
||||||
IsAllPush = trackPushConfig.IsAllPush,
|
IsAllPush = trackPushConfig.IsAllPush,
|
||||||
|
IsAllPushWithLatest = trackPushConfig.IsAllPushWithLatest,
|
||||||
IsCanDelete = trackPushConfig.IsCanDelete,
|
IsCanDelete = trackPushConfig.IsCanDelete,
|
||||||
DateTimeFormatType = (int) trackPushConfig.DateTimeFormatType,
|
DateTimeFormatType = (int) trackPushConfig.DateTimeFormatType,
|
||||||
DateTimeFormat = trackPushConfig.DateTimeFormat,
|
DateTimeFormat = trackPushConfig.DateTimeFormat,
|
||||||
@ -89,6 +91,7 @@ public class TrackPushCacheService : ITrackPushCacheService, ITransientDependenc
|
|||||||
TrackContentValue = item.TrackContentValue,
|
TrackContentValue = item.TrackContentValue,
|
||||||
TrackEnContentValue = item.TrackEnContentValue,
|
TrackEnContentValue = item.TrackEnContentValue,
|
||||||
TrackTimeZone = item.TrackTimeZone,
|
TrackTimeZone = item.TrackTimeZone,
|
||||||
|
// todo:废弃字段如果没有外部子系统依赖,可以逐步删除
|
||||||
ExpandFieldsValue = item.ExpandFieldsValue,
|
ExpandFieldsValue = item.ExpandFieldsValue,
|
||||||
}).ToList();
|
}).ToList();
|
||||||
|
|
||||||
|
|||||||
@ -56,6 +56,12 @@ public class TrackPushConfigEntity : IFullAuditedBasicEntitys, IAggregateRoot
|
|||||||
[SugarColumn(ColumnName = "IsAllPush")]
|
[SugarColumn(ColumnName = "IsAllPush")]
|
||||||
public bool IsAllPush { get; set; }
|
public bool IsAllPush { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 是否全量推送(最新轨迹)
|
||||||
|
/// </summary>
|
||||||
|
[SugarColumn(ColumnName = "IsAllPushWithLatest")]
|
||||||
|
public bool IsAllPushWithLatest { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 日期时间格式类型
|
/// 日期时间格式类型
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
@ -51,6 +51,11 @@ public class GetTrackPushConfigDetailOutputVO
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public bool IsAllPush { get; set; }
|
public bool IsAllPush { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 是否全量推送(最新轨迹)
|
||||||
|
/// </summary>
|
||||||
|
public bool IsAllPushWithLatest { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 时间格式枚举
|
/// 时间格式枚举
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
@ -19,7 +19,7 @@ public class TrackDetailsEsRepository : ElasticSearchContextAbstract<TrackDetail
|
|||||||
public async Task<List<TrackDetailsIndex>> GetListAsync(int[] orderIds, string trackCode,
|
public async Task<List<TrackDetailsIndex>> GetListAsync(int[] orderIds, string trackCode,
|
||||||
bool forUpsert = false)
|
bool forUpsert = false)
|
||||||
{
|
{
|
||||||
var r = !forUpsert
|
var r = forUpsert
|
||||||
? await Context.SearchAsync<TrackDetailsIndex>(s => s
|
? await Context.SearchAsync<TrackDetailsIndex>(s => s
|
||||||
.Index(GlobalConst.TrackDetailsIndex)
|
.Index(GlobalConst.TrackDetailsIndex)
|
||||||
.Source()
|
.Source()
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user