This commit is contained in:
xiaolipro 2024-09-15 18:33:12 +08:00
parent e0e376404e
commit 6ed311bc1f
18 changed files with 235 additions and 260 deletions

View File

@ -2,12 +2,9 @@ namespace SJZY.Track.Application.Contract.Dtos.TrackPull;
public class TrackRefreshAttach public class TrackRefreshAttach
{ {
public TrackRefreshAttach(string serviceProviderCode, string serviceProviderName, string subSystemCode, public TrackRefreshAttach(string serviceProviderCode, int subSystemId, int orderType)
int subSystemId, int orderType)
{ {
ServiceProviderCode = serviceProviderCode; ServiceProviderCode = serviceProviderCode;
ServiceProviderName = serviceProviderName;
SubSystemCode = subSystemCode;
SubSystemId = subSystemId; SubSystemId = subSystemId;
OrderType = orderType; OrderType = orderType;
} }
@ -17,21 +14,11 @@ public class TrackRefreshAttach
/// </summary> /// </summary>
public string ServiceProviderCode { get; set; } public string ServiceProviderCode { get; set; }
/// <summary>
/// 服务商name
/// </summary>
public string ServiceProviderName { get; set; }
/// <summary> /// <summary>
/// 订单类型(主数据枚举TrackOrderType) /// 订单类型(主数据枚举TrackOrderType)
/// </summary> /// </summary>
public int OrderType { get; set; } public int OrderType { get; set; }
/// <summary>
/// 子系统code
/// </summary>
public string SubSystemCode { get; set; }
/// <summary> /// <summary>
/// 子系统id /// 子系统id
/// </summary> /// </summary>

View File

@ -18,9 +18,9 @@ public class TrackRefreshContext
public string OrderNo { get; set; } = null!; public string OrderNo { get; set; } = null!;
/// <summary> /// <summary>
/// 服务商 /// 服务商代码
/// </summary> /// </summary>
public string ServiceProviderName { get; set; } = null!; public string ServiceProviderCode { get; set; } = null!;
/// <summary> /// <summary>
/// 客户id /// 客户id

View File

@ -3,9 +3,9 @@ namespace SJZY.Track.Application.Contract.Events;
public struct TrackRefreshStruct public struct TrackRefreshStruct
{ {
/// <summary> /// <summary>
/// 服务商 /// 服务商code
/// </summary> /// </summary>
public string? ServiceProviderName { get; set; } public string? ServiceProviderCode { get; set; }
/// <summary> /// <summary>
/// 原轨迹内容 /// 原轨迹内容

View File

@ -54,11 +54,6 @@ public class TrackUpsertEvent
public TrackRefreshStruct TrackRefreshData { get; set; } public TrackRefreshStruct TrackRefreshData { get; set; }
/// <summary>
/// 时区缺失和发生地缺失标记,1表示时区,2表示发生地,3表示两种
/// </summary>
public int DeficiencyTagValue { get; set; }
public override string ToString() public override string ToString()
{ {
return return

View File

@ -4,17 +4,16 @@ namespace SJZY.Track.Application.Contract.Services;
public interface ITrackPullCacheService public interface ITrackPullCacheService
{ {
string TrackPullKey(string subSystemCode, string serviceProviderCode); string TrackPullKey(int subSystemId, string serviceProviderCode);
string TrackPullContentKey(string subSystemCode, string serviceProviderCode);
/// <summary> /// <summary>
/// 获取服务商拉取配置 /// 获取服务商拉取配置
/// </summary> /// </summary>
/// <param name="subSystemCode">子系统code</param> /// <param name="subSystemId">子系统id</param>
/// <param name="serviceProviderCode">服务商code</param> /// <param name="serviceProviderCode">服务商code</param>
/// <returns></returns> /// <returns></returns>
Task<TrackPullParamsWithContentDto?> Task<TrackPullParamsWithContentDto?>
GetPullParamsWithContentAsync(string subSystemCode, string serviceProviderCode); GetPullParamsWithContentAsync(int subSystemId, string serviceProviderCode);
/// <summary> /// <summary>
/// 设置拉取配置缓存 /// 设置拉取配置缓存

View File

@ -4,6 +4,9 @@ using SJZY.Track.Domain.Aggregates.OrderAggregate;
namespace SJZY.Track.Application.BackgroundServices; namespace SJZY.Track.Application.BackgroundServices;
/// <summary>
/// 订单拉取状态扫描
/// </summary>
public class OrderPullStatusScanner : BackgroundService public class OrderPullStatusScanner : BackgroundService
{ {
private readonly IOrderRepository _orderRepository; private readonly IOrderRepository _orderRepository;

View File

@ -0,0 +1,156 @@
using System.Linq.Expressions;
using Microsoft.Extensions.Hosting;
using Newtonsoft.Json.Linq;
using SJZY.Track.Application.Contract.Dtos.TrackPull;
using SJZY.Track.Application.Helpers;
using SJZY.Track.Domain.Aggregates.OrderAggregate;
using SJZY.Track.Domain.Enums;
using SJZY.Track.Domain.Queries;
namespace SJZY.Track.Application.BackgroundServices;
/// <summary>
/// 轨迹兜底扫描
/// </summary>
public class TrackButtonUpScanner : BackgroundService
{
private readonly IOrderRepository _orderRepository;
private readonly ITimezoneQueries _timezoneQueries;
public TrackButtonUpScanner(ITimezoneQueries timezoneQueries, IOrderRepository orderRepository)
{
_timezoneQueries = timezoneQueries;
_orderRepository = orderRepository;
}
protected override Task ExecuteAsync(CancellationToken stoppingToken)
{
throw new NotImplementedException();
}
/// <summary>
/// 获取轨迹时区
/// </summary>
/// <param name="matchedContentConfig">配置信息</param>
/// <param name="context">订单id</param>
/// <returns>时区,是否执行了兜底轨迹时区</returns>
private async Task<(float? trackTimeZone, bool hasTimezoneBottomLine)> GetTimezone(
TrackPullContentConfigDto? matchedContentConfig,
TrackRefreshContext context)
{
float? trackTimeZone = null;
var hasTimezoneBottomLine = false; // 执行了兜底但是没有兜底住,需要记录
if (matchedContentConfig?.TrackZonePlaceValue is not null)
{
//兜底没配置的就不需要兜底,拉取的发生地没就没
var timezone = await GetTimezone(matchedContentConfig, context.OrderId);
trackTimeZone = timezone;
hasTimezoneBottomLine = !timezone.HasValue;
}
return (trackTimeZone, hasTimezoneBottomLine);
}
/// <summary>
/// 获得轨迹地址
/// </summary>
/// <param name="matchedContentConfig">配置信息</param>
/// <param name="context">订单id</param>
/// <returns>时区,是否执行了兜底轨迹时区</returns>
private async Task<(string? trackPlace, bool hasPlaceBottomLine)> GetTrackPlace(
TrackPullContentConfigDto? matchedContentConfig, TrackRefreshContext context)
{
string? trackPlace = null;
var hasPlaceBottomLine = false; //执行了兜底但是没有兜底住,需要记录
if (matchedContentConfig?.TrackPlaceValue is not null)
{
//兜底没配置的就不需要兜底,拉取的发生地没就没
trackPlace = await GetPlaceByOrder(matchedContentConfig!.TrackPlaceValue.Value, context.OrderId);
hasPlaceBottomLine = string.IsNullOrWhiteSpace(trackPlace);
}
return (trackPlace, hasPlaceBottomLine);
}
/// <summary>
/// 根据订单id获取兜底位置
/// </summary>
/// <param name="trackValue"></param>
/// <param name="orderId"></param>
/// <returns></returns>
private Task<string?> GetPlaceByOrder(int trackValue, int orderId)
{
Expression<Func<OrderEntity, string?>> resultExpression =
(TrackLocationValue) trackValue switch
{
TrackLocationValue.ArrivalPort => x => x.ArrivalPort,
TrackLocationValue.ArriveCity => x => x.ArrivalCity,
TrackLocationValue.ArrivalCountry => x => x.ArrivalCountry,
TrackLocationValue.LeavePort => x => x.LeavePort,
TrackLocationValue.LeaveCity => x => x.LeaveCity,
TrackLocationValue.LeaveCountry => x => x.LeaveCountry,
_ => x => x.LeaveCountry
};
return _orderRepository.GetFirstAsync(x => x.Id == orderId, resultExpression);
}
/// <summary>
/// 获取时区
/// </summary>
/// <param name="matchedContentConfig"></param>
/// <param name="orderId"></param>
/// <returns></returns>
private async Task<float?> GetTimezone(TrackPullContentConfigDto matchedContentConfig, int orderId)
{
var placeOrCode = await GetPlaceByOrder(matchedContentConfig!.TrackZonePlaceValue.Value, orderId);
string timezone = null;
if (!string.IsNullOrEmpty(placeOrCode))
{
if (matchedContentConfig!.TrackZonePlaceValue.Value == (int) TrackLocationValue.ArrivalPort
|| matchedContentConfig!.TrackZonePlaceValue.Value == (int) TrackLocationValue.LeavePort)
{
timezone = await _timezoneQueries.GetPortTimezone(placeOrCode);
return DateTimeHelper.ConvertTimeZoneToFloat(timezone);
}
timezone = await _timezoneQueries.GetCityTimezone(placeOrCode);
return DateTimeHelper.ConvertTimeZoneToFloat(timezone);
}
return null;
}
/// <summary>
/// 触发了兜底,但是没有兜底住,对订单进行标记
/// 1表示时区,2表示发生地,3表示两种
/// </summary>
/// <param name="hasPlaceBottomLine"></param>
/// <param name="hasTimezoneBottomLine"></param>
/// <param name="trackToken"></param>
/// <param name="context"></param>
/// <returns></returns>
private int CalcDeficiencyTagValue(bool hasPlaceBottomLine, bool hasTimezoneBottomLine, JToken trackToken,
TrackRefreshContext context)
{
var deficiencyTagValue = 0;
if (hasTimezoneBottomLine)
{
// _logger.LogWarning("订单号:{@OrderNo}, 轨迹发生时区无法解析,触发了兜底,但是没有兜底住:{@Data}", context.OrderNo,
// trackToken.ToString());
deficiencyTagValue += 1;
}
if (hasPlaceBottomLine)
{
// _logger.LogWarning("订单号:{@OrderNo}, 轨迹发生地无法解析,触发了兜底,但是没有兜底住:{@Data}", context.OrderNo,
// trackToken.ToString());
deficiencyTagValue += 2;
}
return deficiencyTagValue;
}
}

View File

@ -61,7 +61,7 @@ public class TrackUpsertEventHandler : ITransientDependency, ICapSubscribe
nextEvent.CustomId = group.Key.CustomId; nextEvent.CustomId = group.Key.CustomId;
nextEvent.TrackRefreshData = new TrackRefreshStruct nextEvent.TrackRefreshData = new TrackRefreshStruct
{ {
ServiceProviderName = @event.TrackRefreshData.ServiceProviderName, ServiceProviderCode = @event.TrackRefreshData.ServiceProviderCode,
OriginTrackContent = @event.TrackRefreshData.OriginTrackContent, OriginTrackContent = @event.TrackRefreshData.OriginTrackContent,
OriginTrackDataHash = @event.TrackRefreshData.OriginTrackDataHash, OriginTrackDataHash = @event.TrackRefreshData.OriginTrackDataHash,
}; };
@ -171,7 +171,6 @@ public class TrackUpsertEventHandler : ITransientDependency, ICapSubscribe
TrackPlace = @event.TrackPlace, TrackPlace = @event.TrackPlace,
TrackTime = @event.TrackTime, TrackTime = @event.TrackTime,
TrackTimeZone = @event.TrackTimeZone, TrackTimeZone = @event.TrackTimeZone,
DeficiencyTagValue = @event.DeficiencyTagValue
}); });
// 触发轨迹推送事件(异步) // 触发轨迹推送事件(异步)
@ -241,7 +240,7 @@ public class TrackUpsertEventHandler : ITransientDependency, ICapSubscribe
TrackPlace = @event.TrackPlace, TrackPlace = @event.TrackPlace,
TrackTime = @event.TrackTime, TrackTime = @event.TrackTime,
TrackTimeZone = @event.TrackTimeZone, TrackTimeZone = @event.TrackTimeZone,
ServiceProviderName = @event.TrackRefreshData.ServiceProviderName ?? GlobalConst.EmptyString, ServiceProviderCode = @event.TrackRefreshData.ServiceProviderCode ?? GlobalConst.EmptyString,
OriginTrackContent = @event.TrackRefreshData.OriginTrackContent ?? GlobalConst.EmptyString, OriginTrackContent = @event.TrackRefreshData.OriginTrackContent ?? GlobalConst.EmptyString,
OriginTrackDataHash = @event.TrackRefreshData.OriginTrackDataHash ?? GlobalConst.EmptyString, OriginTrackDataHash = @event.TrackRefreshData.OriginTrackDataHash ?? GlobalConst.EmptyString,
CreateUser = @event.OperationMan ?? GlobalConst.SystemUser, CreateUser = @event.OperationMan ?? GlobalConst.SystemUser,

View File

@ -1,5 +1,4 @@
using System.Diagnostics; using System.Diagnostics;
using System.Linq.Expressions;
using System.Text; using System.Text;
using BSI.Stack.Rabbit; using BSI.Stack.Rabbit;
using BSI.Stack.Rabbit.Handler; using BSI.Stack.Rabbit.Handler;
@ -16,8 +15,6 @@ using SJZY.Track.Application.Contract.Services;
using SJZY.Track.Application.Helpers; using SJZY.Track.Application.Helpers;
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.Enums;
using SJZY.Track.Domain.Queries;
using Volo.Abp.DependencyInjection; using Volo.Abp.DependencyInjection;
namespace SJZY.Track.Application.Rabbit; namespace SJZY.Track.Application.Rabbit;
@ -27,20 +24,18 @@ public class TrackRefreshEventHandler : ITransientDependency, IRabbitHandler
private readonly ICapPublisher _capPublisher; private readonly ICapPublisher _capPublisher;
private readonly ILogger<TrackRefreshEventHandler> _logger; private readonly ILogger<TrackRefreshEventHandler> _logger;
private readonly IOrderRepository _orderRepository; private readonly IOrderRepository _orderRepository;
private readonly ITimezoneQueries _timezoneQueries;
private readonly ITrackDetailsEsRepository _trackDetailsEsRepository; private readonly ITrackDetailsEsRepository _trackDetailsEsRepository;
private readonly ITrackPullCacheService _trackPullCacheService; private readonly ITrackPullCacheService _trackPullCacheService;
public TrackRefreshEventHandler(IOrderRepository orderRepository, public TrackRefreshEventHandler(IOrderRepository orderRepository,
ICapPublisher capPublisher, ITrackPullCacheService trackPullCacheService, ICapPublisher capPublisher, ITrackPullCacheService trackPullCacheService,
ITrackDetailsEsRepository trackDetailsEsRepository, ITimezoneQueries timezoneQueries, ITrackDetailsEsRepository trackDetailsEsRepository,
ILogger<TrackRefreshEventHandler> logger) ILogger<TrackRefreshEventHandler> logger)
{ {
_orderRepository = orderRepository; _orderRepository = orderRepository;
_capPublisher = capPublisher; _capPublisher = capPublisher;
_trackPullCacheService = trackPullCacheService; _trackPullCacheService = trackPullCacheService;
_trackDetailsEsRepository = trackDetailsEsRepository; _trackDetailsEsRepository = trackDetailsEsRepository;
_timezoneQueries = timezoneQueries;
_logger = logger; _logger = logger;
} }
@ -79,7 +74,7 @@ public class TrackRefreshEventHandler : ITransientDependency, IRabbitHandler
return; return;
} }
var config = await _trackPullCacheService.GetPullParamsWithContentAsync(attach.SubSystemCode, var config = await _trackPullCacheService.GetPullParamsWithContentAsync(attach.SubSystemId,
attach.ServiceProviderCode); attach.ServiceProviderCode);
if (config == null) if (config == null)
{ {
@ -114,11 +109,10 @@ public class TrackRefreshEventHandler : ITransientDependency, IRabbitHandler
if (trackToken is null) return; if (trackToken is null) return;
var order = await _orderRepository.GetFirstAsync(x => var order = await _orderRepository.GetFirstAsync(x =>
x.OrderType == attach.OrderType && x.OrderNo == orderNo, x.SubSystemId == attach.SubSystemId && x.OrderType == attach.OrderType && x.OrderNo == orderNo,
x => new x => new
{ {
x.Id, x.Id,
x.LatestPushTrackCode,
x.CustomId x.CustomId
}); });
if (order == default) return; if (order == default) return;
@ -128,7 +122,7 @@ public class TrackRefreshEventHandler : ITransientDependency, IRabbitHandler
OrderId = order.Id, OrderId = order.Id,
OrderType = attach.OrderType, OrderType = attach.OrderType,
OrderNo = orderNo!, OrderNo = orderNo!,
ServiceProviderName = attach.ServiceProviderName, ServiceProviderCode = attach.ServiceProviderCode,
CustomId = order.CustomId, CustomId = order.CustomId,
SubSystemId = attach.SubSystemId SubSystemId = attach.SubSystemId
}; };
@ -161,6 +155,11 @@ public class TrackRefreshEventHandler : ITransientDependency, IRabbitHandler
var contentConfigs = paramsWithContent.ContentConfigs; var contentConfigs = paramsWithContent.ContentConfigs;
TrackPullContentConfigDto? matchedContentConfig = null; TrackPullContentConfigDto? matchedContentConfig = null;
// 轨迹内容
var trackContent = paramConfig.TrackContentName == null
? null
: trackToken[paramConfig.TrackContentName]?.Value<string>();
// 1、匹配轨迹代码 // 1、匹配轨迹代码
// 2、匹配轨迹状态 // 2、匹配轨迹状态
@ -175,7 +174,6 @@ public class TrackRefreshEventHandler : ITransientDependency, IRabbitHandler
// 3、匹配轨迹内容 // 3、匹配轨迹内容
else if (!paramConfig.TrackContentName.IsNullOrWhiteSpace()) else if (!paramConfig.TrackContentName.IsNullOrWhiteSpace())
{ {
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");
@ -215,25 +213,24 @@ public class TrackRefreshEventHandler : ITransientDependency, IRabbitHandler
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
var (trackTimeZone, hasTimezoneBottomLine) = ? null
await GetTimezone(paramConfig, matchedContentConfig, context, trackToken); : trackToken[paramConfig.TrackTimeZoneName]?.Value<float>();
// 轨迹发生地 // 轨迹发生地
var (trackPlace, hasPlaceBottomLine) = var trackPlace = paramConfig.TrackPlaceName == null
await GetTrackPlace(paramConfig, matchedContentConfig, context, trackToken); ? null
: trackToken[paramConfig.TrackPlaceName]?.Value<string>();
if (matchedContentConfig is null) if (matchedContentConfig is null)
{ {
_logger.LogDebug("订单号:{OrderNo},未匹配到轨迹内容,轨迹报文:{TrackContent}", _logger.LogDebug("订单号:{OrderNo},未匹配到轨迹内容,轨迹报文:{TrackContent}",
context.OrderNo, trackToken.ToString()); context.OrderNo, trackToken.ToString());
await InsertNotMappedTrackAsync(trackToken, context, trackPlace, trackTime, trackTimeZone, paramConfig); await InsertNotMappedTrackAsync(trackToken, context, trackPlace, trackTime, trackTimeZone, trackContent);
return; return;
} }
var deficiencyTagValue = CalcDeficiencyTagValue(hasPlaceBottomLine, hasTimezoneBottomLine, trackToken, context);
// 新增/更新轨迹 // 新增/更新轨迹
var trackUpsertEvent = new TrackUpsertEvent var trackUpsertEvent = new TrackUpsertEvent
{ {
@ -249,57 +246,23 @@ public class TrackRefreshEventHandler : ITransientDependency, IRabbitHandler
}, },
TrackRefreshData = new TrackRefreshStruct TrackRefreshData = new TrackRefreshStruct
{ {
ServiceProviderName = context.ServiceProviderName, ServiceProviderCode = context.ServiceProviderCode,
OriginTrackDataHash = originTrackDataHash, OriginTrackDataHash = originTrackDataHash,
OriginTrackContent = paramConfig.TrackContentName != null OriginTrackContent = trackContent ?? GlobalConst.EmptyString,
? trackToken[paramConfig.TrackContentName]?.Value<string>()
: GlobalConst.EmptyString
}, },
SubSystemId = context.SubSystemId, SubSystemId = context.SubSystemId,
TrackCode = matchedContentConfig.TrackContentCode, TrackCode = matchedContentConfig.TrackContentCode,
TrackPlace = trackPlace ?? GlobalConst.EmptyString, TrackPlace = trackPlace ?? GlobalConst.EmptyString,
TrackTime = trackTime ?? DateTime.Now, TrackTime = trackTime ?? DateTime.Now,
TrackTimeZone = trackTimeZone ?? GlobalConst.NoneTrackTimeZone, TrackTimeZone = trackTimeZone ?? GlobalConst.NoneTrackTimeZone,
DeficiencyTagValue = deficiencyTagValue,
IsAdd = true, IsAdd = true,
}; };
await _capPublisher.PublishAsync(GlobalConst.TrackUpsertForRefreshSubscribe, trackUpsertEvent); await _capPublisher.PublishAsync(GlobalConst.TrackUpsertForRefreshSubscribe, trackUpsertEvent);
} }
/// <summary>
/// 触发了兜底,但是没有兜底住,对订单进行标记
/// 1表示时区,2表示发生地,3表示两种
/// </summary>
/// <param name="hasPlaceBottomLine"></param>
/// <param name="hasTimezoneBottomLine"></param>
/// <param name="trackToken"></param>
/// <param name="context"></param>
/// <returns></returns>
private int CalcDeficiencyTagValue(bool hasPlaceBottomLine, bool hasTimezoneBottomLine, JToken trackToken,
TrackRefreshContext context)
{
var deficiencyTagValue = 0;
if (hasTimezoneBottomLine)
{
_logger.LogWarning("订单号:{@OrderNo}, 轨迹发生时区无法解析,触发了兜底,但是没有兜底住:{@Data}", context.OrderNo,
trackToken.ToString());
deficiencyTagValue += 1;
}
if (hasPlaceBottomLine)
{
_logger.LogWarning("订单号:{@OrderNo}, 轨迹发生地无法解析,触发了兜底,但是没有兜底住:{@Data}", context.OrderNo,
trackToken.ToString());
deficiencyTagValue += 2;
}
return deficiencyTagValue;
}
private async Task InsertNotMappedTrackAsync(JToken trackToken, TrackRefreshContext context, string? trackPlace, private async Task InsertNotMappedTrackAsync(JToken trackToken, TrackRefreshContext context, string? trackPlace,
DateTime? trackTime, float? trackTimeZone, TrackPullParamConfigDto paramConfig) DateTime? trackTime, float? trackTimeZone, string? trackContent)
{ {
// 新增服务商轨迹到es // 新增服务商轨迹到es
var track = new TrackDetailsIndex var track = new TrackDetailsIndex
@ -312,16 +275,12 @@ public class TrackRefreshEventHandler : ITransientDependency, IRabbitHandler
TrackPlace = trackPlace ?? GlobalConst.EmptyString, TrackPlace = trackPlace ?? GlobalConst.EmptyString,
TrackTime = trackTime ?? DateTime.Now, TrackTime = trackTime ?? DateTime.Now,
TrackTimeZone = trackTimeZone ?? GlobalConst.NoneTrackTimeZone, TrackTimeZone = trackTimeZone ?? GlobalConst.NoneTrackTimeZone,
ServiceProviderName = context.ServiceProviderName, ServiceProviderCode = context.ServiceProviderCode,
OriginTrackDataHash = StringHelper.GetHash(JsonConvert.SerializeObject(trackToken)), OriginTrackDataHash = StringHelper.GetHash(JsonConvert.SerializeObject(trackToken)),
OriginTrackContent = trackContent ?? GlobalConst.EmptyString,
CreateUser = GlobalConst.SystemUser, CreateUser = GlobalConst.SystemUser,
CreateTime = DateTime.Now CreateTime = DateTime.Now
}; };
if (!paramConfig.TrackContentName.IsNullOrWhiteSpace())
{
track.OriginTrackContent =
trackToken[paramConfig.TrackContentName!]?.Value<string>() ?? GlobalConst.EmptyString;
}
track.ZeroTrackTime = Math.Abs(track.TrackTimeZone - GlobalConst.NoneTrackTimeZone) < 1 track.ZeroTrackTime = Math.Abs(track.TrackTimeZone - GlobalConst.NoneTrackTimeZone) < 1
? track.TrackTime ? track.TrackTime
@ -329,109 +288,4 @@ public class TrackRefreshEventHandler : ITransientDependency, IRabbitHandler
await _trackDetailsEsRepository.AddAsync(track); await _trackDetailsEsRepository.AddAsync(track);
} }
/// <summary>
/// 获取轨迹时区
/// </summary>
/// <param name="paramConfig">配置信息</param>
/// <param name="matchedContentConfig">配置信息</param>
/// <param name="context">订单id</param>
/// <param name="trackToken"></param>
/// <returns>时区,是否执行了兜底轨迹时区</returns>
private async Task<(float? trackTimeZone, bool hasTimezoneBottomLine)> GetTimezone(
TrackPullParamConfigDto paramConfig, TrackPullContentConfigDto? matchedContentConfig,
TrackRefreshContext context,
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, context.OrderId);
trackTimeZone = timezone;
hasTimezoneBottomLine = !timezone.HasValue;
}
return (trackTimeZone, hasTimezoneBottomLine);
}
/// <summary>
/// 获得轨迹地址
/// </summary>
/// <param name="paramConfig">配置信息</param>
/// <param name="matchedContentConfig">配置信息</param>
/// <param name="context">订单id</param>
/// <param name="trackToken"></param>
/// <returns>时区,是否执行了兜底轨迹时区</returns>
private async Task<(string? trackPlace, bool hasPlaceBottomLine)> GetTrackPlace(TrackPullParamConfigDto paramConfig,
TrackPullContentConfigDto? matchedContentConfig, TrackRefreshContext context, JToken trackToken)
{
// 轨迹发生地
var trackPlace = paramConfig.TrackPlaceName == null
? null
: trackToken[paramConfig.TrackPlaceName]?.Value<string>();
var hasPlaceBottomLine = false; //执行了兜底但是没有兜底住,需要记录
if (trackPlace.IsNullOrWhiteSpace() && matchedContentConfig?.TrackPlaceValue is not null)
{
//兜底没配置的就不需要兜底,拉取的发生地没就没
trackPlace = await GetPlaceByOrder(matchedContentConfig!.TrackPlaceValue.Value, context.OrderId);
hasPlaceBottomLine = string.IsNullOrWhiteSpace(trackPlace);
}
return (trackPlace, hasPlaceBottomLine);
}
/// <summary>
/// 根据订单id获取兜底位置
/// </summary>
/// <param name="trackValue"></param>
/// <param name="orderId"></param>
/// <returns></returns>
private Task<string?> GetPlaceByOrder(int trackValue, int orderId)
{
Expression<Func<OrderEntity, string?>> resultExpression =
(TrackLocationValue) trackValue switch
{
TrackLocationValue.ArrivalPort => x => x.ArrivalPort,
TrackLocationValue.ArriveCity => x => x.ArrivalCity,
TrackLocationValue.ArrivalCountry => x => x.ArrivalCountry,
TrackLocationValue.LeavePort => x => x.LeavePort,
TrackLocationValue.LeaveCity => x => x.LeaveCity,
TrackLocationValue.LeaveCountry => x => x.LeaveCountry,
_ => x => x.LeaveCountry
};
return _orderRepository.GetFirstAsync(x => x.Id == orderId, resultExpression);
}
/// <summary>
/// 获取时区
/// </summary>
/// <param name="matchedContentConfig"></param>
/// <param name="orderId"></param>
/// <returns></returns>
private async Task<float?> GetTimezone(TrackPullContentConfigDto matchedContentConfig, int orderId)
{
var placeOrCode = await GetPlaceByOrder(matchedContentConfig!.TrackZonePlaceValue.Value, orderId);
string timezone = null;
if (!string.IsNullOrEmpty(placeOrCode))
{
if (matchedContentConfig!.TrackZonePlaceValue.Value == (int) TrackLocationValue.ArrivalPort
|| matchedContentConfig!.TrackZonePlaceValue.Value == (int) TrackLocationValue.LeavePort)
{
timezone = await _timezoneQueries.GetPortTimezone(placeOrCode);
return DateTimeHelper.ConvertTimeZoneToFloat(timezone);
}
timezone = await _timezoneQueries.GetCityTimezone(placeOrCode);
return DateTimeHelper.ConvertTimeZoneToFloat(timezone);
}
return null;
}
} }

