admin/src/Oms.Application/Services/Orders/Batch/OrderBatchCreateActionHandler.cs
zzh 7d5bc2408f fix(order): 批量导入回写订单 ID 并增强 Excel 表头映射匹配
导入行成功后写入 batch job 的 orderId/serviceNo;预报失败时尽量关联草稿订单。Excel 读取与行映射支持表头归一化,兼容带括号说明的列名。

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-08 18:34:59 +08:00

97 lines
3.6 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using Fake.Application;
using Fake.DependencyInjection;
using Microsoft.Extensions.DependencyInjection;
using Newtonsoft.Json;
using Oms.Application.Dtos.Orders;
using Oms.Application.Messaging;
using Oms.Domain.OrdersAggregate.Consts;
namespace Oms.Application.Services.Orders.Batch;
/// <summary>
/// 创建类批量操作(Excel 导入行、小包批量创建)执行器。
/// </summary>
public sealed class OrderBatchCreateActionHandler(IServiceScopeFactory scopeFactory) : IScopedDependency
{
public async Task<OrderBatchActionExecuteResult> ExecuteImportRowAsync(
OrderBatchJobMessage message,
CancellationToken cancellationToken = default)
{
if (string.IsNullOrWhiteSpace(message.PayloadJson))
{
return OrderBatchActionExecuteResult.BusinessFail("导入行消息体为空");
}
var payload = JsonConvert.DeserializeObject<OrderBatchImportRowPayload>(message.PayloadJson);
if (payload == null)
{
return OrderBatchActionExecuteResult.BusinessFail("导入行消息体无效");
}
try
{
using var scope = scopeFactory.CreateScope();
var orderService = scope.ServiceProvider.GetRequiredService<OrderService>();
var output = await orderService.ImportRowForBatchAsync(payload, message.OperatorUserId, cancellationToken);
return OrderBatchActionExecuteResult.Ok(
createdOrderId: output.OrderId,
serviceNo: output.ServiceNo,
clientNo: output.ClientNo,
trackNo: output.TrackNo,
labelUrl: output.LabelUrl);
}
catch (BusinessException ex)
{
using var scope = scopeFactory.CreateScope();
var orderService = scope.ServiceProvider.GetRequiredService<OrderService>();
var createdOrderId = await orderService.TryResolveImportOrderIdAsync(payload, cancellationToken);
return OrderBatchActionExecuteResult.BusinessFail(ex.Message, createdOrderId);
}
catch (Exception ex)
{
return OrderBatchActionExecuteResult.SystemFail(ex.Message);
}
}
public async Task<OrderBatchActionExecuteResult> ExecuteParcelCreateAsync(
OrderBatchJobMessage message,
CancellationToken cancellationToken = default)
{
if (string.IsNullOrWhiteSpace(message.PayloadJson))
{
return OrderBatchActionExecuteResult.BusinessFail("小包创建消息体为空");
}
var input = JsonConvert.DeserializeObject<OrderParcelCreateInput>(message.PayloadJson);
if (input == null)
{
return OrderBatchActionExecuteResult.BusinessFail("小包创建消息体无效");
}
try
{
using var scope = scopeFactory.CreateScope();
var orderService = scope.ServiceProvider.GetRequiredService<OrderService>();
var output = await orderService.CreateParcelForBatchAsync(
input,
message.OperatorUserId,
cancellationToken);
return OrderBatchActionExecuteResult.Ok(
createdOrderId: null,
serviceNo: output.ServiceNo,
clientNo: output.ClientNo,
trackNo: output.TrackNo,
labelUrl: output.LabelUrl);
}
catch (BusinessException ex)
{
return OrderBatchActionExecuteResult.BusinessFail(ex.Message);
}
catch (Exception ex)
{
return OrderBatchActionExecuteResult.SystemFail(ex.Message);
}
}
}