From ea77583ce41e13c28929b9b5e6b8e5f4110ddb90 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=BA=91=E9=BE=99=20=E7=8E=8B?= Date: Mon, 25 Nov 2024 18:16:42 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=E5=88=A0=E9=99=A4?= =?UTF-8?q?=E8=BD=A8=E8=BF=B9=E5=A4=B1=E8=B4=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ProvideServices/BatchDeleteTrackInput.cs | 4 +- .../Dtos/ProvideServices/DeleteOrderInput.cs | 4 +- .../ProvideServices/TrackIdentifierDto.cs | 21 +++++++++ .../Events/TrackDeleteEvent.cs | 8 ++-- .../EventHandlers/TrackDeleteEventHandler.cs | 43 +++++++++++++++---- .../Services/ProvideServices/TrackService.cs | 24 ++++++++--- .../ITrackDetailsEsRepository.cs | 3 +- .../Dtos/TrackContents/TrackCodeMapVO.cs | 27 ++++++++++++ .../Queries/IProvideQueries.cs | 8 ++++ .../Queries/ProvideQueries.cs | 20 ++++++++- .../Repositories/TrackDetailsEsRepository.cs | 38 +++++++++++++--- 11 files changed, 168 insertions(+), 32 deletions(-) create mode 100644 src/SJZY.Track.Application.Contract/Dtos/ProvideServices/TrackIdentifierDto.cs create mode 100644 src/SJZY.Track.Domain/Dtos/TrackContents/TrackCodeMapVO.cs diff --git a/src/SJZY.Track.Application.Contract/Dtos/ProvideServices/BatchDeleteTrackInput.cs b/src/SJZY.Track.Application.Contract/Dtos/ProvideServices/BatchDeleteTrackInput.cs index 07db4f25..45ccc51c 100644 --- a/src/SJZY.Track.Application.Contract/Dtos/ProvideServices/BatchDeleteTrackInput.cs +++ b/src/SJZY.Track.Application.Contract/Dtos/ProvideServices/BatchDeleteTrackInput.cs @@ -5,9 +5,9 @@ namespace SJZY.Track.Application.Contract.Dtos.ProvideServices; public class BatchDeleteTrackInput : OrderNosInfo { /// - /// 轨迹code,必填 + /// 轨迹标识符集合,必填 /// [Required] [MaxLength(500)] - public List TrackCodes { get; set; } = new(); + public List TrackIdentifiers { get; set; } = new(); } diff --git a/src/SJZY.Track.Application.Contract/Dtos/ProvideServices/DeleteOrderInput.cs b/src/SJZY.Track.Application.Contract/Dtos/ProvideServices/DeleteOrderInput.cs index c70c9b42..de305c57 100644 --- a/src/SJZY.Track.Application.Contract/Dtos/ProvideServices/DeleteOrderInput.cs +++ b/src/SJZY.Track.Application.Contract/Dtos/ProvideServices/DeleteOrderInput.cs @@ -9,8 +9,8 @@ public class DeleteOrderInput : OrderNoInfo public class DeleteTrackInput : OrderNoInfo { /// - /// 轨迹code + /// 轨迹标识符集合,必填 /// [Required] - public List TrackCodes { get; set; } = new(); + public List TrackIdentifiers { get; set; } = new(); } diff --git a/src/SJZY.Track.Application.Contract/Dtos/ProvideServices/TrackIdentifierDto.cs b/src/SJZY.Track.Application.Contract/Dtos/ProvideServices/TrackIdentifierDto.cs new file mode 100644 index 00000000..993de61c --- /dev/null +++ b/src/SJZY.Track.Application.Contract/Dtos/ProvideServices/TrackIdentifierDto.cs @@ -0,0 +1,21 @@ +using System.ComponentModel.DataAnnotations; + +namespace SJZY.Track.Application.Contract.Dtos.ProvideServices; + +/// +/// 轨迹标识符,用于唯一标识一个轨迹 +/// +public sealed class TrackIdentifierDto +{ + /// + /// 轨迹code + /// + [Required] + public string TrackCode { get; set; } + + /// + /// 轨迹发生时间 + /// + [Required] + public DateTime TrackTime { get; set; } +} diff --git a/src/SJZY.Track.Application.Contract/Events/TrackDeleteEvent.cs b/src/SJZY.Track.Application.Contract/Events/TrackDeleteEvent.cs index e8072e27..0859de6b 100644 --- a/src/SJZY.Track.Application.Contract/Events/TrackDeleteEvent.cs +++ b/src/SJZY.Track.Application.Contract/Events/TrackDeleteEvent.cs @@ -1,3 +1,5 @@ +using SJZY.Track.Application.Contract.Dtos.ProvideServices; + namespace SJZY.Track.Application.Contract.Events; public class TrackDeleteEvent @@ -18,9 +20,9 @@ public class TrackDeleteEvent public int[] OrderIds { get; set; } = null!; /// - /// 轨迹代码 + /// 轨迹标识符 /// - public List TrackCodes { get; set; } = null!; + public List TrackIdentifiers { get; set; } = null!; /// /// 操作人 @@ -40,6 +42,6 @@ public class TrackDeleteEvent public override string ToString() { return $"[TrackDelete by {OperationMan}] SubSystemId: {SubSystemId}, OrderIds: {string.Join(",", - OrderIds)}, TrackCodes: {string.Join(",", TrackCodes)}"; + OrderIds)}, TrackCodes: {string.Join(",", TrackIdentifiers.Select(x=>x.TrackCode))}"; } } diff --git a/src/SJZY.Track.Application/CAP/EventHandlers/TrackDeleteEventHandler.cs b/src/SJZY.Track.Application/CAP/EventHandlers/TrackDeleteEventHandler.cs index 288face2..dd4704ca 100644 --- a/src/SJZY.Track.Application/CAP/EventHandlers/TrackDeleteEventHandler.cs +++ b/src/SJZY.Track.Application/CAP/EventHandlers/TrackDeleteEventHandler.cs @@ -3,6 +3,7 @@ using BSI.Stack.Rabbit; using DotNetCore.CAP; using SJZY.Expand.ABP.Core.Logger; using SJZY.Expand.ABP.Core.PublicMethords; +using SJZY.Track.Application.Contract.Dtos.ProvideServices; using SJZY.Track.Application.Contract.Events; using SJZY.Track.Domain.Aggregates.OrderAggregate; using SJZY.Track.Domain.Aggregates.TrackContentAggregate; @@ -67,22 +68,29 @@ public class TrackDeleteEventHandler : ITransientDependency, ICapSubscribe { var nextEvent = @event.DeepCopy(); nextEvent.Visited.AddRange(@event.OrderIds); - nextEvent.TrackCodes = @event.TrackCodes; + nextEvent.TrackIdentifiers = @event.TrackIdentifiers; nextEvent.SubSystemId = group.Key; // 不同子系统需要做内容映射 if (@event.SubSystemId != nextEvent.SubSystemId) { - var mapCodes = await _provideQueries - .MapTrackCodesAsync(@event.SubSystemId, nextEvent.SubSystemId, @event.TrackCodes.ToArray()); + var codeMaps = await _provideQueries + .GetTrackCodeMapsAsync(@event.SubSystemId, nextEvent.SubSystemId, + @event.TrackIdentifiers.Select(x => x.TrackCode).ToArray()); - if (mapCodes.Count == 0) + if (codeMaps.Count == 0) { LogHelper.Warn($"订单跨子系统,未配置内容映射,请联系管理员:{@event}", true); continue; } - nextEvent.TrackCodes = mapCodes; + //映射轨迹code + foreach (var trackIdentity in nextEvent.TrackIdentifiers) + { + var match = codeMaps.FirstOrDefault(x => x.MapTrackContentCode == trackIdentity.TrackCode); + if (match == null) continue; + trackIdentity.TrackCode = match.TrackContentCode; + } } var identifiers = group.Select(x => x.OrderId).ToList(); @@ -172,7 +180,11 @@ public class TrackDeleteEventHandler : ITransientDependency, ICapSubscribe tracks = await _trackDetailsEsRepository.GetDataByIds(@event.EsIds); orderIds = tracks.Select(m => m.OrderId).Distinct().ToList(); @event.OrderIds = orderIds.ToArray(); - @event.TrackCodes = tracks.Select(x => x.TrackCode).Distinct().ToList(); + @event.TrackIdentifiers = tracks.Select(x => new TrackIdentifierDto + { + TrackCode = x.TrackCode, + TrackTime = x.TrackTime + }).ToList(); // 外部api获取的轨迹不允许删除 if (tracks.Any(m => m.Source == TrackSourceEnum.ExternalServiceProvide.GetHashCode())) @@ -189,11 +201,24 @@ public class TrackDeleteEventHandler : ITransientDependency, ICapSubscribe } else //原有逻辑,根据轨迹code和订单进行删除 { + var trackCodes = @event.TrackIdentifiers.Select(x => x.TrackCode).ToList(); // 删除轨迹(删的是同子系统下的单,所以code是统一的) - tracks = await _trackDetailsEsRepository.GetLatestListAsync(@event.OrderIds, @event.TrackCodes); + tracks = await _trackDetailsEsRepository.GetListAsync(@event.OrderIds, trackCodes,null); - orderIds = await _trackDetailsEsRepository.DeleteTrackAsync(@event.OrderIds, @event.TrackCodes); - if (orderIds.Count == 0) return tracks; + //构建标识符集合 + var ids = @event.TrackIdentifiers.Select(x => $"{x.TrackCode}{x.TrackTime}").ToList(); + //根据标识符选出要删除的轨迹明细 + var deleteTracks = tracks.Where(x => ids.Contains($"{x.TrackCode}{x.TrackTime}")).ToList(); + + if (deleteTracks.Count == 0) return deleteTracks; + + foreach (var track in deleteTracks) + { + await _trackDetailsEsRepository.DeleteTrackByIdAsync(track.Id, track.IndexName); + } + + orderIds = tracks.Select(m => m.OrderId).Distinct().ToList(); + tracks = deleteTracks; } diff --git a/src/SJZY.Track.Application/Services/ProvideServices/TrackService.cs b/src/SJZY.Track.Application/Services/ProvideServices/TrackService.cs index ab931373..8023836a 100644 --- a/src/SJZY.Track.Application/Services/ProvideServices/TrackService.cs +++ b/src/SJZY.Track.Application/Services/ProvideServices/TrackService.cs @@ -163,8 +163,14 @@ public partial class TrackService : ApplicationService, ITrackService //删除轨迹约束,只要其中有一条来源是外部的就立即返回错误 var tracks = await _trackDetailsEsRepository - .GetListAsync(new[] { orderId }, input.TrackCodes, TrackSourceEnum.ExternalServiceProvide); - if (tracks.Count > 0) + .GetListAsync(new[] { orderId }, + input.TrackIdentifiers.Select(x => x.TrackCode).ToList(), + TrackSourceEnum.ExternalServiceProvide); + + //当要删除的轨迹标识出现交叉则不允许删除 + var intersect = tracks.Select(x => $"{x.TrackCode}{x.TrackTime}") + .Intersect(input.TrackIdentifiers.Select(y => $"{y.TrackCode}{y.TrackTime}")).ToList(); + if (intersect.Count > 0) { throw new BusinessException(message: "存在来源于外部服务商的轨迹,不允许删除"); } @@ -173,7 +179,7 @@ public partial class TrackService : ApplicationService, ITrackService var @event = new TrackDeleteEvent { OrderIds = new[] { orderId }, - TrackCodes = input.TrackCodes, + TrackIdentifiers = input.TrackIdentifiers, SubSystemId = input.SubSystemId, OperationMan = name }; @@ -254,8 +260,14 @@ public partial class TrackService : ApplicationService, ITrackService //删除轨迹约束,只要其中有一条来源是外部的就立即返回错误 var tracks = await _trackDetailsEsRepository - .GetListAsync(orderIds.ToArray(), input.TrackCodes, TrackSourceEnum.ExternalServiceProvide); - if (tracks.Count > 0) + .GetListAsync(orderIds.ToArray(), + input.TrackIdentifiers.Select(x => x.TrackCode).ToList(), + TrackSourceEnum.ExternalServiceProvide); + + //当要删除的轨迹标识出现交叉则不允许删除 + var intersect = tracks.Select(x => $"{x.TrackCode}{x.TrackTime}") + .Intersect(input.TrackIdentifiers.Select(y => $"{y.TrackCode}{y.TrackTime}")).ToList(); + if (intersect.Count > 0) { throw new BusinessException(message: "存在来源于外部服务商的轨迹,不允许删除"); } @@ -264,7 +276,7 @@ public partial class TrackService : ApplicationService, ITrackService var @event = new TrackDeleteEvent { OrderIds = orderIds.ToArray(), - TrackCodes = input.TrackCodes, + TrackIdentifiers = input.TrackIdentifiers, SubSystemId = input.SubSystemId, OperationMan = userInfo.Data.UserName, }; diff --git a/src/SJZY.Track.Domain/Aggregates/TrackDetailsAggregate/ITrackDetailsEsRepository.cs b/src/SJZY.Track.Domain/Aggregates/TrackDetailsAggregate/ITrackDetailsEsRepository.cs index 482d7142..c57b797b 100644 --- a/src/SJZY.Track.Domain/Aggregates/TrackDetailsAggregate/ITrackDetailsEsRepository.cs +++ b/src/SJZY.Track.Domain/Aggregates/TrackDetailsAggregate/ITrackDetailsEsRepository.cs @@ -1,4 +1,5 @@ using SJZY.Expand.ElasticSearch.Services; +using SJZY.Track.Domain.Dtos.TrackContents; using SJZY.Track.Domain.Enums; namespace SJZY.Track.Domain.Aggregates.TrackDetailsAggregate; @@ -23,7 +24,7 @@ public interface ITrackDetailsEsRepository : IElasticsearchClientService> GetListAsync(int orderId); - Task> GetListAsync(int[] orderIds, List trackCodes, TrackSourceEnum source); + Task> GetListAsync(int[] orderIds, List trackCodes, TrackSourceEnum? source); Task> DeleteTrackAsync(int[] orderIds, List trackCodes); diff --git a/src/SJZY.Track.Domain/Dtos/TrackContents/TrackCodeMapVO.cs b/src/SJZY.Track.Domain/Dtos/TrackContents/TrackCodeMapVO.cs new file mode 100644 index 00000000..c06fc740 --- /dev/null +++ b/src/SJZY.Track.Domain/Dtos/TrackContents/TrackCodeMapVO.cs @@ -0,0 +1,27 @@ +namespace SJZY.Track.Domain.Dtos.TrackContents; + +/// +/// 轨迹代码映射 +/// +public sealed class TrackCodeMapVO +{ + /// + /// 源子系统id + /// + public int SubSystemId { get; set; } + + /// + /// 源轨迹内容code + /// + public string TrackContentCode { get; set; } = null!; + + /// + /// 映射子系统id + /// + public int MapSubSystemId { get; set; } + + /// + /// 映射轨迹内容code + /// + public string MapTrackContentCode { get; set; } = null!; +} diff --git a/src/SJZY.Track.Domain/Queries/IProvideQueries.cs b/src/SJZY.Track.Domain/Queries/IProvideQueries.cs index 60c0b330..351224c5 100644 --- a/src/SJZY.Track.Domain/Queries/IProvideQueries.cs +++ b/src/SJZY.Track.Domain/Queries/IProvideQueries.cs @@ -18,6 +18,14 @@ public interface IProvideQueries /// Task> MapTrackCodesAsync(int upSubSystemId, int subSystemId, params string[] trackCodes); + /// + /// 获取子系统内容Code映射 + /// + /// + /// + /// + /// + Task> GetTrackCodeMapsAsync(int upSubSystemId, int subSystemId, params string[] trackCodes); /// /// 根据订单模板找对应服务商 /// diff --git a/src/SJZY.Track.Repository/Queries/ProvideQueries.cs b/src/SJZY.Track.Repository/Queries/ProvideQueries.cs index 31855027..8dd6fc96 100644 --- a/src/SJZY.Track.Repository/Queries/ProvideQueries.cs +++ b/src/SJZY.Track.Repository/Queries/ProvideQueries.cs @@ -33,6 +33,22 @@ public class ProvideQueries : ISugarRepository, IProvideQueries, ITransientDepen .ToListAsync(); } + public async Task> GetTrackCodeMapsAsync(int upSubSystemId, int subSystemId, params string[] trackCodes) + { + // 根据上游code得到下游code + return await Context.Queryable() + .Where(x => x.SubSystemId == subSystemId && x.MapSubSystemId == upSubSystemId && + trackCodes.Contains(x.MapTrackContentCode)) + .Select(x => new TrackCodeMapVO() + { + SubSystemId = x.SubSystemId, + TrackContentCode = x.TrackContentCode, + MapSubSystemId = x.MapSubSystemId, + MapTrackContentCode = x.MapTrackContentCode + }) + .ToListAsync(); + } + /// public async Task> FindOrderWithServiceProviderAsync(int subSystemId, List orderNos) @@ -46,7 +62,7 @@ public class ProvideQueries : ISugarRepository, IProvideQueries, ITransientDepen .Select((a, b, c) => new OrderWithServiceProviderVO { //优先使用第三方的订单号,为空时才使用主单号 - OrderNo = b.OrderNo ?? a.OrderNo, + OrderNo = b.OrderNo.IsNullOrWhiteSpace() ? a.OrderNo : b.OrderNo!, OrderType = a.OrderType, SubSystemId = a.SubSystemId, ServiceProviderCode = b.ServiceProviderCode, @@ -67,7 +83,7 @@ public class ProvideQueries : ISugarRepository, IProvideQueries, ITransientDepen .Select((a, b) => new OrderWithServiceProviderVO { //优先使用第三方的订单号,为空时才使用主单号 - OrderNo = b.OrderNo ?? a.OrderNo, + OrderNo = b.OrderNo.IsNullOrWhiteSpace() ? a.OrderNo : b.OrderNo!, OrderType = a.OrderType, SubSystemId = a.SubSystemId, ServiceProviderCode = b.ServiceProviderCode diff --git a/src/SJZY.Track.Repository/Repositories/TrackDetailsEsRepository.cs b/src/SJZY.Track.Repository/Repositories/TrackDetailsEsRepository.cs index cb62b1b1..346d8c57 100644 --- a/src/SJZY.Track.Repository/Repositories/TrackDetailsEsRepository.cs +++ b/src/SJZY.Track.Repository/Repositories/TrackDetailsEsRepository.cs @@ -3,6 +3,7 @@ using SJZY.Expand.ABP.Core.PublicMethords; using SJZY.Expand.ElasticSearch.Services; using SJZY.Track.Domain.Aggregates.TrackDetailsAggregate; using SJZY.Track.Domain.Consts; +using SJZY.Track.Domain.Dtos.TrackContents; using SJZY.Track.Domain.Enums; namespace SJZY.Track.Repository.Repositories; @@ -75,6 +76,8 @@ public class TrackDetailsEsRepository : ElasticSearchContextAbstract f.TrackTimeZone) .Field(f => f.OrderId) .Field(f => f.TrackCode) + .Field(f => f.Id) + .Field(f => f.IndexName) )) .Query(q => q .Bool(b => b @@ -99,6 +102,17 @@ public class TrackDetailsEsRepository : ElasticSearchContextAbstract so .Field(f => f.ZeroTrackTime, SortOrder.Descending) ) + .Source(s2 => s2.Includes(fd2 => fd2 + .Field(f => f.TrackEnContent) + .Field(f => f.TrackContent) + .Field(f => f.TrackPlace) + .Field(f => f.TrackTime) + .Field(f => f.TrackTimeZone) + .Field(f => f.OrderId) + .Field(f => f.TrackCode) + .Field(f => f.Id) + .Field(f => f.IndexName) + )) ) ) ) @@ -343,15 +357,26 @@ public class TrackDetailsEsRepository : ElasticSearchContextAbstract> GetListAsync(int[] orderIds, List trackCodes, TrackSourceEnum source) + public async Task> GetListAsync(int[] orderIds, List trackCodes, TrackSourceEnum? source) { + var query = new QueryContainer(); + + if (orderIds.Length > 0) + { + query &= Query.Terms(t => t.Field(f => f.OrderId).Terms(orderIds)); + } + if (trackCodes.Count > 0) + { + query &= Query.Terms(t => t.Field(f => f.TrackCode.Suffix("keyword")).Terms(trackCodes)); + } + if (source.HasValue) + { + query &= Query.Term(t => t.Field(f => f.Source).Value(source.Value)); + } + var r = await Context.SearchAsync(x => x .Index(GlobalConst.TrackDetailsIndex) - .Query(q => - q.Terms(t => t.Field(f => f.OrderId).Terms(orderIds)) - && q.Terms(t => t.Field(f => f.TrackCode.Suffix("keyword")).Terms(trackCodes)) - && q.Term(t => t.Source, (int) source) - ) + .Query(q => query) .Size(SafelyLimit) .Sort(s => s.Field(f => f.ZeroTrackTime, SortOrder.Descending))); @@ -474,5 +499,4 @@ public class TrackDetailsEsRepository : ElasticSearchContextAbstract