Merge branch 'refs/heads/S04轨迹预警' into test
This commit is contained in:
commit
89b4c3f25e
@ -5,7 +5,7 @@
|
|||||||
"Apollo": {
|
"Apollo": {
|
||||||
"AppId": "SJZY.Track.Configuration",
|
"AppId": "SJZY.Track.Configuration",
|
||||||
"Env": "DEV",
|
"Env": "DEV",
|
||||||
"Namespace": "DEV",
|
"Namespace": "Test",
|
||||||
"MetaServer": "http://apollo-service-test-apollo-configservice.apollo.svc.cluster.local:8080",
|
"MetaServer": "http://apollo-service-test-apollo-configservice.apollo.svc.cluster.local:8080",
|
||||||
"ConfigServer": [ "http://apollo-service-test-apollo-configservice.apollo.svc.cluster.local:8080" ]
|
"ConfigServer": [ "http://apollo-service-test-apollo-configservice.apollo.svc.cluster.local:8080" ]
|
||||||
}
|
}
|
||||||
|
|||||||
@ -18,5 +18,5 @@ public class TrackDetail
|
|||||||
public string? OriginContent { get; set; }
|
public string? OriginContent { get; set; }
|
||||||
public string Location { get; set; } = null!;
|
public string Location { get; set; } = null!;
|
||||||
public DateTime Time { get; set; }
|
public DateTime Time { get; set; }
|
||||||
public float TimeZone { get; set; }
|
public float? TimeZone { get; set; }
|
||||||
}
|
}
|
||||||
@ -0,0 +1,6 @@
|
|||||||
|
namespace SJZY.Track.Application.Contract.Events;
|
||||||
|
|
||||||
|
public class PushWarningEvent
|
||||||
|
{
|
||||||
|
public int PageSize { get; set; }
|
||||||
|
}
|
||||||
@ -13,13 +13,13 @@ public struct TrackRefreshStruct
|
|||||||
public string? OriginTrackContent { get; set; }
|
public string? OriginTrackContent { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 原轨迹报文
|
/// 原轨迹报文hash(刷新轨迹重复性校验使用)
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string? OriginTrackData { get; set; }
|
public string? OriginTrackDataHash { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 表示订单是否完成(只由轨迹刷新配置决定)
|
/// 表示订单是否完成(只由轨迹刷新配置决定)
|
||||||
/// tips:能够使得IsCompleted为true的点,全局只有一个:轨迹刷新
|
/// todo:能够使得IsCompleted为true的点,全局只有一个:轨迹刷新??
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public bool IsCompleted { get; set; }
|
public bool IsCompleted { get; set; }
|
||||||
}
|
}
|
||||||
@ -1,9 +1,8 @@
|
|||||||
using System.Security.Cryptography;
|
using DotNetCore.CAP.Filter;
|
||||||
using System.Text;
|
|
||||||
using DotNetCore.CAP.Filter;
|
|
||||||
using SJZY.Expand.ABP.Core;
|
using SJZY.Expand.ABP.Core;
|
||||||
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.Helpers;
|
||||||
using SJZY.Track.Domain.Consts;
|
using SJZY.Track.Domain.Consts;
|
||||||
|
|
||||||
namespace SJZY.Track.Application.CAP;
|
namespace SJZY.Track.Application.CAP;
|
||||||
@ -33,7 +32,7 @@ public class CapFilter : SubscribeFilter
|
|||||||
context.DeliverMessage.Headers.TryGetValue("sjzy-arguments-hash", out var hash);
|
context.DeliverMessage.Headers.TryGetValue("sjzy-arguments-hash", out var hash);
|
||||||
if (hash.IsNullOrEmpty()) // 计算参数hash
|
if (hash.IsNullOrEmpty()) // 计算参数hash
|
||||||
{
|
{
|
||||||
hash = GetHash(argumentJsonStr);
|
hash = StringHelper.GetHash(argumentJsonStr);
|
||||||
context.DeliverMessage.Headers["sjzy-arguments-hash"] = hash;
|
context.DeliverMessage.Headers["sjzy-arguments-hash"] = hash;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -76,22 +75,4 @@ public class CapFilter : SubscribeFilter
|
|||||||
|
|
||||||
return Task.CompletedTask;
|
return Task.CompletedTask;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/// <summary>获取字符串的hash值</summary>
|
|
||||||
/// <param name="str"></param>
|
|
||||||
/// <returns></returns>
|
|
||||||
public static string GetHash(string str)
|
|
||||||
{
|
|
||||||
// 将字符串转换为字节
|
|
||||||
byte[] data = Encoding.UTF8.GetBytes(str);
|
|
||||||
|
|
||||||
// 创建SHA256实例
|
|
||||||
using SHA256 sha256 = SHA256.Create();
|
|
||||||
// 计算哈希值
|
|
||||||
byte[] hash = sha256.ComputeHash(data);
|
|
||||||
|
|
||||||
// 将哈希值转换为16进制字符串
|
|
||||||
return BitConverter.ToString(hash);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@ -0,0 +1,43 @@
|
|||||||
|
using DotNetCore.CAP;
|
||||||
|
using Microsoft.Extensions.Logging;
|
||||||
|
using SJZY.Track.Application.Contract.Events;
|
||||||
|
using SJZY.Track.Domain.Aggregates.OrderAggregate;
|
||||||
|
using SJZY.Track.Domain.Consts;
|
||||||
|
using Volo.Abp.DependencyInjection;
|
||||||
|
|
||||||
|
namespace SJZY.Track.Application.CAP.EventHandlers;
|
||||||
|
|
||||||
|
public class PushWarningEventHandler : ITransientDependency, ICapSubscribe
|
||||||
|
{
|
||||||
|
private readonly ILogger<PushWarningEventHandler> _logger;
|
||||||
|
private readonly IOrderRepository _orderRepository;
|
||||||
|
|
||||||
|
public PushWarningEventHandler(IOrderRepository orderRepository,
|
||||||
|
ILogger<PushWarningEventHandler> logger)
|
||||||
|
{
|
||||||
|
_orderRepository = orderRepository;
|
||||||
|
_logger = logger;
|
||||||
|
}
|
||||||
|
|
||||||
|
[CapSubscribe(GlobalConst.TrackPushWarning)]
|
||||||
|
public async Task Handle(PushWarningEvent @event)
|
||||||
|
{
|
||||||
|
int total = 0, pageSize = @event.PageSize, waitTime = 1000;
|
||||||
|
var dateTimes = Enumerable.Range(1, 12).Select(val => DateTime.Now.AddHours(-val)).ToList();
|
||||||
|
|
||||||
|
foreach (var dateTime in dateTimes)
|
||||||
|
{
|
||||||
|
var rows = 0;
|
||||||
|
var pageindex = 1;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
rows = await _orderRepository.PushWarnOrdersAsync(pageSize, pageindex, dateTime);
|
||||||
|
pageindex++;
|
||||||
|
total += rows;
|
||||||
|
await Task.Delay(waitTime);
|
||||||
|
} while (rows != pageSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
_logger.LogInformation(message: "本次预警扫描了:{total}个订单", total);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -12,13 +12,14 @@ namespace SJZY.Track.Application.CAP.EventHandlers;
|
|||||||
|
|
||||||
public class TrackChangeAfterUpdateOrderEventHandler : ITransientDependency, ICapSubscribe
|
public class TrackChangeAfterUpdateOrderEventHandler : ITransientDependency, ICapSubscribe
|
||||||
{
|
{
|
||||||
private readonly IOrderRepository _orderRepository;
|
|
||||||
private readonly IForewarningNotifyService _forewarningNotifyService;
|
private readonly IForewarningNotifyService _forewarningNotifyService;
|
||||||
private readonly ITrackPullCacheService _trackPullCacheService;
|
private readonly IOrderRepository _orderRepository;
|
||||||
private readonly IProvideQueries _provideQueries;
|
private readonly IProvideQueries _provideQueries;
|
||||||
|
private readonly ITrackPullCacheService _trackPullCacheService;
|
||||||
|
|
||||||
public TrackChangeAfterUpdateOrderEventHandler(IOrderRepository orderRepository,
|
public TrackChangeAfterUpdateOrderEventHandler(IOrderRepository orderRepository,
|
||||||
IForewarningNotifyService forewarningNotifyService, ITrackPullCacheService trackPullCacheService, IProvideQueries provideQueries)
|
IForewarningNotifyService forewarningNotifyService, ITrackPullCacheService trackPullCacheService,
|
||||||
|
IProvideQueries provideQueries)
|
||||||
{
|
{
|
||||||
_orderRepository = orderRepository;
|
_orderRepository = orderRepository;
|
||||||
_forewarningNotifyService = forewarningNotifyService;
|
_forewarningNotifyService = forewarningNotifyService;
|
||||||
@ -34,7 +35,7 @@ public class TrackChangeAfterUpdateOrderEventHandler : ITransientDependency, ICa
|
|||||||
if (orders.Count == 0) return;
|
if (orders.Count == 0) return;
|
||||||
|
|
||||||
var updateOrders = new List<OrderEntity>();
|
var updateOrders = new List<OrderEntity>();
|
||||||
var providerDic= await GetProviderDic(@event.OrderIds);
|
var providerDic = await GetProviderDic(@event.OrderIds);
|
||||||
foreach (var order in orders)
|
foreach (var order in orders)
|
||||||
{
|
{
|
||||||
if (order.LatestTrackContent != @event.TrackContent)
|
if (order.LatestTrackContent != @event.TrackContent)
|
||||||
@ -48,11 +49,11 @@ public class TrackChangeAfterUpdateOrderEventHandler : ITransientDependency, ICa
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 执行轨迹兜底时 时区缺失和发生地缺失标记,1表示时区,2表示发生地,3表示两种
|
// 执行轨迹兜底时 时区缺失和发生地缺失标记,1表示时区,2表示发生地,3表示两种
|
||||||
if (@event.DeficiencyTagValue > 0 && @event.DeficiencyTagValue<=3)
|
if (@event.DeficiencyTagValue > 0 && @event.DeficiencyTagValue <= 3)
|
||||||
{
|
{
|
||||||
order.DeficiencyTag = @event.DeficiencyTagValue;
|
order.DeficiencyTag = @event.DeficiencyTagValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!order.IsCompleted)
|
if (!order.IsCompleted)
|
||||||
{
|
{
|
||||||
order.IsCompleted = @event.IsCompleted;
|
order.IsCompleted = @event.IsCompleted;
|
||||||
@ -60,15 +61,18 @@ public class TrackChangeAfterUpdateOrderEventHandler : ITransientDependency, ICa
|
|||||||
|
|
||||||
if (!string.IsNullOrEmpty(@event.TrackCode) && providerDic.TryGetValue(order.Id, out var provider))
|
if (!string.IsNullOrEmpty(@event.TrackCode) && providerDic.TryGetValue(order.Id, out var provider))
|
||||||
{
|
{
|
||||||
var config = await _trackPullCacheService.GetPullParamWithContentConfigAsync(provider.SubSystemId, provider.ServiceProviderId);
|
var config =
|
||||||
|
await _trackPullCacheService.GetPullParamWithContentConfigAsync(provider.SubSystemId,
|
||||||
if (!string.IsNullOrEmpty(config?.ParamConfig.TrackContentCode) && config.ParamConfig.TrackContentCode!.ToLower() == @event.TrackCode.ToLower())
|
provider.ServiceProviderId);
|
||||||
|
|
||||||
|
if (!string.IsNullOrEmpty(config?.ParamConfig.TrackContentCode) &&
|
||||||
|
config.ParamConfig.TrackContentCode!.ToLower() == @event.TrackCode.ToLower())
|
||||||
{
|
{
|
||||||
// 触发拉取节点
|
// 触发拉取节点
|
||||||
order.IsTriggerPull = 1;
|
order.IsTriggerPull = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
order.LatestTrackContent = @event.TrackContent;
|
order.LatestTrackContent = @event.TrackContent;
|
||||||
order.LatestTrackEnContent = @event.TrackEnContent;
|
order.LatestTrackEnContent = @event.TrackEnContent;
|
||||||
order.LatestTrackPlace = @event.TrackPlace;
|
order.LatestTrackPlace = @event.TrackPlace;
|
||||||
@ -80,7 +84,7 @@ public class TrackChangeAfterUpdateOrderEventHandler : ITransientDependency, ICa
|
|||||||
await _orderRepository.UpdateRangeAsync(updateOrders, x => new
|
await _orderRepository.UpdateRangeAsync(updateOrders, x => new
|
||||||
{
|
{
|
||||||
x.IsCompleted, x.LatestTrackContent, x.LatestTrackEnContent, x.LatestTrackPlace, x.LatestTrackTime,
|
x.IsCompleted, x.LatestTrackContent, x.LatestTrackEnContent, x.LatestTrackPlace, x.LatestTrackTime,
|
||||||
x.LatestTrackTimeZone,x.IsTriggerPull,x.DeficiencyTag
|
x.LatestTrackTimeZone, x.IsTriggerPull, x.DeficiencyTag
|
||||||
});
|
});
|
||||||
|
|
||||||
// 预警计算
|
// 预警计算
|
||||||
@ -110,7 +114,8 @@ public class TrackChangeAfterUpdateOrderEventHandler : ITransientDependency, ICa
|
|||||||
ArrivalPostCode = order.ArrivalPostCode,
|
ArrivalPostCode = order.ArrivalPostCode,
|
||||||
IsTransit = order.IsTransit,
|
IsTransit = order.IsTransit,
|
||||||
LeavePort = order.LeavePort,
|
LeavePort = order.LeavePort,
|
||||||
ProductCode = order.ProductCode
|
ProductCode = order.ProductCode,
|
||||||
|
IsTriggerPull = order.IsTriggerPull
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -139,7 +144,7 @@ public class TrackChangeAfterUpdateOrderEventHandler : ITransientDependency, ICa
|
|||||||
}).ToList()
|
}).ToList()
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 获取服务商字典
|
/// 获取服务商字典
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
@ -1,50 +0,0 @@
|
|||||||
using DotNetCore.CAP;
|
|
||||||
using SJZY.Track.Application.Contract.Events;
|
|
||||||
using SJZY.Track.Domain.Aggregates.TrackDetailsAggregate;
|
|
||||||
using SJZY.Track.Domain.Consts;
|
|
||||||
using Volo.Abp.DependencyInjection;
|
|
||||||
|
|
||||||
namespace SJZY.Track.Application.CAP.EventHandlers;
|
|
||||||
|
|
||||||
public class TrackInsertForNotMappedEventHandler : ITransientDependency, ICapSubscribe
|
|
||||||
{
|
|
||||||
private readonly ITrackDetailsRepository _trackDetailsRepository;
|
|
||||||
|
|
||||||
public TrackInsertForNotMappedEventHandler(ITrackDetailsRepository trackDetailsRepository)
|
|
||||||
{
|
|
||||||
_trackDetailsRepository = trackDetailsRepository;
|
|
||||||
}
|
|
||||||
|
|
||||||
[CapSubscribe(GlobalConst.TrackInsertForNotMappedEventSubscribe)]
|
|
||||||
public async Task ConsumerAsync(TrackInsertForNotMappedEvent @event)
|
|
||||||
{
|
|
||||||
if (await _trackDetailsRepository.AnyAsync(@event.OrderId, @event.TrackTime))
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 新增服务商轨迹到es
|
|
||||||
var track = new TrackDetailsIndex
|
|
||||||
{
|
|
||||||
IndexName = $"{GlobalConst.TrackIndex}-{DateTime.Now:yyyy.MM.dd}",
|
|
||||||
OrderId = @event.OrderId,
|
|
||||||
OrderNo = @event.OrderNo,
|
|
||||||
OrderType = @event.OrderType,
|
|
||||||
TrackPlace = @event.TrackPlace,
|
|
||||||
TrackTime = @event.TrackTime,
|
|
||||||
TrackTimeZone = @event.TrackTimeZone,
|
|
||||||
ServiceProviderName = @event.ServiceProviderName,
|
|
||||||
OriginTrackContent = @event.OriginTrackContent,
|
|
||||||
OriginTrackData = @event.OriginTrackData,
|
|
||||||
CreateUser = GlobalConst.SystemUser,
|
|
||||||
CreateTime = DateTime.Now
|
|
||||||
};
|
|
||||||
track.TrackCode = GlobalConst.EmptyString;
|
|
||||||
track.TrackStatus = GlobalConst.EmptyString;
|
|
||||||
track.TrackContent = GlobalConst.EmptyString;
|
|
||||||
track.TrackEnContent = GlobalConst.EmptyString;
|
|
||||||
track.ZeroTrackTime = track.TrackTime.Subtract(TimeSpan.FromHours(track.TrackTimeZone));
|
|
||||||
|
|
||||||
await _trackDetailsRepository.AddAsync(track);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -19,11 +19,11 @@ namespace SJZY.Track.Application.CAP.EventHandlers;
|
|||||||
|
|
||||||
public class TrackRefreshEventHandler : ITransientDependency, ICapSubscribe
|
public class TrackRefreshEventHandler : ITransientDependency, ICapSubscribe
|
||||||
{
|
{
|
||||||
private readonly IOrderRepository _orderRepository;
|
|
||||||
private readonly ICapPublisher _capPublisher;
|
private readonly ICapPublisher _capPublisher;
|
||||||
private readonly ITrackPullCacheService _trackPullCacheService;
|
private readonly IOrderRepository _orderRepository;
|
||||||
private readonly ITrackDetailsRepository _trackDetailsRepository;
|
|
||||||
private readonly ITimezoneQueries _timezoneQueries;
|
private readonly ITimezoneQueries _timezoneQueries;
|
||||||
|
private readonly ITrackDetailsRepository _trackDetailsRepository;
|
||||||
|
private readonly ITrackPullCacheService _trackPullCacheService;
|
||||||
|
|
||||||
public TrackRefreshEventHandler(IOrderRepository orderRepository,
|
public TrackRefreshEventHandler(IOrderRepository orderRepository,
|
||||||
ICapPublisher capPublisher, ITrackPullCacheService trackPullCacheService,
|
ICapPublisher capPublisher, ITrackPullCacheService trackPullCacheService,
|
||||||
@ -48,7 +48,8 @@ public class TrackRefreshEventHandler : ITransientDependency, ICapSubscribe
|
|||||||
if (@event.Data == null || config == null) return;
|
if (@event.Data == null || config == null) return;
|
||||||
|
|
||||||
var data = JObject.Parse(@event.Data);
|
var data = JObject.Parse(@event.Data);
|
||||||
var orderToken = data[config.ParamConfig.OrderPath];
|
|
||||||
|
var orderToken = data.SelectToken(config.ParamConfig.OrderPath);
|
||||||
if (orderToken is JArray orderTokens)
|
if (orderToken is JArray orderTokens)
|
||||||
{
|
{
|
||||||
foreach (var token in orderTokens)
|
foreach (var token in orderTokens)
|
||||||
@ -69,7 +70,7 @@ public class TrackRefreshEventHandler : ITransientDependency, ICapSubscribe
|
|||||||
var orderNo = orderToken[paramConfig.OrderNoName]?.Value<string>();
|
var orderNo = orderToken[paramConfig.OrderNoName]?.Value<string>();
|
||||||
if (orderNo.IsNullOrWhiteSpace()) return;
|
if (orderNo.IsNullOrWhiteSpace()) return;
|
||||||
|
|
||||||
var trackToken = orderToken[paramConfig.TrackDetailsPath];
|
var trackToken = orderToken.SelectToken(paramConfig.TrackDetailsPath);
|
||||||
if (trackToken is null) return;
|
if (trackToken is null) return;
|
||||||
|
|
||||||
var order = await _orderRepository.GetFirstAsync(x =>
|
var order = await _orderRepository.GetFirstAsync(x =>
|
||||||
@ -106,42 +107,46 @@ public class TrackRefreshEventHandler : ITransientDependency, ICapSubscribe
|
|||||||
private async Task HandleTrackAsync(JToken trackToken, TrackPullParamWithContentConfigDto paramWithContentConfig,
|
private async Task HandleTrackAsync(JToken trackToken, TrackPullParamWithContentConfigDto paramWithContentConfig,
|
||||||
TrackRefreshContext context)
|
TrackRefreshContext context)
|
||||||
{
|
{
|
||||||
var originTrackData = JsonConvert.SerializeObject(trackToken);
|
var originTrackDataHash = StringHelper.GetHash(JsonConvert.SerializeObject(trackToken));
|
||||||
// 如果已经存在一模一样的报文了说明处理过了,直接return
|
// 如果已经存在一模一样的报文了说明处理过了,直接return
|
||||||
if (await _trackDetailsRepository.AnyAsync(context.OrderId, originTrackData)) return;
|
if (await _trackDetailsRepository.AnyAsync(context.OrderId, originTrackDataHash))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
var paramConfig = paramWithContentConfig.ParamConfig;
|
var paramConfig = paramWithContentConfig.ParamConfig;
|
||||||
var contentConfigs = paramWithContentConfig.ContentConfigs;
|
var contentConfigs = paramWithContentConfig.ContentConfigs;
|
||||||
TrackPullContentConfigDto? matchedContentConfig = null;
|
TrackPullContentConfigDto? matchedContentConfig = null;
|
||||||
|
|
||||||
// 1、匹配轨迹代码
|
// 1、匹配轨迹代码
|
||||||
if (paramConfig.TrackContentCodeName != null)
|
if (!paramConfig.TrackContentCodeName.IsNullOrWhiteSpace())
|
||||||
{
|
{
|
||||||
var trackCode = trackToken[paramConfig.TrackContentCodeName]?.Value<string>();
|
var trackCode = trackToken[paramConfig.TrackContentCodeName!]?.Value<string>();
|
||||||
if (!trackCode.IsNullOrWhiteSpace())
|
if (!trackCode.IsNullOrWhiteSpace())
|
||||||
{
|
{
|
||||||
matchedContentConfig = contentConfigs.FirstOrDefault(x => x.TrackContentCodeValue == trackCode);
|
matchedContentConfig = contentConfigs.FirstOrDefault(x => x.TrackContentCodeValue == trackCode);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// 2、匹配轨迹状态
|
// 2、匹配轨迹状态
|
||||||
else if (paramConfig.TrackStatusName != null)
|
else if (!paramConfig.TrackStatusName.IsNullOrWhiteSpace())
|
||||||
{
|
{
|
||||||
var trackStatus = trackToken[paramConfig.TrackStatusName]?.Value<string>();
|
var trackStatus = trackToken[paramConfig.TrackStatusName!]?.Value<string>();
|
||||||
if (!trackStatus.IsNullOrWhiteSpace())
|
if (!trackStatus.IsNullOrWhiteSpace())
|
||||||
{
|
{
|
||||||
matchedContentConfig = contentConfigs.FirstOrDefault(x => x.TrackStatusValue == trackStatus);
|
matchedContentConfig = contentConfigs.FirstOrDefault(x => x.TrackStatusValue == trackStatus);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// 3、匹配轨迹内容
|
// 3、匹配轨迹内容
|
||||||
else if (paramConfig.TrackContentName != null)
|
else if (!paramConfig.TrackContentName.IsNullOrWhiteSpace())
|
||||||
{
|
{
|
||||||
var trackContent = trackToken[paramConfig.TrackContentName]?.Value<string>();
|
var trackContent = trackToken[paramConfig.TrackContentName!]?.Value<string>();
|
||||||
if (!trackContent.IsNullOrWhiteSpace())
|
if (!trackContent.IsNullOrWhiteSpace())
|
||||||
{
|
{
|
||||||
Debug.Assert(trackContent != null, nameof(trackContent) + " != null");
|
Debug.Assert(trackContent != null, nameof(trackContent) + " != null");
|
||||||
|
// 3.1 按内容直接匹配
|
||||||
matchedContentConfig = contentConfigs.FirstOrDefault(x => x.TrackContentValue == trackContent);
|
matchedContentConfig = contentConfigs.FirstOrDefault(x => x.TrackContentValue == trackContent);
|
||||||
|
|
||||||
// 按关键字分析轨迹内容
|
// 3.2 按关键字分析轨迹内容
|
||||||
if (matchedContentConfig is null)
|
if (matchedContentConfig is null)
|
||||||
{
|
{
|
||||||
foreach (var contentConfig in contentConfigs)
|
foreach (var contentConfig in contentConfigs)
|
||||||
@ -171,57 +176,22 @@ public class TrackRefreshEventHandler : ITransientDependency, ICapSubscribe
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 轨迹发生地
|
|
||||||
var trackPlace = paramConfig.TrackPlaceName == null
|
|
||||||
? null
|
|
||||||
: trackToken[paramConfig.TrackPlaceName]?.Value<string>();
|
|
||||||
var hasPlaceBottomLine = false; //执行了兜底但是没有兜底住,需要记录
|
|
||||||
if (trackPlace.IsNullOrWhiteSpace() && matchedContentConfig?.TrackPlaceValue != null && matchedContentConfig.TrackPlaceValue.HasValue)
|
|
||||||
{
|
|
||||||
//兜底没配置的就不需要兜底,拉取的发生地没就没
|
|
||||||
trackPlace = await GetPlaceByOrder(matchedContentConfig!.TrackPlaceValue.Value,context.OrderId);
|
|
||||||
hasPlaceBottomLine = string.IsNullOrWhiteSpace(trackPlace);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 轨迹发生时间
|
// 轨迹发生时间
|
||||||
var trackTime = paramConfig.TrackTimeName == null
|
var trackTime = paramConfig.TrackTimeName == null
|
||||||
? null
|
? null
|
||||||
: trackToken[paramConfig.TrackTimeName]?.Value<DateTime>();
|
: trackToken[paramConfig.TrackTimeName]?.Value<DateTime>();
|
||||||
// 轨迹发生时区
|
|
||||||
var trackTimeZone = paramConfig.TrackTimeZoneName == null
|
|
||||||
? null
|
|
||||||
: trackToken[paramConfig.TrackTimeZoneName]?.Value<float>();
|
|
||||||
|
|
||||||
//兜底时区
|
// 轨迹时区
|
||||||
var hasTimezoneBottomLine = false; //执行了兜底但是没有兜底住,需要记录
|
var (trackTimeZone, hasTimezoneBottomLine) =
|
||||||
if (!trackTimeZone.HasValue && matchedContentConfig?.TrackZonePlaceValue != null && matchedContentConfig.TrackZonePlaceValue.HasValue)
|
await GetTimezone(paramConfig, matchedContentConfig, context.OrderId, trackToken);
|
||||||
{
|
|
||||||
//兜底没配置的就不需要兜底,拉取的发生地没就没
|
// 轨迹发生地
|
||||||
var timezone= await GetTimezone(matchedContentConfig,context.OrderId);
|
var (trackPlace, hasPlaceBottomLine) =
|
||||||
|
await GetTrackPlace(paramConfig, matchedContentConfig, context.OrderId, trackToken);
|
||||||
trackTimeZone = timezone;
|
|
||||||
hasTimezoneBottomLine = !timezone.HasValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (matchedContentConfig is null)
|
if (matchedContentConfig is null)
|
||||||
{
|
{
|
||||||
var notMappedEvent = new TrackInsertForNotMappedEvent
|
await InsertNotMappedTrackAsync(trackToken, context, trackPlace, trackTime, trackTimeZone, paramConfig);
|
||||||
{
|
|
||||||
OrderId = context.OrderId,
|
|
||||||
OrderType = context.OrderType,
|
|
||||||
OrderNo = context.OrderNo,
|
|
||||||
ServiceProviderName = context.ServiceProviderName,
|
|
||||||
OriginTrackData = JsonConvert.SerializeObject(trackToken),
|
|
||||||
TrackPlace = trackPlace ?? GlobalConst.EmptyString,
|
|
||||||
TrackTime = trackTime ?? DateTime.Now,
|
|
||||||
TrackTimeZone = trackTimeZone ?? 8
|
|
||||||
};
|
|
||||||
if (paramConfig.TrackContentName != null)
|
|
||||||
{
|
|
||||||
notMappedEvent.OriginTrackContent = trackToken[paramConfig.TrackContentName]?.Value<string>();
|
|
||||||
}
|
|
||||||
|
|
||||||
await _capPublisher.PublishAsync(GlobalConst.TrackInsertForNotMappedEventSubscribe, notMappedEvent);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -234,7 +204,7 @@ public class TrackRefreshEventHandler : ITransientDependency, ICapSubscribe
|
|||||||
var timezoneTagValue = hasTimezoneBottomLine ? 1 : 0;
|
var timezoneTagValue = hasTimezoneBottomLine ? 1 : 0;
|
||||||
deficiencyTagValue = placeTagValue + timezoneTagValue;
|
deficiencyTagValue = placeTagValue + timezoneTagValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 新增/更新轨迹
|
// 新增/更新轨迹
|
||||||
var trackUpsertEvent = new TrackUpsertEvent
|
var trackUpsertEvent = new TrackUpsertEvent
|
||||||
{
|
{
|
||||||
@ -247,11 +217,11 @@ public class TrackRefreshEventHandler : ITransientDependency, ICapSubscribe
|
|||||||
OrderType = context.OrderType,
|
OrderType = context.OrderType,
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
TrackRefreshData = new TrackRefreshStruct
|
TrackRefreshData = new TrackRefreshStruct
|
||||||
{
|
{
|
||||||
ServiceProviderName = context.ServiceProviderName,
|
ServiceProviderName = context.ServiceProviderName,
|
||||||
OriginTrackData = originTrackData,
|
OriginTrackDataHash = originTrackDataHash,
|
||||||
IsCompleted = matchedContentConfig.IsCompleted,
|
IsCompleted = matchedContentConfig.IsCompleted,
|
||||||
OriginTrackContent = paramConfig.TrackContentName != null
|
OriginTrackContent = paramConfig.TrackContentName != null
|
||||||
? trackToken[paramConfig.TrackContentName]?.Value<string>()
|
? trackToken[paramConfig.TrackContentName]?.Value<string>()
|
||||||
@ -261,22 +231,107 @@ public class TrackRefreshEventHandler : ITransientDependency, ICapSubscribe
|
|||||||
TrackCode = matchedContentConfig.TrackContentCode,
|
TrackCode = matchedContentConfig.TrackContentCode,
|
||||||
TrackPlace = trackPlace ?? GlobalConst.EmptyString,
|
TrackPlace = trackPlace ?? GlobalConst.EmptyString,
|
||||||
TrackTime = trackTime ?? DateTime.Now,
|
TrackTime = trackTime ?? DateTime.Now,
|
||||||
TrackTimeZone = trackTimeZone ?? 8,
|
TrackTimeZone = trackTimeZone ?? GlobalConst.NoneTrackTimeZone,
|
||||||
DeficiencyTagValue = deficiencyTagValue
|
DeficiencyTagValue = deficiencyTagValue,
|
||||||
|
IsAdd = true,
|
||||||
};
|
};
|
||||||
|
|
||||||
trackUpsertEvent.IsAdd =
|
|
||||||
!await _trackDetailsRepository.AnyByCodeAsync(context.OrderId, matchedContentConfig.TrackContentCode);
|
|
||||||
await _capPublisher.PublishAsync(GlobalConst.TrackUpsertForRefreshSubscribe, trackUpsertEvent);
|
await _capPublisher.PublishAsync(GlobalConst.TrackUpsertForRefreshSubscribe, trackUpsertEvent);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private async Task InsertNotMappedTrackAsync(JToken trackToken, TrackRefreshContext context, string? trackPlace,
|
||||||
|
DateTime? trackTime, float? trackTimeZone, TrackPullParamConfigDto paramConfig)
|
||||||
|
{
|
||||||
|
// 新增服务商轨迹到es
|
||||||
|
var track = new TrackDetailsIndex
|
||||||
|
{
|
||||||
|
IndexName = $"{GlobalConst.TrackIndex}-{DateTime.Now:yyyy.MM.dd}",
|
||||||
|
OrderId = context.OrderId,
|
||||||
|
OrderType = context.OrderType,
|
||||||
|
OrderNo = context.OrderNo,
|
||||||
|
TrackPlace = trackPlace ?? GlobalConst.EmptyString,
|
||||||
|
TrackTime = trackTime ?? DateTime.Now,
|
||||||
|
TrackTimeZone = trackTimeZone ?? GlobalConst.NoneTrackTimeZone,
|
||||||
|
ServiceProviderName = context.ServiceProviderName,
|
||||||
|
OriginTrackDataHash = StringHelper.GetHash(JsonConvert.SerializeObject(trackToken)),
|
||||||
|
CreateUser = GlobalConst.SystemUser,
|
||||||
|
CreateTime = DateTime.Now
|
||||||
|
};
|
||||||
|
if (!paramConfig.TrackContentName.IsNullOrWhiteSpace())
|
||||||
|
{
|
||||||
|
track.OriginTrackContent =
|
||||||
|
trackToken[paramConfig.TrackContentName!]?.Value<string>() ?? GlobalConst.EmptyString;
|
||||||
|
}
|
||||||
|
|
||||||
|
track.ZeroTrackTime = track.TrackTime.Subtract(TimeSpan.FromHours(track.TrackTimeZone));
|
||||||
|
|
||||||
|
await _trackDetailsRepository.AddAsync(track);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取轨迹时区
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="paramConfig">配置信息</param>
|
||||||
|
/// <param name="matchedContentConfig">配置信息</param>
|
||||||
|
/// <param name="orderId">订单id</param>
|
||||||
|
/// <param name="trackToken"></param>
|
||||||
|
/// <returns>时区,是否执行了兜底轨迹时区</returns>
|
||||||
|
private async Task<(float? trackTimeZone, bool hasTimezoneBottomLine)> GetTimezone(
|
||||||
|
TrackPullParamConfigDto paramConfig, TrackPullContentConfigDto? matchedContentConfig, int orderId,
|
||||||
|
JToken trackToken)
|
||||||
|
{
|
||||||
|
// 轨迹发生时区
|
||||||
|
var trackTimeZone = paramConfig.TrackTimeZoneName == null
|
||||||
|
? null
|
||||||
|
: trackToken[paramConfig.TrackTimeZoneName]?.Value<float>();
|
||||||
|
|
||||||
|
bool hasTimezoneBottomLine = false; //执行了兜底但是没有兜底住,需要记录
|
||||||
|
if (!trackTimeZone.HasValue && matchedContentConfig?.TrackZonePlaceValue is not null)
|
||||||
|
{
|
||||||
|
//兜底没配置的就不需要兜底,拉取的发生地没就没
|
||||||
|
var timezone = await GetTimezone(matchedContentConfig, orderId);
|
||||||
|
|
||||||
|
trackTimeZone = timezone;
|
||||||
|
hasTimezoneBottomLine = !timezone.HasValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (trackTimeZone, hasTimezoneBottomLine);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获得轨迹地址
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="paramConfig">配置信息</param>
|
||||||
|
/// <param name="matchedContentConfig">配置信息</param>
|
||||||
|
/// <param name="orderId">订单id</param>
|
||||||
|
/// <param name="trackToken"></param>
|
||||||
|
/// <returns>时区,是否执行了兜底轨迹时区</returns>
|
||||||
|
private async Task<(string? trackPlace, bool hasPlaceBottomLine)> GetTrackPlace(TrackPullParamConfigDto paramConfig,
|
||||||
|
TrackPullContentConfigDto? matchedContentConfig, int orderId, JToken trackToken)
|
||||||
|
{
|
||||||
|
// 轨迹发生地
|
||||||
|
var trackPlace = paramConfig.TrackPlaceName == null
|
||||||
|
? null
|
||||||
|
: trackToken[paramConfig.TrackPlaceName]?.Value<string>();
|
||||||
|
var hasPlaceBottomLine = false; //执行了兜底但是没有兜底住,需要记录
|
||||||
|
if (trackPlace.IsNullOrWhiteSpace() && matchedContentConfig?.TrackPlaceValue != null &&
|
||||||
|
matchedContentConfig.TrackPlaceValue.HasValue)
|
||||||
|
{
|
||||||
|
//兜底没配置的就不需要兜底,拉取的发生地没就没
|
||||||
|
trackPlace = await GetPlaceByOrder(matchedContentConfig!.TrackPlaceValue.Value, orderId);
|
||||||
|
hasPlaceBottomLine = string.IsNullOrWhiteSpace(trackPlace);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (trackPlace, hasPlaceBottomLine);
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 根据订单id获取兜底位置
|
/// 根据订单id获取兜底位置
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="trackValue"></param>
|
/// <param name="trackValue"></param>
|
||||||
/// <param name="orderId"></param>
|
/// <param name="orderId"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
private Task<string?> GetPlaceByOrder(int trackValue,int orderId)
|
private Task<string?> GetPlaceByOrder(int trackValue, int orderId)
|
||||||
{
|
{
|
||||||
Expression<Func<OrderEntity, string?>> resultExpression =
|
Expression<Func<OrderEntity, string?>> resultExpression =
|
||||||
(TrackLocationValue)trackValue switch
|
(TrackLocationValue)trackValue switch
|
||||||
@ -289,7 +344,7 @@ public class TrackRefreshEventHandler : ITransientDependency, ICapSubscribe
|
|||||||
TrackLocationValue.LeaveCountry => x => x.LeaveCountry,
|
TrackLocationValue.LeaveCountry => x => x.LeaveCountry,
|
||||||
_ => x => x.LeaveCountry
|
_ => x => x.LeaveCountry
|
||||||
};
|
};
|
||||||
return _orderRepository.GetFirstAsync(x => x.Id == orderId, resultExpression);
|
return _orderRepository.GetFirstAsync(x => x.Id == orderId, resultExpression);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -298,13 +353,12 @@ public class TrackRefreshEventHandler : ITransientDependency, ICapSubscribe
|
|||||||
/// <param name="matchedContentConfig"></param>
|
/// <param name="matchedContentConfig"></param>
|
||||||
/// <param name="orderId"></param>
|
/// <param name="orderId"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
private async Task<float?> GetTimezone(TrackPullContentConfigDto matchedContentConfig,int orderId )
|
private async Task<float?> GetTimezone(TrackPullContentConfigDto matchedContentConfig, int orderId)
|
||||||
{
|
{
|
||||||
var placeOrCode = await GetPlaceByOrder(matchedContentConfig!.TrackZonePlaceValue.Value,orderId);
|
var placeOrCode = await GetPlaceByOrder(matchedContentConfig!.TrackZonePlaceValue.Value, orderId);
|
||||||
string timezone = null;
|
string timezone = null;
|
||||||
if (!string.IsNullOrEmpty(placeOrCode))
|
if (!string.IsNullOrEmpty(placeOrCode))
|
||||||
{
|
{
|
||||||
|
|
||||||
if (matchedContentConfig!.TrackZonePlaceValue.Value == (int)TrackLocationValue.ArrivalPort
|
if (matchedContentConfig!.TrackZonePlaceValue.Value == (int)TrackLocationValue.ArrivalPort
|
||||||
|| matchedContentConfig!.TrackZonePlaceValue.Value == (int)TrackLocationValue.LeavePort)
|
|| matchedContentConfig!.TrackZonePlaceValue.Value == (int)TrackLocationValue.LeavePort)
|
||||||
{
|
{
|
||||||
|
|||||||
@ -2,11 +2,9 @@
|
|||||||
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;
|
||||||
using SJZY.Track.Application.Contract.Services;
|
|
||||||
using SJZY.Track.Domain.Aggregates.OrderAggregate;
|
using SJZY.Track.Domain.Aggregates.OrderAggregate;
|
||||||
using SJZY.Track.Domain.Aggregates.TrackDetailsAggregate;
|
using SJZY.Track.Domain.Aggregates.TrackDetailsAggregate;
|
||||||
using SJZY.Track.Domain.Consts;
|
using SJZY.Track.Domain.Consts;
|
||||||
using SJZY.Track.Domain.Dtos.Order;
|
|
||||||
using SJZY.Track.Domain.Queries;
|
using SJZY.Track.Domain.Queries;
|
||||||
using Volo.Abp.DependencyInjection;
|
using Volo.Abp.DependencyInjection;
|
||||||
using OrderIdentifier = SJZY.Track.Application.Contract.Events.OrderIdentifier;
|
using OrderIdentifier = SJZY.Track.Application.Contract.Events.OrderIdentifier;
|
||||||
@ -61,7 +59,7 @@ public class TrackUpsertEventHandler : ITransientDependency, ICapSubscribe
|
|||||||
{
|
{
|
||||||
ServiceProviderName = @event.TrackRefreshData.ServiceProviderName,
|
ServiceProviderName = @event.TrackRefreshData.ServiceProviderName,
|
||||||
OriginTrackContent = @event.TrackRefreshData.OriginTrackContent,
|
OriginTrackContent = @event.TrackRefreshData.OriginTrackContent,
|
||||||
OriginTrackData = @event.TrackRefreshData.OriginTrackData,
|
OriginTrackDataHash = @event.TrackRefreshData.OriginTrackDataHash,
|
||||||
// tips:一定要重置为false,父级订单的完成不会使得关联订单完成,关联单也必须由刷新来完成或手动设置完成!!
|
// tips:一定要重置为false,父级订单的完成不会使得关联订单完成,关联单也必须由刷新来完成或手动设置完成!!
|
||||||
IsCompleted = false
|
IsCompleted = false
|
||||||
};
|
};
|
||||||
@ -103,7 +101,7 @@ public class TrackUpsertEventHandler : ITransientDependency, ICapSubscribe
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task HandleTrackAsync(TrackUpsertEvent @event, List<int> canNextOrderIds)
|
private async Task HandleTrackAsync(TrackUpsertEvent @event, List<int> canNextOrderIds)
|
||||||
{
|
{
|
||||||
var content = await _provideQueries.GetTrackContentAsync(@event.SubSystemId, @event.TrackCode);
|
var content = await _provideQueries.GetTrackContentAsync(@event.SubSystemId, @event.TrackCode);
|
||||||
@ -113,14 +111,20 @@ public class TrackUpsertEventHandler : ITransientDependency, ICapSubscribe
|
|||||||
var orderIds = @event.OrderIdentifiers.Select(x => x.OrderId).ToArray();
|
var orderIds = @event.OrderIdentifiers.Select(x => x.OrderId).ToArray();
|
||||||
var tracks = await _trackDetailsRepository.GetListAsync(orderIds, @event.TrackCode, true);
|
var tracks = await _trackDetailsRepository.GetListAsync(orderIds, @event.TrackCode, true);
|
||||||
|
|
||||||
var newOrderIds = orderIds.Except(tracks.Select(x => x.OrderId)).ToArray();
|
// important:轨迹code相同,时间、发生地不同的,允许存在多条!!
|
||||||
|
var newOrderIds = orderIds
|
||||||
|
.Except(tracks
|
||||||
|
.Where(x => x.TrackTime == @event.TrackTime && x.TrackPlace == @event.TrackPlace)
|
||||||
|
.Select(x => x.OrderId)
|
||||||
|
).ToArray();
|
||||||
var trackContents = await _provideQueries.MatchTrackContentAsync(newOrderIds, @event.TrackCode);
|
var trackContents = await _provideQueries.MatchTrackContentAsync(newOrderIds, @event.TrackCode);
|
||||||
|
|
||||||
var insertTracks = new List<TrackDetailsIndex>();
|
var insertTracks = new List<TrackDetailsIndex>();
|
||||||
|
|
||||||
foreach (var order in @event.OrderIdentifiers)
|
foreach (var order in @event.OrderIdentifiers)
|
||||||
{
|
{
|
||||||
var track = tracks.FirstOrDefault(x => x.OrderId == order.OrderId);
|
var track = tracks.FirstOrDefault(x =>
|
||||||
|
x.OrderId == order.OrderId && x.TrackTime == @event.TrackTime && x.TrackPlace == @event.TrackPlace);
|
||||||
|
|
||||||
if (track == null && !@event.IsAdd) continue; // 不存在不让改
|
if (track == null && !@event.IsAdd) continue; // 不存在不让改
|
||||||
if (track != null && @event.IsAdd) continue; // 存在不让创建
|
if (track != null && @event.IsAdd) continue; // 存在不让创建
|
||||||
@ -138,8 +142,7 @@ public class TrackUpsertEventHandler : ITransientDependency, ICapSubscribe
|
|||||||
TrackTimeZone = @event.TrackTimeZone,
|
TrackTimeZone = @event.TrackTimeZone,
|
||||||
ServiceProviderName = @event.TrackRefreshData.ServiceProviderName ?? GlobalConst.EmptyString,
|
ServiceProviderName = @event.TrackRefreshData.ServiceProviderName ?? GlobalConst.EmptyString,
|
||||||
OriginTrackContent = @event.TrackRefreshData.OriginTrackContent ?? GlobalConst.EmptyString,
|
OriginTrackContent = @event.TrackRefreshData.OriginTrackContent ?? GlobalConst.EmptyString,
|
||||||
OriginTrackData = @event.TrackRefreshData.OriginTrackData ?? GlobalConst.EmptyString,
|
OriginTrackDataHash = @event.TrackRefreshData.OriginTrackDataHash ?? GlobalConst.EmptyString,
|
||||||
IsCanDelete = false,
|
|
||||||
CreateUser = @event.OperationMan ?? GlobalConst.SystemUser,
|
CreateUser = @event.OperationMan ?? GlobalConst.SystemUser,
|
||||||
CreateTime = DateTime.Now
|
CreateTime = DateTime.Now
|
||||||
};
|
};
|
||||||
@ -157,8 +160,9 @@ public class TrackUpsertEventHandler : ITransientDependency, ICapSubscribe
|
|||||||
track.TrackContent = trackContent.Content;
|
track.TrackContent = trackContent.Content;
|
||||||
track.TrackEnContent = trackContent.EnContent;
|
track.TrackEnContent = trackContent.EnContent;
|
||||||
track.IsCanDelete = trackContent.IsCanDelete;
|
track.IsCanDelete = trackContent.IsCanDelete;
|
||||||
track.ZeroTrackTime = track.TrackTime.Subtract(TimeSpan.FromHours(track.TrackTimeZone));
|
track.ZeroTrackTime = Math.Abs(track.TrackTimeZone - GlobalConst.NoneTrackTimeZone) < 1
|
||||||
|
? track.TrackTime
|
||||||
|
: track.TrackTime.Subtract(TimeSpan.FromHours(track.TrackTimeZone));
|
||||||
insertTracks.Add(track);
|
insertTracks.Add(track);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -166,6 +170,9 @@ public class TrackUpsertEventHandler : ITransientDependency, ICapSubscribe
|
|||||||
track.TrackPlace = @event.TrackPlace;
|
track.TrackPlace = @event.TrackPlace;
|
||||||
track.TrackTime = @event.TrackTime;
|
track.TrackTime = @event.TrackTime;
|
||||||
track.TrackTimeZone = @event.TrackTimeZone;
|
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.UpdateUser = @event.OperationMan ?? GlobalConst.SystemUser;
|
||||||
track.UpdateTime = DateTime.Now;
|
track.UpdateTime = DateTime.Now;
|
||||||
|
|
||||||
@ -179,7 +186,7 @@ public class TrackUpsertEventHandler : ITransientDependency, ICapSubscribe
|
|||||||
|
|
||||||
// 批量add to es
|
// 批量add to es
|
||||||
await _trackDetailsRepository.AddManyAsync(insertTracks);
|
await _trackDetailsRepository.AddManyAsync(insertTracks);
|
||||||
|
|
||||||
// 触发订单主表更新事件(异步)
|
// 触发订单主表更新事件(异步)
|
||||||
await _capPublisher.PublishAsync(GlobalConst.TrackChangeAfterUpdateOrderSubscribe,
|
await _capPublisher.PublishAsync(GlobalConst.TrackChangeAfterUpdateOrderSubscribe,
|
||||||
new TrackChangeAfterUpdateOrderEvent
|
new TrackChangeAfterUpdateOrderEvent
|
||||||
|
|||||||
@ -1,24 +1,48 @@
|
|||||||
|
using System.Security.Cryptography;
|
||||||
|
using System.Text;
|
||||||
using System.Text.RegularExpressions;
|
using System.Text.RegularExpressions;
|
||||||
|
|
||||||
namespace SJZY.Track.Application.Helpers
|
namespace SJZY.Track.Application.Helpers;
|
||||||
{
|
|
||||||
public class StringHelper
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// 只能输入英文字符和键盘上常用的符号
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="input"></param>
|
|
||||||
/// <returns></returns>
|
|
||||||
public static bool IsValidEnglishString(string input)
|
|
||||||
{
|
|
||||||
if (string.IsNullOrEmpty(input))
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Regular expression to match only English letters and specified symbols
|
public class StringHelper
|
||||||
var regex = new Regex(@"^[a-zA-Z\(\)@!#$%^&*_\-+=;:""'/><,.\s]+$");
|
{
|
||||||
return regex.IsMatch(input);
|
/// <summary>
|
||||||
|
/// 只能输入英文字符和键盘上常用的符号
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="input"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public static bool IsValidEnglishString(string input)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrEmpty(input))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Regular expression to match only English letters and specified symbols
|
||||||
|
var regex = new Regex(@"^[a-zA-Z\(\)@!#$%^&*_\-+=;:""'/><,.\s]+$");
|
||||||
|
return regex.IsMatch(input);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>获取字符串的hash值</summary>
|
||||||
|
/// <param name="str"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public static string GetHash(string str)
|
||||||
|
{
|
||||||
|
// 将字符串转换为字节
|
||||||
|
byte[] data = Encoding.UTF8.GetBytes(str);
|
||||||
|
|
||||||
|
// 创建SHA256实例
|
||||||
|
using SHA256 sha256 = SHA256.Create();
|
||||||
|
// 计算哈希值
|
||||||
|
byte[] hash = sha256.ComputeHash(data);
|
||||||
|
|
||||||
|
// 将哈希值转换为16进制字符串
|
||||||
|
StringBuilder sb = new StringBuilder();
|
||||||
|
foreach (byte b in hash)
|
||||||
|
{
|
||||||
|
sb.Append(b.ToString("x2"));
|
||||||
|
}
|
||||||
|
return sb.ToString();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -4,6 +4,7 @@ using SJZY.Expand.ABP.Core;
|
|||||||
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.InterfaceRelay.Application.Contracts;
|
using SJZY.InterfaceRelay.Application.Contracts;
|
||||||
|
using SJZY.Track.Application.CAP.EventHandlers;
|
||||||
using SJZY.Track.Application.Contract.Dtos.ProvideServices;
|
using SJZY.Track.Application.Contract.Dtos.ProvideServices;
|
||||||
using SJZY.Track.Application.Contract.Dtos.TrackPull;
|
using SJZY.Track.Application.Contract.Dtos.TrackPull;
|
||||||
using SJZY.Track.Application.Contract.Services;
|
using SJZY.Track.Application.Contract.Services;
|
||||||
@ -67,9 +68,14 @@ public class TrackPullService : ApplicationService
|
|||||||
|
|
||||||
var attach = Base64Helper.SerializeObject(group.Key);
|
var attach = Base64Helper.SerializeObject(group.Key);
|
||||||
// 批量获取轨迹
|
// 批量获取轨迹
|
||||||
var _ = await _httpClientProxy.Service.BatchForwardThenPushToQueueAsync(
|
var res = await _httpClientProxy.Service.BatchForwardThenPushToQueueAsync(
|
||||||
InterfaceRelayConst.GetTrackInterfaceCode, serviceProviderCode, data, GlobalConst.TrackRefreshSubscribe,
|
InterfaceRelayConst.GetTrackInterfaceCode, serviceProviderCode, data, GlobalConst.TrackRefreshSubscribe,
|
||||||
attach);
|
attach);
|
||||||
|
|
||||||
|
if (res.Code != InterfaceRelayConst.SuccessCode)
|
||||||
|
{
|
||||||
|
LogHelper.Error($"刷新轨迹失败:{res.ToJson()}");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@ -88,6 +94,23 @@ public class TrackPullService : ApplicationService
|
|||||||
await Task.WhenAll(tasks);
|
await Task.WhenAll(tasks);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 轨迹刷新测试
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="trackRefreshEventHandler"></param>
|
||||||
|
/// <param name="input"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
[HttpPost("Track/TrackRefreshEventTest")]
|
||||||
|
#if DEBUG
|
||||||
|
[AllowAnonymous]
|
||||||
|
#endif
|
||||||
|
public async Task<bool> TrackRefreshEventTest([FromServices]TrackRefreshEventHandler trackRefreshEventHandler, InterfaceRelayForwardReplayEvent input)
|
||||||
|
{
|
||||||
|
await trackRefreshEventHandler.ConsumerAsync(input);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
private async Task RefreshForConfigAsync(TrackPullConfigDto config)
|
private async Task RefreshForConfigAsync(TrackPullConfigDto config)
|
||||||
{
|
{
|
||||||
|
|||||||
@ -18,10 +18,10 @@ namespace SJZY.Track.Application.Services.ProvideServices;
|
|||||||
[Route("/ProviderService")]
|
[Route("/ProviderService")]
|
||||||
public class TrackPushService : ApplicationService
|
public class TrackPushService : ApplicationService
|
||||||
{
|
{
|
||||||
private readonly IOrderRepository _orderRepository;
|
|
||||||
private readonly ICapPublisher _capPublisher;
|
private readonly ICapPublisher _capPublisher;
|
||||||
private readonly ITrackPushRecordsRepository _trackPushRecordsRepository;
|
private readonly IOrderRepository _orderRepository;
|
||||||
private readonly IHttpClientProxy<IRequestCurrentUserService> _requestCurrentUserService;
|
private readonly IHttpClientProxy<IRequestCurrentUserService> _requestCurrentUserService;
|
||||||
|
private readonly ITrackPushRecordsRepository _trackPushRecordsRepository;
|
||||||
|
|
||||||
public TrackPushService(IOrderRepository orderRepository
|
public TrackPushService(IOrderRepository orderRepository
|
||||||
, ICapPublisher capPublisher
|
, ICapPublisher capPublisher
|
||||||
@ -91,23 +91,12 @@ public class TrackPushService : ApplicationService
|
|||||||
[HttpPost("Track/PushWarnForTask")]
|
[HttpPost("Track/PushWarnForTask")]
|
||||||
public async Task<string> PushWarnForTaskAsync()
|
public async Task<string> PushWarnForTaskAsync()
|
||||||
{
|
{
|
||||||
int total = 0, pageSize = 1000, waitTime = 1000;
|
await _capPublisher.PublishAsync(GlobalConst.TrackPushWarning, new PushWarningEvent
|
||||||
var dateTimes = Enumerable.Range(1, 12).Select(val => DateTime.Now.AddHours(-val)).ToList();
|
|
||||||
|
|
||||||
foreach (var dateTime in dateTimes)
|
|
||||||
{
|
{
|
||||||
var rows = 0;
|
PageSize = 1000
|
||||||
var pageindex = 1;
|
});
|
||||||
do
|
|
||||||
{
|
|
||||||
rows = await _orderRepository.PushWarnOrdersAsync(pageSize, pageindex, dateTime);
|
|
||||||
total += rows;
|
|
||||||
pageindex++;
|
|
||||||
await Task.Delay(waitTime);
|
|
||||||
} while (rows != pageSize);
|
|
||||||
}
|
|
||||||
|
|
||||||
return $"本次预警扫描了:{total}个订单";
|
return "推送预警任务已启动";
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
@ -1,5 +1,6 @@
|
|||||||
using SJZY.Track.Application.Contract.Dtos.ProvideServices;
|
using SJZY.Track.Application.Contract.Dtos.ProvideServices;
|
||||||
using SJZY.Track.Domain.Aggregates.TrackDetailsAggregate;
|
using SJZY.Track.Domain.Aggregates.TrackDetailsAggregate;
|
||||||
|
using SJZY.Track.Domain.Consts;
|
||||||
|
|
||||||
namespace SJZY.Track.Application.Services.ProvideServices;
|
namespace SJZY.Track.Application.Services.ProvideServices;
|
||||||
|
|
||||||
@ -41,8 +42,8 @@ public partial class TrackService
|
|||||||
Content = x.TrackContent,
|
Content = x.TrackContent,
|
||||||
OriginContent = x.OriginTrackContent,
|
OriginContent = x.OriginTrackContent,
|
||||||
Location = x.TrackPlace,
|
Location = x.TrackPlace,
|
||||||
Time = x.TrackTime.AddHours(input.TimeZone ?? 8 - x.TrackTimeZone),
|
Time = Math.Abs(x.TrackTimeZone - GlobalConst.NoneTrackTimeZone) < 1 ? x.TrackTime: x.ZeroTrackTime.AddHours(input.TimeZone ?? 8),
|
||||||
TimeZone = input.TimeZone ?? 8
|
TimeZone = Math.Abs(x.TrackTimeZone - GlobalConst.NoneTrackTimeZone) < 1? null: input.TimeZone ?? 8
|
||||||
}).ToList();
|
}).ToList();
|
||||||
|
|
||||||
res.Add(item);
|
res.Add(item);
|
||||||
|
|||||||
@ -5,6 +5,7 @@ using SJZY.Track.Domain.Aggregates.OrderAggregate;
|
|||||||
using SJZY.Track.Domain.Aggregates.TrackContentAggregate;
|
using SJZY.Track.Domain.Aggregates.TrackContentAggregate;
|
||||||
using SJZY.Track.Domain.Aggregates.TrackDetailsAggregate;
|
using SJZY.Track.Domain.Aggregates.TrackDetailsAggregate;
|
||||||
using SJZY.Track.Domain.Aggregates.TrackPushAggregate;
|
using SJZY.Track.Domain.Aggregates.TrackPushAggregate;
|
||||||
|
using SJZY.Track.Domain.Consts;
|
||||||
using SJZY.Track.Domain.Dtos.Order;
|
using SJZY.Track.Domain.Dtos.Order;
|
||||||
using SJZY.Track.Domain.Dtos.TrackTemplate;
|
using SJZY.Track.Domain.Dtos.TrackTemplate;
|
||||||
using SJZY.Track.Domain.Enums;
|
using SJZY.Track.Domain.Enums;
|
||||||
@ -87,6 +88,10 @@ public class TrackOrderService : ApplicationService
|
|||||||
{
|
{
|
||||||
a.TrackTimeZone = "GTM +00:00";
|
a.TrackTimeZone = "GTM +00:00";
|
||||||
}
|
}
|
||||||
|
else if (Math.Abs(a.TrackTimeZoneValue - GlobalConst.NoneTrackTimeZone) < 1)
|
||||||
|
{
|
||||||
|
a.TrackTimeZone = "--";
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// 将小数形式的小时转换为时区偏移量
|
// 将小数形式的小时转换为时区偏移量
|
||||||
|
|||||||
@ -10,7 +10,7 @@ public interface ITrackDetailsRepository
|
|||||||
|
|
||||||
Task<bool> AnyAsync(int orderId, DateTime trackTime);
|
Task<bool> AnyAsync(int orderId, DateTime trackTime);
|
||||||
|
|
||||||
Task<bool> AnyAsync(int orderId, string originTrackData);
|
Task<bool> AnyAsync(int orderId, string originTrackDataHash);
|
||||||
|
|
||||||
Task<bool> AnyByCodeAsync(int orderId, string trackCode);
|
Task<bool> AnyByCodeAsync(int orderId, string trackCode);
|
||||||
|
|
||||||
|
|||||||
@ -30,37 +30,37 @@ public class TrackDetailsIndex : IdBaseIndex
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// 轨迹状态
|
/// 轨迹状态
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string TrackStatus { get; set; } = null!;
|
public string TrackStatus { get; set; } = GlobalConst.EmptyString;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 轨迹内容代码
|
/// 轨迹内容代码
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string TrackCode { get; set; } = null!;
|
public string TrackCode { get; set; } = GlobalConst.EmptyString;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 轨迹内容
|
/// 轨迹内容
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string TrackContent { get; set; } = null!;
|
public string TrackContent { get; set; } = GlobalConst.EmptyString;
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 服务商
|
|
||||||
/// </summary>
|
|
||||||
public string? ServiceProviderName { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 原轨迹内容
|
|
||||||
/// </summary>
|
|
||||||
public string? OriginTrackContent { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 原轨迹报文
|
|
||||||
/// </summary>
|
|
||||||
public string? OriginTrackData { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 轨迹内容英文
|
/// 轨迹内容英文
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string TrackEnContent { get; set; } = null!;
|
public string TrackEnContent { get; set; } = GlobalConst.EmptyString;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 服务商
|
||||||
|
/// </summary>
|
||||||
|
public string ServiceProviderName { get; set; } = null!;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 原轨迹内容
|
||||||
|
/// </summary>
|
||||||
|
public string OriginTrackContent { get; set; } = null!;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 原轨迹报文hash(刷新轨迹重复性校验使用)
|
||||||
|
/// </summary>
|
||||||
|
public string OriginTrackDataHash { get; set; } = null!;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 轨迹发生地
|
/// 轨迹发生地
|
||||||
|
|||||||
@ -56,4 +56,9 @@ public partial class GlobalConst
|
|||||||
/// 关联订单后补轨迹
|
/// 关联订单后补轨迹
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public const string OrderLinkAfterFillTrack = "SJZY.Track.OrderLinkAfterFillTrack";
|
public const string OrderLinkAfterFillTrack = "SJZY.Track.OrderLinkAfterFillTrack";
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 推送预警任务
|
||||||
|
/// </summary>
|
||||||
|
public const string TrackPushWarning = "SJZY.Track.TrackPushWarning";
|
||||||
}
|
}
|
||||||
@ -5,4 +5,6 @@ public partial class GlobalConst
|
|||||||
public const string SystemUser = "系统";
|
public const string SystemUser = "系统";
|
||||||
public const string EmptyString = "--";
|
public const string EmptyString = "--";
|
||||||
public const int ChunkSize = 100;
|
public const int ChunkSize = 100;
|
||||||
|
|
||||||
|
public const float NoneTrackTimeZone = 99999;
|
||||||
}
|
}
|
||||||
@ -5,7 +5,7 @@ namespace SJZY.Track.Domain.VEntities;
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// 空港
|
/// 空港
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[SugarTable("t_airport", "空港")]
|
[SugarTable("v_airport", "空港")]
|
||||||
public class VAirportEntity : IFullAuditedBasicEntitys
|
public class VAirportEntity : IFullAuditedBasicEntitys
|
||||||
{
|
{
|
||||||
[SugarColumn(ColumnName = "Id", IsPrimaryKey = true, IsIdentity = true)]
|
[SugarColumn(ColumnName = "Id", IsPrimaryKey = true, IsIdentity = true)]
|
||||||
|
|||||||
@ -3,7 +3,7 @@ using System;
|
|||||||
|
|
||||||
namespace SJZY.Track.Domain.VEntities;
|
namespace SJZY.Track.Domain.VEntities;
|
||||||
|
|
||||||
[SugarTable("t_city")]
|
[SugarTable("v_city")]
|
||||||
public class VCityEntity : IFullAuditedBasicEntitys
|
public class VCityEntity : IFullAuditedBasicEntitys
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
@ -34,6 +34,8 @@ internal class TrackDetailsRepository : ElasticSearchContextAbstract<TrackDetail
|
|||||||
.Source(s2 => s2.Includes(fd => fd
|
.Source(s2 => s2.Includes(fd => fd
|
||||||
.Field(f => f.IndexName)
|
.Field(f => f.IndexName)
|
||||||
.Field(f => f.OrderId)
|
.Field(f => f.OrderId)
|
||||||
|
.Field(f => f.TrackTime)
|
||||||
|
.Field(f => f.TrackPlace)
|
||||||
))
|
))
|
||||||
.Size(1000)
|
.Size(1000)
|
||||||
.Query(q => q
|
.Query(q => q
|
||||||
@ -123,13 +125,13 @@ internal class TrackDetailsRepository : ElasticSearchContextAbstract<TrackDetail
|
|||||||
return r.Hits.Count > 0;
|
return r.Hits.Count > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<bool> AnyAsync(int orderId, string originTrackData)
|
public async Task<bool> AnyAsync(int orderId, string originTrackDataHash)
|
||||||
{
|
{
|
||||||
var r = await Context.SearchAsync<TrackDetailsIndex>(x => x
|
var r = await Context.SearchAsync<TrackDetailsIndex>(x => x
|
||||||
.Source(s => s.Includes(fd => fd.Field(f => f.TrackCode)))
|
.Source(s => s.Includes(fd => fd.Field(f => f.TrackCode)))
|
||||||
.Query(q =>
|
.Query(q =>
|
||||||
q.Term(f => f.OrderId, orderId)
|
q.Term(f => f.OrderId, orderId)
|
||||||
&& q.Term(f => f.OriginTrackData.Suffix("keyword"), originTrackData)
|
&& q.Term(f => f.OriginTrackDataHash.Suffix("keyword"), originTrackDataHash)
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user