admin/src/Oms.Application/Services/Orders/OrderService.BatchCreate.cs
zzh 60cb2c5e0f fix: document marketing APIs and hide Order batch helpers from Swagger
Add Chinese XML summaries for OMS-Marketing endpoints, and mark OrderService batch worker methods internal to stop OMS-Order swagger generation conflicts.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-24 11:09:55 +08:00

119 lines
4.4 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 Newtonsoft.Json;
using Oms.Application.Dtos.Orders;
using Oms.Application.Messaging;
using Oms.Application.Services.Orders.Batch;
using Oms.Application.Services.Orders.Templates;
using Oms.Domain.OrdersAggregate.Consts;
namespace Oms.Application.Services.Orders;
public partial class OrderService
{
private IOrderBatchJobPublisher BatchJobPublisher =>
LazyServiceProvider.GetRequiredService<IOrderBatchJobPublisher>();
/// <summary>
/// 批量 Worker 导入单行 Excel 数据(内部方法,勿暴露为 HTTP API)。
/// </summary>
internal async Task<OrderParcelCreateOutput> ImportRowForBatchAsync(
OrderBatchImportRowPayload payload,
int operatorUserId,
CancellationToken cancellationToken = default)
{
var template = await OrderTemplateRepository.FirstOrDefaultAsync(x => x.Id == payload.TemplateId, cancellationToken)
?? throw new BusinessException("模板不存在");
OrderTemplateImportMapping.EnsureTemplateReadyForImport(template);
var mapping = OrderTemplateImportMapping.Resolve(template);
var sourceValues = JsonConvert.DeserializeObject<Dictionary<string, object>>(payload.RowDataJson)
?? throw new BusinessException("行数据无效");
var input = OrderTemplateRowMapper.MapToParcelCreateInput(sourceValues, mapping, payload.CustomerId);
if (payload.CustomerSenderAddressId is > 0)
{
await ApplyCustomerSenderAddressToParcelInputAsync(
input,
payload.CustomerId,
payload.CustomerSenderAddressId.Value,
cancellationToken);
}
return await CreateParcelForBatchAsync(
input,
operatorUserId,
orderSource: null,
customerSenderAddressId: payload.CustomerSenderAddressId,
cancellationToken);
}
internal async Task<int?> TryResolveImportOrderIdAsync(
OrderBatchImportRowPayload payload,
CancellationToken cancellationToken = default)
{
try
{
var template = await OrderTemplateRepository.FirstOrDefaultAsync(x => x.Id == payload.TemplateId, cancellationToken);
if (template == null)
{
return null;
}
var mapping = OrderTemplateImportMapping.Resolve(template);
var sourceValues = JsonConvert.DeserializeObject<Dictionary<string, object>>(payload.RowDataJson);
if (sourceValues == null || sourceValues.Count == 0)
{
return null;
}
var input = OrderTemplateRowMapper.MapToParcelCreateInput(sourceValues, mapping, payload.CustomerId);
if (string.IsNullOrWhiteSpace(input.ClientNo))
{
return null;
}
var order = await OrderRepository.GetByCustomerAndClientNoAsync(
payload.CustomerId,
input.ClientNo.Trim(),
cancellationToken);
return order?.Id;
}
catch
{
return null;
}
}
/// <summary>
/// 批量 Worker 创建小包订单。
/// </summary>
internal Task<OrderParcelCreateOutput> CreateParcelForBatchAsync(
OrderParcelCreateInput input,
int operatorUserId,
CancellationToken cancellationToken = default) =>
CreateParcelForBatchAsync(input, operatorUserId, orderSource: null, customerSenderAddressId: null, cancellationToken);
/// <summary>
/// 批量 Worker 创建小包订单(可指定 <paramref name="orderSource"/> 与默认发件地址)。
/// </summary>
internal async Task<OrderParcelCreateOutput> CreateParcelForBatchAsync(
OrderParcelCreateInput input,
int operatorUserId,
string? orderSource,
int? customerSenderAddressId,
CancellationToken cancellationToken = default)
{
ParcelCreateContext? createContext = null;
if (!string.IsNullOrWhiteSpace(orderSource) || customerSenderAddressId is > 0)
{
createContext = new ParcelCreateContext
{
OrderSource = string.IsNullOrWhiteSpace(orderSource) ? null : orderSource.Trim(),
CustomerSenderAddressId = customerSenderAddressId,
};
}
return await CreateParcelCoreAsync(input, operatorUserId, createContext);
}
}