- 新增 AdminRolesController 实现角色 CRUD 和权限管理 - 新增 BillingsController 实现账单查询功能 - 新增 SubscriptionsController 实现订阅管理功能 - 新增 TenantPackagesController 实现套餐管理功能 - 新增租户详情、配额使用、账单列表等查询功能 - 新增 TenantPackage、TenantSubscription 等领域实体 - 新增相关枚举:SubscriptionStatus、TenantPackageType 等 - 更新 appsettings 配置文件 - 更新权限授权策略提供者 Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
93 lines
3.0 KiB
C#
93 lines
3.0 KiB
C#
using MediatR;
|
|
using TakeoutSaaS.Application.App.Billings.Commands;
|
|
using TakeoutSaaS.Application.App.Billings.Contracts;
|
|
using TakeoutSaaS.Domain.Billings.Entities;
|
|
using TakeoutSaaS.Domain.Billings.Enums;
|
|
using TakeoutSaaS.Domain.Billings.Repositories;
|
|
using TakeoutSaaS.Shared.Abstractions.Security;
|
|
|
|
namespace TakeoutSaaS.Application.App.Billings.Handlers;
|
|
|
|
/// <summary>
|
|
/// 确认收款命令处理器。
|
|
/// </summary>
|
|
public sealed class ConfirmPaymentCommandHandler(
|
|
IBillingRepository billingRepository,
|
|
ICurrentUserAccessor currentUserAccessor)
|
|
: IRequestHandler<ConfirmPaymentCommand, PaymentRecordDto?>
|
|
{
|
|
/// <inheritdoc />
|
|
public async Task<PaymentRecordDto?> Handle(
|
|
ConfirmPaymentCommand request,
|
|
CancellationToken cancellationToken)
|
|
{
|
|
// 1. 获取账单(带跟踪)
|
|
var billing = await billingRepository.GetByIdForUpdateAsync(request.BillingId, cancellationToken);
|
|
|
|
// 2. 如果不存在,返回 null
|
|
if (billing is null)
|
|
{
|
|
return null;
|
|
}
|
|
|
|
// 3. 获取当前用户 ID
|
|
var currentUserId = currentUserAccessor.UserId;
|
|
var now = DateTime.UtcNow;
|
|
|
|
// 4. 创建支付记录(已审核通过状态)
|
|
var payment = new TenantPayment
|
|
{
|
|
TenantId = billing.TenantId,
|
|
BillingStatementId = billing.Id,
|
|
Amount = request.Amount,
|
|
Method = request.Method,
|
|
Status = TenantPaymentStatus.Success,
|
|
TransactionNo = request.TransactionNo,
|
|
ProofUrl = request.ProofUrl,
|
|
Notes = request.Notes,
|
|
PaidAt = now,
|
|
VerifiedBy = currentUserId,
|
|
VerifiedAt = now,
|
|
CreatedAt = now,
|
|
CreatedBy = currentUserId
|
|
};
|
|
|
|
// 5. 添加支付记录
|
|
await billingRepository.AddPaymentAsync(payment, cancellationToken);
|
|
|
|
// 6. 更新账单已付金额
|
|
billing.AmountPaid += request.Amount;
|
|
|
|
// 7. 如果已付金额 >= 应付金额,更新账单状态为已支付
|
|
if (billing.AmountPaid >= billing.AmountDue)
|
|
{
|
|
billing.Status = TenantBillingStatus.Paid;
|
|
}
|
|
|
|
// 8. 更新账单时间戳
|
|
billing.UpdatedAt = now;
|
|
|
|
// 9. 保存变更
|
|
await billingRepository.SaveChangesAsync(cancellationToken);
|
|
|
|
// 10. 返回支付记录 DTO
|
|
return new PaymentRecordDto
|
|
{
|
|
Id = payment.Id,
|
|
BillingStatementId = payment.BillingStatementId,
|
|
Amount = payment.Amount,
|
|
Method = (int)payment.Method,
|
|
Status = (int)payment.Status,
|
|
TransactionNo = payment.TransactionNo,
|
|
ProofUrl = payment.ProofUrl,
|
|
PaidAt = payment.PaidAt,
|
|
Notes = payment.Notes,
|
|
VerifiedBy = payment.VerifiedBy,
|
|
VerifiedAt = payment.VerifiedAt,
|
|
RefundReason = payment.RefundReason,
|
|
RefundedAt = payment.RefundedAt,
|
|
CreatedAt = payment.CreatedAt
|
|
};
|
|
}
|
|
}
|