105 lines
3.9 KiB
C#
105 lines
3.9 KiB
C#
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;
|
|
|
|
/// <summary>
|
|
/// 批量发送续费提醒命令处理器。
|
|
/// </summary>
|
|
public sealed class BatchSendReminderCommandHandler(
|
|
ISubscriptionRepository subscriptionRepository,
|
|
IIdGenerator idGenerator,
|
|
ILogger<BatchSendReminderCommandHandler> logger)
|
|
: IRequestHandler<BatchSendReminderCommand, BatchSendReminderResult>
|
|
{
|
|
/// <inheritdoc />
|
|
public async Task<BatchSendReminderResult> Handle(BatchSendReminderCommand request, CancellationToken cancellationToken)
|
|
{
|
|
var successCount = 0;
|
|
var failures = new List<BatchFailureItem>();
|
|
|
|
// 查询所有订阅及租户信息
|
|
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
|
|
};
|
|
}
|
|
}
|