View File

@ -59,7 +59,7 @@ public class TrackPullService : ApplicationService, ITrackPullService
foreach (var group in orders.GroupBy(x => foreach (var group in orders.GroupBy(x =>
new new
{ {
x.ServiceProviderName, x.ServiceProviderCode,
x.SubSystemId, x.SubSystemId,
x.SubSystemCode, x.SubSystemCode,
x.OrderType x.OrderType
@ -71,7 +71,8 @@ public class TrackPullService : ApplicationService, ITrackPullService
})); }));
var serviceProviderCode = group.FirstOrDefault()!.ServiceProviderCode; var serviceProviderCode = group.FirstOrDefault()!.ServiceProviderCode;
var attach = Base64Helper.SerializeObject(group.Key); var attach = Base64Helper.SerializeObject(new TrackRefreshAttach(group.Key.ServiceProviderCode,
group.Key.SubSystemId, group.Key.OrderType));
using (Track2InterfaceRelaySubSystemContext.Use( using (Track2InterfaceRelaySubSystemContext.Use(
new Track2InterfaceRelaySubSystemContext(group.Key.SubSystemCode))) new Track2InterfaceRelaySubSystemContext(group.Key.SubSystemCode)))
@ -130,7 +131,7 @@ public class TrackPullService : ApplicationService, ITrackPullService
private async Task RefreshForConfigAsync(TrackPullConfigVo config) private async Task RefreshForConfigAsync(TrackPullConfigVo config)
{ {
var redisKey = _trackPullCacheService.TrackPullKey(config.SubSystemCode, config.ServiceProviderCode); var redisKey = _trackPullCacheService.TrackPullKey(config.SubSystemId, config.ServiceProviderCode);
if (await RedisHelper.Client.ExistsAsync(redisKey)) if (await RedisHelper.Client.ExistsAsync(redisKey))
{ {
return; return;
@ -145,11 +146,10 @@ public class TrackPullService : ApplicationService, ITrackPullService
{ {
var page = 1; var page = 1;
var orders = var orders =
await _provideQueries.FindOrderWithServiceProviderAsync(config.ServiceProviderId, page); await _provideQueries.FindOrderWithServiceProviderAsync(config.ServiceProviderCode, page);
while (orders.Any()) while (orders.Any())
{ {
var serviceProviderCode = orders.FirstOrDefault()?.ServiceProviderCode; var serviceProviderCode = orders.FirstOrDefault()?.ServiceProviderCode;
var serviceProviderName = orders.FirstOrDefault()?.ServiceProviderName;
foreach (var group in orders.GroupBy(x => x.OrderType)) foreach (var group in orders.GroupBy(x => x.OrderType))
{ {
@ -158,7 +158,7 @@ public class TrackPullService : ApplicationService, ITrackPullService
OrderNo = x.OrderNo OrderNo = x.OrderNo
})); }));
var attach = Base64Helper.SerializeObject(new TrackRefreshAttach(config.ServiceProviderCode, var attach = Base64Helper.SerializeObject(new TrackRefreshAttach(config.ServiceProviderCode,
serviceProviderName!, config.SubSystemCode, config.SubSystemId, group.Key)); config.SubSystemId, group.Key));
var res = await _httpClientProxy.Service.BatchForwardThenPushToQueueAsync( var res = await _httpClientProxy.Service.BatchForwardThenPushToQueueAsync(
InterfaceRelayConst.GetTrackInterfaceCode, serviceProviderCode, data, InterfaceRelayConst.GetTrackInterfaceCode, serviceProviderCode, data,
GlobalConst.TrackRefreshSubscribe, attach); GlobalConst.TrackRefreshSubscribe, attach);
@ -169,7 +169,7 @@ public class TrackPullService : ApplicationService, ITrackPullService
} }
} }
orders = await _provideQueries.FindOrderWithServiceProviderAsync(config.ServiceProviderId, orders = await _provideQueries.FindOrderWithServiceProviderAsync(config.ServiceProviderCode,
++page); ++page);
} }
} }

