fix: 完善订单支付校验规则

This commit is contained in:
2025-12-02 12:17:02 +08:00
parent 5332c87d9d
commit 5d1dd54c80
4 changed files with 112 additions and 0 deletions

View File

@@ -1,5 +1,7 @@
using FluentValidation;
using TakeoutSaaS.Application.App.Orders.Commands;
using TakeoutSaaS.Domain.Orders.Enums;
using TakeoutSaaS.Domain.Payments.Enums;
namespace TakeoutSaaS.Application.App.Orders.Validators;
@@ -25,6 +27,37 @@ public sealed class CreateOrderCommandValidator : AbstractValidator<CreateOrderC
RuleFor(x => x.DiscountAmount).GreaterThanOrEqualTo(0);
RuleFor(x => x.PayableAmount).GreaterThanOrEqualTo(0);
RuleFor(x => x.PaidAmount).GreaterThanOrEqualTo(0);
RuleFor(x => x.PayableAmount)
.Must((cmd, payable) => payable == cmd.ItemsAmount - cmd.DiscountAmount)
.WithMessage("应付金额必须等于商品金额减去优惠金额");
RuleFor(x => x.PaidAmount)
.LessThanOrEqualTo(x => x.PayableAmount)
.WithMessage("实付金额不得超过应付金额");
RuleFor(x => x.PaymentStatus)
.Must(status => status is PaymentStatus.Unpaid or PaymentStatus.Paying or PaymentStatus.Paid or PaymentStatus.Failed or PaymentStatus.Refunded)
.WithMessage("支付状态不合法");
When(x => x.PaymentStatus == PaymentStatus.Paid, () =>
{
RuleFor(x => x.PaidAt).NotNull().WithMessage("支付成功必须包含支付时间");
RuleFor(x => x.PaidAmount).GreaterThan(0).WithMessage("支付成功时实付金额必须大于 0");
});
When(x => x.PaymentStatus != PaymentStatus.Paid, () =>
{
RuleFor(x => x.PaidAt).Must(paidAt => paidAt == null).WithMessage("非支付成功状态不应包含支付时间");
});
When(x => x.PaymentStatus == PaymentStatus.Refunded, () =>
{
RuleFor(x => x.PaidAmount).GreaterThanOrEqualTo(0).WithMessage("退款状态下实付金额需合法");
});
When(x => x.Status == OrderStatus.Cancelled, () =>
{
RuleFor(x => x.CancelReason).NotEmpty().WithMessage("取消订单必须提供取消原因");
});
When(x => x.Status != OrderStatus.Cancelled, () =>
{
RuleFor(x => x.CancelReason).Must(reason => string.IsNullOrWhiteSpace(reason)).WithMessage("非取消状态不应包含取消原因");
});
RuleFor(x => x.Items)
.NotEmpty()

View File

@@ -1,5 +1,7 @@
using FluentValidation;
using TakeoutSaaS.Application.App.Orders.Commands;
using TakeoutSaaS.Domain.Orders.Enums;
using TakeoutSaaS.Domain.Payments.Enums;
namespace TakeoutSaaS.Application.App.Orders.Validators;
@@ -26,5 +28,36 @@ public sealed class UpdateOrderCommandValidator : AbstractValidator<UpdateOrderC
RuleFor(x => x.DiscountAmount).GreaterThanOrEqualTo(0);
RuleFor(x => x.PayableAmount).GreaterThanOrEqualTo(0);
RuleFor(x => x.PaidAmount).GreaterThanOrEqualTo(0);
RuleFor(x => x.PayableAmount)
.Must((cmd, payable) => payable == cmd.ItemsAmount - cmd.DiscountAmount)
.WithMessage("应付金额必须等于商品金额减去优惠金额");
RuleFor(x => x.PaidAmount)
.LessThanOrEqualTo(x => x.PayableAmount)
.WithMessage("实付金额不得超过应付金额");
RuleFor(x => x.PaymentStatus)
.Must(status => status is PaymentStatus.Unpaid or PaymentStatus.Paying or PaymentStatus.Paid or PaymentStatus.Failed or PaymentStatus.Refunded)
.WithMessage("支付状态不合法");
When(x => x.PaymentStatus == PaymentStatus.Paid, () =>
{
RuleFor(x => x.PaidAt).NotNull().WithMessage("支付成功必须包含支付时间");
RuleFor(x => x.PaidAmount).GreaterThan(0).WithMessage("支付成功时实付金额必须大于 0");
});
When(x => x.PaymentStatus != PaymentStatus.Paid, () =>
{
RuleFor(x => x.PaidAt).Must(paidAt => paidAt == null).WithMessage("非支付成功状态不应包含支付时间");
});
When(x => x.PaymentStatus == PaymentStatus.Refunded, () =>
{
RuleFor(x => x.PaidAmount).GreaterThanOrEqualTo(0).WithMessage("退款状态下实付金额需合法");
});
When(x => x.Status == OrderStatus.Cancelled, () =>
{
RuleFor(x => x.CancelReason).NotEmpty().WithMessage("取消订单必须提供取消原因");
});
When(x => x.Status != OrderStatus.Cancelled, () =>
{
RuleFor(x => x.CancelReason).Must(reason => string.IsNullOrWhiteSpace(reason)).WithMessage("非取消状态不应包含取消原因");
});
}
}

