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; /// /// 赛事状态自动更新后台服务 /// 每5分钟执行一次,自动更新赛事状态 /// public class EventStatusUpdateService : BackgroundService { private readonly IServiceProvider _serviceProvider; private readonly ILogger _logger; private readonly PeriodicTimer _timer; public EventStatusUpdateService( IServiceProvider serviceProvider, ILogger 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>(); var now = DateTime.Now; var eventsToUpdate = new List(); 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, "更新赛事状态时发生异常"); } } /// /// 根据时间计算赛事状态 /// /// 赛事信息 /// 当前时间 /// 计算后的赛事状态 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(); } }