View File

@ -19,19 +19,16 @@ public class TrackPullCacheService : ITransientDependency, ITrackPullCacheServic
_objectMapper = objectMapper; _objectMapper = objectMapper;
} }
public string TrackPullKey(string subSystemCode, string serviceProviderCode) => public string TrackPullKey(int subSystemId, string serviceProviderCode) =>
$"{GlobalConst.TrackPullKeyPrefix}:{subSystemCode}:{serviceProviderCode}"; $"{GlobalConst.TrackPullKeyPrefix}:{subSystemId}:{serviceProviderCode}";
public string TrackPullContentKey(string subSystemCode, string serviceProviderCode) => public async Task<TrackPullParamsWithContentDto?> GetPullParamsWithContentAsync(int subSystemId,
$"{GlobalConst.TrackPullContentKeyPrefix}:{subSystemCode}:{serviceProviderCode}";
public async Task<TrackPullParamsWithContentDto?> GetPullParamsWithContentAsync(string subSystemCode,
string serviceProviderCode) string serviceProviderCode)
{ {
var data = await RedisHelper.Client.GetAsync<TrackPullParamsWithContentDto>(TrackPullContentKey( var data = await RedisHelper.Client.GetAsync<TrackPullParamsWithContentDto>(TrackPullContentKey(
subSystemCode, serviceProviderCode)); subSystemId, serviceProviderCode));
var pullId = await _trackPullConfigRepository.FindIdAsync(subSystemCode, serviceProviderCode); var pullId = await _trackPullConfigRepository.FindIdAsync(subSystemId, serviceProviderCode);
data ??= await SetPullConfigAsync(pullId); data ??= await SetPullConfigAsync(pullId);
return data; return data;
@ -54,8 +51,11 @@ public class TrackPullCacheService : ITransientDependency, ITrackPullCacheServic
}; };
await RedisHelper.Client.SetAsync( await RedisHelper.Client.SetAsync(
TrackPullContentKey(trackPullConfigDetail.SubSystemCode, trackPullConfigDetail.ServiceProviderCode), data); TrackPullContentKey(trackPullConfigDetail.SubSystemId, trackPullConfigDetail.ServiceProviderCode), data);
return data; return data;
} }
public string TrackPullContentKey(int subSystemId, string serviceProviderCode) =>
$"{GlobalConst.TrackPullContentKeyPrefix}:{subSystemId}:{serviceProviderCode}";
} }

