74 lines
2.6 KiB
C#
74 lines
2.6 KiB
C#
using MediatR;
|
|
using TakeoutSaaS.Application.App.Billings.Commands;
|
|
using TakeoutSaaS.Application.App.Billings.Dto;
|
|
using TakeoutSaaS.Domain.Tenants.Repositories;
|
|
using TakeoutSaaS.Shared.Abstractions.Constants;
|
|
using TakeoutSaaS.Shared.Abstractions.Exceptions;
|
|
using TakeoutSaaS.Shared.Abstractions.Security;
|
|
|
|
namespace TakeoutSaaS.Application.App.Billings.Handlers;
|
|
|
|
/// <summary>
|
|
/// 审核支付命令处理器。
|
|
/// </summary>
|
|
public sealed class VerifyPaymentCommandHandler(
|
|
ITenantPaymentRepository paymentRepository,
|
|
ITenantBillingRepository billingRepository,
|
|
ICurrentUserAccessor currentUserAccessor)
|
|
: IRequestHandler<VerifyPaymentCommand, PaymentRecordDto>
|
|
{
|
|
/// <inheritdoc />
|
|
public async Task<PaymentRecordDto> Handle(VerifyPaymentCommand request, CancellationToken cancellationToken)
|
|
{
|
|
// 1. 校验操作者身份
|
|
if (!currentUserAccessor.IsAuthenticated || currentUserAccessor.UserId <= 0)
|
|
{
|
|
throw new BusinessException(ErrorCodes.Unauthorized, "未登录或无效的操作者身份");
|
|
}
|
|
|
|
// 2. 查询支付记录
|
|
var payment = await paymentRepository.FindByIdAsync(request.PaymentId, cancellationToken);
|
|
if (payment is null)
|
|
{
|
|
throw new BusinessException(ErrorCodes.NotFound, "支付记录不存在");
|
|
}
|
|
|
|
// 3. 查询关联账单
|
|
var billing = await billingRepository.FindByIdAsync(payment.BillingStatementId, cancellationToken);
|
|
if (billing is null)
|
|
{
|
|
throw new BusinessException(ErrorCodes.NotFound, "关联账单不存在");
|
|
}
|
|
|
|
// 4. 归一化审核备注
|
|
var normalizedNotes = string.IsNullOrWhiteSpace(request.Notes) ? null : request.Notes.Trim();
|
|
|
|
// 5. 根据审核结果更新支付与账单状态
|
|
if (request.Approved)
|
|
{
|
|
payment.Verify(currentUserAccessor.UserId);
|
|
payment.Notes = normalizedNotes;
|
|
|
|
billing.MarkAsPaid(payment.Amount, payment.TransactionNo ?? string.Empty);
|
|
}
|
|
else
|
|
{
|
|
payment.Reject(currentUserAccessor.UserId, normalizedNotes ?? string.Empty);
|
|
payment.Notes = normalizedNotes;
|
|
}
|
|
|
|
// 6. 持久化更新状态
|
|
await paymentRepository.UpdateAsync(payment, cancellationToken);
|
|
if (request.Approved)
|
|
{
|
|
await billingRepository.UpdateAsync(billing, cancellationToken);
|
|
}
|
|
|
|
// 7. 保存数据库更改
|
|
await paymentRepository.SaveChangesAsync(cancellationToken);
|
|
|
|
// 8. 返回 DTO
|
|
return payment.ToPaymentRecordDto();
|
|
}
|
|
}
|