feat: 增加分页排序与FluentValidation
This commit is contained in:
@@ -81,4 +81,9 @@ public sealed class DeliveryOrderDto
|
||||
/// 事件列表。
|
||||
/// </summary>
|
||||
public IReadOnlyList<DeliveryEventDto> Events { get; init; } = Array.Empty<DeliveryEventDto>();
|
||||
|
||||
/// <summary>
|
||||
/// 创建时间。
|
||||
/// </summary>
|
||||
public DateTime CreatedAt { get; init; }
|
||||
}
|
||||
|
||||
@@ -56,6 +56,7 @@ public sealed class CreateDeliveryOrderCommandHandler(IDeliveryRepository delive
|
||||
PickedUpAt = deliveryOrder.PickedUpAt,
|
||||
DeliveredAt = deliveryOrder.DeliveredAt,
|
||||
FailureReason = deliveryOrder.FailureReason,
|
||||
CreatedAt = deliveryOrder.CreatedAt,
|
||||
Events = events.Select(x => new DeliveryEventDto
|
||||
{
|
||||
Id = x.Id,
|
||||
|
||||
@@ -47,6 +47,7 @@ public sealed class GetDeliveryOrderByIdQueryHandler(
|
||||
PickedUpAt = deliveryOrder.PickedUpAt,
|
||||
DeliveredAt = deliveryOrder.DeliveredAt,
|
||||
FailureReason = deliveryOrder.FailureReason,
|
||||
CreatedAt = deliveryOrder.CreatedAt,
|
||||
Events = events.Select(x => new DeliveryEventDto
|
||||
{
|
||||
Id = x.Id,
|
||||
|
||||
@@ -23,7 +23,13 @@ public sealed class SearchDeliveryOrdersQueryHandler(
|
||||
var tenantId = _tenantProvider.GetCurrentTenantId();
|
||||
var orders = await _deliveryRepository.SearchAsync(tenantId, request.Status, request.OrderId, cancellationToken);
|
||||
|
||||
return orders.Select(order => new DeliveryOrderDto
|
||||
var sorted = ApplySorting(orders, request.SortBy, request.SortDescending);
|
||||
var paged = sorted
|
||||
.Skip((request.Page - 1) * request.PageSize)
|
||||
.Take(request.PageSize)
|
||||
.ToList();
|
||||
|
||||
return paged.Select(order => new DeliveryOrderDto
|
||||
{
|
||||
Id = order.Id,
|
||||
TenantId = order.TenantId,
|
||||
@@ -37,7 +43,21 @@ public sealed class SearchDeliveryOrdersQueryHandler(
|
||||
DispatchedAt = order.DispatchedAt,
|
||||
PickedUpAt = order.PickedUpAt,
|
||||
DeliveredAt = order.DeliveredAt,
|
||||
FailureReason = order.FailureReason
|
||||
FailureReason = order.FailureReason,
|
||||
CreatedAt = order.CreatedAt
|
||||
}).ToList();
|
||||
}
|
||||
|
||||
private static IOrderedEnumerable<Domain.Deliveries.Entities.DeliveryOrder> ApplySorting(
|
||||
IReadOnlyCollection<Domain.Deliveries.Entities.DeliveryOrder> orders,
|
||||
string? sortBy,
|
||||
bool sortDescending)
|
||||
{
|
||||
return sortBy?.ToLowerInvariant() switch
|
||||
{
|
||||
"status" => sortDescending ? orders.OrderByDescending(x => x.Status) : orders.OrderBy(x => x.Status),
|
||||
"provider" => sortDescending ? orders.OrderByDescending(x => x.Provider) : orders.OrderBy(x => x.Provider),
|
||||
_ => sortDescending ? orders.OrderByDescending(x => x.CreatedAt) : orders.OrderBy(x => x.CreatedAt)
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -66,6 +66,7 @@ public sealed class UpdateDeliveryOrderCommandHandler(
|
||||
PickedUpAt = deliveryOrder.PickedUpAt,
|
||||
DeliveredAt = deliveryOrder.DeliveredAt,
|
||||
FailureReason = deliveryOrder.FailureReason,
|
||||
CreatedAt = deliveryOrder.CreatedAt,
|
||||
Events = events.Select(x => new DeliveryEventDto
|
||||
{
|
||||
Id = x.Id,
|
||||
|
||||
@@ -18,4 +18,24 @@ public sealed class SearchDeliveryOrdersQuery : IRequest<IReadOnlyList<DeliveryO
|
||||
/// 配送状态。
|
||||
/// </summary>
|
||||
public DeliveryStatus? Status { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// 页码。
|
||||
/// </summary>
|
||||
public int Page { get; init; } = 1;
|
||||
|
||||
/// <summary>
|
||||
/// 每页条数。
|
||||
/// </summary>
|
||||
public int PageSize { get; init; } = 20;
|
||||
|
||||
/// <summary>
|
||||
/// 排序字段(createdAt/status/provider)。
|
||||
/// </summary>
|
||||
public string? SortBy { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// 是否倒序。
|
||||
/// </summary>
|
||||
public bool SortDescending { get; init; } = true;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
using FluentValidation;
|
||||
using TakeoutSaaS.Application.App.Deliveries.Commands;
|
||||
|
||||
namespace TakeoutSaaS.Application.App.Deliveries.Validators;
|
||||
|
||||
/// <summary>
|
||||
/// 创建配送单命令验证器。
|
||||
/// </summary>
|
||||
public sealed class CreateDeliveryOrderCommandValidator : AbstractValidator<CreateDeliveryOrderCommand>
|
||||
{
|
||||
/// <summary>
|
||||
/// 初始化验证规则。
|
||||
/// </summary>
|
||||
public CreateDeliveryOrderCommandValidator()
|
||||
{
|
||||
RuleFor(x => x.OrderId).GreaterThan(0);
|
||||
RuleFor(x => x.ProviderOrderId).MaximumLength(64);
|
||||
RuleFor(x => x.CourierName).MaximumLength(64);
|
||||
RuleFor(x => x.CourierPhone).MaximumLength(32);
|
||||
RuleFor(x => x.FailureReason).MaximumLength(256);
|
||||
RuleFor(x => x.DeliveryFee).GreaterThanOrEqualTo(0).When(x => x.DeliveryFee.HasValue);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
using FluentValidation;
|
||||
using TakeoutSaaS.Application.App.Deliveries.Queries;
|
||||
|
||||
namespace TakeoutSaaS.Application.App.Deliveries.Validators;
|
||||
|
||||
/// <summary>
|
||||
/// 配送单列表查询验证器。
|
||||
/// </summary>
|
||||
public sealed class SearchDeliveryOrdersQueryValidator : AbstractValidator<SearchDeliveryOrdersQuery>
|
||||
{
|
||||
/// <summary>
|
||||
/// 初始化验证规则。
|
||||
/// </summary>
|
||||
public SearchDeliveryOrdersQueryValidator()
|
||||
{
|
||||
RuleFor(x => x.Page).GreaterThan(0);
|
||||
RuleFor(x => x.PageSize).InclusiveBetween(1, 200);
|
||||
RuleFor(x => x.SortBy).MaximumLength(64);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
using FluentValidation;
|
||||
using TakeoutSaaS.Application.App.Deliveries.Commands;
|
||||
|
||||
namespace TakeoutSaaS.Application.App.Deliveries.Validators;
|
||||
|
||||
/// <summary>
|
||||
/// 更新配送单命令验证器。
|
||||
/// </summary>
|
||||
public sealed class UpdateDeliveryOrderCommandValidator : AbstractValidator<UpdateDeliveryOrderCommand>
|
||||
{
|
||||
/// <summary>
|
||||
/// 初始化验证规则。
|
||||
/// </summary>
|
||||
public UpdateDeliveryOrderCommandValidator()
|
||||
{
|
||||
RuleFor(x => x.DeliveryOrderId).GreaterThan(0);
|
||||
RuleFor(x => x.OrderId).GreaterThan(0);
|
||||
RuleFor(x => x.ProviderOrderId).MaximumLength(64);
|
||||
RuleFor(x => x.CourierName).MaximumLength(64);
|
||||
RuleFor(x => x.CourierPhone).MaximumLength(32);
|
||||
RuleFor(x => x.FailureReason).MaximumLength(256);
|
||||
RuleFor(x => x.DeliveryFee).GreaterThanOrEqualTo(0).When(x => x.DeliveryFee.HasValue);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user