View File

@ -53,14 +53,14 @@ public class TrackDetailsIndex : IdBaseIndex
public string TrackEnContent { get; set; } = GlobalConst.EmptyString; public string TrackEnContent { get; set; } = GlobalConst.EmptyString;
/// <summary> /// <summary>
/// 服务商 /// 服务商code
/// </summary> /// </summary>
public string ServiceProviderName { get; set; } = null!; public string ServiceProviderCode { get; set; } = GlobalConst.EmptyString;
/// <summary> /// <summary>
/// 原轨迹内容 /// 原轨迹内容
/// </summary> /// </summary>
public string OriginTrackContent { get; set; } = null!; public string? OriginTrackContent { get; set; } = GlobalConst.EmptyString;
/// <summary> /// <summary>
/// 原轨迹报文hash(刷新轨迹重复性校验使用) /// 原轨迹报文hash(刷新轨迹重复性校验使用)
@ -70,7 +70,7 @@ public class TrackDetailsIndex : IdBaseIndex
/// <summary> /// <summary>
/// 轨迹发生地 /// 轨迹发生地
/// </summary> /// </summary>
public string TrackPlace { get; set; } = null!; public string TrackPlace { get; set; } = GlobalConst.EmptyString;
/// <summary> /// <summary>
/// 轨迹发生时间 /// 轨迹发生时间
@ -90,7 +90,7 @@ public class TrackDetailsIndex : IdBaseIndex
/// <summary> /// <summary>
/// 创建人 /// 创建人
/// </summary> /// </summary>
public string? CreateUser { get; set; } public string CreateUser { get; set; } = GlobalConst.EmptyString;
/// <summary> /// <summary>
/// 创建时间 /// 创建时间
@ -100,7 +100,7 @@ public class TrackDetailsIndex : IdBaseIndex
/// <summary> /// <summary>
/// 修改人 /// 修改人
/// </summary> /// </summary>
public string? UpdateUser { get; set; } public string UpdateUser { get; set; } = GlobalConst.EmptyString;
/// <summary> /// <summary>
/// 修改时间 /// 修改时间

