YD_Event.Admin/YD_Event.Application/Event/EventStatusUpdateService.cs

132 lines
4.2 KiB
C#
Raw Normal View History

2026-04-06 14:13:43 +08:00
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using YD_Event.Core.Entities;
using YD_Event.Core.Enum;
namespace YD_Event.Application.Event;
/// <summary>
/// 赛事状态自动更新后台服务
/// 每5分钟执行一次,自动更新赛事状态
/// </summary>
public class EventStatusUpdateService : BackgroundService
{
private readonly IServiceProvider _serviceProvider;
private readonly ILogger<EventStatusUpdateService> _logger;
private readonly PeriodicTimer _timer;
public EventStatusUpdateService(
IServiceProvider serviceProvider,
ILogger<EventStatusUpdateService> logger)
{
_serviceProvider = serviceProvider;
_logger = logger;
_timer = new PeriodicTimer(TimeSpan.FromMinutes(5));
}
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
_logger.LogInformation("赛事状态自动更新服务已启动,每5分钟执行一次");
try
{
do
{
await UpdateEventStatusesAsync(stoppingToken);
} while (await _timer.WaitForNextTickAsync(stoppingToken));
}
catch (OperationCanceledException)
{
_logger.LogInformation("赛事状态自动更新服务已停止");
}
catch (Exception ex)
{
_logger.LogError(ex, "赛事状态自动更新服务发生异常");
}
}
private async Task UpdateEventStatusesAsync(CancellationToken stoppingToken)
{
try
{
_logger.LogDebug("开始执行赛事状态更新...");
using var scope = _serviceProvider.CreateScope();
var repository = scope.ServiceProvider.GetRequiredService<ISqlSugarRepository<EventInfo>>();
var now = DateTime.Now;
var eventsToUpdate = new List<EventInfo>();
var allEvents = await repository.AsQueryable()
.Where(e => !e.DeleteMark && e.Status == AvailabilityStatus.Enable)
.ToListAsync(stoppingToken);
foreach (var evt in allEvents)
{
var newStatus = CalculateEventStatus(evt, now);
if (evt.EventStatus != newStatus)
{
evt.EventStatus = newStatus;
evt.UpdatedTime = now;
eventsToUpdate.Add(evt);
_logger.LogInformation("赛事 {EventId}({EventName}) 状态更新: {OldStatus} -> {NewStatus}",
evt.Id, evt.EventName, evt.EventStatus, newStatus);
}
}
if (eventsToUpdate.Any())
{
await repository.UpdateRangeAsync(eventsToUpdate);
_logger.LogInformation("成功更新 {Count} 个赛事的状态", eventsToUpdate.Count);
}
else
{
_logger.LogDebug("没有需要更新状态的赛事");
}
}
catch (Exception ex)
{
_logger.LogError(ex, "更新赛事状态时发生异常");
}
}
/// <summary>
/// 根据时间计算赛事状态
/// </summary>
/// <param name="evt">赛事信息</param>
/// <param name="now">当前时间</param>
/// <returns>计算后的赛事状态</returns>
public static EventStatus CalculateEventStatus(EventInfo evt, DateTime now)
{
if (now < evt.RegistrationStartTime)
{
return EventStatus.NotStarted;
}
else if (now >= evt.RegistrationStartTime && now <= evt.RegistrationEndTime)
{
return EventStatus.Enrolling;
}
else if (now > evt.RegistrationEndTime && now < evt.MatchStartTime)
{
return EventStatus.RegistrationEnded;
}
else if (now >= evt.MatchStartTime && now <= evt.MatchEndTime)
{
return EventStatus.Ongoing;
}
else if (now > evt.MatchEndTime)
{
return EventStatus.Ended;
}
return EventStatus.NotStarted;
}
public override void Dispose()
{
_timer.Dispose();
base.Dispose();
}
}