refactor: 订阅任务按租户上下文执行
This commit is contained in:
@@ -2,7 +2,9 @@ using MediatR;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.Extensions.Options;
|
||||
using TakeoutSaaS.Application.App.Subscriptions.Commands;
|
||||
using TakeoutSaaS.Domain.Tenants.Repositories;
|
||||
using TakeoutSaaS.Module.Scheduler.Options;
|
||||
using TakeoutSaaS.Shared.Abstractions.Tenancy;
|
||||
|
||||
namespace TakeoutSaaS.Module.Scheduler.Jobs;
|
||||
|
||||
@@ -11,6 +13,8 @@ namespace TakeoutSaaS.Module.Scheduler.Jobs;
|
||||
/// </summary>
|
||||
public sealed class SubscriptionAutoRenewalJob(
|
||||
IMediator mediator,
|
||||
ITenantRepository tenantRepository,
|
||||
ITenantContextAccessor tenantContextAccessor,
|
||||
IOptionsMonitor<SubscriptionAutomationOptions> optionsMonitor,
|
||||
ILogger<SubscriptionAutoRenewalJob> logger)
|
||||
{
|
||||
@@ -19,18 +23,48 @@ public sealed class SubscriptionAutoRenewalJob(
|
||||
/// </summary>
|
||||
public async Task ExecuteAsync()
|
||||
{
|
||||
// 1. 读取配置并执行自动续费
|
||||
// 1. 读取配置
|
||||
var options = optionsMonitor.CurrentValue;
|
||||
var result = await mediator.Send(new ProcessAutoRenewalCommand
|
||||
{
|
||||
RenewalDaysBeforeExpiry = options.AutoRenewalDaysBeforeExpiry
|
||||
});
|
||||
|
||||
// 2. 记录执行结果
|
||||
// 2. (空行后) 获取需要处理的租户列表(排除系统租户)
|
||||
var tenants = await tenantRepository.SearchAsync(null, null, CancellationToken.None);
|
||||
var targets = tenants.Where(x => x.Id > 0).ToList();
|
||||
|
||||
// 3. (空行后) 按租户逐个执行自动续费
|
||||
var candidateCount = 0;
|
||||
var createdBillCount = 0;
|
||||
var previousContext = tenantContextAccessor.Current;
|
||||
try
|
||||
{
|
||||
foreach (var tenant in targets)
|
||||
{
|
||||
tenantContextAccessor.Current = new TenantContext(tenant.Id, tenant.Code, "scheduler");
|
||||
try
|
||||
{
|
||||
var result = await mediator.Send(new ProcessAutoRenewalCommand
|
||||
{
|
||||
RenewalDaysBeforeExpiry = options.AutoRenewalDaysBeforeExpiry
|
||||
});
|
||||
|
||||
candidateCount += result.CandidateCount;
|
||||
createdBillCount += result.CreatedBillCount;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
logger.LogError(ex, "定时任务:自动续费执行失败 TenantId={TenantId}", tenant.Id);
|
||||
}
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
tenantContextAccessor.Current = previousContext;
|
||||
}
|
||||
|
||||
// 4. (空行后) 记录执行结果
|
||||
logger.LogInformation(
|
||||
"定时任务:自动续费处理完成,候选 {CandidateCount},创建账单 {CreatedBillCount}",
|
||||
result.CandidateCount,
|
||||
result.CreatedBillCount);
|
||||
"定时任务:自动续费处理完成,处理租户 {TenantCount},候选 {CandidateCount},创建账单 {CreatedBillCount}",
|
||||
targets.Count,
|
||||
candidateCount,
|
||||
createdBillCount);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -2,7 +2,9 @@ using MediatR;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.Extensions.Options;
|
||||
using TakeoutSaaS.Application.App.Subscriptions.Commands;
|
||||
using TakeoutSaaS.Domain.Tenants.Repositories;
|
||||
using TakeoutSaaS.Module.Scheduler.Options;
|
||||
using TakeoutSaaS.Shared.Abstractions.Tenancy;
|
||||
|
||||
namespace TakeoutSaaS.Module.Scheduler.Jobs;
|
||||
|
||||
@@ -11,6 +13,8 @@ namespace TakeoutSaaS.Module.Scheduler.Jobs;
|
||||
/// </summary>
|
||||
public sealed class SubscriptionExpiryCheckJob(
|
||||
IMediator mediator,
|
||||
ITenantRepository tenantRepository,
|
||||
ITenantContextAccessor tenantContextAccessor,
|
||||
IOptionsMonitor<SubscriptionAutomationOptions> optionsMonitor,
|
||||
ILogger<SubscriptionExpiryCheckJob> logger)
|
||||
{
|
||||
@@ -19,17 +23,48 @@ public sealed class SubscriptionExpiryCheckJob(
|
||||
/// </summary>
|
||||
public async Task ExecuteAsync()
|
||||
{
|
||||
// 1. 读取配置并执行到期处理
|
||||
// 1. 读取配置
|
||||
var options = optionsMonitor.CurrentValue;
|
||||
var result = await mediator.Send(new ProcessSubscriptionExpiryCommand
|
||||
{
|
||||
GracePeriodDays = options.GracePeriodDays
|
||||
});
|
||||
|
||||
// 2. 记录执行结果
|
||||
// 2. (空行后) 获取需要处理的租户列表(排除系统租户)
|
||||
var tenants = await tenantRepository.SearchAsync(null, null, CancellationToken.None);
|
||||
var targets = tenants.Where(x => x.Id > 0).ToList();
|
||||
|
||||
// 3. (空行后) 按租户逐个执行到期处理
|
||||
var enteredGracePeriodCount = 0;
|
||||
var suspendedCount = 0;
|
||||
var previousContext = tenantContextAccessor.Current;
|
||||
try
|
||||
{
|
||||
foreach (var tenant in targets)
|
||||
{
|
||||
tenantContextAccessor.Current = new TenantContext(tenant.Id, tenant.Code, "scheduler");
|
||||
try
|
||||
{
|
||||
var result = await mediator.Send(new ProcessSubscriptionExpiryCommand
|
||||
{
|
||||
GracePeriodDays = options.GracePeriodDays
|
||||
});
|
||||
|
||||
enteredGracePeriodCount += result.EnteredGracePeriodCount;
|
||||
suspendedCount += result.SuspendedCount;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
logger.LogError(ex, "定时任务:订阅到期检查执行失败 TenantId={TenantId}", tenant.Id);
|
||||
}
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
tenantContextAccessor.Current = previousContext;
|
||||
}
|
||||
|
||||
// 4. (空行后) 记录执行结果
|
||||
logger.LogInformation(
|
||||
"定时任务:订阅到期检查完成,进入宽限期 {EnteredGracePeriodCount},暂停 {SuspendedCount}",
|
||||
result.EnteredGracePeriodCount,
|
||||
result.SuspendedCount);
|
||||
"定时任务:订阅到期检查完成,处理租户 {TenantCount},进入宽限期 {EnteredGracePeriodCount},暂停 {SuspendedCount}",
|
||||
targets.Count,
|
||||
enteredGracePeriodCount,
|
||||
suspendedCount);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,7 +2,9 @@ using MediatR;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.Extensions.Options;
|
||||
using TakeoutSaaS.Application.App.Subscriptions.Commands;
|
||||
using TakeoutSaaS.Domain.Tenants.Repositories;
|
||||
using TakeoutSaaS.Module.Scheduler.Options;
|
||||
using TakeoutSaaS.Shared.Abstractions.Tenancy;
|
||||
|
||||
namespace TakeoutSaaS.Module.Scheduler.Jobs;
|
||||
|
||||
@@ -11,6 +13,8 @@ namespace TakeoutSaaS.Module.Scheduler.Jobs;
|
||||
/// </summary>
|
||||
public sealed class SubscriptionRenewalReminderJob(
|
||||
IMediator mediator,
|
||||
ITenantRepository tenantRepository,
|
||||
ITenantContextAccessor tenantContextAccessor,
|
||||
IOptionsMonitor<SubscriptionAutomationOptions> optionsMonitor,
|
||||
ILogger<SubscriptionRenewalReminderJob> logger)
|
||||
{
|
||||
@@ -19,17 +23,48 @@ public sealed class SubscriptionRenewalReminderJob(
|
||||
/// </summary>
|
||||
public async Task ExecuteAsync()
|
||||
{
|
||||
// 1. 读取配置并执行续费提醒
|
||||
// 1. 读取配置
|
||||
var options = optionsMonitor.CurrentValue;
|
||||
var result = await mediator.Send(new ProcessRenewalRemindersCommand
|
||||
{
|
||||
ReminderDaysBeforeExpiry = options.ReminderDaysBeforeExpiry
|
||||
});
|
||||
|
||||
// 2. 记录执行结果
|
||||
// 2. (空行后) 获取需要处理的租户列表(排除系统租户)
|
||||
var tenants = await tenantRepository.SearchAsync(null, null, CancellationToken.None);
|
||||
var targets = tenants.Where(x => x.Id > 0).ToList();
|
||||
|
||||
// 3. (空行后) 按租户逐个执行续费提醒
|
||||
var candidateCount = 0;
|
||||
var createdReminderCount = 0;
|
||||
var previousContext = tenantContextAccessor.Current;
|
||||
try
|
||||
{
|
||||
foreach (var tenant in targets)
|
||||
{
|
||||
tenantContextAccessor.Current = new TenantContext(tenant.Id, tenant.Code, "scheduler");
|
||||
try
|
||||
{
|
||||
var result = await mediator.Send(new ProcessRenewalRemindersCommand
|
||||
{
|
||||
ReminderDaysBeforeExpiry = options.ReminderDaysBeforeExpiry
|
||||
});
|
||||
|
||||
candidateCount += result.CandidateCount;
|
||||
createdReminderCount += result.CreatedReminderCount;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
logger.LogError(ex, "定时任务:续费提醒执行失败 TenantId={TenantId}", tenant.Id);
|
||||
}
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
tenantContextAccessor.Current = previousContext;
|
||||
}
|
||||
|
||||
// 4. (空行后) 记录执行结果
|
||||
logger.LogInformation(
|
||||
"定时任务:续费提醒处理完成,候选 {CandidateCount},创建 {CreatedReminderCount}",
|
||||
result.CandidateCount,
|
||||
result.CreatedReminderCount);
|
||||
"定时任务:续费提醒处理完成,处理租户 {TenantCount},候选 {CandidateCount},创建 {CreatedReminderCount}",
|
||||
targets.Count,
|
||||
candidateCount,
|
||||
createdReminderCount);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user