View File

@ -49,5 +49,5 @@ public interface ITrackPullConfigRepository : IBasicRepository<TrackPullConfigEn
Task<bool> UpdateContentAsync(TrackPullContentConfigEntity updateObj); Task<bool> UpdateContentAsync(TrackPullContentConfigEntity updateObj);
Task<bool> IsContentAnyAsync(Expression<Func<TrackPullContentConfigEntity, bool>> whereExpression); Task<bool> IsContentAnyAsync(Expression<Func<TrackPullContentConfigEntity, bool>> whereExpression);
Task<int> FindIdAsync(string subSystemCode, string serviceProviderCode); Task<int> FindIdAsync(int subSystemId, string serviceProviderCode);
} }

View File

@ -1,5 +1,3 @@
using SJZY.Track.Domain.Aggregates.OrderAggregate;
namespace SJZY.Track.Domain.Dtos.Order; namespace SJZY.Track.Domain.Dtos.Order;
public class OrderWithServiceProviderVO public class OrderWithServiceProviderVO
@ -16,23 +14,13 @@ public class OrderWithServiceProviderVO
/// </summary> /// </summary>
public string ServiceProviderCode { get; set; } = null!; public string ServiceProviderCode { get; set; } = null!;
/// <summary>
/// 服务商name
/// </summary>
public string ServiceProviderName { get; set; } = null!;
/// <summary>
/// 子系统code
/// </summary>
public string SubSystemCode { get; set; }
/// <summary> /// <summary>
/// 子系统id /// 子系统id
/// </summary> /// </summary>
public int SubSystemId { get; set; } public int SubSystemId { get; set; }
/// <summary> /// <summary>
/// 轨迹拉取状态 /// 子系统code
/// </summary> /// </summary>
public TrackPullStatus TrackPullStatus { get; set; } public string SubSystemCode { get; set; }
} }