View File

@@ -1,5 +1,6 @@
using FluentValidation;
using TakeoutSaaS.Application.App.Payments.Commands;
using TakeoutSaaS.Domain.Payments.Enums;
namespace TakeoutSaaS.Application.App.Payments.Validators;
@@ -15,8 +16,30 @@ public sealed class CreatePaymentCommandValidator : AbstractValidator<CreatePaym
{
RuleFor(x => x.OrderId).GreaterThan(0);
RuleFor(x => x.Amount).GreaterThan(0);
RuleFor(x => x.Method)
.Must(method => method != PaymentMethod.Unknown)
.WithMessage("支付方式不可为空");
RuleFor(x => x.TradeNo).MaximumLength(64);
RuleFor(x => x.ChannelTransactionId).MaximumLength(64);
RuleFor(x => x.Remark).MaximumLength(256);
RuleFor(x => x.Status)
.Must(status => status is PaymentStatus.Unpaid or PaymentStatus.Paying or PaymentStatus.Paid or PaymentStatus.Failed or PaymentStatus.Refunded)
.WithMessage("支付状态不合法");
When(x => x.Status == PaymentStatus.Paid, () =>
{
RuleFor(x => x.PaidAt).NotNull().WithMessage("支付成功必须包含支付时间");
});
When(x => x.Status != PaymentStatus.Paid, () =>
{
RuleFor(x => x.PaidAt).Must(paidAt => paidAt == null).WithMessage("非支付成功状态不应包含支付时间");
});
When(x => x.Method is PaymentMethod.Cash or PaymentMethod.Card or PaymentMethod.Balance, () =>
{
RuleFor(x => x.Status)
.Must(status => status is not PaymentStatus.Paying)
.WithMessage("线下/余额支付不允许处于 Paying 状态");
});
}
}

View File

@@ -1,5 +1,6 @@
using FluentValidation;
using TakeoutSaaS.Application.App.Payments.Commands;
using TakeoutSaaS.Domain.Payments.Enums;
namespace TakeoutSaaS.Application.App.Payments.Validators;
@@ -16,8 +17,30 @@ public sealed class UpdatePaymentCommandValidator : AbstractValidator<UpdatePaym
RuleFor(x => x.PaymentId).GreaterThan(0);
RuleFor(x => x.OrderId).GreaterThan(0);
RuleFor(x => x.Amount).GreaterThan(0);
RuleFor(x => x.Method)
.Must(method => method != PaymentMethod.Unknown)
.WithMessage("支付方式不可为空");
RuleFor(x => x.TradeNo).MaximumLength(64);
RuleFor(x => x.ChannelTransactionId).MaximumLength(64);
RuleFor(x => x.Remark).MaximumLength(256);
RuleFor(x => x.Status)
.Must(status => status is PaymentStatus.Unpaid or PaymentStatus.Paying or PaymentStatus.Paid or PaymentStatus.Failed or PaymentStatus.Refunded)
.WithMessage("支付状态不合法");
When(x => x.Status == PaymentStatus.Paid, () =>
{
RuleFor(x => x.PaidAt).NotNull().WithMessage("支付成功必须包含支付时间");
});
When(x => x.Status != PaymentStatus.Paid, () =>
{
RuleFor(x => x.PaidAt).Must(paidAt => paidAt == null).WithMessage("非支付成功状态不应包含支付时间");
});
When(x => x.Method is PaymentMethod.Cash or PaymentMethod.Card or PaymentMethod.Balance, () =>
{
RuleFor(x => x.Status)
.Must(status => status is not PaymentStatus.Paying)
.WithMessage("线下/余额支付不允许处于 Paying 状态");
});
}
}