admin/src/Oms.Application/Workers/MarketingBackgroundWorker.cs
zzh 89233bc3da feat: add customer marketing module (M1-M6 backend)
Implement referral, points, coupons, commission, member levels, and order integration with migration SQL and background jobs.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-23 16:42:08 +08:00

67 lines
2.1 KiB
C#

using Fake.UnitOfWork;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using Oms.Application.Shared;
namespace Oms.Application.Workers;
/// <summary>
/// 营销定时任务:释放过期券锁、结算 Pending 分成。
/// </summary>
public class MarketingBackgroundWorker : BackgroundService
{
private static readonly TimeSpan PollInterval = TimeSpan.FromMinutes(1);
private const int BatchSize = 50;
private readonly IServiceScopeFactory _scopeFactory;
private readonly ILogger<MarketingBackgroundWorker> _logger;
public MarketingBackgroundWorker(
IServiceScopeFactory scopeFactory,
ILogger<MarketingBackgroundWorker> logger)
{
_scopeFactory = scopeFactory;
_logger = logger;
}
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
while (!stoppingToken.IsCancellationRequested)
{
try
{
await ProcessAsync(stoppingToken);
}
catch (Exception ex) when (ex is not OperationCanceledException)
{
_logger.LogError(ex, "营销后台任务异常");
}
try
{
await Task.Delay(PollInterval, stoppingToken);
}
catch (OperationCanceledException)
{
break;
}
}
}
private async Task ProcessAsync(CancellationToken cancellationToken)
{
using var scope = _scopeFactory.CreateScope();
var unitOfWorkManager = scope.ServiceProvider.GetRequiredService<IUnitOfWorkManager>();
using var unitOfWork = unitOfWorkManager.Begin();
var couponManager = scope.ServiceProvider.GetRequiredService<MarketingCouponManager>();
await couponManager.ReleaseExpiredLocksAsync(BatchSize, cancellationToken);
var commissionManager = scope.ServiceProvider.GetRequiredService<ReferralCommissionManager>();
await commissionManager.SettlePendingAsync(BatchSize, cancellationToken);
await unitOfWork.CompleteAsync(cancellationToken);
}
}