From 581de918bcba1b3ce640fe0f32897c830812799d Mon Sep 17 00:00:00 2001 From: hardstylewyl <827778732@qq.com> Date: Fri, 11 Apr 2025 17:19:37 +0800 Subject: [PATCH] =?UTF-8?q?add-params:=E5=A2=9E=E5=8A=A0=E6=96=B0=E5=A2=9E?= =?UTF-8?q?=E4=BF=AE=E6=94=B9=E8=BD=A8=E8=BF=B9=E6=96=B0=E6=89=A9=E5=B1=95?= =?UTF-8?q?=E4=BF=A1=E6=81=AF=E5=8F=82=E6=95=B0,=E7=9B=AE=E7=9A=84?= =?UTF-8?q?=E6=98=AF=E4=B8=BA=E4=BA=86=E4=BF=AE=E6=94=B9=E6=89=A9=E5=B1=95?= =?UTF-8?q?=E4=BF=A1=E6=81=AF=20fix:=E5=AE=8C=E5=96=84=E8=BD=A8=E8=BF=B9?= =?UTF-8?q?=E6=96=B0=E5=A2=9E/=E4=BF=AE=E6=94=B9=E9=AA=8C=E8=AF=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ProvideServices/BatchUpsertTrackInput.cs | 13 ++- .../Dtos/ProvideServices/UpsertTrackInput.cs | 11 ++- .../Events/TrackUpsertEvent.cs | 11 ++- .../EventHandlers/TrackUpsertEventHandler.cs | 91 +++++++++---------- .../Services/ProvideServices/TrackService.cs | 78 ++++++++++------ 5 files changed, 124 insertions(+), 80 deletions(-) diff --git a/src/SJZY.Track.Application.Contract/Dtos/ProvideServices/BatchUpsertTrackInput.cs b/src/SJZY.Track.Application.Contract/Dtos/ProvideServices/BatchUpsertTrackInput.cs index bd7a5c2f..e0e1e796 100644 --- a/src/SJZY.Track.Application.Contract/Dtos/ProvideServices/BatchUpsertTrackInput.cs +++ b/src/SJZY.Track.Application.Contract/Dtos/ProvideServices/BatchUpsertTrackInput.cs @@ -30,7 +30,9 @@ public class BatchUpsertTrackInput : OrderNosInfo public DateTime TrackTime { get; set; } /// - /// 更改后的轨迹发生时间,无需更改保持为空 + /// 新的轨迹发生时间 + /// 如果是新增,那么优先级高于TrackTime + /// 如果要修改TrackTime,请同时传递TrackTime(旧的用于匹配),和NewTrackTime /// public DateTime? NewTrackTime { get; set; } @@ -39,7 +41,7 @@ public class BatchUpsertTrackInput : OrderNosInfo /// // [Required] // [Range(-12, 12)] - public float TrackTimeZone { get; set; } + public float? TrackTimeZone { get; set; } /// /// 客户是否可见 @@ -136,6 +138,13 @@ public class BatchUpsertTrackInput : OrderNosInfo /// public string? Extra { get; set; } + /// + /// 新的扩展信息, + /// 如果是新增,那么优先级高于Extra + /// 如果要修改Extra,请同时传递Extra(用于匹配旧的)和NewExtra + /// + public string? NewExtra { get; set; } + /// /// 是否强制推送 /// diff --git a/src/SJZY.Track.Application.Contract/Dtos/ProvideServices/UpsertTrackInput.cs b/src/SJZY.Track.Application.Contract/Dtos/ProvideServices/UpsertTrackInput.cs index 961841a6..f8fb030b 100644 --- a/src/SJZY.Track.Application.Contract/Dtos/ProvideServices/UpsertTrackInput.cs +++ b/src/SJZY.Track.Application.Contract/Dtos/ProvideServices/UpsertTrackInput.cs @@ -35,7 +35,9 @@ public class UpsertTrackInput : OrderNoInfo public DateTime TrackTime { get; set; } /// - /// 更改后的轨迹发生时间,无需更改保持为空 + /// 新的轨迹发生时间 + /// 如果是新增,那么优先级高于TrackTime + /// 如果要修改TrackTime,请同时传递TrackTime(旧的用于匹配),和NewTrackTime /// public DateTime? NewTrackTime { get; set; } @@ -145,6 +147,13 @@ public class UpsertTrackInput : OrderNoInfo /// public string? Extra { get; set; } + /// + /// 新的扩展信息, + /// 如果是新增,那么优先级高于Extra + /// 如果要修改Extra,请同时传递Extra(用于匹配旧的)和NewExtra + /// + public string? NewExtra { get; set; } + /// /// 是否强制推送 /// diff --git a/src/SJZY.Track.Application.Contract/Events/TrackUpsertEvent.cs b/src/SJZY.Track.Application.Contract/Events/TrackUpsertEvent.cs index 182672cb..d6df40bb 100644 --- a/src/SJZY.Track.Application.Contract/Events/TrackUpsertEvent.cs +++ b/src/SJZY.Track.Application.Contract/Events/TrackUpsertEvent.cs @@ -55,7 +55,9 @@ public class TrackUpsertEvent public DateTime TrackTime { get; set; } /// - /// 更改后的轨迹发生时间,无需更改保持为空 + /// 新的轨迹发生时间 + /// 如果是新增,那么优先级高于TrackTime + /// 如果要修改TrackTime,请同时传递TrackTime(旧的用于匹配),和NewTrackTime /// public DateTime? NewTrackTime { get; set; } @@ -162,6 +164,13 @@ public class TrackUpsertEvent /// public string? Extra { get; set; } + /// + /// 新的扩展信息, + /// 如果是新增,那么优先级高于Extra + /// 如果要修改Extra,请同时传递Extra(用于匹配旧的)和NewExtra + /// + public string? NewExtra { get; set; } + /// /// 是否强制推送 /// diff --git a/src/SJZY.Track.Application/CAP/EventHandlers/TrackUpsertEventHandler.cs b/src/SJZY.Track.Application/CAP/EventHandlers/TrackUpsertEventHandler.cs index c5465d51..030eb361 100644 --- a/src/SJZY.Track.Application/CAP/EventHandlers/TrackUpsertEventHandler.cs +++ b/src/SJZY.Track.Application/CAP/EventHandlers/TrackUpsertEventHandler.cs @@ -289,55 +289,26 @@ public class TrackUpsertEventHandler : ITransientDependency, ICapSubscribe var existTracks = tracks.Where(x => x.OrderId == order.OrderId).ToList(); - if (@event.CompareFields.IsNullOrEmpty()) + // tips:如果没传时区则使用+8兜底进行过滤 + var timezone = Math.Abs(@event.TrackTimeZone - GlobalConst.NoneTrackTimeZone) < 0.01f ? 8.0f : @event.TrackTimeZone; + + // 根据时间过滤 + existTracks = @event.IsAdd + ? existTracks.Where(x => x.GetUtc0TrackTime() == (@event.NewTrackTime ?? @event.TrackTime).Subtract(TimeSpan.FromHours(timezone))).ToList() + : existTracks.Where(x => + x.GetUtc0TrackTime() == @event.TrackTime.Subtract(TimeSpan.FromHours(timezone)) + // 修改了并且修改了时间 + || (@event.NewTrackTime != null && x.GetUtc0TrackTime() == @event.NewTrackTime.Value.Subtract(TimeSpan.FromHours(timezone))) + ).ToList(); + + // 根据扩展信息过滤 + existTracks = @event.IsAdd + ? existTracks.Where(x => x.Extra == (@event.NewExtra ?? @event.Extra)).ToList() + : existTracks.Where(x => x.Extra == @event.Extra || x.Extra == @event.NewExtra).ToList(); + + if (@event.IsAdd) { - existTracks = existTracks.Where(x => x.TrackTime == @event.TrackTime).ToList(); - } - else - { - Debug.Assert(@event.CompareFields != null, "@event.CompareFields != null"); - var extraDict = TextJsonHelper.DeserializeToDictionary(@event.Extra); - if (extraDict == null || !extraDict.TryGetValue(@event.CompareFields, out var compareValue)) - { - throw new BusinessException(message: $"请检查拓展字段,为什么找不到比较字段:{@event.CompareFields}"); - } - - existTracks = existTracks.Where(x => - { - var oldExtraDict = TextJsonHelper.DeserializeToDictionary(x.Extra); - // tips:注意兼容性,历史轨迹的字段可能为空 - if (oldExtraDict == null || !oldExtraDict.TryGetValue(@event.CompareFields, out var oldValue)) - { - return false; - } - - return TextJsonHelper.EqJsonElement(oldValue, compareValue); - }).ToList(); - } - - var track = existTracks.FirstOrDefault(); - - if (!@event.IsAdd) - { - if (existTracks.Count > 1) - { - _logger.LogInformation("订单存在多条轨迹不允许修改:{@event}", @event); - continue; - } - - if (track == null) - { - _logger.LogInformation("订单不存在轨迹不允许修改:{@event}", @event); - continue; // 不存在不让改 - } - - updateTracks.Add(BuiltUpdateTrack(@event, track, order, trackContent)); - operationRecords.Add(BuildOrderOperationRecord(@event, track, order)); - } - else - { - // 不允许重复轨迹,跳过 - if (!trackContent.IsRepeatable && existTracks.Count > 0) + if (existTracks.Count > 0) { _logger.LogInformation("订单已经存在不允许重复的轨迹,不允许重复添加:{@event}", @event); continue; @@ -345,6 +316,26 @@ public class TrackUpsertEventHandler : ITransientDependency, ICapSubscribe insertTracks.Add(BuiltNewTrack(@event, order, trackContent)); } + else + { + // 不存在不让改 + if (existTracks.Count == 0) + { + _logger.LogInformation("订单不存在轨迹,不允许修改:{@event}", @event); + continue; + } + + if (existTracks.Count > 1) + { + _logger.LogInformation("订单存在多条轨迹不允许修改:{@event}", @event); + continue; + } + + var track = existTracks.First(); + updateTracks.Add(BuiltUpdateTrack(@event, track, order, trackContent)); + operationRecords.Add(BuildOrderOperationRecord(@event, track, order)); + } + canNextOrderIds.Add(order.OrderId); } @@ -406,7 +397,7 @@ public class TrackUpsertEventHandler : ITransientDependency, ICapSubscribe track.TrackPlacePostcode = @event.TrackPlacePostcode ?? GlobalConst.EmptyString; track.DestinationTimeZone = @event.DestinationTimeZone; track.EstimatedDeliveryDate = @event.EstimatedDeliveryDate; - track.Extra = @event.Extra; + track.Extra = @event.NewExtra ?? @event.Extra; return track; } @@ -456,7 +447,7 @@ public class TrackUpsertEventHandler : ITransientDependency, ICapSubscribe TrackPlacePostcode = @event.TrackPlacePostcode ?? GlobalConst.EmptyString, DestinationTimeZone = @event.DestinationTimeZone, EstimatedDeliveryDate = @event.EstimatedDeliveryDate, - Extra = @event.Extra + Extra = @event.NewExtra ?? @event.Extra, }; track.ZeroTrackTime = Math.Abs(track.TrackTimeZone - GlobalConst.NoneTrackTimeZone) < 1 diff --git a/src/SJZY.Track.Application/Services/ProvideServices/TrackService.cs b/src/SJZY.Track.Application/Services/ProvideServices/TrackService.cs index f74c501e..d0f5a4aa 100644 --- a/src/SJZY.Track.Application/Services/ProvideServices/TrackService.cs +++ b/src/SJZY.Track.Application/Services/ProvideServices/TrackService.cs @@ -3,6 +3,7 @@ using Microsoft.AspNetCore.Http; using SJZY.Track.Application.Contract.Dtos.ProvideServices; using SJZY.Track.Application.Contract.Events; using SJZY.Track.Application.Contract.Services.ProvideServices; +using SJZY.Track.Application.Helpers; using SJZY.Track.Domain.Aggregates.OrderAggregate; using SJZY.Track.Domain.Aggregates.TrackContentAggregate; using SJZY.Track.Domain.Aggregates.TrackDetailsAggregate; @@ -289,10 +290,12 @@ public partial class TrackService : ApplicationService, ITrackService input.TrackCode, input.Source, input.TrackTime, + input.TrackTimeZone ?? 8.0f, //没传时区默认使用+8参与过滤 input.NewTrackTime, input.EstimatedDeliveryDate, input.DestinationTimeZone, input.Extra, + input.NewExtra, input.CompareFields); var userInfo = await _requestCurrentUserService.Service.GetCurrentUserBasicInfoAsync(); @@ -308,6 +311,7 @@ public partial class TrackService : ApplicationService, ITrackService var name = userInfo.Data.UserName; // 新增/更新轨迹 + input.TrackTimeZone ??= GlobalConst.NoneTrackTimeZone; //时区为空使用一个特殊值填充 var @event = ObjectMapper.Map(input); @event.SubSystemId = input.SubSystemId; @event.CustomId = order.CustomId; @@ -366,10 +370,12 @@ public partial class TrackService : ApplicationService, ITrackService input.TrackCode, input.Source, input.TrackTime, + input.TrackTimeZone ?? 8.0f, //没传时区默认使用+8参与过滤 input.NewTrackTime, input.EstimatedDeliveryDate, input.DestinationTimeZone, input.Extra, + input.NewExtra, input.CompareFields); // 获取用户name @@ -397,7 +403,7 @@ public partial class TrackService : ApplicationService, ITrackService TrackPlace = input.TrackPlace, TrackTime = input.TrackTime, NewTrackTime = input.NewTrackTime, - TrackTimeZone = input.TrackTimeZone, + TrackTimeZone = input.TrackTimeZone ?? GlobalConst.NoneTrackTimeZone, //时区为空使用一个特殊值填充 OperationMan = userInfo.Data.UserName, OperationManId = userInfo.Data.UserId, IsVisibility = input.IsVisibility, @@ -418,6 +424,7 @@ public partial class TrackService : ApplicationService, ITrackService DestinationTimeZone = input.DestinationTimeZone, CompareFields = input.CompareFields, Extra = input.Extra, + NewExtra = input.NewExtra, ForcedPush = input.ForcedPush, IsToMq = input.IsToMq, }; @@ -436,10 +443,12 @@ public partial class TrackService : ApplicationService, ITrackService string trackCode, int source, DateTime trackTime, + float trackTimezone, DateTime? newTrackTime, DateTime? estimatedDeliveryDate, float? destinationTimeZone, string? extra, + string? newExtra, string? compareFields ) { @@ -505,10 +514,8 @@ public partial class TrackService : ApplicationService, ITrackService //轨迹新增,不允许重复的轨迹提前拦截 if (isAdd) { - //允许重复,跳过检查 - if (trackContent.IsRepeatable) return; //找到这个订单的这个轨迹code的所有轨迹 - var tracks = await RetryQueryTrackAsync(orderId, trackCode, trackTime, extra, compareFields, trackContent.IsRepeatable); + var tracks = await RetryQueryTrackAsync(isAdd, orderId, trackCode, trackTime, trackTimezone, newTrackTime, extra, newExtra, compareFields, trackContent.IsRepeatable); if (tracks.Count > 0) throw new BusinessException(message: $"订单:[{orderNo}],轨迹代码:{trackCode}不允许重复创建轨迹"); } @@ -516,21 +523,45 @@ public partial class TrackService : ApplicationService, ITrackService else { //找到这个订单的这个轨迹code的所有轨迹, - var tracks = await RetryQueryTrackAsync(orderId, trackCode, trackTime, extra, compareFields, trackContent.IsRepeatable); - //不存在需要更新的轨迹 + var tracks = await RetryQueryTrackAsync(isAdd, orderId, trackCode, trackTime, trackTimezone, newTrackTime, extra, newExtra, compareFields, trackContent.IsRepeatable); + + // 不存在需要更新的轨迹 if (tracks.Count == 0) throw new BusinessException(message: $"订单:[{orderNo}],轨迹代码:[{trackCode}]没有要更新的记录"); - //更新轨迹,同一时间存在多条轨迹记录,理由:不清晰到底要修改哪一条或是全部修改 + // 更新轨迹,同一时间存在多条轨迹记录,理由:不清晰到底要修改哪一条或是全部修改 if (tracks.Count > 1) + { + if (newTrackTime.HasValue && tracks.Any(track => DateTimeHelper.ConvertUtc0Compare(track.TrackTime, track.TrackTimeZone, newTrackTime.Value, trackTimezone) == 0)) + { + throw new BusinessException(message: $"订单:[{orderNo}],轨迹代码:[{trackCode}]和现存轨迹时间重复,不允许修改,请检查轨迹NewTrackTime"); + } + + if (!string.IsNullOrWhiteSpace(extra) && tracks.Any(track => string.Equals(track.Extra, newExtra))) + { + throw new BusinessException(message: $"订单:[{orderNo}],轨迹代码:[{trackCode}]和现存轨迹Extra重复,不允许修改,请检查轨迹NewExtra"); + } + throw new BusinessException(message: $"订单:{orderNo},轨迹代码:[{trackCode}]存在多条记录,不允许修改"); + } + + var track = tracks.First(); + if (DateTimeHelper.ConvertUtc0Compare(track.TrackTime, track.TrackTimeZone, trackTime, trackTimezone) != 0) + { + throw new BusinessException(message: $"订单:[{orderNo}],轨迹代码:[{trackCode}]找不到要更新的记录,不允许修改,请检查轨迹TrackTime"); + } + + if (!string.Equals(track.Extra, extra)) + { + throw new BusinessException(message: $"订单:[{orderNo}],轨迹代码:[{trackCode}]找不到要更新的记录,不允许修改,请检查轨迹Extra"); + } } } // 重试查询轨迹,直到存在符合要求的轨迹,或者超过最大重试次数 - private async Task> RetryQueryTrackAsync(int orderId, string trackCode, DateTime trackTime, string? extra, string? compareFields, bool isRepeatable) + private async Task> RetryQueryTrackAsync(bool isAdd, int orderId, string trackCode, DateTime trackTime, float trackTimezone, DateTime? newTrackTime, string? extra, string? newExtra, string? compareFields, bool isRepeatable) { - var tracks = await QueryAndFilterAsync(orderId, trackCode, trackTime, extra, compareFields, isRepeatable); + var tracks = await QueryAndFilterAsync(isAdd, orderId, trackCode, trackTime, trackTimezone, newTrackTime, extra, newExtra, compareFields, isRepeatable); if (tracks.Count > 0) return tracks; @@ -540,7 +571,7 @@ public partial class TrackService : ApplicationService, ITrackService { try { - tracks = await QueryAndFilterAsync(orderId, trackCode, trackTime, extra, compareFields, isRepeatable); + tracks = await QueryAndFilterAsync(isAdd, orderId, trackCode, trackTime, trackTimezone, newTrackTime, extra, newExtra, compareFields, isRepeatable); if (tracks.Count > 0) return tracks; //指数退避等待 @@ -559,28 +590,23 @@ public partial class TrackService : ApplicationService, ITrackService //查询并按比较字段过滤轨迹,当比较字段为空时则使用轨迹发生时间过滤 //tips:后续进行投影缩参优化 - private async Task> QueryAndFilterAsync(int orderId, string trackCode, DateTime trackTime, string? extra, string? compareFields, bool isRepeatable) + private async Task> QueryAndFilterAsync(bool isAdd, int orderId, string trackCode, DateTime trackTime, float trackTimezone, DateTime? newTrackTime, string? extra, string? newExtra, string? compareFields, bool isRepeatable) { var tracks = await _trackDetailsEsRepository.GetListAsync(new[] { orderId }, trackCode, true); // 如果不允许重复,则直接返回 if (!isRepeatable) return tracks; - //无比较字段时使用轨迹时间参与过滤(兼容老版本) - if (string.IsNullOrWhiteSpace(compareFields)) - { - return tracks.Where(x => x.TrackTime == trackTime).ToList(); - } + tracks = isAdd + ? tracks.Where(x => x.GetUtc0TrackTime() == (newTrackTime ?? trackTime).Subtract(TimeSpan.FromHours(trackTimezone))).ToList() + : tracks.Where(x => + x.GetUtc0TrackTime() == trackTime.Subtract(TimeSpan.FromHours(trackTimezone)) + // 修改了并且修改了时间 + || (newTrackTime != null && x.GetUtc0TrackTime() == newTrackTime.Value.Subtract(TimeSpan.FromHours(trackTimezone))) + ).ToList(); - return tracks.Where(x => - { - if (string.IsNullOrWhiteSpace(x.Extra)) - throw new BusinessException(message: "轨迹extra为空无法使用比较字段比较,请检查轨迹"); - var extraJsonElement = TextJsonHelper.DeserializeToJsonElement(x.Extra); - var inputExtraJsonElement = TextJsonHelper.DeserializeToJsonElement(extra); - - return TextJsonHelper.EqByJsonElementField(extraJsonElement, inputExtraJsonElement, compareFields); - }) - .ToList(); + return isAdd + ? tracks.Where(x => x.Extra == (newExtra ?? extra)).ToList() + : tracks.Where(x => x.Extra == extra || x.Extra == newExtra).ToList(); } }