feat(order): add all-orders APIs and query workflow
All checks were successful
Build and Deploy TenantApi + SkuWorker / build-and-deploy (push) Successful in 1m51s
All checks were successful
Build and Deploy TenantApi + SkuWorker / build-and-deploy (push) Successful in 1m51s
This commit is contained in:
@@ -0,0 +1,81 @@
|
||||
using MediatR;
|
||||
using TakeoutSaaS.Application.App.Orders.Dto;
|
||||
using TakeoutSaaS.Application.App.Orders.Queries;
|
||||
using TakeoutSaaS.Domain.Orders.Entities;
|
||||
using TakeoutSaaS.Domain.Orders.Repositories;
|
||||
using TakeoutSaaS.Shared.Abstractions.Tenancy;
|
||||
|
||||
namespace TakeoutSaaS.Application.App.Orders.Handlers;
|
||||
|
||||
/// <summary>
|
||||
/// 全部订单统计查询处理器。
|
||||
/// </summary>
|
||||
public sealed class GetOrderAllStatsQueryHandler(
|
||||
IOrderRepository orderRepository,
|
||||
ITenantProvider tenantProvider)
|
||||
: IRequestHandler<GetOrderAllStatsQuery, OrderAllStatsDto>
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public async Task<OrderAllStatsDto> Handle(GetOrderAllStatsQuery request, CancellationToken cancellationToken)
|
||||
{
|
||||
var tenantId = tenantProvider.GetCurrentTenantId();
|
||||
|
||||
var orders = (await orderRepository.SearchAllOrdersAsync(
|
||||
tenantId,
|
||||
request.StoreId,
|
||||
request.StartAt,
|
||||
request.EndAt,
|
||||
request.Status,
|
||||
request.DeliveryType,
|
||||
request.PaymentMethod,
|
||||
request.Keyword,
|
||||
cancellationToken))
|
||||
.ToList();
|
||||
|
||||
var refundedIds = await LoadRefundedOrderIdsAsync(orders, tenantId, cancellationToken);
|
||||
if (request.RefundedOnly)
|
||||
{
|
||||
orders = orders.Where(order => refundedIds.Contains(order.Id)).ToList();
|
||||
}
|
||||
|
||||
var totalOrders = orders.Count;
|
||||
if (totalOrders == 0)
|
||||
{
|
||||
return new OrderAllStatsDto();
|
||||
}
|
||||
|
||||
var totalAmount = orders.Sum(ResolveDisplayAmount);
|
||||
var averageAmount = decimal.Round(totalAmount / totalOrders, 2, MidpointRounding.AwayFromZero);
|
||||
var refundCount = request.RefundedOnly
|
||||
? totalOrders
|
||||
: orders.Count(order => refundedIds.Contains(order.Id));
|
||||
|
||||
return new OrderAllStatsDto
|
||||
{
|
||||
TotalOrders = totalOrders,
|
||||
TotalAmount = totalAmount,
|
||||
AverageAmount = averageAmount,
|
||||
RefundCount = refundCount
|
||||
};
|
||||
}
|
||||
|
||||
private async Task<HashSet<long>> LoadRefundedOrderIdsAsync(
|
||||
IReadOnlyCollection<Order> orders,
|
||||
long tenantId,
|
||||
CancellationToken cancellationToken)
|
||||
{
|
||||
var orderIds = orders.Select(order => order.Id).ToList();
|
||||
if (orderIds.Count == 0)
|
||||
{
|
||||
return [];
|
||||
}
|
||||
|
||||
var refunded = await orderRepository.GetRefundedOrderIdsAsync(orderIds, tenantId, cancellationToken);
|
||||
return refunded.ToHashSet();
|
||||
}
|
||||
|
||||
private static decimal ResolveDisplayAmount(Order order)
|
||||
{
|
||||
return order.PaidAmount > 0 ? order.PaidAmount : order.PayableAmount;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user