From f1a48cc9a60c269add9c2f459c5988559fc4d12f Mon Sep 17 00:00:00 2001 From: moyongzhen <2534173414@qq.com> Date: Wed, 10 Apr 2024 15:04:30 +0800 Subject: [PATCH 01/72] =?UTF-8?q?=E6=9F=A5=E8=AF=A2=E8=BD=A8=E8=BF=B9=20?= =?UTF-8?q?=E8=BF=94=E5=9B=9E=E5=8F=82=E6=95=B0=E8=B0=83=E6=95=B4=E6=88=90?= =?UTF-8?q?UnifyResultDto?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/SJZY.Track.Application.Contract/Services/ITrackService.cs | 2 +- .../Services/ProvideServices/TrackService.Query.cs | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/SJZY.Track.Application.Contract/Services/ITrackService.cs b/src/SJZY.Track.Application.Contract/Services/ITrackService.cs index 31dae617..904f834d 100644 --- a/src/SJZY.Track.Application.Contract/Services/ITrackService.cs +++ b/src/SJZY.Track.Application.Contract/Services/ITrackService.cs @@ -31,5 +31,5 @@ public interface ITrackService : IRemoteService /// /// /// - Task> QueryAsync(GetTrackInput input); + Task QueryAsync(GetTrackInput input); } \ No newline at end of file diff --git a/src/SJZY.Track.Application/Services/ProvideServices/TrackService.Query.cs b/src/SJZY.Track.Application/Services/ProvideServices/TrackService.Query.cs index 3864b604..74f4e52f 100644 --- a/src/SJZY.Track.Application/Services/ProvideServices/TrackService.Query.cs +++ b/src/SJZY.Track.Application/Services/ProvideServices/TrackService.Query.cs @@ -17,7 +17,7 @@ public partial class TrackService /// /// [HttpPost("Track/Query")] - public async Task> QueryAsync(GetTrackInput input) + public async Task QueryAsync(GetTrackInput input) { if (input.OrderNos.Count > 500) { @@ -50,7 +50,7 @@ public partial class TrackService await TrackDetailSort(res, input); - return res; + return new UnifyResultDto(true, res, "操作成功"); } private async Task TrackDetailSort(List list, GetTrackInput input) From 636f189e50de0c4207efc88309c473182dda1598 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=B9=8F=E5=86=9B?= <2357729423@qq.com> Date: Wed, 10 Apr 2024 15:22:17 +0800 Subject: [PATCH 02/72] =?UTF-8?q?version=EF=BC=9A7.0.1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../SJZY.Track.Application.Contract.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/SJZY.Track.Application.Contract/SJZY.Track.Application.Contract.csproj b/src/SJZY.Track.Application.Contract/SJZY.Track.Application.Contract.csproj index 1b129506..7f1f52a3 100644 --- a/src/SJZY.Track.Application.Contract/SJZY.Track.Application.Contract.csproj +++ b/src/SJZY.Track.Application.Contract/SJZY.Track.Application.Contract.csproj @@ -5,7 +5,7 @@ net7.0 True - 7.0.0 + 7.0.1 True From 8e9f5931e4916d3751a8ed0703090a6b362deabc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=B9=8F=E5=86=9B?= <2357729423@qq.com> Date: Wed, 10 Apr 2024 15:27:52 +0800 Subject: [PATCH 03/72] =?UTF-8?q?opt=EF=BC=9A=E8=BD=A8=E8=BF=B9=E6=8E=A8?= =?UTF-8?q?=E9=80=81=E5=90=8E=E6=9B=B4=E6=96=B0=E8=AE=A2=E5=8D=95=E5=90=88?= =?UTF-8?q?=E5=B9=B6=E5=88=B0=E6=8E=A8=E9=80=81=E5=A4=84=E7=90=86=E9=80=BB?= =?UTF-8?q?=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../TrackPushAfterUpdateOrderEventHandler.cs | 50 ------------------- 1 file changed, 50 deletions(-) delete mode 100644 src/SJZY.Track.Application/EventHandlers/TrackPushAfterUpdateOrderEventHandler.cs diff --git a/src/SJZY.Track.Application/EventHandlers/TrackPushAfterUpdateOrderEventHandler.cs b/src/SJZY.Track.Application/EventHandlers/TrackPushAfterUpdateOrderEventHandler.cs deleted file mode 100644 index a6c65fdd..00000000 --- a/src/SJZY.Track.Application/EventHandlers/TrackPushAfterUpdateOrderEventHandler.cs +++ /dev/null @@ -1,50 +0,0 @@ -using DotNetCore.CAP; -using SJZY.Track.Application.Contract.Dtos.TrackPush; -using SJZY.Track.Domain.Aggregates.OrderAggregate; -using SJZY.Track.Domain.Consts; -using SJZY.Track.Domain.Enums; -using Volo.Abp.DependencyInjection; - -namespace SJZY.Track.Application.EventHandlers; - -public class TrackPushAfterUpdateOrderEventHandler : ITransientDependency, ICapSubscribe -{ - private readonly IOrderRepository _orderRepository; - - public TrackPushAfterUpdateOrderEventHandler(IOrderRepository orderRepository) - { - _orderRepository = orderRepository; - } - - [CapSubscribe(GlobalConst.TrackPushAfterUpdateOrderSubscribe)] - public async Task ConsumerAsync(TrackPushAfterUpdateOrderDto dto) - { - var order = await _orderRepository.GetFirstAsync(x => x.Id == dto.OrderId); - if (order == default) return; - - /* - * 异常:最近一条推送是失败 - */ - if (!dto.IsSuccess) - { - order.QuestionType = (int)TrackProblemType.Error; - order.LatestPushError = dto.Message; - } - else - { - order.QuestionType = (int)TrackProblemType.None; - order.LatestPushError = null; - if (dto.OptionType == OptionType.新增) - { - // tips:只有新增会影响推送进度 - order.LatestPushTrackCode = dto.TrackCode; - order.LatestPushTime = DateTime.Now; - } - } - - await _orderRepository.UpdateColumnAsync(order, x => new - { - x.LatestPushTrackCode, x.QuestionType, x.LatestPushError, x.LatestPushTime - }); - } -} \ No newline at end of file From 6ef5ba86cf9f0e6cdc34807bb1910d8dd9a679b5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=B9=8F=E5=86=9B?= <2357729423@qq.com> Date: Wed, 10 Apr 2024 19:18:18 +0800 Subject: [PATCH 04/72] =?UTF-8?q?opt=EF=BC=9A=E5=BC=80=E5=90=AFcap?= =?UTF-8?q?=E5=A4=9A=E7=BA=BF=E7=A8=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/SJZY.Track.Application/SjzyTrackApplicationModule.cs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/SJZY.Track.Application/SjzyTrackApplicationModule.cs b/src/SJZY.Track.Application/SjzyTrackApplicationModule.cs index f9f5633a..26725fbd 100644 --- a/src/SJZY.Track.Application/SjzyTrackApplicationModule.cs +++ b/src/SJZY.Track.Application/SjzyTrackApplicationModule.cs @@ -84,7 +84,13 @@ namespace SJZY.Track.Application configure.UserName = configuration["RabbitMQ:UserName"]!; configure.Password = configuration["RabbitMQ:Password"]!; configure.Port = configuration.GetValue("RabbitMQ:Port"); + configure.BasicQosOptions = + new RabbitMQOptions.BasicQos(configuration.GetValue("CAP:PrefetchCount")); }); + options.FailedRetryInterval = configuration.GetValue("CAP:FailedRetryInterval"); + options.FailedRetryCount = configuration.GetValue("CAP:FailedRetryCount"); + options.UseDispatchingPerGroup = configuration.GetValue("CAP:UseDispatchingPerGroup"); + options.ConsumerThreadCount = configuration.GetValue("CAP:ConsumerThreadCount"); // options.TopicNamePrefix = "v1"; options.SucceedMessageExpiredAfter = 6 * 60 * 60; From 80e1db40b2a0a1d17c027bed214eb0c50577d383 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=B9=8F=E5=86=9B?= <2357729423@qq.com> Date: Wed, 10 Apr 2024 19:21:37 +0800 Subject: [PATCH 05/72] attach --- src/SJZY.Track.Application/SjzyTrackApplicationModule.cs | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/SJZY.Track.Application/SjzyTrackApplicationModule.cs b/src/SJZY.Track.Application/SjzyTrackApplicationModule.cs index 26725fbd..c7be9ea2 100644 --- a/src/SJZY.Track.Application/SjzyTrackApplicationModule.cs +++ b/src/SJZY.Track.Application/SjzyTrackApplicationModule.cs @@ -87,15 +87,13 @@ namespace SJZY.Track.Application configure.BasicQosOptions = new RabbitMQOptions.BasicQos(configuration.GetValue("CAP:PrefetchCount")); }); + // options.TopicNamePrefix = "v1"; options.FailedRetryInterval = configuration.GetValue("CAP:FailedRetryInterval"); options.FailedRetryCount = configuration.GetValue("CAP:FailedRetryCount"); options.UseDispatchingPerGroup = configuration.GetValue("CAP:UseDispatchingPerGroup"); options.ConsumerThreadCount = configuration.GetValue("CAP:ConsumerThreadCount"); + options.SucceedMessageExpiredAfter = configuration.GetValue("CAP:SucceedMessageExpiredAfter"); - // options.TopicNamePrefix = "v1"; - options.SucceedMessageExpiredAfter = 6 * 60 * 60; - options.FailedRetryInterval = 60; - options.FailedRetryCount = 3; options.UseDashboard(dashboardOptions => { dashboardOptions.PathBase = System.Diagnostics.Debugger.IsAttached From 8c81406e6e2a669156b8170f10f44c3007d74884 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=B9=8F=E5=86=9B?= <2357729423@qq.com> Date: Wed, 10 Apr 2024 19:51:07 +0800 Subject: [PATCH 06/72] =?UTF-8?q?=E6=B5=8B=E8=AF=95cap=E5=8F=82=E6=95=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/SJZY.Track.Application/SjzyTrackApplicationModule.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/SJZY.Track.Application/SjzyTrackApplicationModule.cs b/src/SJZY.Track.Application/SjzyTrackApplicationModule.cs index c7be9ea2..d479f7f8 100644 --- a/src/SJZY.Track.Application/SjzyTrackApplicationModule.cs +++ b/src/SJZY.Track.Application/SjzyTrackApplicationModule.cs @@ -93,6 +93,8 @@ namespace SJZY.Track.Application options.UseDispatchingPerGroup = configuration.GetValue("CAP:UseDispatchingPerGroup"); options.ConsumerThreadCount = configuration.GetValue("CAP:ConsumerThreadCount"); options.SucceedMessageExpiredAfter = configuration.GetValue("CAP:SucceedMessageExpiredAfter"); + options.UseDispatchingPerGroup = true; + options.EnableConsumerPrefetch = true; options.UseDashboard(dashboardOptions => { From 93417db5229975eb5c84a1e6b3978be884dc83ac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=B9=8F=E5=86=9B?= <2357729423@qq.com> Date: Wed, 10 Apr 2024 19:51:46 +0800 Subject: [PATCH 07/72] 1 --- src/SJZY.Track.Application/SjzyTrackApplicationModule.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/SJZY.Track.Application/SjzyTrackApplicationModule.cs b/src/SJZY.Track.Application/SjzyTrackApplicationModule.cs index d479f7f8..4e8f5fff 100644 --- a/src/SJZY.Track.Application/SjzyTrackApplicationModule.cs +++ b/src/SJZY.Track.Application/SjzyTrackApplicationModule.cs @@ -90,7 +90,6 @@ namespace SJZY.Track.Application // options.TopicNamePrefix = "v1"; options.FailedRetryInterval = configuration.GetValue("CAP:FailedRetryInterval"); options.FailedRetryCount = configuration.GetValue("CAP:FailedRetryCount"); - options.UseDispatchingPerGroup = configuration.GetValue("CAP:UseDispatchingPerGroup"); options.ConsumerThreadCount = configuration.GetValue("CAP:ConsumerThreadCount"); options.SucceedMessageExpiredAfter = configuration.GetValue("CAP:SucceedMessageExpiredAfter"); options.UseDispatchingPerGroup = true; From 3aecf92eb7ddf56b1684fedfa271933dbbd8ef15 Mon Sep 17 00:00:00 2001 From: moyongzhen <2534173414@qq.com> Date: Thu, 11 Apr 2024 15:14:01 +0800 Subject: [PATCH 08/72] =?UTF-8?q?=E8=BD=A8=E8=BF=B9=E6=8E=A8=E9=80=81?= =?UTF-8?q?=E9=85=8D=E7=BD=AE=E5=85=B3=E7=B3=BB=E5=AF=B9=E5=A4=96=E6=8E=A5?= =?UTF-8?q?=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../QueryTrackPullMappingsInput.cs | 60 +++++++++++++++++++ .../TrackPushConfigAutoMapperProfile.cs | 22 +++++++ .../ProvideServices/TrackPushConfigService.cs | 44 ++++++++++++++ .../ITrackPushConfigRepository.cs | 1 + .../TrackPush/QueryTrackPullMappingsInfoVO.cs | 60 +++++++++++++++++++ .../Repositories/TrackPushConfigRepository.cs | 25 ++++++++ 6 files changed, 212 insertions(+) create mode 100644 src/SJZY.Track.Application.Contract/Dtos/ProvideServices/QueryTrackPullMappingsInput.cs create mode 100644 src/SJZY.Track.Application/AutoMapper/TrackPushConfigAutoMapperProfile.cs create mode 100644 src/SJZY.Track.Application/Services/ProvideServices/TrackPushConfigService.cs create mode 100644 src/SJZY.Track.Domain/Dtos/TrackPush/QueryTrackPullMappingsInfoVO.cs diff --git a/src/SJZY.Track.Application.Contract/Dtos/ProvideServices/QueryTrackPullMappingsInput.cs b/src/SJZY.Track.Application.Contract/Dtos/ProvideServices/QueryTrackPullMappingsInput.cs new file mode 100644 index 00000000..ed0e9da4 --- /dev/null +++ b/src/SJZY.Track.Application.Contract/Dtos/ProvideServices/QueryTrackPullMappingsInput.cs @@ -0,0 +1,60 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace SJZY.Track.Application.Contract.Dtos.ProvideServices +{ + /// + /// 查询轨迹推送映射关系入参 + /// + public class QueryTrackPullMappingsInput + { + /// + /// 子系统id + /// + public int SubsystemsId { get; set; } + + /// + /// 客户id + /// + public int CustomerId { get; set; } + } + + /// + /// 查询轨迹推送映射关系返参项 + /// + public class QueryTrackPullMappingsInfo + { + /// + /// 轨迹代码 + /// + public string? Code { get; set; } + + /// + /// 订单类型 + /// + public int OrderType { get; set; } + + /// + /// 服务商轨迹代码 + /// + public string? ServiceCode { get; set; } + + /// + /// 服务商轨迹状态 + /// + public string? Status { get; set; } + + /// + /// 服务商轨迹内容 + /// + public string? Content { get; set; } + + /// + /// 服务商轨迹内容英文 + /// + public string? ContentEn { get; set; } + } +} diff --git a/src/SJZY.Track.Application/AutoMapper/TrackPushConfigAutoMapperProfile.cs b/src/SJZY.Track.Application/AutoMapper/TrackPushConfigAutoMapperProfile.cs new file mode 100644 index 00000000..7cb8ccd2 --- /dev/null +++ b/src/SJZY.Track.Application/AutoMapper/TrackPushConfigAutoMapperProfile.cs @@ -0,0 +1,22 @@ +using AutoMapper; +using SJZY.Track.Application.Contract.Dtos.ProvideServices; +using SJZY.Track.Application.Contract.Dtos.TrackPush; +using SJZY.Track.Domain.Aggregates.TrackPushAggregate; +using SJZY.Track.Domain.Dtos.TrackPush; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace SJZY.Track.Application.AutoMapper +{ + public class TrackPushConfigAutoMapperProfile : Profile + { + public TrackPushConfigAutoMapperProfile() + { + CreateMap(MemberList.None); + CreateMap(MemberList.None); + } + } +} diff --git a/src/SJZY.Track.Application/Services/ProvideServices/TrackPushConfigService.cs b/src/SJZY.Track.Application/Services/ProvideServices/TrackPushConfigService.cs new file mode 100644 index 00000000..4a575526 --- /dev/null +++ b/src/SJZY.Track.Application/Services/ProvideServices/TrackPushConfigService.cs @@ -0,0 +1,44 @@ +using SJZY.Track.Application.Contract.Dtos.ProvideServices; +using SJZY.Track.Domain.Aggregates.TrackPushAggregate; +using SJZY.Track.Domain.Dtos.TrackPush; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Volo.Abp.ObjectMapping; + +namespace SJZY.Track.Application.Services.ProvideServices +{ + /// + /// 轨迹推送配置服务 + /// + [ApiExplorerSettings(GroupName = "提供接口")] + [Route("/ProviderService")] + public class TrackPushConfigService : ApplicationService + { + private readonly ITrackPushConfigRepository _trackPushConfigRepository; + + public TrackPushConfigService( + ITrackPushConfigRepository trackPushConfigRepository + ) + { + _trackPushConfigRepository = trackPushConfigRepository; + } + + /// + /// 查询轨迹推送配置关系 + /// + /// + /// + [HttpPost("Track/QueryTrackPullMappings")] + public async Task QueryTrackPullMappingsAsync(QueryTrackPullMappingsInput input) + { + var vo = ObjectMapper.Map(input); + var result = await _trackPushConfigRepository.QueryTrackPullMappingsAsync(vo); + var output = ObjectMapper.Map, List>(result); + + return new UnifyResultDto(true, output, "操作成功"); + } + } +} diff --git a/src/SJZY.Track.Domain/Aggregates/TrackPushAggregate/ITrackPushConfigRepository.cs b/src/SJZY.Track.Domain/Aggregates/TrackPushAggregate/ITrackPushConfigRepository.cs index 641fb386..3983cd7c 100644 --- a/src/SJZY.Track.Domain/Aggregates/TrackPushAggregate/ITrackPushConfigRepository.cs +++ b/src/SJZY.Track.Domain/Aggregates/TrackPushAggregate/ITrackPushConfigRepository.cs @@ -35,4 +35,5 @@ public interface ITrackPushConfigRepository : IBasicRepository UpdateContentAsync(Expression> columns, Expression> whereExpression); + Task> QueryTrackPullMappingsAsync(QueryTrackPullMappingsInputVO input); } \ No newline at end of file diff --git a/src/SJZY.Track.Domain/Dtos/TrackPush/QueryTrackPullMappingsInfoVO.cs b/src/SJZY.Track.Domain/Dtos/TrackPush/QueryTrackPullMappingsInfoVO.cs new file mode 100644 index 00000000..26f7b4a8 --- /dev/null +++ b/src/SJZY.Track.Domain/Dtos/TrackPush/QueryTrackPullMappingsInfoVO.cs @@ -0,0 +1,60 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace SJZY.Track.Domain.Dtos.TrackPush +{ + /// + /// 查询轨迹推送关系入参 + /// + public class QueryTrackPullMappingsInfoVO + { + /// + /// 轨迹代码 + /// + public string? Code { get; set; } + + /// + /// 订单类型 + /// + public int OrderType { get; set; } + + /// + /// 服务商轨迹代码 + /// + public string? ServiceCode { get; set; } + + /// + /// 服务商轨迹状态 + /// + public string? Status { get; set; } + + /// + /// 服务商轨迹内容 + /// + public string? Content { get; set; } + + /// + /// 服务商轨迹内容英文 + /// + public string? ContentEn { get; set; } + } + + /// + /// 查询轨迹推送关系返参项 + /// + public class QueryTrackPullMappingsInputVO + { + /// + /// 子系统id + /// + public int SubsystemsId { get; set; } + + /// + /// 客户id + /// + public int CustomerId { get; set; } + } +} diff --git a/src/SJZY.Track.Repository/Repositories/TrackPushConfigRepository.cs b/src/SJZY.Track.Repository/Repositories/TrackPushConfigRepository.cs index 43bbae70..c7e21820 100644 --- a/src/SJZY.Track.Repository/Repositories/TrackPushConfigRepository.cs +++ b/src/SJZY.Track.Repository/Repositories/TrackPushConfigRepository.cs @@ -166,4 +166,29 @@ public class TrackPushConfigRepository : BasicRepository, return await Context.Updateable().SetColumns(columns).Where(whereExpression) .ExecuteCommandHasChangeAsync(); } + + /// + /// 查询轨迹推送关系 + /// + /// + /// + public async Task> QueryTrackPullMappingsAsync(QueryTrackPullMappingsInputVO input) + { + var result = await Context.Queryable().LeftJoin((a, b) => a.Id == b.TrackPushConfigId && !b.IsDeleted) + .LeftJoin((a, b, c) => b.TrackContentId == c.Id && !c.IsDeleted) + .Where((a, b, c) => !a.IsDeleted) + .Where((a, b, c) => a.SubSystemId == input.SubsystemsId && a.CustomId == input.CustomerId) + .Select((a, b, c) => new QueryTrackPullMappingsInfoVO + { + Code = c.Code, + OrderType = b.OrderNoType, + ServiceCode = b.TrackContentCodeValue, + Status = b.TrackStatusValue, + Content = b.TrackContentValue, + ContentEn = b.TrackEnContentValue + }) + .ToListAsync(); + + return result; + } } \ No newline at end of file From c2c1e24dcf5089fbeb0a6829efc5efbe540f8997 Mon Sep 17 00:00:00 2001 From: moyongzhen <2534173414@qq.com> Date: Thu, 11 Apr 2024 15:21:38 +0800 Subject: [PATCH 09/72] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E5=AF=B9=E5=A4=96?= =?UTF-8?q?=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Services/ITrackPushConfigService.cs | 20 +++++++++++++++++++ .../ProvideServices/TrackPushConfigService.cs | 3 ++- 2 files changed, 22 insertions(+), 1 deletion(-) create mode 100644 src/SJZY.Track.Application.Contract/Services/ITrackPushConfigService.cs diff --git a/src/SJZY.Track.Application.Contract/Services/ITrackPushConfigService.cs b/src/SJZY.Track.Application.Contract/Services/ITrackPushConfigService.cs new file mode 100644 index 00000000..e191f6bb --- /dev/null +++ b/src/SJZY.Track.Application.Contract/Services/ITrackPushConfigService.cs @@ -0,0 +1,20 @@ +using SJZY.Track.Application.Contract.Dtos.ProvideServices; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Volo.Abp; + +namespace SJZY.Track.Application.Contract.Services +{ + public interface ITrackPushConfigService : IRemoteService + { + /// + /// 查询轨迹推送配置关系 + /// + /// + /// + Task QueryTrackPullMappingsAsync(QueryTrackPullMappingsInput input); + } +} diff --git a/src/SJZY.Track.Application/Services/ProvideServices/TrackPushConfigService.cs b/src/SJZY.Track.Application/Services/ProvideServices/TrackPushConfigService.cs index 4a575526..04a8ea53 100644 --- a/src/SJZY.Track.Application/Services/ProvideServices/TrackPushConfigService.cs +++ b/src/SJZY.Track.Application/Services/ProvideServices/TrackPushConfigService.cs @@ -1,4 +1,5 @@ using SJZY.Track.Application.Contract.Dtos.ProvideServices; +using SJZY.Track.Application.Contract.Services; using SJZY.Track.Domain.Aggregates.TrackPushAggregate; using SJZY.Track.Domain.Dtos.TrackPush; using System; @@ -15,7 +16,7 @@ namespace SJZY.Track.Application.Services.ProvideServices /// [ApiExplorerSettings(GroupName = "提供接口")] [Route("/ProviderService")] - public class TrackPushConfigService : ApplicationService + public class TrackPushConfigService : ApplicationService, ITrackPushConfigService { private readonly ITrackPushConfigRepository _trackPushConfigRepository; From 0408ab8e136d65b1715767e7b8ee144ba3d5bf08 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=B9=8F=E5=86=9B?= <2357729423@qq.com> Date: Thu, 11 Apr 2024 15:31:35 +0800 Subject: [PATCH 10/72] =?UTF-8?q?version=EF=BC=9A7.0.2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../SJZY.Track.Application.Contract.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/SJZY.Track.Application.Contract/SJZY.Track.Application.Contract.csproj b/src/SJZY.Track.Application.Contract/SJZY.Track.Application.Contract.csproj index 7f1f52a3..7a7f7902 100644 --- a/src/SJZY.Track.Application.Contract/SJZY.Track.Application.Contract.csproj +++ b/src/SJZY.Track.Application.Contract/SJZY.Track.Application.Contract.csproj @@ -5,7 +5,7 @@ net7.0 True - 7.0.1 + 7.0.2 True From 2bedb127b6087b8e0077a608c34916a180e8a613 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=B9=8F=E5=86=9B?= <2357729423@qq.com> Date: Fri, 12 Apr 2024 21:34:15 +0800 Subject: [PATCH 11/72] =?UTF-8?q?opt=EF=BC=9A=E9=87=8D=E6=9E=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Events/OrderIdentifier.cs | 8 + .../Events/OrderLinkAfterFillTrackEvent.cs | 28 -- .../TrackChangeAfterUpdateOrderEvent.cs | 2 +- .../Events/TrackDeleteEvent.cs | 19 +- .../Events/TrackRefreshStruct.cs | 25 ++ .../Events/TrackUpsertEvent.cs | 46 +--- .../Events/TrackUpsertForRefreshEvent.cs | 94 +++++++ .../OrderLinkAfterFillTrackHandler.cs | 48 ---- ...TrackChangeAfterUpdateOrderEventHandler.cs | 85 +++--- .../EventHandlers/TrackDeleteEventHandler.cs | 71 ++--- .../TrackInsertForNotMappedEventHandler.cs | 2 +- .../EventHandlers/TrackPushEventHandler.cs | 9 +- .../EventHandlers/TrackRefreshEventHandler.cs | 44 ++- .../EventHandlers/TrackUpsertEventHandler.cs | 257 ++++++++++-------- .../ProvideServices/OrderService.Link.cs | 52 ++-- .../Services/ProvideServices/OrderService.cs | 4 +- .../Services/ProvideServices/TrackService.cs | 30 +- .../OrderAggregate/IOrderRepository.cs | 2 +- .../ITrackDetailsRepository.cs | 22 +- .../Consts/GlobalConst.MQ.cs | 5 + src/SJZY.Track.Repository/EsExtensions.cs | 22 ++ .../Repositories/OrderRepository.cs | 6 +- .../Repositories/TrackDetailsRepository.cs | 121 +++++---- 23 files changed, 568 insertions(+), 434 deletions(-) create mode 100644 src/SJZY.Track.Application.Contract/Events/OrderIdentifier.cs delete mode 100644 src/SJZY.Track.Application.Contract/Events/OrderLinkAfterFillTrackEvent.cs create mode 100644 src/SJZY.Track.Application.Contract/Events/TrackRefreshStruct.cs create mode 100644 src/SJZY.Track.Application.Contract/Events/TrackUpsertForRefreshEvent.cs delete mode 100644 src/SJZY.Track.Application/EventHandlers/OrderLinkAfterFillTrackHandler.cs create mode 100644 src/SJZY.Track.Repository/EsExtensions.cs diff --git a/src/SJZY.Track.Application.Contract/Events/OrderIdentifier.cs b/src/SJZY.Track.Application.Contract/Events/OrderIdentifier.cs new file mode 100644 index 00000000..49e79b04 --- /dev/null +++ b/src/SJZY.Track.Application.Contract/Events/OrderIdentifier.cs @@ -0,0 +1,8 @@ +namespace SJZY.Track.Application.Contract.Events; + +public struct OrderIdentifier +{ + public int OrderId { get; set; } + public string OrderNo { get; set; } + public int OrderType { get; set; } +} \ No newline at end of file diff --git a/src/SJZY.Track.Application.Contract/Events/OrderLinkAfterFillTrackEvent.cs b/src/SJZY.Track.Application.Contract/Events/OrderLinkAfterFillTrackEvent.cs deleted file mode 100644 index f4caa481..00000000 --- a/src/SJZY.Track.Application.Contract/Events/OrderLinkAfterFillTrackEvent.cs +++ /dev/null @@ -1,28 +0,0 @@ -namespace SJZY.Track.Application.Contract.Events; - -public class OrderLinkAfterFillTrackEvent -{ - /// - /// 关联订单id - /// - public int OrderId { get; set; } - - /// - /// 子系统id - /// - public int SubSystemId { get; set; } - - /// - /// 关联订单 - /// - public List LinkedOrders { get; set; } = null!; -} - -public struct LinkedOrder -{ - public int SubSystemId { get; set; } - - public int OrderId { get; set; } - public string OrderNo { get; set; } - public int OrderType { get; set; } -} \ No newline at end of file diff --git a/src/SJZY.Track.Application.Contract/Events/TrackChangeAfterUpdateOrderEvent.cs b/src/SJZY.Track.Application.Contract/Events/TrackChangeAfterUpdateOrderEvent.cs index c779a647..544c98b1 100644 --- a/src/SJZY.Track.Application.Contract/Events/TrackChangeAfterUpdateOrderEvent.cs +++ b/src/SJZY.Track.Application.Contract/Events/TrackChangeAfterUpdateOrderEvent.cs @@ -5,7 +5,7 @@ public class TrackChangeAfterUpdateOrderEvent /// /// 订单Id /// - public int OrderId { get; set; } + public int[] OrderIds { get; set; } /// /// 是否删除引起的更新 diff --git a/src/SJZY.Track.Application.Contract/Events/TrackDeleteEvent.cs b/src/SJZY.Track.Application.Contract/Events/TrackDeleteEvent.cs index d5286726..73b4d0ac 100644 --- a/src/SJZY.Track.Application.Contract/Events/TrackDeleteEvent.cs +++ b/src/SJZY.Track.Application.Contract/Events/TrackDeleteEvent.cs @@ -2,25 +2,20 @@ public class TrackDeleteEvent { - /// - /// 订单id - /// - public int OrderId { get; set; } - - /// - /// 轨迹代码 - /// - public List TrackCodes { get; set; } = null!; - /// /// 子系统id /// public int SubSystemId { get; set; } /// - /// 上游子系统id + /// 订单ids /// - public int UpSubSystemId { get; set; } + public int[] OrderIds { get; set; } = null!; + + /// + /// 轨迹代码 + /// + public List TrackCodes { get; set; } = null!; /// /// 操作人 diff --git a/src/SJZY.Track.Application.Contract/Events/TrackRefreshStruct.cs b/src/SJZY.Track.Application.Contract/Events/TrackRefreshStruct.cs new file mode 100644 index 00000000..62bcf4a2 --- /dev/null +++ b/src/SJZY.Track.Application.Contract/Events/TrackRefreshStruct.cs @@ -0,0 +1,25 @@ +namespace SJZY.Track.Application.Contract.Events; + +public struct TrackRefreshStruct +{ + /// + /// 服务商 + /// + public string? ServiceProviderName { get; set; } + + /// + /// 原轨迹内容 + /// + public string? OriginTrackContent { get; set; } + + /// + /// 原轨迹报文 + /// + public string? OriginTrackData { get; set; } + + /// + /// 表示订单是否完成(只由轨迹刷新配置决定) + /// tips:能够使得IsCompleted为true的点,全局只有一个:轨迹刷新 + /// + public bool IsCompleted { get; set; } +} \ No newline at end of file diff --git a/src/SJZY.Track.Application.Contract/Events/TrackUpsertEvent.cs b/src/SJZY.Track.Application.Contract/Events/TrackUpsertEvent.cs index 53e0d856..3b449bbf 100644 --- a/src/SJZY.Track.Application.Contract/Events/TrackUpsertEvent.cs +++ b/src/SJZY.Track.Application.Contract/Events/TrackUpsertEvent.cs @@ -3,50 +3,14 @@ public class TrackUpsertEvent { /// - /// 订单id - /// - public int OrderId { get; set; } - - /// - /// 订单类型 - /// - public int OrderType { get; set; } - - /// - /// 订单号 - /// - public string OrderNo { get; set; } = null!; - - /// - /// 服务商 - /// - public string? ServiceProviderName { get; set; } - - /// - /// 原轨迹内容 - /// - public string? OriginTrackContent { get; set; } - - /// - /// 原轨迹报文 - /// - public string? OriginTrackData { get; set; } - - /// - /// 表示订单是否完成(只由轨迹刷新配置决定) - /// tips:能够使得IsCompleted为true的点,全局只有一个:轨迹刷新 - /// - public bool IsCompleted { get; set; } - - /// - /// 子系统id + /// 子系统id(操作的订单都是相同子系统下的) /// public int SubSystemId { get; set; } /// - /// 上游子系统id(0表示事件起点) + /// 订单id /// - public int UpSubSystemId { get; set; } + public OrderIdentifier[] OrderIdentifiers { get; set; } = null!; /// /// 操作人(null则默认系统) @@ -54,7 +18,7 @@ public class TrackUpsertEvent public string? OperationMan { get; set; } /// - /// true新增,false更新,null表示新增/更新 + /// true新增,false更新,null表示刷新 /// public bool? IsAdd { get; set; } @@ -82,4 +46,6 @@ public class TrackUpsertEvent /// 已经处理过的订单 /// public List Visited { get; set; } = new(); + + public TrackRefreshStruct TrackRefreshData { get; set; } } \ No newline at end of file diff --git a/src/SJZY.Track.Application.Contract/Events/TrackUpsertForRefreshEvent.cs b/src/SJZY.Track.Application.Contract/Events/TrackUpsertForRefreshEvent.cs new file mode 100644 index 00000000..7069903a --- /dev/null +++ b/src/SJZY.Track.Application.Contract/Events/TrackUpsertForRefreshEvent.cs @@ -0,0 +1,94 @@ +namespace SJZY.Track.Application.Contract.Events; + +public class TrackUpsertForRefreshEvent +{ + /// + /// 子系统id(操作的订单都是相同子系统下的) + /// + public int SubSystemId { get; set; } + + /// + /// 订单 + /// + public OrderIdentifier OrderIdentifiers { get; set; } + + /// + /// 服务商 + /// + public string? ServiceProviderName { get; set; } + + /// + /// 原轨迹内容 + /// + public string? OriginTrackContent { get; set; } + + /// + /// 原轨迹报文 + /// + public string? OriginTrackData { get; set; } + + /// + /// 表示订单是否完成(只由轨迹刷新配置决定) + /// tips:能够使得IsCompleted为true的点,全局只有一个:轨迹刷新 + /// + public bool IsCompleted { get; set; } + + /// + /// 轨迹内容代码 + /// + public string TrackCode { get; set; } = null!; + + /// + /// 轨迹发生地 + /// + public string TrackPlace { get; set; } = null!; + + /// + /// 轨迹发生时间 + /// + public DateTime TrackTime { get; set; } + + /// + /// 轨迹发生时区 + /// + public float TrackTimeZone { get; set; } +} + +public class TrackHandledDto +{ + /// + /// 原轨迹内容 + /// + public string? OriginTrackContent { get; set; } + + /// + /// 原轨迹报文 + /// + public string? OriginTrackData { get; set; } + + /// + /// 表示订单是否完成(只由轨迹刷新配置决定) + /// tips:能够使得IsCompleted为true的点,全局只有一个:轨迹刷新 + /// + public bool? IsCompleted { get; set; } + + /// + /// 轨迹内容代码 + /// + public string? TrackCode { get; set; } + + /// + /// 轨迹发生地 + /// + public string? TrackPlace { get; set; } + + /// + /// 轨迹发生时间 + /// + public DateTime? TrackTime { get; set; } + + /// + /// 轨迹发生时区 + /// + public float? TrackTimeZone { get; set; } +} \ No newline at end of file diff --git a/src/SJZY.Track.Application/EventHandlers/OrderLinkAfterFillTrackHandler.cs b/src/SJZY.Track.Application/EventHandlers/OrderLinkAfterFillTrackHandler.cs deleted file mode 100644 index 37daa472..00000000 --- a/src/SJZY.Track.Application/EventHandlers/OrderLinkAfterFillTrackHandler.cs +++ /dev/null @@ -1,48 +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.EventHandlers; - -public class OrderLinkAfterFillTrackHandler : ITransientDependency, ICapSubscribe -{ - private readonly ITrackDetailsRepository _trackDetailsRepository; - private readonly ICapPublisher _capPublisher; - - public OrderLinkAfterFillTrackHandler(ITrackDetailsRepository trackDetailsRepository, ICapPublisher capPublisher) - { - _trackDetailsRepository = trackDetailsRepository; - _capPublisher = capPublisher; - } - - [CapSubscribe(GlobalConst.OrderLinkAfterFillTrack)] - public async Task ConsumerAsync(OrderLinkAfterFillTrackEvent @event) - { - var tracks = await _trackDetailsRepository.GetListAsync(@event.OrderId); - - - foreach (var order in @event.LinkedOrders) - { - // 补轨迹 - foreach (var track in tracks) - { - var fillTrackEvent = new TrackUpsertEvent - { - OrderId = order.OrderId, - OrderType = order.OrderType, - OrderNo = order.OrderNo, - TrackCode = track.TrackCode, - TrackPlace = track.TrackPlace, - TrackTime = track.TrackTime, - TrackTimeZone = track.TrackTimeZone, - SubSystemId = order.SubSystemId, - UpSubSystemId = @event.SubSystemId, - }; - - await _capPublisher.PublishAsync(GlobalConst.TrackUpsertSubscribe, fillTrackEvent); - } - } - } -} \ No newline at end of file diff --git a/src/SJZY.Track.Application/EventHandlers/TrackChangeAfterUpdateOrderEventHandler.cs b/src/SJZY.Track.Application/EventHandlers/TrackChangeAfterUpdateOrderEventHandler.cs index a738576e..25e74d44 100644 --- a/src/SJZY.Track.Application/EventHandlers/TrackChangeAfterUpdateOrderEventHandler.cs +++ b/src/SJZY.Track.Application/EventHandlers/TrackChangeAfterUpdateOrderEventHandler.cs @@ -22,53 +22,70 @@ public class TrackChangeAfterUpdateOrderEventHandler : ITransientDependency, ICa [CapSubscribe(GlobalConst.TrackChangeAfterUpdateOrderSubscribe)] public async Task ConsumerAsync(TrackChangeAfterUpdateOrderEvent @event) { - var order = await _orderRepository.GetFirstAsync(x => x.Id == @event.OrderId); - if (order == default) return; + var orders = await _orderRepository.GetListAsync(x => @event.OrderIds.Contains(x.Id), + x => new OrderEntity + { + Id = x.Id, + IsCompleted = x.IsCompleted, + LatestTrackContent = x.LatestTrackContent, + LatestTrackEnContent = x.LatestTrackEnContent, + LatestTrackPlace = x.LatestTrackPlace, + LatestTrackTime = x.LatestTrackTime, + LatestTrackTimeZone = x.LatestTrackTimeZone, + }); + if (orders.Count == 0) return; + + // todo:delete可能发生回退,直接去es查最新轨迹,但是可能es还没有刷盘,导致回退失效,可以考虑加个定时任务弥补 if (@event.IsDelete) { - var track = await _trackDetailsRepository.GetLatestAsync(@event.OrderId); - - // 删除全部轨迹导致的重置行为 - if (track == default) + foreach (var order in orders) { - if (order.LatestTrackTime == null) return; + var tracks = await _trackDetailsRepository.GetListAsync(@event.OrderIds); - // tips:订单是支持从已完成态到未完成态的 - order.ResetTrackInfo(); + var track = tracks.Where(x => x.OrderId == order.Id).MaxBy(x => x.TrackTime); + // 删除全部轨迹导致的重置行为 + if (track == default) + { + if (order.LatestTrackTime == null) return; - await _orderRepository.UpdateAsync(order); - - return; + // tips:订单是支持从已完成态到未完成态的 + order.ResetTrackInfo(); + } + else + { + // 删除引发的回退更新 + order.IsCompleted = @event.IsCompleted; + order.LatestTrackContent = track.TrackContent; + order.LatestTrackEnContent = track.TrackEnContent; + order.LatestTrackPlace = track.TrackPlace; + order.LatestTrackTime = track.TrackTime; + order.LatestTrackTimeZone = track.TrackTimeZone; + } } - - // 删除引发的回退更新 - order.IsCompleted = @event.IsCompleted; - order.LatestTrackContent = track.TrackContent; - order.LatestTrackEnContent = track.TrackEnContent; - order.LatestTrackPlace = track.TrackPlace; - order.LatestTrackTime = track.TrackTime; - order.LatestTrackTimeZone = track.TrackTimeZone; } - else + else // upsert可以直接计算 { - if (order.LatestTrackTime != null && - @event.TrackTime.Subtract(TimeSpan.FromHours(@event.TrackTimeZone)) < - order.LatestTrackTime.Value.Subtract(TimeSpan.FromHours(order.LatestTrackTimeZone ?? 0))) + foreach (var order in orders) { - return; - } + if (order.LatestTrackTime != null && + @event.TrackTime.Subtract(TimeSpan.FromHours(@event.TrackTimeZone)) < + order.LatestTrackTime.Value.Subtract(TimeSpan.FromHours(order.LatestTrackTimeZone ?? 0))) + { + continue; + } - // upsert引发的更新 - order.IsCompleted = @event.IsCompleted; - order.LatestTrackContent = @event.TrackContent; - order.LatestTrackEnContent = @event.TrackEnContent; - order.LatestTrackPlace = @event.TrackPlace; - order.LatestTrackTime = @event.TrackTime; - order.LatestTrackTimeZone = @event.TrackTimeZone; + // upsert引发的更新 + order.IsCompleted = @event.IsCompleted; + order.LatestTrackContent = @event.TrackContent; + order.LatestTrackEnContent = @event.TrackEnContent; + order.LatestTrackPlace = @event.TrackPlace; + order.LatestTrackTime = @event.TrackTime; + order.LatestTrackTimeZone = @event.TrackTimeZone; + } } - await _orderRepository.UpdateColumnAsync(order, x => new + await _orderRepository.UpdateRangeAsync(orders, x => new { x.IsCompleted, x.LatestTrackContent, x.LatestTrackEnContent, x.LatestTrackPlace, x.LatestTrackTime, x.LatestTrackTimeZone diff --git a/src/SJZY.Track.Application/EventHandlers/TrackDeleteEventHandler.cs b/src/SJZY.Track.Application/EventHandlers/TrackDeleteEventHandler.cs index 28b38520..ea6698fb 100644 --- a/src/SJZY.Track.Application/EventHandlers/TrackDeleteEventHandler.cs +++ b/src/SJZY.Track.Application/EventHandlers/TrackDeleteEventHandler.cs @@ -29,34 +29,52 @@ public class TrackDeleteEventHandler : ITransientDependency, ICapSubscribe [CapSubscribe(GlobalConst.TrackDeleteSubscribe, Group = GlobalConst.TrackDeleteSubscribe)] public async Task ConsumerAsync(TrackDeleteEvent @event) { - if (@event.Visited.Contains(@event.OrderId)) + var dup = @event.Visited.Intersect(@event.OrderIds).ToArray(); + if (dup.Any()) { - LogHelper.Error($"删除轨迹订单时,发现循环依赖:{@event.Visited.JoinAsString(",")}"); + LogHelper.Error($"删除轨迹订单时,发现循环依赖:{dup.JoinAsString(",")}"); return; } - // 不同子系统需要做内容映射 - if (@event.UpSubSystemId != 0 && @event.UpSubSystemId != @event.SubSystemId) - { - var mapCodes = await _provideQueries - .MapTrackCodesAsync(@event.UpSubSystemId, @event.SubSystemId, @event.TrackCodes.ToArray()); - - if (mapCodes.Count == 0) - { - //throw new BusinessException(message: "订单跨子系统,未配置内容映射,请联系管理员"); - return; - } - - @event.TrackCodes = mapCodes; - } - await DeleteTrackAsync(@event); + + // 根据订单关联关系异步向下刷(异步) + var linkedOrders = await _orderRepository.GetLinkedOrdersAsync(@event.OrderIds); + foreach (var orderId in @event.OrderIds) + { + foreach (var group in linkedOrders.Where(x => x.OrderId == orderId) + .GroupBy(x => x.SubSystemId)) + { + var nextEvent = @event.DeepCopy(); + nextEvent.Visited.AddRange(@event.OrderIds); + nextEvent.TrackCodes = @event.TrackCodes; + nextEvent.SubSystemId = group.Key; + + + // 不同子系统需要做内容映射 + if (@event.SubSystemId != nextEvent.SubSystemId) + { + var mapCodes = await _provideQueries + .MapTrackCodesAsync(@event.SubSystemId, nextEvent.SubSystemId, @event.TrackCodes.ToArray()); + + if (mapCodes.Count == 0) + { + //throw new BusinessException(message: "订单跨子系统,未配置内容映射,请联系管理员"); + return; + } + + nextEvent.TrackCodes = mapCodes; + } + + await _capPublisher.PublishAsync(GlobalConst.TrackDeleteSubscribe, nextEvent); + } + } } private async Task DeleteTrackAsync(TrackDeleteEvent @event) { - // 删除轨迹 - var isOk = await _trackDetailsRepository.DeleteTrackAsync(@event.OrderId, @event.TrackCodes); + // 删除轨迹(删的是同子系统下的单,所以code是统一的) + var isOk = await _trackDetailsRepository.DeleteTrackAsync(@event.OrderIds, @event.TrackCodes); if (isOk) { @@ -65,22 +83,9 @@ public class TrackDeleteEventHandler : ITransientDependency, ICapSubscribe GlobalConst.TrackChangeAfterUpdateOrderSubscribe, new TrackChangeAfterUpdateOrderEvent { - OrderId = @event.OrderId, + OrderIds = @event.OrderIds, IsDelete = true }); } - - // 根据订单关联关系异步向下刷 - var linkedOrders = await _orderRepository.GetLinkedOrdersAsync(@event.OrderId); - foreach (var linkedOrder in linkedOrders) - { - var nextEvent = @event.DeepCopy(); - nextEvent.Visited.Add(@event.OrderId); - nextEvent.TrackCodes = @event.TrackCodes; - nextEvent.SubSystemId = linkedOrder.SubSystemId; - nextEvent.UpSubSystemId = @event.SubSystemId; - - await _capPublisher.PublishAsync(GlobalConst.TrackDeleteSubscribe, nextEvent); - } } } \ No newline at end of file diff --git a/src/SJZY.Track.Application/EventHandlers/TrackInsertForNotMappedEventHandler.cs b/src/SJZY.Track.Application/EventHandlers/TrackInsertForNotMappedEventHandler.cs index f135b558..a0df5114 100644 --- a/src/SJZY.Track.Application/EventHandlers/TrackInsertForNotMappedEventHandler.cs +++ b/src/SJZY.Track.Application/EventHandlers/TrackInsertForNotMappedEventHandler.cs @@ -45,6 +45,6 @@ public class TrackInsertForNotMappedEventHandler : ITransientDependency, ICapSub track.TrackEnContent = GlobalConst.EmptyString; track.ZeroTrackTime = track.TrackTime.Subtract(TimeSpan.FromHours(track.TrackTimeZone)); - await _trackDetailsRepository.UpsertAsync(track); + await _trackDetailsRepository.UpdateAsync(track); } } \ No newline at end of file diff --git a/src/SJZY.Track.Application/EventHandlers/TrackPushEventHandler.cs b/src/SJZY.Track.Application/EventHandlers/TrackPushEventHandler.cs index a9a207e9..65e60991 100644 --- a/src/SJZY.Track.Application/EventHandlers/TrackPushEventHandler.cs +++ b/src/SJZY.Track.Application/EventHandlers/TrackPushEventHandler.cs @@ -37,7 +37,7 @@ public class TrackPushEventHandler : ITransientDependency, ICapSubscribe var order = await _orderRepository.GetFirstAsync(x => x.Id == @event.OrderId, x => new { - x.SubSystemId, x.LatestPushTrackCode, x.QuestionType, x.CustomId + x.SubSystemId, x.LatestPushTrackCode, x.QuestionType, x.CustomId, x.OrderType }); if (order == null) return; @@ -70,10 +70,9 @@ public class TrackPushEventHandler : ITransientDependency, ICapSubscribe // 推送新增,需要根据上一次的推送 推断 本次推送 是否可行 config = await _trackPushCacheService.IsValidPushAsync(order.SubSystemId, order.CustomId, order.LatestPushTrackCode, @event.TrackCode); - if (config is not { IsAutoPush: true }) - { - config = null; - } + if (config == null) return; + if (!config.IsAutoPush) return; + if (config.OrderType != order.OrderType) return; } } else diff --git a/src/SJZY.Track.Application/EventHandlers/TrackRefreshEventHandler.cs b/src/SJZY.Track.Application/EventHandlers/TrackRefreshEventHandler.cs index 61431b30..4c132e26 100644 --- a/src/SJZY.Track.Application/EventHandlers/TrackRefreshEventHandler.cs +++ b/src/SJZY.Track.Application/EventHandlers/TrackRefreshEventHandler.cs @@ -9,6 +9,7 @@ using SJZY.Track.Application.Contract.Events; using SJZY.Track.Application.Contract.Services; using SJZY.Track.Application.Helpers; using SJZY.Track.Domain.Aggregates.OrderAggregate; +using SJZY.Track.Domain.Aggregates.TrackDetailsAggregate; using SJZY.Track.Domain.Consts; using SJZY.Track.Domain.Enums; using Volo.Abp.DependencyInjection; @@ -20,13 +21,16 @@ public class TrackRefreshEventHandler : ITransientDependency, ICapSubscribe private readonly IOrderRepository _orderRepository; private readonly ICapPublisher _capPublisher; private readonly ITrackPullCacheService _trackPullCacheService; + private readonly ITrackDetailsRepository _trackDetailsRepository; public TrackRefreshEventHandler(IOrderRepository orderRepository, - ICapPublisher capPublisher, ITrackPullCacheService trackPullCacheService) + ICapPublisher capPublisher, ITrackPullCacheService trackPullCacheService, + ITrackDetailsRepository trackDetailsRepository) { _orderRepository = orderRepository; _capPublisher = capPublisher; _trackPullCacheService = trackPullCacheService; + _trackDetailsRepository = trackDetailsRepository; } [CapSubscribe(GlobalConst.TrackRefreshSubscribe, Group = GlobalConst.TrackRefreshSubscribe)] @@ -89,15 +93,19 @@ public class TrackRefreshEventHandler : ITransientDependency, ICapSubscribe await HandleTrackAsync(item, paramWithContentConfig, context); } } - else if (orderToken is JObject) + else if (trackToken is JObject) { - await HandleTrackAsync(orderToken, paramWithContentConfig, context); + await HandleTrackAsync(trackToken, paramWithContentConfig, context); } } private async Task HandleTrackAsync(JToken trackToken, TrackPullParamWithContentConfigDto paramWithContentConfig, TrackRefreshContext context) { + var originTrackData = JsonConvert.SerializeObject(trackToken); + // 如果已经存在一模一样的报文了说明处理过了,直接return + if (await _trackDetailsRepository.AnyAsync(context.OrderId, originTrackData)) return; + var paramConfig = paramWithContentConfig.ParamConfig; var contentConfigs = paramWithContentConfig.ContentConfigs; TrackPullContentConfigDto? matchedContentConfig = null; @@ -214,23 +222,31 @@ public class TrackRefreshEventHandler : ITransientDependency, ICapSubscribe // 新增/更新轨迹 var trackUpsertEvent = new TrackUpsertEvent { - OrderId = context.OrderId, - OrderType = context.OrderType, - OrderNo = context.OrderNo, - ServiceProviderName = context.ServiceProviderName, - OriginTrackData = JsonConvert.SerializeObject(trackToken), - IsCompleted = matchedContentConfig.IsCompleted, + OrderIdentifiers = new[] + { + new OrderIdentifier + { + OrderId = context.OrderId, + OrderNo = context.OrderNo, + OrderType = context.OrderType + } + }, + TrackRefreshData = new TrackRefreshStruct + { + ServiceProviderName = context.ServiceProviderName, + OriginTrackData = originTrackData, + IsCompleted = matchedContentConfig.IsCompleted, + OriginTrackContent = paramConfig.TrackContentName != null + ? trackToken[paramConfig.TrackContentName]?.Value() + : GlobalConst.EmptyString + }, SubSystemId = context.SubSystemId, TrackCode = matchedContentConfig.TrackContentCode, TrackPlace = trackPlace ?? GlobalConst.EmptyString, TrackTime = trackTime ?? DateTime.Now, TrackTimeZone = trackTimeZone ?? matchedContentConfig.TrackTimeZoneValue ?? 8 }; - if (paramConfig.TrackContentName != null) - { - trackUpsertEvent.OriginTrackContent = trackToken[paramConfig.TrackContentName]?.Value(); - } - await _capPublisher.PublishAsync(GlobalConst.TrackUpsertSubscribe, trackUpsertEvent); + await _capPublisher.PublishAsync(GlobalConst.TrackUpsertForRefreshSubscribe, trackUpsertEvent); } } \ No newline at end of file diff --git a/src/SJZY.Track.Application/EventHandlers/TrackUpsertEventHandler.cs b/src/SJZY.Track.Application/EventHandlers/TrackUpsertEventHandler.cs index 105ef588..81e954fe 100644 --- a/src/SJZY.Track.Application/EventHandlers/TrackUpsertEventHandler.cs +++ b/src/SJZY.Track.Application/EventHandlers/TrackUpsertEventHandler.cs @@ -26,145 +26,166 @@ public class TrackUpsertEventHandler : ITransientDependency, ICapSubscribe _trackDetailsRepository = trackDetailsRepository; } + [CapSubscribe(GlobalConst.TrackUpsertSubscribe, Group = GlobalConst.TrackUpsertSubscribe)] [CapSubscribe(GlobalConst.TrackUpsertSubscribe, Group = GlobalConst.TrackUpsertSubscribe)] public async Task ConsumerAsync(TrackUpsertEvent @event) { - if (@event.Visited.Contains(@event.OrderId)) + var orderIds = @event.OrderIdentifiers.Select(x => x.OrderId).ToArray(); + + var dup = @event.Visited.Intersect(orderIds).ToArray(); + if (dup.Any()) { - LogHelper.Error($"轨迹订单循环依赖预警:{@event.Visited.JoinAsString(",")}"); + LogHelper.Error($"删除轨迹订单时,发现循环依赖:{dup.JoinAsString(",")}"); return; } - // 不同子系统需要做内容映射 - if (@event.UpSubSystemId != 0 && @event.UpSubSystemId != @event.SubSystemId) - { - var mapCode = (await _provideQueries - .MapTrackCodesAsync(@event.UpSubSystemId, @event.SubSystemId, @event.TrackCode)) - .FirstOrDefault(); + await HandleTrackAsync(@event); - if (mapCode == default) + // 根据订单关联关系异步向下刷(异步) + var linkedOrders = await _orderRepository.GetLinkedOrdersAsync(orderIds); + foreach (var order in @event.OrderIdentifiers) + { + // 理论上小包在这不会分组 + foreach (var group in linkedOrders.Where(x => x.OrderId == order.OrderId) + .GroupBy(x => x.SubSystemId)) { - // 跨子系统没做映射的轨迹不处理 - return; + var nextEvent = @event.DeepCopy(); + nextEvent.Visited.AddRange(orderIds); + nextEvent.SubSystemId = group.Key; + nextEvent.OrderIdentifiers = group.Select(x => new OrderIdentifier + { + OrderId = x.OrderId, + OrderNo = x.OrderNo, + OrderType = x.OrderType + }).ToArray(); + nextEvent.TrackRefreshData = new TrackRefreshStruct + { + ServiceProviderName = @event.TrackRefreshData.ServiceProviderName, + OriginTrackContent = @event.TrackRefreshData.OriginTrackContent, + OriginTrackData = @event.TrackRefreshData.OriginTrackData, + // tips:一定要重置为false,父级订单的完成不会使得关联订单完成,关联单也必须由刷新来完成或手动设置完成!! + IsCompleted = false + }; + + // 不同子系统需要做内容映射 + if (@event.SubSystemId != nextEvent.SubSystemId) + { + var mapCode = (await _provideQueries + .MapTrackCodesAsync(@event.SubSystemId, nextEvent.SubSystemId, @event.TrackCode)) + .FirstOrDefault(); + + if (mapCode == default) + { + // 跨子系统没做映射的轨迹不处理 + return; + } + + @event.TrackCode = mapCode; + } + + await _capPublisher.PublishAsync(GlobalConst.TrackUpsertSubscribe, nextEvent); + } + } + } + + private async Task HandleTrackAsync(TrackUpsertEvent @event) + { + var orderIds = @event.OrderIdentifiers.Select(x => x.OrderId).ToArray(); + var tracks = await _trackDetailsRepository.GetListAsync(orderIds, @event.TrackCode); + + var insertTracks = new List(); + + foreach (var order in @event.OrderIdentifiers) + { + var track = tracks.FirstOrDefault(x => x.OrderId == order.OrderId); + + if (@event.IsAdd != null) + { + if (track == null && !@event.IsAdd!.Value) return; // 不存在不让改 + if (track != null && @event.IsAdd!.Value) return; // 存在不让创建 } - @event.TrackCode = mapCode; - } - - var track = await _trackDetailsRepository.GetFirstOrDefaultAsync(@event.OrderId, @event.TrackCode); - - if (@event.IsAdd != null) - { - if (track == null && !@event.IsAdd!.Value) return; // 不存在不让改 - if (track != null && @event.IsAdd!.Value) return; // 存在不让创建 - } - - // step1、upsert es轨迹 - track = await UpsertTrackAsync(track, @event); - - if (track == null) return; // 模板没配该轨迹代码,不再继续 - - // step2、触发轨迹推送事件(异步) - var trackPushEvent = new TrackPushEvent - { - OptionType = track.Id.IsNullOrWhiteSpace() ? OptionType.新增 : OptionType.修改, - OrderId = track.OrderId, - OrderNo = track.OrderNo, - TrackStatus = track.TrackStatus, - TrackCode = track.TrackCode, - TrackContent = track.TrackContent, - TrackPlace = track.TrackPlace, - TrackTime = track.TrackTime, - TrackTimeZone = track.TrackTimeZone, - }; - - await _capPublisher.PublishAsync(GlobalConst.TrackPushSubscribe, trackPushEvent); - - // step3、触发订单主表更新事件(异步) - await _capPublisher.PublishAsync(GlobalConst.TrackChangeAfterUpdateOrderSubscribe, - new TrackChangeAfterUpdateOrderEvent + // step1、upsert es轨迹 + if (track == default) { + track = new TrackDetailsIndex + { + IndexName = $"{GlobalConst.TrackIndex}-{DateTime.Now:yyyy.MM.dd}", + OrderId = order.OrderId, + OrderNo = order.OrderNo, + OrderType = order.OrderType, + TrackCode = @event.TrackCode, + TrackPlace = @event.TrackPlace, + TrackTime = @event.TrackTime, + TrackTimeZone = @event.TrackTimeZone, + ServiceProviderName = @event.TrackRefreshData.ServiceProviderName, + OriginTrackContent = @event.TrackRefreshData.OriginTrackContent, + OriginTrackData = @event.TrackRefreshData.OriginTrackData, + IsCanDelete = false, + CreateUser = @event.OperationMan ?? GlobalConst.SystemUser, + CreateTime = DateTime.Now + }; + + //todo:可以优化? + // 根据轨迹code在订单模板内容中寻找匹配的 + var trackContent = await _provideQueries.MatchTrackContentAsync(order.OrderId, @event.TrackCode); + if (trackContent == default) + { + // 订单所绑定的模板,没有一条内容可以匹配发生的轨迹 + continue; + } + + track.TrackStatus = trackContent.Status; + track.TrackCode = trackContent.TrackCode; + track.TrackContent = trackContent.Content; + track.TrackEnContent = trackContent.EnContent; + track.IsCanDelete = trackContent.IsCanDelete; + track.ZeroTrackTime = track.TrackTime.Subtract(TimeSpan.FromHours(track.TrackTimeZone)); + + insertTracks.Add(track); + } + else + { + track.TrackPlace = @event.TrackPlace; + track.TrackTime = @event.TrackTime; + track.TrackTimeZone = @event.TrackTimeZone; + track.UpdateUser = @event.OperationMan ?? GlobalConst.SystemUser; + track.UpdateTime = DateTime.Now; + + await _trackDetailsRepository.UpdateAsync(track); + } + + // step2、触发轨迹推送事件(异步) + var trackPushEvent = new TrackPushEvent + { + OptionType = track.Id.IsNullOrWhiteSpace() ? OptionType.新增 : OptionType.修改, OrderId = track.OrderId, - IsCompleted = @event.IsCompleted, + OrderNo = track.OrderNo, + TrackStatus = track.TrackStatus, TrackCode = track.TrackCode, TrackContent = track.TrackContent, - TrackEnContent = track.TrackEnContent, TrackPlace = track.TrackPlace, TrackTime = track.TrackTime, - TrackTimeZone = track.TrackTimeZone - }); - - // step4、根据订单关联关系异步向下刷(异步) - var linkedOrders = await _orderRepository.GetLinkedOrdersAsync(@event.OrderId); - foreach (var linkedOrder in linkedOrders) - { - var nextEvent = @event.DeepCopy(); - nextEvent.Visited.Add(@event.OrderId); - // tips:一定要重置为false,父级订单的完成不会使得关联订单完成,关联单也必须由刷新来完成或手动设置完成!! - nextEvent.IsCompleted = false; // 能够使得轨迹IsCompleted为true的点,全局只有一个:轨迹刷新 - nextEvent.OrderId = linkedOrder.OrderId; - nextEvent.OrderType = linkedOrder.OrderType; - nextEvent.OrderNo = linkedOrder.OrderNo; - nextEvent.SubSystemId = linkedOrder.SubSystemId; - nextEvent.UpSubSystemId = @event.SubSystemId; - await _capPublisher.PublishAsync(GlobalConst.TrackUpsertSubscribe, nextEvent); - } - } - - /// - /// 不存在则新增轨迹,存在则更新 - /// - /// - /// - private async Task UpsertTrackAsync(TrackDetailsIndex? track, TrackUpsertEvent @event) - { - if (track == default) - { - track = new TrackDetailsIndex - { - IndexName = $"{GlobalConst.TrackIndex}-{DateTime.Now:yyyy.MM.dd}", - OrderId = @event.OrderId, - OrderNo = @event.OrderNo, - OrderType = @event.OrderType, - TrackCode = @event.TrackCode, - TrackPlace = @event.TrackPlace, - TrackTime = @event.TrackTime, - TrackTimeZone = @event.TrackTimeZone, - ServiceProviderName = @event.ServiceProviderName, - OriginTrackContent = @event.OriginTrackContent, - OriginTrackData = @event.OriginTrackData, - IsCanDelete = false, - CreateUser = @event.OperationMan ?? GlobalConst.SystemUser, - CreateTime = DateTime.Now + TrackTimeZone = track.TrackTimeZone, }; - //todo:可以优化 - // 根据轨迹code在订单模板内容中寻找匹配的 - var trackContent = await _provideQueries.MatchTrackContentAsync(@event.OrderId, @event.TrackCode); - if (trackContent == default) - { - // 订单所绑定的模板,没有一条内容可以匹配发生的轨迹 - return null; - } + await _capPublisher.PublishAsync(GlobalConst.TrackPushSubscribe, trackPushEvent); - track.TrackStatus = trackContent.Status; - track.TrackCode = trackContent.TrackCode; - track.TrackContent = trackContent.Content; - track.TrackEnContent = trackContent.EnContent; - track.IsCanDelete = trackContent.IsCanDelete; - track.ZeroTrackTime = track.TrackTime.Subtract(TimeSpan.FromHours(track.TrackTimeZone)); - } - else - { - track.TrackPlace = @event.TrackPlace; - track.TrackTime = @event.TrackTime; - track.TrackTimeZone = @event.TrackTimeZone; - track.UpdateUser = @event.OperationMan ?? GlobalConst.SystemUser; - track.UpdateTime = DateTime.Now; + // step3、触发订单主表更新事件(异步) + await _capPublisher.PublishAsync(GlobalConst.TrackChangeAfterUpdateOrderSubscribe, + new TrackChangeAfterUpdateOrderEvent + { + OrderIds = new[] { track.OrderId }, + IsCompleted = @event.TrackRefreshData.IsCompleted, + TrackCode = track.TrackCode, + TrackContent = track.TrackContent, + TrackEnContent = track.TrackEnContent, + TrackPlace = track.TrackPlace, + TrackTime = track.TrackTime, + TrackTimeZone = track.TrackTimeZone + }); } - await _trackDetailsRepository.UpsertAsync(track); - - return track; + await _trackDetailsRepository.AddManyAsync(insertTracks); } } \ No newline at end of file diff --git a/src/SJZY.Track.Application/Services/ProvideServices/OrderService.Link.cs b/src/SJZY.Track.Application/Services/ProvideServices/OrderService.Link.cs index 5eca209c..f37ff3b5 100644 --- a/src/SJZY.Track.Application/Services/ProvideServices/OrderService.Link.cs +++ b/src/SJZY.Track.Application/Services/ProvideServices/OrderService.Link.cs @@ -2,6 +2,7 @@ using SJZY.Track.Application.Contract.Dtos.ProvideServices; using SJZY.Track.Application.Contract.Events; using SJZY.Track.Domain.Aggregates.OrderAggregate; +using SJZY.Track.Domain.Aggregates.TrackDetailsAggregate; using SJZY.Track.Domain.Consts; using SJZY.Track.Domain.Queries; @@ -14,6 +15,7 @@ public partial class OrderService { private readonly IBasicQuery _orderLinkQuery; private readonly ICapPublisher _capPublisher; + private readonly ITrackDetailsRepository _trackDetailsRepository; /// /// 关联、解除关联订单 @@ -52,23 +54,12 @@ public partial class OrderService if (!input.IsLink) return await UnLinkOrderAsync(input); // 关联订单 - var linkedOrders = await DoLinkOrderAsync(input, order.Id); - - // 补轨迹 - if (linkedOrders.Count > 0) - { - await _capPublisher.PublishAsync(GlobalConst.OrderLinkAfterFillTrack, new OrderLinkAfterFillTrackEvent - { - OrderId = order.Id, - SubSystemId = order.SubSystemId, - LinkedOrders = linkedOrders, - }); - } + await DoLinkOrderAsync(input, order.Id); return new UnifyResultDto(true, true); } - private async Task> DoLinkOrderAsync(LinkOrderInput input, int orderId) + private async Task DoLinkOrderAsync(LinkOrderInput input, int orderId) { // 获取已关联的订单 var linkOrderNos = await _orderLinkQuery.GetListAsync(x => @@ -81,9 +72,9 @@ public partial class OrderService // 过滤掉不存在的订单 var canLinkOrders = await _orderRepository.GetListAsync(x => x.OrderType == input.LinkOrderType && noLinkOrderNos.Contains(x.OrderNo), - x => new { x.Id, x.OrderNo, x.SubSystemId }); + x => new { x.Id, x.OrderNo, x.OrderType, x.SubSystemId }); - if (canLinkOrders.Count == 0) return new List(); + if (canLinkOrders.Count == 0) return; await _orderRepository.LinkOrderAsync(canLinkOrders.Select(x => new OrderLinkEntity { @@ -95,13 +86,32 @@ public partial class OrderService LinkOrderType = input.LinkOrderType }).ToList()); - return canLinkOrders.Select(x => new LinkedOrder + var tracks = await _trackDetailsRepository.GetListAsync(orderId); + + // 补轨迹 + foreach (var group in canLinkOrders.GroupBy(x => x.SubSystemId)) { - SubSystemId = x.SubSystemId, - OrderId = x.Id, - OrderNo = x.OrderNo, - OrderType = input.LinkOrderType - }).ToList(); + foreach (var track in tracks) + { + var fillTrackEvent = new TrackUpsertEvent + { + SubSystemId = group.Key, + OrderIdentifiers = group.Select(x => new OrderIdentifier + { + OrderId = x.Id, + OrderNo = x.OrderNo, + OrderType = x.OrderType + }).ToArray(), + TrackCode = track.TrackCode, + TrackPlace = track.TrackPlace, + TrackTime = track.TrackTime, + TrackTimeZone = track.TrackTimeZone, + IsAdd = true + }; + + await _capPublisher.PublishAsync(GlobalConst.TrackUpsertSubscribe, fillTrackEvent); + } + } } private async Task UnLinkOrderAsync(LinkOrderInput input) diff --git a/src/SJZY.Track.Application/Services/ProvideServices/OrderService.cs b/src/SJZY.Track.Application/Services/ProvideServices/OrderService.cs index d1086bf7..4a72f258 100644 --- a/src/SJZY.Track.Application/Services/ProvideServices/OrderService.cs +++ b/src/SJZY.Track.Application/Services/ProvideServices/OrderService.cs @@ -2,6 +2,7 @@ using SJZY.Track.Application.Contract.Dtos.ProvideServices; using SJZY.Track.Application.Contract.Services; using SJZY.Track.Domain.Aggregates.OrderAggregate; +using SJZY.Track.Domain.Aggregates.TrackDetailsAggregate; using SJZY.Track.Domain.Queries; using SJZY.UserCenter.HttpApi.Services; @@ -17,9 +18,10 @@ public partial class OrderService : ApplicationService, IOrderService private readonly IOrderRepository _orderRepository; public OrderService(IOrderRepository orderRepository, IBasicQuery orderLinkQuery, - ICapPublisher capPublisher) + ICapPublisher capPublisher, ITrackDetailsRepository trackDetailsRepository) { _orderRepository = orderRepository; + _trackDetailsRepository = trackDetailsRepository; _capPublisher = capPublisher; _orderLinkQuery = orderLinkQuery; } diff --git a/src/SJZY.Track.Application/Services/ProvideServices/TrackService.cs b/src/SJZY.Track.Application/Services/ProvideServices/TrackService.cs index 1d081ead..1d20b169 100644 --- a/src/SJZY.Track.Application/Services/ProvideServices/TrackService.cs +++ b/src/SJZY.Track.Application/Services/ProvideServices/TrackService.cs @@ -43,7 +43,7 @@ public partial class TrackService : ApplicationService, ITrackService var order = await _orderRepository.GetFirstAsync(x => x.OrderType == input.OrderType && x.OrderNo == input.OrderNo, x => new { - x.Id, x.SubSystemId + x.Id, x.SubSystemId, x.OrderNo, x.OrderType }); if (order == default) { @@ -52,8 +52,16 @@ public partial class TrackService : ApplicationService, ITrackService // 新增/更新轨迹 var @event = ObjectMapper.Map(input); - @event.OrderId = order.Id; @event.SubSystemId = order.SubSystemId; + @event.OrderIdentifiers = new[] + { + new OrderIdentifier + { + OrderId = order.Id, + OrderNo = order.OrderNo, + OrderType = order.OrderType + } + }; @event.OperationMan = CurrentUserRequest.CurrentUser.Name; await _capPublisher.PublishAsync(GlobalConst.TrackUpsertSubscribe, @event); return new UnifyResultDto(true, true); @@ -80,25 +88,29 @@ public partial class TrackService : ApplicationService, ITrackService x.Id, x.OrderNo, x.SubSystemId }); - foreach (var order in orders) + foreach (var group in orders.GroupBy(x => x.SubSystemId)) { // 新增/更新轨迹 var @event = new TrackUpsertEvent { + SubSystemId = group.Key, + OrderIdentifiers = group.Select(order => new OrderIdentifier + { + OrderId = order.Id, + OrderNo = order.OrderNo, + OrderType = input.OrderType + }).ToArray(), IsAdd = input.IsAdd, TrackCode = input.TrackCode, TrackPlace = input.TrackPlace, TrackTime = input.TrackTime!.Value, TrackTimeZone = input.TrackTimeZone!.Value, - OrderType = input.OrderType, - OrderNo = order.OrderNo, - OrderId = order.Id, - SubSystemId = order.SubSystemId, OperationMan = CurrentUserRequest.CurrentUser.Name }; await _capPublisher.PublishAsync(GlobalConst.TrackUpsertSubscribe, @event); } + return new UnifyResultDto(true, true); } @@ -132,7 +144,7 @@ public partial class TrackService : ApplicationService, ITrackService // 删除轨迹 var @event = new TrackDeleteEvent { - OrderId = order.Id, + OrderIds = new[] { order.Id }, TrackCodes = codes.Select(x => x.TrackCode).ToList(), SubSystemId = order.SubSystemId, OperationMan = CurrentUserRequest.CurrentUser.Name @@ -173,7 +185,7 @@ public partial class TrackService : ApplicationService, ITrackService { var @event = new TrackDeleteEvent { - OrderId = group.Key, + OrderIds = group.Select(x => x.OrderId).ToArray(), TrackCodes = codes.Select(x => x.TrackCode).ToList(), SubSystemId = orders.First(x => x.Id == group.Key).SubSystemId, OperationMan = CurrentUserRequest.CurrentUser.Name diff --git a/src/SJZY.Track.Domain/Aggregates/OrderAggregate/IOrderRepository.cs b/src/SJZY.Track.Domain/Aggregates/OrderAggregate/IOrderRepository.cs index 7eaf030f..78cdd5df 100644 --- a/src/SJZY.Track.Domain/Aggregates/OrderAggregate/IOrderRepository.cs +++ b/src/SJZY.Track.Domain/Aggregates/OrderAggregate/IOrderRepository.cs @@ -38,7 +38,7 @@ public interface IOrderRepository : IBasicRepository /// /// /// - Task> GetLinkedOrdersAsync(int orderId); + Task> GetLinkedOrdersAsync(int[] orderId); /// /// 关联订单 diff --git a/src/SJZY.Track.Domain/Aggregates/TrackDetailsAggregate/ITrackDetailsRepository.cs b/src/SJZY.Track.Domain/Aggregates/TrackDetailsAggregate/ITrackDetailsRepository.cs index 628acc1f..d32ed593 100644 --- a/src/SJZY.Track.Domain/Aggregates/TrackDetailsAggregate/ITrackDetailsRepository.cs +++ b/src/SJZY.Track.Domain/Aggregates/TrackDetailsAggregate/ITrackDetailsRepository.cs @@ -4,11 +4,18 @@ namespace SJZY.Track.Domain.Aggregates.TrackDetailsAggregate; public interface ITrackDetailsRepository { - Task GetFirstOrDefaultAsync(int orderId, string trackCode); + Task> GetListAsync(int[] orderIds, string trackCode); + + Task> GetListAsync(int[] orderIds); Task AnyAsync(int orderId, DateTime trackTime); - Task UpsertAsync(TrackDetailsIndex index); + Task AnyAsync(int orderId, string originTrackData); + + Task UpdateAsync(TrackDetailsIndex index); + + Task AddManyAsync(List index); + Task> GetListAsync(int orderType, List orderNos); @@ -20,15 +27,8 @@ public interface ITrackDetailsRepository /// /// 删除轨迹 /// - /// + /// /// /// - Task DeleteTrackAsync(int orderId, List trackCodes); - - /// - /// 获取最近一条发生的轨迹 - /// - /// - /// - Task GetLatestAsync(int orderId); + Task DeleteTrackAsync(int[] orderIds, List trackCodes); } \ No newline at end of file diff --git a/src/SJZY.Track.Domain/Consts/GlobalConst.MQ.cs b/src/SJZY.Track.Domain/Consts/GlobalConst.MQ.cs index 35179262..b855eb70 100644 --- a/src/SJZY.Track.Domain/Consts/GlobalConst.MQ.cs +++ b/src/SJZY.Track.Domain/Consts/GlobalConst.MQ.cs @@ -7,6 +7,11 @@ public partial class GlobalConst /// public const string TrackUpsertSubscribe = "SJZY.Track.TrackUpsert"; + /// + /// 轨迹刷新引发的新增/更新 专用 + /// + public const string TrackUpsertForRefreshSubscribe = "SJZY.Track.TrackUpsertForRefresh"; + /// /// 无法映射的轨迹新增 /// diff --git a/src/SJZY.Track.Repository/EsExtensions.cs b/src/SJZY.Track.Repository/EsExtensions.cs new file mode 100644 index 00000000..b926f93b --- /dev/null +++ b/src/SJZY.Track.Repository/EsExtensions.cs @@ -0,0 +1,22 @@ +using Nest; +using SJZY.Expand.ElasticSearch; + +namespace SJZY.Track.Repository; + +public static class EsExtensions +{ + public static List ToIdList(this ISearchResponse response) where T : IdBaseIndex + { + var dtos = new List(); + + foreach (var hit in response.Hits) + { + var dto = hit.Source; + dto.Id = hit.Id; + + dtos.Add(dto); + } + + return dtos; + } +} \ No newline at end of file diff --git a/src/SJZY.Track.Repository/Repositories/OrderRepository.cs b/src/SJZY.Track.Repository/Repositories/OrderRepository.cs index b2f48a68..5e78fc5f 100644 --- a/src/SJZY.Track.Repository/Repositories/OrderRepository.cs +++ b/src/SJZY.Track.Repository/Repositories/OrderRepository.cs @@ -67,16 +67,16 @@ AND `a`.`IsDeleted` = 0 AND `b`.`IsDeleted` = 0;"); #region 订单关联 - public async Task> GetLinkedOrdersAsync(int orderId) + public async Task> GetLinkedOrdersAsync(int[] orderIds) { return await Context.Queryable() .LeftJoin((a, b) => a.LinkOrderId == b.Id) - .Where(a => a.OrderId == orderId) + .Where(a => orderIds.Contains(a.OrderId)) .Select((a, b) => new LinkedOrderVO { OrderId = b.Id, - OrderType = b.OrderType, OrderNo = b.OrderNo, + OrderType = b.OrderType, SubSystemId = b.SubSystemId }) .ToListAsync(); diff --git a/src/SJZY.Track.Repository/Repositories/TrackDetailsRepository.cs b/src/SJZY.Track.Repository/Repositories/TrackDetailsRepository.cs index 03b3c7c9..b692a3f2 100644 --- a/src/SJZY.Track.Repository/Repositories/TrackDetailsRepository.cs +++ b/src/SJZY.Track.Repository/Repositories/TrackDetailsRepository.cs @@ -2,6 +2,7 @@ using Nest; using SJZY.Expand.ABP.Core.Logger; using SJZY.Expand.ElasticSearch.Services; using SJZY.Track.Domain.Aggregates.TrackDetailsAggregate; +using SJZY.Track.Domain.Consts; using SJZY.Track.Domain.Dtos.TrackDetails; namespace SJZY.Track.Repository.Repositories; @@ -13,29 +14,50 @@ internal class TrackDetailsRepository : ElasticSearchContextAbstract GetFirstOrDefaultAsync(int orderId, string trackCode) + public async Task> GetListAsync(int[] orderIds, string trackCode) { var r = await Context.SearchAsync(s => s .Source() .Query(q => - q.Term(f => f.OrderId, orderId) + q.Terms(t => t + .Field(f => f.OrderId) + .Terms(orderIds)) && q.Term(f => f.TrackCode.Suffix("keyword"), trackCode) + && q.Term(f => f.ServiceProviderName.Suffix("keyword"), GlobalConst.EmptyString) ) ); - var res = r.Documents.FirstOrDefault(); - if (res != default && r.Hits.FirstOrDefault() != default) - { - res.Id = r.Hits.FirstOrDefault()!.Id; - } + return r.ToIdList(); + } - return res; + public async Task> GetListAsync(int[] orderIds) + { + var data = await Context.SearchAsync(x => x + .Source(s => s.Includes(fd => fd + .Field(f => f.TrackEnContent) + .Field(f => f.TrackContent) + .Field(f => f.TrackPlace) + .Field(f => f.TrackTime) + .Field(f => f.TrackTimeZone) + .Field(f => f.OrderId) + )) + .Query(q => + q.Terms(t => t + .Field(f => f.OrderId) + .Terms(orderIds)) + && q.Term(f => f.ServiceProviderName.Suffix("keyword"), GlobalConst.EmptyString) + ) + .Sort(s => s.Field(f => f.TrackTime, SortOrder.Descending)) + .Size(1) + ); + + return data.Documents.ToList(); } public async Task AnyAsync(int orderId, DateTime trackTime) { var r = await Context.SearchAsync(x => x - .Source(s => s.Includes(fd => fd.Field(f => f.Id))) + .Source(s => s.Includes(fd => fd.Field(f => f.TrackCode))) .Query(q => q.Term(f => f.OrderId, orderId) && q.Term(f => f.TrackTime, trackTime) @@ -45,33 +67,44 @@ internal class TrackDetailsRepository : ElasticSearchContextAbstract 0; } - public async Task UpsertAsync(TrackDetailsIndex index) + public async Task AnyAsync(int orderId, string originTrackData) { - if (index.Id.IsNullOrWhiteSpace()) - { - // 按天写入es - var r = await Context.IndexAsync(index, request => request - .Index(index.IndexName) - //.Refresh(Refresh.True) // 可选:立即刷新索引使更改立即可见 - ); + 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) + ) + ); - if (!r.IsValid) - { - LogHelper.Error($"轨迹新增失败,原因:{r.DebugInformation}。"); - } + return r.Hits.Count > 0; + } + + + public async Task UpdateAsync(TrackDetailsIndex track) + { + var r = await Context.UpdateAsync(track.Id, u => u + .Index(track.IndexName) + .Doc(track) + //.Refresh(Refresh.True) // 可选:立即刷新索引使更改立即可见 + ); + + if (!r.IsValid) + { + LogHelper.Error($"轨迹更新失败,原因:{r.DebugInformation}。"); } - else - { - var r = await Context.UpdateAsync(index.Id, u => u - .Index(index.IndexName) - .Doc(index) - //.Refresh(Refresh.True) // 可选:立即刷新索引使更改立即可见 - ); + } - if (!r.IsValid) - { - LogHelper.Error($"轨迹更新失败,原因:{r.DebugInformation}。"); - } + public async Task AddManyAsync(List tracks) + { + if (!tracks.Any()) return; + + // 按天写入es + var r = await Context.IndexManyAsync(tracks, tracks.First().IndexName); + + if (!r.IsValid) + { + LogHelper.Error($"{tracks.Count}条轨迹新增失败,原因:{r.DebugInformation}。"); } } @@ -140,32 +173,12 @@ internal class TrackDetailsRepository : ElasticSearchContextAbstract GetLatestAsync(int orderId) - { - var data = await Context.SearchAsync(x => x - .Source(s => s.Includes(fd => fd - .Field(f => f.TrackEnContent) - .Field(f => f.TrackContent) - .Field(f => f.TrackPlace) - .Field(f => f.TrackTime) - .Field(f => f.TrackTimeZone) - )) - .Query(q => - q.Term(f => f.OrderId, orderId) - ) - .Sort(s => s.Field(f => f.TrackTime, SortOrder.Descending)) - .Size(1) - ); - - return data.Documents.FirstOrDefault(); - } - - public async Task DeleteTrackAsync(int orderId, List trackCodes) + public async Task DeleteTrackAsync(int[] orderIds, List trackCodes) { var r = await Context.DeleteByQueryAsync(x => x .Query( q => - q.Term(t => t.OrderId, orderId) + q.Terms(t => t.Field(f => f.OrderId).Terms(orderIds)) && q.Term(t => t.IsCanDelete, true) && q.Terms(t => t.Field(f => f.TrackCode.Suffix("keyword")).Terms(trackCodes))) //.Refresh(Refresh.True) // 可选:立即刷新索引使更改立即可见 From 1f8fe7c2489b16754e70f230e647d95779056216 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=B9=8F=E5=86=9B?= <2357729423@qq.com> Date: Fri, 12 Apr 2024 21:40:17 +0800 Subject: [PATCH 12/72] =?UTF-8?q?change=EF=BC=9A=E5=8F=8C=E8=AE=A2?= =?UTF-8?q?=E9=98=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../EventHandlers/TrackUpsertEventHandler.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/SJZY.Track.Application/EventHandlers/TrackUpsertEventHandler.cs b/src/SJZY.Track.Application/EventHandlers/TrackUpsertEventHandler.cs index 81e954fe..0ce9623c 100644 --- a/src/SJZY.Track.Application/EventHandlers/TrackUpsertEventHandler.cs +++ b/src/SJZY.Track.Application/EventHandlers/TrackUpsertEventHandler.cs @@ -27,7 +27,7 @@ public class TrackUpsertEventHandler : ITransientDependency, ICapSubscribe } [CapSubscribe(GlobalConst.TrackUpsertSubscribe, Group = GlobalConst.TrackUpsertSubscribe)] - [CapSubscribe(GlobalConst.TrackUpsertSubscribe, Group = GlobalConst.TrackUpsertSubscribe)] + [CapSubscribe(GlobalConst.TrackUpsertForRefreshSubscribe, Group = GlobalConst.TrackUpsertForRefreshSubscribe)] public async Task ConsumerAsync(TrackUpsertEvent @event) { var orderIds = @event.OrderIdentifiers.Select(x => x.OrderId).ToArray(); From 639a2232a3f4bf4b6f9b4d53fe94165039b78c5a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=B9=8F=E5=86=9B?= <2357729423@qq.com> Date: Mon, 15 Apr 2024 09:03:04 +0800 Subject: [PATCH 13/72] =?UTF-8?q?fix=EF=BC=9Aorder=20link=20query=20logic?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../EventHandlers/TrackDeleteEventHandler.cs | 2 +- .../EventHandlers/TrackUpsertEventHandler.cs | 2 +- src/SJZY.Track.Domain/Dtos/Order/LinkedOrderVO.cs | 5 +++++ src/SJZY.Track.Repository/Repositories/OrderRepository.cs | 1 + 4 files changed, 8 insertions(+), 2 deletions(-) diff --git a/src/SJZY.Track.Application/EventHandlers/TrackDeleteEventHandler.cs b/src/SJZY.Track.Application/EventHandlers/TrackDeleteEventHandler.cs index ea6698fb..fc413d98 100644 --- a/src/SJZY.Track.Application/EventHandlers/TrackDeleteEventHandler.cs +++ b/src/SJZY.Track.Application/EventHandlers/TrackDeleteEventHandler.cs @@ -42,7 +42,7 @@ public class TrackDeleteEventHandler : ITransientDependency, ICapSubscribe var linkedOrders = await _orderRepository.GetLinkedOrdersAsync(@event.OrderIds); foreach (var orderId in @event.OrderIds) { - foreach (var group in linkedOrders.Where(x => x.OrderId == orderId) + foreach (var group in linkedOrders.Where(x => x.OwnerOrderId == orderId) .GroupBy(x => x.SubSystemId)) { var nextEvent = @event.DeepCopy(); diff --git a/src/SJZY.Track.Application/EventHandlers/TrackUpsertEventHandler.cs b/src/SJZY.Track.Application/EventHandlers/TrackUpsertEventHandler.cs index 0ce9623c..81d7e461 100644 --- a/src/SJZY.Track.Application/EventHandlers/TrackUpsertEventHandler.cs +++ b/src/SJZY.Track.Application/EventHandlers/TrackUpsertEventHandler.cs @@ -46,7 +46,7 @@ public class TrackUpsertEventHandler : ITransientDependency, ICapSubscribe foreach (var order in @event.OrderIdentifiers) { // 理论上小包在这不会分组 - foreach (var group in linkedOrders.Where(x => x.OrderId == order.OrderId) + foreach (var group in linkedOrders.Where(x => x.OwnerOrderId == order.OrderId) .GroupBy(x => x.SubSystemId)) { var nextEvent = @event.DeepCopy(); diff --git a/src/SJZY.Track.Domain/Dtos/Order/LinkedOrderVO.cs b/src/SJZY.Track.Domain/Dtos/Order/LinkedOrderVO.cs index c6eea835..5b81e796 100644 --- a/src/SJZY.Track.Domain/Dtos/Order/LinkedOrderVO.cs +++ b/src/SJZY.Track.Domain/Dtos/Order/LinkedOrderVO.cs @@ -2,6 +2,11 @@ public class LinkedOrderVO { + /// + /// 被关联订单id + /// + public int OwnerOrderId { get; set; } + /// /// 关联订单id /// diff --git a/src/SJZY.Track.Repository/Repositories/OrderRepository.cs b/src/SJZY.Track.Repository/Repositories/OrderRepository.cs index 5e78fc5f..93edf756 100644 --- a/src/SJZY.Track.Repository/Repositories/OrderRepository.cs +++ b/src/SJZY.Track.Repository/Repositories/OrderRepository.cs @@ -74,6 +74,7 @@ AND `a`.`IsDeleted` = 0 AND `b`.`IsDeleted` = 0;"); .Where(a => orderIds.Contains(a.OrderId)) .Select((a, b) => new LinkedOrderVO { + OwnerOrderId = a.OrderId, OrderId = b.Id, OrderNo = b.OrderNo, OrderType = b.OrderType, From c89e3f940ce660cd70749bdf550dee6e04116cb4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=B9=8F=E5=86=9B?= <2357729423@qq.com> Date: Mon, 15 Apr 2024 09:25:34 +0800 Subject: [PATCH 14/72] =?UTF-8?q?change=EF=BC=9A=E6=9C=8D=E5=8A=A1?= =?UTF-8?q?=E5=95=86=E7=A9=BA=E6=95=B0=E6=8D=AE=E7=94=A8--=E6=9B=BF?= =?UTF-8?q?=E4=BB=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../EventHandlers/TrackDeleteEventHandler.cs | 2 +- .../EventHandlers/TrackUpsertEventHandler.cs | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/SJZY.Track.Application/EventHandlers/TrackDeleteEventHandler.cs b/src/SJZY.Track.Application/EventHandlers/TrackDeleteEventHandler.cs index fc413d98..cf076a42 100644 --- a/src/SJZY.Track.Application/EventHandlers/TrackDeleteEventHandler.cs +++ b/src/SJZY.Track.Application/EventHandlers/TrackDeleteEventHandler.cs @@ -49,7 +49,7 @@ public class TrackDeleteEventHandler : ITransientDependency, ICapSubscribe nextEvent.Visited.AddRange(@event.OrderIds); nextEvent.TrackCodes = @event.TrackCodes; nextEvent.SubSystemId = group.Key; - + nextEvent.OrderIds = group.Select(x => x.OrderId).ToArray(); // 不同子系统需要做内容映射 if (@event.SubSystemId != nextEvent.SubSystemId) diff --git a/src/SJZY.Track.Application/EventHandlers/TrackUpsertEventHandler.cs b/src/SJZY.Track.Application/EventHandlers/TrackUpsertEventHandler.cs index 81d7e461..192a1b87 100644 --- a/src/SJZY.Track.Application/EventHandlers/TrackUpsertEventHandler.cs +++ b/src/SJZY.Track.Application/EventHandlers/TrackUpsertEventHandler.cs @@ -60,9 +60,9 @@ public class TrackUpsertEventHandler : ITransientDependency, ICapSubscribe }).ToArray(); nextEvent.TrackRefreshData = new TrackRefreshStruct { - ServiceProviderName = @event.TrackRefreshData.ServiceProviderName, - OriginTrackContent = @event.TrackRefreshData.OriginTrackContent, - OriginTrackData = @event.TrackRefreshData.OriginTrackData, + ServiceProviderName = @event.TrackRefreshData.ServiceProviderName ?? GlobalConst.EmptyString, + OriginTrackContent = @event.TrackRefreshData.OriginTrackContent ?? GlobalConst.EmptyString, + OriginTrackData = @event.TrackRefreshData.OriginTrackData ?? GlobalConst.EmptyString, // tips:一定要重置为false,父级订单的完成不会使得关联订单完成,关联单也必须由刷新来完成或手动设置完成!! IsCompleted = false }; From be7a3dc674a87f32f0b7f3b1589b1a64628d100e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=B9=8F=E5=86=9B?= <2357729423@qq.com> Date: Mon, 15 Apr 2024 09:58:07 +0800 Subject: [PATCH 15/72] format --- .../EventHandlers/TrackDeleteEventHandler.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/SJZY.Track.Application/EventHandlers/TrackDeleteEventHandler.cs b/src/SJZY.Track.Application/EventHandlers/TrackDeleteEventHandler.cs index cf076a42..ccd4d0d5 100644 --- a/src/SJZY.Track.Application/EventHandlers/TrackDeleteEventHandler.cs +++ b/src/SJZY.Track.Application/EventHandlers/TrackDeleteEventHandler.cs @@ -84,6 +84,7 @@ public class TrackDeleteEventHandler : ITransientDependency, ICapSubscribe new TrackChangeAfterUpdateOrderEvent { OrderIds = @event.OrderIds, + TrackCode = @event.TrackCodes.JoinAsString(","), IsDelete = true }); } From 193f66a6e6fce9b19c0a8f59c7d838c93e68659a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=B9=8F=E5=86=9B?= <2357729423@qq.com> Date: Mon, 15 Apr 2024 10:02:28 +0800 Subject: [PATCH 16/72] =?UTF-8?q?change=EF=BC=9Amod=20gitignore=20file?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.gitignore b/.gitignore index 72a52f27..d53fbc8a 100644 --- a/.gitignore +++ b/.gitignore @@ -6,6 +6,9 @@ *.user *.sln.docstates +appsettings.json + +logs/ # Build results [Dd]ebug/ [Dd]ebugPublic/ From 9df9769bd28971ba4a4c95d88b1c7172d32ff646 Mon Sep 17 00:00:00 2001 From: moyongzhen <2534173414@qq.com> Date: Mon, 15 Apr 2024 10:26:13 +0800 Subject: [PATCH 17/72] =?UTF-8?q?=E5=88=A0=E9=99=A4=E6=97=A0=E7=94=A8?= =?UTF-8?q?=E7=9A=84=E7=B1=BB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Options/GetCamsUrlOptions.cs | 17 ----------------- 1 file changed, 17 deletions(-) delete mode 100644 src/SJZY.Track.Application/Options/GetCamsUrlOptions.cs diff --git a/src/SJZY.Track.Application/Options/GetCamsUrlOptions.cs b/src/SJZY.Track.Application/Options/GetCamsUrlOptions.cs deleted file mode 100644 index 82677724..00000000 --- a/src/SJZY.Track.Application/Options/GetCamsUrlOptions.cs +++ /dev/null @@ -1,17 +0,0 @@ -using SJZY.Expand.ABP.Core; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace SJZY.Track.Application.Options -{ - public class GetCamsUrlOptions : IOptionAutoInjection - { - /// - /// 2.5URL - /// - public string? Cams25URL { get; set; } - } -} From d95c5da96b1c97ee39089a276da77f937ef610df Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=B9=8F=E5=86=9B?= <2357729423@qq.com> Date: Mon, 15 Apr 2024 11:08:04 +0800 Subject: [PATCH 18/72] =?UTF-8?q?fix=EF=BC=9A=E8=B7=A8=E5=AD=90=E7=B3=BB?= =?UTF-8?q?=E7=BB=9F=E6=98=A0=E5=B0=84=E8=B5=8B=E5=80=BC=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../EventHandlers/TrackUpsertEventHandler.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/SJZY.Track.Application/EventHandlers/TrackUpsertEventHandler.cs b/src/SJZY.Track.Application/EventHandlers/TrackUpsertEventHandler.cs index 192a1b87..278667aa 100644 --- a/src/SJZY.Track.Application/EventHandlers/TrackUpsertEventHandler.cs +++ b/src/SJZY.Track.Application/EventHandlers/TrackUpsertEventHandler.cs @@ -80,7 +80,7 @@ public class TrackUpsertEventHandler : ITransientDependency, ICapSubscribe return; } - @event.TrackCode = mapCode; + nextEvent.TrackCode = mapCode; } await _capPublisher.PublishAsync(GlobalConst.TrackUpsertSubscribe, nextEvent); From a28a9ac5dbe6ec5a8b20ef61d0a2e341c2a0dda4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=B9=8F=E5=86=9B?= <2357729423@qq.com> Date: Mon, 15 Apr 2024 14:09:12 +0800 Subject: [PATCH 19/72] =?UTF-8?q?change=EF=BC=9A=E8=BD=A8=E8=BF=B9?= =?UTF-8?q?=E4=BB=A3=E7=A0=81=E4=B8=BA--=E7=9A=84=E4=B8=8D=E5=8F=82?= =?UTF-8?q?=E4=B8=8E=E8=AE=A1=E7=AE=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../EventHandlers/TrackUpsertEventHandler.cs | 12 +++---- .../Repositories/TrackDetailsRepository.cs | 31 ++++++++++++------- 2 files changed, 25 insertions(+), 18 deletions(-) diff --git a/src/SJZY.Track.Application/EventHandlers/TrackUpsertEventHandler.cs b/src/SJZY.Track.Application/EventHandlers/TrackUpsertEventHandler.cs index 278667aa..277ad96b 100644 --- a/src/SJZY.Track.Application/EventHandlers/TrackUpsertEventHandler.cs +++ b/src/SJZY.Track.Application/EventHandlers/TrackUpsertEventHandler.cs @@ -60,9 +60,9 @@ public class TrackUpsertEventHandler : ITransientDependency, ICapSubscribe }).ToArray(); nextEvent.TrackRefreshData = new TrackRefreshStruct { - ServiceProviderName = @event.TrackRefreshData.ServiceProviderName ?? GlobalConst.EmptyString, - OriginTrackContent = @event.TrackRefreshData.OriginTrackContent ?? GlobalConst.EmptyString, - OriginTrackData = @event.TrackRefreshData.OriginTrackData ?? GlobalConst.EmptyString, + ServiceProviderName = @event.TrackRefreshData.ServiceProviderName, + OriginTrackContent = @event.TrackRefreshData.OriginTrackContent, + OriginTrackData = @event.TrackRefreshData.OriginTrackData, // tips:一定要重置为false,父级订单的完成不会使得关联订单完成,关联单也必须由刷新来完成或手动设置完成!! IsCompleted = false }; @@ -118,9 +118,9 @@ public class TrackUpsertEventHandler : ITransientDependency, ICapSubscribe TrackPlace = @event.TrackPlace, TrackTime = @event.TrackTime, TrackTimeZone = @event.TrackTimeZone, - ServiceProviderName = @event.TrackRefreshData.ServiceProviderName, - OriginTrackContent = @event.TrackRefreshData.OriginTrackContent, - OriginTrackData = @event.TrackRefreshData.OriginTrackData, + ServiceProviderName = @event.TrackRefreshData.ServiceProviderName ?? GlobalConst.EmptyString, + OriginTrackContent = @event.TrackRefreshData.OriginTrackContent ?? GlobalConst.EmptyString, + OriginTrackData = @event.TrackRefreshData.OriginTrackData ?? GlobalConst.EmptyString, IsCanDelete = false, CreateUser = @event.OperationMan ?? GlobalConst.SystemUser, CreateTime = DateTime.Now diff --git a/src/SJZY.Track.Repository/Repositories/TrackDetailsRepository.cs b/src/SJZY.Track.Repository/Repositories/TrackDetailsRepository.cs index b692a3f2..d1345e90 100644 --- a/src/SJZY.Track.Repository/Repositories/TrackDetailsRepository.cs +++ b/src/SJZY.Track.Repository/Repositories/TrackDetailsRepository.cs @@ -2,7 +2,6 @@ using Nest; using SJZY.Expand.ABP.Core.Logger; using SJZY.Expand.ElasticSearch.Services; using SJZY.Track.Domain.Aggregates.TrackDetailsAggregate; -using SJZY.Track.Domain.Consts; using SJZY.Track.Domain.Dtos.TrackDetails; namespace SJZY.Track.Repository.Repositories; @@ -18,12 +17,13 @@ internal class TrackDetailsRepository : ElasticSearchContextAbstract(s => s .Source() - .Query(q => - q.Terms(t => t - .Field(f => f.OrderId) - .Terms(orderIds)) - && q.Term(f => f.TrackCode.Suffix("keyword"), trackCode) - && q.Term(f => f.ServiceProviderName.Suffix("keyword"), GlobalConst.EmptyString) + .Query(q => q + .Bool(b => b + .Must( + mu => mu.Terms(t => t.Field(f => f.OrderId).Terms(orderIds)), + mu => mu.Term(t => t.Field(f => f.TrackCode.Suffix("keyword")).Value(trackCode)) + ) + ) ) ); @@ -41,11 +41,18 @@ internal class TrackDetailsRepository : ElasticSearchContextAbstract f.TrackTimeZone) .Field(f => f.OrderId) )) - .Query(q => - q.Terms(t => t - .Field(f => f.OrderId) - .Terms(orderIds)) - && q.Term(f => f.ServiceProviderName.Suffix("keyword"), GlobalConst.EmptyString) + .Query(q => q + .Bool(b => b + .Must( + mu => mu.Terms(t => t.Field(f => f.OrderId).Terms(orderIds)) + ) + .MustNot(mn => mn + .Term(t => t + .Field(f => f.TrackCode.Suffix("keyword")) + .Value("--") + ) + ) + ) ) .Sort(s => s.Field(f => f.TrackTime, SortOrder.Descending)) .Size(1) From 0fb2690efdfa4669d06f7050f724e4c0f3413284 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=B9=8F=E5=86=9B?= <2357729423@qq.com> Date: Mon, 15 Apr 2024 14:47:52 +0800 Subject: [PATCH 20/72] =?UTF-8?q?opt=EF=BC=9A=E5=8E=8B=E7=BC=A9=E8=AE=A2?= =?UTF-8?q?=E5=8D=95=E4=B8=BB=E8=A1=A8=E6=9B=B4=E6=96=B0=E4=BA=8B=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../EventHandlers/TrackUpsertEventHandler.cs | 30 ++++++++++--------- 1 file changed, 16 insertions(+), 14 deletions(-) diff --git a/src/SJZY.Track.Application/EventHandlers/TrackUpsertEventHandler.cs b/src/SJZY.Track.Application/EventHandlers/TrackUpsertEventHandler.cs index 277ad96b..661848b9 100644 --- a/src/SJZY.Track.Application/EventHandlers/TrackUpsertEventHandler.cs +++ b/src/SJZY.Track.Application/EventHandlers/TrackUpsertEventHandler.cs @@ -170,22 +170,24 @@ public class TrackUpsertEventHandler : ITransientDependency, ICapSubscribe }; await _capPublisher.PublishAsync(GlobalConst.TrackPushSubscribe, trackPushEvent); - - // step3、触发订单主表更新事件(异步) - await _capPublisher.PublishAsync(GlobalConst.TrackChangeAfterUpdateOrderSubscribe, - new TrackChangeAfterUpdateOrderEvent - { - OrderIds = new[] { track.OrderId }, - IsCompleted = @event.TrackRefreshData.IsCompleted, - TrackCode = track.TrackCode, - TrackContent = track.TrackContent, - TrackEnContent = track.TrackEnContent, - TrackPlace = track.TrackPlace, - TrackTime = track.TrackTime, - TrackTimeZone = track.TrackTimeZone - }); } + var firstTrack = insertTracks.FirstOrDefault(); + if (firstTrack == null) return; + // step3、触发订单主表更新事件(异步) + await _capPublisher.PublishAsync(GlobalConst.TrackChangeAfterUpdateOrderSubscribe, + new TrackChangeAfterUpdateOrderEvent + { + OrderIds = orderIds, + IsCompleted = @event.TrackRefreshData.IsCompleted, + TrackCode = firstTrack.TrackCode, + TrackContent = firstTrack.TrackContent, + TrackEnContent = firstTrack.TrackEnContent, + TrackPlace = firstTrack.TrackPlace, + TrackTime = firstTrack.TrackTime, + TrackTimeZone = firstTrack.TrackTimeZone + }); + await _trackDetailsRepository.AddManyAsync(insertTracks); } } \ No newline at end of file From 932ca3d1c553647c6cdc530872bc86ab25f1f2e1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=B9=8F=E5=86=9B?= <2357729423@qq.com> Date: Mon, 15 Apr 2024 19:02:01 +0800 Subject: [PATCH 21/72] opt --- .../TrackChangeAfterUpdateOrderEvent.cs | 2 +- .../Events/TrackPushEvent.cs | 5 ++++ .../EventHandlers/TrackPushEventHandler.cs | 19 ++++++++++-- .../EventHandlers/TrackUpsertEventHandler.cs | 10 +++---- .../ProvideServices/TrackPushService.cs | 14 ++++----- .../ITrackDetailsRepository.cs | 2 -- src/SJZY.Track.Domain/Queries/IBasicQuery.cs | 3 ++ .../Queries/BasicQuery.cs | 6 ++++ .../Repositories/TrackDetailsRepository.cs | 29 ------------------- 9 files changed, 43 insertions(+), 47 deletions(-) diff --git a/src/SJZY.Track.Application.Contract/Events/TrackChangeAfterUpdateOrderEvent.cs b/src/SJZY.Track.Application.Contract/Events/TrackChangeAfterUpdateOrderEvent.cs index 544c98b1..47a507d2 100644 --- a/src/SJZY.Track.Application.Contract/Events/TrackChangeAfterUpdateOrderEvent.cs +++ b/src/SJZY.Track.Application.Contract/Events/TrackChangeAfterUpdateOrderEvent.cs @@ -5,7 +5,7 @@ public class TrackChangeAfterUpdateOrderEvent /// /// 订单Id /// - public int[] OrderIds { get; set; } + public int[] OrderIds { get; set; } = null!; /// /// 是否删除引起的更新 diff --git a/src/SJZY.Track.Application.Contract/Events/TrackPushEvent.cs b/src/SJZY.Track.Application.Contract/Events/TrackPushEvent.cs index 9d98dcf1..43156556 100644 --- a/src/SJZY.Track.Application.Contract/Events/TrackPushEvent.cs +++ b/src/SJZY.Track.Application.Contract/Events/TrackPushEvent.cs @@ -2,6 +2,11 @@ public class TrackPushEvent { + /// + /// 重试次数 + /// + public int RetryNum { get; set; } + /// /// 操作类型 /// diff --git a/src/SJZY.Track.Application/EventHandlers/TrackPushEventHandler.cs b/src/SJZY.Track.Application/EventHandlers/TrackPushEventHandler.cs index 65e60991..1334e3ce 100644 --- a/src/SJZY.Track.Application/EventHandlers/TrackPushEventHandler.cs +++ b/src/SJZY.Track.Application/EventHandlers/TrackPushEventHandler.cs @@ -20,15 +20,17 @@ public class TrackPushEventHandler : ITransientDependency, ICapSubscribe private readonly ITrackPushRecordsRepository _trackPushRecordsRepository; private readonly IOrderRepository _orderRepository; private readonly ITrackPushCacheService _trackPushCacheService; + private readonly ICapPublisher _capPublisher; public TrackPushEventHandler(IHttpClientProxy httpClientProxy, ITrackPushRecordsRepository trackPushRecordsRepository, - IOrderRepository orderRepository, ITrackPushCacheService trackPushCacheService) + IOrderRepository orderRepository, ITrackPushCacheService trackPushCacheService, ICapPublisher capPublisher) { _httpClientProxy = httpClientProxy; _trackPushRecordsRepository = trackPushRecordsRepository; _orderRepository = orderRepository; _trackPushCacheService = trackPushCacheService; + _capPublisher = capPublisher; } [CapSubscribe(GlobalConst.TrackPushSubscribe, Group = GlobalConst.TrackPushSubscribe)] @@ -103,6 +105,19 @@ public class TrackPushEventHandler : ITransientDependency, ICapSubscribe throw new ArgumentOutOfRangeException(); } + if (!log.IsSuccess) + { + if (@event.RetryNum < 3) + { + // 1, 2, 4min + await _capPublisher.PublishDelayAsync( + TimeSpan.FromSeconds((1 << @event.RetryNum) * 60), + GlobalConst.TrackPushSubscribe, @event); + @event.RetryNum++; + return; + } + } + // 往es 写推送日志 await _trackPushRecordsRepository.AddAsync(log); @@ -169,7 +184,7 @@ public class TrackPushEventHandler : ITransientDependency, ICapSubscribe Extra = config.ExpandFieldsValue }; - var body = new TrackPushInput() + var body = new TrackPushInput { OrderNo = @event.OrderNo, }; diff --git a/src/SJZY.Track.Application/EventHandlers/TrackUpsertEventHandler.cs b/src/SJZY.Track.Application/EventHandlers/TrackUpsertEventHandler.cs index 661848b9..8059fcf6 100644 --- a/src/SJZY.Track.Application/EventHandlers/TrackUpsertEventHandler.cs +++ b/src/SJZY.Track.Application/EventHandlers/TrackUpsertEventHandler.cs @@ -105,7 +105,6 @@ public class TrackUpsertEventHandler : ITransientDependency, ICapSubscribe if (track != null && @event.IsAdd!.Value) return; // 存在不让创建 } - // step1、upsert es轨迹 if (track == default) { track = new TrackDetailsIndex @@ -159,8 +158,7 @@ public class TrackUpsertEventHandler : ITransientDependency, ICapSubscribe var trackPushEvent = new TrackPushEvent { OptionType = track.Id.IsNullOrWhiteSpace() ? OptionType.新增 : OptionType.修改, - OrderId = track.OrderId, - OrderNo = track.OrderNo, + OrderId = order.OrderId, TrackStatus = track.TrackStatus, TrackCode = track.TrackCode, TrackContent = track.TrackContent, @@ -174,6 +172,10 @@ public class TrackUpsertEventHandler : ITransientDependency, ICapSubscribe var firstTrack = insertTracks.FirstOrDefault(); if (firstTrack == null) return; + + // step1、upsert es轨迹 + await _trackDetailsRepository.AddManyAsync(insertTracks); + // step3、触发订单主表更新事件(异步) await _capPublisher.PublishAsync(GlobalConst.TrackChangeAfterUpdateOrderSubscribe, new TrackChangeAfterUpdateOrderEvent @@ -187,7 +189,5 @@ public class TrackUpsertEventHandler : ITransientDependency, ICapSubscribe TrackTime = firstTrack.TrackTime, TrackTimeZone = firstTrack.TrackTimeZone }); - - await _trackDetailsRepository.AddManyAsync(insertTracks); } } \ 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 ac2d5277..4a0ef260 100644 --- a/src/SJZY.Track.Application/Services/ProvideServices/TrackPushService.cs +++ b/src/SJZY.Track.Application/Services/ProvideServices/TrackPushService.cs @@ -43,18 +43,16 @@ public class TrackPushService : ApplicationService { input.OrderNos = input.OrderNos.Where(x => !x.IsNullOrWhiteSpace()).Distinct().ToList(); // 单号去重、去空 - var orders = await _orderRepository.GetListAsync(x => - x.OrderType == input.OrderType && input.OrderNos.Contains(x.OrderNo), x => new - { - x.Id, x.OrderNo, x.OrderType, x.SubSystemId, x.CustomId - }); + var orderIds = await _orderRepository.GetArrayAsync(x => + x.OrderType == input.OrderType && input.OrderNos.Contains(x.OrderNo), x => x.Id); - if (orders.Count == 0) + if (!orderIds.Any()) { - throw new BusinessException(message: "一个推送配置都不存在"); + throw new BusinessException(message: "一个订单都不存在"); } - var tracks = await _trackDetailsRepository.GetListAsync(input.OrderType, input.OrderNos, input.TrackCode); + var tracks = await _trackDetailsRepository.GetListAsync(orderIds, input.TrackCode); + tracks = tracks.DistinctBy(x => x.OrderId).ToList(); if (tracks.Count == 0) { diff --git a/src/SJZY.Track.Domain/Aggregates/TrackDetailsAggregate/ITrackDetailsRepository.cs b/src/SJZY.Track.Domain/Aggregates/TrackDetailsAggregate/ITrackDetailsRepository.cs index d32ed593..b35145a4 100644 --- a/src/SJZY.Track.Domain/Aggregates/TrackDetailsAggregate/ITrackDetailsRepository.cs +++ b/src/SJZY.Track.Domain/Aggregates/TrackDetailsAggregate/ITrackDetailsRepository.cs @@ -19,8 +19,6 @@ public interface ITrackDetailsRepository Task> GetListAsync(int orderType, List orderNos); - Task> GetListAsync(int orderType, List orderNos, string trackCode); - Task<(List list, long total)> GetListAsync(TrackDetailsQueryInput input); Task> GetListAsync(int orderId); diff --git a/src/SJZY.Track.Domain/Queries/IBasicQuery.cs b/src/SJZY.Track.Domain/Queries/IBasicQuery.cs index 460e58be..d2bddef3 100644 --- a/src/SJZY.Track.Domain/Queries/IBasicQuery.cs +++ b/src/SJZY.Track.Domain/Queries/IBasicQuery.cs @@ -22,6 +22,9 @@ public interface IBasicQuery where T : IEntity Task> GetListAsync(Expression> whereExpression, Expression> resultExpression); + Task GetArrayAsync(Expression> whereExpression, + Expression> resultExpression); + /// /// count /// diff --git a/src/SJZY.Track.Repository/Queries/BasicQuery.cs b/src/SJZY.Track.Repository/Queries/BasicQuery.cs index d8003be8..23a3abf1 100644 --- a/src/SJZY.Track.Repository/Queries/BasicQuery.cs +++ b/src/SJZY.Track.Repository/Queries/BasicQuery.cs @@ -24,4 +24,10 @@ public class BasicQuery : SimpleClient, IBasicQuery where T : class, IE { return await Context.Queryable().Where(whereExpression).Select(resultExpression).ToListAsync(); } + + public async Task GetArrayAsync(Expression> whereExpression, + Expression> resultExpression) + { + return await Context.Queryable().Where(whereExpression).Select(resultExpression).ToArrayAsync(); + } } \ No newline at end of file diff --git a/src/SJZY.Track.Repository/Repositories/TrackDetailsRepository.cs b/src/SJZY.Track.Repository/Repositories/TrackDetailsRepository.cs index d1345e90..61950329 100644 --- a/src/SJZY.Track.Repository/Repositories/TrackDetailsRepository.cs +++ b/src/SJZY.Track.Repository/Repositories/TrackDetailsRepository.cs @@ -104,8 +104,6 @@ internal class TrackDetailsRepository : ElasticSearchContextAbstract tracks) { - if (!tracks.Any()) return; - // 按天写入es var r = await Context.IndexManyAsync(tracks, tracks.First().IndexName); @@ -141,33 +139,6 @@ internal class TrackDetailsRepository : ElasticSearchContextAbstract> GetListAsync(int orderType, List orderNos, string trackCode) - { - if (orderNos.Count < 1) return new List(); - - var data = await Context.SearchAsync(x => x - .Source(s => s.Includes(fd => fd - .Field(f => f.OrderId) - .Field(f => f.OrderNo) - .Field(f => f.TrackStatus) - .Field(f => f.TrackCode) - .Field(f => f.TrackContent) - .Field(f => f.TrackPlace) - .Field(f => f.TrackTime) - .Field(f => f.TrackTimeZone) - )) - .Query(q => - q.Terms(t => t - .Field(f => f.OrderNo.Suffix("keyword")) - .Terms(orderNos)) - && q.Term(f => f.OrderType, orderType) - && q.Term(f => f.TrackCode.Suffix("keyword"), trackCode) - ) - ); - - return data.Documents.ToList(); - } - public async Task> GetListAsync(int orderId) { var data = await Context.SearchAsync(x => x From ad563dda97d4c901e89b1934e043a4c92b2ba281 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=B9=8F=E5=86=9B?= <2357729423@qq.com> Date: Mon, 15 Apr 2024 19:14:41 +0800 Subject: [PATCH 22/72] =?UTF-8?q?opt=EF=BC=9A=E5=88=A0=E4=B8=8D=E5=81=9A?= =?UTF-8?q?=E5=B9=82=E7=AD=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/SJZY.Track.Application/EventHandlers/CAPFilter.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/SJZY.Track.Application/EventHandlers/CAPFilter.cs b/src/SJZY.Track.Application/EventHandlers/CAPFilter.cs index 06bdeca3..20d168f2 100644 --- a/src/SJZY.Track.Application/EventHandlers/CAPFilter.cs +++ b/src/SJZY.Track.Application/EventHandlers/CAPFilter.cs @@ -20,9 +20,9 @@ public class CapFilter : SubscribeFilter { context.DeliverMessage.Headers["sjzy-receive-time"] = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss fff"); - // 轨迹增删改要做幂等 + // 轨迹增改要做幂等 if (!context.DeliverMessage.Headers["cap-msg-name"] - .IsIn(GlobalConst.TrackUpsertSubscribe, GlobalConst.TrackDeleteSubscribe)) + .IsIn(GlobalConst.TrackUpsertSubscribe)) return Task.CompletedTask; // 本地调试不做幂等 @@ -44,7 +44,7 @@ public class CapFilter : SubscribeFilter throw new BusinessException(ErrorCode, $"检测到重复消费,消费参数:{argumentJsonStr}"); RedisHelper.Client.Set($"CapExcuteFilter:{hash}", 60 * 10, - TimeSpan.FromHours(1).Seconds); // 1h内不允许一模一样的参数重复消费 + TimeSpan.FromMinutes(5).Seconds); } } From 64ab6757a99d873be02f79d9309f9e131b4bc88e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=B9=8F=E5=86=9B?= <2357729423@qq.com> Date: Tue, 16 Apr 2024 11:47:21 +0800 Subject: [PATCH 23/72] opt --- .../TrackChangeAfterUpdateOrderEvent.cs | 5 -- .../EventHandlers/CAPFilter.cs | 11 ++-- ...TrackChangeAfterUpdateOrderEventHandler.cs | 54 +++++-------------- .../EventHandlers/TrackDeleteEventHandler.cs | 53 ++++++++++++++---- .../ITrackDetailsRepository.cs | 11 ++-- .../Repositories/TrackDetailsRepository.cs | 37 ++++++++----- 6 files changed, 89 insertions(+), 82 deletions(-) diff --git a/src/SJZY.Track.Application.Contract/Events/TrackChangeAfterUpdateOrderEvent.cs b/src/SJZY.Track.Application.Contract/Events/TrackChangeAfterUpdateOrderEvent.cs index 47a507d2..3fd35deb 100644 --- a/src/SJZY.Track.Application.Contract/Events/TrackChangeAfterUpdateOrderEvent.cs +++ b/src/SJZY.Track.Application.Contract/Events/TrackChangeAfterUpdateOrderEvent.cs @@ -7,11 +7,6 @@ public class TrackChangeAfterUpdateOrderEvent /// public int[] OrderIds { get; set; } = null!; - /// - /// 是否删除引起的更新 - /// - public bool IsDelete { get; set; } - /// /// 这条轨迹是否意味着完成(只有刷新会设为true) /// diff --git a/src/SJZY.Track.Application/EventHandlers/CAPFilter.cs b/src/SJZY.Track.Application/EventHandlers/CAPFilter.cs index 20d168f2..94cbc37d 100644 --- a/src/SJZY.Track.Application/EventHandlers/CAPFilter.cs +++ b/src/SJZY.Track.Application/EventHandlers/CAPFilter.cs @@ -21,8 +21,7 @@ public class CapFilter : SubscribeFilter context.DeliverMessage.Headers["sjzy-receive-time"] = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss fff"); // 轨迹增改要做幂等 - if (!context.DeliverMessage.Headers["cap-msg-name"] - .IsIn(GlobalConst.TrackUpsertSubscribe)) + if (!context.DeliverMessage.Headers["cap-msg-name"].IsIn(GlobalConst.TrackUpsertSubscribe)) return Task.CompletedTask; // 本地调试不做幂等 @@ -76,11 +75,13 @@ public class CapFilter : SubscribeFilter /// public override Task OnSubscribeExceptionAsync(ExceptionContext context) { - context.ExceptionHandled = true; context.DeliverMessage.Headers.TryGetValue("cap-msg-id", out var messageId); if (context.Exception is BusinessException ex && ex.Code == ErrorCode) + { + context.ExceptionHandled = true; // 幂等不做重试 LogHelper.Warn(ex.ToString()); + } else LogHelper.Error($"cap-msg-id:{messageId}\n{context.Exception}"); @@ -101,14 +102,14 @@ public class CapFilter : SubscribeFilter var parsedDate = DateTime.ParseExact(receiveTime, "yyyy-MM-dd HH:mm:ss fff", CultureInfo.InvariantCulture); var useTime = DateTime.Now - parsedDate; - if (useTime.Minutes > 20) + if (useTime.Minutes > 10) { var log = $@" |-消息编号:{messageId} |-消费者名:{receiveName} |-跳过执行:{(isFromExecptionFliter ? "是" : "否")} |-执行时间:{receiveTime} -|-消费耗时:{useTime.Milliseconds}毫秒 +|-消费耗时:{useTime.Seconds}秒 |-请求参数:{arguments}"; LogHelper.Error(log); } diff --git a/src/SJZY.Track.Application/EventHandlers/TrackChangeAfterUpdateOrderEventHandler.cs b/src/SJZY.Track.Application/EventHandlers/TrackChangeAfterUpdateOrderEventHandler.cs index 25e74d44..3f586b15 100644 --- a/src/SJZY.Track.Application/EventHandlers/TrackChangeAfterUpdateOrderEventHandler.cs +++ b/src/SJZY.Track.Application/EventHandlers/TrackChangeAfterUpdateOrderEventHandler.cs @@ -36,53 +36,25 @@ public class TrackChangeAfterUpdateOrderEventHandler : ITransientDependency, ICa if (orders.Count == 0) return; - // todo:delete可能发生回退,直接去es查最新轨迹,但是可能es还没有刷盘,导致回退失效,可以考虑加个定时任务弥补 - if (@event.IsDelete) + foreach (var order in orders) { - foreach (var order in orders) + if (order.LatestTrackTime != null && + @event.TrackTime.Subtract(TimeSpan.FromHours(@event.TrackTimeZone)) < + order.LatestTrackTime.Value.Subtract(TimeSpan.FromHours(order.LatestTrackTimeZone ?? 0))) { - var tracks = await _trackDetailsRepository.GetListAsync(@event.OrderIds); - - var track = tracks.Where(x => x.OrderId == order.Id).MaxBy(x => x.TrackTime); - // 删除全部轨迹导致的重置行为 - if (track == default) - { - if (order.LatestTrackTime == null) return; - - // tips:订单是支持从已完成态到未完成态的 - order.ResetTrackInfo(); - } - else - { - // 删除引发的回退更新 - order.IsCompleted = @event.IsCompleted; - order.LatestTrackContent = track.TrackContent; - order.LatestTrackEnContent = track.TrackEnContent; - order.LatestTrackPlace = track.TrackPlace; - order.LatestTrackTime = track.TrackTime; - order.LatestTrackTimeZone = track.TrackTimeZone; - } + continue; } - } - else // upsert可以直接计算 - { - foreach (var order in orders) - { - if (order.LatestTrackTime != null && - @event.TrackTime.Subtract(TimeSpan.FromHours(@event.TrackTimeZone)) < - order.LatestTrackTime.Value.Subtract(TimeSpan.FromHours(order.LatestTrackTimeZone ?? 0))) - { - continue; - } - // upsert引发的更新 + if (!order.IsCompleted) + { order.IsCompleted = @event.IsCompleted; - order.LatestTrackContent = @event.TrackContent; - order.LatestTrackEnContent = @event.TrackEnContent; - order.LatestTrackPlace = @event.TrackPlace; - order.LatestTrackTime = @event.TrackTime; - order.LatestTrackTimeZone = @event.TrackTimeZone; } + + order.LatestTrackContent = @event.TrackContent; + order.LatestTrackEnContent = @event.TrackEnContent; + order.LatestTrackPlace = @event.TrackPlace; + order.LatestTrackTime = @event.TrackTime; + order.LatestTrackTimeZone = @event.TrackTimeZone; } await _orderRepository.UpdateRangeAsync(orders, x => new diff --git a/src/SJZY.Track.Application/EventHandlers/TrackDeleteEventHandler.cs b/src/SJZY.Track.Application/EventHandlers/TrackDeleteEventHandler.cs index ccd4d0d5..e9ed2dec 100644 --- a/src/SJZY.Track.Application/EventHandlers/TrackDeleteEventHandler.cs +++ b/src/SJZY.Track.Application/EventHandlers/TrackDeleteEventHandler.cs @@ -74,19 +74,50 @@ public class TrackDeleteEventHandler : ITransientDependency, ICapSubscribe private async Task DeleteTrackAsync(TrackDeleteEvent @event) { // 删除轨迹(删的是同子系统下的单,所以code是统一的) - var isOk = await _trackDetailsRepository.DeleteTrackAsync(@event.OrderIds, @event.TrackCodes); + var tracks = await _trackDetailsRepository.GetLatestListAsync(@event.OrderIds, @event.TrackCodes); - if (isOk) + await _trackDetailsRepository.DeleteTrackAsync(@event.OrderIds, @event.TrackCodes); + + var orders = await _orderRepository.GetListAsync(x => @event.OrderIds.Contains(x.Id), + x => new OrderEntity + { + Id = x.Id, + LatestTrackContent = x.LatestTrackContent, + LatestTrackEnContent = x.LatestTrackEnContent, + LatestTrackPlace = x.LatestTrackPlace, + LatestTrackTime = x.LatestTrackTime, + LatestTrackTimeZone = x.LatestTrackTimeZone, + }); + + if (orders.Count == 0) return; + + foreach (var order in orders) { - // 触发订单主表更新事件 - await _capPublisher.PublishDelayAsync(TimeSpan.FromSeconds(3), - GlobalConst.TrackChangeAfterUpdateOrderSubscribe, - new TrackChangeAfterUpdateOrderEvent - { - OrderIds = @event.OrderIds, - TrackCode = @event.TrackCodes.JoinAsString(","), - IsDelete = true - }); + var track = tracks.FirstOrDefault(x => x.OrderId == order.Id); + + // 删除全部轨迹导致的重置行为 + if (track == default) + { + if (order.LatestTrackTime == null) return; + + // tips:订单是支持从已完成态到未完成态的 + order.ResetTrackInfo(); + } + else + { + // 删除引发的回退更新 + order.LatestTrackContent = track.TrackContent; + order.LatestTrackEnContent = track.TrackEnContent; + order.LatestTrackPlace = track.TrackPlace; + order.LatestTrackTime = track.TrackTime; + order.LatestTrackTimeZone = track.TrackTimeZone; + } } + + await _orderRepository.UpdateRangeAsync(orders, x => new + { + x.LatestTrackContent, x.LatestTrackEnContent, x.LatestTrackPlace, x.LatestTrackTime, + x.LatestTrackTimeZone + }); } } \ No newline at end of file diff --git a/src/SJZY.Track.Domain/Aggregates/TrackDetailsAggregate/ITrackDetailsRepository.cs b/src/SJZY.Track.Domain/Aggregates/TrackDetailsAggregate/ITrackDetailsRepository.cs index b35145a4..f44f298f 100644 --- a/src/SJZY.Track.Domain/Aggregates/TrackDetailsAggregate/ITrackDetailsRepository.cs +++ b/src/SJZY.Track.Domain/Aggregates/TrackDetailsAggregate/ITrackDetailsRepository.cs @@ -6,7 +6,8 @@ public interface ITrackDetailsRepository { Task> GetListAsync(int[] orderIds, string trackCode); - Task> GetListAsync(int[] orderIds); + Task> GetLatestListAsync(int[] eventOrderIds, List trackCodes); + Task AnyAsync(int orderId, DateTime trackTime); @@ -22,11 +23,5 @@ public interface ITrackDetailsRepository Task<(List list, long total)> GetListAsync(TrackDetailsQueryInput input); Task> GetListAsync(int orderId); - /// - /// 删除轨迹 - /// - /// - /// - /// - Task DeleteTrackAsync(int[] orderIds, List trackCodes); + Task DeleteTrackAsync(int[] orderIds, List trackCodes); } \ No newline at end of file diff --git a/src/SJZY.Track.Repository/Repositories/TrackDetailsRepository.cs b/src/SJZY.Track.Repository/Repositories/TrackDetailsRepository.cs index 61950329..75ecc85a 100644 --- a/src/SJZY.Track.Repository/Repositories/TrackDetailsRepository.cs +++ b/src/SJZY.Track.Repository/Repositories/TrackDetailsRepository.cs @@ -1,7 +1,7 @@ using Nest; -using SJZY.Expand.ABP.Core.Logger; using SJZY.Expand.ElasticSearch.Services; using SJZY.Track.Domain.Aggregates.TrackDetailsAggregate; +using SJZY.Track.Domain.Consts; using SJZY.Track.Domain.Dtos.TrackDetails; namespace SJZY.Track.Repository.Repositories; @@ -30,8 +30,10 @@ internal class TrackDetailsRepository : ElasticSearchContextAbstract> GetListAsync(int[] orderIds) + public async Task> GetLatestListAsync(int[] orderIds, List trackCodes) { + var excludeTrackCodes = trackCodes.ToList(); + excludeTrackCodes.Add(GlobalConst.EmptyString); var data = await Context.SearchAsync(x => x .Source(s => s.Includes(fd => fd .Field(f => f.TrackEnContent) @@ -40,6 +42,7 @@ internal class TrackDetailsRepository : ElasticSearchContextAbstract f.TrackTime) .Field(f => f.TrackTimeZone) .Field(f => f.OrderId) + .Field(f => f.TrackCode) )) .Query(q => q .Bool(b => b @@ -47,15 +50,27 @@ internal class TrackDetailsRepository : ElasticSearchContextAbstract mu.Terms(t => t.Field(f => f.OrderId).Terms(orderIds)) ) .MustNot(mn => mn - .Term(t => t + .Terms(t => t .Field(f => f.TrackCode.Suffix("keyword")) - .Value("--") + .Terms(excludeTrackCodes) + ) + ) + ) + ) + .Size(0) + .Aggregations(a => a + .Terms("orders", t => t + .Field(f => f.OrderId) + .Aggregations(aa => aa + .TopHits("latest_track", th => th + .Size(1) + .Sort(so => so + .Field(f => f.ZeroTrackTime, SortOrder.Descending) + ) ) ) ) ) - .Sort(s => s.Field(f => f.TrackTime, SortOrder.Descending)) - .Size(1) ); return data.Documents.ToList(); @@ -98,7 +113,7 @@ internal class TrackDetailsRepository : ElasticSearchContextAbstract t.OrderId, orderId) ) .Size(1000) - .Sort(s => s.Field(f => f.TrackTime, SortOrder.Descending))); + .Sort(s => s.Field(f => f.ZeroTrackTime, SortOrder.Descending))); return data.Documents.ToList(); } - public async Task DeleteTrackAsync(int[] orderIds, List trackCodes) + public async Task DeleteTrackAsync(int[] orderIds, List trackCodes) { var r = await Context.DeleteByQueryAsync(x => x .Query( @@ -164,8 +179,6 @@ internal class TrackDetailsRepository : ElasticSearchContextAbstract 0; } public async Task<(List list, long total)> GetListAsync(TrackDetailsQueryInput input) From 7769d6cf8074f22a2091f88936b990ce40c30a0b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=B9=8F=E5=86=9B?= <2357729423@qq.com> Date: Tue, 16 Apr 2024 14:33:29 +0800 Subject: [PATCH 24/72] =?UTF-8?q?fix=EF=BC=9A=E8=BD=A8=E8=BF=B9=E5=88=B7?= =?UTF-8?q?=E6=96=B0=E5=88=B0=E6=9C=8D=E5=8A=A1=E5=95=86=E8=BD=A8=E8=BF=B9?= =?UTF-8?q?=E5=8D=95=E6=9D=A1=E5=85=A5=E5=BA=93?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../TrackInsertForNotMappedEventHandler.cs | 4 ++-- .../EventHandlers/TrackUpsertEventHandler.cs | 1 - .../ITrackDetailsRepository.cs | 1 + .../Repositories/TrackDetailsRepository.cs | 18 +++++++++++++++++- 4 files changed, 20 insertions(+), 4 deletions(-) diff --git a/src/SJZY.Track.Application/EventHandlers/TrackInsertForNotMappedEventHandler.cs b/src/SJZY.Track.Application/EventHandlers/TrackInsertForNotMappedEventHandler.cs index a0df5114..9bd76c5e 100644 --- a/src/SJZY.Track.Application/EventHandlers/TrackInsertForNotMappedEventHandler.cs +++ b/src/SJZY.Track.Application/EventHandlers/TrackInsertForNotMappedEventHandler.cs @@ -20,7 +20,7 @@ public class TrackInsertForNotMappedEventHandler : ITransientDependency, ICapSub { if (await _trackDetailsRepository.AnyAsync(@event.OrderId, @event.TrackTime)) { - return; // 无法映射的轨迹只做新增 + return; } // 新增服务商轨迹到es @@ -45,6 +45,6 @@ public class TrackInsertForNotMappedEventHandler : ITransientDependency, ICapSub track.TrackEnContent = GlobalConst.EmptyString; track.ZeroTrackTime = track.TrackTime.Subtract(TimeSpan.FromHours(track.TrackTimeZone)); - await _trackDetailsRepository.UpdateAsync(track); + await _trackDetailsRepository.AddAsync(track); } } \ No newline at end of file diff --git a/src/SJZY.Track.Application/EventHandlers/TrackUpsertEventHandler.cs b/src/SJZY.Track.Application/EventHandlers/TrackUpsertEventHandler.cs index 8059fcf6..8fdc61bc 100644 --- a/src/SJZY.Track.Application/EventHandlers/TrackUpsertEventHandler.cs +++ b/src/SJZY.Track.Application/EventHandlers/TrackUpsertEventHandler.cs @@ -109,7 +109,6 @@ public class TrackUpsertEventHandler : ITransientDependency, ICapSubscribe { track = new TrackDetailsIndex { - IndexName = $"{GlobalConst.TrackIndex}-{DateTime.Now:yyyy.MM.dd}", OrderId = order.OrderId, OrderNo = order.OrderNo, OrderType = order.OrderType, diff --git a/src/SJZY.Track.Domain/Aggregates/TrackDetailsAggregate/ITrackDetailsRepository.cs b/src/SJZY.Track.Domain/Aggregates/TrackDetailsAggregate/ITrackDetailsRepository.cs index f44f298f..a61e4f95 100644 --- a/src/SJZY.Track.Domain/Aggregates/TrackDetailsAggregate/ITrackDetailsRepository.cs +++ b/src/SJZY.Track.Domain/Aggregates/TrackDetailsAggregate/ITrackDetailsRepository.cs @@ -17,6 +17,7 @@ public interface ITrackDetailsRepository Task AddManyAsync(List index); + Task AddAsync(TrackDetailsIndex track); Task> GetListAsync(int orderType, List orderNos); diff --git a/src/SJZY.Track.Repository/Repositories/TrackDetailsRepository.cs b/src/SJZY.Track.Repository/Repositories/TrackDetailsRepository.cs index 75ecc85a..3d88e56b 100644 --- a/src/SJZY.Track.Repository/Repositories/TrackDetailsRepository.cs +++ b/src/SJZY.Track.Repository/Repositories/TrackDetailsRepository.cs @@ -120,7 +120,10 @@ internal class TrackDetailsRepository : ElasticSearchContextAbstract tracks) { // 按天写入es - var r = await Context.IndexManyAsync(tracks, tracks.First().IndexName); + var indexName = $"{GlobalConst.TrackIndex}-{DateTime.Now:yyyy.MM.dd}"; + tracks.ForEach(x => x.IndexName = indexName); + + var r = await Context.IndexManyAsync(tracks, indexName); if (!r.IsValid) { @@ -128,6 +131,19 @@ internal class TrackDetailsRepository : ElasticSearchContextAbstract s.Index(indexName)); + + if (!r.IsValid) + { + throw new Exception($"轨迹新增失败,原因:{r.DebugInformation}。"); + } + } + public async Task> GetListAsync(int orderType, List orderNos) { if (orderNos.Count < 1) return new List(); From 2b678c2eb4c1d27b0f05372ebaf72d6973c4d0dc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=B9=8F=E5=86=9B?= <2357729423@qq.com> Date: Tue, 16 Apr 2024 14:59:10 +0800 Subject: [PATCH 25/72] =?UTF-8?q?fix=EF=BC=9A=E8=BD=A8=E8=BF=B9=E8=81=9A?= =?UTF-8?q?=E5=90=88size?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Repositories/TrackDetailsRepository.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/SJZY.Track.Repository/Repositories/TrackDetailsRepository.cs b/src/SJZY.Track.Repository/Repositories/TrackDetailsRepository.cs index 3d88e56b..238a9fd0 100644 --- a/src/SJZY.Track.Repository/Repositories/TrackDetailsRepository.cs +++ b/src/SJZY.Track.Repository/Repositories/TrackDetailsRepository.cs @@ -57,7 +57,7 @@ internal class TrackDetailsRepository : ElasticSearchContextAbstract a .Terms("orders", t => t .Field(f => f.OrderId) From ba5bf2493189974c71d844adcb15a77079f9aa09 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=B9=8F=E5=86=9B?= <2357729423@qq.com> Date: Tue, 16 Apr 2024 15:28:29 +0800 Subject: [PATCH 26/72] =?UTF-8?q?opt=EF=BC=9A=E8=BD=A8=E8=BF=B9upsert?= =?UTF-8?q?=E5=89=AA=E6=9E=9D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../EventHandlers/TrackUpsertEventHandler.cs | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/src/SJZY.Track.Application/EventHandlers/TrackUpsertEventHandler.cs b/src/SJZY.Track.Application/EventHandlers/TrackUpsertEventHandler.cs index 8fdc61bc..a162428a 100644 --- a/src/SJZY.Track.Application/EventHandlers/TrackUpsertEventHandler.cs +++ b/src/SJZY.Track.Application/EventHandlers/TrackUpsertEventHandler.cs @@ -39,10 +39,11 @@ public class TrackUpsertEventHandler : ITransientDependency, ICapSubscribe return; } - await HandleTrackAsync(@event); + var canNextOrderIds = new List(); + await HandleTrackAsync(@event, canNextOrderIds); // 根据订单关联关系异步向下刷(异步) - var linkedOrders = await _orderRepository.GetLinkedOrdersAsync(orderIds); + var linkedOrders = await _orderRepository.GetLinkedOrdersAsync(canNextOrderIds.ToArray()); foreach (var order in @event.OrderIdentifiers) { // 理论上小包在这不会分组 @@ -88,7 +89,7 @@ public class TrackUpsertEventHandler : ITransientDependency, ICapSubscribe } } - private async Task HandleTrackAsync(TrackUpsertEvent @event) + private async Task HandleTrackAsync(TrackUpsertEvent @event, List canNextOrderIds) { var orderIds = @event.OrderIdentifiers.Select(x => x.OrderId).ToArray(); var tracks = await _trackDetailsRepository.GetListAsync(orderIds, @event.TrackCode); @@ -101,8 +102,8 @@ public class TrackUpsertEventHandler : ITransientDependency, ICapSubscribe if (@event.IsAdd != null) { - if (track == null && !@event.IsAdd!.Value) return; // 不存在不让改 - if (track != null && @event.IsAdd!.Value) return; // 存在不让创建 + if (track == null && !@event.IsAdd!.Value) continue; // 不存在不让改 + if (track != null && @event.IsAdd!.Value) continue; // 存在不让创建 } if (track == default) @@ -167,6 +168,8 @@ public class TrackUpsertEventHandler : ITransientDependency, ICapSubscribe }; await _capPublisher.PublishAsync(GlobalConst.TrackPushSubscribe, trackPushEvent); + + canNextOrderIds.Add(order.OrderId); } var firstTrack = insertTracks.FirstOrDefault(); From 1f115bad3ebeed633a4bd8524aa2aa6aea09d598 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=B9=8F=E5=86=9B?= <2357729423@qq.com> Date: Tue, 16 Apr 2024 18:34:39 +0800 Subject: [PATCH 27/72] =?UTF-8?q?change=EF=BC=9Aes=20=E8=8E=B7=E5=8F=96lis?= =?UTF-8?q?t=20size=E6=94=B9=E4=B8=BA1000?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Repositories/TrackDetailsRepository.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/SJZY.Track.Repository/Repositories/TrackDetailsRepository.cs b/src/SJZY.Track.Repository/Repositories/TrackDetailsRepository.cs index 238a9fd0..81d2bd06 100644 --- a/src/SJZY.Track.Repository/Repositories/TrackDetailsRepository.cs +++ b/src/SJZY.Track.Repository/Repositories/TrackDetailsRepository.cs @@ -17,6 +17,7 @@ internal class TrackDetailsRepository : ElasticSearchContextAbstract(s => s .Source() + .Size(1000) .Query(q => q .Bool(b => b .Must( @@ -165,6 +166,7 @@ internal class TrackDetailsRepository : ElasticSearchContextAbstract f.OrderType, orderType) ) + .Size(1000) ); return data.Documents.ToList(); From d73a7ad119d175355a5d9508341df58b18202546 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=B9=8F=E5=86=9B?= <2357729423@qq.com> Date: Tue, 16 Apr 2024 18:38:18 +0800 Subject: [PATCH 28/72] =?UTF-8?q?fix=EF=BC=9A=E4=BF=AE=E6=94=B9=E8=BD=A8?= =?UTF-8?q?=E8=BF=B9=E5=BC=95=E5=8F=91=E7=9A=84=E5=88=B7=E6=96=B0=E4=B8=BB?= =?UTF-8?q?=E8=A1=A8=E9=80=BB=E8=BE=91bug?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../EventHandlers/TrackUpsertEventHandler.cs | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/SJZY.Track.Application/EventHandlers/TrackUpsertEventHandler.cs b/src/SJZY.Track.Application/EventHandlers/TrackUpsertEventHandler.cs index a162428a..56157b2d 100644 --- a/src/SJZY.Track.Application/EventHandlers/TrackUpsertEventHandler.cs +++ b/src/SJZY.Track.Application/EventHandlers/TrackUpsertEventHandler.cs @@ -94,6 +94,9 @@ public class TrackUpsertEventHandler : ITransientDependency, ICapSubscribe var orderIds = @event.OrderIdentifiers.Select(x => x.OrderId).ToArray(); var tracks = await _trackDetailsRepository.GetListAsync(orderIds, @event.TrackCode); + var firstTrack = tracks.FirstOrDefault(); + if (firstTrack == null) return; + var insertTracks = new List(); foreach (var order in @event.OrderIdentifiers) @@ -172,24 +175,21 @@ public class TrackUpsertEventHandler : ITransientDependency, ICapSubscribe canNextOrderIds.Add(order.OrderId); } - var firstTrack = insertTracks.FirstOrDefault(); - if (firstTrack == null) return; - - // step1、upsert es轨迹 + // 批量add to es await _trackDetailsRepository.AddManyAsync(insertTracks); - // step3、触发订单主表更新事件(异步) + // 触发订单主表更新事件(异步) await _capPublisher.PublishAsync(GlobalConst.TrackChangeAfterUpdateOrderSubscribe, new TrackChangeAfterUpdateOrderEvent { OrderIds = orderIds, IsCompleted = @event.TrackRefreshData.IsCompleted, - TrackCode = firstTrack.TrackCode, + TrackCode = @event.TrackCode, TrackContent = firstTrack.TrackContent, TrackEnContent = firstTrack.TrackEnContent, - TrackPlace = firstTrack.TrackPlace, - TrackTime = firstTrack.TrackTime, - TrackTimeZone = firstTrack.TrackTimeZone + TrackPlace = @event.TrackPlace, + TrackTime = @event.TrackTime, + TrackTimeZone = @event.TrackTimeZone }); } } \ No newline at end of file From af09e7581198670f36add95077f7ea1bfc30e722 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=B9=8F=E5=86=9B?= <2357729423@qq.com> Date: Tue, 16 Apr 2024 18:49:15 +0800 Subject: [PATCH 29/72] opt --- .../EventHandlers/TrackUpsertEventHandler.cs | 7 +++++-- .../Repositories/TrackDetailsRepository.cs | 1 + 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/SJZY.Track.Application/EventHandlers/TrackUpsertEventHandler.cs b/src/SJZY.Track.Application/EventHandlers/TrackUpsertEventHandler.cs index 56157b2d..65dba149 100644 --- a/src/SJZY.Track.Application/EventHandlers/TrackUpsertEventHandler.cs +++ b/src/SJZY.Track.Application/EventHandlers/TrackUpsertEventHandler.cs @@ -94,8 +94,7 @@ public class TrackUpsertEventHandler : ITransientDependency, ICapSubscribe var orderIds = @event.OrderIdentifiers.Select(x => x.OrderId).ToArray(); var tracks = await _trackDetailsRepository.GetListAsync(orderIds, @event.TrackCode); - var firstTrack = tracks.FirstOrDefault(); - if (firstTrack == null) return; + TrackDetailsIndex firstTrack = null; var insertTracks = new List(); @@ -173,11 +172,15 @@ public class TrackUpsertEventHandler : ITransientDependency, ICapSubscribe await _capPublisher.PublishAsync(GlobalConst.TrackPushSubscribe, trackPushEvent); canNextOrderIds.Add(order.OrderId); + + firstTrack ??= track; } // 批量add to es await _trackDetailsRepository.AddManyAsync(insertTracks); + if (firstTrack == null) return; + // 触发订单主表更新事件(异步) await _capPublisher.PublishAsync(GlobalConst.TrackChangeAfterUpdateOrderSubscribe, new TrackChangeAfterUpdateOrderEvent diff --git a/src/SJZY.Track.Repository/Repositories/TrackDetailsRepository.cs b/src/SJZY.Track.Repository/Repositories/TrackDetailsRepository.cs index 81d2bd06..644beb65 100644 --- a/src/SJZY.Track.Repository/Repositories/TrackDetailsRepository.cs +++ b/src/SJZY.Track.Repository/Repositories/TrackDetailsRepository.cs @@ -120,6 +120,7 @@ internal class TrackDetailsRepository : ElasticSearchContextAbstract tracks) { + if (!tracks.Any()) return; // 按天写入es var indexName = $"{GlobalConst.TrackIndex}-{DateTime.Now:yyyy.MM.dd}"; tracks.ForEach(x => x.IndexName = indexName); From 7199398dd7e62151ca48c545476c4eeb995918bc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=B9=8F=E5=86=9B?= <2357729423@qq.com> Date: Tue, 16 Apr 2024 19:20:40 +0800 Subject: [PATCH 30/72] =?UTF-8?q?fix=EF=BC=9A=E6=9B=B4=E6=96=B0=E7=9A=84?= =?UTF-8?q?=E5=8D=B3=E6=98=AF=E6=9C=80=E6=96=B0=E8=BD=A8=E8=BF=B9=E6=97=B6?= =?UTF-8?q?=EF=BC=8C=E7=9B=B4=E6=8E=A5=E8=A6=86=E7=9B=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Events/TrackChangeAfterUpdateOrderEvent.cs | 5 ----- .../TrackChangeAfterUpdateOrderEventHandler.cs | 11 +++++++---- .../EventHandlers/TrackUpsertEventHandler.cs | 1 - 3 files changed, 7 insertions(+), 10 deletions(-) diff --git a/src/SJZY.Track.Application.Contract/Events/TrackChangeAfterUpdateOrderEvent.cs b/src/SJZY.Track.Application.Contract/Events/TrackChangeAfterUpdateOrderEvent.cs index 3fd35deb..a59c31c8 100644 --- a/src/SJZY.Track.Application.Contract/Events/TrackChangeAfterUpdateOrderEvent.cs +++ b/src/SJZY.Track.Application.Contract/Events/TrackChangeAfterUpdateOrderEvent.cs @@ -12,11 +12,6 @@ public class TrackChangeAfterUpdateOrderEvent /// public bool IsCompleted { get; set; } - /// - /// 轨迹代码 - /// - public string TrackCode { get; set; } = null!; - /// /// 轨迹内容 /// diff --git a/src/SJZY.Track.Application/EventHandlers/TrackChangeAfterUpdateOrderEventHandler.cs b/src/SJZY.Track.Application/EventHandlers/TrackChangeAfterUpdateOrderEventHandler.cs index 3f586b15..3e3b1d07 100644 --- a/src/SJZY.Track.Application/EventHandlers/TrackChangeAfterUpdateOrderEventHandler.cs +++ b/src/SJZY.Track.Application/EventHandlers/TrackChangeAfterUpdateOrderEventHandler.cs @@ -38,11 +38,14 @@ public class TrackChangeAfterUpdateOrderEventHandler : ITransientDependency, ICa foreach (var order in orders) { - if (order.LatestTrackTime != null && - @event.TrackTime.Subtract(TimeSpan.FromHours(@event.TrackTimeZone)) < - order.LatestTrackTime.Value.Subtract(TimeSpan.FromHours(order.LatestTrackTimeZone ?? 0))) + if (order.LatestTrackContent != @event.TrackContent) { - continue; + if (order.LatestTrackTime != null && + @event.TrackTime.Subtract(TimeSpan.FromHours(@event.TrackTimeZone)) < + order.LatestTrackTime.Value.Subtract(TimeSpan.FromHours(order.LatestTrackTimeZone ?? 0))) + { + continue; + } } if (!order.IsCompleted) diff --git a/src/SJZY.Track.Application/EventHandlers/TrackUpsertEventHandler.cs b/src/SJZY.Track.Application/EventHandlers/TrackUpsertEventHandler.cs index 65dba149..c4073332 100644 --- a/src/SJZY.Track.Application/EventHandlers/TrackUpsertEventHandler.cs +++ b/src/SJZY.Track.Application/EventHandlers/TrackUpsertEventHandler.cs @@ -187,7 +187,6 @@ public class TrackUpsertEventHandler : ITransientDependency, ICapSubscribe { OrderIds = orderIds, IsCompleted = @event.TrackRefreshData.IsCompleted, - TrackCode = @event.TrackCode, TrackContent = firstTrack.TrackContent, TrackEnContent = firstTrack.TrackEnContent, TrackPlace = @event.TrackPlace, From f817b71c059185b166723a3108ec9a15ad780fce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=B9=8F=E5=86=9B?= <2357729423@qq.com> Date: Wed, 17 Apr 2024 14:41:14 +0800 Subject: [PATCH 31/72] =?UTF-8?q?fix=EF=BC=9A=E6=8E=A8=E9=80=81=E5=8D=95?= =?UTF-8?q?=E5=8F=B7=E6=B2=A1=E4=BC=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../appsettings.Development.json | 56 +++++++++++++------ .../EventHandlers/TrackPushEventHandler.cs | 4 +- .../EventHandlers/TrackUpsertEventHandler.cs | 1 + 3 files changed, 42 insertions(+), 19 deletions(-) diff --git a/src/SJZY.Track.Api/appsettings.Development.json b/src/SJZY.Track.Api/appsettings.Development.json index 671ae998..c9efd594 100644 --- a/src/SJZY.Track.Api/appsettings.Development.json +++ b/src/SJZY.Track.Api/appsettings.Development.json @@ -3,27 +3,40 @@ "Logging": { "LogLevel": { "Default": "Debug", - "Microsoft.AspNetCore": "Warning" + "Microsoft.AspNetCore": "Debug" } }, "ConnectionStrings": { - "DefaultConnection": "server=mysql-dev.default.svc.cluster.local;Database=sjzy_track;Uid=sjzy_dev_user;Pwd=818f83e5;AllowLoadLocalInfile=true;SslMode=None;Charset=utf8mb4;", + "DefaultConnection": "server=mysql-dev.default.svc.cluster.local;Database=sjzy_track;Uid=sjzy_dev_user;Pwd=818f83e5;AllowLoadLocalInfile=true;SslMode=None;Charset=utf8mb4;" + }, + "CAP": { + "FailedRetryCount": 0, + "FailedRetryInterval": 60, + "PrefetchCount": 1, + "ConsumerThreadCount": 2, + "UseDispatchingPerGroup": true, + "SucceedMessageExpiredAfter": 21600 }, "Redis": { "Host": "redis-dev.default.svc.cluster.local:6379", "Password": "gaVEHR3V7qiY", "MaxPoolSize": 1000, "Database": 6, - "Prefix": "" + "Prefix": "", + "IdleTimeout": 1000 }, "CorsPolicy": [ "" ], "Swagger": { "IsEnable": true, - "ServiceUrl": "", - "JsonUrlPrefix": "", //转发目录前缀,部署服务器时需要配置 /kingmall - "ScanPrefix": [ "SJZY" ] //全局扫描程序集或xml文件时只加载以 SJZY 开头的内容 + "ServiceUrl": "/trackApi", + "JsonUrlPrefix": "/trackApi", + //转发目录前缀,部署服务器时需要配置 /kingmall + "ScanPrefix": [ + "SJZY" + ] + //全局扫描程序集或xml文件时只加载以 SJZY 开头的内容 }, "RabbitMQ": { "UserName": "sjzy", @@ -31,14 +44,18 @@ "HostName": "rabbitmq-dev.default.svc.cluster.local", "Port": 5672 }, + "Notice": { + "Webhook": "https://open.feishu.cn/open-apis/bot/v2/hook/fbe92f24-7f9f-41ea-a93a-63d855a03bc0", + "Title": "😭 轨迹中台开发环境异常" + }, "Serilog": { "MinimumLevel": { - "Default": "Information", + "Default": "Debug", "Override": { - "System": "Warning", - "Microsoft": "Warning", - "Microsoft.Hosting.Lifetime": "Information", - "Microsoft.EntityFrameworkCore": "Information" + "System": "Debug", + "Microsoft": "Debug", + "Microsoft.Hosting.Lifetime": "Debug", + "Microsoft.EntityFrameworkCore": "Debug" } }, "Enrich": [ "FromLogContext", "WithMachineName", "WithProcessId", "WithThreadId" ], @@ -66,13 +83,18 @@ "Base64PassPassword": "Basic ZWxhc3RpYzphZnlUZ21WYjhqcTY=" }, "RemoteServices": { - "UserCenter": { - "BaseUrl": "http://192.168.80.55:5020/" - }, "InterfaceForward": { - "BaseUrl": "http://192.168.80.55:5041/", //开发环境80.55,测试环境80.57 - "AppKey": "从接口通应用获取", - "AppSecret": "从接口通应用获取" + "BaseUrl": "http://interfaceapi-test.default.svc.cluster.local:5041/", + "AppKey": "BSI2302001", + "AppSecret": "ArJYL14XZneXpqvpq80wyi3h2hT918AX" + }, + "UserCenter": { + "BaseUrl": "http://userapi-dev.default.svc.cluster.local:5020/" } + }, + "Language": { + "SystemName": "Track", + "Index": 6, + "KeyPrefix": "language" } } diff --git a/src/SJZY.Track.Application/EventHandlers/TrackPushEventHandler.cs b/src/SJZY.Track.Application/EventHandlers/TrackPushEventHandler.cs index 1334e3ce..55d0ed5e 100644 --- a/src/SJZY.Track.Application/EventHandlers/TrackPushEventHandler.cs +++ b/src/SJZY.Track.Application/EventHandlers/TrackPushEventHandler.cs @@ -109,11 +109,11 @@ public class TrackPushEventHandler : ITransientDependency, ICapSubscribe { if (@event.RetryNum < 3) { + @event.RetryNum++; // 1, 2, 4min await _capPublisher.PublishDelayAsync( - TimeSpan.FromSeconds((1 << @event.RetryNum) * 60), + TimeSpan.FromSeconds((1 << @event.RetryNum - 1) * RandomHelper.GetRandom(30, 60)), GlobalConst.TrackPushSubscribe, @event); - @event.RetryNum++; return; } } diff --git a/src/SJZY.Track.Application/EventHandlers/TrackUpsertEventHandler.cs b/src/SJZY.Track.Application/EventHandlers/TrackUpsertEventHandler.cs index c4073332..f7746db2 100644 --- a/src/SJZY.Track.Application/EventHandlers/TrackUpsertEventHandler.cs +++ b/src/SJZY.Track.Application/EventHandlers/TrackUpsertEventHandler.cs @@ -161,6 +161,7 @@ public class TrackUpsertEventHandler : ITransientDependency, ICapSubscribe { OptionType = track.Id.IsNullOrWhiteSpace() ? OptionType.新增 : OptionType.修改, OrderId = order.OrderId, + OrderNo = order.OrderNo, TrackStatus = track.TrackStatus, TrackCode = track.TrackCode, TrackContent = track.TrackContent, From f78d463a681958baa5f08e08793de499653fd125 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=B9=8F=E5=86=9B?= <2357729423@qq.com> Date: Wed, 17 Apr 2024 14:51:13 +0800 Subject: [PATCH 32/72] =?UTF-8?q?opt=EF=BC=9A=E5=8D=87=E7=BA=A7core=207.7.?= =?UTF-8?q?5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/SJZY.Track.Domain/SJZY.Track.Domain.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/SJZY.Track.Domain/SJZY.Track.Domain.csproj b/src/SJZY.Track.Domain/SJZY.Track.Domain.csproj index cb0a715f..3c38d62a 100644 --- a/src/SJZY.Track.Domain/SJZY.Track.Domain.csproj +++ b/src/SJZY.Track.Domain/SJZY.Track.Domain.csproj @@ -8,7 +8,7 @@ - + From 954654ede60cf5993e949cea53feaebce9a1bdac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=B9=8F=E5=86=9B?= <2357729423@qq.com> Date: Mon, 22 Apr 2024 09:06:45 +0800 Subject: [PATCH 33/72] =?UTF-8?q?change=EF=BC=9Acap=E4=B8=8D=E6=89=93?= =?UTF-8?q?=E5=8D=B0=E8=B6=85=E6=97=B6=E6=97=A5=E5=BF=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .idea/.idea.SJZY.Track.Api/.idea/.gitignore | 13 +++++++++++ .../EventHandlers/CAPFilter.cs | 22 +++++++++---------- 2 files changed, 24 insertions(+), 11 deletions(-) create mode 100644 .idea/.idea.SJZY.Track.Api/.idea/.gitignore diff --git a/.idea/.idea.SJZY.Track.Api/.idea/.gitignore b/.idea/.idea.SJZY.Track.Api/.idea/.gitignore new file mode 100644 index 00000000..d6752705 --- /dev/null +++ b/.idea/.idea.SJZY.Track.Api/.idea/.gitignore @@ -0,0 +1,13 @@ +# Default ignored files +/shelf/ +/workspace.xml +# Rider ignored files +/projectSettingsUpdater.xml +/.idea.SJZY.Track.Api.iml +/modules.xml +/contentModel.xml +# Editor-based HTTP Client requests +/httpRequests/ +# Datasource local storage ignored files +/dataSources/ +/dataSources.local.xml diff --git a/src/SJZY.Track.Application/EventHandlers/CAPFilter.cs b/src/SJZY.Track.Application/EventHandlers/CAPFilter.cs index 94cbc37d..4c0014c6 100644 --- a/src/SJZY.Track.Application/EventHandlers/CAPFilter.cs +++ b/src/SJZY.Track.Application/EventHandlers/CAPFilter.cs @@ -57,12 +57,12 @@ public class CapFilter : SubscribeFilter /// public override Task OnSubscribeExecutedAsync(ExecutedContext context) { - context.DeliverMessage.Headers.TryGetValue("sjzy-receive-time", out var receiveTime); - context.DeliverMessage.Headers.TryGetValue("cap-msg-name", out var receiveName); - context.DeliverMessage.Headers.TryGetValue("sjzy-arguments", out var arguments); - context.DeliverMessage.Headers.TryGetValue("cap-msg-id", out var messageId); - - BuildLog(receiveTime!, receiveName!, arguments!, false, messageId!); + // context.DeliverMessage.Headers.TryGetValue("sjzy-receive-time", out var receiveTime); + // context.DeliverMessage.Headers.TryGetValue("cap-msg-name", out var receiveName); + // context.DeliverMessage.Headers.TryGetValue("sjzy-arguments", out var arguments); + // context.DeliverMessage.Headers.TryGetValue("cap-msg-id", out var messageId); + // + // BuildLog(receiveTime!, receiveName!, arguments!, false, messageId!); return Task.CompletedTask; } @@ -86,11 +86,11 @@ public class CapFilter : SubscribeFilter LogHelper.Error($"cap-msg-id:{messageId}\n{context.Exception}"); - context.DeliverMessage.Headers.TryGetValue("sjzy-receive-time", out var receiveTime); - context.DeliverMessage.Headers.TryGetValue("cap-msg-name", out var receiveName); - context.DeliverMessage.Headers.TryGetValue("sjzy-arguments", out var arguments); - - BuildLog(receiveTime!, receiveName!, arguments, true, messageId!); + // context.DeliverMessage.Headers.TryGetValue("sjzy-receive-time", out var receiveTime); + // context.DeliverMessage.Headers.TryGetValue("cap-msg-name", out var receiveName); + // context.DeliverMessage.Headers.TryGetValue("sjzy-arguments", out var arguments); + // + // BuildLog(receiveTime!, receiveName!, arguments, true, messageId!); return Task.CompletedTask; } From aecb488045fac3ad1b292f7a3cc19e21fa555523 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=B9=8F=E5=86=9B?= <2357729423@qq.com> Date: Mon, 22 Apr 2024 14:14:45 +0800 Subject: [PATCH 34/72] =?UTF-8?q?change=EF=BC=9A=E8=BD=A8=E8=BF=B9?= =?UTF-8?q?=E5=88=B7=E6=96=B0=E6=9C=80=E7=9F=ADcd=2060min?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Services/TrackPull/TrackPullService.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/SJZY.Track.Application/Services/TrackPull/TrackPullService.cs b/src/SJZY.Track.Application/Services/TrackPull/TrackPullService.cs index d23937e9..cd027698 100644 --- a/src/SJZY.Track.Application/Services/TrackPull/TrackPullService.cs +++ b/src/SJZY.Track.Application/Services/TrackPull/TrackPullService.cs @@ -86,6 +86,8 @@ public class TrackPullService : ApplicationService [HttpPost("Edit")] public async Task EditAsync([FromBody] EditTrackPullConfigInput input) { + if (input.PullInterval < 60) input.PullInterval = 60; + if (input.Options != OptionTypeNoNull.删除) { Expression> isAnyExp = x => From d95bcb70c029421e5ec65c9a81090fcac0305f8b Mon Sep 17 00:00:00 2001 From: moyongzhen <2534173414@qq.com> Date: Mon, 22 Apr 2024 14:42:40 +0800 Subject: [PATCH 35/72] =?UTF-8?q?fix=EF=BC=9A=E8=BD=A8=E8=BF=B9=E6=A0=87?= =?UTF-8?q?=E8=AE=B0=E5=88=86=E9=A1=B5=E6=9F=A5=E8=AF=A2=E6=B7=BB=E5=8A=A0?= =?UTF-8?q?code=E6=A8=A1=E7=B3=8A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Dtos/TrackFlags/GetTrackFlagListDto.cs | 10 +++++----- .../Dtos/TrackFlags/GetPageTrackFlagVO.cs | 8 ++++---- .../Repositories/TrackFlagRepository.cs | 3 ++- 3 files changed, 11 insertions(+), 10 deletions(-) diff --git a/src/SJZY.Track.Application.Contract/Dtos/TrackFlags/GetTrackFlagListDto.cs b/src/SJZY.Track.Application.Contract/Dtos/TrackFlags/GetTrackFlagListDto.cs index 3964caea..505536e1 100644 --- a/src/SJZY.Track.Application.Contract/Dtos/TrackFlags/GetTrackFlagListDto.cs +++ b/src/SJZY.Track.Application.Contract/Dtos/TrackFlags/GetTrackFlagListDto.cs @@ -58,11 +58,11 @@ /// /// 选中的轨迹标记id /// - public List? SelectIds { get; set; } + public List? SelectIds { get; set; } - ///// - ///// 关键字 - ///// - //public string Keywords { get; set; } + /// + /// 关键字 + /// + public string? Keywords { get; set; } } } \ No newline at end of file diff --git a/src/SJZY.Track.Domain/Dtos/TrackFlags/GetPageTrackFlagVO.cs b/src/SJZY.Track.Domain/Dtos/TrackFlags/GetPageTrackFlagVO.cs index adbf1a5d..f838b37d 100644 --- a/src/SJZY.Track.Domain/Dtos/TrackFlags/GetPageTrackFlagVO.cs +++ b/src/SJZY.Track.Domain/Dtos/TrackFlags/GetPageTrackFlagVO.cs @@ -18,10 +18,10 @@ namespace SJZY.Track.Domain.Dtos.TrackFlags /// public List? SelectIds { get; set; } - ///// - ///// 关键字 - ///// - //public string Keywords { get; set; } + /// + /// 关键字 + /// + public string? Keywords { get; set; } } public class GetTrackFlagListVO diff --git a/src/SJZY.Track.Repository/Repositories/TrackFlagRepository.cs b/src/SJZY.Track.Repository/Repositories/TrackFlagRepository.cs index d2227924..ed92d283 100644 --- a/src/SJZY.Track.Repository/Repositories/TrackFlagRepository.cs +++ b/src/SJZY.Track.Repository/Repositories/TrackFlagRepository.cs @@ -46,8 +46,9 @@ public class TrackFlagRepository : BasicRepository, ITrackFlagR .LeftJoin((a, b, c) => a.CreateUserId == c.Id && c.IsDeleted == false) .LeftJoin((a, b, c, d) => a.UpdateUserId == d.Id && d.IsDeleted == false) .WhereIF(input.SubSystemId > 0, (a, b, c, d) => a.SubSystemId == input.SubSystemId) + .WhereIF(!input.Keywords.IsNullOrWhiteSpace(), (a, b, c, d) => SqlFunc.Contains(a.Code, input.Keywords)) .OrderByIF(input.SelectIds.IsNullOrEmpty(), (a, b, c, d) => a.CreateTime, OrderByType.Desc) - .OrderByIF(!input.SelectIds.IsNullOrEmpty(), (a, b, c, d) => SqlFunc.IIF(input.SelectIds.Contains(a.Id), SqlFunc.DateAdd(SqlFunc.GetDate(), 1), a.CreateTime), OrderByType.Desc) + .OrderByIF(!input.SelectIds.IsNullOrEmpty(), (a, b, c, d) => SqlFunc.IIF(input.SelectIds!.Contains(a.Id), SqlFunc.DateAdd(SqlFunc.GetDate(), 1), a.CreateTime), OrderByType.Desc) .Select((a, b, c, d) => new GetTrackFlagListVO { Id = a.Id, From 2c5aa4f35a750e3904e3ac20f9157f98a2b91503 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=B9=8F=E5=86=9B?= <2357729423@qq.com> Date: Mon, 22 Apr 2024 15:05:01 +0800 Subject: [PATCH 36/72] =?UTF-8?q?opt=EF=BC=9A=E5=AE=9A=E6=97=B6=E4=BB=BB?= =?UTF-8?q?=E5=8A=A1=E5=88=B7=E6=96=B0=E8=BD=A8=E8=BF=B9=E5=88=86=E9=A1=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ProvideServices/TrackPullService.cs | 42 ++++++++++--------- .../Queries/IProvideQueries.cs | 5 ++- .../Queries/ProvideQueries.cs | 5 ++- 3 files changed, 31 insertions(+), 21 deletions(-) diff --git a/src/SJZY.Track.Application/Services/ProvideServices/TrackPullService.cs b/src/SJZY.Track.Application/Services/ProvideServices/TrackPullService.cs index 7cf315b2..354af4e1 100644 --- a/src/SJZY.Track.Application/Services/ProvideServices/TrackPullService.cs +++ b/src/SJZY.Track.Application/Services/ProvideServices/TrackPullService.cs @@ -88,32 +88,36 @@ public class TrackPullService : ApplicationService continue; } - var orders = await _provideQueries.FindOrderWithServiceProviderAsync(config.ServiceProviderId); - var serviceProviderCode = orders.FirstOrDefault()?.ServiceProviderCode; - var serviceProviderName = orders.FirstOrDefault()?.ServiceProviderName; - - foreach (var group in orders.GroupBy(x => - new { x.SubSystemId, x.OrderType })) + var page = 1; + var orders = await _provideQueries.FindOrderWithServiceProviderAsync(config.ServiceProviderId, page); + while (orders.Any()) { - var data = group.Select(x => new - { - x.OrderNo - }).ToList(); + var serviceProviderCode = orders.FirstOrDefault()?.ServiceProviderCode; + var serviceProviderName = orders.FirstOrDefault()?.ServiceProviderName; - var attach = Base64Helper.SerializeObject(new TrackRefreshAttach(config.ServiceProviderId, - serviceProviderName!, - group.Key.SubSystemId, group.Key.OrderType)); - // 批量获取轨迹 - await _httpClientProxy.Service.BatchForwardThenPushToQueueAsync( - InterfaceRelayConst.GetTrackInterfaceCode, serviceProviderCode, data, - GlobalConst.TrackRefreshSubscribe, attach); + foreach (var group in orders.GroupBy(x => + new { x.SubSystemId, x.OrderType })) + { + var data = group.Select(x => new + { + x.OrderNo + }).ToList(); + + var attach = Base64Helper.SerializeObject(new TrackRefreshAttach(config.ServiceProviderId, + serviceProviderName!, + group.Key.SubSystemId, group.Key.OrderType)); + // 批量获取轨迹 + await _httpClientProxy.Service.BatchForwardThenPushToQueueAsync( + InterfaceRelayConst.GetTrackInterfaceCode, serviceProviderCode, data, + GlobalConst.TrackRefreshSubscribe, attach); + } + + orders = await _provideQueries.FindOrderWithServiceProviderAsync(config.ServiceProviderId, ++page); } - if (config.PullInterval < 60) config.PullInterval = 60; await RedisHelper.Client.SetExAsync(redisKey, config.PullInterval * 60, orders.Count); } - return true; } } \ No newline at end of file diff --git a/src/SJZY.Track.Domain/Queries/IProvideQueries.cs b/src/SJZY.Track.Domain/Queries/IProvideQueries.cs index 2795df48..7d043a9f 100644 --- a/src/SJZY.Track.Domain/Queries/IProvideQueries.cs +++ b/src/SJZY.Track.Domain/Queries/IProvideQueries.cs @@ -60,6 +60,9 @@ public interface IProvideQueries /// 获取服务商下所有单(未完成的) /// /// + /// + /// /// - Task> FindOrderWithServiceProviderAsync(int serviceProvider); + Task> FindOrderWithServiceProviderAsync(int serviceProvider, int pageIndex, + int pageSize = 1000); } \ No newline at end of file diff --git a/src/SJZY.Track.Repository/Queries/ProvideQueries.cs b/src/SJZY.Track.Repository/Queries/ProvideQueries.cs index 7f144688..82e4993f 100644 --- a/src/SJZY.Track.Repository/Queries/ProvideQueries.cs +++ b/src/SJZY.Track.Repository/Queries/ProvideQueries.cs @@ -113,7 +113,8 @@ public class ProvideQueries : ISugarRepository, IProvideQueries, .ToListAsync(); } - public async Task> FindOrderWithServiceProviderAsync(int serviceProvider) + public async Task> FindOrderWithServiceProviderAsync(int serviceProvider, + int pageIndex, int pageSize = 1000) { return await Context.Queryable() .RightJoin((a, b) => a.Id == b.OrderId) @@ -128,6 +129,8 @@ public class ProvideQueries : ISugarRepository, IProvideQueries, ServiceProviderName = c.Name, SubSystemId = a.SubSystemId }) + .Skip((pageIndex - 1) * pageSize) + .Take(pageSize) .ToListAsync(); } } \ No newline at end of file From 2e551b21d7c55beb96f1b86d3fc21dc3ace005ae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=B9=8F=E5=86=9B?= <2357729423@qq.com> Date: Mon, 22 Apr 2024 22:14:35 +0800 Subject: [PATCH 37/72] =?UTF-8?q?change=EF=BC=9A=E6=8E=A8=E9=80=81?= =?UTF-8?q?=E9=87=8D=E8=AF=95=E9=87=8D=E5=85=A5=E9=98=9F=E5=88=97+?= =?UTF-8?q?=E5=A4=B1=E8=B4=A5=E6=97=A5=E5=BF=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../EventHandlers/TrackPushEventHandler.cs | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/src/SJZY.Track.Application/EventHandlers/TrackPushEventHandler.cs b/src/SJZY.Track.Application/EventHandlers/TrackPushEventHandler.cs index 55d0ed5e..ceed798d 100644 --- a/src/SJZY.Track.Application/EventHandlers/TrackPushEventHandler.cs +++ b/src/SJZY.Track.Application/EventHandlers/TrackPushEventHandler.cs @@ -105,22 +105,20 @@ public class TrackPushEventHandler : ITransientDependency, ICapSubscribe throw new ArgumentOutOfRangeException(); } + // 往es 写推送日志 + await _trackPushRecordsRepository.AddAsync(log); + if (!log.IsSuccess) { + // 重试过程中不会去更新订单主表 if (@event.RetryNum < 3) { @event.RetryNum++; - // 1, 2, 4min - await _capPublisher.PublishDelayAsync( - TimeSpan.FromSeconds((1 << @event.RetryNum - 1) * RandomHelper.GetRandom(30, 60)), - GlobalConst.TrackPushSubscribe, @event); + await _capPublisher.PublishAsync(GlobalConst.TrackPushSubscribe, @event); return; } } - // 往es 写推送日志 - await _trackPushRecordsRepository.AddAsync(log); - // 同步去更新订单主表 await TrackPushAfterUpdateOrderAsync(new TrackPushAfterUpdateOrderDto { From 04ef34548128f28f0d41516eebc0a85e67e8f17b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=B9=8F=E5=86=9B?= <2357729423@qq.com> Date: Tue, 23 Apr 2024 12:00:53 +0800 Subject: [PATCH 38/72] =?UTF-8?q?opt=EF=BC=9A=E6=8B=86=E5=8C=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../EventHandlers/TrackDeleteEventHandler.cs | 17 ++++++-- .../EventHandlers/TrackUpsertEventHandler.cs | 29 +++++++++---- src/SJZY.Track.Domain/Consts/GlobalConst.cs | 1 + .../Repositories/TrackDetailsRepository.cs | 42 ++++++++++++++++--- 4 files changed, 71 insertions(+), 18 deletions(-) diff --git a/src/SJZY.Track.Application/EventHandlers/TrackDeleteEventHandler.cs b/src/SJZY.Track.Application/EventHandlers/TrackDeleteEventHandler.cs index e9ed2dec..5272757f 100644 --- a/src/SJZY.Track.Application/EventHandlers/TrackDeleteEventHandler.cs +++ b/src/SJZY.Track.Application/EventHandlers/TrackDeleteEventHandler.cs @@ -49,7 +49,6 @@ public class TrackDeleteEventHandler : ITransientDependency, ICapSubscribe nextEvent.Visited.AddRange(@event.OrderIds); nextEvent.TrackCodes = @event.TrackCodes; nextEvent.SubSystemId = group.Key; - nextEvent.OrderIds = group.Select(x => x.OrderId).ToArray(); // 不同子系统需要做内容映射 if (@event.SubSystemId != nextEvent.SubSystemId) @@ -60,13 +59,25 @@ public class TrackDeleteEventHandler : ITransientDependency, ICapSubscribe if (mapCodes.Count == 0) { //throw new BusinessException(message: "订单跨子系统,未配置内容映射,请联系管理员"); - return; + continue; } nextEvent.TrackCodes = mapCodes; } - await _capPublisher.PublishAsync(GlobalConst.TrackDeleteSubscribe, nextEvent); + var identifiers = group.Select(x => x.OrderId).ToList(); + var idx = 0; + while (idx < identifiers.Count) + { + var subEvent = nextEvent.DeepCopy(); + var cnt = idx + GlobalConst.ChunkSize > identifiers.Count + ? identifiers.Count - idx + : GlobalConst.ChunkSize; + subEvent.OrderIds = identifiers.GetRange(idx, cnt).ToArray(); + idx += GlobalConst.ChunkSize; + + await _capPublisher.PublishAsync(GlobalConst.TrackUpsertSubscribe, subEvent); + } } } } diff --git a/src/SJZY.Track.Application/EventHandlers/TrackUpsertEventHandler.cs b/src/SJZY.Track.Application/EventHandlers/TrackUpsertEventHandler.cs index f7746db2..fc282668 100644 --- a/src/SJZY.Track.Application/EventHandlers/TrackUpsertEventHandler.cs +++ b/src/SJZY.Track.Application/EventHandlers/TrackUpsertEventHandler.cs @@ -53,12 +53,6 @@ public class TrackUpsertEventHandler : ITransientDependency, ICapSubscribe var nextEvent = @event.DeepCopy(); nextEvent.Visited.AddRange(orderIds); nextEvent.SubSystemId = group.Key; - nextEvent.OrderIdentifiers = group.Select(x => new OrderIdentifier - { - OrderId = x.OrderId, - OrderNo = x.OrderNo, - OrderType = x.OrderType - }).ToArray(); nextEvent.TrackRefreshData = new TrackRefreshStruct { ServiceProviderName = @event.TrackRefreshData.ServiceProviderName, @@ -78,13 +72,30 @@ public class TrackUpsertEventHandler : ITransientDependency, ICapSubscribe if (mapCode == default) { // 跨子系统没做映射的轨迹不处理 - return; + continue; } nextEvent.TrackCode = mapCode; } - await _capPublisher.PublishAsync(GlobalConst.TrackUpsertSubscribe, nextEvent); + var identifiers = group.Select(x => new OrderIdentifier + { + OrderId = x.OrderId, + OrderNo = x.OrderNo, + OrderType = x.OrderType + }).ToList(); + var idx = 0; + while (idx < identifiers.Count) + { + var subEvent = nextEvent.DeepCopy(); + var cnt = idx + GlobalConst.ChunkSize > identifiers.Count + ? identifiers.Count - idx + : GlobalConst.ChunkSize; + subEvent.OrderIdentifiers = identifiers.GetRange(idx, cnt).ToArray(); + idx += GlobalConst.ChunkSize; + + await _capPublisher.PublishAsync(GlobalConst.TrackUpsertSubscribe, subEvent); + } } } } @@ -94,7 +105,7 @@ public class TrackUpsertEventHandler : ITransientDependency, ICapSubscribe var orderIds = @event.OrderIdentifiers.Select(x => x.OrderId).ToArray(); var tracks = await _trackDetailsRepository.GetListAsync(orderIds, @event.TrackCode); - TrackDetailsIndex firstTrack = null; + TrackDetailsIndex? firstTrack = null; var insertTracks = new List(); diff --git a/src/SJZY.Track.Domain/Consts/GlobalConst.cs b/src/SJZY.Track.Domain/Consts/GlobalConst.cs index ec269ee2..22beb8e1 100644 --- a/src/SJZY.Track.Domain/Consts/GlobalConst.cs +++ b/src/SJZY.Track.Domain/Consts/GlobalConst.cs @@ -4,4 +4,5 @@ public partial class GlobalConst { public const string SystemUser = "系统"; public const string EmptyString = "--"; + public const int ChunkSize = 100; } \ No newline at end of file diff --git a/src/SJZY.Track.Repository/Repositories/TrackDetailsRepository.cs b/src/SJZY.Track.Repository/Repositories/TrackDetailsRepository.cs index 644beb65..fdd64ce4 100644 --- a/src/SJZY.Track.Repository/Repositories/TrackDetailsRepository.cs +++ b/src/SJZY.Track.Repository/Repositories/TrackDetailsRepository.cs @@ -28,6 +28,11 @@ internal class TrackDetailsRepository : ElasticSearchContextAbstract(x => x + var r = await Context.SearchAsync(x => x .Source(s => s.Includes(fd => fd .Field(f => f.TrackEnContent) .Field(f => f.TrackContent) @@ -74,7 +79,12 @@ internal class TrackDetailsRepository : ElasticSearchContextAbstract AnyAsync(int orderId, DateTime trackTime) @@ -87,6 +97,11 @@ internal class TrackDetailsRepository : ElasticSearchContextAbstract 0; } @@ -100,6 +115,11 @@ internal class TrackDetailsRepository : ElasticSearchContextAbstract 0; } @@ -150,7 +170,7 @@ internal class TrackDetailsRepository : ElasticSearchContextAbstract(); - var data = await Context.SearchAsync(x => x + var r = await Context.SearchAsync(x => x .Source(s => s.Includes(fd => fd .Field(f => f.OrderNo) .Field(f => f.TrackStatus) @@ -170,19 +190,29 @@ internal class TrackDetailsRepository : ElasticSearchContextAbstract> GetListAsync(int orderId) { - var data = await Context.SearchAsync(x => x + var r = await Context.SearchAsync(x => x .Query(q => q.Term(t => t.OrderId, orderId) ) .Size(1000) .Sort(s => s.Field(f => f.ZeroTrackTime, SortOrder.Descending))); - return data.Documents.ToList(); + if (!r.IsValid) + { + throw new Exception($"轨迹查询,原因:{r.DebugInformation}。"); + } + + return r.Documents.ToList(); } public async Task DeleteTrackAsync(int[] orderIds, List trackCodes) From d5846f2b27c5e9ee0c2788226c13f2fd69f450e5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=B9=8F=E5=86=9B?= <2357729423@qq.com> Date: Tue, 23 Apr 2024 12:34:36 +0800 Subject: [PATCH 39/72] attach --- .../EventHandlers/TrackDeleteEventHandler.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/SJZY.Track.Application/EventHandlers/TrackDeleteEventHandler.cs b/src/SJZY.Track.Application/EventHandlers/TrackDeleteEventHandler.cs index 5272757f..40684c57 100644 --- a/src/SJZY.Track.Application/EventHandlers/TrackDeleteEventHandler.cs +++ b/src/SJZY.Track.Application/EventHandlers/TrackDeleteEventHandler.cs @@ -76,7 +76,7 @@ public class TrackDeleteEventHandler : ITransientDependency, ICapSubscribe subEvent.OrderIds = identifiers.GetRange(idx, cnt).ToArray(); idx += GlobalConst.ChunkSize; - await _capPublisher.PublishAsync(GlobalConst.TrackUpsertSubscribe, subEvent); + await _capPublisher.PublishAsync(GlobalConst.TrackDeleteSubscribe, subEvent); } } } From 141e6f1ee7c635e3c12341b7a3dbb2e8204d11cf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=B9=8F=E5=86=9B?= <2357729423@qq.com> Date: Wed, 24 Apr 2024 09:37:32 +0800 Subject: [PATCH 40/72] =?UTF-8?q?fix=EF=BC=9A=E6=89=B9=E9=87=8F=E5=88=A0?= =?UTF-8?q?=E9=99=A4=E8=BD=A8=E8=BF=B9=E4=BB=A3=E7=A0=81=E9=87=8D=E5=A4=8D?= =?UTF-8?q?=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Services/ProvideServices/TrackService.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/SJZY.Track.Application/Services/ProvideServices/TrackService.cs b/src/SJZY.Track.Application/Services/ProvideServices/TrackService.cs index 1d20b169..eba2ef6c 100644 --- a/src/SJZY.Track.Application/Services/ProvideServices/TrackService.cs +++ b/src/SJZY.Track.Application/Services/ProvideServices/TrackService.cs @@ -186,7 +186,7 @@ public partial class TrackService : ApplicationService, ITrackService var @event = new TrackDeleteEvent { OrderIds = group.Select(x => x.OrderId).ToArray(), - TrackCodes = codes.Select(x => x.TrackCode).ToList(), + TrackCodes = input.TrackCodes, SubSystemId = orders.First(x => x.Id == group.Key).SubSystemId, OperationMan = CurrentUserRequest.CurrentUser.Name }; From ae1b7852732077b8a6bd34cee109fe4baa80f1cf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=B9=8F=E5=86=9B?= <2357729423@qq.com> Date: Wed, 24 Apr 2024 10:40:26 +0800 Subject: [PATCH 41/72] =?UTF-8?q?try=EF=BC=9Aupdate-by-query=E5=AE=9E?= =?UTF-8?q?=E7=8E=B0bulk=20del?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Repositories/TrackDetailsRepository.cs | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/src/SJZY.Track.Repository/Repositories/TrackDetailsRepository.cs b/src/SJZY.Track.Repository/Repositories/TrackDetailsRepository.cs index fdd64ce4..3e12410f 100644 --- a/src/SJZY.Track.Repository/Repositories/TrackDetailsRepository.cs +++ b/src/SJZY.Track.Repository/Repositories/TrackDetailsRepository.cs @@ -217,13 +217,15 @@ internal class TrackDetailsRepository : ElasticSearchContextAbstract trackCodes) { - var r = await Context.DeleteByQueryAsync(x => x - .Query( - q => - q.Terms(t => t.Field(f => f.OrderId).Terms(orderIds)) - && q.Term(t => t.IsCanDelete, true) - && q.Terms(t => t.Field(f => f.TrackCode.Suffix("keyword")).Terms(trackCodes))) - //.Refresh(Refresh.True) // 可选:立即刷新索引使更改立即可见 + var r = await Context.UpdateByQueryAsync(x => x + .Script(s => s + .Source("ctx.op = 'delete'") + ) + .Query( + q => + q.Terms(t => t.Field(f => f.OrderId).Terms(orderIds)) + && q.Term(t => t.IsCanDelete, true) + && q.Terms(t => t.Field(f => f.TrackCode.Suffix("keyword")).Terms(trackCodes))) ); if (!r.IsValid) From 9bf4150990d073c324f56edfb585f7ff3bfe0037 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=B9=8F=E5=86=9B?= <2357729423@qq.com> Date: Wed, 24 Apr 2024 11:13:05 +0800 Subject: [PATCH 42/72] =?UTF-8?q?try=EF=BC=9Aes=E6=89=B9=E9=87=8Fdel?= =?UTF-8?q?=E7=A6=81=E6=AD=A2=E5=86=B2=E7=AA=81=E6=A3=80=E6=B5=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Repositories/TrackDetailsRepository.cs | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/SJZY.Track.Repository/Repositories/TrackDetailsRepository.cs b/src/SJZY.Track.Repository/Repositories/TrackDetailsRepository.cs index 3e12410f..4622534e 100644 --- a/src/SJZY.Track.Repository/Repositories/TrackDetailsRepository.cs +++ b/src/SJZY.Track.Repository/Repositories/TrackDetailsRepository.cs @@ -1,3 +1,4 @@ +using Elasticsearch.Net; using Nest; using SJZY.Expand.ElasticSearch.Services; using SJZY.Track.Domain.Aggregates.TrackDetailsAggregate; @@ -217,10 +218,8 @@ internal class TrackDetailsRepository : ElasticSearchContextAbstract trackCodes) { - var r = await Context.UpdateByQueryAsync(x => x - .Script(s => s - .Source("ctx.op = 'delete'") - ) + var r = await Context.DeleteByQueryAsync(x => x + .Conflicts(Conflicts.Proceed) .Query( q => q.Terms(t => t.Field(f => f.OrderId).Terms(orderIds)) From 5ab91c3d8cf69067ea7f16cbc46f5abf3072e954 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=B9=8F=E5=86=9B?= <2357729423@qq.com> Date: Wed, 24 Apr 2024 17:49:31 +0800 Subject: [PATCH 43/72] temp --- .../Dtos/TrackPush/TrackPushInput.cs | 11 + .../Events/OrderIdentifier.cs | 2 + .../Events/TrackPushEvent.cs | 54 +-- .../Events/TrackUpsertEvent.cs | 4 +- .../Services/ITrackPushCacheService.cs | 22 -- .../EventHandlers/TrackDeleteEventHandler.cs | 2 +- .../TrackPushCompletedEventHandler.cs | 85 +++++ .../EventHandlers/TrackPushEventHandler.cs | 334 +++++++++--------- .../EventHandlers/TrackRefreshEventHandler.cs | 12 +- .../EventHandlers/TrackUpsertEventHandler.cs | 54 +-- .../SJZY.Track.Application.csproj | 2 +- .../ProvideServices/OrderService.Link.cs | 5 +- .../ProvideServices/TrackPullService.cs | 3 +- .../ProvideServices/TrackPushService.cs | 43 +-- .../Services/ProvideServices/TrackService.cs | 16 +- .../TrackPush/TrackPushCacheService.cs | 28 -- .../ITrackDetailsRepository.cs | 2 + .../ITrackPushRecordsRepository.cs | 2 + .../TrackPushRecordIndex.cs | 5 + .../Consts/GlobalConst.MQ.cs | 5 + .../Dtos/Order/LinkedOrderVO.cs | 5 + .../Repositories/OrderRepository.cs | 3 +- .../Repositories/TrackDetailsRepository.cs | 38 +- .../TrackPushRecordsRepository.cs | 18 + 24 files changed, 436 insertions(+), 319 deletions(-) create mode 100644 src/SJZY.Track.Application/EventHandlers/TrackPushCompletedEventHandler.cs diff --git a/src/SJZY.Track.Application.Contract/Dtos/TrackPush/TrackPushInput.cs b/src/SJZY.Track.Application.Contract/Dtos/TrackPush/TrackPushInput.cs index 7875d4da..bc1d10bc 100644 --- a/src/SJZY.Track.Application.Contract/Dtos/TrackPush/TrackPushInput.cs +++ b/src/SJZY.Track.Application.Contract/Dtos/TrackPush/TrackPushInput.cs @@ -5,6 +5,17 @@ public class TrackPushInput public string OrderNo { get; set; } = null!; public List Data { get; set; } = new(); + + public string Log { get; set; } +} + +public class TrackUpdateInput +{ + public string OrderNo { get; set; } = null!; + + public List Data { get; set; } = new(); + + public string Log { get; set; } } public class TrackItem diff --git a/src/SJZY.Track.Application.Contract/Events/OrderIdentifier.cs b/src/SJZY.Track.Application.Contract/Events/OrderIdentifier.cs index 49e79b04..158e64b1 100644 --- a/src/SJZY.Track.Application.Contract/Events/OrderIdentifier.cs +++ b/src/SJZY.Track.Application.Contract/Events/OrderIdentifier.cs @@ -5,4 +5,6 @@ public struct OrderIdentifier public int OrderId { get; set; } public string OrderNo { get; set; } public int OrderType { get; set; } + + public int CustomId { get; set; } } \ No newline at end of file diff --git a/src/SJZY.Track.Application.Contract/Events/TrackPushEvent.cs b/src/SJZY.Track.Application.Contract/Events/TrackPushEvent.cs index 43156556..b2724e3d 100644 --- a/src/SJZY.Track.Application.Contract/Events/TrackPushEvent.cs +++ b/src/SJZY.Track.Application.Contract/Events/TrackPushEvent.cs @@ -2,45 +2,58 @@ public class TrackPushEvent { - /// - /// 重试次数 - /// - public int RetryNum { get; set; } - /// /// 操作类型 /// public OptionType OptionType { get; set; } + /// + /// 子系统id + /// + public int SubSystemId { get; set; } + + /// + /// 客户id + /// + public int CustomId { get; set; } + /// /// 订单id /// - public int OrderId { get; set; } - - /// - /// 订单号 - /// - public string OrderNo { get; set; } = null!; - - /// - /// 轨迹状态 - /// - public string TrackStatus { get; set; } = null!; + public int[] OrderIds { get; set; } = null!; /// /// 轨迹代码(我们系统的) /// public string TrackCode { get; set; } = null!; + /// + /// 操作人 + /// + public string? OperationMan { get; set; } + + /// + /// 系统推送信息 + /// + public SystemPushStruct SystemPushInfo { get; set; } +} + +public struct SystemPushStruct +{ + /// + /// 轨迹状态 + /// + public string TrackStatus { get; set; } + /// /// 轨迹内容 /// - public string TrackContent { get; set; } = null!; + public string TrackContent { get; set; } /// /// 轨迹发生地 /// - public string TrackPlace { get; set; } = null!; + public string TrackPlace { get; set; } /// /// 轨迹发生时间 @@ -51,9 +64,4 @@ public class TrackPushEvent /// 轨迹发生时区 /// public float TrackTimeZone { get; set; } - - /// - /// 操作人 - /// - public string? OperationMan { get; set; } } \ No newline at end of file diff --git a/src/SJZY.Track.Application.Contract/Events/TrackUpsertEvent.cs b/src/SJZY.Track.Application.Contract/Events/TrackUpsertEvent.cs index 3b449bbf..905060ea 100644 --- a/src/SJZY.Track.Application.Contract/Events/TrackUpsertEvent.cs +++ b/src/SJZY.Track.Application.Contract/Events/TrackUpsertEvent.cs @@ -18,9 +18,9 @@ public class TrackUpsertEvent public string? OperationMan { get; set; } /// - /// true新增,false更新,null表示刷新 + /// true新增,false更新 /// - public bool? IsAdd { get; set; } + public bool IsAdd { get; set; } /// /// 轨迹内容代码 diff --git a/src/SJZY.Track.Application.Contract/Services/ITrackPushCacheService.cs b/src/SJZY.Track.Application.Contract/Services/ITrackPushCacheService.cs index 8928ae11..d243a7a0 100644 --- a/src/SJZY.Track.Application.Contract/Services/ITrackPushCacheService.cs +++ b/src/SJZY.Track.Application.Contract/Services/ITrackPushCacheService.cs @@ -19,26 +19,4 @@ public interface ITrackPushCacheService /// /// Task?> SetPushContentConfigsAsync(int subSystemId, int customId); - - /// - /// 获取服务商拉取配置 - /// - /// 子系统id - /// 服务商id - /// 轨迹代码 - /// - Task GetPushContentConfigAsync(int subSystemId, int customId, string trackConde); - - /// - /// 根据轨迹代码推断下一个(升序)要推送的内容,如果找不到或者已经是最后一个了 - /// 则查询有没有可交换的推送,没有就返回null - /// - /// - /// - /// - /// - /// - Task IsValidPushAsync(int subSystemId, int customId, - string? latestPushTrackCode, - string? trackCode); } \ No newline at end of file diff --git a/src/SJZY.Track.Application/EventHandlers/TrackDeleteEventHandler.cs b/src/SJZY.Track.Application/EventHandlers/TrackDeleteEventHandler.cs index 40684c57..46b87f8b 100644 --- a/src/SJZY.Track.Application/EventHandlers/TrackDeleteEventHandler.cs +++ b/src/SJZY.Track.Application/EventHandlers/TrackDeleteEventHandler.cs @@ -32,7 +32,7 @@ public class TrackDeleteEventHandler : ITransientDependency, ICapSubscribe var dup = @event.Visited.Intersect(@event.OrderIds).ToArray(); if (dup.Any()) { - LogHelper.Error($"删除轨迹订单时,发现循环依赖:{dup.JoinAsString(",")}"); + LogHelper.Error($"删除轨迹时,发现循环依赖:{dup.JoinAsString(",")}"); return; } diff --git a/src/SJZY.Track.Application/EventHandlers/TrackPushCompletedEventHandler.cs b/src/SJZY.Track.Application/EventHandlers/TrackPushCompletedEventHandler.cs new file mode 100644 index 00000000..cfa667a9 --- /dev/null +++ b/src/SJZY.Track.Application/EventHandlers/TrackPushCompletedEventHandler.cs @@ -0,0 +1,85 @@ +using DotNetCore.CAP; +using Newtonsoft.Json; +using SJZY.InterfaceRelay.Application.Contracts; +using SJZY.Track.Domain.Aggregates.OrderAggregate; +using SJZY.Track.Domain.Aggregates.TrackPushAggregate; +using SJZY.Track.Domain.Consts; +using SJZY.Track.Domain.Enums; +using Volo.Abp.DependencyInjection; + +namespace SJZY.Track.Application.EventHandlers; + +public class TrackPushCompletedEventHandler : ITransientDependency, ICapSubscribe +{ + private readonly ITrackPushRecordsRepository _trackPushRecordsRepository; + private readonly IOrderRepository _orderRepository; + + public TrackPushCompletedEventHandler(ITrackPushRecordsRepository trackPushRecordsRepository, + IOrderRepository orderRepository) + { + _trackPushRecordsRepository = trackPushRecordsRepository; + _orderRepository = orderRepository; + } + + [CapSubscribe(GlobalConst.TrackPushCompletedSubscribe, Group = GlobalConst.TrackPushSubscribe)] + public async Task ConsumerAsync(InterfaceRelayForwardReplayEvent @event) + { + var log = JsonConvert.DeserializeObject(@event.RequestParams); + if (log == null) throw new BusinessException(message: "轨迹推送返回结果解析异常"); + log.IsSuccess = @event.IsSuccess; + log.Message = @event.Message; + log.RequestId = @event.RequestId; + + // 往es 写推送日志 + await _trackPushRecordsRepository.AddAsync(log); + + // if (!log.IsSuccess) + // { + // // 重试过程中不会去更新订单主表 + // if (@event.RetryNum < 3) + // { + // @event.RetryNum++; + // await _capPublisher.PublishAsync(GlobalConst.TrackPushSubscribe, @event); + // return; + // } + // } + + // 同步去更新订单主表 + await TrackPushAfterUpdateOrderAsync(log); + } + + private async Task TrackPushAfterUpdateOrderAsync(TrackPushRecordIndex log) + { + var order = new OrderEntity(); + order.Id = log.OrderId; + /* + * 异常:最近一条推送是失败 + */ + if (!log.IsSuccess) + { + order.QuestionType = (int)TrackProblemType.Error; + order.LatestPushError = log.Message; + } + else + { + order.QuestionType = (int)TrackProblemType.None; + order.LatestPushError = null; + if (log.OptionType == OptionType.新增.ToString()) + { + // tips:只有新增会影响推送进度? + order.LatestPushTrackCode = log.TrackCode; + order.LatestPushTime = DateTime.Now; + await _orderRepository.UpdateColumnAsync(order, x => new + { + x.LatestPushTrackCode, x.LatestPushTime, x.QuestionType, x.LatestPushError + }); + return; + } + } + + await _orderRepository.UpdateColumnAsync(order, x => new + { + x.QuestionType, x.LatestPushError + }); + } +} \ No newline at end of file diff --git a/src/SJZY.Track.Application/EventHandlers/TrackPushEventHandler.cs b/src/SJZY.Track.Application/EventHandlers/TrackPushEventHandler.cs index ceed798d..4eb337ba 100644 --- a/src/SJZY.Track.Application/EventHandlers/TrackPushEventHandler.cs +++ b/src/SJZY.Track.Application/EventHandlers/TrackPushEventHandler.cs @@ -6,6 +6,7 @@ using SJZY.Track.Application.Contract.Dtos.TrackPush; 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.Aggregates.TrackPushAggregate; using SJZY.Track.Domain.Consts; using SJZY.Track.Domain.Enums; @@ -17,212 +18,176 @@ namespace SJZY.Track.Application.EventHandlers; public class TrackPushEventHandler : ITransientDependency, ICapSubscribe { private readonly IHttpClientProxy _httpClientProxy; - private readonly ITrackPushRecordsRepository _trackPushRecordsRepository; private readonly IOrderRepository _orderRepository; private readonly ITrackPushCacheService _trackPushCacheService; - private readonly ICapPublisher _capPublisher; + private readonly ITrackDetailsRepository _trackDetailsRepository; + private readonly ITrackPushRecordsRepository _trackPushRecordsRepository; + private List _pushConfigs; + private List _orders; public TrackPushEventHandler(IHttpClientProxy httpClientProxy, - ITrackPushRecordsRepository trackPushRecordsRepository, - IOrderRepository orderRepository, ITrackPushCacheService trackPushCacheService, ICapPublisher capPublisher) + IOrderRepository orderRepository, ITrackPushCacheService trackPushCacheService, + ITrackDetailsRepository trackDetailsRepository, ITrackPushRecordsRepository trackPushRecordsRepository) { _httpClientProxy = httpClientProxy; - _trackPushRecordsRepository = trackPushRecordsRepository; _orderRepository = orderRepository; _trackPushCacheService = trackPushCacheService; - _capPublisher = capPublisher; + _trackDetailsRepository = trackDetailsRepository; + _trackPushRecordsRepository = trackPushRecordsRepository; } [CapSubscribe(GlobalConst.TrackPushSubscribe, Group = GlobalConst.TrackPushSubscribe)] public async Task ConsumerAsync(TrackPushEvent @event) { - var order = await _orderRepository.GetFirstAsync(x => - x.Id == @event.OrderId, x => new + var pushConfigs = await _trackPushCacheService.GetPushContentConfigsAsync(@event.SubSystemId, @event.CustomId); + if (pushConfigs == null || pushConfigs.Count == 0) return; + _pushConfigs = pushConfigs; + + var errorType = (int)TrackProblemType.Error; + var orders = await _orderRepository.GetListAsync(x => + @event.OrderIds.Contains(x.Id) && x.QuestionType != errorType, x => new OrderEntity { - x.SubSystemId, x.LatestPushTrackCode, x.QuestionType, x.CustomId, x.OrderType + Id = x.Id, OrderNo = x.OrderNo, LatestPushTrackCode = x.LatestPushTrackCode, + OrderType = x.OrderType }); - if (order == null) return; - - var log = new TrackPushRecordIndex - { - IndexName = $"{GlobalConst.TrackPushRecordsIndex}-{DateTime.Now:yyyy.MM.dd}", - OptionType = @event.OptionType.ToString(), - OrderId = @event.OrderId, - TrackStatus = @event.TrackStatus, - TrackCode = @event.TrackCode, - TrackContent = @event.TrackContent, - TrackPlace = @event.TrackPlace, - TrackTime = @event.TrackTime, - TrackTimeZone = @event.TrackTimeZone, - CreateUser = @event.OperationMan ?? GlobalConst.SystemUser, - CreateTime = DateTime.Now - }; - - TrackPushContentConfigDto? config = null; + if (orders.Count == 0) return; + _orders = orders; switch (@event.OptionType) { case OptionType.无: return; case OptionType.新增: - if (@event.OperationMan == null) - { - if (order.QuestionType != (int)TrackProblemType.Error) - { - // 推送新增,需要根据上一次的推送 推断 本次推送 是否可行 - config = await _trackPushCacheService.IsValidPushAsync(order.SubSystemId, order.CustomId, - order.LatestPushTrackCode, @event.TrackCode); - if (config == null) return; - if (!config.IsAutoPush) return; - if (config.OrderType != order.OrderType) return; - } - } - else - { - // 手工推送单条不推断,直接无脑推 - config = await _trackPushCacheService.GetPushContentConfigAsync(order.SubSystemId, order.CustomId, - @event.TrackCode); - if (config is { IsAllPush: true }) - { - // 推断 本次推送 是否可行 - config = await _trackPushCacheService.IsValidPushAsync(order.SubSystemId, order.CustomId, - order.LatestPushTrackCode, @event.TrackCode); - } - } - - if (config == null) return; - await DoAddAsync(@event, config, log); + await DoPushAsync(@event); break; case OptionType.删除: break; case OptionType.修改: - config = await _trackPushCacheService.GetPushContentConfigAsync(order.SubSystemId, order.CustomId, - @event.TrackCode); - if (config == null || !config.IsCanUpdate) return; - await DoUpdateAsync(@event, config, log); + await DoUpdateAsync(@event); break; default: throw new ArgumentOutOfRangeException(); } - - // 往es 写推送日志 - await _trackPushRecordsRepository.AddAsync(log); - - if (!log.IsSuccess) - { - // 重试过程中不会去更新订单主表 - if (@event.RetryNum < 3) - { - @event.RetryNum++; - await _capPublisher.PublishAsync(GlobalConst.TrackPushSubscribe, @event); - return; - } - } - - // 同步去更新订单主表 - await TrackPushAfterUpdateOrderAsync(new TrackPushAfterUpdateOrderDto - { - OptionType = @event.OptionType, - OrderId = @event.OrderId, - TrackCode = @event.TrackCode, - IsSuccess = log.IsSuccess, - Message = log.Message - }); } - private async Task TrackPushAfterUpdateOrderAsync(TrackPushAfterUpdateOrderDto dto) + private async Task DoPushAsync(TrackPushEvent @event) { - var order = new OrderEntity(); - order.Id = dto.OrderId; - /* - * 异常:最近一条推送是失败 - */ - if (!dto.IsSuccess) + var logs = new List(); + TrackPushContentConfigDto? config; + + if (@event.OperationMan == null) { - order.QuestionType = (int)TrackProblemType.Error; - order.LatestPushError = dto.Message; - } - else - { - order.QuestionType = (int)TrackProblemType.None; - order.LatestPushError = null; - if (dto.OptionType == OptionType.新增) + foreach (var order in _orders) { - // tips:只有新增会影响推送进度? - order.LatestPushTrackCode = dto.TrackCode; - order.LatestPushTime = DateTime.Now; - await _orderRepository.UpdateColumnAsync(order, x => new + // 推送新增,需要根据上一次的推送 推断 本次推送 是否可行 + config = GetValidPushConfigAsync(_pushConfigs, order.LatestPushTrackCode, @event.TrackCode); + if (config == null) continue; + if (!config.IsAutoPush) continue; + if (config.OrderType != order.OrderType) continue; + + var log = new TrackPushRecordIndex { - x.LatestPushTrackCode, x.LatestPushTime, x.QuestionType, x.LatestPushError - }); - return; + OptionType = @event.OptionType.ToString(), + OrderId = order.Id, + OrderNo = order.OrderNo, + TrackStatus = @event.SystemPushInfo.TrackStatus, + TrackCode = @event.TrackCode, + TrackContent = @event.SystemPushInfo.TrackContent, + TrackPlace = @event.SystemPushInfo.TrackPlace, + TrackTime = @event.SystemPushInfo.TrackTime, + TrackTimeZone = @event.SystemPushInfo.TrackTimeZone, + CreateUser = GlobalConst.SystemUser, + }; + await BuiltPushItem(config, log); + logs.Add(log); } } - - await _orderRepository.UpdateColumnAsync(order, x => new + else //手工推送 { - x.QuestionType, x.LatestPushError - }); - } + config = _pushConfigs.FirstOrDefault(x => x.TrackCode == @event.TrackCode); + if (config == null) return; - private async Task DoAddAsync(TrackPushEvent @event, - TrackPushContentConfigDto config, TrackPushRecordIndex log) - { - var track = new TrackItem - { - // 推真实的发生地和发生时间(时间是计算后的) - Location = @event.TrackPlace, - Date = @event.TrackTime.AddHours( - config.TrackTimeZone ?? @event.TrackTimeZone - @event.TrackTimeZone), - TimeZone = config.TrackTimeZone ?? @event.TrackTimeZone, - Description = config.TrackEnContentValue, - DescriptionCn = config.TrackContentValue, - Code = config.TrackContentCodeValue, - Status = config.TrackStatusValue, - Extra = config.ExpandFieldsValue - }; + var tracks = await _trackDetailsRepository.GetListAsync(@event.OrderIds, @event.TrackCode); + tracks = tracks.DistinctBy(x => x.OrderId).ToList(); // 防止重复推送 - var body = new TrackPushInput - { - OrderNo = @event.OrderNo, - }; - body.Data.Add(track); + if (tracks.Count == 0) return; // 一个能推的轨迹都不存在 - if (config.IsAllPush) - { - var history = await _trackPushRecordsRepository.GetLatestTrackPushRecordAsync(@event.OrderId); - if (history != default) + foreach (var track in tracks) { - body = JsonConvert.DeserializeObject(history.PushContent); - body!.Data.Add(track); + var order = _orders.First(x => x.Id == track.OrderId); + if (config is { IsAllPush: true }) + { + // 推断 本次推送 是否可行 + config = GetValidPushConfigAsync(_pushConfigs, order.LatestPushTrackCode, @event.TrackCode); + } + + if (config == null) continue; + + var log = new TrackPushRecordIndex + { + OptionType = @event.OptionType.ToString(), + OrderId = track.OrderId, + OrderNo = order.OrderNo, + TrackStatus = track.TrackStatus, + TrackCode = @event.TrackCode, + TrackContent = track.TrackContent, + TrackPlace = track.TrackPlace, + TrackTime = track.TrackTime, + TrackTimeZone = track.TrackTimeZone, + CreateUser = @event.OperationMan, + }; + await BuiltPushItem(config, log); + logs.Add(log); } } - var res = await _httpClientProxy.Service.ForwardWithSubscribeAsync(InterfaceRelayConst.PushTrackInterfaceCode, - config.ServiceProviderCode, body); - - log.PushContent = body.ToJson(); - - log.IsSuccess = res.Code == InterfaceRelayConst.SuccessCode; - log.RequestId = res.RequestId; - log.Message = res.Msg; + await _httpClientProxy.Service.BatchForwardThenPushToQueueAsync(InterfaceRelayConst.PushTrackInterfaceCode, + _pushConfigs.First().ServiceProviderCode, logs, GlobalConst.TrackPushCompletedSubscribe); } - private async Task DoUpdateAsync(TrackPushEvent @event, - TrackPushContentConfigDto config, TrackPushRecordIndex log) + private async Task DoUpdateAsync(TrackPushEvent @event) + { + var config = _pushConfigs.FirstOrDefault(x => x.TrackCode == @event.TrackCode); + if (config == null || !config.IsCanUpdate) return; + + var logs = new List(); + foreach (var order in _orders) + { + var log = new TrackPushRecordIndex + { + OptionType = @event.OptionType.ToString(), + OrderId = order.Id, + OrderNo = order.OrderNo, + TrackStatus = @event.SystemPushInfo.TrackStatus, + TrackCode = @event.TrackCode, + TrackContent = @event.SystemPushInfo.TrackContent, + TrackPlace = @event.SystemPushInfo.TrackPlace, + TrackTime = @event.SystemPushInfo.TrackTime, + TrackTimeZone = @event.SystemPushInfo.TrackTimeZone, + CreateUser = GlobalConst.SystemUser, + }; + BuiltUpdateItem(config, log); + logs.Add(log); + } + + await _httpClientProxy.Service.BatchForwardThenPushToQueueAsync(InterfaceRelayConst.TrackUpdateInterfaceCode, + _pushConfigs.First().ServiceProviderCode, logs, GlobalConst.TrackPushCompletedSubscribe); + } + + private void BuiltUpdateItem(TrackPushContentConfigDto config, TrackPushRecordIndex log) { var data = new { - orderNo = @event.OrderNo, + orderNo = log.OrderNo, data = new[] { new { // 推真实的发生地和发生时间 - location = @event.TrackPlace, - date = @event.TrackTime.AddHours( - config.TrackTimeZone ?? @event.TrackTimeZone - @event.TrackTimeZone), - timeZone = config.TrackTimeZone ?? @event.TrackTimeZone, + location = log.TrackPlace, + date = log.TrackTime.AddHours( + config.TrackTimeZone ?? log.TrackTimeZone - log.TrackTimeZone), + timeZone = config.TrackTimeZone ?? log.TrackTimeZone, description = config.TrackEnContentValue, description_cn = config.TrackContentValue, code = config.TrackContentCodeValue, @@ -232,13 +197,66 @@ public class TrackPushEventHandler : ITransientDependency, ICapSubscribe } }; - - var res = await _httpClientProxy.Service.ForwardWithSubscribeAsync(InterfaceRelayConst.TrackUpdateInterfaceCode, - config.ServiceProviderCode, data); - log.PushContent = data.ToJson(); - log.IsSuccess = res.Code == InterfaceRelayConst.SuccessCode; - log.RequestId = res.RequestId; - log.Message = res.Msg; + } + + private async Task BuiltPushItem(TrackPushContentConfigDto config, TrackPushRecordIndex log) + { + var track = new TrackItem + { + // 推真实的发生地和发生时间(时间是计算后的) + Location = log.TrackPlace, + Date = log.TrackTime.AddHours( + config.TrackTimeZone ?? log.TrackTimeZone - log.TrackTimeZone), + TimeZone = config.TrackTimeZone ?? log.TrackTimeZone, + Description = config.TrackEnContentValue, + DescriptionCn = config.TrackContentValue, + Code = config.TrackContentCodeValue, + Status = config.TrackStatusValue, + Extra = config.ExpandFieldsValue + }; + + var body = new TrackPushInput + { + OrderNo = log.OrderNo, + }; + body.Data.Add(track); + + if (config.IsAllPush) + { + var history = await _trackPushRecordsRepository.GetLatestTrackPushRecordAsync(log.OrderId); + if (history != default) + { + body = JsonConvert.DeserializeObject(history.PushContent); + body!.Data.Add(track); + } + } + + log.PushContent = body.ToJson(); + } + + /// + /// 根据轨迹代码推断下一个(升序)要推送的内容,如果找不到或者已经是最后一个了 + /// 则查询有没有可交换的推送,没有就返回null + /// + /// + /// + /// + /// + TrackPushContentConfigDto? GetValidPushConfigAsync(List cache, + string? latestPushTrackCode, string? trackCode) + { + var idx = cache.FindIndex(x => x.TrackCode == latestPushTrackCode); + + if (idx + 1 >= cache.Count) return default; // 推完了 + + // find next + var matched = cache[idx + 1].TrackCode == trackCode + ? cache[idx + 1] + : + // find swap + cache.FirstOrDefault(x => x.TrackCode == cache[idx + 1].SwapTrackCode); + + return matched != null && matched.TrackCode == trackCode ? matched : default; } } \ No newline at end of file diff --git a/src/SJZY.Track.Application/EventHandlers/TrackRefreshEventHandler.cs b/src/SJZY.Track.Application/EventHandlers/TrackRefreshEventHandler.cs index 4c132e26..ea34f0e6 100644 --- a/src/SJZY.Track.Application/EventHandlers/TrackRefreshEventHandler.cs +++ b/src/SJZY.Track.Application/EventHandlers/TrackRefreshEventHandler.cs @@ -36,6 +36,7 @@ public class TrackRefreshEventHandler : ITransientDependency, ICapSubscribe [CapSubscribe(GlobalConst.TrackRefreshSubscribe, Group = GlobalConst.TrackRefreshSubscribe)] public async Task ConsumerAsync(InterfaceRelayForwardReplayEvent @event) { + if (!@event.IsSuccess) return; var attach = Base64Helper.DeSerialize(@event.Attach); if (attach is null) return; @@ -222,15 +223,16 @@ public class TrackRefreshEventHandler : ITransientDependency, ICapSubscribe // 新增/更新轨迹 var trackUpsertEvent = new TrackUpsertEvent { - OrderIdentifiers = new[] - { + OrderIdentifiers = + [ new OrderIdentifier { OrderId = context.OrderId, OrderNo = context.OrderNo, - OrderType = context.OrderType + OrderType = context.OrderType, + CustomId = context.CustomId } - }, + ], TrackRefreshData = new TrackRefreshStruct { ServiceProviderName = context.ServiceProviderName, @@ -247,6 +249,8 @@ public class TrackRefreshEventHandler : ITransientDependency, ICapSubscribe TrackTimeZone = trackTimeZone ?? matchedContentConfig.TrackTimeZoneValue ?? 8 }; + trackUpsertEvent.IsAdd = + !await _trackDetailsRepository.AnyByCodeAsync(context.OrderId, matchedContentConfig.TrackContentCode); await _capPublisher.PublishAsync(GlobalConst.TrackUpsertForRefreshSubscribe, trackUpsertEvent); } } \ No newline at end of file diff --git a/src/SJZY.Track.Application/EventHandlers/TrackUpsertEventHandler.cs b/src/SJZY.Track.Application/EventHandlers/TrackUpsertEventHandler.cs index fc282668..937c0a21 100644 --- a/src/SJZY.Track.Application/EventHandlers/TrackUpsertEventHandler.cs +++ b/src/SJZY.Track.Application/EventHandlers/TrackUpsertEventHandler.cs @@ -35,7 +35,7 @@ public class TrackUpsertEventHandler : ITransientDependency, ICapSubscribe var dup = @event.Visited.Intersect(orderIds).ToArray(); if (dup.Any()) { - LogHelper.Error($"删除轨迹订单时,发现循环依赖:{dup.JoinAsString(",")}"); + LogHelper.Error($"{(@event.IsAdd ? "添加" : "修改")}轨迹时,发现循环依赖:{dup.JoinAsString(",")}"); return; } @@ -48,11 +48,11 @@ public class TrackUpsertEventHandler : ITransientDependency, ICapSubscribe { // 理论上小包在这不会分组 foreach (var group in linkedOrders.Where(x => x.OwnerOrderId == order.OrderId) - .GroupBy(x => x.SubSystemId)) + .GroupBy(x => new { x.SubSystemId, x.CustomId })) { var nextEvent = @event.DeepCopy(); nextEvent.Visited.AddRange(orderIds); - nextEvent.SubSystemId = group.Key; + nextEvent.SubSystemId = group.Key.SubSystemId; nextEvent.TrackRefreshData = new TrackRefreshStruct { ServiceProviderName = @event.TrackRefreshData.ServiceProviderName, @@ -82,7 +82,8 @@ public class TrackUpsertEventHandler : ITransientDependency, ICapSubscribe { OrderId = x.OrderId, OrderNo = x.OrderNo, - OrderType = x.OrderType + OrderType = x.OrderType, + CustomId = x.CustomId }).ToList(); var idx = 0; while (idx < identifiers.Count) @@ -113,11 +114,8 @@ public class TrackUpsertEventHandler : ITransientDependency, ICapSubscribe { var track = tracks.FirstOrDefault(x => x.OrderId == order.OrderId); - if (@event.IsAdd != null) - { - if (track == null && !@event.IsAdd!.Value) continue; // 不存在不让改 - if (track != null && @event.IsAdd!.Value) continue; // 存在不让创建 - } + if (track == null && !@event.IsAdd) continue; // 不存在不让改 + if (track != null && @event.IsAdd) continue; // 存在不让创建 if (track == default) { @@ -167,22 +165,6 @@ public class TrackUpsertEventHandler : ITransientDependency, ICapSubscribe await _trackDetailsRepository.UpdateAsync(track); } - // step2、触发轨迹推送事件(异步) - var trackPushEvent = new TrackPushEvent - { - OptionType = track.Id.IsNullOrWhiteSpace() ? OptionType.新增 : OptionType.修改, - OrderId = order.OrderId, - OrderNo = order.OrderNo, - TrackStatus = track.TrackStatus, - TrackCode = track.TrackCode, - TrackContent = track.TrackContent, - TrackPlace = track.TrackPlace, - TrackTime = track.TrackTime, - TrackTimeZone = track.TrackTimeZone, - }; - - await _capPublisher.PublishAsync(GlobalConst.TrackPushSubscribe, trackPushEvent); - canNextOrderIds.Add(order.OrderId); firstTrack ??= track; @@ -205,5 +187,27 @@ public class TrackUpsertEventHandler : ITransientDependency, ICapSubscribe TrackTime = @event.TrackTime, TrackTimeZone = @event.TrackTimeZone }); + + // 触发轨迹推送事件(异步) + foreach (var group in @event.OrderIdentifiers.GroupBy(x => x.CustomId)) + { + var trackPushEvent = new TrackPushEvent + { + OptionType = @event.IsAdd ? OptionType.新增 : OptionType.修改, + SubSystemId = @event.SubSystemId, + CustomId = group.Key, + OrderIds = group.Select(x => x.OrderId).ToArray(), + TrackCode = @event.TrackCode, + SystemPushInfo = new SystemPushStruct + { + TrackStatus = firstTrack.TrackStatus, + TrackContent = firstTrack.TrackContent, + TrackPlace = @event.TrackPlace, + TrackTime = @event.TrackTime, + TrackTimeZone = @event.TrackTimeZone + } + }; + await _capPublisher.PublishAsync(GlobalConst.TrackPushSubscribe, trackPushEvent); + } } } \ No newline at end of file diff --git a/src/SJZY.Track.Application/SJZY.Track.Application.csproj b/src/SJZY.Track.Application/SJZY.Track.Application.csproj index 99912fb3..fba5f4d2 100644 --- a/src/SJZY.Track.Application/SJZY.Track.Application.csproj +++ b/src/SJZY.Track.Application/SJZY.Track.Application.csproj @@ -12,7 +12,7 @@ - + diff --git a/src/SJZY.Track.Application/Services/ProvideServices/OrderService.Link.cs b/src/SJZY.Track.Application/Services/ProvideServices/OrderService.Link.cs index f37ff3b5..e9554da2 100644 --- a/src/SJZY.Track.Application/Services/ProvideServices/OrderService.Link.cs +++ b/src/SJZY.Track.Application/Services/ProvideServices/OrderService.Link.cs @@ -72,7 +72,7 @@ public partial class OrderService // 过滤掉不存在的订单 var canLinkOrders = await _orderRepository.GetListAsync(x => x.OrderType == input.LinkOrderType && noLinkOrderNos.Contains(x.OrderNo), - x => new { x.Id, x.OrderNo, x.OrderType, x.SubSystemId }); + x => new { x.Id, x.OrderNo, x.OrderType, x.SubSystemId, x.CustomId }); if (canLinkOrders.Count == 0) return; @@ -100,7 +100,8 @@ public partial class OrderService { OrderId = x.Id, OrderNo = x.OrderNo, - OrderType = x.OrderType + OrderType = x.OrderType, + CustomId = x.CustomId }).ToArray(), TrackCode = track.TrackCode, TrackPlace = track.TrackPlace, diff --git a/src/SJZY.Track.Application/Services/ProvideServices/TrackPullService.cs b/src/SJZY.Track.Application/Services/ProvideServices/TrackPullService.cs index 354af4e1..d7f71038 100644 --- a/src/SJZY.Track.Application/Services/ProvideServices/TrackPullService.cs +++ b/src/SJZY.Track.Application/Services/ProvideServices/TrackPullService.cs @@ -65,7 +65,8 @@ public class TrackPullService : ApplicationService var attach = Base64Helper.SerializeObject(group.Key); // 批量获取轨迹 var _ = await _httpClientProxy.Service.BatchForwardThenPushToQueueAsync( - "A012", serviceProviderCode, data, GlobalConst.TrackRefreshSubscribe, attach); + InterfaceRelayConst.GetTrackInterfaceCode, serviceProviderCode, data, GlobalConst.TrackRefreshSubscribe, + attach); } return true; diff --git a/src/SJZY.Track.Application/Services/ProvideServices/TrackPushService.cs b/src/SJZY.Track.Application/Services/ProvideServices/TrackPushService.cs index 4a0ef260..8b43e04f 100644 --- a/src/SJZY.Track.Application/Services/ProvideServices/TrackPushService.cs +++ b/src/SJZY.Track.Application/Services/ProvideServices/TrackPushService.cs @@ -3,7 +3,6 @@ using Microsoft.AspNetCore.Authorization; using SJZY.Track.Application.Contract.Dtos.ProvideServices; using SJZY.Track.Application.Contract.Events; using SJZY.Track.Domain.Aggregates.OrderAggregate; -using SJZY.Track.Domain.Aggregates.TrackDetailsAggregate; using SJZY.Track.Domain.Aggregates.TrackPushAggregate; using SJZY.Track.Domain.Consts; using SJZY.UserCenter.HttpApi.Services; @@ -17,17 +16,14 @@ namespace SJZY.Track.Application.Services.ProvideServices; [Route("/ProviderService")] public class TrackPushService : ApplicationService { - private readonly ITrackDetailsRepository _trackDetailsRepository; private readonly IOrderRepository _orderRepository; private readonly ICapPublisher _capPublisher; private readonly ITrackPushRecordsRepository _trackPushRecordsRepository; - public TrackPushService(ITrackDetailsRepository trackDetailsRepository - , IOrderRepository orderRepository + public TrackPushService(IOrderRepository orderRepository , ICapPublisher capPublisher , ITrackPushRecordsRepository trackPushRecordsRepository) { - _trackDetailsRepository = trackDetailsRepository; _orderRepository = orderRepository; _capPublisher = capPublisher; _trackPushRecordsRepository = trackPushRecordsRepository; @@ -51,38 +47,17 @@ public class TrackPushService : ApplicationService throw new BusinessException(message: "一个订单都不存在"); } - var tracks = await _trackDetailsRepository.GetListAsync(orderIds, input.TrackCode); - tracks = tracks.DistinctBy(x => x.OrderId).ToList(); - - if (tracks.Count == 0) + var trackPushEvent = new TrackPushEvent { - throw new BusinessException(message: "一个能推的轨迹都不存在"); - } + OptionType = OptionType.新增, + OrderIds = orderIds, + TrackCode = input.TrackCode, + OperationMan = CurrentUserRequest.CurrentUser.Name, + }; - var res = 0; + await _capPublisher.PublishAsync(GlobalConst.TrackPushSubscribe, trackPushEvent); - foreach (var track in tracks) - { - var trackPushEvent = new TrackPushEvent - { - OptionType = OptionType.新增, - OrderId = track.OrderId, - OrderNo = track.OrderNo, - TrackStatus = track.TrackStatus, - TrackCode = track.TrackCode, - TrackContent = track.TrackContent, - TrackPlace = track.TrackPlace, - TrackTime = track.TrackTime, - TrackTimeZone = track.TrackTimeZone, - OperationMan = CurrentUserRequest.CurrentUser.Name, - }; - - await _capPublisher.PublishAsync(GlobalConst.TrackPushSubscribe, trackPushEvent); - - res++; - } - - return $"即将推送轨迹代码{input.TrackCode}给{res}个订单"; + return $"即将推送轨迹代码{input.TrackCode}给{orderIds.Length}个订单"; } diff --git a/src/SJZY.Track.Application/Services/ProvideServices/TrackService.cs b/src/SJZY.Track.Application/Services/ProvideServices/TrackService.cs index eba2ef6c..2b820625 100644 --- a/src/SJZY.Track.Application/Services/ProvideServices/TrackService.cs +++ b/src/SJZY.Track.Application/Services/ProvideServices/TrackService.cs @@ -43,7 +43,7 @@ public partial class TrackService : ApplicationService, ITrackService var order = await _orderRepository.GetFirstAsync(x => x.OrderType == input.OrderType && x.OrderNo == input.OrderNo, x => new { - x.Id, x.SubSystemId, x.OrderNo, x.OrderType + x.Id, x.SubSystemId, x.OrderNo, x.OrderType, x.CustomId }); if (order == default) { @@ -53,15 +53,16 @@ public partial class TrackService : ApplicationService, ITrackService // 新增/更新轨迹 var @event = ObjectMapper.Map(input); @event.SubSystemId = order.SubSystemId; - @event.OrderIdentifiers = new[] - { + @event.OrderIdentifiers = + [ new OrderIdentifier { OrderId = order.Id, OrderNo = order.OrderNo, - OrderType = order.OrderType + OrderType = order.OrderType, + CustomId = order.CustomId } - }; + ]; @event.OperationMan = CurrentUserRequest.CurrentUser.Name; await _capPublisher.PublishAsync(GlobalConst.TrackUpsertSubscribe, @event); return new UnifyResultDto(true, true); @@ -85,7 +86,7 @@ public partial class TrackService : ApplicationService, ITrackService var orders = await _orderRepository.GetListAsync(x => x.OrderType == input.OrderType && input.OrderNos.Contains(x.OrderNo), x => new { - x.Id, x.OrderNo, x.SubSystemId + x.Id, x.OrderNo, x.SubSystemId, x.CustomId }); foreach (var group in orders.GroupBy(x => x.SubSystemId)) @@ -98,7 +99,8 @@ public partial class TrackService : ApplicationService, ITrackService { OrderId = order.Id, OrderNo = order.OrderNo, - OrderType = input.OrderType + OrderType = input.OrderType, + CustomId = order.CustomId }).ToArray(), IsAdd = input.IsAdd, TrackCode = input.TrackCode, diff --git a/src/SJZY.Track.Application/Services/TrackPush/TrackPushCacheService.cs b/src/SJZY.Track.Application/Services/TrackPush/TrackPushCacheService.cs index e5d413f4..dfda8279 100644 --- a/src/SJZY.Track.Application/Services/TrackPush/TrackPushCacheService.cs +++ b/src/SJZY.Track.Application/Services/TrackPush/TrackPushCacheService.cs @@ -43,34 +43,6 @@ public class TrackPushCacheService : ITrackPushCacheService, ITransientDependenc return data; } - public async Task GetPushContentConfigAsync(int subSystemId, int customId, - string trackConde) - { - var configs = await GetPushContentConfigsAsync(subSystemId, customId); - return configs?.FirstOrDefault(x => x.TrackCode == trackConde); - } - - public async Task IsValidPushAsync(int subSystemId, int customId, - string? latestPushTrackCode, - string? trackCode) - { - var cache = await GetPushContentConfigsAsync(subSystemId, customId); - if (cache == null || cache.Count < 1) return default; - - var idx = cache.FindIndex(x => x.TrackCode == latestPushTrackCode); - - if (idx + 1 >= cache.Count) return default; // 推完了 - - // find next - var matched = cache[idx + 1].TrackCode == trackCode - ? cache[idx + 1] - : - // find swap - cache.FirstOrDefault(x => x.TrackCode == cache[idx + 1].SwapTrackCode); - - return matched != null && matched.TrackCode == trackCode ? matched : default; - } - private async Task?> DoGetPushContentConfigsAsync(int subSystemId, int customId) { var trackPushConfig = await _trackPushConfigRepository.GetFirstAsync( diff --git a/src/SJZY.Track.Domain/Aggregates/TrackDetailsAggregate/ITrackDetailsRepository.cs b/src/SJZY.Track.Domain/Aggregates/TrackDetailsAggregate/ITrackDetailsRepository.cs index a61e4f95..0d06b2fd 100644 --- a/src/SJZY.Track.Domain/Aggregates/TrackDetailsAggregate/ITrackDetailsRepository.cs +++ b/src/SJZY.Track.Domain/Aggregates/TrackDetailsAggregate/ITrackDetailsRepository.cs @@ -13,6 +13,8 @@ public interface ITrackDetailsRepository Task AnyAsync(int orderId, string originTrackData); + Task AnyByCodeAsync(int orderId, string trackCode); + Task UpdateAsync(TrackDetailsIndex index); Task AddManyAsync(List index); diff --git a/src/SJZY.Track.Domain/Aggregates/TrackPushAggregate/ITrackPushRecordsRepository.cs b/src/SJZY.Track.Domain/Aggregates/TrackPushAggregate/ITrackPushRecordsRepository.cs index 8783078d..99276b4b 100644 --- a/src/SJZY.Track.Domain/Aggregates/TrackPushAggregate/ITrackPushRecordsRepository.cs +++ b/src/SJZY.Track.Domain/Aggregates/TrackPushAggregate/ITrackPushRecordsRepository.cs @@ -9,6 +9,8 @@ public interface ITrackPushRecordsRepository /// Task AddAsync(TrackPushRecordIndex index); + Task AddManyAsync(List index); + /// /// 获取轨迹推送记录 /// diff --git a/src/SJZY.Track.Domain/Aggregates/TrackPushAggregate/TrackPushRecordIndex.cs b/src/SJZY.Track.Domain/Aggregates/TrackPushAggregate/TrackPushRecordIndex.cs index 8f877463..956e241d 100644 --- a/src/SJZY.Track.Domain/Aggregates/TrackPushAggregate/TrackPushRecordIndex.cs +++ b/src/SJZY.Track.Domain/Aggregates/TrackPushAggregate/TrackPushRecordIndex.cs @@ -17,6 +17,11 @@ public class TrackPushRecordIndex : IdBaseIndex /// public int OrderId { get; set; } + /// + /// 订单号 + /// + public string OrderNo { get; set; } = null!; + /// /// 接口通请求Id /// diff --git a/src/SJZY.Track.Domain/Consts/GlobalConst.MQ.cs b/src/SJZY.Track.Domain/Consts/GlobalConst.MQ.cs index b855eb70..93fd1c53 100644 --- a/src/SJZY.Track.Domain/Consts/GlobalConst.MQ.cs +++ b/src/SJZY.Track.Domain/Consts/GlobalConst.MQ.cs @@ -32,6 +32,11 @@ public partial class GlobalConst /// public const string TrackPushSubscribe = "SJZY.Track.TrackPush"; + /// + /// 轨迹推送完成(接口通回调) + /// + public const string TrackPushCompletedSubscribe = "SJZY.Track.TrackPushCompleted"; + /// /// 轨迹新增/更新/删除后触发更新订单主表 /// diff --git a/src/SJZY.Track.Domain/Dtos/Order/LinkedOrderVO.cs b/src/SJZY.Track.Domain/Dtos/Order/LinkedOrderVO.cs index 5b81e796..23299e30 100644 --- a/src/SJZY.Track.Domain/Dtos/Order/LinkedOrderVO.cs +++ b/src/SJZY.Track.Domain/Dtos/Order/LinkedOrderVO.cs @@ -26,4 +26,9 @@ public class LinkedOrderVO /// 子系统id /// public int SubSystemId { get; set; } + + /// + /// 客户id + /// + public int CustomId { get; set; } } \ No newline at end of file diff --git a/src/SJZY.Track.Repository/Repositories/OrderRepository.cs b/src/SJZY.Track.Repository/Repositories/OrderRepository.cs index 93edf756..85faff5d 100644 --- a/src/SJZY.Track.Repository/Repositories/OrderRepository.cs +++ b/src/SJZY.Track.Repository/Repositories/OrderRepository.cs @@ -78,7 +78,8 @@ AND `a`.`IsDeleted` = 0 AND `b`.`IsDeleted` = 0;"); OrderId = b.Id, OrderNo = b.OrderNo, OrderType = b.OrderType, - SubSystemId = b.SubSystemId + SubSystemId = b.SubSystemId, + CustomId = b.CustomId }) .ToListAsync(); } diff --git a/src/SJZY.Track.Repository/Repositories/TrackDetailsRepository.cs b/src/SJZY.Track.Repository/Repositories/TrackDetailsRepository.cs index 4622534e..af29d3fd 100644 --- a/src/SJZY.Track.Repository/Repositories/TrackDetailsRepository.cs +++ b/src/SJZY.Track.Repository/Repositories/TrackDetailsRepository.cs @@ -31,7 +31,7 @@ internal class TrackDetailsRepository : ElasticSearchContextAbstract 0; @@ -118,7 +118,25 @@ internal class TrackDetailsRepository : ElasticSearchContextAbstract 0; + } + + public async Task AnyByCodeAsync(int orderId, string trackCode) + { + 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.TrackCode.Suffix("keyword"), trackCode) + ) + ); + + if (!r.IsValid) + { + throw new Exception($"轨迹查询异常,原因:{r.DebugInformation}。"); } return r.Hits.Count > 0; @@ -128,9 +146,8 @@ internal class TrackDetailsRepository : ElasticSearchContextAbstract(track.Id, u => u - .Index(track.IndexName) - .Doc(track) - //.Refresh(Refresh.True) // 可选:立即刷新索引使更改立即可见 + .Index(track.IndexName) + .Doc(track) ); if (!r.IsValid) @@ -193,7 +210,7 @@ internal class TrackDetailsRepository : ElasticSearchContextAbstract trackCodes) { var r = await Context.DeleteByQueryAsync(x => x - .Conflicts(Conflicts.Proceed) + .Conflicts(Conflicts.Abort) .Query( q => q.Terms(t => t.Field(f => f.OrderId).Terms(orderIds)) && q.Term(t => t.IsCanDelete, true) && q.Terms(t => t.Field(f => f.TrackCode.Suffix("keyword")).Terms(trackCodes))) + .WaitForCompletion() ); if (!r.IsValid) diff --git a/src/SJZY.Track.Repository/Repositories/TrackPushRecordsRepository.cs b/src/SJZY.Track.Repository/Repositories/TrackPushRecordsRepository.cs index a2745e96..760614e9 100644 --- a/src/SJZY.Track.Repository/Repositories/TrackPushRecordsRepository.cs +++ b/src/SJZY.Track.Repository/Repositories/TrackPushRecordsRepository.cs @@ -16,6 +16,8 @@ public class TrackPushRecordsRepository : ElasticSearchContextAbstract request .Index(index.IndexName) @@ -28,6 +30,22 @@ public class TrackPushRecordsRepository : ElasticSearchContextAbstract records) + { + if (!records.Any()) return; + // 按天写入es + var indexName = $"{GlobalConst.TrackIndex}-{DateTime.Now:yyyy.MM.dd}"; + records.ForEach(x => x.IndexName = indexName); + + var r = await Context.IndexManyAsync(records, indexName); + + if (!r.IsValid) + { + throw new Exception($"{records.Count}条轨迹推送记录写入失败,原因:{r.DebugInformation}。"); + } + } + + public async Task> GetTrackPushRecordsAsync(int orderId) { var data = await Context.SearchAsync(x => x From ee35276ee6309ef3d9161f21cd7071f513ab22e7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=B9=8F=E5=86=9B?= <2357729423@qq.com> Date: Wed, 24 Apr 2024 18:00:02 +0800 Subject: [PATCH 44/72] =?UTF-8?q?change=EF=BC=9A=E8=AF=AD=E6=B3=95?= =?UTF-8?q?=E9=99=8D=E7=BA=A7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- common.props | 1 - .../EventHandlers/TrackRefreshEventHandler.cs | 6 +++--- .../Services/ProvideServices/TrackService.cs | 6 +++--- src/SJZY.Track.Repository/SJZY.Track.Repository.csproj | 1 - 4 files changed, 6 insertions(+), 8 deletions(-) diff --git a/common.props b/common.props index 492bcb09..f66ce331 100644 --- a/common.props +++ b/common.props @@ -1,6 +1,5 @@ - latest enable enable $(NoWarn);CS1591;CS0436;NU1803 diff --git a/src/SJZY.Track.Application/EventHandlers/TrackRefreshEventHandler.cs b/src/SJZY.Track.Application/EventHandlers/TrackRefreshEventHandler.cs index ea34f0e6..0e9fd334 100644 --- a/src/SJZY.Track.Application/EventHandlers/TrackRefreshEventHandler.cs +++ b/src/SJZY.Track.Application/EventHandlers/TrackRefreshEventHandler.cs @@ -223,8 +223,8 @@ public class TrackRefreshEventHandler : ITransientDependency, ICapSubscribe // 新增/更新轨迹 var trackUpsertEvent = new TrackUpsertEvent { - OrderIdentifiers = - [ + OrderIdentifiers = new[] + { new OrderIdentifier { OrderId = context.OrderId, @@ -232,7 +232,7 @@ public class TrackRefreshEventHandler : ITransientDependency, ICapSubscribe OrderType = context.OrderType, CustomId = context.CustomId } - ], + }, TrackRefreshData = new TrackRefreshStruct { ServiceProviderName = context.ServiceProviderName, diff --git a/src/SJZY.Track.Application/Services/ProvideServices/TrackService.cs b/src/SJZY.Track.Application/Services/ProvideServices/TrackService.cs index 2b820625..6c5d81ba 100644 --- a/src/SJZY.Track.Application/Services/ProvideServices/TrackService.cs +++ b/src/SJZY.Track.Application/Services/ProvideServices/TrackService.cs @@ -53,8 +53,8 @@ public partial class TrackService : ApplicationService, ITrackService // 新增/更新轨迹 var @event = ObjectMapper.Map(input); @event.SubSystemId = order.SubSystemId; - @event.OrderIdentifiers = - [ + @event.OrderIdentifiers = new[] + { new OrderIdentifier { OrderId = order.Id, @@ -62,7 +62,7 @@ public partial class TrackService : ApplicationService, ITrackService OrderType = order.OrderType, CustomId = order.CustomId } - ]; + }; @event.OperationMan = CurrentUserRequest.CurrentUser.Name; await _capPublisher.PublishAsync(GlobalConst.TrackUpsertSubscribe, @event); return new UnifyResultDto(true, true); diff --git a/src/SJZY.Track.Repository/SJZY.Track.Repository.csproj b/src/SJZY.Track.Repository/SJZY.Track.Repository.csproj index b2285e0b..d8cf6950 100644 --- a/src/SJZY.Track.Repository/SJZY.Track.Repository.csproj +++ b/src/SJZY.Track.Repository/SJZY.Track.Repository.csproj @@ -3,7 +3,6 @@ net7.0 True - preview From 9d5cad393e48e5aec9095d946c193d4cbcf0f65a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=B9=8F=E5=86=9B?= <2357729423@qq.com> Date: Wed, 24 Apr 2024 21:01:55 +0800 Subject: [PATCH 45/72] attach --- .../TrackPushCompletedEventHandler.cs | 15 +++- .../EventHandlers/TrackPushEventHandler.cs | 75 +++++++++++-------- 2 files changed, 57 insertions(+), 33 deletions(-) diff --git a/src/SJZY.Track.Application/EventHandlers/TrackPushCompletedEventHandler.cs b/src/SJZY.Track.Application/EventHandlers/TrackPushCompletedEventHandler.cs index cfa667a9..ce7e5f3c 100644 --- a/src/SJZY.Track.Application/EventHandlers/TrackPushCompletedEventHandler.cs +++ b/src/SJZY.Track.Application/EventHandlers/TrackPushCompletedEventHandler.cs @@ -1,6 +1,7 @@ using DotNetCore.CAP; using Newtonsoft.Json; using SJZY.InterfaceRelay.Application.Contracts; +using SJZY.Track.Application.Contract.Dtos.TrackPush; using SJZY.Track.Domain.Aggregates.OrderAggregate; using SJZY.Track.Domain.Aggregates.TrackPushAggregate; using SJZY.Track.Domain.Consts; @@ -24,7 +25,19 @@ public class TrackPushCompletedEventHandler : ITransientDependency, ICapSubscrib [CapSubscribe(GlobalConst.TrackPushCompletedSubscribe, Group = GlobalConst.TrackPushSubscribe)] public async Task ConsumerAsync(InterfaceRelayForwardReplayEvent @event) { - var log = JsonConvert.DeserializeObject(@event.RequestParams); + string logStr = null; + if (@event.Attach == OptionType.新增.ToString()) + { + logStr = JsonConvert.DeserializeObject(@event.RequestParams)!.Log; + } + else if (@event.Attach == OptionType.修改.ToString()) + { + logStr = JsonConvert.DeserializeObject(@event.RequestParams)!.Log; + } + + if (logStr.IsNullOrEmpty()) throw new InvalidOperationException(); + var log = JsonConvert.DeserializeObject(logStr!); + if (log == null) throw new BusinessException(message: "轨迹推送返回结果解析异常"); log.IsSuccess = @event.IsSuccess; log.Message = @event.Message; diff --git a/src/SJZY.Track.Application/EventHandlers/TrackPushEventHandler.cs b/src/SJZY.Track.Application/EventHandlers/TrackPushEventHandler.cs index 4eb337ba..555511d9 100644 --- a/src/SJZY.Track.Application/EventHandlers/TrackPushEventHandler.cs +++ b/src/SJZY.Track.Application/EventHandlers/TrackPushEventHandler.cs @@ -1,4 +1,5 @@ -using DotNetCore.CAP; +using System.Text; +using DotNetCore.CAP; using Newtonsoft.Json; using SJZY.Expand.ABP.Core.PublicMethords; using SJZY.InterfaceRelay.Application.Contracts; @@ -72,7 +73,7 @@ public class TrackPushEventHandler : ITransientDependency, ICapSubscribe private async Task DoPushAsync(TrackPushEvent @event) { - var logs = new List(); + var items = new List(); TrackPushContentConfigDto? config; if (@event.OperationMan == null) @@ -98,8 +99,9 @@ public class TrackPushEventHandler : ITransientDependency, ICapSubscribe TrackTimeZone = @event.SystemPushInfo.TrackTimeZone, CreateUser = GlobalConst.SystemUser, }; - await BuiltPushItem(config, log); - logs.Add(log); + var item = await BuiltPushItem(config, log); + item.Log = JsonConvert.SerializeObject(log); + items.Add(item); } } else //手工推送 @@ -136,13 +138,18 @@ public class TrackPushEventHandler : ITransientDependency, ICapSubscribe TrackTimeZone = track.TrackTimeZone, CreateUser = @event.OperationMan, }; - await BuiltPushItem(config, log); - logs.Add(log); + var item = await BuiltPushItem(config, log); + item.Log = JsonConvert.SerializeObject(log); + items.Add(item); } } + byte[] asciiBytes = Encoding.ASCII.GetBytes(OptionType.新增.ToString()); + string asciiString = Encoding.ASCII.GetString(asciiBytes); + await _httpClientProxy.Service.BatchForwardThenPushToQueueAsync(InterfaceRelayConst.PushTrackInterfaceCode, - _pushConfigs.First().ServiceProviderCode, logs, GlobalConst.TrackPushCompletedSubscribe); + _pushConfigs.First().ServiceProviderCode, items, GlobalConst.TrackPushCompletedSubscribe, + attach: asciiString); } private async Task DoUpdateAsync(TrackPushEvent @event) @@ -150,7 +157,7 @@ public class TrackPushEventHandler : ITransientDependency, ICapSubscribe var config = _pushConfigs.FirstOrDefault(x => x.TrackCode == @event.TrackCode); if (config == null || !config.IsCanUpdate) return; - var logs = new List(); + var items = new List(); foreach (var order in _orders) { var log = new TrackPushRecordIndex @@ -166,41 +173,43 @@ public class TrackPushEventHandler : ITransientDependency, ICapSubscribe TrackTimeZone = @event.SystemPushInfo.TrackTimeZone, CreateUser = GlobalConst.SystemUser, }; - BuiltUpdateItem(config, log); - logs.Add(log); + var item = BuiltUpdateItem(config, log); + item.Log = JsonConvert.SerializeObject(log); + items.Add(item); } await _httpClientProxy.Service.BatchForwardThenPushToQueueAsync(InterfaceRelayConst.TrackUpdateInterfaceCode, - _pushConfigs.First().ServiceProviderCode, logs, GlobalConst.TrackPushCompletedSubscribe); + _pushConfigs.First().ServiceProviderCode, items, GlobalConst.TrackPushCompletedSubscribe, + attach: OptionType.修改.ToString()); } - private void BuiltUpdateItem(TrackPushContentConfigDto config, TrackPushRecordIndex log) + private TrackUpdateInput BuiltUpdateItem(TrackPushContentConfigDto config, TrackPushRecordIndex log) { - var data = new + var track = new TrackItem { - orderNo = log.OrderNo, - data = new[] - { - new - { - // 推真实的发生地和发生时间 - location = log.TrackPlace, - date = log.TrackTime.AddHours( - config.TrackTimeZone ?? log.TrackTimeZone - log.TrackTimeZone), - timeZone = config.TrackTimeZone ?? log.TrackTimeZone, - description = config.TrackEnContentValue, - description_cn = config.TrackContentValue, - code = config.TrackContentCodeValue, - status = config.TrackStatusValue, - extra = config.ExpandFieldsValue - } - } + // 推真实的发生地和发生时间(时间是计算后的) + Location = log.TrackPlace, + Date = log.TrackTime.AddHours( + config.TrackTimeZone ?? log.TrackTimeZone - log.TrackTimeZone), + TimeZone = config.TrackTimeZone ?? log.TrackTimeZone, + Description = config.TrackEnContentValue, + DescriptionCn = config.TrackContentValue, + Code = config.TrackContentCodeValue, + Status = config.TrackStatusValue, + Extra = config.ExpandFieldsValue }; - log.PushContent = data.ToJson(); + var body = new TrackUpdateInput + { + OrderNo = log.OrderNo, + }; + body.Data.Add(track); + log.PushContent = body.ToJson(); + + return body; } - private async Task BuiltPushItem(TrackPushContentConfigDto config, TrackPushRecordIndex log) + private async Task BuiltPushItem(TrackPushContentConfigDto config, TrackPushRecordIndex log) { var track = new TrackItem { @@ -233,6 +242,8 @@ public class TrackPushEventHandler : ITransientDependency, ICapSubscribe } log.PushContent = body.ToJson(); + + return body; } /// From 09881a3932fc172d8c77227d7a417b0c0fb3f3bb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=B9=8F=E5=86=9B?= <2357729423@qq.com> Date: Wed, 24 Apr 2024 21:44:08 +0800 Subject: [PATCH 46/72] attach --- .../EventHandlers/TrackPushCompletedEventHandler.cs | 6 ++++-- .../EventHandlers/TrackPushEventHandler.cs | 9 +++++---- .../Repositories/TrackPushRecordsRepository.cs | 2 +- 3 files changed, 10 insertions(+), 7 deletions(-) diff --git a/src/SJZY.Track.Application/EventHandlers/TrackPushCompletedEventHandler.cs b/src/SJZY.Track.Application/EventHandlers/TrackPushCompletedEventHandler.cs index ce7e5f3c..022c1b36 100644 --- a/src/SJZY.Track.Application/EventHandlers/TrackPushCompletedEventHandler.cs +++ b/src/SJZY.Track.Application/EventHandlers/TrackPushCompletedEventHandler.cs @@ -2,6 +2,7 @@ using Newtonsoft.Json; using SJZY.InterfaceRelay.Application.Contracts; using SJZY.Track.Application.Contract.Dtos.TrackPush; +using SJZY.Track.Application.Helpers; using SJZY.Track.Domain.Aggregates.OrderAggregate; using SJZY.Track.Domain.Aggregates.TrackPushAggregate; using SJZY.Track.Domain.Consts; @@ -26,11 +27,12 @@ public class TrackPushCompletedEventHandler : ITransientDependency, ICapSubscrib public async Task ConsumerAsync(InterfaceRelayForwardReplayEvent @event) { string logStr = null; - if (@event.Attach == OptionType.新增.ToString()) + var optionType = Base64Helper.DeSerialize(@event.Attach); + if (optionType == OptionType.新增.ToString()) { logStr = JsonConvert.DeserializeObject(@event.RequestParams)!.Log; } - else if (@event.Attach == OptionType.修改.ToString()) + else if (optionType == OptionType.修改.ToString()) { logStr = JsonConvert.DeserializeObject(@event.RequestParams)!.Log; } diff --git a/src/SJZY.Track.Application/EventHandlers/TrackPushEventHandler.cs b/src/SJZY.Track.Application/EventHandlers/TrackPushEventHandler.cs index 555511d9..3d7ae977 100644 --- a/src/SJZY.Track.Application/EventHandlers/TrackPushEventHandler.cs +++ b/src/SJZY.Track.Application/EventHandlers/TrackPushEventHandler.cs @@ -1,11 +1,11 @@ -using System.Text; -using DotNetCore.CAP; +using DotNetCore.CAP; using Newtonsoft.Json; using SJZY.Expand.ABP.Core.PublicMethords; using SJZY.InterfaceRelay.Application.Contracts; using SJZY.Track.Application.Contract.Dtos.TrackPush; using SJZY.Track.Application.Contract.Events; using SJZY.Track.Application.Contract.Services; +using SJZY.Track.Application.Helpers; using SJZY.Track.Domain.Aggregates.OrderAggregate; using SJZY.Track.Domain.Aggregates.TrackDetailsAggregate; using SJZY.Track.Domain.Aggregates.TrackPushAggregate; @@ -144,9 +144,9 @@ public class TrackPushEventHandler : ITransientDependency, ICapSubscribe } } - byte[] asciiBytes = Encoding.ASCII.GetBytes(OptionType.新增.ToString()); - string asciiString = Encoding.ASCII.GetString(asciiBytes); + string asciiString = Base64Helper.SerializeObject(OptionType.新增.ToString()); + if (items.Count == 0) return; await _httpClientProxy.Service.BatchForwardThenPushToQueueAsync(InterfaceRelayConst.PushTrackInterfaceCode, _pushConfigs.First().ServiceProviderCode, items, GlobalConst.TrackPushCompletedSubscribe, attach: asciiString); @@ -178,6 +178,7 @@ public class TrackPushEventHandler : ITransientDependency, ICapSubscribe items.Add(item); } + if (items.Count == 0) return; await _httpClientProxy.Service.BatchForwardThenPushToQueueAsync(InterfaceRelayConst.TrackUpdateInterfaceCode, _pushConfigs.First().ServiceProviderCode, items, GlobalConst.TrackPushCompletedSubscribe, attach: OptionType.修改.ToString()); diff --git a/src/SJZY.Track.Repository/Repositories/TrackPushRecordsRepository.cs b/src/SJZY.Track.Repository/Repositories/TrackPushRecordsRepository.cs index 760614e9..044f8753 100644 --- a/src/SJZY.Track.Repository/Repositories/TrackPushRecordsRepository.cs +++ b/src/SJZY.Track.Repository/Repositories/TrackPushRecordsRepository.cs @@ -16,7 +16,7 @@ public class TrackPushRecordsRepository : ElasticSearchContextAbstract request From 52b70cb2133e1d7e599d1a711b50c2a869289499 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=B9=8F=E5=86=9B?= <2357729423@qq.com> Date: Thu, 25 Apr 2024 09:45:02 +0800 Subject: [PATCH 47/72] =?UTF-8?q?fix=EF=BC=9A=E6=8E=A8=E9=80=81=E6=9B=B4?= =?UTF-8?q?=E6=96=B0attach=20ascii?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../EventHandlers/TrackPushEventHandler.cs | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/SJZY.Track.Application/EventHandlers/TrackPushEventHandler.cs b/src/SJZY.Track.Application/EventHandlers/TrackPushEventHandler.cs index 3d7ae977..95a1088e 100644 --- a/src/SJZY.Track.Application/EventHandlers/TrackPushEventHandler.cs +++ b/src/SJZY.Track.Application/EventHandlers/TrackPushEventHandler.cs @@ -144,9 +144,9 @@ public class TrackPushEventHandler : ITransientDependency, ICapSubscribe } } - string asciiString = Base64Helper.SerializeObject(OptionType.新增.ToString()); - if (items.Count == 0) return; + + string asciiString = Base64Helper.SerializeObject(OptionType.新增.ToString()); await _httpClientProxy.Service.BatchForwardThenPushToQueueAsync(InterfaceRelayConst.PushTrackInterfaceCode, _pushConfigs.First().ServiceProviderCode, items, GlobalConst.TrackPushCompletedSubscribe, attach: asciiString); @@ -179,9 +179,11 @@ public class TrackPushEventHandler : ITransientDependency, ICapSubscribe } if (items.Count == 0) return; + + string asciiString = Base64Helper.SerializeObject(OptionType.修改.ToString()); await _httpClientProxy.Service.BatchForwardThenPushToQueueAsync(InterfaceRelayConst.TrackUpdateInterfaceCode, _pushConfigs.First().ServiceProviderCode, items, GlobalConst.TrackPushCompletedSubscribe, - attach: OptionType.修改.ToString()); + attach: asciiString); } private TrackUpdateInput BuiltUpdateItem(TrackPushContentConfigDto config, TrackPushRecordIndex log) From 96b3486956600852f8ed3879ed79a0d750757a5c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=B9=8F=E5=86=9B?= <2357729423@qq.com> Date: Thu, 25 Apr 2024 10:23:09 +0800 Subject: [PATCH 48/72] =?UTF-8?q?fix=EF=BC=9A=E6=89=8B=E5=8A=A8=E6=8E=A8?= =?UTF-8?q?=E9=80=81=20=E5=AD=90=E7=B3=BB=E7=BB=9F=EF=BC=8C=E5=AE=A2?= =?UTF-8?q?=E6=88=B7=20=E5=88=86=E7=BB=84=E6=8E=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ProvideServices/TrackPushService.cs | 30 ++++++++++++------- 1 file changed, 19 insertions(+), 11 deletions(-) diff --git a/src/SJZY.Track.Application/Services/ProvideServices/TrackPushService.cs b/src/SJZY.Track.Application/Services/ProvideServices/TrackPushService.cs index 8b43e04f..d4bcb72d 100644 --- a/src/SJZY.Track.Application/Services/ProvideServices/TrackPushService.cs +++ b/src/SJZY.Track.Application/Services/ProvideServices/TrackPushService.cs @@ -39,25 +39,33 @@ public class TrackPushService : ApplicationService { input.OrderNos = input.OrderNos.Where(x => !x.IsNullOrWhiteSpace()).Distinct().ToList(); // 单号去重、去空 - var orderIds = await _orderRepository.GetArrayAsync(x => - x.OrderType == input.OrderType && input.OrderNos.Contains(x.OrderNo), x => x.Id); + var orders = await _orderRepository.GetArrayAsync(x => + x.OrderType == input.OrderType && input.OrderNos.Contains(x.OrderNo), x => new + { + x.Id, x.SubSystemId, x.CustomId + }); - if (!orderIds.Any()) + if (!orders.Any()) { throw new BusinessException(message: "一个订单都不存在"); } - var trackPushEvent = new TrackPushEvent + foreach (var group in orders.GroupBy(x => new { x.SubSystemId, x.CustomId })) { - OptionType = OptionType.新增, - OrderIds = orderIds, - TrackCode = input.TrackCode, - OperationMan = CurrentUserRequest.CurrentUser.Name, - }; + var trackPushEvent = new TrackPushEvent + { + OptionType = OptionType.新增, + SubSystemId = group.Key.SubSystemId, + CustomId = group.Key.CustomId, + OrderIds = group.Select(x => x.Id).ToArray(), + TrackCode = input.TrackCode, + OperationMan = CurrentUserRequest.CurrentUser.Name, + }; - await _capPublisher.PublishAsync(GlobalConst.TrackPushSubscribe, trackPushEvent); + await _capPublisher.PublishAsync(GlobalConst.TrackPushSubscribe, trackPushEvent); + } - return $"即将推送轨迹代码{input.TrackCode}给{orderIds.Length}个订单"; + return $"即将推送轨迹代码{input.TrackCode}给{orders.Length}个订单"; } From 4cb5f465da2475bf081d637d46c9521ea02f2ce9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=B9=8F=E5=86=9B?= <2357729423@qq.com> Date: Thu, 25 Apr 2024 10:43:39 +0800 Subject: [PATCH 49/72] =?UTF-8?q?opt=EF=BC=9A=E6=8E=A5=E5=8F=A3=E9=80=9A?= =?UTF-8?q?=E8=AF=B7=E6=B1=82=E5=A4=B1=E8=B4=A5=E6=89=93=E5=8D=B0=E5=BC=82?= =?UTF-8?q?=E5=B8=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../TrackPushCompletedEventHandler.cs | 35 ++++++++++--------- .../EventHandlers/TrackPushEventHandler.cs | 21 ++++++++--- 2 files changed, 35 insertions(+), 21 deletions(-) diff --git a/src/SJZY.Track.Application/EventHandlers/TrackPushCompletedEventHandler.cs b/src/SJZY.Track.Application/EventHandlers/TrackPushCompletedEventHandler.cs index 022c1b36..a1024118 100644 --- a/src/SJZY.Track.Application/EventHandlers/TrackPushCompletedEventHandler.cs +++ b/src/SJZY.Track.Application/EventHandlers/TrackPushCompletedEventHandler.cs @@ -65,8 +65,14 @@ public class TrackPushCompletedEventHandler : ITransientDependency, ICapSubscrib private async Task TrackPushAfterUpdateOrderAsync(TrackPushRecordIndex log) { - var order = new OrderEntity(); - order.Id = log.OrderId; + // tips:只有新增会影响推送进度? + if (log.OptionType != OptionType.新增.ToString()) return; + + var order = new OrderEntity + { + Id = log.OrderId + }; + /* * 异常:最近一条推送是失败 */ @@ -74,27 +80,22 @@ public class TrackPushCompletedEventHandler : ITransientDependency, ICapSubscrib { order.QuestionType = (int)TrackProblemType.Error; order.LatestPushError = log.Message; + await _orderRepository.UpdateColumnAsync(order, x => new + { + x.QuestionType, x.LatestPushError + }); } else { + // 还原成正常态 order.QuestionType = (int)TrackProblemType.None; order.LatestPushError = null; - if (log.OptionType == OptionType.新增.ToString()) + order.LatestPushTrackCode = log.TrackCode; + order.LatestPushTime = log.CreateTime; + await _orderRepository.UpdateColumnAsync(order, x => new { - // tips:只有新增会影响推送进度? - order.LatestPushTrackCode = log.TrackCode; - order.LatestPushTime = DateTime.Now; - await _orderRepository.UpdateColumnAsync(order, x => new - { - x.LatestPushTrackCode, x.LatestPushTime, x.QuestionType, x.LatestPushError - }); - return; - } + x.LatestPushTrackCode, x.LatestPushTime, x.QuestionType, x.LatestPushError + }); } - - await _orderRepository.UpdateColumnAsync(order, x => new - { - x.QuestionType, x.LatestPushError - }); } } \ No newline at end of file diff --git a/src/SJZY.Track.Application/EventHandlers/TrackPushEventHandler.cs b/src/SJZY.Track.Application/EventHandlers/TrackPushEventHandler.cs index 95a1088e..67fb60d9 100644 --- a/src/SJZY.Track.Application/EventHandlers/TrackPushEventHandler.cs +++ b/src/SJZY.Track.Application/EventHandlers/TrackPushEventHandler.cs @@ -44,9 +44,8 @@ public class TrackPushEventHandler : ITransientDependency, ICapSubscribe if (pushConfigs == null || pushConfigs.Count == 0) return; _pushConfigs = pushConfigs; - var errorType = (int)TrackProblemType.Error; var orders = await _orderRepository.GetListAsync(x => - @event.OrderIds.Contains(x.Id) && x.QuestionType != errorType, x => new OrderEntity + @event.OrderIds.Contains(x.Id), x => new OrderEntity { Id = x.Id, OrderNo = x.OrderNo, LatestPushTrackCode = x.LatestPushTrackCode, OrderType = x.OrderType @@ -80,6 +79,7 @@ public class TrackPushEventHandler : ITransientDependency, ICapSubscribe { foreach (var order in _orders) { + if (order.QuestionType == (int)TrackProblemType.Error) continue; // 系统不推异常单,只能人工操作 // 推送新增,需要根据上一次的推送 推断 本次推送 是否可行 config = GetValidPushConfigAsync(_pushConfigs, order.LatestPushTrackCode, @event.TrackCode); if (config == null) continue; @@ -114,6 +114,7 @@ public class TrackPushEventHandler : ITransientDependency, ICapSubscribe if (tracks.Count == 0) return; // 一个能推的轨迹都不存在 + // tips:人工推送只要能推就推了,不会校验已推和顺序问题,因为可能是更新 foreach (var track in tracks) { var order = _orders.First(x => x.Id == track.OrderId); @@ -147,9 +148,15 @@ public class TrackPushEventHandler : ITransientDependency, ICapSubscribe if (items.Count == 0) return; string asciiString = Base64Helper.SerializeObject(OptionType.新增.ToString()); - await _httpClientProxy.Service.BatchForwardThenPushToQueueAsync(InterfaceRelayConst.PushTrackInterfaceCode, + var r = await _httpClientProxy.Service.BatchForwardThenPushToQueueAsync( + InterfaceRelayConst.PushTrackInterfaceCode, _pushConfigs.First().ServiceProviderCode, items, GlobalConst.TrackPushCompletedSubscribe, attach: asciiString); + + if (r.Code != InterfaceRelayConst.SuccessCode) + { + throw new BusinessException(message: r.Msg); + } } private async Task DoUpdateAsync(TrackPushEvent @event) @@ -181,9 +188,15 @@ public class TrackPushEventHandler : ITransientDependency, ICapSubscribe if (items.Count == 0) return; string asciiString = Base64Helper.SerializeObject(OptionType.修改.ToString()); - await _httpClientProxy.Service.BatchForwardThenPushToQueueAsync(InterfaceRelayConst.TrackUpdateInterfaceCode, + var r = await _httpClientProxy.Service.BatchForwardThenPushToQueueAsync( + InterfaceRelayConst.TrackUpdateInterfaceCode, _pushConfigs.First().ServiceProviderCode, items, GlobalConst.TrackPushCompletedSubscribe, attach: asciiString); + + if (r.Code != InterfaceRelayConst.SuccessCode) + { + throw new BusinessException(message: r.Msg); + } } private TrackUpdateInput BuiltUpdateItem(TrackPushContentConfigDto config, TrackPushRecordIndex log) From c6e99193c3590a7837022077de57329306f38011 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=B9=8F=E5=86=9B?= <2357729423@qq.com> Date: Thu, 25 Apr 2024 17:00:27 +0800 Subject: [PATCH 50/72] =?UTF-8?q?fix=EF=BC=9A=E8=BD=A8=E8=BF=B9=E5=88=A0?= =?UTF-8?q?=E9=99=A4=E5=BC=95=E5=8F=91=E7=9A=84=E4=B8=BB=E8=A1=A8=E7=BB=B4?= =?UTF-8?q?=E6=8A=A4=E4=B8=8D=E5=AE=8C=E6=95=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../EventHandlers/TrackDeleteEventHandler.cs | 3 ++- .../Repositories/TrackDetailsRepository.cs | 5 ++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/SJZY.Track.Application/EventHandlers/TrackDeleteEventHandler.cs b/src/SJZY.Track.Application/EventHandlers/TrackDeleteEventHandler.cs index 46b87f8b..bd85a916 100644 --- a/src/SJZY.Track.Application/EventHandlers/TrackDeleteEventHandler.cs +++ b/src/SJZY.Track.Application/EventHandlers/TrackDeleteEventHandler.cs @@ -109,13 +109,14 @@ public class TrackDeleteEventHandler : ITransientDependency, ICapSubscribe // 删除全部轨迹导致的重置行为 if (track == default) { - if (order.LatestTrackTime == null) return; + if (order.LatestTrackTime == null) continue; // tips:订单是支持从已完成态到未完成态的 order.ResetTrackInfo(); } else { + if (order.LatestTrackContent == track.TrackContent) continue; // 删除引发的回退更新 order.LatestTrackContent = track.TrackContent; order.LatestTrackEnContent = track.TrackEnContent; diff --git a/src/SJZY.Track.Repository/Repositories/TrackDetailsRepository.cs b/src/SJZY.Track.Repository/Repositories/TrackDetailsRepository.cs index af29d3fd..be3e4d85 100644 --- a/src/SJZY.Track.Repository/Repositories/TrackDetailsRepository.cs +++ b/src/SJZY.Track.Repository/Repositories/TrackDetailsRepository.cs @@ -236,17 +236,16 @@ internal class TrackDetailsRepository : ElasticSearchContextAbstract trackCodes) { var r = await Context.DeleteByQueryAsync(x => x - .Conflicts(Conflicts.Abort) + .Conflicts(Conflicts.Proceed) .Query( q => q.Terms(t => t.Field(f => f.OrderId).Terms(orderIds)) && q.Term(t => t.IsCanDelete, true) && q.Terms(t => t.Field(f => f.TrackCode.Suffix("keyword")).Terms(trackCodes))) - .WaitForCompletion() ); if (!r.IsValid) - throw new Exception($"轨迹数据删除失败,原因:{r.DebugInformation}"); + throw new Exception($"轨迹数据删除失败,原因:{r.ServerError.Error}"); } public async Task<(List list, long total)> GetListAsync(TrackDetailsQueryInput input) From d8f594f19318a33935a7bfc89a91f6ab126ad3a6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=B9=8F=E5=86=9B?= <2357729423@qq.com> Date: Thu, 25 Apr 2024 17:22:41 +0800 Subject: [PATCH 51/72] try abort --- .../Repositories/TrackDetailsRepository.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/SJZY.Track.Repository/Repositories/TrackDetailsRepository.cs b/src/SJZY.Track.Repository/Repositories/TrackDetailsRepository.cs index be3e4d85..97133bfb 100644 --- a/src/SJZY.Track.Repository/Repositories/TrackDetailsRepository.cs +++ b/src/SJZY.Track.Repository/Repositories/TrackDetailsRepository.cs @@ -236,12 +236,13 @@ internal class TrackDetailsRepository : ElasticSearchContextAbstract trackCodes) { var r = await Context.DeleteByQueryAsync(x => x - .Conflicts(Conflicts.Proceed) + .Conflicts(Conflicts.Abort) .Query( q => q.Terms(t => t.Field(f => f.OrderId).Terms(orderIds)) && q.Term(t => t.IsCanDelete, true) && q.Terms(t => t.Field(f => f.TrackCode.Suffix("keyword")).Terms(trackCodes))) + .WaitForCompletion() ); if (!r.IsValid) From 9d3ef9e4a3cf7c6a730f145b2c62f11e2051af03 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=B9=8F=E5=86=9B?= <2357729423@qq.com> Date: Thu, 25 Apr 2024 18:21:02 +0800 Subject: [PATCH 52/72] =?UTF-8?q?change=EF=BC=9A=E8=BD=A8=E8=BF=B9?= =?UTF-8?q?=E5=88=A0=E9=99=A4=E9=99=8D=E7=BA=A7=E4=B8=BA=E6=BB=9A=E5=8A=A8?= =?UTF-8?q?=E5=88=A0=E9=99=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ITrackDetailsRepository.cs | 1 - .../Repositories/TrackDetailsRepository.cs | 49 ++++++++++++++----- 2 files changed, 38 insertions(+), 12 deletions(-) diff --git a/src/SJZY.Track.Domain/Aggregates/TrackDetailsAggregate/ITrackDetailsRepository.cs b/src/SJZY.Track.Domain/Aggregates/TrackDetailsAggregate/ITrackDetailsRepository.cs index 0d06b2fd..cc4c033a 100644 --- a/src/SJZY.Track.Domain/Aggregates/TrackDetailsAggregate/ITrackDetailsRepository.cs +++ b/src/SJZY.Track.Domain/Aggregates/TrackDetailsAggregate/ITrackDetailsRepository.cs @@ -8,7 +8,6 @@ public interface ITrackDetailsRepository Task> GetLatestListAsync(int[] eventOrderIds, List trackCodes); - Task AnyAsync(int orderId, DateTime trackTime); Task AnyAsync(int orderId, string originTrackData); diff --git a/src/SJZY.Track.Repository/Repositories/TrackDetailsRepository.cs b/src/SJZY.Track.Repository/Repositories/TrackDetailsRepository.cs index 97133bfb..c48a0ec0 100644 --- a/src/SJZY.Track.Repository/Repositories/TrackDetailsRepository.cs +++ b/src/SJZY.Track.Repository/Repositories/TrackDetailsRepository.cs @@ -1,4 +1,3 @@ -using Elasticsearch.Net; using Nest; using SJZY.Expand.ElasticSearch.Services; using SJZY.Track.Domain.Aggregates.TrackDetailsAggregate; @@ -235,18 +234,46 @@ internal class TrackDetailsRepository : ElasticSearchContextAbstract trackCodes) { - var r = await Context.DeleteByQueryAsync(x => x - .Conflicts(Conflicts.Abort) - .Query( - q => - q.Terms(t => t.Field(f => f.OrderId).Terms(orderIds)) - && q.Term(t => t.IsCanDelete, true) - && q.Terms(t => t.Field(f => f.TrackCode.Suffix("keyword")).Terms(trackCodes))) - .WaitForCompletion() + var search = await Context.SearchAsync(s => s + .Source(fd => fd.Includes(f => f.Field("indexName"))) + .Size(1000) + .Query(q => q + .Bool(b => b + .Must( + mu => mu.Terms(t => t.Field(f => f.OrderId).Terms(orderIds)), + mu => mu.Terms(t => t.Field(f => f.TrackCode.Suffix("keyword")).Terms(trackCodes)) + ) + ) + ) + .Scroll("1m") // 设置滚动时间 ); - if (!r.IsValid) - throw new Exception($"轨迹数据删除失败,原因:{r.ServerError.Error}"); + + while (search.IsValid && search.Documents.Any()) + { + // 处理滚动查询结果 + var tracks = search.ToIdList(); + + foreach (var track in tracks) + { + var r = await Context.DeleteAsync(track.Id, u => u + .Index(track.IndexName) + ); + + if (!r.IsValid) + throw new Exception($"轨迹数据删除失败,原因:{r.ServerError.Error}"); + } + + var scrollId = search.ScrollId; // 更新滚动ID + + // 滚动查询 + search = await Context.ScrollAsync("1m", scrollId); + } + + if (!search.IsValid) + { + throw new Exception($"轨迹查询异常,原因:{search.DebugInformation}。"); + } } public async Task<(List list, long total)> GetListAsync(TrackDetailsQueryInput input) From 399106ec0a17887a52d80b05535cc1d11149ba47 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=B9=8F=E5=86=9B?= <2357729423@qq.com> Date: Thu, 25 Apr 2024 18:27:59 +0800 Subject: [PATCH 53/72] =?UTF-8?q?retry=EF=BC=9A=E6=BB=9A=E5=8A=A8=E4=B8=8A?= =?UTF-8?q?=E4=B8=8B=E6=96=87=E5=8F=AA=E8=83=BD500=EF=BC=8C=E5=9B=A0?= =?UTF-8?q?=E6=AD=A4=E5=9B=9E=E9=80=80=E5=88=B0=E6=99=AE=E9=80=9A=E5=BE=AA?= =?UTF-8?q?=E7=8E=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Repositories/TrackDetailsRepository.cs | 53 ++++++++----------- 1 file changed, 21 insertions(+), 32 deletions(-) diff --git a/src/SJZY.Track.Repository/Repositories/TrackDetailsRepository.cs b/src/SJZY.Track.Repository/Repositories/TrackDetailsRepository.cs index c48a0ec0..74666a61 100644 --- a/src/SJZY.Track.Repository/Repositories/TrackDetailsRepository.cs +++ b/src/SJZY.Track.Repository/Repositories/TrackDetailsRepository.cs @@ -234,46 +234,35 @@ internal class TrackDetailsRepository : ElasticSearchContextAbstract trackCodes) { - var search = await Context.SearchAsync(s => s - .Source(fd => fd.Includes(f => f.Field("indexName"))) - .Size(1000) - .Query(q => q - .Bool(b => b - .Must( - mu => mu.Terms(t => t.Field(f => f.OrderId).Terms(orderIds)), - mu => mu.Terms(t => t.Field(f => f.TrackCode.Suffix("keyword")).Terms(trackCodes)) - ) + var search = await Context.SearchAsync(x => x + .Source(s => s.Includes(fd => fd.Field(f => f.IndexName))) + .Size(1000) + .Query(q => q + .Bool(b => b + .Must( + mu => mu.Terms(t => t.Field(f => f.OrderId).Terms(orderIds)), + mu => mu.Terms(t => t.Field(f => f.TrackCode.Suffix("keyword")).Terms(trackCodes)) ) ) - .Scroll("1m") // 设置滚动时间 + ) ); - - while (search.IsValid && search.Documents.Any()) - { - // 处理滚动查询结果 - var tracks = search.ToIdList(); - - foreach (var track in tracks) - { - var r = await Context.DeleteAsync(track.Id, u => u - .Index(track.IndexName) - ); - - if (!r.IsValid) - throw new Exception($"轨迹数据删除失败,原因:{r.ServerError.Error}"); - } - - var scrollId = search.ScrollId; // 更新滚动ID - - // 滚动查询 - search = await Context.ScrollAsync("1m", scrollId); - } - if (!search.IsValid) { throw new Exception($"轨迹查询异常,原因:{search.DebugInformation}。"); } + + var tracks = search.ToIdList(); + + foreach (var track in tracks) + { + var r = await Context.DeleteAsync(track.Id, u => u + .Index(track.IndexName) + ); + + if (!r.IsValid) + throw new Exception($"轨迹数据删除失败,原因:{r.ServerError.Error}"); + } } public async Task<(List list, long total)> GetListAsync(TrackDetailsQueryInput input) From d075c02d5e1c8a4f0bfa2ed07b12c47ad94726b3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=B9=8F=E5=86=9B?= <2357729423@qq.com> Date: Thu, 25 Apr 2024 18:58:38 +0800 Subject: [PATCH 54/72] =?UTF-8?q?opt=EF=BC=9A=E4=BC=98=E5=8C=96=E6=8E=A8?= =?UTF-8?q?=E9=80=81=E5=AF=B9=E6=8E=A5=E6=8E=A5=E5=8F=A3=E9=80=9A=E6=97=A5?= =?UTF-8?q?=E5=BF=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../EventHandlers/TrackPushEventHandler.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/SJZY.Track.Application/EventHandlers/TrackPushEventHandler.cs b/src/SJZY.Track.Application/EventHandlers/TrackPushEventHandler.cs index 67fb60d9..3b42b3db 100644 --- a/src/SJZY.Track.Application/EventHandlers/TrackPushEventHandler.cs +++ b/src/SJZY.Track.Application/EventHandlers/TrackPushEventHandler.cs @@ -155,7 +155,7 @@ public class TrackPushEventHandler : ITransientDependency, ICapSubscribe if (r.Code != InterfaceRelayConst.SuccessCode) { - throw new BusinessException(message: r.Msg); + throw new BusinessException(message: $"requestId: {r.Data}; {r.Msg}"); } } @@ -195,7 +195,7 @@ public class TrackPushEventHandler : ITransientDependency, ICapSubscribe if (r.Code != InterfaceRelayConst.SuccessCode) { - throw new BusinessException(message: r.Msg); + throw new BusinessException(message: $"requestId: {r.Data}; {r.Msg}"); } } From 62ba69aed92dc89e04401660aa8b82d53aa1adef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=B9=8F=E5=86=9B?= <2357729423@qq.com> Date: Thu, 25 Apr 2024 19:07:55 +0800 Subject: [PATCH 55/72] attach --- .../Repositories/TrackDetailsRepository.cs | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/src/SJZY.Track.Repository/Repositories/TrackDetailsRepository.cs b/src/SJZY.Track.Repository/Repositories/TrackDetailsRepository.cs index 74666a61..d2b2e3cc 100644 --- a/src/SJZY.Track.Repository/Repositories/TrackDetailsRepository.cs +++ b/src/SJZY.Track.Repository/Repositories/TrackDetailsRepository.cs @@ -236,14 +236,10 @@ internal class TrackDetailsRepository : ElasticSearchContextAbstract(x => x .Source(s => s.Includes(fd => fd.Field(f => f.IndexName))) - .Size(1000) - .Query(q => q - .Bool(b => b - .Must( - mu => mu.Terms(t => t.Field(f => f.OrderId).Terms(orderIds)), - mu => mu.Terms(t => t.Field(f => f.TrackCode.Suffix("keyword")).Terms(trackCodes)) - ) - ) + .Size(orderIds.Length * trackCodes.Count * 2) + .Query(q => + q.Terms(t => t.Field(f => f.OrderId).Terms(orderIds)) + && q.Terms(t => t.Field(f => f.TrackCode.Suffix("keyword")).Terms(trackCodes)) ) ); From 148434dda016263cfb380a6f9377047ae316f33b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=B9=8F=E5=86=9B?= <2357729423@qq.com> Date: Thu, 25 Apr 2024 20:23:12 +0800 Subject: [PATCH 56/72] =?UTF-8?q?fix=EF=BC=9A=E5=88=A0=E9=99=A4=E4=B8=8D?= =?UTF-8?q?=E5=AD=98=E5=9C=A8=E6=96=87=E6=A1=A3response.IsValid=E4=B8=BAfa?= =?UTF-8?q?lse=E5=BC=95=E8=B5=B7=E7=9A=84=E5=BC=82=E5=B8=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Repositories/TrackDetailsRepository.cs | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/SJZY.Track.Repository/Repositories/TrackDetailsRepository.cs b/src/SJZY.Track.Repository/Repositories/TrackDetailsRepository.cs index d2b2e3cc..e4c08278 100644 --- a/src/SJZY.Track.Repository/Repositories/TrackDetailsRepository.cs +++ b/src/SJZY.Track.Repository/Repositories/TrackDetailsRepository.cs @@ -252,12 +252,9 @@ internal class TrackDetailsRepository : ElasticSearchContextAbstract(track.Id, u => u + await Context.DeleteAsync(track.Id, u => u .Index(track.IndexName) ); - - if (!r.IsValid) - throw new Exception($"轨迹数据删除失败,原因:{r.ServerError.Error}"); } } From de7d1daf81715e4982280ae9f486758b69b699b2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=B9=8F=E5=86=9B?= <2357729423@qq.com> Date: Thu, 9 May 2024 10:51:38 +0800 Subject: [PATCH 57/72] =?UTF-8?q?change=EF=BC=9A=E9=87=8D=E8=AF=95?= =?UTF-8?q?=E4=B8=8D=E5=81=9A=E5=B9=82=E7=AD=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../EventHandlers/CAPFilter.cs | 64 +++---------------- 1 file changed, 9 insertions(+), 55 deletions(-) diff --git a/src/SJZY.Track.Application/EventHandlers/CAPFilter.cs b/src/SJZY.Track.Application/EventHandlers/CAPFilter.cs index 4c0014c6..1ce7c51b 100644 --- a/src/SJZY.Track.Application/EventHandlers/CAPFilter.cs +++ b/src/SJZY.Track.Application/EventHandlers/CAPFilter.cs @@ -1,5 +1,4 @@ -using System.Globalization; -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; @@ -20,6 +19,9 @@ public class CapFilter : SubscribeFilter { context.DeliverMessage.Headers["sjzy-receive-time"] = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss fff"); + // 异常重试不做幂等 + if (context.DeliverMessage.Headers.ContainsKey("cap-exception")) return Task.CompletedTask; + // 轨迹增改要做幂等 if (!context.DeliverMessage.Headers["cap-msg-name"].IsIn(GlobalConst.TrackUpsertSubscribe)) return Task.CompletedTask; @@ -31,18 +33,19 @@ public class CapFilter : SubscribeFilter } var argumentJsonStr = context.Arguments.ToJson(); - context.DeliverMessage.Headers["sjzy-arguments"] = argumentJsonStr; + var hash = argumentJsonStr.GetHash(); + + context.DeliverMessage.Headers["sjzy-arguments-hash"] = hash; if (!string.IsNullOrEmpty(argumentJsonStr)) { - var hash = argumentJsonStr.GetHash(); using (RedisHelper.Client.Lock("Filter:" + hash, 10)) { - var isSkip = !string.IsNullOrEmpty(RedisHelper.Client.Get($"CapExcuteFilter:{hash}")); + var isSkip = !string.IsNullOrEmpty(RedisHelper.Client.Get($"CapExecuteFilter:{hash}")); if (isSkip) throw new BusinessException(ErrorCode, $"检测到重复消费,消费参数:{argumentJsonStr}"); - RedisHelper.Client.Set($"CapExcuteFilter:{hash}", 60 * 10, + RedisHelper.Client.Set($"CapExecuteFilter:{hash}", 60 * 10, TimeSpan.FromMinutes(5).Seconds); } } @@ -50,24 +53,6 @@ public class CapFilter : SubscribeFilter return Task.CompletedTask; } - /// - /// 执行后 - /// - /// - /// - public override Task OnSubscribeExecutedAsync(ExecutedContext context) - { - // context.DeliverMessage.Headers.TryGetValue("sjzy-receive-time", out var receiveTime); - // context.DeliverMessage.Headers.TryGetValue("cap-msg-name", out var receiveName); - // context.DeliverMessage.Headers.TryGetValue("sjzy-arguments", out var arguments); - // context.DeliverMessage.Headers.TryGetValue("cap-msg-id", out var messageId); - // - // BuildLog(receiveTime!, receiveName!, arguments!, false, messageId!); - - return Task.CompletedTask; - } - - /// /// 消费异常事件 /// @@ -85,37 +70,6 @@ public class CapFilter : SubscribeFilter else LogHelper.Error($"cap-msg-id:{messageId}\n{context.Exception}"); - - // context.DeliverMessage.Headers.TryGetValue("sjzy-receive-time", out var receiveTime); - // context.DeliverMessage.Headers.TryGetValue("cap-msg-name", out var receiveName); - // context.DeliverMessage.Headers.TryGetValue("sjzy-arguments", out var arguments); - // - // BuildLog(receiveTime!, receiveName!, arguments, true, messageId!); - return Task.CompletedTask; } - - - private void BuildLog(string receiveTime, string receiveName, string? arguments, bool isFromExecptionFliter, - string messageId) - { - var parsedDate = DateTime.ParseExact(receiveTime, "yyyy-MM-dd HH:mm:ss fff", CultureInfo.InvariantCulture); - var useTime = DateTime.Now - parsedDate; - - if (useTime.Minutes > 10) - { - var log = $@" -|-消息编号:{messageId} -|-消费者名:{receiveName} -|-跳过执行:{(isFromExecptionFliter ? "是" : "否")} -|-执行时间:{receiveTime} -|-消费耗时:{useTime.Seconds}秒 -|-请求参数:{arguments}"; - LogHelper.Error(log); - } - else - { - //LogHelper.Info(log); - } - } } \ No newline at end of file From 78c0aa11918b8a52a2d0dcf93495cea4a6417ea0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=B9=8F=E5=86=9B?= <2357729423@qq.com> Date: Thu, 9 May 2024 10:53:52 +0800 Subject: [PATCH 58/72] =?UTF-8?q?change=EF=BC=9A=E7=BA=BF=E7=A8=8B?= =?UTF-8?q?=E5=88=86=E7=BB=84=E5=8F=AF=E9=85=8D=E7=BD=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/SJZY.Track.Application/SjzyTrackApplicationModule.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/SJZY.Track.Application/SjzyTrackApplicationModule.cs b/src/SJZY.Track.Application/SjzyTrackApplicationModule.cs index 4e8f5fff..1fa422f6 100644 --- a/src/SJZY.Track.Application/SjzyTrackApplicationModule.cs +++ b/src/SJZY.Track.Application/SjzyTrackApplicationModule.cs @@ -92,7 +92,7 @@ namespace SJZY.Track.Application options.FailedRetryCount = configuration.GetValue("CAP:FailedRetryCount"); options.ConsumerThreadCount = configuration.GetValue("CAP:ConsumerThreadCount"); options.SucceedMessageExpiredAfter = configuration.GetValue("CAP:SucceedMessageExpiredAfter"); - options.UseDispatchingPerGroup = true; + options.UseDispatchingPerGroup = configuration.GetValue("CAP:UseDispatchingPerGroup"); options.EnableConsumerPrefetch = true; options.UseDashboard(dashboardOptions => From 49eda2a3aa7b553a1ecb09595b98a0fcc2c8c123 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=B9=8F=E5=86=9B?= <2357729423@qq.com> Date: Thu, 9 May 2024 11:28:55 +0800 Subject: [PATCH 59/72] =?UTF-8?q?opt=EF=BC=9A=E4=BC=98=E5=8C=96=E8=BD=A8?= =?UTF-8?q?=E8=BF=B9=E6=96=B0=E5=A2=9E?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../EventHandlers/TrackUpsertEventHandler.cs | 6 ++++-- .../Dtos/TrackDetails/MatchTrackContentDto.cs | 9 +++++++-- src/SJZY.Track.Domain/Queries/IProvideQueries.cs | 4 ++-- src/SJZY.Track.Repository/Queries/ProvideQueries.cs | 7 ++++--- 4 files changed, 17 insertions(+), 9 deletions(-) diff --git a/src/SJZY.Track.Application/EventHandlers/TrackUpsertEventHandler.cs b/src/SJZY.Track.Application/EventHandlers/TrackUpsertEventHandler.cs index 937c0a21..8817a331 100644 --- a/src/SJZY.Track.Application/EventHandlers/TrackUpsertEventHandler.cs +++ b/src/SJZY.Track.Application/EventHandlers/TrackUpsertEventHandler.cs @@ -106,6 +106,9 @@ public class TrackUpsertEventHandler : ITransientDependency, ICapSubscribe var orderIds = @event.OrderIdentifiers.Select(x => x.OrderId).ToArray(); var tracks = await _trackDetailsRepository.GetListAsync(orderIds, @event.TrackCode); + var newOrderIds = orderIds.Except(tracks.Select(x => x.OrderId)).ToArray(); + var trackContents = await _provideQueries.MatchTrackContentAsync(newOrderIds, @event.TrackCode); + TrackDetailsIndex? firstTrack = null; var insertTracks = new List(); @@ -136,9 +139,8 @@ public class TrackUpsertEventHandler : ITransientDependency, ICapSubscribe CreateTime = DateTime.Now }; - //todo:可以优化? // 根据轨迹code在订单模板内容中寻找匹配的 - var trackContent = await _provideQueries.MatchTrackContentAsync(order.OrderId, @event.TrackCode); + var trackContent = trackContents.FirstOrDefault(x => x.OrderId == order.OrderId); if (trackContent == default) { // 订单所绑定的模板,没有一条内容可以匹配发生的轨迹 diff --git a/src/SJZY.Track.Domain/Dtos/TrackDetails/MatchTrackContentDto.cs b/src/SJZY.Track.Domain/Dtos/TrackDetails/MatchTrackContentDto.cs index 58429cdb..23c27bfe 100644 --- a/src/SJZY.Track.Domain/Dtos/TrackDetails/MatchTrackContentDto.cs +++ b/src/SJZY.Track.Domain/Dtos/TrackDetails/MatchTrackContentDto.cs @@ -3,9 +3,14 @@ public class MatchTrackContentDto { /// - /// 轨迹内容id + /// 订单Id /// - public string TrackCode { get; set; } + public int OrderId { get; set; } + + /// + /// 轨迹内容code + /// + public string TrackCode { get; set; } = null!; /// /// 轨迹内容 diff --git a/src/SJZY.Track.Domain/Queries/IProvideQueries.cs b/src/SJZY.Track.Domain/Queries/IProvideQueries.cs index 7d043a9f..ab50db31 100644 --- a/src/SJZY.Track.Domain/Queries/IProvideQueries.cs +++ b/src/SJZY.Track.Domain/Queries/IProvideQueries.cs @@ -27,10 +27,10 @@ public interface IProvideQueries /// /// 根据订单id找到订单模板,匹配模板命中的轨迹内容 /// - /// 订单id + /// 订单ids /// 轨迹代码 /// - Task MatchTrackContentAsync(int orderId, string code); + Task> MatchTrackContentAsync(int[] orderIds, string code); /// /// 获取可删除的订单轨迹代码 diff --git a/src/SJZY.Track.Repository/Queries/ProvideQueries.cs b/src/SJZY.Track.Repository/Queries/ProvideQueries.cs index 82e4993f..c2013762 100644 --- a/src/SJZY.Track.Repository/Queries/ProvideQueries.cs +++ b/src/SJZY.Track.Repository/Queries/ProvideQueries.cs @@ -50,22 +50,23 @@ public class ProvideQueries : ISugarRepository, IProvideQueries, .ToListAsync(); } - public async Task MatchTrackContentAsync(int orderId, string code) + public async Task> MatchTrackContentAsync(int[] orderIds, string code) { return await Context.Queryable() .LeftJoin((x, a) => x.TrackTemplateId == a.TrackTemplateId) .LeftJoin((x, a, b) => a.TrackContentId == b.Id) .LeftJoin((x, a, b, c) => b.TrackStatusId == c.Id) - .Where((x, a, b) => x.OrderId == orderId && b.Code == code) + .Where((x, a, b) => orderIds.Contains(x.OrderId) && b.Code == code) .Select((x, a, b, c) => new MatchTrackContentDto { + OrderId = x.OrderId, TrackCode = b.Code, Content = b.Content, EnContent = b.EnContent, Status = c.Status, IsCanDelete = a.IsCanDelete }) - .FirstAsync(); + .ToListAsync(); } public async Task> GetCanDeleteTrackCodesAsync(List orderIds, From 5cda1270fbe6602c42bd4ac2af2e120e622019c6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=B9=8F=E5=86=9B?= <2357729423@qq.com> Date: Thu, 9 May 2024 11:45:44 +0800 Subject: [PATCH 60/72] =?UTF-8?q?opt=EF=BC=9A=E4=BC=98=E5=8C=96=E6=9B=B4?= =?UTF-8?q?=E6=96=B0=E8=BD=A8=E8=BF=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../EventHandlers/TrackUpsertEventHandler.cs | 2 +- .../ITrackDetailsRepository.cs | 2 +- .../Repositories/TrackDetailsRepository.cs | 46 ++++++++++++++----- 3 files changed, 36 insertions(+), 14 deletions(-) diff --git a/src/SJZY.Track.Application/EventHandlers/TrackUpsertEventHandler.cs b/src/SJZY.Track.Application/EventHandlers/TrackUpsertEventHandler.cs index 8817a331..edeadec2 100644 --- a/src/SJZY.Track.Application/EventHandlers/TrackUpsertEventHandler.cs +++ b/src/SJZY.Track.Application/EventHandlers/TrackUpsertEventHandler.cs @@ -104,7 +104,7 @@ public class TrackUpsertEventHandler : ITransientDependency, ICapSubscribe private async Task HandleTrackAsync(TrackUpsertEvent @event, List canNextOrderIds) { var orderIds = @event.OrderIdentifiers.Select(x => x.OrderId).ToArray(); - var tracks = await _trackDetailsRepository.GetListAsync(orderIds, @event.TrackCode); + var tracks = await _trackDetailsRepository.GetListAsync(orderIds, @event.TrackCode, true); var newOrderIds = orderIds.Except(tracks.Select(x => x.OrderId)).ToArray(); var trackContents = await _provideQueries.MatchTrackContentAsync(newOrderIds, @event.TrackCode); diff --git a/src/SJZY.Track.Domain/Aggregates/TrackDetailsAggregate/ITrackDetailsRepository.cs b/src/SJZY.Track.Domain/Aggregates/TrackDetailsAggregate/ITrackDetailsRepository.cs index cc4c033a..4296713a 100644 --- a/src/SJZY.Track.Domain/Aggregates/TrackDetailsAggregate/ITrackDetailsRepository.cs +++ b/src/SJZY.Track.Domain/Aggregates/TrackDetailsAggregate/ITrackDetailsRepository.cs @@ -4,7 +4,7 @@ namespace SJZY.Track.Domain.Aggregates.TrackDetailsAggregate; public interface ITrackDetailsRepository { - Task> GetListAsync(int[] orderIds, string trackCode); + Task> GetListAsync(int[] orderIds, string trackCode, bool onlyIndexName = false); Task> GetLatestListAsync(int[] eventOrderIds, List trackCodes); diff --git a/src/SJZY.Track.Repository/Repositories/TrackDetailsRepository.cs b/src/SJZY.Track.Repository/Repositories/TrackDetailsRepository.cs index e4c08278..ad8bba7d 100644 --- a/src/SJZY.Track.Repository/Repositories/TrackDetailsRepository.cs +++ b/src/SJZY.Track.Repository/Repositories/TrackDetailsRepository.cs @@ -13,20 +13,35 @@ internal class TrackDetailsRepository : ElasticSearchContextAbstract> GetListAsync(int[] orderIds, string trackCode) + public async Task> GetListAsync(int[] orderIds, string trackCode, + bool onlyIndexName = false) { - var r = await Context.SearchAsync(s => s - .Source() - .Size(1000) - .Query(q => q - .Bool(b => b - .Must( - mu => mu.Terms(t => t.Field(f => f.OrderId).Terms(orderIds)), - mu => mu.Term(t => t.Field(f => f.TrackCode.Suffix("keyword")).Value(trackCode)) + var r = !onlyIndexName + ? await Context.SearchAsync(s => s + .Source() + .Size(1000) + .Query(q => q + .Bool(b => b + .Must( + mu => mu.Terms(t => t.Field(f => f.OrderId).Terms(orderIds)), + mu => mu.Term(t => t.Field(f => f.TrackCode.Suffix("keyword")).Value(trackCode)) + ) ) ) ) - ); + : await Context.SearchAsync(s => s + .Source(s2 => s2.Includes(fd => fd + .Field(f => f.IndexName))) + .Size(1000) + .Query(q => q + .Bool(b => b + .Must( + mu => mu.Terms(t => t.Field(f => f.OrderId).Terms(orderIds)), + mu => mu.Term(t => t.Field(f => f.TrackCode.Suffix("keyword")).Value(trackCode)) + ) + ) + ) + ); if (!r.IsValid) { @@ -144,9 +159,16 @@ internal class TrackDetailsRepository : ElasticSearchContextAbstract(track.Id, u => u + var r = await Context.UpdateAsync(track.Id, u => u .Index(track.IndexName) - .Doc(track) + .Doc(new + { + track.TrackPlace, + track.TrackTime, + track.TrackTimeZone, + track.UpdateUser, + UpdateTime = DateTime.Now, + }) ); if (!r.IsValid) From 761446c06933c4f1bf1de25738b289831ec96e83 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=B9=8F=E5=86=9B?= <2357729423@qq.com> Date: Thu, 9 May 2024 12:01:02 +0800 Subject: [PATCH 61/72] attach --- .../TrackDetailsAggregate/ITrackDetailsRepository.cs | 2 +- src/SJZY.Track.Repository/Queries/ProvideQueries.cs | 1 + .../Repositories/TrackDetailsRepository.cs | 7 ++++--- 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/src/SJZY.Track.Domain/Aggregates/TrackDetailsAggregate/ITrackDetailsRepository.cs b/src/SJZY.Track.Domain/Aggregates/TrackDetailsAggregate/ITrackDetailsRepository.cs index 4296713a..4e4a0b9c 100644 --- a/src/SJZY.Track.Domain/Aggregates/TrackDetailsAggregate/ITrackDetailsRepository.cs +++ b/src/SJZY.Track.Domain/Aggregates/TrackDetailsAggregate/ITrackDetailsRepository.cs @@ -4,7 +4,7 @@ namespace SJZY.Track.Domain.Aggregates.TrackDetailsAggregate; public interface ITrackDetailsRepository { - Task> GetListAsync(int[] orderIds, string trackCode, bool onlyIndexName = false); + Task> GetListAsync(int[] orderIds, string trackCode, bool forUpsert = false); Task> GetLatestListAsync(int[] eventOrderIds, List trackCodes); diff --git a/src/SJZY.Track.Repository/Queries/ProvideQueries.cs b/src/SJZY.Track.Repository/Queries/ProvideQueries.cs index c2013762..7e80e4e8 100644 --- a/src/SJZY.Track.Repository/Queries/ProvideQueries.cs +++ b/src/SJZY.Track.Repository/Queries/ProvideQueries.cs @@ -52,6 +52,7 @@ public class ProvideQueries : ISugarRepository, IProvideQueries, public async Task> MatchTrackContentAsync(int[] orderIds, string code) { + if (orderIds.Length == 0) return new List(); return await Context.Queryable() .LeftJoin((x, a) => x.TrackTemplateId == a.TrackTemplateId) .LeftJoin((x, a, b) => a.TrackContentId == b.Id) diff --git a/src/SJZY.Track.Repository/Repositories/TrackDetailsRepository.cs b/src/SJZY.Track.Repository/Repositories/TrackDetailsRepository.cs index ad8bba7d..64a426d2 100644 --- a/src/SJZY.Track.Repository/Repositories/TrackDetailsRepository.cs +++ b/src/SJZY.Track.Repository/Repositories/TrackDetailsRepository.cs @@ -14,9 +14,9 @@ internal class TrackDetailsRepository : ElasticSearchContextAbstract> GetListAsync(int[] orderIds, string trackCode, - bool onlyIndexName = false) + bool forUpsert = false) { - var r = !onlyIndexName + var r = !forUpsert ? await Context.SearchAsync(s => s .Source() .Size(1000) @@ -31,7 +31,8 @@ internal class TrackDetailsRepository : ElasticSearchContextAbstract(s => s .Source(s2 => s2.Includes(fd => fd - .Field(f => f.IndexName))) + .Field(f => f.IndexName) + .Field(f => f.OrderId))) .Size(1000) .Query(q => q .Bool(b => b From eff09f1cb008c6e7a9fec82170e433ab930de0b5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=B9=8F=E5=86=9B?= <2357729423@qq.com> Date: Thu, 9 May 2024 14:59:36 +0800 Subject: [PATCH 62/72] =?UTF-8?q?upg=EF=BC=9A=E5=8D=87=E7=BA=A7=E6=8E=A5?= =?UTF-8?q?=E5=8F=A3=E9=80=9A7.2.1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../EventHandlers/TrackPushEventHandler.cs | 4 ++-- src/SJZY.Track.Application/SJZY.Track.Application.csproj | 2 +- src/SJZY.Track.Application/SjzyTrackApplicationModule.cs | 5 ++--- 3 files changed, 5 insertions(+), 6 deletions(-) diff --git a/src/SJZY.Track.Application/EventHandlers/TrackPushEventHandler.cs b/src/SJZY.Track.Application/EventHandlers/TrackPushEventHandler.cs index 3b42b3db..5edf8f4a 100644 --- a/src/SJZY.Track.Application/EventHandlers/TrackPushEventHandler.cs +++ b/src/SJZY.Track.Application/EventHandlers/TrackPushEventHandler.cs @@ -155,7 +155,7 @@ public class TrackPushEventHandler : ITransientDependency, ICapSubscribe if (r.Code != InterfaceRelayConst.SuccessCode) { - throw new BusinessException(message: $"requestId: {r.Data}; {r.Msg}"); + throw new BusinessException(message: $"requestId: {r.RequestId}; {r.Msg}"); } } @@ -195,7 +195,7 @@ public class TrackPushEventHandler : ITransientDependency, ICapSubscribe if (r.Code != InterfaceRelayConst.SuccessCode) { - throw new BusinessException(message: $"requestId: {r.Data}; {r.Msg}"); + throw new BusinessException(message: $"requestId: {r.RequestId}; {r.Msg}"); } } diff --git a/src/SJZY.Track.Application/SJZY.Track.Application.csproj b/src/SJZY.Track.Application/SJZY.Track.Application.csproj index fba5f4d2..f9d34258 100644 --- a/src/SJZY.Track.Application/SJZY.Track.Application.csproj +++ b/src/SJZY.Track.Application/SJZY.Track.Application.csproj @@ -12,7 +12,7 @@ - + diff --git a/src/SJZY.Track.Application/SjzyTrackApplicationModule.cs b/src/SJZY.Track.Application/SjzyTrackApplicationModule.cs index 1fa422f6..ff8ecefe 100644 --- a/src/SJZY.Track.Application/SjzyTrackApplicationModule.cs +++ b/src/SJZY.Track.Application/SjzyTrackApplicationModule.cs @@ -1,5 +1,4 @@ -using System.Text.Json; -using DotNetCore.CAP; +using DotNetCore.CAP; using Microsoft.Extensions.Configuration; using SJZY.Expand.ABP.Core.Localization; using SJZY.Expand.ABP.Core.Logger; @@ -109,7 +108,7 @@ namespace SJZY.Track.Application |-CAP失败回调事件: |-处理类型:{(faileCalback.MessageType == DotNetCore.CAP.Messages.MessageType.Subscribe ? "消费消息达到最大重试次数,需要开发人员介入" : "生产消息推送失败")} |-头部信息:{faileCalback.Message.Headers.ToJson()} - |-消息内容:{(faileCalback.Message.Value is string ? faileCalback.Message.Value : ((JsonElement?)faileCalback.Message.Value)?.GetRawText())}"); + |-消息内容:{(faileCalback.Message.Value is string ? faileCalback.Message.Value : faileCalback.Message.Value?.ToJson())}"); } catch (Exception ex) { From 56f8d95e48db1f5769ca07dde46e123725c416ec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=B9=8F=E5=86=9B?= <2357729423@qq.com> Date: Thu, 9 May 2024 15:45:59 +0800 Subject: [PATCH 63/72] =?UTF-8?q?opt=EF=BC=9A=E4=BC=98=E5=8C=96upsert?= =?UTF-8?q?=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../EventHandlers/TrackUpsertEventHandler.cs | 24 +++++++++---------- .../Dtos/TrackContents/TrackContentVO.cs | 19 +++++++++++++++ .../Queries/IProvideQueries.cs | 3 +++ .../Queries/ProvideQueries.cs | 15 ++++++++++++ .../Repositories/TrackDetailsRepository.cs | 3 ++- 5 files changed, 51 insertions(+), 13 deletions(-) create mode 100644 src/SJZY.Track.Domain/Dtos/TrackContents/TrackContentVO.cs diff --git a/src/SJZY.Track.Application/EventHandlers/TrackUpsertEventHandler.cs b/src/SJZY.Track.Application/EventHandlers/TrackUpsertEventHandler.cs index edeadec2..201c4efc 100644 --- a/src/SJZY.Track.Application/EventHandlers/TrackUpsertEventHandler.cs +++ b/src/SJZY.Track.Application/EventHandlers/TrackUpsertEventHandler.cs @@ -109,8 +109,6 @@ public class TrackUpsertEventHandler : ITransientDependency, ICapSubscribe var newOrderIds = orderIds.Except(tracks.Select(x => x.OrderId)).ToArray(); var trackContents = await _provideQueries.MatchTrackContentAsync(newOrderIds, @event.TrackCode); - TrackDetailsIndex? firstTrack = null; - var insertTracks = new List(); foreach (var order in @event.OrderIdentifiers) @@ -168,30 +166,32 @@ public class TrackUpsertEventHandler : ITransientDependency, ICapSubscribe } canNextOrderIds.Add(order.OrderId); - - firstTrack ??= track; } + if (canNextOrderIds.Count == 0) return; + + var content = await _provideQueries.GetTrackContentAsync(@event.SubSystemId, @event.TrackCode); + // 批量add to es await _trackDetailsRepository.AddManyAsync(insertTracks); - if (firstTrack == null) return; - // 触发订单主表更新事件(异步) await _capPublisher.PublishAsync(GlobalConst.TrackChangeAfterUpdateOrderSubscribe, new TrackChangeAfterUpdateOrderEvent { - OrderIds = orderIds, + OrderIds = canNextOrderIds.ToArray(), IsCompleted = @event.TrackRefreshData.IsCompleted, - TrackContent = firstTrack.TrackContent, - TrackEnContent = firstTrack.TrackEnContent, + TrackContent = content.TrackContent, + TrackEnContent = content.TrackEnContent, TrackPlace = @event.TrackPlace, TrackTime = @event.TrackTime, TrackTimeZone = @event.TrackTimeZone }); // 触发轨迹推送事件(异步) - foreach (var group in @event.OrderIdentifiers.GroupBy(x => x.CustomId)) + foreach (var group in @event.OrderIdentifiers + .Where(x => x.OrderId.IsIn(canNextOrderIds)) + .GroupBy(x => x.CustomId)) { var trackPushEvent = new TrackPushEvent { @@ -202,8 +202,8 @@ public class TrackUpsertEventHandler : ITransientDependency, ICapSubscribe TrackCode = @event.TrackCode, SystemPushInfo = new SystemPushStruct { - TrackStatus = firstTrack.TrackStatus, - TrackContent = firstTrack.TrackContent, + TrackStatus = content.TrackStatus, + TrackContent = content.TrackContent, TrackPlace = @event.TrackPlace, TrackTime = @event.TrackTime, TrackTimeZone = @event.TrackTimeZone diff --git a/src/SJZY.Track.Domain/Dtos/TrackContents/TrackContentVO.cs b/src/SJZY.Track.Domain/Dtos/TrackContents/TrackContentVO.cs new file mode 100644 index 00000000..d44e75c8 --- /dev/null +++ b/src/SJZY.Track.Domain/Dtos/TrackContents/TrackContentVO.cs @@ -0,0 +1,19 @@ +namespace SJZY.Track.Domain.Dtos.TrackContents; + +public class TrackContentVO +{ + /// + /// 轨迹状态 + /// + public string TrackStatus { get; set; } = null!; + + /// + /// 轨迹内容 + /// + public string TrackContent { get; set; } = null!; + + /// + /// 轨迹内容英文 + /// + public string TrackEnContent { get; set; } = null!; +} \ No newline at end of file diff --git a/src/SJZY.Track.Domain/Queries/IProvideQueries.cs b/src/SJZY.Track.Domain/Queries/IProvideQueries.cs index ab50db31..34e99ae9 100644 --- a/src/SJZY.Track.Domain/Queries/IProvideQueries.cs +++ b/src/SJZY.Track.Domain/Queries/IProvideQueries.cs @@ -1,4 +1,5 @@ using SJZY.Track.Domain.Dtos.Order; +using SJZY.Track.Domain.Dtos.TrackContents; using SJZY.Track.Domain.Dtos.TrackDetails; using SJZY.Track.Domain.Dtos.TrackTemplate; @@ -65,4 +66,6 @@ public interface IProvideQueries /// Task> FindOrderWithServiceProviderAsync(int serviceProvider, int pageIndex, int pageSize = 1000); + + Task GetTrackContentAsync(int subSystemId, string trackCode); } \ No newline at end of file diff --git a/src/SJZY.Track.Repository/Queries/ProvideQueries.cs b/src/SJZY.Track.Repository/Queries/ProvideQueries.cs index 7e80e4e8..f2a9f25c 100644 --- a/src/SJZY.Track.Repository/Queries/ProvideQueries.cs +++ b/src/SJZY.Track.Repository/Queries/ProvideQueries.cs @@ -3,6 +3,7 @@ using SJZY.Track.Domain.Aggregates.TrackContentAggregate; using SJZY.Track.Domain.Aggregates.TrackStatusAggregate; using SJZY.Track.Domain.Aggregates.TrackTemplateAggregate; using SJZY.Track.Domain.Dtos.Order; +using SJZY.Track.Domain.Dtos.TrackContents; using SJZY.Track.Domain.Dtos.TrackDetails; using SJZY.Track.Domain.Dtos.TrackTemplate; using SJZY.Track.Domain.Queries; @@ -135,4 +136,18 @@ public class ProvideQueries : ISugarRepository, IProvideQueries, .Take(pageSize) .ToListAsync(); } + + public async Task GetTrackContentAsync(int subSystemId, string trackCode) + { + return await Context.Queryable() + .LeftJoin((x, y) => x.TrackStatusId == y.Id) + .Where(x => x.SubSystemId == subSystemId && x.Code == trackCode) + .Select((x, y) => new TrackContentVO + { + TrackStatus = y.Status, + TrackContent = x.Content, + TrackEnContent = x.EnContent + }) + .FirstAsync(); + } } \ No newline at end of file diff --git a/src/SJZY.Track.Repository/Repositories/TrackDetailsRepository.cs b/src/SJZY.Track.Repository/Repositories/TrackDetailsRepository.cs index 64a426d2..4f798cb2 100644 --- a/src/SJZY.Track.Repository/Repositories/TrackDetailsRepository.cs +++ b/src/SJZY.Track.Repository/Repositories/TrackDetailsRepository.cs @@ -32,7 +32,8 @@ internal class TrackDetailsRepository : ElasticSearchContextAbstract(s => s .Source(s2 => s2.Includes(fd => fd .Field(f => f.IndexName) - .Field(f => f.OrderId))) + .Field(f => f.OrderId) + )) .Size(1000) .Query(q => q .Bool(b => b From 5b12642faf9199cee7bf66166aed6c45491af28c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=B9=8F=E5=86=9B?= <2357729423@qq.com> Date: Thu, 9 May 2024 17:49:33 +0800 Subject: [PATCH 64/72] =?UTF-8?q?change=EF=BC=9Acap=E5=BC=82=E6=AD=A5?= =?UTF-8?q?=E4=B8=8D=E6=89=93=E6=B6=88=E6=81=AF=E5=86=85=E5=AE=B9=EF=BC=88?= =?UTF-8?q?=E5=8E=BBcap=E7=9C=8B=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/SJZY.Track.Application/SjzyTrackApplicationModule.cs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/SJZY.Track.Application/SjzyTrackApplicationModule.cs b/src/SJZY.Track.Application/SjzyTrackApplicationModule.cs index ff8ecefe..59827ae9 100644 --- a/src/SJZY.Track.Application/SjzyTrackApplicationModule.cs +++ b/src/SJZY.Track.Application/SjzyTrackApplicationModule.cs @@ -107,8 +107,7 @@ namespace SJZY.Track.Application LogHelper.Error($@" |-CAP失败回调事件: |-处理类型:{(faileCalback.MessageType == DotNetCore.CAP.Messages.MessageType.Subscribe ? "消费消息达到最大重试次数,需要开发人员介入" : "生产消息推送失败")} - |-头部信息:{faileCalback.Message.Headers.ToJson()} - |-消息内容:{(faileCalback.Message.Value is string ? faileCalback.Message.Value : faileCalback.Message.Value?.ToJson())}"); + |-头部信息:{faileCalback.Message.Headers.ToJson()}"); } catch (Exception ex) { From 7482521e7553eacb3cbd6f58350b49e0a8825a21 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=B9=8F=E5=86=9B?= <2357729423@qq.com> Date: Sat, 11 May 2024 10:13:00 +0800 Subject: [PATCH 65/72] =?UTF-8?q?opt=EF=BC=9A=E5=8D=87=E7=BA=A7cap?= =?UTF-8?q?=E5=88=B08.1.2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/SJZY.Track.Application/SJZY.Track.Application.csproj | 8 ++++---- src/SJZY.Track.Application/SjzyTrackApplicationModule.cs | 4 +--- 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/src/SJZY.Track.Application/SJZY.Track.Application.csproj b/src/SJZY.Track.Application/SJZY.Track.Application.csproj index f9d34258..b2801d4a 100644 --- a/src/SJZY.Track.Application/SJZY.Track.Application.csproj +++ b/src/SJZY.Track.Application/SJZY.Track.Application.csproj @@ -17,10 +17,10 @@ - - - - + + + + diff --git a/src/SJZY.Track.Application/SjzyTrackApplicationModule.cs b/src/SJZY.Track.Application/SjzyTrackApplicationModule.cs index 59827ae9..2984ac45 100644 --- a/src/SJZY.Track.Application/SjzyTrackApplicationModule.cs +++ b/src/SJZY.Track.Application/SjzyTrackApplicationModule.cs @@ -89,10 +89,8 @@ namespace SJZY.Track.Application // options.TopicNamePrefix = "v1"; options.FailedRetryInterval = configuration.GetValue("CAP:FailedRetryInterval"); options.FailedRetryCount = configuration.GetValue("CAP:FailedRetryCount"); - options.ConsumerThreadCount = configuration.GetValue("CAP:ConsumerThreadCount"); options.SucceedMessageExpiredAfter = configuration.GetValue("CAP:SucceedMessageExpiredAfter"); - options.UseDispatchingPerGroup = configuration.GetValue("CAP:UseDispatchingPerGroup"); - options.EnableConsumerPrefetch = true; + options.EnableSubscriberParallelExecute = true; options.UseDashboard(dashboardOptions => { From 4b0acb1978c89bdca231b08ad3da0398f50b8d92 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=B9=8F=E5=86=9B?= <2357729423@qq.com> Date: Tue, 14 May 2024 17:17:14 +0800 Subject: [PATCH 66/72] =?UTF-8?q?opt=EF=BC=9A=E4=BC=98=E5=8C=96=E8=BD=A8?= =?UTF-8?q?=E8=BF=B9=E5=88=B7=E6=96=B0=E5=AE=9A=E6=97=B6=E4=BB=BB=E5=8A=A1?= =?UTF-8?q?=E7=AD=89=E5=BE=85=E8=B6=85=E6=97=B6=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ProvideServices/TrackPullService.cs | 68 ++++++++++--------- 1 file changed, 36 insertions(+), 32 deletions(-) diff --git a/src/SJZY.Track.Application/Services/ProvideServices/TrackPullService.cs b/src/SJZY.Track.Application/Services/ProvideServices/TrackPullService.cs index d7f71038..cb7cd5e1 100644 --- a/src/SJZY.Track.Application/Services/ProvideServices/TrackPullService.cs +++ b/src/SJZY.Track.Application/Services/ProvideServices/TrackPullService.cs @@ -78,46 +78,50 @@ public class TrackPullService : ApplicationService /// [AllowAnonymous] [HttpPost("Track/RefreshForTask")] - public async Task RefreshForTaskAsync() + public bool RefreshForTaskAsync() { - var configs = await _trackPullCacheService.GetAllPullConfigsAsync(); - foreach (var config in configs) + Task.Run(async () => { - var redisKey = _trackPullCacheService.TrackPullKey(config.SubSystemId, config.ServiceProviderId); - if (await RedisHelper.Client.ExistsAsync(redisKey)) - { - continue; - } + var configs = await _trackPullCacheService.GetAllPullConfigsAsync(); - var page = 1; - var orders = await _provideQueries.FindOrderWithServiceProviderAsync(config.ServiceProviderId, page); - while (orders.Any()) + foreach (var config in configs) { - var serviceProviderCode = orders.FirstOrDefault()?.ServiceProviderCode; - var serviceProviderName = orders.FirstOrDefault()?.ServiceProviderName; - - foreach (var group in orders.GroupBy(x => - new { x.SubSystemId, x.OrderType })) + var redisKey = _trackPullCacheService.TrackPullKey(config.SubSystemId, config.ServiceProviderId); + if (await RedisHelper.Client.ExistsAsync(redisKey)) { - var data = group.Select(x => new - { - x.OrderNo - }).ToList(); - - var attach = Base64Helper.SerializeObject(new TrackRefreshAttach(config.ServiceProviderId, - serviceProviderName!, - group.Key.SubSystemId, group.Key.OrderType)); - // 批量获取轨迹 - await _httpClientProxy.Service.BatchForwardThenPushToQueueAsync( - InterfaceRelayConst.GetTrackInterfaceCode, serviceProviderCode, data, - GlobalConst.TrackRefreshSubscribe, attach); + continue; } - orders = await _provideQueries.FindOrderWithServiceProviderAsync(config.ServiceProviderId, ++page); - } + var page = 1; + var orders = await _provideQueries.FindOrderWithServiceProviderAsync(config.ServiceProviderId, page); + while (orders.Any()) + { + var serviceProviderCode = orders.FirstOrDefault()?.ServiceProviderCode; + var serviceProviderName = orders.FirstOrDefault()?.ServiceProviderName; - await RedisHelper.Client.SetExAsync(redisKey, config.PullInterval * 60, orders.Count); - } + foreach (var group in orders.GroupBy(x => + new { x.SubSystemId, x.OrderType })) + { + var data = group.Select(x => new + { + x.OrderNo + }).ToList(); + + var attach = Base64Helper.SerializeObject(new TrackRefreshAttach(config.ServiceProviderId, + serviceProviderName!, + group.Key.SubSystemId, group.Key.OrderType)); + // 批量获取轨迹 + await _httpClientProxy.Service.BatchForwardThenPushToQueueAsync( + InterfaceRelayConst.GetTrackInterfaceCode, serviceProviderCode, data, + GlobalConst.TrackRefreshSubscribe, attach); + } + + orders = await _provideQueries.FindOrderWithServiceProviderAsync(config.ServiceProviderId, ++page); + } + + await RedisHelper.Client.SetExAsync(redisKey, config.PullInterval * 60, orders.Count); + } + }); return true; } From 505d8e7dc1ed16e2ec52a38046869fd26ec9bb95 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=B9=8F=E5=86=9B?= <2357729423@qq.com> Date: Tue, 14 May 2024 17:17:37 +0800 Subject: [PATCH 67/72] =?UTF-8?q?add=EF=BC=9A=E6=B7=BB=E5=8A=A0cap?= =?UTF-8?q?=E6=9C=AC=E5=9C=B0=E5=86=85=E5=AD=98debug?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/SJZY.Track.Application/SJZY.Track.Application.csproj | 2 ++ src/SJZY.Track.Application/SjzyTrackApplicationModule.cs | 7 ++++++- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/src/SJZY.Track.Application/SJZY.Track.Application.csproj b/src/SJZY.Track.Application/SJZY.Track.Application.csproj index b2801d4a..982969a4 100644 --- a/src/SJZY.Track.Application/SJZY.Track.Application.csproj +++ b/src/SJZY.Track.Application/SJZY.Track.Application.csproj @@ -21,6 +21,8 @@ + + diff --git a/src/SJZY.Track.Application/SjzyTrackApplicationModule.cs b/src/SJZY.Track.Application/SjzyTrackApplicationModule.cs index 2984ac45..fa522c48 100644 --- a/src/SJZY.Track.Application/SjzyTrackApplicationModule.cs +++ b/src/SJZY.Track.Application/SjzyTrackApplicationModule.cs @@ -1,5 +1,6 @@ using DotNetCore.CAP; using Microsoft.Extensions.Configuration; +using Savorboard.CAP.InMemoryMessageQueue; using SJZY.Expand.ABP.Core.Localization; using SJZY.Expand.ABP.Core.Logger; using SJZY.Expand.ABP.Core.PublicMethords; @@ -76,6 +77,10 @@ namespace SJZY.Track.Application context.Services.AddCapTableNameService(); context.Services.AddCap(options => { +#if DEBUG + options.UseInMemoryStorage(); + options.UseInMemoryMessageQueue(); +#else options.UseMySql(configuration["ConnectionStrings:DefaultConnection"]!); options.UseRabbitMQ(configure => { @@ -86,7 +91,7 @@ namespace SJZY.Track.Application configure.BasicQosOptions = new RabbitMQOptions.BasicQos(configuration.GetValue("CAP:PrefetchCount")); }); - // options.TopicNamePrefix = "v1"; +#endif options.FailedRetryInterval = configuration.GetValue("CAP:FailedRetryInterval"); options.FailedRetryCount = configuration.GetValue("CAP:FailedRetryCount"); options.SucceedMessageExpiredAfter = configuration.GetValue("CAP:SucceedMessageExpiredAfter"); From b5f7f866646fb0f64be1d62c24ed34a77e3e96e0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=B9=8F=E5=86=9B?= <2357729423@qq.com> Date: Mon, 27 May 2024 11:51:34 +0800 Subject: [PATCH 68/72] =?UTF-8?q?opt=EF=BC=9A=E4=BC=98=E5=8C=96=E6=8E=A8?= =?UTF-8?q?=E9=80=81=E5=B9=82=E7=AD=89=EF=BC=8C=E4=BC=98=E5=8C=96cap?= =?UTF-8?q?=E9=87=8D=E8=AF=95=E6=9C=BA=E5=88=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/SJZY.Track.Api/appsettings.json | 2 +- .../{EventHandlers => CAP}/CAPFilter.cs | 54 ++-- ...TrackChangeAfterUpdateOrderEventHandler.cs | 6 +- .../EventHandlers/TrackDeleteEventHandler.cs | 4 +- .../TrackInsertForNotMappedEventHandler.cs | 2 +- .../TrackPushCompletedEventHandler.cs | 2 +- .../EventHandlers/TrackPushEventHandler.cs | 3 +- .../EventHandlers/TrackRefreshEventHandler.cs | 2 +- .../EventHandlers/TrackUpsertEventHandler.cs | 2 +- .../CAP/LoggerExtensions.cs | 89 ++++++ .../CAP/MySubscribeExecutor.cs | 268 ++++++++++++++++++ .../CAP/SubscriberExecutionFailedException.cs | 15 + .../ProvideServices/TrackPushService.cs | 2 +- .../SjzyTrackApplicationModule.cs | 4 +- .../Consts/GlobalConst.MQ.cs | 5 + 15 files changed, 431 insertions(+), 29 deletions(-) rename src/SJZY.Track.Application/{EventHandlers => CAP}/CAPFilter.cs (59%) rename src/SJZY.Track.Application/{ => CAP}/EventHandlers/TrackChangeAfterUpdateOrderEventHandler.cs (92%) rename src/SJZY.Track.Application/{ => CAP}/EventHandlers/TrackDeleteEventHandler.cs (98%) rename src/SJZY.Track.Application/{ => CAP}/EventHandlers/TrackInsertForNotMappedEventHandler.cs (97%) rename src/SJZY.Track.Application/{ => CAP}/EventHandlers/TrackPushCompletedEventHandler.cs (98%) rename src/SJZY.Track.Application/{ => CAP}/EventHandlers/TrackPushEventHandler.cs (98%) rename src/SJZY.Track.Application/{ => CAP}/EventHandlers/TrackRefreshEventHandler.cs (99%) rename src/SJZY.Track.Application/{ => CAP}/EventHandlers/TrackUpsertEventHandler.cs (99%) create mode 100644 src/SJZY.Track.Application/CAP/LoggerExtensions.cs create mode 100644 src/SJZY.Track.Application/CAP/MySubscribeExecutor.cs create mode 100644 src/SJZY.Track.Application/CAP/SubscriberExecutionFailedException.cs diff --git a/src/SJZY.Track.Api/appsettings.json b/src/SJZY.Track.Api/appsettings.json index 676973d6..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/EventHandlers/CAPFilter.cs b/src/SJZY.Track.Application/CAP/CAPFilter.cs similarity index 59% rename from src/SJZY.Track.Application/EventHandlers/CAPFilter.cs rename to src/SJZY.Track.Application/CAP/CAPFilter.cs index 1ce7c51b..a4e1f841 100644 --- a/src/SJZY.Track.Application/EventHandlers/CAPFilter.cs +++ b/src/SJZY.Track.Application/CAP/CAPFilter.cs @@ -1,10 +1,12 @@ -using DotNetCore.CAP.Filter; +using System.Security.Cryptography; +using System.Text; +using DotNetCore.CAP.Filter; using SJZY.Expand.ABP.Core; using SJZY.Expand.ABP.Core.Logger; using SJZY.Expand.ABP.Core.PublicMethords; using SJZY.Track.Domain.Consts; -namespace SJZY.Track.Application.EventHandlers; +namespace SJZY.Track.Application.CAP; public class CapFilter : SubscribeFilter { @@ -17,21 +19,11 @@ public class CapFilter : SubscribeFilter /// public override Task OnSubscribeExecutingAsync(ExecutingContext context) { - context.DeliverMessage.Headers["sjzy-receive-time"] = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss fff"); - - // 异常重试不做幂等 - if (context.DeliverMessage.Headers.ContainsKey("cap-exception")) return Task.CompletedTask; - - // 轨迹增改要做幂等 - if (!context.DeliverMessage.Headers["cap-msg-name"].IsIn(GlobalConst.TrackUpsertSubscribe)) + // 轨迹新增、更新要做幂等 + if (!context.DeliverMessage.Headers["cap-msg-name"] + .IsIn(GlobalConst.TrackUpsertSubscribe, GlobalConst.TrackManualPushSubscribe)) return Task.CompletedTask; - // 本地调试不做幂等 - if (System.Diagnostics.Debugger.IsAttached) - { - return Task.CompletedTask; - } - var argumentJsonStr = context.Arguments.ToJson(); var hash = argumentJsonStr.GetHash(); @@ -44,15 +36,23 @@ public class CapFilter : SubscribeFilter var isSkip = !string.IsNullOrEmpty(RedisHelper.Client.Get($"CapExecuteFilter:{hash}")); if (isSkip) throw new BusinessException(ErrorCode, $"检测到重复消费,消费参数:{argumentJsonStr}"); - - RedisHelper.Client.Set($"CapExecuteFilter:{hash}", 60 * 10, - TimeSpan.FromMinutes(5).Seconds); } } return Task.CompletedTask; } + public override Task OnSubscribeExecutedAsync(ExecutedContext context) + { + context.DeliverMessage.Headers.TryGetValue("sjzy-arguments-hash", out var hash); + if (!hash.IsNullOrEmpty()) + { + RedisHelper.Client.Set($"CapExecuteFilter:{hash}", 60 * 10, TimeSpan.FromMinutes(10).Seconds); + } + + return Task.CompletedTask; + } + /// /// 消费异常事件 /// @@ -72,4 +72,22 @@ 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/EventHandlers/TrackChangeAfterUpdateOrderEventHandler.cs b/src/SJZY.Track.Application/CAP/EventHandlers/TrackChangeAfterUpdateOrderEventHandler.cs similarity index 92% rename from src/SJZY.Track.Application/EventHandlers/TrackChangeAfterUpdateOrderEventHandler.cs rename to src/SJZY.Track.Application/CAP/EventHandlers/TrackChangeAfterUpdateOrderEventHandler.cs index 3e3b1d07..c8f184ae 100644 --- a/src/SJZY.Track.Application/EventHandlers/TrackChangeAfterUpdateOrderEventHandler.cs +++ b/src/SJZY.Track.Application/CAP/EventHandlers/TrackChangeAfterUpdateOrderEventHandler.cs @@ -5,7 +5,7 @@ using SJZY.Track.Domain.Aggregates.TrackDetailsAggregate; using SJZY.Track.Domain.Consts; using Volo.Abp.DependencyInjection; -namespace SJZY.Track.Application.EventHandlers; +namespace SJZY.Track.Application.CAP.EventHandlers; public class TrackChangeAfterUpdateOrderEventHandler : ITransientDependency, ICapSubscribe { @@ -36,6 +36,7 @@ public class TrackChangeAfterUpdateOrderEventHandler : ITransientDependency, ICa if (orders.Count == 0) return; + var updateOrders = new List(); foreach (var order in orders) { if (order.LatestTrackContent != @event.TrackContent) @@ -58,9 +59,10 @@ public class TrackChangeAfterUpdateOrderEventHandler : ITransientDependency, ICa order.LatestTrackPlace = @event.TrackPlace; order.LatestTrackTime = @event.TrackTime; order.LatestTrackTimeZone = @event.TrackTimeZone; + updateOrders.Add(order); } - await _orderRepository.UpdateRangeAsync(orders, x => new + await _orderRepository.UpdateRangeAsync(updateOrders, x => new { x.IsCompleted, x.LatestTrackContent, x.LatestTrackEnContent, x.LatestTrackPlace, x.LatestTrackTime, x.LatestTrackTimeZone diff --git a/src/SJZY.Track.Application/EventHandlers/TrackDeleteEventHandler.cs b/src/SJZY.Track.Application/CAP/EventHandlers/TrackDeleteEventHandler.cs similarity index 98% rename from src/SJZY.Track.Application/EventHandlers/TrackDeleteEventHandler.cs rename to src/SJZY.Track.Application/CAP/EventHandlers/TrackDeleteEventHandler.cs index bd85a916..fa2751bf 100644 --- a/src/SJZY.Track.Application/EventHandlers/TrackDeleteEventHandler.cs +++ b/src/SJZY.Track.Application/CAP/EventHandlers/TrackDeleteEventHandler.cs @@ -8,7 +8,7 @@ using SJZY.Track.Domain.Consts; using SJZY.Track.Domain.Queries; using Volo.Abp.DependencyInjection; -namespace SJZY.Track.Application.EventHandlers; +namespace SJZY.Track.Application.CAP.EventHandlers; public class TrackDeleteEventHandler : ITransientDependency, ICapSubscribe { @@ -29,6 +29,8 @@ public class TrackDeleteEventHandler : ITransientDependency, ICapSubscribe [CapSubscribe(GlobalConst.TrackDeleteSubscribe, Group = GlobalConst.TrackDeleteSubscribe)] public async Task ConsumerAsync(TrackDeleteEvent @event) { + throw new Exception(); + var dup = @event.Visited.Intersect(@event.OrderIds).ToArray(); if (dup.Any()) { diff --git a/src/SJZY.Track.Application/EventHandlers/TrackInsertForNotMappedEventHandler.cs b/src/SJZY.Track.Application/CAP/EventHandlers/TrackInsertForNotMappedEventHandler.cs similarity index 97% rename from src/SJZY.Track.Application/EventHandlers/TrackInsertForNotMappedEventHandler.cs rename to src/SJZY.Track.Application/CAP/EventHandlers/TrackInsertForNotMappedEventHandler.cs index 9bd76c5e..b2f59331 100644 --- a/src/SJZY.Track.Application/EventHandlers/TrackInsertForNotMappedEventHandler.cs +++ b/src/SJZY.Track.Application/CAP/EventHandlers/TrackInsertForNotMappedEventHandler.cs @@ -4,7 +4,7 @@ using SJZY.Track.Domain.Aggregates.TrackDetailsAggregate; using SJZY.Track.Domain.Consts; using Volo.Abp.DependencyInjection; -namespace SJZY.Track.Application.EventHandlers; +namespace SJZY.Track.Application.CAP.EventHandlers; public class TrackInsertForNotMappedEventHandler : ITransientDependency, ICapSubscribe { diff --git a/src/SJZY.Track.Application/EventHandlers/TrackPushCompletedEventHandler.cs b/src/SJZY.Track.Application/CAP/EventHandlers/TrackPushCompletedEventHandler.cs similarity index 98% rename from src/SJZY.Track.Application/EventHandlers/TrackPushCompletedEventHandler.cs rename to src/SJZY.Track.Application/CAP/EventHandlers/TrackPushCompletedEventHandler.cs index a1024118..4658aa44 100644 --- a/src/SJZY.Track.Application/EventHandlers/TrackPushCompletedEventHandler.cs +++ b/src/SJZY.Track.Application/CAP/EventHandlers/TrackPushCompletedEventHandler.cs @@ -9,7 +9,7 @@ using SJZY.Track.Domain.Consts; using SJZY.Track.Domain.Enums; using Volo.Abp.DependencyInjection; -namespace SJZY.Track.Application.EventHandlers; +namespace SJZY.Track.Application.CAP.EventHandlers; public class TrackPushCompletedEventHandler : ITransientDependency, ICapSubscribe { diff --git a/src/SJZY.Track.Application/EventHandlers/TrackPushEventHandler.cs b/src/SJZY.Track.Application/CAP/EventHandlers/TrackPushEventHandler.cs similarity index 98% rename from src/SJZY.Track.Application/EventHandlers/TrackPushEventHandler.cs rename to src/SJZY.Track.Application/CAP/EventHandlers/TrackPushEventHandler.cs index 5edf8f4a..734246eb 100644 --- a/src/SJZY.Track.Application/EventHandlers/TrackPushEventHandler.cs +++ b/src/SJZY.Track.Application/CAP/EventHandlers/TrackPushEventHandler.cs @@ -14,7 +14,7 @@ using SJZY.Track.Domain.Enums; using Volo.Abp.DependencyInjection; using Volo.Abp.Http.Client.DynamicProxying; -namespace SJZY.Track.Application.EventHandlers; +namespace SJZY.Track.Application.CAP.EventHandlers; public class TrackPushEventHandler : ITransientDependency, ICapSubscribe { @@ -38,6 +38,7 @@ public class TrackPushEventHandler : ITransientDependency, ICapSubscribe } [CapSubscribe(GlobalConst.TrackPushSubscribe, Group = GlobalConst.TrackPushSubscribe)] + [CapSubscribe(GlobalConst.TrackManualPushSubscribe, Group = GlobalConst.TrackPushSubscribe)] public async Task ConsumerAsync(TrackPushEvent @event) { var pushConfigs = await _trackPushCacheService.GetPushContentConfigsAsync(@event.SubSystemId, @event.CustomId); diff --git a/src/SJZY.Track.Application/EventHandlers/TrackRefreshEventHandler.cs b/src/SJZY.Track.Application/CAP/EventHandlers/TrackRefreshEventHandler.cs similarity index 99% rename from src/SJZY.Track.Application/EventHandlers/TrackRefreshEventHandler.cs rename to src/SJZY.Track.Application/CAP/EventHandlers/TrackRefreshEventHandler.cs index 0e9fd334..f982343e 100644 --- a/src/SJZY.Track.Application/EventHandlers/TrackRefreshEventHandler.cs +++ b/src/SJZY.Track.Application/CAP/EventHandlers/TrackRefreshEventHandler.cs @@ -14,7 +14,7 @@ using SJZY.Track.Domain.Consts; using SJZY.Track.Domain.Enums; using Volo.Abp.DependencyInjection; -namespace SJZY.Track.Application.EventHandlers; +namespace SJZY.Track.Application.CAP.EventHandlers; public class TrackRefreshEventHandler : ITransientDependency, ICapSubscribe { diff --git a/src/SJZY.Track.Application/EventHandlers/TrackUpsertEventHandler.cs b/src/SJZY.Track.Application/CAP/EventHandlers/TrackUpsertEventHandler.cs similarity index 99% rename from src/SJZY.Track.Application/EventHandlers/TrackUpsertEventHandler.cs rename to src/SJZY.Track.Application/CAP/EventHandlers/TrackUpsertEventHandler.cs index 201c4efc..46443ffb 100644 --- a/src/SJZY.Track.Application/EventHandlers/TrackUpsertEventHandler.cs +++ b/src/SJZY.Track.Application/CAP/EventHandlers/TrackUpsertEventHandler.cs @@ -8,7 +8,7 @@ using SJZY.Track.Domain.Consts; using SJZY.Track.Domain.Queries; using Volo.Abp.DependencyInjection; -namespace SJZY.Track.Application.EventHandlers; +namespace SJZY.Track.Application.CAP.EventHandlers; public class TrackUpsertEventHandler : ITransientDependency, ICapSubscribe { diff --git a/src/SJZY.Track.Application/CAP/LoggerExtensions.cs b/src/SJZY.Track.Application/CAP/LoggerExtensions.cs new file mode 100644 index 00000000..8b430825 --- /dev/null +++ b/src/SJZY.Track.Application/CAP/LoggerExtensions.cs @@ -0,0 +1,89 @@ +using Microsoft.Extensions.Logging; + +namespace SJZY.Track.Application.CAP; + +internal static class LoggerExtensions +{ + public static void ConsumerExecutedAfterThreshold(this ILogger logger, string messageId, int retries) + { + logger.LogWarning( + $"The Subscriber of the message({messageId}) still fails after {retries}th executions and we will stop retrying."); + } + + public static void SenderAfterThreshold(this ILogger logger, string messageId, int retries) + { + logger.LogWarning( + $"The Publisher of the message({messageId}) still fails after {retries}th sends and we will stop retrying."); + } + + public static void ExecutedThresholdCallbackFailed(this ILogger logger, Exception ex) + { + logger.LogWarning(ex, "FailedThresholdCallback action raised an exception:" + ex.Message); + } + + public static void ConsumerDuplicates(this ILogger logger, string subscriber, string group) + { + logger.LogWarning( + $"We detected that you have duplicate subscribers ({subscriber}) in same group ({group}), this will cause diversity behavior."); + } + + public static void ConsumerExecutionRetrying(this ILogger logger, string messageId, int retries) + { + logger.LogWarning($"The {retries}th retrying consume a message failed. message id: {messageId}"); + } + + public static void SenderRetrying(this ILogger logger, string messageId, int retries) + { + logger.LogWarning($"The {retries}th retrying send a message failed. message id: {messageId} "); + } + + public static void MessageReceived(this ILogger logger, string messageId, string name) + { + logger.LogDebug($"Received message. id:{messageId}, name: {name}"); + } + + public static void MessagePublishException(this ILogger logger, string? messageId, string reason, Exception? ex) + { + logger.LogError(ex, + $"An exception occurred while publishing a message, reason:{reason}. message id:{messageId}"); + } + + public static void ConsumerExecuting(this ILogger logger, string className, string methodName, string group) + { + logger.LogInformation($"Executing subscriber method '{className}.{methodName}' on group '{group}'"); + } + + public static void ConsumerExecuted(this ILogger logger, string className, string methodName, string group, + double milliseconds, string? instance) + { + logger.LogInformation( + $"Executed subscriber method '{className}.{methodName}' on group '{group}' with instance '{instance}' in {milliseconds}ms"); + } + + public static void ConsumerExecuteFailed(this ILogger logger, string topic, string id, string? instance, + Exception? ex) + { + logger.LogError(ex, + $"An exception occurred while executing the subscription method. Topic:{topic}, Id:{id}, Instance: {instance}"); + } + + public static void ServerStarting(this ILogger logger) + { + logger.LogInformation("Starting the processing server."); + } + + public static void ProcessorsStartedError(this ILogger logger, Exception ex) + { + logger.LogError(ex, "Starting the processors throw an exception."); + } + + public static void ServerShuttingDown(this ILogger logger) + { + logger.LogInformation("Shutting down the processing server..."); + } + + public static void ExpectedOperationCanceledException(this ILogger logger, Exception ex) + { + logger.LogWarning(ex, $"Expected an OperationCanceledException, but found '{ex.Message}'."); + } +} \ No newline at end of file diff --git a/src/SJZY.Track.Application/CAP/MySubscribeExecutor.cs b/src/SJZY.Track.Application/CAP/MySubscribeExecutor.cs new file mode 100644 index 00000000..c9ff478b --- /dev/null +++ b/src/SJZY.Track.Application/CAP/MySubscribeExecutor.cs @@ -0,0 +1,268 @@ +using System.Diagnostics; +using System.Reflection; +using DotNetCore.CAP; +using DotNetCore.CAP.Diagnostics; +using DotNetCore.CAP.Internal; +using DotNetCore.CAP.Messages; +using DotNetCore.CAP.Persistence; +using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Options; + +namespace SJZY.Track.Application.CAP; + +public class MySubscribeExecutor : ISubscribeExecutor +{ + // diagnostics listener + // ReSharper disable once InconsistentNaming + private static readonly DiagnosticListener s_diagnosticListener = + new(CapDiagnosticListenerNames.DiagnosticListenerName); + + private readonly IDataStorage _dataStorage; + private readonly string? _hostName; + private readonly ILogger _logger; + private readonly CapOptions _options; + private readonly IServiceProvider _provider; + + public MySubscribeExecutor( + ILogger logger, + IOptions options, + IServiceProvider provider) + { + _provider = provider; + _logger = logger; + _options = options.Value; + + _dataStorage = _provider.GetRequiredService(); + Invoker = _provider.GetRequiredService(); + _hostName = Helper.GetInstanceHostname(); + } + + private ISubscribeInvoker Invoker { get; } + + public async Task ExecuteAsync(MediumMessage message, ConsumerExecutorDescriptor? descriptor = null, + CancellationToken cancellationToken = default) + { + if (descriptor == null) + { + var selector = _provider.GetRequiredService(); + if (!selector.TryGetTopicExecutor(message.Origin.GetName(), message.Origin.GetGroup()!, out descriptor)) + { + var error = + $"Message (Name:{message.Origin.GetName()},Group:{message.Origin.GetGroup()}) can not be found subscriber." + + $"{Environment.NewLine} see: https://github.com/dotnetcore/CAP/issues/63"; + _logger.LogError(error); + + TracingError(DateTimeOffset.UtcNow.ToUnixTimeMilliseconds(), message.Origin, null, + new Exception(error)); + + var ex = new SubscriberNotFoundException(error); + await SetFailedState(message, ex); + return OperateResult.Failed(ex); + } + } + + bool retry; + OperateResult result; + + //record instance id + message.Origin.Headers[Headers.ExecutionInstanceId] = _hostName; + + do + { + var (shouldRetry, operateResult) = await ExecuteWithoutRetryAsync(message, descriptor, cancellationToken) + .ConfigureAwait(false); + result = operateResult; + if (result.Equals(OperateResult.Success)) return result; + retry = shouldRetry; + } while (retry); + + return result; + } + + private async Task<(bool, OperateResult)> ExecuteWithoutRetryAsync(MediumMessage message, + ConsumerExecutorDescriptor descriptor, CancellationToken cancellationToken) + { + if (message == null) throw new ArgumentNullException(nameof(message)); + + cancellationToken.ThrowIfCancellationRequested(); + + try + { + _logger.ConsumerExecuting(descriptor.ImplTypeInfo.Name, descriptor.MethodInfo.Name, + descriptor.Attribute.Group); + + var sp = Stopwatch.StartNew(); + + await InvokeConsumerMethodAsync(message, descriptor, cancellationToken).ConfigureAwait(false); + + sp.Stop(); + + await SetSuccessfulState(message).ConfigureAwait(false); + + CapEventCounterSource.Log.WriteInvokeTimeMetrics(sp.Elapsed.TotalMilliseconds); + _logger.ConsumerExecuted(descriptor.ImplTypeInfo.Name, descriptor.MethodInfo.Name, + descriptor.Attribute.Group, sp.Elapsed.TotalMilliseconds, message.Origin.GetExecutionInstanceId()); + + return (false, OperateResult.Success); + } + catch (Exception ex) + { + _logger.ConsumerExecuteFailed(message.Origin.GetName(), message.DbId, + message.Origin.GetExecutionInstanceId(), ex); + + return (await SetFailedState(message, ex).ConfigureAwait(false), OperateResult.Failed(ex)); + } + } + + private Task SetSuccessfulState(MediumMessage message) + { + message.ExpiresAt = DateTime.Now.AddSeconds(_options.SucceedMessageExpiredAfter); + + return _dataStorage.ChangeReceiveStateAsync(message, StatusName.Succeeded); + } + + private async Task SetFailedState(MediumMessage message, Exception ex) + { + if (ex is SubscriberNotFoundException) + message.Retries = _options.FailedRetryCount; // not retry if SubscriberNotFoundException + + var needRetry = UpdateMessageForRetry(message); + + message.Origin.AddOrUpdateException(ex); + message.ExpiresAt = message.Added.AddSeconds(_options.FailedMessageExpiredAfter); + + await _dataStorage.ChangeReceiveStateAsync(message, StatusName.Failed).ConfigureAwait(false); + + return needRetry; + } + + private bool UpdateMessageForRetry(MediumMessage message) + { + var retries = ++message.Retries; + + if (retries == _options.FailedRetryCount) + { + try + { + _options.FailedThresholdCallback?.Invoke(new FailedInfo + { + ServiceProvider = _provider, + MessageType = MessageType.Subscribe, + Message = message.Origin + }); + + _logger.ConsumerExecutedAfterThreshold(message.DbId, _options.FailedRetryCount); + } + catch (Exception ex) + { + _logger.ExecutedThresholdCallbackFailed(ex); + } + } + + return false; + } + + private async Task InvokeConsumerMethodAsync(MediumMessage message, ConsumerExecutorDescriptor descriptor, + CancellationToken cancellationToken) + { + var consumerContext = new ConsumerContext(descriptor, message); + var tracingTimestamp = TracingBefore(message.Origin, descriptor.MethodInfo); + try + { + var ret = await Invoker.InvokeAsync(consumerContext, cancellationToken).ConfigureAwait(false); + + TracingAfter(tracingTimestamp, message.Origin, descriptor.MethodInfo); + + if (!string.IsNullOrEmpty(ret.CallbackName)) + { + var header = new Dictionary + { + [Headers.CorrelationId] = message.Origin.GetId(), + [Headers.CorrelationSequence] = (message.Origin.GetCorrelationSequence() + 1).ToString() + }; + + if (message.Origin.Headers.TryGetValue(Headers.TraceParent, out var traceparent)) + header[Headers.TraceParent] = traceparent; + + await _provider.GetRequiredService() + .PublishAsync(ret.CallbackName, ret.Result, header, cancellationToken).ConfigureAwait(false); + } + } + catch (OperationCanceledException) + { + //ignore + } + catch (Exception ex) + { + var e = new SubscriberExecutionFailedException(ex.Message, ex); + + TracingError(tracingTimestamp, message.Origin, descriptor.MethodInfo, e); + + e.ReThrow(); + } + } + + #region tracing + + private long? TracingBefore(Message message, MethodInfo method) + { + if (s_diagnosticListener.IsEnabled(CapDiagnosticListenerNames.BeforeSubscriberInvoke)) + { + var eventData = new CapEventDataSubExecute + { + OperationTimestamp = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds(), + Operation = message.GetName(), + Message = message, + MethodInfo = method + }; + + s_diagnosticListener.Write(CapDiagnosticListenerNames.BeforeSubscriberInvoke, eventData); + + return eventData.OperationTimestamp; + } + + return null; + } + + private void TracingAfter(long? tracingTimestamp, Message message, MethodInfo method) + { + CapEventCounterSource.Log.WriteInvokeMetrics(); + if (tracingTimestamp != null && + s_diagnosticListener.IsEnabled(CapDiagnosticListenerNames.AfterSubscriberInvoke)) + { + var now = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds(); + var eventData = new CapEventDataSubExecute + { + OperationTimestamp = now, + Operation = message.GetName(), + Message = message, + MethodInfo = method, + ElapsedTimeMs = now - tracingTimestamp.Value + }; + + s_diagnosticListener.Write(CapDiagnosticListenerNames.AfterSubscriberInvoke, eventData); + } + } + + private void TracingError(long? tracingTimestamp, Message message, MethodInfo? method, Exception ex) + { + if (tracingTimestamp != null && + s_diagnosticListener.IsEnabled(CapDiagnosticListenerNames.ErrorSubscriberInvoke)) + { + var now = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds(); + var eventData = new CapEventDataSubExecute + { + OperationTimestamp = now, + Operation = message.GetName(), + Message = message, + MethodInfo = method, + ElapsedTimeMs = now - tracingTimestamp.Value, + Exception = ex + }; + + s_diagnosticListener.Write(CapDiagnosticListenerNames.ErrorSubscriberInvoke, eventData); + } + } + + #endregion +} \ No newline at end of file diff --git a/src/SJZY.Track.Application/CAP/SubscriberExecutionFailedException.cs b/src/SJZY.Track.Application/CAP/SubscriberExecutionFailedException.cs new file mode 100644 index 00000000..31b183af --- /dev/null +++ b/src/SJZY.Track.Application/CAP/SubscriberExecutionFailedException.cs @@ -0,0 +1,15 @@ +namespace SJZY.Track.Application.CAP; + +internal class SubscriberExecutionFailedException : Exception +{ + private readonly Exception _originException; + + public SubscriberExecutionFailedException(string message, Exception ex) : base(message, ex) + { + _originException = ex; + } + + public override string? StackTrace => _originException.StackTrace; + + public override string? Source => _originException.Source; +} \ 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 d4bcb72d..6897451e 100644 --- a/src/SJZY.Track.Application/Services/ProvideServices/TrackPushService.cs +++ b/src/SJZY.Track.Application/Services/ProvideServices/TrackPushService.cs @@ -62,7 +62,7 @@ public class TrackPushService : ApplicationService OperationMan = CurrentUserRequest.CurrentUser.Name, }; - await _capPublisher.PublishAsync(GlobalConst.TrackPushSubscribe, trackPushEvent); + await _capPublisher.PublishAsync(GlobalConst.TrackManualPushSubscribe, trackPushEvent); } return $"即将推送轨迹代码{input.TrackCode}给{orders.Length}个订单"; diff --git a/src/SJZY.Track.Application/SjzyTrackApplicationModule.cs b/src/SJZY.Track.Application/SjzyTrackApplicationModule.cs index fa522c48..efa5aa41 100644 --- a/src/SJZY.Track.Application/SjzyTrackApplicationModule.cs +++ b/src/SJZY.Track.Application/SjzyTrackApplicationModule.cs @@ -1,12 +1,13 @@ using DotNetCore.CAP; +using DotNetCore.CAP.Internal; using Microsoft.Extensions.Configuration; using Savorboard.CAP.InMemoryMessageQueue; using SJZY.Expand.ABP.Core.Localization; using SJZY.Expand.ABP.Core.Logger; using SJZY.Expand.ABP.Core.PublicMethords; using SJZY.InterfaceRelay.Application.Contracts; +using SJZY.Track.Application.CAP; using SJZY.Track.Application.Contract; -using SJZY.Track.Application.EventHandlers; using SJZY.Track.Application.Localization; using SJZY.UserCenter.Contracts; using SJZY.UserCenter.SharedModel; @@ -74,6 +75,7 @@ namespace SJZY.Track.Application ); //CAP + context.Services.AddSingleton(); context.Services.AddCapTableNameService(); context.Services.AddCap(options => { diff --git a/src/SJZY.Track.Domain/Consts/GlobalConst.MQ.cs b/src/SJZY.Track.Domain/Consts/GlobalConst.MQ.cs index 93fd1c53..378f0b89 100644 --- a/src/SJZY.Track.Domain/Consts/GlobalConst.MQ.cs +++ b/src/SJZY.Track.Domain/Consts/GlobalConst.MQ.cs @@ -32,6 +32,11 @@ public partial class GlobalConst /// public const string TrackPushSubscribe = "SJZY.Track.TrackPush"; + /// + /// 轨迹人工手动推送 + /// + public const string TrackManualPushSubscribe = "SJZY.Track.TrackManualPush"; + /// /// 轨迹推送完成(接口通回调) /// From 33c36bed103e050eaf01a7a7b9858f6b87386319 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=B9=8F=E5=86=9B?= <2357729423@qq.com> Date: Mon, 27 May 2024 16:52:08 +0800 Subject: [PATCH 69/72] =?UTF-8?q?opt=EF=BC=9A=E4=BC=98=E5=8C=96cap=20filte?= =?UTF-8?q?r?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/SJZY.Track.Application/CAP/CAPFilter.cs | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/src/SJZY.Track.Application/CAP/CAPFilter.cs b/src/SJZY.Track.Application/CAP/CAPFilter.cs index a4e1f841..110395fc 100644 --- a/src/SJZY.Track.Application/CAP/CAPFilter.cs +++ b/src/SJZY.Track.Application/CAP/CAPFilter.cs @@ -19,24 +19,21 @@ public class CapFilter : SubscribeFilter /// public override Task OnSubscribeExecutingAsync(ExecutingContext context) { + if (!context.DeliverMessage.Headers["sjzy-arguments-hash"].IsNullOrEmpty()) return Task.CompletedTask; + // 轨迹新增、更新要做幂等 if (!context.DeliverMessage.Headers["cap-msg-name"] .IsIn(GlobalConst.TrackUpsertSubscribe, GlobalConst.TrackManualPushSubscribe)) return Task.CompletedTask; var argumentJsonStr = context.Arguments.ToJson(); - var hash = argumentJsonStr.GetHash(); - - context.DeliverMessage.Headers["sjzy-arguments-hash"] = hash; if (!string.IsNullOrEmpty(argumentJsonStr)) { - using (RedisHelper.Client.Lock("Filter:" + hash, 10)) - { - var isSkip = !string.IsNullOrEmpty(RedisHelper.Client.Get($"CapExecuteFilter:{hash}")); - if (isSkip) - throw new BusinessException(ErrorCode, $"检测到重复消费,消费参数:{argumentJsonStr}"); - } + var hash = GetHash(argumentJsonStr); + context.DeliverMessage.Headers["sjzy-arguments-hash"] = hash; + if (!string.IsNullOrEmpty(RedisHelper.Client.Get($"CapExecuteFilter:{hash}"))) + throw new BusinessException(ErrorCode, $"检测到重复消费,消费参数:{argumentJsonStr}"); } return Task.CompletedTask; From 5712f567dfbf9d5168f2e9b6a3828baefd0fe1d2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=B9=8F=E5=86=9B?= <2357729423@qq.com> Date: Mon, 27 May 2024 17:00:39 +0800 Subject: [PATCH 70/72] =?UTF-8?q?opt=EF=BC=9A=E6=8F=90=E5=8F=96=E9=85=8D?= =?UTF-8?q?=E7=BD=AE=E9=87=8D=E8=AF=95=E5=86=B7=E5=8D=B4=E7=AA=97=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/SJZY.Track.Application/CAP/CAPFilter.cs | 35 +++++++++++-------- .../SjzyTrackApplicationModule.cs | 2 ++ 2 files changed, 23 insertions(+), 14 deletions(-) diff --git a/src/SJZY.Track.Application/CAP/CAPFilter.cs b/src/SJZY.Track.Application/CAP/CAPFilter.cs index 110395fc..6522599b 100644 --- a/src/SJZY.Track.Application/CAP/CAPFilter.cs +++ b/src/SJZY.Track.Application/CAP/CAPFilter.cs @@ -17,37 +17,40 @@ public class CapFilter : SubscribeFilter /// /// /// - public override Task OnSubscribeExecutingAsync(ExecutingContext context) + public override async Task OnSubscribeExecutingAsync(ExecutingContext context) { - if (!context.DeliverMessage.Headers["sjzy-arguments-hash"].IsNullOrEmpty()) return Task.CompletedTask; - // 轨迹新增、更新要做幂等 if (!context.DeliverMessage.Headers["cap-msg-name"] .IsIn(GlobalConst.TrackUpsertSubscribe, GlobalConst.TrackManualPushSubscribe)) - return Task.CompletedTask; + { + return; + } var argumentJsonStr = context.Arguments.ToJson(); if (!string.IsNullOrEmpty(argumentJsonStr)) { - var hash = GetHash(argumentJsonStr); - context.DeliverMessage.Headers["sjzy-arguments-hash"] = hash; - if (!string.IsNullOrEmpty(RedisHelper.Client.Get($"CapExecuteFilter:{hash}"))) - throw new BusinessException(ErrorCode, $"检测到重复消费,消费参数:{argumentJsonStr}"); - } + var hash = context.DeliverMessage.Headers["sjzy-arguments-hash"]; + if (hash.IsNullOrEmpty()) // 计算参数hash + { + hash = GetHash(argumentJsonStr); + context.DeliverMessage.Headers["sjzy-arguments-hash"] = hash; + } - return Task.CompletedTask; + if (await RedisHelper.Client.ExistsAsync($"CapExecuteFilter:{hash}")) + { + throw new BusinessException(ErrorCode, $"检测到重复消费,消费参数:{argumentJsonStr}"); + } + } } - public override Task OnSubscribeExecutedAsync(ExecutedContext context) + public override async Task OnSubscribeExecutedAsync(ExecutedContext context) { context.DeliverMessage.Headers.TryGetValue("sjzy-arguments-hash", out var hash); if (!hash.IsNullOrEmpty()) { - RedisHelper.Client.Set($"CapExecuteFilter:{hash}", 60 * 10, TimeSpan.FromMinutes(10).Seconds); + await RedisHelper.Client.SetAsync($"CapExecuteFilter:{hash}", 1, TimeSpan.FromMinutes(10).Seconds); } - - return Task.CompletedTask; } /// @@ -65,7 +68,11 @@ public class CapFilter : SubscribeFilter LogHelper.Warn(ex.ToString()); } else + { + // 发飞书,异常继续上抛,进入重试机制 + // tips:重试有冷却期(默认4分钟) LogHelper.Error($"cap-msg-id:{messageId}\n{context.Exception}"); + } return Task.CompletedTask; } diff --git a/src/SJZY.Track.Application/SjzyTrackApplicationModule.cs b/src/SJZY.Track.Application/SjzyTrackApplicationModule.cs index efa5aa41..10394daa 100644 --- a/src/SJZY.Track.Application/SjzyTrackApplicationModule.cs +++ b/src/SJZY.Track.Application/SjzyTrackApplicationModule.cs @@ -97,6 +97,8 @@ namespace SJZY.Track.Application options.FailedRetryInterval = configuration.GetValue("CAP:FailedRetryInterval"); options.FailedRetryCount = configuration.GetValue("CAP:FailedRetryCount"); options.SucceedMessageExpiredAfter = configuration.GetValue("CAP:SucceedMessageExpiredAfter"); + options.FallbackWindowLookbackSeconds = + configuration.GetValue("CAP:FallbackWindowLookbackSeconds"); options.EnableSubscriberParallelExecute = true; options.UseDashboard(dashboardOptions => From b4bcb377eccef946eba125789469f32c4727e18e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=B9=8F=E5=86=9B?= <2357729423@qq.com> Date: Mon, 27 May 2024 17:29:51 +0800 Subject: [PATCH 71/72] =?UTF-8?q?fix=EF=BC=9Ahash=20key=E4=B8=8D=E5=AD=98?= =?UTF-8?q?=E5=9C=A8=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/SJZY.Track.Application/CAP/CAPFilter.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/SJZY.Track.Application/CAP/CAPFilter.cs b/src/SJZY.Track.Application/CAP/CAPFilter.cs index 6522599b..036c1e34 100644 --- a/src/SJZY.Track.Application/CAP/CAPFilter.cs +++ b/src/SJZY.Track.Application/CAP/CAPFilter.cs @@ -30,7 +30,7 @@ public class CapFilter : SubscribeFilter if (!string.IsNullOrEmpty(argumentJsonStr)) { - var hash = context.DeliverMessage.Headers["sjzy-arguments-hash"]; + context.DeliverMessage.Headers.TryGetValue("sjzy-arguments-hash", out var hash); if (hash.IsNullOrEmpty()) // 计算参数hash { hash = GetHash(argumentJsonStr); From c63bf09c085e135ff3a80ec56cf2147404869edf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=B9=8F=E5=86=9B?= <2357729423@qq.com> Date: Tue, 28 May 2024 09:05:39 +0800 Subject: [PATCH 72/72] =?UTF-8?q?=E8=BF=98=E5=8E=9F=E8=B0=83=E8=AF=95?= =?UTF-8?q?=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../CAP/EventHandlers/TrackDeleteEventHandler.cs | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/SJZY.Track.Application/CAP/EventHandlers/TrackDeleteEventHandler.cs b/src/SJZY.Track.Application/CAP/EventHandlers/TrackDeleteEventHandler.cs index fa2751bf..ae24d7e3 100644 --- a/src/SJZY.Track.Application/CAP/EventHandlers/TrackDeleteEventHandler.cs +++ b/src/SJZY.Track.Application/CAP/EventHandlers/TrackDeleteEventHandler.cs @@ -29,8 +29,6 @@ public class TrackDeleteEventHandler : ITransientDependency, ICapSubscribe [CapSubscribe(GlobalConst.TrackDeleteSubscribe, Group = GlobalConst.TrackDeleteSubscribe)] public async Task ConsumerAsync(TrackDeleteEvent @event) { - throw new Exception(); - var dup = @event.Visited.Intersect(@event.OrderIds).ToArray(); if (dup.Any()) {