optimize&fix:force push event case

This commit is contained in:
xiaolipro 2025-01-15 15:02:03 +08:00
parent 0b6e20da3f
commit 08f0ebeeae

View File

@ -96,107 +96,72 @@ public class TrackPushEventHandler : ITransientDependency, ICapSubscribe
private async Task DoPushAsync(TrackPushEvent @event) private async Task DoPushAsync(TrackPushEvent @event)
{ {
var items = new List<TrackPushInput>(); var items = new List<TrackPushInput>();
TrackPushContentConfigDto? config; if (@event.OperationMan == null)
var isSystemPush = @event.OperationMan == null;
if (isSystemPush && !@event.ForcedPush)
{ {
config = _pushConfigs.FirstOrDefault(x => x.TrackCode == @event.TrackCode); if (@event.OptionType == OptionType.新增)
foreach (var order in _orders)
{ {
if (config == null) await BuiltSystemPushItemsAsync(@event, items);
{
TrackPushFailedPublicTopic($"没有在推送映射配置中找到关于轨迹代码[{@event.TrackCode}]的配置", @event, order);
return;
} }
else if (@event.OptionType == OptionType.修改)
// 系统不推异常单,只能人工操作
if (order.QuestionType == (int) TrackProblemType.Error)
{ {
TrackPushFailedPublicTopic("系统不推异常单,只能人工操作", @event, order); await BuiltManualPushItemsAsync(@event, items);
continue;
}
// 推送新增,需要根据上一次的推送 推断 本次推送 是否可行,为了约束顺序
var (resultConfig, nextCode) = GetValidPushConfigAsync(_pushConfigs, order.LatestPushTrackCode, @event.TrackCode);
if (resultConfig == null)
{
TrackPushFailedPublicTopic($"推送顺序异常,下一个要推送的应为[{nextCode}]", @event, order);
continue;
}
config = resultConfig;
// 是否自动推送
if (!config.IsAutoPush)
{
TrackPushFailedPublicTopic($"没有设置为自动推送,如果要推送请手动推送", @event, order);
continue;
}
// 配置的类型如何和订单类型不一致则不允许推送
if (config.OrderType != order.OrderType)
{
TrackPushFailedPublicTopic($"订单类型{order.OrderType}和配置中的订单类型[{config.OrderType}]不一致,不能推送", @event, order);
continue;
}
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,
SubSystemCode = @event.SubSystemCode,
IsToMq = @event.IsToMq,
Extra = @event.SystemPushInfo.Extra
};
var item = await BuiltPushItem(config, log, @event.SystemPushInfo.CompareFields);
item.Log = JsonConvert.SerializeObject(log);
items.Add(item);
} }
} }
// 手工或强制推送,不会校验已推和顺序问题,因为可能是更新
else else
{ {
config = _pushConfigs.FirstOrDefault(x => x.TrackCode == @event.TrackCode); // 手工推送,不会校验已推和顺序问题,因为可能是更新
foreach (var order in _orders) await BuiltManualPushItemsAsync(@event, items);
{
if (config == null)
{
TrackPushFailedPublicTopic($"没有在推送映射配置中找到关于轨迹代码[{@event.TrackCode}]的配置", @event, order);
return;
} }
if (items.Count == 0) return;
using (Track2InterfaceRelaySubSystemContext.Use(
new Track2InterfaceRelaySubSystemContext(@event.SubSystemCode)))
{
var asciiString = Base64Helper.SerializeObject(OptionType.新增.ToString());
var serviceProviderCode = _pushConfigs.First().ServiceProviderCode;
var r = await _httpClientProxy.Service.BatchForwardThenPushToQueueAsync(
_options.CurrentValue.PushTrackInterfaceCode,
serviceProviderCode, items.Cast<object>().ToList(), GlobalConst.TrackPushCompletedSubscribe,
attach: asciiString);
if (r.Code != GlobalConst.SuccessCode)
{
TrackPushFailedPublicTopic($"轨迹中台调用接口通失败,RequestId: {r.RequestId}; Msg: {r.Msg}", @event, r.RequestId,
items.Cast<dynamic>().ToList());
throw new BusinessException(
message: $"requestId: {r.RequestId}; serviceProviderCode:{serviceProviderCode} Msg: {r.Msg}");
}
}
}
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 }) if (config is { IsAllPush: true })
{ {
// 非强制推送需要 推断 本次推送 是否可行 // 非强制推送需要 推断 本次推送 是否可行
if (!@event.ForcedPush) if (!@event.ForcedPush)
{ {
var (resultConfig, nextCode) = GetValidPushConfigAsync(_pushConfigs, order.LatestPushTrackCode, @event.TrackCode); config = GetValidPushConfigAsync(_pushConfigs, order.LatestPushTrackCode, @event);
if (resultConfig == null) }
}
if (config == null)
{ {
TrackPushFailedPublicTopic($"推送顺序异常,下一个要推送的应为[{nextCode}]", @event, order); TrackPushFailedPublicTopic("推送顺序异常,找不到有效推送配置", @event, order);
continue; return;
}
config = resultConfig;
}
// tips:强制推送直接使用配置
} }
//配置的类型如何和订单类型不一致则不允许推送 //配置的类型如何和订单类型不一致则不允许推送
if (config.OrderType != order.OrderType) if (config.OrderType != order.OrderType)
{ {
TrackPushFailedPublicTopic($"订单类型{order.OrderType}和配置中的订单类型[{config.OrderType}]不一致,不能推送", @event, order); TrackPushFailedPublicTopic($"订单类型{order.OrderType}和配置中的订单类型[{config.OrderType}]不一致,不能推送", @event,
order);
continue; continue;
} }
@ -222,23 +187,66 @@ public class TrackPushEventHandler : ITransientDependency, ICapSubscribe
} }
} }
if (items.Count == 0) return; private async Task BuiltSystemPushItemsAsync(TrackPushEvent @event, List<TrackPushInput> items)
using (Track2InterfaceRelaySubSystemContext.Use(
new Track2InterfaceRelaySubSystemContext(@event.SubSystemCode)))
{ {
var asciiString = Base64Helper.SerializeObject(OptionType.新增.ToString()); var config = _pushConfigs.FirstOrDefault(x => x.TrackCode == @event.TrackCode);
var serviceProviderCode = _pushConfigs.First().ServiceProviderCode; foreach (var order in _orders)
var r = await _httpClientProxy.Service.BatchForwardThenPushToQueueAsync(
_options.CurrentValue.PushTrackInterfaceCode,
serviceProviderCode, items.Cast<object>().ToList(), GlobalConst.TrackPushCompletedSubscribe,
attach: asciiString);
if (r.Code != GlobalConst.SuccessCode)
{ {
TrackPushFailedPublicTopic($"轨迹中台调用接口通失败,RequestId: {r.RequestId}; Msg: {r.Msg}", @event, r.RequestId, items.Cast<dynamic>().ToList()); if (config == null)
throw new BusinessException(message: $"requestId: {r.RequestId}; serviceProviderCode:{serviceProviderCode} Msg: {r.Msg}"); {
TrackPushFailedPublicTopic($"没有在推送映射配置中找到关于轨迹代码[{@event.TrackCode}]的配置", @event, order);
return;
} }
// 系统不推异常单,只能人工操作
if (order.QuestionType == (int) TrackProblemType.Error)
{
TrackPushFailedPublicTopic("系统不推异常单,只能人工操作", @event, order);
continue;
}
// 推送新增,需要根据上一次的推送 推断 本次推送 是否可行,为了约束顺序
config = GetValidPushConfigAsync(_pushConfigs, order.LatestPushTrackCode, @event);
if (config == null)
{
TrackPushFailedPublicTopic("推送顺序异常,找不到有效推送配置", @event, order);
continue;
}
// 是否自动推送
if (!config.IsAutoPush)
{
TrackPushFailedPublicTopic("没有设置为自动推送,如果要推送请手动推送", @event, order);
continue;
}
// 配置的类型如何和订单类型不一致则不允许推送
if (config.OrderType != order.OrderType)
{
TrackPushFailedPublicTopic($"订单类型{order.OrderType}和配置中的订单类型[{config.OrderType}]不一致,不能推送", @event,
order);
continue;
}
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,
SubSystemCode = @event.SubSystemCode,
IsToMq = @event.IsToMq,
Extra = @event.SystemPushInfo.Extra
};
var item = await BuiltPushItem(config, log, @event.SystemPushInfo.CompareFields);
item.Log = JsonConvert.SerializeObject(log);
items.Add(item);
} }
} }
@ -253,7 +261,8 @@ public class TrackPushEventHandler : ITransientDependency, ICapSubscribe
//配置的类型如何和订单类型不一致则不允许推送 //配置的类型如何和订单类型不一致则不允许推送
if (config.OrderType != order.OrderType) if (config.OrderType != order.OrderType)
{ {
TrackPushFailedPublicTopic($"订单类型{order.OrderType}和配置中的订单类型[{config.OrderType}]不一致,不能推送", @event, order); TrackPushFailedPublicTopic($"订单类型{order.OrderType}和配置中的订单类型[{config.OrderType}]不一致,不能推送", @event,
order);
continue; continue;
} }
@ -292,8 +301,10 @@ public class TrackPushEventHandler : ITransientDependency, ICapSubscribe
if (r.Code != GlobalConst.SuccessCode) if (r.Code != GlobalConst.SuccessCode)
{ {
TrackPushFailedPublicTopic($"轨迹中台调用接口通失败,RequestId: {r.RequestId}; Msg: {r.Msg}", @event, r.RequestId, items.Cast<dynamic>().ToList()); TrackPushFailedPublicTopic($"轨迹中台调用接口通失败,RequestId: {r.RequestId}; Msg: {r.Msg}", @event, r.RequestId,
throw new BusinessException(message: $"requestId: {r.RequestId}; serviceProviderCode:{serviceProviderCode} Msg: {r.Msg}"); items.Cast<dynamic>().ToList());
throw new BusinessException(
message: $"requestId: {r.RequestId}; serviceProviderCode:{serviceProviderCode} Msg: {r.Msg}");
} }
} }
} }
@ -363,12 +374,15 @@ public class TrackPushEventHandler : ITransientDependency, ICapSubscribe
{ {
//反序列化出的JsonElement和字典字符串类型做比较 //反序列化出的JsonElement和字典字符串类型做比较
var a = ((JsonElement) x["code"]!).GetString(); var a = ((JsonElement) x["code"]!).GetString();
var b = cur["code"]!.ToString(); //tips: 需要要将object类型的字符串转为string类型,否则使用的是引用比较,反序列化出的string一定和本地string引用不同 var b = cur["code"]!
.ToString(); //tips: 需要要将object类型的字符串转为string类型,否则使用的是引用比较,反序列化出的string一定和本地string引用不同
return a == b; return a == b;
}).WhereIf(!compareFields.IsNullOrWhiteSpace(), x => })
.WhereIf(!compareFields.IsNullOrWhiteSpace(), x =>
{ {
if (x["extra"] == null || log.Extra == null) return false; if (x["extra"] == null || log.Extra == null) return false;
return TextJsonHelper.EqByJsonElementField(x["extra"]!, TextJsonHelper.Deserialize<JsonElement>(log.Extra), compareFields!); return TextJsonHelper.EqByJsonElementField(x["extra"]!,
TextJsonHelper.Deserialize<JsonElement>(log.Extra), compareFields!);
}) })
.FirstOrDefault(); .FirstOrDefault();
@ -376,8 +390,8 @@ public class TrackPushEventHandler : ITransientDependency, ICapSubscribe
{ {
body.Data.Remove(old); body.Data.Remove(old);
} }
} }
// //添加当前要推送的轨迹 // //添加当前要推送的轨迹
body!.Data.Add(cur); body!.Data.Add(cur);
} }
@ -392,24 +406,28 @@ public class TrackPushEventHandler : ITransientDependency, ICapSubscribe
/// 根据轨迹代码推断下一个(升序)要推送的内容,如果找不到或者已经是最后一个了 /// 根据轨迹代码推断下一个(升序)要推送的内容,如果找不到或者已经是最后一个了
/// 则查询有没有可交换的推送,没有就返回null /// 则查询有没有可交换的推送,没有就返回null
/// </summary> /// </summary>
private static (TrackPushContentConfigDto? config, string nextCode) GetValidPushConfigAsync(List<TrackPushContentConfigDto> cache, private static TrackPushContentConfigDto? GetValidPushConfigAsync(List<TrackPushContentConfigDto> cache,
string? latestPushTrackCode, string? trackCode) string? latestPushTrackCode, TrackPushEvent @event)
{ {
var trackCode = @event.TrackCode;
var idx = cache.FindIndex(x => x.TrackCode == latestPushTrackCode); var idx = cache.FindIndex(x => x.TrackCode == latestPushTrackCode);
if (@event.ForcedPush && trackCode == latestPushTrackCode)
{
//强制推送,允许重复推送当前轨迹
return cache[idx];
}
if (idx + 1 >= cache.Count) return default; // 推完了 if (idx + 1 >= cache.Count) return default; // 推完了
// find next // find next
var matched = cache[idx + 1].TrackCode == trackCode var matched = cache[idx + 1].TrackCode == trackCode
? cache[idx + 1] ? cache[idx + 1]
:
// find swap // find swap
cache.FirstOrDefault(x => x.TrackCode == cache[idx + 1].SwapTrackCode); : cache.FirstOrDefault(x => x.TrackCode == cache[idx + 1].SwapTrackCode);
//没推完,可能不符合推送顺序 //没推完,可能不符合推送顺序
return matched != null && matched.TrackCode == trackCode return matched != null && matched.TrackCode == trackCode ? matched : default;
? (matched, matched.TrackCode)
: (default, matched?.TrackCode ?? cache[idx + 1].TrackCode);
} }
/// <summary> /// <summary>
@ -433,10 +451,7 @@ public class TrackPushEventHandler : ITransientDependency, ICapSubscribe
} }
//轨迹推送失败(被拦截) //轨迹推送失败(被拦截)
private void TrackPushFailedPublicTopic( private void TrackPushFailedPublicTopic(string failedMessage, TrackPushEvent @event, OrderEntity order)
string failedMessage,
TrackPushEvent @event,
OrderEntity order)
{ {
_broadcastingService.TrackPushFailedPubilcTopic(new TrackPushRecordDto _broadcastingService.TrackPushFailedPubilcTopic(new TrackPushRecordDto
{ {