1.05 #7
@ -72,7 +72,8 @@ public sealed class OrderBatchOrderActionHandler(IServiceScopeFactory scopeFacto
|
||||
message.OrderId,
|
||||
message.PayloadJson,
|
||||
message.OperatorUserId,
|
||||
cancellationToken);
|
||||
cancellationToken,
|
||||
message.Authorization);
|
||||
return OrderBatchActionExecuteResult.Ok();
|
||||
|
||||
case OrderBatchActionCodes.Reallocate:
|
||||
|
||||
@ -2329,20 +2329,26 @@ public partial class OrderService
|
||||
await OrderRepository.UpdateAsync(order);
|
||||
|
||||
var operatorId = operatorUserId ?? (CurrentUser.IsAuthenticated ? CurrentUser.GetId<int>() : 0);
|
||||
var authorization = CaptureRequestAuthorization();
|
||||
var publisher = LazyServiceProvider.GetRequiredService<IOrderBatchJobPublisher>();
|
||||
if (!publisher.IsEnabled)
|
||||
{
|
||||
var payloadJson = JsonConvert.SerializeObject(new ForecastBillingJobPayload
|
||||
{
|
||||
CouponInstanceId = order.CouponInstanceId
|
||||
CouponInstanceId = order.CouponInstanceId,
|
||||
Authorization = authorization
|
||||
});
|
||||
await ProcessForecastBillingForBatchAsync(order.Id, payloadJson, operatorId);
|
||||
await ProcessForecastBillingForBatchAsync(
|
||||
order.Id,
|
||||
payloadJson,
|
||||
operatorId,
|
||||
authorization: authorization);
|
||||
}
|
||||
else
|
||||
{
|
||||
var orderId = order.Id;
|
||||
var couponInstanceId = order.CouponInstanceId;
|
||||
await ScheduleForecastEnqueueAsync(orderId, couponInstanceId, operatorId);
|
||||
await ScheduleForecastEnqueueAsync(orderId, couponInstanceId, operatorId, authorization);
|
||||
}
|
||||
|
||||
await ScheduleForecastSideEffectsAsync(order.Id, operatorId);
|
||||
@ -2663,7 +2669,8 @@ public partial class OrderService
|
||||
int orderId,
|
||||
string? payloadJson = null,
|
||||
int operatorUserId = 0,
|
||||
CancellationToken cancellationToken = default)
|
||||
CancellationToken cancellationToken = default,
|
||||
string? authorization = null)
|
||||
{
|
||||
var order = await OrderRepository.FirstOrDefaultAsync(x => x.Id == orderId, cancellationToken);
|
||||
if (order == null)
|
||||
@ -2687,6 +2694,7 @@ public partial class OrderService
|
||||
var beforeSnap = await CaptureOrderAuditSnapshotAsync(order, includeFees: true, includeWeights: true);
|
||||
|
||||
int? couponInstanceId = order.CouponInstanceId;
|
||||
string? trackAuthorization = authorization;
|
||||
if (!string.IsNullOrWhiteSpace(payloadJson))
|
||||
{
|
||||
try
|
||||
@ -2696,6 +2704,12 @@ public partial class OrderService
|
||||
{
|
||||
couponInstanceId = payload.CouponInstanceId;
|
||||
}
|
||||
|
||||
if (string.IsNullOrWhiteSpace(trackAuthorization)
|
||||
&& !string.IsNullOrWhiteSpace(payload?.Authorization))
|
||||
{
|
||||
trackAuthorization = payload.Authorization.Trim();
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
@ -2829,9 +2843,10 @@ public partial class OrderService
|
||||
await OrderRepository.UpdateAsync(order);
|
||||
|
||||
// 轨迹订单依赖排货后的渠道/ApiCode,只有排货成功才创建。
|
||||
// 消费端没有 HttpContext,须用创单时捕获的 Authorization,否则轨迹网关返回 401。
|
||||
if (allocated && !string.IsNullOrWhiteSpace(order.ChannelCode))
|
||||
{
|
||||
await ScheduleTrackAfterAllocationAsync(order.Id);
|
||||
await ScheduleTrackAfterAllocationAsync(order.Id, trackAuthorization);
|
||||
}
|
||||
|
||||
var afterSnap = await CaptureOrderAuditSnapshotAsync(order, includeFees: true, includeWeights: true);
|
||||
@ -2850,6 +2865,11 @@ public partial class OrderService
|
||||
private sealed class ForecastBillingJobPayload
|
||||
{
|
||||
public int? CouponInstanceId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 创单/预报请求的 Authorization,供排货后异步创建轨迹订单转发到轨迹网关。
|
||||
/// </summary>
|
||||
public string? Authorization { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -2868,6 +2888,8 @@ public partial class OrderService
|
||||
var logger = LazyServiceProvider.GetRequiredService<ILoggerFactory>().CreateLogger("Oms.OrderParcelCreate");
|
||||
var platformCode = input.PlatformCode;
|
||||
var couponInstanceId = input.CouponInstanceId;
|
||||
// 事务提交后 HttpContext 已不可用,这里先捕获登录态供轨迹网关使用。
|
||||
var authorization = CaptureRequestAuthorization();
|
||||
|
||||
await OmsAfterCommit.ScheduleAsync(unitOfWorkManager, async () =>
|
||||
{
|
||||
@ -2882,7 +2904,11 @@ public partial class OrderService
|
||||
forecastQueued = await OmsAfterCommit.RunStepAsync(scopeFactory, logger, "forecast-billing", async sp =>
|
||||
{
|
||||
var service = sp.GetRequiredService<OrderService>();
|
||||
await service.EnqueueForecastBillingByIdAsync(orderId, couponInstanceId, operatorUserId);
|
||||
await service.EnqueueForecastBillingByIdAsync(
|
||||
orderId,
|
||||
couponInstanceId,
|
||||
operatorUserId,
|
||||
authorization);
|
||||
});
|
||||
await OmsAfterCommit.RunStepAsync(scopeFactory, logger, "label-generate", sp =>
|
||||
sp.GetRequiredService<OrderService>().PublishForecastLabelAsync(orderId, operatorUserId));
|
||||
@ -2906,7 +2932,11 @@ public partial class OrderService
|
||||
});
|
||||
}
|
||||
|
||||
private async Task ScheduleForecastEnqueueAsync(int orderId, int? couponInstanceId, int operatorUserId)
|
||||
private async Task ScheduleForecastEnqueueAsync(
|
||||
int orderId,
|
||||
int? couponInstanceId,
|
||||
int operatorUserId,
|
||||
string? authorization)
|
||||
{
|
||||
var unitOfWorkManager = LazyServiceProvider.GetRequiredService<IUnitOfWorkManager>();
|
||||
var scopeFactory = LazyServiceProvider.GetRequiredService<IServiceScopeFactory>();
|
||||
@ -2916,7 +2946,8 @@ public partial class OrderService
|
||||
sp.GetRequiredService<OrderService>().EnqueueForecastBillingByIdAsync(
|
||||
orderId,
|
||||
couponInstanceId,
|
||||
operatorUserId)));
|
||||
operatorUserId,
|
||||
authorization)));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -2939,14 +2970,14 @@ public partial class OrderService
|
||||
/// <summary>
|
||||
/// 预报计费事务提交后,再创建轨迹订单(此时已有渠道和 ApiCode)。
|
||||
/// </summary>
|
||||
private async Task ScheduleTrackAfterAllocationAsync(int orderId)
|
||||
private async Task ScheduleTrackAfterAllocationAsync(int orderId, string? authorization)
|
||||
{
|
||||
var unitOfWorkManager = LazyServiceProvider.GetRequiredService<IUnitOfWorkManager>();
|
||||
var scopeFactory = LazyServiceProvider.GetRequiredService<IServiceScopeFactory>();
|
||||
var logger = LazyServiceProvider.GetRequiredService<ILoggerFactory>().CreateLogger("Oms.ForecastBilling");
|
||||
await OmsAfterCommit.ScheduleAsync(unitOfWorkManager, () =>
|
||||
OmsAfterCommit.RunStepAsync(scopeFactory, logger, "track-upsert", sp =>
|
||||
sp.GetRequiredService<OrderService>().PublishForecastTrackAsync(orderId)));
|
||||
sp.GetRequiredService<OrderService>().PublishForecastTrackAsync(orderId, authorization)));
|
||||
}
|
||||
|
||||
private async Task PublishCustomsForOrderAsync(int orderId, string? platformCode)
|
||||
@ -2961,7 +2992,11 @@ public partial class OrderService
|
||||
await ParcelCreateEventPublisher.PublishCustoms9610UpsertAsync(order, platformCode);
|
||||
}
|
||||
|
||||
private async Task EnqueueForecastBillingByIdAsync(int orderId, int? couponInstanceId, int operatorUserId)
|
||||
private async Task EnqueueForecastBillingByIdAsync(
|
||||
int orderId,
|
||||
int? couponInstanceId,
|
||||
int operatorUserId,
|
||||
string? authorization)
|
||||
{
|
||||
var order = await OrderRepository.FirstOrDefaultAsync(x => x.Id == orderId);
|
||||
if (order == null
|
||||
@ -2970,7 +3005,7 @@ public partial class OrderService
|
||||
return;
|
||||
}
|
||||
|
||||
await EnqueueForecastBillingAsync(order, couponInstanceId, operatorUserId);
|
||||
await EnqueueForecastBillingAsync(order, couponInstanceId, operatorUserId, authorization);
|
||||
}
|
||||
|
||||
private async Task MarkForecastEnqueueFailedIfStillProcessingAsync(int orderId)
|
||||
@ -2985,7 +3020,7 @@ public partial class OrderService
|
||||
await MarkParcelDraftFailedAsync(order, ForecastBillingEnqueueFailReason);
|
||||
}
|
||||
|
||||
private async Task PublishForecastTrackAsync(int orderId)
|
||||
private async Task PublishForecastTrackAsync(int orderId, string? authorization = null)
|
||||
{
|
||||
var order = await OrderRepository.FirstOrDefaultAsync(x => x.Id == orderId);
|
||||
if (order == null
|
||||
@ -3000,7 +3035,7 @@ public partial class OrderService
|
||||
: null;
|
||||
var request = await BuildSmallBagTrackUpsertRequestAsync(order, receiverInput: null);
|
||||
request.AppendInitialTrackOnSuccess = true;
|
||||
ApplyTrackAuthorization(request);
|
||||
ApplyTrackAuthorization(request, authorization);
|
||||
await ParcelCreateEventPublisher.PublishTrackUpsertAsync(order, request, customer?.Id);
|
||||
}
|
||||
|
||||
@ -3031,13 +3066,16 @@ public partial class OrderService
|
||||
private async Task EnqueueForecastBillingAsync(
|
||||
Order order,
|
||||
int? couponInstanceId,
|
||||
int operatorUserId)
|
||||
int operatorUserId,
|
||||
string? authorization = null)
|
||||
{
|
||||
var logger = LazyServiceProvider.GetRequiredService<ILoggerFactory>()
|
||||
.CreateLogger("Oms.ForecastBilling");
|
||||
authorization ??= CaptureRequestAuthorization();
|
||||
var payloadJson = JsonConvert.SerializeObject(new ForecastBillingJobPayload
|
||||
{
|
||||
CouponInstanceId = couponInstanceId
|
||||
CouponInstanceId = couponInstanceId,
|
||||
Authorization = authorization
|
||||
});
|
||||
|
||||
try
|
||||
@ -3047,7 +3085,11 @@ public partial class OrderService
|
||||
{
|
||||
try
|
||||
{
|
||||
await ProcessForecastBillingForBatchAsync(order.Id, payloadJson, operatorUserId);
|
||||
await ProcessForecastBillingForBatchAsync(
|
||||
order.Id,
|
||||
payloadJson,
|
||||
operatorUserId,
|
||||
authorization: authorization);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
@ -3073,7 +3115,8 @@ public partial class OrderService
|
||||
RequestId = requestId,
|
||||
PayloadJson = payloadJson
|
||||
},
|
||||
operatorUserId);
|
||||
operatorUserId,
|
||||
authorization);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
@ -3375,18 +3418,37 @@ public partial class OrderService
|
||||
await ParcelCreateEventPublisher.PublishTrackUpsertAsync(order, request, customer?.Id);
|
||||
}
|
||||
|
||||
private void ApplyTrackAuthorization(SmallBagTrackUpsertRequest request)
|
||||
private void ApplyTrackAuthorization(SmallBagTrackUpsertRequest request, string? authorization = null)
|
||||
{
|
||||
var authorization = LazyServiceProvider
|
||||
.GetRequiredService<IHttpContextAccessor>()
|
||||
.HttpContext?
|
||||
.Request
|
||||
.Headers
|
||||
.Authorization
|
||||
.ToString();
|
||||
if (!string.IsNullOrWhiteSpace(authorization))
|
||||
{
|
||||
request.Authorization = authorization;
|
||||
request.Authorization = authorization.Trim();
|
||||
return;
|
||||
}
|
||||
|
||||
var fromRequest = CaptureRequestAuthorization();
|
||||
if (!string.IsNullOrWhiteSpace(fromRequest))
|
||||
{
|
||||
request.Authorization = fromRequest;
|
||||
}
|
||||
}
|
||||
|
||||
private string? CaptureRequestAuthorization()
|
||||
{
|
||||
try
|
||||
{
|
||||
var authorization = LazyServiceProvider
|
||||
.GetRequiredService<IHttpContextAccessor>()
|
||||
.HttpContext?
|
||||
.Request
|
||||
.Headers
|
||||
.Authorization
|
||||
.ToString();
|
||||
return string.IsNullOrWhiteSpace(authorization) ? null : authorization.Trim();
|
||||
}
|
||||
catch (ObjectDisposedException)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -623,6 +623,7 @@ public partial class OrderService : ApplicationService
|
||||
/// <para>
|
||||
/// 【预报计费消费后】计费重、应收、排货应付、营销快照 → 订单改已预报。
|
||||
/// 排货成功且已有 ChannelCode 时,再投递轨迹订单 + A0101(track-upsert);
|
||||
/// 轨迹网关需要登录 Authorization,创单时写入预报任务 Payload,消费端原样转发;
|
||||
/// 排货失败不阻断预报,也不建轨迹(可页面补做)。
|
||||
/// </para>
|
||||
/// </summary>
|
||||
|
||||
Loading…
Reference in New Issue
Block a user