track/src/TrackCenter.Application/Services/ProvideServices/OrderService.V2.cs
zzh f6590de824
All checks were successful
Build and Deploy / deploy (push) Successful in 49s
feat: UpsertBigBag 支持 apiCode 并匹配大包拉取配置
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-28 16:57:59 +08:00

292 lines
10 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 InterfaceForward.Domain.Shared.Helpers;
using TrackCenter.Application.Dtos.ProvideServices;
using TrackCenter.Application.Dtos.ProvideServices.V2;
using TrackCenter.Application.Filters;
using TrackCenter.Domain.Aggregates.OrderAggregate;
using TrackCenter.Domain.Aggregates.TrackPullAggregate;
namespace TrackCenter.Application.Services.ProvideServices;
/// <summary>
/// 订单服务 - 小包/大包/主单 Upsert(原 OrderServiceV2)
/// </summary>
public partial class OrderService
{
/// <summary>
/// 新增、更新小包(存在就更新)
/// </summary>
[HttpPost("Order/UpsertSmallBag")]
[VerifySignature]
public async Task<IdBaseDto> UpsertSmallBagAsync(UpsertSmallBagInput input)
{
var order = await _orderRepository.GetFirstAsync(x =>
x.AppKey == AppKey && x.OrderType == TrackOrderType.小包 && x.OrderNo == input.OrderNo);
if (order != null)
{
order = await BuiltOrder(input);
await _orderRepository.UpdateOrderAsync(order);
var index = new OrderOperationRecordIndex
{
OrderId = order.Id,
OrderNo = input.OrderNo,
OptionType = nameof(OrderOperationType.修改订单),
Content = input.ToJson(),
CreateUserId = CurrentUserId,
CreateUserName = CurrentUser.UserName ?? string.Empty,
};
_ = _orderOperationRecordEsRepository.AddAsync(index);
return new IdBaseDto { Id = order.Id };
}
order = await BuiltOrder(input);
var orderId = await _orderRepository.CreateOrderAsync(order);
var indexForAdd = new OrderOperationRecordIndex
{
OrderId = orderId,
OrderNo = input.OrderNo,
OptionType = nameof(OrderOperationType.创建订单),
Content = input.ToJson(),
CreateUserId = CurrentUserId,
CreateUserName = CurrentUser.UserName ?? string.Empty,
CreateTime = DateTime.Now
};
_ = _orderOperationRecordEsRepository.AddAsync(indexForAdd);
return new IdBaseDto { Id = orderId };
}
/// <summary>
/// 新增、更新大包(存在就更新)
/// </summary>
[HttpPost("Order/UpsertBigBag")]
[VerifySignature]
public async Task<IdBaseDto> UpsertBigBagAsync(UpsertBigBagInput input)
{
var order = await _orderRepository.GetFirstAsync(x =>
x.AppKey == AppKey && x.OrderType == TrackOrderType.大包 && x.OrderNo == input.BagNo);
if (order != null)
{
order = await BuiltOrder(input);
await _orderRepository.UpdateOrderAsync(order);
var index = new OrderOperationRecordIndex
{
OrderId = order.Id,
OrderNo = input.BagNo,
OptionType = OrderOperationType.修改订单.ToString(),
Content = input.ToJson(),
CreateUserId = CurrentUserId,
CreateUserName = CurrentUser.UserName ?? string.Empty,
};
_ = _orderOperationRecordEsRepository.AddAsync(index);
return new IdBaseDto { Id = order.Id };
}
order = await BuiltOrder(input);
var orderId = await _orderRepository.CreateOrderAsync(order);
var indexForAdd = new OrderOperationRecordIndex
{
OrderId = orderId,
OrderNo = input.BagNo,
OptionType = nameof(OrderOperationType.创建订单),
Content = input.ToJson(),
CreateUserId = CurrentUserId,
CreateUserName = CurrentUser.UserName ?? string.Empty,
CreateTime = DateTime.Now
};
_ = _orderOperationRecordEsRepository.AddAsync(indexForAdd);
return new IdBaseDto { Id = orderId };
}
/// <summary>
/// 新增、更新主单(存在就更新)
/// </summary>
[HttpPost("Order/UpsertMasterOrder")]
[VerifySignature]
public async Task<IdBaseDto> UpsertMasterOrderAsync(UpsertMasterOrderInput input)
{
var order = await _orderRepository.GetFirstAsync(x =>
x.AppKey == AppKey && x.OrderType == TrackOrderType.主单 && x.OrderNo == input.MasterNo);
if (order != null)
{
order = await BuiltOrder(input);
await _orderRepository.UpdateOrderAsync(order);
var index = new OrderOperationRecordIndex
{
OrderId = order.Id,
OrderNo = input.MasterNo,
OptionType = nameof(OrderOperationType.修改订单),
Content = input.ToJson(),
CreateUserId = CurrentUserId,
CreateUserName = CurrentUser.UserName ?? string.Empty,
};
_ = _orderOperationRecordEsRepository.AddAsync(index);
return new IdBaseDto { Id = order.Id };
}
order = await BuiltOrder(input);
var orderId = await _orderRepository.CreateOrderAsync(order);
var indexForAdd = new OrderOperationRecordIndex
{
OrderId = orderId,
OrderNo = input.MasterNo,
OptionType = nameof(OrderOperationType.创建订单),
Content = input.ToJson(),
CreateUserId = CurrentUserId,
CreateUserName = CurrentUser.UserName ?? string.Empty,
CreateTime = DateTime.Now
};
_ = _orderOperationRecordEsRepository.AddAsync(indexForAdd);
return new IdBaseDto { Id = orderId };
}
private async Task<OrderEntity> BuiltOrder(UpsertSmallBagInput input)
{
var order = new OrderEntity
{
AppKey = AppKey!,
ServiceProviderCode = input.ApiCode,
OrderType = TrackOrderType.小包,
OrderNo = input.OrderNo,
TrackNo = input.TrackNo,
ThirdPartyOrderNumber = input.OtherNo,
Customer = input.Client,
Channel = input.Channel,
ProductCode = input.Product,
ArrivalCountry = input.Consignee.CountryCode,
ArrivalProvince = input.Consignee.Province,
ArrivalPostCode = input.Consignee.Postcode,
ArrivalCity = input.Consignee.City,
ArrivalEmail = input.Consignee.Email,
};
var config = await _trackPullConfigRepository
.FirstOrDefaultAsync(x => x.AppKey == AppKey
&& x.ServiceProviderCode == input.ApiCode
&& x.OrderType == TrackOrderType.小包);
if (config == null)
{
throw ProviderServiceActionResult.Exception("创建/更新失败",
"没有适用的拉取配置,请先配置轨迹拉取,否则无法拉取轨迹");
}
order.OrderPullStatus = [CreateOrderPullStatus(config, order)];
return order;
}
private async Task<OrderEntity> BuiltOrder(UpsertBigBagInput input)
{
var order = new OrderEntity
{
AppKey = AppKey!,
ServiceProviderCode = input.ApiCode,
OrderType = TrackOrderType.大包,
OrderNo = input.BagNo,
ThirdPartyOrderNumber = input.OtherNo,
Customer = input.Client,
Channel = input.Channel,
ProductCode = input.Product,
ArrivalCountry = input.Country
};
if (string.IsNullOrWhiteSpace(input.ApiCode))
{
// 未传 apiCode 时保持兼容:不挂拉取配置
return order;
}
var config = await _trackPullConfigRepository
.FirstOrDefaultAsync(x => x.AppKey == AppKey
&& x.ServiceProviderCode == input.ApiCode
&& x.OrderType == TrackOrderType.大包);
if (config == null)
{
throw ProviderServiceActionResult.Exception("创建/更新失败",
"没有适用的大包拉取配置,请先配置轨迹拉取,否则无法拉取轨迹");
}
order.OrderPullStatus = [CreateOrderPullStatus(config, order)];
return order;
}
private async Task<OrderEntity> BuiltOrder(UpsertMasterOrderInput input)
{
var order = new OrderEntity
{
AppKey = AppKey!,
ServiceProviderCode = input.ApiCode,
OrderType = TrackOrderType.小包,
OrderNo = input.MasterNo,
IsTransit = input.IsTransfer,
ArrivalCountry = input.ArrivalCountry,
LeaveCountry = input.LeaveCountry,
};
order.OrderFlights = new List<OrderFlightEntity>();
var config = await _trackPullConfigRepository
.FirstOrDefaultAsync(x => x.AppKey == AppKey
&& x.ServiceProviderCode == input.ApiCode
&& x.OrderType == TrackOrderType.小包);
if (config == null)
{
throw ProviderServiceActionResult.Exception("创建/更新失败",
"没有适用的拉取配置,请先配置轨迹拉取,否则无法拉取轨迹");
}
order.OrderPullStatus = [CreateOrderPullStatus(config, order)];
return order;
}
private static OrderPullStatusEntity CreateOrderPullStatus(TrackPullConfigEntity config, OrderEntity order)
{
var status = new OrderPullStatusEntity
{
ServiceProviderCode = config.ServiceProviderCode,
OrderNo = order.OrderNo,
PullStatus = TrackPullStatus.Init,
StartTrackCode = config.StartTrackCode,
EndTrackCode = config.EndTrackCode,
SilenceBeforeStart = config.SilenceBeforeStart,
SilenceAfterEnd = config.SilenceAfterEnd,
StartTime = GlobalConst.MaxDateTime,
EndTime = GlobalConst.MaxDateTime
};
if (string.IsNullOrWhiteSpace(config.StartTrackCode))
{
status.PullStatus = TrackPullStatus.SilenceBeforeStart;
status.StartTime = DateTime.Now.AddHours(config.SilenceBeforeStart);
}
if (string.IsNullOrWhiteSpace(config.EndTrackCode))
{
status.EndTime = DateTime.Now.AddHours(config.SilenceBeforeStart).AddDays(7);
}
return status;
}
}