Files
TakeoutSaaS.AdminApi/src/Application/TakeoutSaaS.Application/App/Deliveries/Handlers/CreateDeliveryOrderCommandHandler.cs

87 lines
3.4 KiB
C#

using MediatR;
using Microsoft.Extensions.Logging;
using TakeoutSaaS.Application.App.Deliveries.Commands;
using TakeoutSaaS.Application.App.Deliveries.Dto;
using TakeoutSaaS.Domain.Deliveries.Entities;
using TakeoutSaaS.Domain.Deliveries.Repositories;
using TakeoutSaaS.Domain.Orders.Repositories;
using TakeoutSaaS.Shared.Abstractions.Constants;
using TakeoutSaaS.Shared.Abstractions.Exceptions;
namespace TakeoutSaaS.Application.App.Deliveries.Handlers;
/// <summary>
/// 创建配送单命令处理器。
/// </summary>
public sealed class CreateDeliveryOrderCommandHandler(
IDeliveryRepository deliveryRepository,
IOrderRepository orderRepository,
ILogger<CreateDeliveryOrderCommandHandler> logger)
: IRequestHandler<CreateDeliveryOrderCommand, DeliveryOrderDto>
{
/// <inheritdoc />
public async Task<DeliveryOrderDto> Handle(CreateDeliveryOrderCommand request, CancellationToken cancellationToken)
{
// 1. 查询订单以确定租户
var order = await orderRepository.FindByIdAsync(request.OrderId, cancellationToken);
if (order is null)
{
throw new BusinessException(ErrorCodes.NotFound, "订单不存在");
}
// 2. (空行后) 构建配送单实体并写入租户
var deliveryOrder = new DeliveryOrder
{
TenantId = order.TenantId,
OrderId = request.OrderId,
Provider = request.Provider,
ProviderOrderId = request.ProviderOrderId?.Trim(),
Status = request.Status,
DeliveryFee = request.DeliveryFee,
CourierName = request.CourierName?.Trim(),
CourierPhone = request.CourierPhone?.Trim(),
DispatchedAt = request.DispatchedAt,
PickedUpAt = request.PickedUpAt,
DeliveredAt = request.DeliveredAt,
FailureReason = request.FailureReason?.Trim()
};
// 3. (空行后) 持久化配送单
await deliveryRepository.AddDeliveryOrderAsync(deliveryOrder, cancellationToken);
await deliveryRepository.SaveChangesAsync(cancellationToken);
// 4. (空行后) 记录日志
logger.LogInformation("创建配送单 {DeliveryOrderId} 对应订单 {OrderId}", deliveryOrder.Id, deliveryOrder.OrderId);
// 5. (空行后) 映射 DTO 返回
return MapToDto(deliveryOrder, []);
}
private static DeliveryOrderDto MapToDto(DeliveryOrder deliveryOrder, IReadOnlyList<DeliveryEvent> events) => new()
{
Id = deliveryOrder.Id,
TenantId = deliveryOrder.TenantId,
OrderId = deliveryOrder.OrderId,
Provider = deliveryOrder.Provider,
ProviderOrderId = deliveryOrder.ProviderOrderId,
Status = deliveryOrder.Status,
DeliveryFee = deliveryOrder.DeliveryFee,
CourierName = deliveryOrder.CourierName,
CourierPhone = deliveryOrder.CourierPhone,
DispatchedAt = deliveryOrder.DispatchedAt,
PickedUpAt = deliveryOrder.PickedUpAt,
DeliveredAt = deliveryOrder.DeliveredAt,
FailureReason = deliveryOrder.FailureReason,
CreatedAt = deliveryOrder.CreatedAt,
Events = events.Select(x => new DeliveryEventDto
{
Id = x.Id,
DeliveryOrderId = x.DeliveryOrderId,
EventType = x.EventType,
Message = x.Message,
OccurredAt = x.OccurredAt,
Payload = x.Payload
}).ToList()
};
}