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

132 lines
4.2 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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();
}
}