using MediatR;
using Microsoft.Extensions.Logging;
using System.Text.Json;
using TakeoutSaaS.Application.App.Subscriptions.Commands;
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 BatchSendReminderCommandHandler(
ISubscriptionRepository subscriptionRepository,
IIdGenerator idGenerator,
ILogger logger)
: IRequestHandler
{
///
public async Task Handle(BatchSendReminderCommand request, CancellationToken cancellationToken)
{
var successCount = 0;
var failures = new List();
// 查询所有订阅及租户信息
var subscriptions = await subscriptionRepository.FindByIdsWithTenantAsync(
request.SubscriptionIds,
cancellationToken);
foreach (var subscriptionId in request.SubscriptionIds)
{
try
{
var item = subscriptions.FirstOrDefault(s => s.Subscription.Id == subscriptionId);
if (item == null)
{
failures.Add(new BatchFailureItem
{
SubscriptionId = subscriptionId,
Reason = "订阅不存在"
});
continue;
}
// 创建通知记录
var notification = new TenantNotification
{
Id = idGenerator.NextId(),
TenantId = item.Subscription.TenantId,
Title = "续费提醒",
Message = request.ReminderContent,
Severity = TenantNotificationSeverity.Warning,
Channel = TenantNotificationChannel.InApp,
SentAt = DateTime.UtcNow,
ReadAt = null,
CreatedAt = DateTime.UtcNow
};
await subscriptionRepository.AddNotificationAsync(notification, cancellationToken);
successCount++;
logger.LogInformation(
"发送续费提醒: SubscriptionId={SubscriptionId}, TenantId={TenantId}, TenantName={TenantName}",
subscriptionId, item.Subscription.TenantId, item.Tenant.Name);
}
catch (Exception ex)
{
logger.LogError(ex, "发送续费提醒失败: SubscriptionId={SubscriptionId}", subscriptionId);
failures.Add(new BatchFailureItem
{
SubscriptionId = subscriptionId,
Reason = $"发送失败: {ex.Message}"
});
}
}
// 记录操作日志
var operationLog = new OperationLog
{
Id = idGenerator.NextId(),
OperationType = "BatchRemind",
TargetType = "Subscription",
TargetIds = JsonSerializer.Serialize(request.SubscriptionIds),
Parameters = JsonSerializer.Serialize(new { request.ReminderContent }),
Result = JsonSerializer.Serialize(new { SuccessCount = successCount, FailureCount = failures.Count }),
Success = failures.Count == 0,
CreatedAt = DateTime.UtcNow
};
await subscriptionRepository.AddOperationLogAsync(operationLog, cancellationToken);
// 保存所有更改
await subscriptionRepository.SaveChangesAsync(cancellationToken);
return new BatchSendReminderResult
{
SuccessCount = successCount,
FailureCount = failures.Count,
Failures = failures
};
}
}