using Microsoft.Extensions.Logging;
using TakeoutSaaS.Domain.Finance.Repositories;
using TakeoutSaaS.Shared.Abstractions.Tenancy;
namespace TakeoutSaaS.Module.Scheduler.Jobs;
///
/// 经营报表快照刷新任务:消费排队中的报表快照并触发生成。
///
public sealed class FinanceBusinessReportRefreshJob(
IFinanceBusinessReportRepository financeBusinessReportRepository,
ITenantContextAccessor tenantContextAccessor,
ILogger logger)
{
private const int BatchSize = 80;
///
/// 执行报表快照刷新。
///
public async Task ExecuteAsync()
{
// 1. 拉取待处理快照任务。
var pendingList = await financeBusinessReportRepository.GetPendingSnapshotsAsync(BatchSize, CancellationToken.None);
if (pendingList.Count == 0)
{
logger.LogDebug("定时任务:经营报表快照刷新无待处理任务");
return;
}
// 2. 逐租户上下文执行生成。
var successCount = 0;
var failedCount = 0;
foreach (var pending in pendingList)
{
var previousContext = tenantContextAccessor.Current;
try
{
tenantContextAccessor.Current = new TenantContext(
pending.TenantId,
$"tenant-{pending.TenantId}",
"scheduler");
await financeBusinessReportRepository.GenerateSnapshotAsync(
pending.SnapshotId,
CancellationToken.None);
successCount += 1;
}
catch (Exception ex)
{
failedCount += 1;
logger.LogError(
ex,
"定时任务:经营报表快照刷新失败 SnapshotId={SnapshotId}, TenantId={TenantId}",
pending.SnapshotId,
pending.TenantId);
}
finally
{
tenantContextAccessor.Current = previousContext;
}
}
// 3. 记录执行结果。
logger.LogInformation(
"定时任务:经营报表快照刷新完成,处理 {TotalCount} 条,成功 {SuccessCount} 条,失败 {FailedCount} 条",
pendingList.Count,
successCount,
failedCount);
}
}