View File

@ -37,7 +37,7 @@ public class GetTrackPullConfigDetailOutputVO
/// <summary> /// <summary>
/// 子系统code /// 子系统code
/// </summary> /// </summary>
public string SubSystemCode { get; set; } public int SubSystemId { get; set; }
/// <summary> /// <summary>
/// 拉取轨迹时区 /// 拉取轨迹时区

View File

@ -29,11 +29,11 @@ public interface IProvideQueries
/// <summary> /// <summary>
/// 获取服务商下所有单(未完成的) /// 获取服务商下所有单(未完成的)
/// </summary> /// </summary>
/// <param name="serviceProviderId"></param> /// <param name="serviceProviderCode">服务商代码</param>
/// <param name="pageIndex"></param> /// <param name="pageIndex"></param>
/// <param name="pageSize"></param> /// <param name="pageSize"></param>
/// <returns></returns> /// <returns></returns>
Task<List<OrderWithServiceProviderVO>> FindOrderWithServiceProviderAsync(int serviceProviderId, int pageIndex, Task<List<OrderWithServiceProviderVO>> FindOrderWithServiceProviderAsync(string serviceProviderCode, int pageIndex,
int pageSize = 1000); int pageSize = 1000);
/// <summary> /// <summary>

View File

@ -39,41 +39,36 @@ public class ProvideQueries : ISugarRepository, IProvideQueries, ITransientDepen
{ {
return await Context.Queryable<OrderEntity>() return await Context.Queryable<OrderEntity>()
.InnerJoin<OrderPullStatusEntity>((a, b) => a.Id == b.OrderId) .InnerJoin<OrderPullStatusEntity>((a, b) => a.Id == b.OrderId)
.LeftJoin<VServiceProviderEntity>((a, b, c) => b.ServiceProviderCode == c.Code) .LeftJoin<VSystemEntity>((a, b, c) => a.SubSystemId == c.Id)
.LeftJoin<VSystemEntity>((a, b, c, d) => a.SubSystemId == d.Id)
.WhereIF(subSystemId > 0, a => a.SubSystemId == subSystemId) .WhereIF(subSystemId > 0, a => a.SubSystemId == subSystemId)
.Where((a, b) => !a.IsCompleted && orderNos.Contains(a.OrderNo) .Where((a, b) => !a.IsCompleted && orderNos.Contains(a.OrderNo)
&& b.StartTime <= DateTime.Now && b.EndTime >= DateTime.Now) && b.StartTime <= DateTime.Now && b.EndTime >= DateTime.Now)
.Select((a, b, c, d) => new OrderWithServiceProviderVO .Select((a, b, c) => new OrderWithServiceProviderVO
{ {
OrderNo = a.OrderNo, OrderNo = a.OrderNo,
OrderType = a.OrderType, OrderType = a.OrderType,
ServiceProviderCode = c.Code,
ServiceProviderName = c.Name,
SubSystemId = a.SubSystemId, SubSystemId = a.SubSystemId,
SubSystemCode = d.Key ServiceProviderCode = b.ServiceProviderCode,
SubSystemCode = c.Key
}) })
.ToListAsync(); .ToListAsync();
} }
public async Task<List<OrderWithServiceProviderVO>> FindOrderWithServiceProviderAsync( public async Task<List<OrderWithServiceProviderVO>> FindOrderWithServiceProviderAsync(
int serviceProviderId, string serviceProviderCode,
int pageIndex, int pageSize = 1000) int pageIndex, int pageSize = 1000)
{ {
return await Context.Queryable<OrderEntity>() return await Context.Queryable<OrderEntity>()
.RightJoin<OrderPullStatusEntity>((a, b) => a.Id == b.OrderId) .InnerJoin<OrderPullStatusEntity>((a, b) => a.Id == b.OrderId)
.LeftJoin<VServiceProviderEntity>((a, b, c) => b.ServiceProviderCode == c.Code) .Where((a, b) => b.ServiceProviderCode == serviceProviderCode && !a.IsCompleted
.LeftJoin<VSystemEntity>((a, b, c, d) => a.SubSystemId == d.Id) && b.StartTime <= DateTime.Now &&
.Where((a, b, c) => c.Id == serviceProviderId && !a.IsCompleted b.EndTime >= DateTime.Now)
&& b.StartTime <= DateTime.Now && b.EndTime >= DateTime.Now) .Select((a, b) => new OrderWithServiceProviderVO
.Select((a, b, c, d) => new OrderWithServiceProviderVO
{ {
OrderNo = a.OrderNo, OrderNo = a.OrderNo,
OrderType = a.OrderType, OrderType = a.OrderType,
ServiceProviderCode = c.Code,
ServiceProviderName = c.Name,
SubSystemId = a.SubSystemId, SubSystemId = a.SubSystemId,
SubSystemCode = d.Key ServiceProviderCode = b.ServiceProviderCode
}) })
.Skip((pageIndex - 1) * pageSize) .Skip((pageIndex - 1) * pageSize)
.Take(pageSize) .Take(pageSize)

View File

@ -84,7 +84,7 @@ public class TrackPullConfigRepository : BasicRepository<TrackPullConfigEntity>,
{ {
Id = trackPull.Id, Id = trackPull.Id,
SubSystem = system.CnName, SubSystem = system.CnName,
SubSystemCode = system.Key, SubSystemId = system.Id,
ServiceProvider = service.Name, ServiceProvider = service.Name,
ServiceProviderCode = service.Code, ServiceProviderCode = service.Code,
}, true) }, true)
@ -141,12 +141,11 @@ public class TrackPullConfigRepository : BasicRepository<TrackPullConfigEntity>,
return await Context.Queryable<TrackPullContentConfigEntity>().Where(whereExpression).AnyAsync(); return await Context.Queryable<TrackPullContentConfigEntity>().Where(whereExpression).AnyAsync();
} }
public async Task<int> FindIdAsync(string subSystemCode, string serviceProviderCode) public async Task<int> FindIdAsync(int subSystemId, string serviceProviderCode)
{ {
return await AsQueryable() return await AsQueryable()
.LeftJoin<VSystemEntity>((trackPull, system) => trackPull.SubSystemId == system.Id) .LeftJoin<VServiceProviderEntity>((trackPull, service) => trackPull.ServiceProviderId == service.Id)
.LeftJoin<VServiceProviderEntity>((trackPull, system, service) => trackPull.ServiceProviderId == service.Id) .Where((trackPull, service) => trackPull.SubSystemId == subSystemId && service.Code == serviceProviderCode)
.Where((trackPull, system, service) => system.Key == subSystemCode && service.Code == serviceProviderCode)
.Select(trackPull => trackPull.Id) .Select(trackPull => trackPull.Id)
.FirstAsync(); .FirstAsync();
} }