120 lines
5.2 KiB
C#
120 lines
5.2 KiB
C#
|
|
using YD_Event.Application.Client.Dtos;
|
|||
|
|
using YD_Event.Application.Event;
|
|||
|
|
|
|||
|
|
namespace YD_Event.Application.Client;
|
|||
|
|
|
|||
|
|
/// <summary>从秩序册实时生成检录项目、组别和列对象。</summary>
|
|||
|
|
public class CheckinScheduleService : ITransient
|
|||
|
|
{
|
|||
|
|
private readonly ISqlSugarRepository<EventInfo> _eventRepository;
|
|||
|
|
private readonly ISqlSugarRepository<EventRegistrationPerson> _personRepository;
|
|||
|
|
private readonly EventArrangementService _arrangementService;
|
|||
|
|
|
|||
|
|
public CheckinScheduleService(
|
|||
|
|
ISqlSugarRepository<EventInfo> eventRepository,
|
|||
|
|
ISqlSugarRepository<EventRegistrationPerson> personRepository,
|
|||
|
|
EventArrangementService arrangementService)
|
|||
|
|
{
|
|||
|
|
_eventRepository = eventRepository;
|
|||
|
|
_personRepository = personRepository;
|
|||
|
|
_arrangementService = arrangementService;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
public async Task<CheckinEventOptionsDto> GetOptionsAsync(long eventId)
|
|||
|
|
{
|
|||
|
|
var evt = await _eventRepository.GetFirstAsync(x =>
|
|||
|
|
x.Id == eventId && !x.DeleteMark && x.Status == AvailabilityStatus.Enable);
|
|||
|
|
if (evt == null) throw Oops.Bah("赛事不存在或已停用");
|
|||
|
|
|
|||
|
|
// Preview 的每一行就是秩序册中的一列:个人项目一人,团队项目可以多人。
|
|||
|
|
var rows = await _arrangementService.Preview(eventId);
|
|||
|
|
if (rows.Count == 0) throw Oops.Bah("当前赛事尚未生成有效秩序册,不能创建检录任务");
|
|||
|
|
|
|||
|
|
var personIds = rows.SelectMany(x => x.RegistrationPersonIds).Distinct().ToList();
|
|||
|
|
var persons = personIds.Count == 0
|
|||
|
|
? new List<EventRegistrationPerson>()
|
|||
|
|
: await _personRepository.AsQueryable()
|
|||
|
|
.Where(x => personIds.Contains(x.Id) && !x.DeleteMark && x.PersonType == PersonType.Athlete)
|
|||
|
|
.ToListAsync();
|
|||
|
|
var personMap = persons.ToDictionary(x => x.Id);
|
|||
|
|
|
|||
|
|
var units = rows.Select((row, index) => new CheckinOrderBookUnitDto
|
|||
|
|
{
|
|||
|
|
UnitKey = BuildUnitKey(row.EventProjectId, row.RegistrationItemId),
|
|||
|
|
Order = index + 1,
|
|||
|
|
SessionIndex = row.SessionIndex,
|
|||
|
|
VenueIndex = row.VenueIndex,
|
|||
|
|
VenueName = $"{row.VenueIndex}号场地",
|
|||
|
|
EventProjectId = row.EventProjectId,
|
|||
|
|
ProjectId = row.ProjectId,
|
|||
|
|
ProjectName = row.ProjectName,
|
|||
|
|
GroupId = row.EventProjectGroupId,
|
|||
|
|
GroupName = row.GroupName,
|
|||
|
|
RegistrationItemId = row.RegistrationItemId,
|
|||
|
|
TeamName = row.TeamName ?? string.Empty,
|
|||
|
|
UnitName = row.UnitName ?? string.Empty,
|
|||
|
|
RegistrationPersonIds = row.RegistrationPersonIds.Distinct().ToList(),
|
|||
|
|
Athletes = row.RegistrationPersonIds.Distinct()
|
|||
|
|
.Where(personMap.ContainsKey)
|
|||
|
|
.Select(personId =>
|
|||
|
|
{
|
|||
|
|
var person = personMap[personId];
|
|||
|
|
return new CheckinAthleteDto
|
|||
|
|
{
|
|||
|
|
Id = person.Id,
|
|||
|
|
UserId = person.UserId,
|
|||
|
|
BibNo = FormatBibNo(person.Id),
|
|||
|
|
Name = person.Name,
|
|||
|
|
TeamName = row.TeamName ?? string.Empty
|
|||
|
|
};
|
|||
|
|
}).ToList()
|
|||
|
|
}).ToList();
|
|||
|
|
|
|||
|
|
var projects = units.GroupBy(x => new { x.EventProjectId, x.ProjectId, x.ProjectName })
|
|||
|
|
.Select((project, projectIndex) => new CheckinProjectOptionDto
|
|||
|
|
{
|
|||
|
|
EventProjectId = project.Key.EventProjectId,
|
|||
|
|
ProjectId = project.Key.ProjectId,
|
|||
|
|
ProjectName = project.Key.ProjectName,
|
|||
|
|
Order = projectIndex + 1,
|
|||
|
|
Groups = project.Where(x => x.GroupId.HasValue)
|
|||
|
|
.GroupBy(x => new { Id = x.GroupId!.Value, x.GroupName })
|
|||
|
|
.Select((group, groupIndex) => new CheckinGroupOptionDto
|
|||
|
|
{
|
|||
|
|
Id = group.Key.Id,
|
|||
|
|
EventProjectId = project.Key.EventProjectId,
|
|||
|
|
ProjectId = project.Key.ProjectId,
|
|||
|
|
ProjectName = project.Key.ProjectName,
|
|||
|
|
GroupName = group.Key.GroupName,
|
|||
|
|
Order = groupIndex + 1
|
|||
|
|
}).ToList()
|
|||
|
|
}).ToList();
|
|||
|
|
|
|||
|
|
return new CheckinEventOptionsDto
|
|||
|
|
{
|
|||
|
|
EventId = evt.Id,
|
|||
|
|
EventName = evt.EventName,
|
|||
|
|
Projects = projects,
|
|||
|
|
Units = units,
|
|||
|
|
// 兼容旧调用方:Sessions 不再是检录对象。
|
|||
|
|
Sessions = new List<CheckinSessionOptionDto>(),
|
|||
|
|
Rounds = new List<CheckinRoundOptionDto>()
|
|||
|
|
};
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
public static CheckinOrderBookUnitDto ResolveUnit(CheckinEventOptionsDto options, string unitKey)
|
|||
|
|
{
|
|||
|
|
var unit = options.Units.FirstOrDefault(x => x.UnitKey == unitKey);
|
|||
|
|
return unit ?? throw Oops.Bah("所选检录对象不属于当前赛事秩序册");
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
public static string BuildUnitKey(long eventProjectId, long registrationItemId) =>
|
|||
|
|
$"EP{eventProjectId}-RI{registrationItemId}";
|
|||
|
|
|
|||
|
|
private static string FormatBibNo(long personId)
|
|||
|
|
{
|
|||
|
|
var value = personId.ToString();
|
|||
|
|
return value.Length > 6 ? value[^6..] : value.PadLeft(6, '0');
|
|||
|
|
}
|
|||
|
|
}
|