feat: 查询轨迹映射-推送映射配置,查询配置列表增加订单类型的支持。

This commit is contained in:
hardstylewyl 2025-02-14 10:04:02 +08:00
parent 4bc45bc05c
commit 7c3e458642
7 changed files with 127 additions and 59 deletions

View File

@ -42,6 +42,11 @@ public class TrackPushContentConfigDto
/// </summary>
public string TrackCode { get; set; } = null!;
/// <summary>
/// 推送顺序
/// </summary>
public int Sort { get; set; }
/// <summary>
/// 可交换顺序的轨迹code
/// </summary>

View File

@ -31,6 +31,7 @@ public class TrackPushEventHandler : ITransientDependency, ICapSubscribe
private readonly IBroadcastingService _broadcastingService;
private List<OrderEntity> _orders = null!;
private List<TrackPushContentConfigDto> _pushConfigs = null!;
private Dictionary<int, List<TrackPushContentConfigDto>> _orderTypeSortedConfigsDict = null!; //订单类型,根据sort从小到大排序后的配置字典
public TrackPushEventHandler(IHttpClientProxy<IInterfaceForwardServiceV2> 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<TrackPushInput> 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<TrackPushInput> 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<TrackUpdateInput>();
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<string, object?>
{
@ -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<TrackPushInput>(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;
}
/// <summary>
@ -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,

View File

@ -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,

View File

@ -159,7 +159,8 @@ public class TrackPushService : ApplicationService, ISingletonDependency
if (input.Options != OptionTypeNoNull.删除)
{
Expression<Func<TrackPushContentConfigEntity, bool>> 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<EditTrackPushContentInput, TrackPushContentConfigEntity>(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)
{

View File

@ -6,4 +6,9 @@ public class GetTrackPushContentPageInputVO : PageInfoInput
/// 轨迹推送配置id
/// </summary>
public int TrackPushConfigId { get; set; }
/// <summary>
/// 配置单号类型,当为空时查所有,不区分单号类型
/// </summary>
public int? OrderNoType { get; set; }
}

View File

@ -27,6 +27,11 @@ public class TrackPushContentConfigVO
/// </summary>
public string TrackCode { get; set; } = null!;
/// <summary>
/// 推送顺序
/// </summary>
public int Sort { get; set; }
/// <summary>
/// 可交换顺序的轨迹code
/// </summary>

View File

@ -45,6 +45,7 @@ public class TrackPushConfigRepository : BasicRepository<TrackPushConfigEntity>,
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<TrackPushConfigEntity>,
OrderType = b.OrderNoType,
TrackCode = d.Code,
SwapTrackCode = e.Code,
Sort = b.Sort,
TrackContentCodeValue = b.TrackContentCodeValue,
TrackContentValue = b.TrackContentValue,
TrackEnContentValue = b.TrackEnContentValue,