YD_Event.Admin/YD_Event.Application/Event/PaymentExpirationBackgroundService.cs

99 lines
3.4 KiB
C#
Raw Normal View History

2026-04-13 15:28:25 +08:00
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
namespace YD_Event.Application.Event;
/// <summary>
/// 支付超时处理后台服务
/// </summary>
public class PaymentExpirationBackgroundService : BackgroundService
{
private readonly IServiceProvider _serviceProvider;
private readonly ILogger<PaymentExpirationBackgroundService> _logger;
private readonly PeriodicTimer _timer;
public PaymentExpirationBackgroundService(
IServiceProvider serviceProvider,
ILogger<PaymentExpirationBackgroundService> logger)
{
_serviceProvider = serviceProvider;
_logger = logger;
_timer = new PeriodicTimer(TimeSpan.FromMinutes(5));
}
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
_logger.LogInformation("支付超时处理后台服务已启动");
try
{
while (await _timer.WaitForNextTickAsync(stoppingToken))
{
await ProcessExpiredPaymentsAsync(stoppingToken);
}
}
catch (OperationCanceledException)
{
_logger.LogInformation("支付超时处理后台服务已停止");
}
}
private async Task ProcessExpiredPaymentsAsync(CancellationToken stoppingToken)
{
try
{
_logger.LogInformation("开始处理超时未支付订单");
using var scope = _serviceProvider.CreateScope();
var registrationRepository = scope.ServiceProvider.GetRequiredService<ISqlSugarRepository<EventRegistration>>();
var orderRepository = scope.ServiceProvider.GetRequiredService<ISqlSugarRepository<YD_Event.Core.Entities.Order>>();
var now = DateTime.Now;
var expirationTime = now.AddMinutes(-30);
var expiredRegistrations = await registrationRepository.AsQueryable()
.Where(x => x.PaymentMethod == 2
&& x.PaymentStatus == 0
&& x.CreatedTime <= expirationTime
&& !x.DeleteMark)
.ToListAsync(stoppingToken);
if (expiredRegistrations.Any())
{
_logger.LogInformation("发现 {Count} 个超时未支付的线上订单", expiredRegistrations.Count);
var idsToCancel = expiredRegistrations.Select(x => x.Id).ToList();
var orderNos = expiredRegistrations.Where(x => !string.IsNullOrEmpty(x.OrderNo)).Select(x => x.OrderNo).ToList();
await registrationRepository.UpdateAsync(x => new EventRegistration
{
PaymentStatus = 4,
UpdatedTime = now
}, x => idsToCancel.Contains(x.Id));
if (orderNos.Any())
{
await orderRepository.UpdateAsync(x => new YD_Event.Core.Entities.Order
{
OrderStatus = OrderStatus.Cancelled,
UpdatedTime = now
}, x => orderNos.Contains(x.OrderNo));
}
_logger.LogInformation("已成功取消 {Count} 个超时未支付订单", expiredRegistrations.Count);
}
}
catch (Exception ex)
{
_logger.LogError(ex, "处理超时未支付订单时发生错误");
}
}
public override void Dispose()
{
_timer.Dispose();
base.Dispose();
}
}