using MediatR;
using TakeoutSaaS.Application.App.Subscriptions.Commands;
using TakeoutSaaS.Application.App.Subscriptions.Dto;
using TakeoutSaaS.Application.App.Subscriptions.Queries;
using TakeoutSaaS.Domain.Tenants.Entities;
using TakeoutSaaS.Domain.Tenants.Enums;
using TakeoutSaaS.Domain.Tenants.Repositories;
using TakeoutSaaS.Shared.Abstractions.Ids;
namespace TakeoutSaaS.Application.App.Subscriptions.Handlers;
///
/// 延期订阅命令处理器。
///
public sealed class ExtendSubscriptionCommandHandler(
ISubscriptionRepository subscriptionRepository,
IIdGenerator idGenerator,
IMediator mediator)
: IRequestHandler
{
///
public async Task Handle(ExtendSubscriptionCommand request, CancellationToken cancellationToken)
{
// 1. 查询订阅
var subscription = await subscriptionRepository.FindByIdAsync(request.SubscriptionId, cancellationToken);
if (subscription == null)
{
return null;
}
// 2. 计算新的到期时间(从当前到期时间延长)
var originalEffectiveTo = subscription.EffectiveTo;
subscription.EffectiveTo = subscription.EffectiveTo.AddMonths(request.DurationMonths);
// 3. 更新备注
if (!string.IsNullOrWhiteSpace(request.Notes))
{
subscription.Notes = request.Notes;
}
// 4. 记录变更历史(使用 Renew 类型表示延期)
var history = new TenantSubscriptionHistory
{
Id = idGenerator.NextId(),
TenantId = subscription.TenantId,
TenantSubscriptionId = subscription.Id,
FromPackageId = subscription.TenantPackageId,
ToPackageId = subscription.TenantPackageId,
ChangeType = SubscriptionChangeType.Renew,
EffectiveFrom = originalEffectiveTo,
EffectiveTo = subscription.EffectiveTo,
Amount = null,
Currency = null,
Notes = request.Notes ?? $"延期 {request.DurationMonths} 个月"
};
await subscriptionRepository.AddHistoryAsync(history, cancellationToken);
// 5. 保存更改
await subscriptionRepository.UpdateAsync(subscription, cancellationToken);
await subscriptionRepository.SaveChangesAsync(cancellationToken);
// 6. 返回更新后的详情
return await mediator.Send(new GetSubscriptionDetailQuery { SubscriptionId = subscription.Id }, cancellationToken);
}
}