From b30846a8113e7a2b5b4a39d98d177b5a1670eb51 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=92=9F=E5=96=9C=E6=97=BA?= Date: Mon, 5 Aug 2024 16:19:04 +0800 Subject: [PATCH 1/5] =?UTF-8?q?feat:=20=E5=AE=9A=E6=97=B6=E4=BB=BB?= =?UTF-8?q?=E5=8A=A1=E6=8E=A8=E9=80=81=E9=A2=84=E8=AD=A6=EF=BC=88=E3=80=8B?= =?UTF-8?q?12=E5=B0=8F=E6=97=B6=E6=B2=A1=E6=9C=89=E6=8E=A8=E9=80=81?= =?UTF-8?q?=E7=9A=84=20=E6=94=B9=E4=B8=BA=E4=BA=8B=E4=BB=B6=E6=8F=90?= =?UTF-8?q?=E4=BA=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Events/PushWarningEvent.cs | 6 +++ .../EventHandlers/PushWarningEventHandler.cs | 43 +++++++++++++++++++ .../ProvideServices/TrackPushService.cs | 26 +++-------- .../Consts/GlobalConst.MQ.cs | 5 +++ 4 files changed, 61 insertions(+), 19 deletions(-) create mode 100644 src/SJZY.Track.Application.Contract/Events/PushWarningEvent.cs create mode 100644 src/SJZY.Track.Application/CAP/EventHandlers/PushWarningEventHandler.cs diff --git a/src/SJZY.Track.Application.Contract/Events/PushWarningEvent.cs b/src/SJZY.Track.Application.Contract/Events/PushWarningEvent.cs new file mode 100644 index 00000000..c8fbdb20 --- /dev/null +++ b/src/SJZY.Track.Application.Contract/Events/PushWarningEvent.cs @@ -0,0 +1,6 @@ +namespace SJZY.Track.Application.Contract.Events; + +public class PushWarningEvent +{ + public int PageSize { get; set; } +} \ No newline at end of file diff --git a/src/SJZY.Track.Application/CAP/EventHandlers/PushWarningEventHandler.cs b/src/SJZY.Track.Application/CAP/EventHandlers/PushWarningEventHandler.cs new file mode 100644 index 00000000..8197ec1c --- /dev/null +++ b/src/SJZY.Track.Application/CAP/EventHandlers/PushWarningEventHandler.cs @@ -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 _logger; + private readonly IOrderRepository _orderRepository; + + public PushWarningEventHandler(IOrderRepository orderRepository, + ILogger 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); + } +} \ No newline at end of file diff --git a/src/SJZY.Track.Application/Services/ProvideServices/TrackPushService.cs b/src/SJZY.Track.Application/Services/ProvideServices/TrackPushService.cs index fe78e2dd..6b21c0fb 100644 --- a/src/SJZY.Track.Application/Services/ProvideServices/TrackPushService.cs +++ b/src/SJZY.Track.Application/Services/ProvideServices/TrackPushService.cs @@ -1,6 +1,5 @@ using DotNetCore.CAP; using Microsoft.AspNetCore.Authorization; -using SJZY.Track.Application.CAP.EventHandlers; using SJZY.Track.Application.Contract.Dtos.ProvideServices; using SJZY.Track.Application.Contract.Events; using SJZY.Track.Domain.Aggregates.OrderAggregate; @@ -18,10 +17,10 @@ namespace SJZY.Track.Application.Services.ProvideServices; [Route("/ProviderService")] public class TrackPushService : ApplicationService { - private readonly IOrderRepository _orderRepository; private readonly ICapPublisher _capPublisher; - private readonly ITrackPushRecordsRepository _trackPushRecordsRepository; + private readonly IOrderRepository _orderRepository; private readonly IHttpClientProxy _requestCurrentUserService; + private readonly ITrackPushRecordsRepository _trackPushRecordsRepository; public TrackPushService(IOrderRepository orderRepository , ICapPublisher capPublisher @@ -92,23 +91,12 @@ public class TrackPushService : ApplicationService [HttpPost("Track/PushWarnForTask")] public async Task PushWarnForTaskAsync() { - int total = 0, pageSize = 1000,waitTime = 1000; - var dateTimes = Enumerable.Range(1, 12).Select(val => DateTime.Now.AddHours(-val)).ToList(); - - foreach (var dateTime in dateTimes) + await _capPublisher.PublishAsync(GlobalConst.TrackPushWarning, new PushWarningEvent { - var rows = 0; - var pageindex = 1; - do - { - rows = await _orderRepository.PushWarnOrdersAsync(pageSize,pageindex,dateTime); - total+=rows; - pageindex++; - await Task.Delay(waitTime); - }while (rows!= pageSize); - } - - return $"本次预警扫描了:{total}个订单"; + PageSize = 1000 + }); + + return "推送预警任务已启动"; } /// diff --git a/src/SJZY.Track.Domain/Consts/GlobalConst.MQ.cs b/src/SJZY.Track.Domain/Consts/GlobalConst.MQ.cs index 378f0b89..515afe91 100644 --- a/src/SJZY.Track.Domain/Consts/GlobalConst.MQ.cs +++ b/src/SJZY.Track.Domain/Consts/GlobalConst.MQ.cs @@ -56,4 +56,9 @@ public partial class GlobalConst /// 关联订单后补轨迹 /// public const string OrderLinkAfterFillTrack = "SJZY.Track.OrderLinkAfterFillTrack"; + + /// + /// 推送预警任务 + /// + public const string TrackPushWarning = "SJZY.Track.TrackPushWarning"; } \ No newline at end of file From e21f3b8460f2b496b33cc7c97deb6ac8ea468494 Mon Sep 17 00:00:00 2001 From: xiaolipro <2357729423@qq.com> Date: Tue, 6 Aug 2024 10:50:00 +0800 Subject: [PATCH 2/5] temp --- src/SJZY.Track.Api/appsettings.json | 2 +- .../EventHandlers/TrackRefreshEventHandler.cs | 28 ++++++++++--------- .../ProvideServices/TrackPullService.cs | 18 ++++++++++++ .../ProvideServices/TrackService.Query.cs | 3 +- src/SJZY.Track.Domain/Consts/GlobalConst.cs | 2 ++ 5 files changed, 38 insertions(+), 15 deletions(-) diff --git a/src/SJZY.Track.Api/appsettings.json b/src/SJZY.Track.Api/appsettings.json index 6f7fc2b9..d69cb0c1 100644 --- a/src/SJZY.Track.Api/appsettings.json +++ b/src/SJZY.Track.Api/appsettings.json @@ -5,7 +5,7 @@ "Apollo": { "AppId": "SJZY.Track.Configuration", "Env": "DEV", - "Namespace": "DEV", + "Namespace": "Test", "MetaServer": "http://apollo-service-test-apollo-configservice.apollo.svc.cluster.local:8080", "ConfigServer": [ "http://apollo-service-test-apollo-configservice.apollo.svc.cluster.local:8080" ] } diff --git a/src/SJZY.Track.Application/CAP/EventHandlers/TrackRefreshEventHandler.cs b/src/SJZY.Track.Application/CAP/EventHandlers/TrackRefreshEventHandler.cs index 8411bf76..cbecb958 100644 --- a/src/SJZY.Track.Application/CAP/EventHandlers/TrackRefreshEventHandler.cs +++ b/src/SJZY.Track.Application/CAP/EventHandlers/TrackRefreshEventHandler.cs @@ -48,7 +48,8 @@ public class TrackRefreshEventHandler : ITransientDependency, ICapSubscribe if (@event.Data == null || config == null) return; var data = JObject.Parse(@event.Data); - var orderToken = data[config.ParamConfig.OrderPath]; + + var orderToken = data.SelectToken(config.ParamConfig.OrderPath); if (orderToken is JArray orderTokens) { foreach (var token in orderTokens) @@ -69,7 +70,7 @@ public class TrackRefreshEventHandler : ITransientDependency, ICapSubscribe var orderNo = orderToken[paramConfig.OrderNoName]?.Value(); if (orderNo.IsNullOrWhiteSpace()) return; - var trackToken = orderToken[paramConfig.TrackDetailsPath]; + var trackToken = orderToken.SelectToken(paramConfig.TrackDetailsPath); if (trackToken is null) return; var order = await _orderRepository.GetFirstAsync(x => @@ -115,33 +116,34 @@ public class TrackRefreshEventHandler : ITransientDependency, ICapSubscribe TrackPullContentConfigDto? matchedContentConfig = null; // 1、匹配轨迹代码 - if (paramConfig.TrackContentCodeName != null) + if (!paramConfig.TrackContentCodeName.IsNullOrWhiteSpace()) { - var trackCode = trackToken[paramConfig.TrackContentCodeName]?.Value(); + var trackCode = trackToken[paramConfig.TrackContentCodeName!]?.Value(); if (!trackCode.IsNullOrWhiteSpace()) { matchedContentConfig = contentConfigs.FirstOrDefault(x => x.TrackContentCodeValue == trackCode); } } // 2、匹配轨迹状态 - else if (paramConfig.TrackStatusName != null) + else if (!paramConfig.TrackStatusName.IsNullOrWhiteSpace()) { - var trackStatus = trackToken[paramConfig.TrackStatusName]?.Value(); + var trackStatus = trackToken[paramConfig.TrackStatusName!]?.Value(); if (!trackStatus.IsNullOrWhiteSpace()) { matchedContentConfig = contentConfigs.FirstOrDefault(x => x.TrackStatusValue == trackStatus); } } // 3、匹配轨迹内容 - else if (paramConfig.TrackContentName != null) + else if (!paramConfig.TrackContentName.IsNullOrWhiteSpace()) { - var trackContent = trackToken[paramConfig.TrackContentName]?.Value(); + var trackContent = trackToken[paramConfig.TrackContentName!]?.Value(); if (!trackContent.IsNullOrWhiteSpace()) { Debug.Assert(trackContent != null, nameof(trackContent) + " != null"); + // 3.1 按内容直接匹配 matchedContentConfig = contentConfigs.FirstOrDefault(x => x.TrackContentValue == trackContent); - // 按关键字分析轨迹内容 + // 3.2 按关键字分析轨迹内容 if (matchedContentConfig is null) { foreach (var contentConfig in contentConfigs) @@ -191,10 +193,10 @@ public class TrackRefreshEventHandler : ITransientDependency, ICapSubscribe var trackTimeZone = paramConfig.TrackTimeZoneName == null ? null : trackToken[paramConfig.TrackTimeZoneName]?.Value(); - - //兜底时区 + + // todo:兜底时区是slow path var hasTimezoneBottomLine = false; //执行了兜底但是没有兜底住,需要记录 - if (!trackTimeZone.HasValue && matchedContentConfig?.TrackZonePlaceValue != null && matchedContentConfig.TrackZonePlaceValue.HasValue) + if (!trackTimeZone.HasValue && matchedContentConfig?.TrackZonePlaceValue is not null) { //兜底没配置的就不需要兜底,拉取的发生地没就没 var timezone= await GetTimezone(matchedContentConfig,context.OrderId); @@ -214,7 +216,7 @@ public class TrackRefreshEventHandler : ITransientDependency, ICapSubscribe OriginTrackData = JsonConvert.SerializeObject(trackToken), TrackPlace = trackPlace ?? GlobalConst.EmptyString, TrackTime = trackTime ?? DateTime.Now, - TrackTimeZone = trackTimeZone ?? 8 + TrackTimeZone = trackTimeZone ?? GlobalConst.NoneTrackTimeZone, }; if (paramConfig.TrackContentName != null) { diff --git a/src/SJZY.Track.Application/Services/ProvideServices/TrackPullService.cs b/src/SJZY.Track.Application/Services/ProvideServices/TrackPullService.cs index 00715aa9..393d31e5 100644 --- a/src/SJZY.Track.Application/Services/ProvideServices/TrackPullService.cs +++ b/src/SJZY.Track.Application/Services/ProvideServices/TrackPullService.cs @@ -4,6 +4,7 @@ using SJZY.Expand.ABP.Core; using SJZY.Expand.ABP.Core.Logger; using SJZY.Expand.ABP.Core.PublicMethords; using SJZY.InterfaceRelay.Application.Contracts; +using SJZY.Track.Application.CAP.EventHandlers; using SJZY.Track.Application.Contract.Dtos.ProvideServices; using SJZY.Track.Application.Contract.Dtos.TrackPull; using SJZY.Track.Application.Contract.Services; @@ -88,6 +89,23 @@ public class TrackPullService : ApplicationService await Task.WhenAll(tasks); return true; } + + /// + /// 轨迹刷新测试 + /// + /// + /// + /// + [HttpPost("Track/TrackRefreshEventTest")] +#if DEBUG + [AllowAnonymous] +#endif + public async Task TrackRefreshEventTest([FromServices]TrackRefreshEventHandler trackRefreshEventHandler, InterfaceRelayForwardReplayEvent input) + { + await trackRefreshEventHandler.ConsumerAsync(input); + + return true; + } private async Task RefreshForConfigAsync(TrackPullConfigDto config) { diff --git a/src/SJZY.Track.Application/Services/ProvideServices/TrackService.Query.cs b/src/SJZY.Track.Application/Services/ProvideServices/TrackService.Query.cs index 74f4e52f..259ee8d9 100644 --- a/src/SJZY.Track.Application/Services/ProvideServices/TrackService.Query.cs +++ b/src/SJZY.Track.Application/Services/ProvideServices/TrackService.Query.cs @@ -1,5 +1,6 @@ using SJZY.Track.Application.Contract.Dtos.ProvideServices; using SJZY.Track.Domain.Aggregates.TrackDetailsAggregate; +using SJZY.Track.Domain.Consts; namespace SJZY.Track.Application.Services.ProvideServices; @@ -41,7 +42,7 @@ public partial class TrackService Content = x.TrackContent, OriginContent = x.OriginTrackContent, 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 }).ToList(); diff --git a/src/SJZY.Track.Domain/Consts/GlobalConst.cs b/src/SJZY.Track.Domain/Consts/GlobalConst.cs index 22beb8e1..11690ae7 100644 --- a/src/SJZY.Track.Domain/Consts/GlobalConst.cs +++ b/src/SJZY.Track.Domain/Consts/GlobalConst.cs @@ -5,4 +5,6 @@ public partial class GlobalConst public const string SystemUser = "系统"; public const string EmptyString = "--"; public const int ChunkSize = 100; + + public const float NoneTrackTimeZone = 99999; } \ No newline at end of file From a3e395a2723d71778d73186bc0d845128a120494 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=92=9F=E5=96=9C=E6=97=BA?= Date: Tue, 6 Aug 2024 11:09:33 +0800 Subject: [PATCH 3/5] =?UTF-8?q?feat:=20=E6=8A=BD=E8=B1=A1=E5=87=BA?= =?UTF-8?q?=E8=BD=A8=E8=BF=B9=E5=8F=91=E7=94=9F=E5=9C=B0=E5=92=8C=E8=BD=A8?= =?UTF-8?q?=E8=BF=B9=E6=97=B6=E5=8C=BA=E7=9A=84=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../EventHandlers/TrackRefreshEventHandler.cs | 115 ++++++++++++------ 1 file changed, 76 insertions(+), 39 deletions(-) diff --git a/src/SJZY.Track.Application/CAP/EventHandlers/TrackRefreshEventHandler.cs b/src/SJZY.Track.Application/CAP/EventHandlers/TrackRefreshEventHandler.cs index cbecb958..f29513a0 100644 --- a/src/SJZY.Track.Application/CAP/EventHandlers/TrackRefreshEventHandler.cs +++ b/src/SJZY.Track.Application/CAP/EventHandlers/TrackRefreshEventHandler.cs @@ -19,11 +19,11 @@ namespace SJZY.Track.Application.CAP.EventHandlers; public class TrackRefreshEventHandler : ITransientDependency, ICapSubscribe { - private readonly IOrderRepository _orderRepository; private readonly ICapPublisher _capPublisher; - private readonly ITrackPullCacheService _trackPullCacheService; - private readonly ITrackDetailsRepository _trackDetailsRepository; + private readonly IOrderRepository _orderRepository; private readonly ITimezoneQueries _timezoneQueries; + private readonly ITrackDetailsRepository _trackDetailsRepository; + private readonly ITrackPullCacheService _trackPullCacheService; public TrackRefreshEventHandler(IOrderRepository orderRepository, ICapPublisher capPublisher, ITrackPullCacheService trackPullCacheService, @@ -48,7 +48,7 @@ public class TrackRefreshEventHandler : ITransientDependency, ICapSubscribe if (@event.Data == null || config == null) return; var data = JObject.Parse(@event.Data); - + var orderToken = data.SelectToken(config.ParamConfig.OrderPath); if (orderToken is JArray orderTokens) { @@ -173,38 +173,19 @@ public class TrackRefreshEventHandler : ITransientDependency, ICapSubscribe } } - // 轨迹发生地 - var trackPlace = paramConfig.TrackPlaceName == null - ? null - : trackToken[paramConfig.TrackPlaceName]?.Value(); - 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 ? null : trackToken[paramConfig.TrackTimeName]?.Value(); - // 轨迹发生时区 - var trackTimeZone = paramConfig.TrackTimeZoneName == null - ? null - : trackToken[paramConfig.TrackTimeZoneName]?.Value(); - - // todo:兜底时区是slow path - var hasTimezoneBottomLine = false; //执行了兜底但是没有兜底住,需要记录 - if (!trackTimeZone.HasValue && matchedContentConfig?.TrackZonePlaceValue is not null) - { - //兜底没配置的就不需要兜底,拉取的发生地没就没 - var timezone= await GetTimezone(matchedContentConfig,context.OrderId); - - trackTimeZone = timezone; - hasTimezoneBottomLine = !timezone.HasValue; - } - + + // 轨迹时区 + var (trackTimeZone, hasTimezoneBottomLine) = + await GetTimezone(paramConfig, matchedContentConfig, context.OrderId, trackToken); + + // 轨迹发生地 + var (trackPlace, hasPlaceBottomLine) = + await GetTrackPlace(paramConfig, matchedContentConfig, context.OrderId, trackToken); + if (matchedContentConfig is null) { var notMappedEvent = new TrackInsertForNotMappedEvent @@ -236,7 +217,7 @@ public class TrackRefreshEventHandler : ITransientDependency, ICapSubscribe var timezoneTagValue = hasTimezoneBottomLine ? 1 : 0; deficiencyTagValue = placeTagValue + timezoneTagValue; } - + // 新增/更新轨迹 var trackUpsertEvent = new TrackUpsertEvent { @@ -249,7 +230,7 @@ public class TrackRefreshEventHandler : ITransientDependency, ICapSubscribe OrderType = context.OrderType, } }, - + TrackRefreshData = new TrackRefreshStruct { ServiceProviderName = context.ServiceProviderName, @@ -272,13 +253,70 @@ public class TrackRefreshEventHandler : ITransientDependency, ICapSubscribe await _capPublisher.PublishAsync(GlobalConst.TrackUpsertForRefreshSubscribe, trackUpsertEvent); } + /// + /// 获取轨迹时区 + /// + /// 配置信息 + /// 配置信息 + /// 订单id + /// + /// 时区,是否执行了兜底轨迹时区 + 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(); + + 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); + } + + /// + /// 获得轨迹地址 + /// + /// 配置信息 + /// 配置信息 + /// 订单id + /// + /// 时区,是否执行了兜底轨迹时区 + 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(); + 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); + } + /// /// 根据订单id获取兜底位置 /// /// /// /// - private Task GetPlaceByOrder(int trackValue,int orderId) + private Task GetPlaceByOrder(int trackValue, int orderId) { Expression> resultExpression = (TrackLocationValue)trackValue switch @@ -291,7 +329,7 @@ public class TrackRefreshEventHandler : ITransientDependency, ICapSubscribe TrackLocationValue.LeaveCountry => x => x.LeaveCountry, _ => x => x.LeaveCountry }; - return _orderRepository.GetFirstAsync(x => x.Id == orderId, resultExpression); + return _orderRepository.GetFirstAsync(x => x.Id == orderId, resultExpression); } /// @@ -300,13 +338,12 @@ public class TrackRefreshEventHandler : ITransientDependency, ICapSubscribe /// /// /// - private async Task GetTimezone(TrackPullContentConfigDto matchedContentConfig,int orderId ) + private async Task GetTimezone(TrackPullContentConfigDto matchedContentConfig, int orderId) { - var placeOrCode = await GetPlaceByOrder(matchedContentConfig!.TrackZonePlaceValue.Value,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) { From 1805cc5b76ce1e00caf7ee4ff2ce07c950bd744e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=92=9F=E5=96=9C=E6=97=BA?= Date: Tue, 6 Aug 2024 11:35:52 +0800 Subject: [PATCH 4/5] =?UTF-8?q?feat:=20IsTriggerPull=20=E5=A4=9A=E6=AC=A1?= =?UTF-8?q?=E5=88=B7=E8=BD=A8=E8=BF=B9=E8=A2=AB=E7=BD=AE=E4=B8=BAnull?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...TrackChangeAfterUpdateOrderEventHandler.cs | 33 +++++++++++-------- 1 file changed, 19 insertions(+), 14 deletions(-) diff --git a/src/SJZY.Track.Application/CAP/EventHandlers/TrackChangeAfterUpdateOrderEventHandler.cs b/src/SJZY.Track.Application/CAP/EventHandlers/TrackChangeAfterUpdateOrderEventHandler.cs index 85d0ef57..1cbff4a3 100644 --- a/src/SJZY.Track.Application/CAP/EventHandlers/TrackChangeAfterUpdateOrderEventHandler.cs +++ b/src/SJZY.Track.Application/CAP/EventHandlers/TrackChangeAfterUpdateOrderEventHandler.cs @@ -12,13 +12,14 @@ namespace SJZY.Track.Application.CAP.EventHandlers; public class TrackChangeAfterUpdateOrderEventHandler : ITransientDependency, ICapSubscribe { - private readonly IOrderRepository _orderRepository; private readonly IForewarningNotifyService _forewarningNotifyService; - private readonly ITrackPullCacheService _trackPullCacheService; + private readonly IOrderRepository _orderRepository; private readonly IProvideQueries _provideQueries; - + private readonly ITrackPullCacheService _trackPullCacheService; + public TrackChangeAfterUpdateOrderEventHandler(IOrderRepository orderRepository, - IForewarningNotifyService forewarningNotifyService, ITrackPullCacheService trackPullCacheService, IProvideQueries provideQueries) + IForewarningNotifyService forewarningNotifyService, ITrackPullCacheService trackPullCacheService, + IProvideQueries provideQueries) { _orderRepository = orderRepository; _forewarningNotifyService = forewarningNotifyService; @@ -34,7 +35,7 @@ public class TrackChangeAfterUpdateOrderEventHandler : ITransientDependency, ICa if (orders.Count == 0) return; var updateOrders = new List(); - var providerDic= await GetProviderDic(@event.OrderIds); + var providerDic = await GetProviderDic(@event.OrderIds); foreach (var order in orders) { if (order.LatestTrackContent != @event.TrackContent) @@ -48,11 +49,11 @@ public class TrackChangeAfterUpdateOrderEventHandler : ITransientDependency, ICa } // 执行轨迹兜底时 时区缺失和发生地缺失标记,1表示时区,2表示发生地,3表示两种 - if (@event.DeficiencyTagValue > 0 && @event.DeficiencyTagValue<=3) + if (@event.DeficiencyTagValue > 0 && @event.DeficiencyTagValue <= 3) { order.DeficiencyTag = @event.DeficiencyTagValue; } - + if (!order.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)) { - var config = await _trackPullCacheService.GetPullParamWithContentConfigAsync(provider.SubSystemId, provider.ServiceProviderId); - - if (!string.IsNullOrEmpty(config?.ParamConfig.TrackContentCode) && config.ParamConfig.TrackContentCode!.ToLower() == @event.TrackCode.ToLower()) + var config = + await _trackPullCacheService.GetPullParamWithContentConfigAsync(provider.SubSystemId, + provider.ServiceProviderId); + + if (!string.IsNullOrEmpty(config?.ParamConfig.TrackContentCode) && + config.ParamConfig.TrackContentCode!.ToLower() == @event.TrackCode.ToLower()) { // 触发拉取节点 order.IsTriggerPull = 1; } } - + order.LatestTrackContent = @event.TrackContent; order.LatestTrackEnContent = @event.TrackEnContent; order.LatestTrackPlace = @event.TrackPlace; @@ -80,7 +84,7 @@ public class TrackChangeAfterUpdateOrderEventHandler : ITransientDependency, ICa await _orderRepository.UpdateRangeAsync(updateOrders, x => new { 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, IsTransit = order.IsTransit, LeavePort = order.LeavePort, - ProductCode = order.ProductCode + ProductCode = order.ProductCode, + IsTriggerPull = order.IsTriggerPull }); } @@ -139,7 +144,7 @@ public class TrackChangeAfterUpdateOrderEventHandler : ITransientDependency, ICa }).ToList() }; } - + /// /// 获取服务商字典 /// From 3127a3a38efe9df0a191e1327df7ed8cc5df4295 Mon Sep 17 00:00:00 2001 From: xiaolipro <2357729423@qq.com> Date: Tue, 6 Aug 2024 16:53:47 +0800 Subject: [PATCH 5/5] =?UTF-8?q?change=EF=BC=9A=E8=BD=A8=E8=BF=B9code?= =?UTF-8?q?=E7=9B=B8=E5=90=8C=EF=BC=8C=E6=97=B6=E9=97=B4=E3=80=81=E5=8F=91?= =?UTF-8?q?=E7=94=9F=E5=9C=B0=E4=B8=8D=E5=90=8C=E7=9A=84=EF=BC=8C=E5=85=81?= =?UTF-8?q?=E8=AE=B8=E5=AD=98=E5=9C=A8=E5=A4=9A=E6=9D=A1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Dtos/ProvideServices/GetTrackOutput.cs | 2 +- .../Events/TrackRefreshStruct.cs | 6 +- src/SJZY.Track.Application/CAP/CAPFilter.cs | 25 +---- .../TrackInsertForNotMappedEventHandler.cs | 50 ---------- .../EventHandlers/TrackRefreshEventHandler.cs | 91 +++++++++++-------- .../EventHandlers/TrackUpsertEventHandler.cs | 31 ++++--- .../Helpers/StringHelper.cs | 60 ++++++++---- .../ProvideServices/TrackPullService.cs | 7 +- .../ProvideServices/TrackService.Query.cs | 4 +- .../Services/TrackOrders/TrackOrderService.cs | 5 + .../ITrackDetailsRepository.cs | 2 +- .../TrackDetailsIndex.cs | 38 ++++---- .../VEntities/VAirportEntity.cs | 2 +- .../VEntities/VCityEntity.cs | 2 +- .../Repositories/TrackDetailsRepository.cs | 6 +- 15 files changed, 160 insertions(+), 171 deletions(-) delete mode 100644 src/SJZY.Track.Application/CAP/EventHandlers/TrackInsertForNotMappedEventHandler.cs diff --git a/src/SJZY.Track.Application.Contract/Dtos/ProvideServices/GetTrackOutput.cs b/src/SJZY.Track.Application.Contract/Dtos/ProvideServices/GetTrackOutput.cs index dcafe452..fadb5727 100644 --- a/src/SJZY.Track.Application.Contract/Dtos/ProvideServices/GetTrackOutput.cs +++ b/src/SJZY.Track.Application.Contract/Dtos/ProvideServices/GetTrackOutput.cs @@ -18,5 +18,5 @@ public class TrackDetail public string? OriginContent { get; set; } public string Location { get; set; } = null!; public DateTime Time { get; set; } - public float TimeZone { get; set; } + public float? TimeZone { get; set; } } \ No newline at end of file diff --git a/src/SJZY.Track.Application.Contract/Events/TrackRefreshStruct.cs b/src/SJZY.Track.Application.Contract/Events/TrackRefreshStruct.cs index 62bcf4a2..56d33357 100644 --- a/src/SJZY.Track.Application.Contract/Events/TrackRefreshStruct.cs +++ b/src/SJZY.Track.Application.Contract/Events/TrackRefreshStruct.cs @@ -13,13 +13,13 @@ public struct TrackRefreshStruct public string? OriginTrackContent { get; set; } /// - /// 原轨迹报文 + /// 原轨迹报文hash(刷新轨迹重复性校验使用) /// - public string? OriginTrackData { get; set; } + public string? OriginTrackDataHash { get; set; } /// /// 表示订单是否完成(只由轨迹刷新配置决定) - /// tips:能够使得IsCompleted为true的点,全局只有一个:轨迹刷新 + /// todo:能够使得IsCompleted为true的点,全局只有一个:轨迹刷新?? /// public bool IsCompleted { get; set; } } \ No newline at end of file diff --git a/src/SJZY.Track.Application/CAP/CAPFilter.cs b/src/SJZY.Track.Application/CAP/CAPFilter.cs index 036c1e34..4b36e128 100644 --- a/src/SJZY.Track.Application/CAP/CAPFilter.cs +++ b/src/SJZY.Track.Application/CAP/CAPFilter.cs @@ -1,9 +1,8 @@ -using System.Security.Cryptography; -using System.Text; -using DotNetCore.CAP.Filter; +using DotNetCore.CAP.Filter; using SJZY.Expand.ABP.Core; using SJZY.Expand.ABP.Core.Logger; using SJZY.Expand.ABP.Core.PublicMethords; +using SJZY.Track.Application.Helpers; using SJZY.Track.Domain.Consts; namespace SJZY.Track.Application.CAP; @@ -33,7 +32,7 @@ public class CapFilter : SubscribeFilter context.DeliverMessage.Headers.TryGetValue("sjzy-arguments-hash", out var hash); if (hash.IsNullOrEmpty()) // 计算参数hash { - hash = GetHash(argumentJsonStr); + hash = StringHelper.GetHash(argumentJsonStr); context.DeliverMessage.Headers["sjzy-arguments-hash"] = hash; } @@ -76,22 +75,4 @@ public class CapFilter : SubscribeFilter return Task.CompletedTask; } - - - /// 获取字符串的hash值 - /// - /// - 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); - } } \ No newline at end of file diff --git a/src/SJZY.Track.Application/CAP/EventHandlers/TrackInsertForNotMappedEventHandler.cs b/src/SJZY.Track.Application/CAP/EventHandlers/TrackInsertForNotMappedEventHandler.cs deleted file mode 100644 index b2f59331..00000000 --- a/src/SJZY.Track.Application/CAP/EventHandlers/TrackInsertForNotMappedEventHandler.cs +++ /dev/null @@ -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); - } -} \ No newline at end of file diff --git a/src/SJZY.Track.Application/CAP/EventHandlers/TrackRefreshEventHandler.cs b/src/SJZY.Track.Application/CAP/EventHandlers/TrackRefreshEventHandler.cs index cbecb958..19dc5ac0 100644 --- a/src/SJZY.Track.Application/CAP/EventHandlers/TrackRefreshEventHandler.cs +++ b/src/SJZY.Track.Application/CAP/EventHandlers/TrackRefreshEventHandler.cs @@ -48,7 +48,7 @@ public class TrackRefreshEventHandler : ITransientDependency, ICapSubscribe if (@event.Data == null || config == null) return; var data = JObject.Parse(@event.Data); - + var orderToken = data.SelectToken(config.ParamConfig.OrderPath); if (orderToken is JArray orderTokens) { @@ -107,9 +107,12 @@ public class TrackRefreshEventHandler : ITransientDependency, ICapSubscribe private async Task HandleTrackAsync(JToken trackToken, TrackPullParamWithContentConfigDto paramWithContentConfig, TrackRefreshContext context) { - var originTrackData = JsonConvert.SerializeObject(trackToken); + var originTrackDataHash = StringHelper.GetHash(JsonConvert.SerializeObject(trackToken)); // 如果已经存在一模一样的报文了说明处理过了,直接return - if (await _trackDetailsRepository.AnyAsync(context.OrderId, originTrackData)) return; + if (await _trackDetailsRepository.AnyAsync(context.OrderId, originTrackDataHash)) + { + return; + } var paramConfig = paramWithContentConfig.ParamConfig; var contentConfigs = paramWithContentConfig.ContentConfigs; @@ -178,10 +181,10 @@ public class TrackRefreshEventHandler : ITransientDependency, ICapSubscribe ? null : trackToken[paramConfig.TrackPlaceName]?.Value(); var hasPlaceBottomLine = false; //执行了兜底但是没有兜底住,需要记录 - if (trackPlace.IsNullOrWhiteSpace() && matchedContentConfig?.TrackPlaceValue != null && matchedContentConfig.TrackPlaceValue.HasValue) + if (trackPlace.IsNullOrWhiteSpace() && matchedContentConfig?.TrackPlaceValue is not null) { //兜底没配置的就不需要兜底,拉取的发生地没就没 - trackPlace = await GetPlaceByOrder(matchedContentConfig!.TrackPlaceValue.Value,context.OrderId); + trackPlace = await GetPlaceByOrder(matchedContentConfig.TrackPlaceValue.Value, context.OrderId); hasPlaceBottomLine = string.IsNullOrWhiteSpace(trackPlace); } @@ -193,37 +196,22 @@ public class TrackRefreshEventHandler : ITransientDependency, ICapSubscribe var trackTimeZone = paramConfig.TrackTimeZoneName == null ? null : trackToken[paramConfig.TrackTimeZoneName]?.Value(); - + // todo:兜底时区是slow path var hasTimezoneBottomLine = false; //执行了兜底但是没有兜底住,需要记录 if (!trackTimeZone.HasValue && matchedContentConfig?.TrackZonePlaceValue is not null) { //兜底没配置的就不需要兜底,拉取的发生地没就没 - var timezone= await GetTimezone(matchedContentConfig,context.OrderId); - + var timezone = await GetTimezone(matchedContentConfig, context.OrderId); + trackTimeZone = timezone; hasTimezoneBottomLine = !timezone.HasValue; } - + + // 没匹配上,新增服务商轨迹 if (matchedContentConfig is null) { - var notMappedEvent = new TrackInsertForNotMappedEvent - { - 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 ?? GlobalConst.NoneTrackTimeZone, - }; - if (paramConfig.TrackContentName != null) - { - notMappedEvent.OriginTrackContent = trackToken[paramConfig.TrackContentName]?.Value(); - } - - await _capPublisher.PublishAsync(GlobalConst.TrackInsertForNotMappedEventSubscribe, notMappedEvent); + await InsertNotMappedTrackAsync(trackToken, context, trackPlace, trackTime, trackTimeZone, paramConfig); return; } @@ -236,7 +224,7 @@ public class TrackRefreshEventHandler : ITransientDependency, ICapSubscribe var timezoneTagValue = hasTimezoneBottomLine ? 1 : 0; deficiencyTagValue = placeTagValue + timezoneTagValue; } - + // 新增/更新轨迹 var trackUpsertEvent = new TrackUpsertEvent { @@ -249,11 +237,11 @@ public class TrackRefreshEventHandler : ITransientDependency, ICapSubscribe OrderType = context.OrderType, } }, - + TrackRefreshData = new TrackRefreshStruct { ServiceProviderName = context.ServiceProviderName, - OriginTrackData = originTrackData, + OriginTrackDataHash = originTrackDataHash, IsCompleted = matchedContentConfig.IsCompleted, OriginTrackContent = paramConfig.TrackContentName != null ? trackToken[paramConfig.TrackContentName]?.Value() @@ -263,22 +251,50 @@ public class TrackRefreshEventHandler : ITransientDependency, ICapSubscribe TrackCode = matchedContentConfig.TrackContentCode, TrackPlace = trackPlace ?? GlobalConst.EmptyString, TrackTime = trackTime ?? DateTime.Now, - TrackTimeZone = trackTimeZone ?? 8, - DeficiencyTagValue = deficiencyTagValue + TrackTimeZone = trackTimeZone ?? GlobalConst.NoneTrackTimeZone, + DeficiencyTagValue = deficiencyTagValue, + IsAdd = true, }; - trackUpsertEvent.IsAdd = - !await _trackDetailsRepository.AnyByCodeAsync(context.OrderId, matchedContentConfig.TrackContentCode); 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() ?? GlobalConst.EmptyString; + } + + track.ZeroTrackTime = track.TrackTime.Subtract(TimeSpan.FromHours(track.TrackTimeZone)); + + await _trackDetailsRepository.AddAsync(track); + } + /// /// 根据订单id获取兜底位置 /// /// /// /// - private Task GetPlaceByOrder(int trackValue,int orderId) + private Task GetPlaceByOrder(int trackValue, int orderId) { Expression> resultExpression = (TrackLocationValue)trackValue switch @@ -291,7 +307,7 @@ public class TrackRefreshEventHandler : ITransientDependency, ICapSubscribe TrackLocationValue.LeaveCountry => x => x.LeaveCountry, _ => x => x.LeaveCountry }; - return _orderRepository.GetFirstAsync(x => x.Id == orderId, resultExpression); + return _orderRepository.GetFirstAsync(x => x.Id == orderId, resultExpression); } /// @@ -300,13 +316,12 @@ public class TrackRefreshEventHandler : ITransientDependency, ICapSubscribe /// /// /// - private async Task GetTimezone(TrackPullContentConfigDto matchedContentConfig,int orderId ) + private async Task GetTimezone(TrackPullContentConfigDto matchedContentConfig, int orderId) { - var placeOrCode = await GetPlaceByOrder(matchedContentConfig!.TrackZonePlaceValue.Value,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) { diff --git a/src/SJZY.Track.Application/CAP/EventHandlers/TrackUpsertEventHandler.cs b/src/SJZY.Track.Application/CAP/EventHandlers/TrackUpsertEventHandler.cs index 703900c5..a3a791ff 100644 --- a/src/SJZY.Track.Application/CAP/EventHandlers/TrackUpsertEventHandler.cs +++ b/src/SJZY.Track.Application/CAP/EventHandlers/TrackUpsertEventHandler.cs @@ -2,11 +2,9 @@ using SJZY.Expand.ABP.Core.Logger; using SJZY.Expand.ABP.Core.PublicMethords; using SJZY.Track.Application.Contract.Events; -using SJZY.Track.Application.Contract.Services; using SJZY.Track.Domain.Aggregates.OrderAggregate; using SJZY.Track.Domain.Aggregates.TrackDetailsAggregate; using SJZY.Track.Domain.Consts; -using SJZY.Track.Domain.Dtos.Order; using SJZY.Track.Domain.Queries; using Volo.Abp.DependencyInjection; using OrderIdentifier = SJZY.Track.Application.Contract.Events.OrderIdentifier; @@ -61,7 +59,7 @@ public class TrackUpsertEventHandler : ITransientDependency, ICapSubscribe { ServiceProviderName = @event.TrackRefreshData.ServiceProviderName, OriginTrackContent = @event.TrackRefreshData.OriginTrackContent, - OriginTrackData = @event.TrackRefreshData.OriginTrackData, + OriginTrackDataHash = @event.TrackRefreshData.OriginTrackDataHash, // tips:一定要重置为false,父级订单的完成不会使得关联订单完成,关联单也必须由刷新来完成或手动设置完成!! IsCompleted = false }; @@ -103,7 +101,7 @@ public class TrackUpsertEventHandler : ITransientDependency, ICapSubscribe } } } - + private async Task HandleTrackAsync(TrackUpsertEvent @event, List canNextOrderIds) { 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 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 insertTracks = new List(); - + 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; // 存在不让创建 @@ -138,8 +142,7 @@ public class TrackUpsertEventHandler : ITransientDependency, ICapSubscribe TrackTimeZone = @event.TrackTimeZone, ServiceProviderName = @event.TrackRefreshData.ServiceProviderName ?? GlobalConst.EmptyString, OriginTrackContent = @event.TrackRefreshData.OriginTrackContent ?? GlobalConst.EmptyString, - OriginTrackData = @event.TrackRefreshData.OriginTrackData ?? GlobalConst.EmptyString, - IsCanDelete = false, + OriginTrackDataHash = @event.TrackRefreshData.OriginTrackDataHash ?? GlobalConst.EmptyString, CreateUser = @event.OperationMan ?? GlobalConst.SystemUser, CreateTime = DateTime.Now }; @@ -157,8 +160,9 @@ public class TrackUpsertEventHandler : ITransientDependency, ICapSubscribe track.TrackContent = trackContent.Content; track.TrackEnContent = trackContent.EnContent; 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); } else @@ -166,6 +170,9 @@ public class TrackUpsertEventHandler : ITransientDependency, ICapSubscribe track.TrackPlace = @event.TrackPlace; track.TrackTime = @event.TrackTime; track.TrackTimeZone = @event.TrackTimeZone; + track.ZeroTrackTime = Math.Abs(track.TrackTimeZone - GlobalConst.NoneTrackTimeZone) < 1 + ? track.TrackTime + : track.TrackTime.Subtract(TimeSpan.FromHours(track.TrackTimeZone)); track.UpdateUser = @event.OperationMan ?? GlobalConst.SystemUser; track.UpdateTime = DateTime.Now; @@ -179,7 +186,7 @@ public class TrackUpsertEventHandler : ITransientDependency, ICapSubscribe // 批量add to es await _trackDetailsRepository.AddManyAsync(insertTracks); - + // 触发订单主表更新事件(异步) await _capPublisher.PublishAsync(GlobalConst.TrackChangeAfterUpdateOrderSubscribe, new TrackChangeAfterUpdateOrderEvent diff --git a/src/SJZY.Track.Application/Helpers/StringHelper.cs b/src/SJZY.Track.Application/Helpers/StringHelper.cs index 682bb788..a0b3b8d4 100644 --- a/src/SJZY.Track.Application/Helpers/StringHelper.cs +++ b/src/SJZY.Track.Application/Helpers/StringHelper.cs @@ -1,24 +1,48 @@ +using System.Security.Cryptography; +using System.Text; using System.Text.RegularExpressions; -namespace SJZY.Track.Application.Helpers -{ - public class StringHelper - { - /// - /// 只能输入英文字符和键盘上常用的符号 - /// - /// - /// - public static bool IsValidEnglishString(string input) - { - if (string.IsNullOrEmpty(input)) - { - return false; - } +namespace SJZY.Track.Application.Helpers; - // Regular expression to match only English letters and specified symbols - var regex = new Regex(@"^[a-zA-Z\(\)@!#$%^&*_\-+=;:""'/><,.\s]+$"); - return regex.IsMatch(input); +public class StringHelper +{ + /// + /// 只能输入英文字符和键盘上常用的符号 + /// + /// + /// + 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); + } + + + /// 获取字符串的hash值 + /// + /// + 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(); } } \ No newline at end of file diff --git a/src/SJZY.Track.Application/Services/ProvideServices/TrackPullService.cs b/src/SJZY.Track.Application/Services/ProvideServices/TrackPullService.cs index 393d31e5..b781d848 100644 --- a/src/SJZY.Track.Application/Services/ProvideServices/TrackPullService.cs +++ b/src/SJZY.Track.Application/Services/ProvideServices/TrackPullService.cs @@ -68,9 +68,14 @@ public class TrackPullService : ApplicationService var attach = Base64Helper.SerializeObject(group.Key); // 批量获取轨迹 - var _ = await _httpClientProxy.Service.BatchForwardThenPushToQueueAsync( + var res = await _httpClientProxy.Service.BatchForwardThenPushToQueueAsync( InterfaceRelayConst.GetTrackInterfaceCode, serviceProviderCode, data, GlobalConst.TrackRefreshSubscribe, attach); + + if (res.Code != InterfaceRelayConst.SuccessCode) + { + LogHelper.Error($"刷新轨迹失败:{res.ToJson()}"); + } } return true; diff --git a/src/SJZY.Track.Application/Services/ProvideServices/TrackService.Query.cs b/src/SJZY.Track.Application/Services/ProvideServices/TrackService.Query.cs index 259ee8d9..a055513f 100644 --- a/src/SJZY.Track.Application/Services/ProvideServices/TrackService.Query.cs +++ b/src/SJZY.Track.Application/Services/ProvideServices/TrackService.Query.cs @@ -42,8 +42,8 @@ public partial class TrackService Content = x.TrackContent, OriginContent = x.OriginTrackContent, Location = x.TrackPlace, - Time = Math.Abs(x.TrackTimeZone - GlobalConst.NoneTrackTimeZone) < 1 ?x.TrackTime: x.ZeroTrackTime.AddHours(input.TimeZone ?? 8), - TimeZone = input.TimeZone ?? 8 + Time = Math.Abs(x.TrackTimeZone - GlobalConst.NoneTrackTimeZone) < 1 ? x.TrackTime: x.ZeroTrackTime.AddHours(input.TimeZone ?? 8), + TimeZone = Math.Abs(x.TrackTimeZone - GlobalConst.NoneTrackTimeZone) < 1? null: input.TimeZone ?? 8 }).ToList(); res.Add(item); diff --git a/src/SJZY.Track.Application/Services/TrackOrders/TrackOrderService.cs b/src/SJZY.Track.Application/Services/TrackOrders/TrackOrderService.cs index 477456cb..fb0d998e 100644 --- a/src/SJZY.Track.Application/Services/TrackOrders/TrackOrderService.cs +++ b/src/SJZY.Track.Application/Services/TrackOrders/TrackOrderService.cs @@ -5,6 +5,7 @@ using SJZY.Track.Domain.Aggregates.OrderAggregate; using SJZY.Track.Domain.Aggregates.TrackContentAggregate; using SJZY.Track.Domain.Aggregates.TrackDetailsAggregate; using SJZY.Track.Domain.Aggregates.TrackPushAggregate; +using SJZY.Track.Domain.Consts; using SJZY.Track.Domain.Dtos.Order; using SJZY.Track.Domain.Dtos.TrackTemplate; using SJZY.Track.Domain.Enums; @@ -87,6 +88,10 @@ public class TrackOrderService : ApplicationService { a.TrackTimeZone = "GTM +00:00"; } + else if (Math.Abs(a.TrackTimeZoneValue - GlobalConst.NoneTrackTimeZone) < 1) + { + a.TrackTimeZone = "--"; + } else { // 将小数形式的小时转换为时区偏移量 diff --git a/src/SJZY.Track.Domain/Aggregates/TrackDetailsAggregate/ITrackDetailsRepository.cs b/src/SJZY.Track.Domain/Aggregates/TrackDetailsAggregate/ITrackDetailsRepository.cs index 4e4a0b9c..639f92ef 100644 --- a/src/SJZY.Track.Domain/Aggregates/TrackDetailsAggregate/ITrackDetailsRepository.cs +++ b/src/SJZY.Track.Domain/Aggregates/TrackDetailsAggregate/ITrackDetailsRepository.cs @@ -10,7 +10,7 @@ public interface ITrackDetailsRepository Task AnyAsync(int orderId, DateTime trackTime); - Task AnyAsync(int orderId, string originTrackData); + Task AnyAsync(int orderId, string originTrackDataHash); Task AnyByCodeAsync(int orderId, string trackCode); diff --git a/src/SJZY.Track.Domain/Aggregates/TrackDetailsAggregate/TrackDetailsIndex.cs b/src/SJZY.Track.Domain/Aggregates/TrackDetailsAggregate/TrackDetailsIndex.cs index 7cb77e84..9af7f023 100644 --- a/src/SJZY.Track.Domain/Aggregates/TrackDetailsAggregate/TrackDetailsIndex.cs +++ b/src/SJZY.Track.Domain/Aggregates/TrackDetailsAggregate/TrackDetailsIndex.cs @@ -30,37 +30,37 @@ public class TrackDetailsIndex : IdBaseIndex /// /// 轨迹状态 /// - public string TrackStatus { get; set; } = null!; + public string TrackStatus { get; set; } = GlobalConst.EmptyString; /// /// 轨迹内容代码 /// - public string TrackCode { get; set; } = null!; + public string TrackCode { get; set; } = GlobalConst.EmptyString; /// /// 轨迹内容 /// - public string TrackContent { get; set; } = null!; - - /// - /// 服务商 - /// - public string? ServiceProviderName { get; set; } - - /// - /// 原轨迹内容 - /// - public string? OriginTrackContent { get; set; } - - /// - /// 原轨迹报文 - /// - public string? OriginTrackData { get; set; } + public string TrackContent { get; set; } = GlobalConst.EmptyString; /// /// 轨迹内容英文 /// - public string TrackEnContent { get; set; } = null!; + public string TrackEnContent { get; set; } = GlobalConst.EmptyString; + + /// + /// 服务商 + /// + public string ServiceProviderName { get; set; } = null!; + + /// + /// 原轨迹内容 + /// + public string OriginTrackContent { get; set; } = null!; + + /// + /// 原轨迹报文hash(刷新轨迹重复性校验使用) + /// + public string OriginTrackDataHash { get; set; } = null!; /// /// 轨迹发生地 diff --git a/src/SJZY.Track.Domain/VEntities/VAirportEntity.cs b/src/SJZY.Track.Domain/VEntities/VAirportEntity.cs index ba69e854..9ce810fd 100644 --- a/src/SJZY.Track.Domain/VEntities/VAirportEntity.cs +++ b/src/SJZY.Track.Domain/VEntities/VAirportEntity.cs @@ -5,7 +5,7 @@ namespace SJZY.Track.Domain.VEntities; /// /// 空港 /// -[SugarTable("t_airport", "空港")] +[SugarTable("v_airport", "空港")] public class VAirportEntity : IFullAuditedBasicEntitys { [SugarColumn(ColumnName = "Id", IsPrimaryKey = true, IsIdentity = true)] diff --git a/src/SJZY.Track.Domain/VEntities/VCityEntity.cs b/src/SJZY.Track.Domain/VEntities/VCityEntity.cs index ad914504..703b5539 100644 --- a/src/SJZY.Track.Domain/VEntities/VCityEntity.cs +++ b/src/SJZY.Track.Domain/VEntities/VCityEntity.cs @@ -3,7 +3,7 @@ using System; namespace SJZY.Track.Domain.VEntities; -[SugarTable("t_city")] +[SugarTable("v_city")] public class VCityEntity : IFullAuditedBasicEntitys { /// diff --git a/src/SJZY.Track.Repository/Repositories/TrackDetailsRepository.cs b/src/SJZY.Track.Repository/Repositories/TrackDetailsRepository.cs index 33c278d9..cb82921e 100644 --- a/src/SJZY.Track.Repository/Repositories/TrackDetailsRepository.cs +++ b/src/SJZY.Track.Repository/Repositories/TrackDetailsRepository.cs @@ -34,6 +34,8 @@ internal class TrackDetailsRepository : ElasticSearchContextAbstract s2.Includes(fd => fd .Field(f => f.IndexName) .Field(f => f.OrderId) + .Field(f => f.TrackTime) + .Field(f => f.TrackPlace) )) .Size(1000) .Query(q => q @@ -123,13 +125,13 @@ internal class TrackDetailsRepository : ElasticSearchContextAbstract 0; } - public async Task AnyAsync(int orderId, string originTrackData) + public async Task AnyAsync(int orderId, string originTrackDataHash) { var r = await Context.SearchAsync(x => x .Source(s => s.Includes(fd => fd.Field(f => f.TrackCode))) .Query(q => q.Term(f => f.OrderId, orderId) - && q.Term(f => f.OriginTrackData.Suffix("keyword"), originTrackData) + && q.Term(f => f.OriginTrackDataHash.Suffix("keyword"), originTrackDataHash) ) );