diff --git a/src/SJZY.Track.Application.Contract/Dtos/TrackPush/TrackPushContentConfigDto.cs b/src/SJZY.Track.Application.Contract/Dtos/TrackPush/TrackPushContentConfigDto.cs index 7c1c1568..d67b7454 100644 --- a/src/SJZY.Track.Application.Contract/Dtos/TrackPush/TrackPushContentConfigDto.cs +++ b/src/SJZY.Track.Application.Contract/Dtos/TrackPush/TrackPushContentConfigDto.cs @@ -42,6 +42,11 @@ public class TrackPushContentConfigDto /// public string TrackCode { get; set; } = null!; + /// + /// 推送顺序 + /// + public int Sort { get; set; } + /// /// 可交换顺序的轨迹code /// diff --git a/src/SJZY.Track.Application/CAP/EventHandlers/TrackPushEventHandler.cs b/src/SJZY.Track.Application/CAP/EventHandlers/TrackPushEventHandler.cs index cd792aa6..110f5c73 100644 --- a/src/SJZY.Track.Application/CAP/EventHandlers/TrackPushEventHandler.cs +++ b/src/SJZY.Track.Application/CAP/EventHandlers/TrackPushEventHandler.cs @@ -31,6 +31,7 @@ public class TrackPushEventHandler : ITransientDependency, ICapSubscribe private readonly IBroadcastingService _broadcastingService; private List _orders = null!; private List _pushConfigs = null!; + private Dictionary> _orderTypeSortedConfigsDict = null!; //订单类型,根据sort从小到大排序后的配置字典 public TrackPushEventHandler(IHttpClientProxy httpClientProxy, IOrderRepository orderRepository, @@ -61,6 +62,11 @@ public class TrackPushEventHandler : ITransientDependency, ICapSubscribe } _pushConfigs = pushConfigs; + _orderTypeSortedConfigsDict = pushConfigs + .GroupBy(x => x.OrderType) + .ToDictionary(x => x.Key, + y => y.OrderBy(item => item.Sort).ToList() + ); var orders = await _orderRepository.GetListAsync(x => @event.OrderIds.Contains(x.Id), @@ -142,33 +148,43 @@ public class TrackPushEventHandler : ITransientDependency, ICapSubscribe private async Task BuiltManualPushItemsAsync(TrackPushEvent @event, List items) { - // tips: 手工强制推送直接使用配置 - var config = _pushConfigs.FirstOrDefault(x => x.TrackCode == @event.TrackCode); foreach (var order in _orders) { - if (config is { IsAllPush: true }) + // tips:不同订单类型可能会有不同的顺序 + if (!_orderTypeSortedConfigsDict.TryGetValue(order.OrderType, out var sortedConfigs)) { - // 非强制推送需要 推断 本次推送 是否可行 - if (!@event.ForcedPush) - { - config = GetValidPushConfigAsync(_pushConfigs, order.LatestPushTrackCode, @event); - } + TrackPushFailedPublicTopic($"子系统id:[{@event.SubSystemId}],客户id:[{@event.CustomId}],没有订单类型[{order.OrderType}]的推送映射配置", @event, order); + continue; + } + + // tips: 手工/强制推送直接使用配置 + var config = sortedConfigs.FirstOrDefault(x => x.TrackCode == @event.TrackCode); + + if (config == null) + { + TrackPushFailedPublicTopic($"针对于订单类型[{order.OrderType}]没有找到轨迹代码[{@event.TrackCode}]对应的配置", @event, order); + continue; + } + + // 非强制推送需要 推断 本次推送 是否可行 + if (config.IsAllPush && !@event.ForcedPush) + { + config = GetValidPushConfigAsync(sortedConfigs, order.LatestPushTrackCode, @event); } if (config == null) { - TrackPushFailedPublicTopic("推送顺序异常,找不到有效推送配置", @event, order); + TrackPushFailedPublicTopic($"推送顺序有误,针对于订单类型[{order.OrderType}],轨迹代码[{@event.TrackCode}]", @event, order); return; } - - //配置的类型如何和订单类型不一致则不允许推送 - if (config.OrderType != order.OrderType) - { - TrackPushFailedPublicTopic($"订单类型{order.OrderType}和配置中的订单类型[{config.OrderType}]不一致,不能推送", @event, - order); - continue; - } + // //配置的类型如何和订单类型不一致则不允许推送 + // if (config.OrderType != order.OrderType) + // { + // TrackPushFailedPublicTopic($"订单类型{order.OrderType}和配置中的订单类型[{config.OrderType}]不一致,不能推送", @event, + // order); + // continue; + // } var log = new TrackPushRecordIndex { @@ -194,12 +210,21 @@ public class TrackPushEventHandler : ITransientDependency, ICapSubscribe private async Task BuiltSystemPushItemsAsync(TrackPushEvent @event, List items) { - var config = _pushConfigs.FirstOrDefault(x => x.TrackCode == @event.TrackCode); foreach (var order in _orders) { + // tips:不同订单类型可能会有不同的顺序 + if (!_orderTypeSortedConfigsDict.TryGetValue(order.OrderType, out var sortedConfigs)) + { + TrackPushFailedPublicTopic($"子系统id:[{@event.SubSystemId}],客户id:[{@event.CustomId}],没有订单类型[{order.OrderType}]的推送映射配置", @event, order); + continue; + } + + // tips: 手工/强制推送直接使用配置 + var config = sortedConfigs.FirstOrDefault(x => x.TrackCode == @event.TrackCode); if (config == null) { - TrackPushFailedPublicTopic($"没有在推送映射配置中找到关于轨迹代码[{@event.TrackCode}]的配置", @event, order); + TrackPushFailedPublicTopic($"子系统id:[{@event.SubSystemId}],客户id:[{@event.CustomId}],没有订单类型[{order.OrderType}]的推送映射配置," + + $"没有在推送映射配置中找到关于轨迹代码[{@event.TrackCode}]的配置", @event, order); return; } @@ -214,7 +239,7 @@ public class TrackPushEventHandler : ITransientDependency, ICapSubscribe // 如果当前推送code与订单上的最后的code不一致,则考虑推送映射顺序 if (!string.Equals(order.LatestPushTrackCode, @event.TrackCode)) { - config = GetValidPushConfigAsync(_pushConfigs, order.LatestPushTrackCode, @event); + config = GetValidPushConfigAsync(sortedConfigs, order.LatestPushTrackCode, @event); if (config == null) { TrackPushFailedPublicTopic("推送顺序异常,找不到有效推送配置", @event, order); @@ -229,13 +254,13 @@ public class TrackPushEventHandler : ITransientDependency, ICapSubscribe continue; } - // 配置的类型如何和订单类型不一致则不允许推送 - if (config.OrderType != order.OrderType) - { - TrackPushFailedPublicTopic($"订单类型{order.OrderType}和配置中的订单类型[{config.OrderType}]不一致,不能推送", @event, - order); - continue; - } + // // 配置的类型如何和订单类型不一致则不允许推送 + // if (config.OrderType != order.OrderType) + // { + // TrackPushFailedPublicTopic($"订单类型{order.OrderType}和配置中的订单类型[{config.OrderType}]不一致,不能推送", @event, + // order); + // continue; + // } var log = new TrackPushRecordIndex { @@ -267,14 +292,29 @@ public class TrackPushEventHandler : ITransientDependency, ICapSubscribe var items = new List(); foreach (var order in _orders) { - //配置的类型如何和订单类型不一致则不允许推送 - if (config.OrderType != order.OrderType) + // tips:不同订单类型可能会有不同的顺序 + if (!_orderTypeSortedConfigsDict.TryGetValue(order.OrderType, out var sortedConfigs)) { - TrackPushFailedPublicTopic($"订单类型{order.OrderType}和配置中的订单类型[{config.OrderType}]不一致,不能推送", @event, - order); + TrackPushFailedPublicTopic($"子系统id:[{@event.SubSystemId}],客户id:[{@event.CustomId}],没有订单类型[{order.OrderType}]的推送映射配置", @event, order); continue; } + // tips:更新轨迹要求只能更新已经推过的历史轨迹 + config = sortedConfigs.FirstOrDefault(x => x.TrackCode == @event.TrackCode); + if (config == null) + { + TrackPushFailedPublicTopic($"针对于订单类型[{order.OrderType}]没有找到轨迹代码[{@event.TrackCode}]对应的配置", @event, order); + continue; + } + + // //配置的类型如何和订单类型不一致则不允许推送 + // if (config.OrderType != order.OrderType) + // { + // TrackPushFailedPublicTopic($"订单类型{order.OrderType}和配置中的订单类型[{config.OrderType}]不一致,不能推送", @event, + // order); + // continue; + // } + var log = new TrackPushRecordIndex { OptionType = @event.OptionType.ToString(), @@ -353,7 +393,7 @@ public class TrackPushEventHandler : ITransientDependency, ICapSubscribe var body = new TrackPushInput { - OrderNo = log.OrderNo, + OrderNo = log.OrderNo }; var cur = new Dictionary { @@ -372,7 +412,7 @@ public class TrackPushEventHandler : ITransientDependency, ICapSubscribe if (config.IsAllPush) { var history = await _trackPushRecordEsRepository.GetLatestTrackPushRecordAsync(log.OrderId, true); - if (history != default) + if (history != null) { body = TextJsonHelper.Deserialize(history.PushContent); @@ -382,13 +422,18 @@ public class TrackPushEventHandler : ITransientDependency, ICapSubscribe var trackIdentifies = tracks.Select(x => { //寻找映射配置(转换后的code) - var code = _pushConfigs.First(y => y.TrackCode == x.TrackCode).TrackContentCodeValue; + var matchConfig = _orderTypeSortedConfigsDict.TryGetValue(x.OrderType, out var sortedConfigs) + ? sortedConfigs.FirstOrDefault(y => y.TrackCode == x.TrackCode) + : null; + if (matchConfig == null) return null; + var code = matchConfig.TrackContentCodeValue; var timeStr = DateTimeFormat(x.TrackTime, config.TrackTimeZone ?? log.TrackTimeZone, config); return string.IsNullOrWhiteSpace(compareFields) ? $"{code}{timeStr}" : $"{code}{TextJsonHelper.ExtractValue(x.Extra, compareFields)}"; - } - ).ToImmutableHashSet(); + }) + .Where(x => x != null) + .ToImmutableHashSet(); //在历史中选取在订单当前轨迹明细中的记录 body!.Data = body.Data.Where(x => { @@ -431,7 +476,7 @@ public class TrackPushEventHandler : ITransientDependency, ICapSubscribe } } - // 添加当前要推送的轨迹 + // 添加当前要推送的轨迹,到末尾 body.Data.Add(cur); } } @@ -457,7 +502,7 @@ public class TrackPushEventHandler : ITransientDependency, ICapSubscribe return cache[idx]; } - if (idx + 1 >= cache.Count) return default; // 推完了 + if (idx + 1 >= cache.Count) return null; // 推完了 // find next var matched = cache[idx + 1].TrackCode == trackCode @@ -466,7 +511,7 @@ public class TrackPushEventHandler : ITransientDependency, ICapSubscribe : cache.FirstOrDefault(x => x.TrackCode == cache[idx + 1].SwapTrackCode); //没推完,可能不符合推送顺序 - return matched != null && matched.TrackCode == trackCode ? matched : default; + return matched != null && matched.TrackCode == trackCode ? matched : null; } /// @@ -494,17 +539,18 @@ public class TrackPushEventHandler : ITransientDependency, ICapSubscribe { _broadcastingService.TrackPushFailedPubilcTopic(new TrackPushRecordDto { + SubSystemCode = @event.SubSystemCode, + IsManualPush = @event.OperationMan != null, + PushTime = DateTime.Now, //还没请求接口通 RequestId = null, - IsSuccess = false, Message = failedMessage, OperationMan = @event.OperationMan, - PushTime = DateTime.Now, OptionType = @event.OptionType.ToString(), - IsManualPush = @event.OperationMan != null, + OrderNo = order.OrderNo, + IsSuccess = false, //还没到构建推送内容那一步就被拦截 PushContent = string.Empty, - OrderNo = order.OrderNo, TrackStatus = @event.SystemPushInfo.TrackStatus, TrackContent = @event.SystemPushInfo.TrackStatus, TrackTimeZone = @event.SystemPushInfo.TrackTimeZone, @@ -526,15 +572,16 @@ public class TrackPushEventHandler : ITransientDependency, ICapSubscribe { _broadcastingService.TrackPushFailedPubilcTopic(new TrackPushRecordDto { - RequestId = requestId, - IsSuccess = false, - Message = failedMessage, - OperationMan = @event.OperationMan, - PushTime = DateTime.Now, - OptionType = @event.OptionType.ToString(), + SubSystemCode = @event.SubSystemCode, IsManualPush = @event.OperationMan != null, - PushContent = TextJsonHelper.Serialize(pushInput), + PushTime = DateTime.Now, + OperationMan = @event.OperationMan, OrderNo = pushInput.OrderNo, + RequestId = requestId, + Message = failedMessage, + OptionType = @event.OptionType.ToString(), + IsSuccess = false, + PushContent = TextJsonHelper.Serialize(pushInput), TrackStatus = @event.SystemPushInfo.TrackStatus, TrackContent = @event.SystemPushInfo.TrackStatus, TrackTimeZone = @event.SystemPushInfo.TrackTimeZone, diff --git a/src/SJZY.Track.Application/Services/TrackPush/TrackPushCacheService.cs b/src/SJZY.Track.Application/Services/TrackPush/TrackPushCacheService.cs index 5b64b496..83c393ed 100644 --- a/src/SJZY.Track.Application/Services/TrackPush/TrackPushCacheService.cs +++ b/src/SJZY.Track.Application/Services/TrackPush/TrackPushCacheService.cs @@ -85,6 +85,7 @@ public class TrackPushCacheService : ITrackPushCacheService, ITransientDependenc ServiceProviderCode = item.ServiceProviderCode, OrderType = item.OrderType, TrackCode = item.TrackCode, + Sort = item.Sort, SwapTrackCode = item.SwapTrackCode, TrackStatusValue = item.TrackStatusValue, TrackContentCodeValue = item.TrackContentCodeValue, diff --git a/src/SJZY.Track.Application/Services/TrackPush/TrackPushService.cs b/src/SJZY.Track.Application/Services/TrackPush/TrackPushService.cs index 66e95cf2..1c535b13 100644 --- a/src/SJZY.Track.Application/Services/TrackPush/TrackPushService.cs +++ b/src/SJZY.Track.Application/Services/TrackPush/TrackPushService.cs @@ -159,7 +159,8 @@ public class TrackPushService : ApplicationService, ISingletonDependency if (input.Options != OptionTypeNoNull.删除) { Expression> isContentAnyExp = x => - x.TrackPushConfigId == input.TrackPushConfigId; + x.TrackPushConfigId == input.TrackPushConfigId + && x.OrderNoType == input.OrderNoType; if (input.Options == OptionTypeNoNull.修改) isContentAnyExp = isContentAnyExp.And(x => x.Id != input.Id); if (await _trackPushConfigRepository.IsContentAnyAsync(isContentAnyExp.And(x => @@ -191,8 +192,10 @@ public class TrackPushService : ApplicationService, ISingletonDependency { case OptionTypeNoNull.新增: { - int maxSort = await _trackPushConfigRepository.ContentMaxAsync(x => x.Sort, - x => x.TrackPushConfigId == input.TrackPushConfigId); + var maxSort = await _trackPushConfigRepository.ContentMaxAsync(x => x.Sort, x => + x.OrderNoType == input.OrderNoType + && x.TrackPushConfigId == input.TrackPushConfigId + ); var entity = ObjectMapper.Map(input); entity.Sort = maxSort + 1; @@ -216,8 +219,11 @@ public class TrackPushService : ApplicationService, ISingletonDependency throw new BusinessException(message: _stringLocalizer["NotFindData"]); trackPushConfigId = entity.TrackPushConfigId; await _trackPushConfigRepository.SoftDeleteContentAsync(x => x.Id == input.Id); - await _trackPushConfigRepository.UpdateContentAsync(x => x.Sort == x.Sort - 1, - x => x.TrackPushConfigId == entity.TrackPushConfigId && x.Sort > entity.Sort); + await _trackPushConfigRepository.UpdateContentAsync(x => x.Sort == x.Sort - 1, x => + x.OrderNoType == entity.OrderNoType + && x.TrackPushConfigId == entity.TrackPushConfigId + && x.Sort > entity.Sort + ); break; } @@ -249,10 +255,7 @@ public class TrackPushService : ApplicationService, ISingletonDependency var trackPushContentEntities = await _trackPushConfigRepository.GetContentListAsync(x => ids.Contains(x.Id)); - trackPushContentEntities.ForEach(item => - { - item.Sort = input.SortInfo.Single(x => x.Key == item.Id.ToString()).Value; - }); + trackPushContentEntities.ForEach(item => { item.Sort = input.SortInfo.Single(x => x.Key == item.Id.ToString()).Value; }); if (trackPushContentEntities.Count > 0) { diff --git a/src/SJZY.Track.Domain/Dtos/TrackPush/GetTrackPushContentPageInputVO.cs b/src/SJZY.Track.Domain/Dtos/TrackPush/GetTrackPushContentPageInputVO.cs index 57bf0626..6ad38fbe 100644 --- a/src/SJZY.Track.Domain/Dtos/TrackPush/GetTrackPushContentPageInputVO.cs +++ b/src/SJZY.Track.Domain/Dtos/TrackPush/GetTrackPushContentPageInputVO.cs @@ -6,4 +6,9 @@ public class GetTrackPushContentPageInputVO : PageInfoInput /// 轨迹推送配置id /// public int TrackPushConfigId { get; set; } + + /// + /// 配置单号类型,当为空时查所有,不区分单号类型 + /// + public int? OrderNoType { get; set; } } diff --git a/src/SJZY.Track.Domain/Dtos/TrackPush/TrackPushContentConfigVO.cs b/src/SJZY.Track.Domain/Dtos/TrackPush/TrackPushContentConfigVO.cs index 66db8889..b8b53dc0 100644 --- a/src/SJZY.Track.Domain/Dtos/TrackPush/TrackPushContentConfigVO.cs +++ b/src/SJZY.Track.Domain/Dtos/TrackPush/TrackPushContentConfigVO.cs @@ -27,6 +27,11 @@ public class TrackPushContentConfigVO /// public string TrackCode { get; set; } = null!; + /// + /// 推送顺序 + /// + public int Sort { get; set; } + /// /// 可交换顺序的轨迹code /// diff --git a/src/SJZY.Track.Repository/Repositories/TrackPushConfigRepository.cs b/src/SJZY.Track.Repository/Repositories/TrackPushConfigRepository.cs index 050d7d9e..98654c32 100644 --- a/src/SJZY.Track.Repository/Repositories/TrackPushConfigRepository.cs +++ b/src/SJZY.Track.Repository/Repositories/TrackPushConfigRepository.cs @@ -45,6 +45,7 @@ public class TrackPushConfigRepository : BasicRepository, enumValue.Property == EnumPropertyEnums.单号类型.GetDescription() && pushContent.OrderNoType == enumValue.Enumkey && !enumValue.IsDeleted) .Where(pushContent => pushContent.TrackPushConfigId == input.TrackPushConfigId) + .WhereIF(input.OrderNoType.HasValue, pushContent => pushContent.OrderNoType == input.OrderNoType) .OrderBy(pushContent => pushContent.Sort) .Select( (pushContent, trackContent, enumValue) => new GetTrackPushContentPageOutputVO @@ -138,6 +139,7 @@ public class TrackPushConfigRepository : BasicRepository, OrderType = b.OrderNoType, TrackCode = d.Code, SwapTrackCode = e.Code, + Sort = b.Sort, TrackContentCodeValue = b.TrackContentCodeValue, TrackContentValue = b.TrackContentValue, TrackEnContentValue = b.TrackEnContentValue,