diff --git a/YD_Event.Application/Client/CheckinController.Progress.cs b/YD_Event.Application/Client/CheckinController.Progress.cs index 8e3ec44..095b4b7 100644 --- a/YD_Event.Application/Client/CheckinController.Progress.cs +++ b/YD_Event.Application/Client/CheckinController.Progress.cs @@ -49,13 +49,12 @@ public partial class CheckinController var activeTasks = await GetActiveEventTasksAsync(eventId); var context = await BuildProgressContextAsync(options, activeTasks); - // 未指定项目组别时投屏当前检录中的项目组别。 + // 未指定项目时投屏当前检录项目,并覆盖该项目下全部组别。 var targetProjectId = eventProjectId ?? context.CurrentCheckin?.EventProjectId; - var targetGroupId = groupId ?? context.CurrentCheckin?.GroupId; - var units = !targetProjectId.HasValue || !targetGroupId.HasValue + var units = !targetProjectId.HasValue ? new List() : options.Units - .Where(x => x.EventProjectId == targetProjectId.Value && x.GroupId == targetGroupId.Value) + .Where(x => x.EventProjectId == targetProjectId.Value) .OrderBy(x => x.Order) .Select(unit => { @@ -150,7 +149,7 @@ public partial class CheckinController // 赛事检录顺序完全跟随一检进度:一检开始即为检录中,一检全部通过即切换下一项目。 var stages = options.Units - .GroupBy(x => new { x.EventProjectId, x.GroupId, x.ProjectName, x.GroupName }) + .GroupBy(x => new { x.EventProjectId, x.ProjectName }) .Select(group => { var groupUnits = group.OrderBy(x => x.Order).ToList(); @@ -160,10 +159,10 @@ public partial class CheckinController return new CheckinProgressStageDto { EventProjectId = group.Key.EventProjectId, - GroupId = group.Key.GroupId, + GroupId = null, ProjectName = group.Key.ProjectName, - GroupName = group.Key.GroupName, - DisplayName = $"{group.Key.ProjectName} - {group.Key.GroupName}", + GroupName = string.Empty, + DisplayName = group.Key.ProjectName, Order = groupUnits[0].Order, TotalUnits = total, CheckedUnits = checkedCount, @@ -211,8 +210,7 @@ public partial class CheckinController if (context.CurrentCheckin != null) { var checkingUnit = options.Units - .Where(x => x.EventProjectId == context.CurrentCheckin.EventProjectId && - x.GroupId == context.CurrentCheckin.GroupId) + .Where(x => x.EventProjectId == context.CurrentCheckin.EventProjectId) .OrderBy(x => x.Order) .FirstOrDefault(x => !context.IsPassed(x.UnitKey, firstCheckinNo)); if (checkingUnit != null) @@ -295,7 +293,7 @@ public partial class CheckinController return activeTasks.Count > 1 ? 2 : 3; var stage = context.CurrentCheckin; - return stage != null && stage.EventProjectId == unit.EventProjectId && stage.GroupId == unit.GroupId + return stage != null && stage.EventProjectId == unit.EventProjectId ? 1 : 0; } @@ -307,7 +305,7 @@ public partial class CheckinController if (context.IsPassed(unit.UnitKey, context.FirstCheckinNo)) return 2; var stage = context.CurrentCheckin; - return stage != null && stage.EventProjectId == unit.EventProjectId && stage.GroupId == unit.GroupId + return stage != null && stage.EventProjectId == unit.EventProjectId ? 1 : 0; } diff --git a/YD_Event.Application/Client/CheckinController.cs b/YD_Event.Application/Client/CheckinController.cs index 1b161b0..6e4645d 100644 --- a/YD_Event.Application/Client/CheckinController.cs +++ b/YD_Event.Application/Client/CheckinController.cs @@ -130,8 +130,8 @@ public partial class CheckinController : IDynamicApiController await _recordRepository.UpdateAsync(record); } - // 保持页面当前项目/组别筛选;UnitKey 已独立校验检录项归属。 - return await BuildContextAsync(task, input.EventProjectId, input.GroupId); + // 保持页面当前项目筛选;UnitKey 已独立校验检录项归属。 + return await BuildContextAsync(task, input.EventProjectId, null); } [HttpPost("start")] @@ -147,24 +147,21 @@ public partial class CheckinController : IDynamicApiController var options = await _scheduleService.GetOptionsAsync(task.EventId); var project = options.Projects.FirstOrDefault(x => x.EventProjectId == input.EventProjectId) ?? throw Oops.Bah("所选参赛项目不属于当前赛事秩序册"); - var group = project.Groups.FirstOrDefault(x => x.Id == input.GroupId) - ?? throw Oops.Bah("所选参赛组别不属于当前参赛项目"); - var units = options.Units - .Where(x => x.EventProjectId == input.EventProjectId && x.GroupId == input.GroupId) + .Where(x => x.EventProjectId == input.EventProjectId) .OrderBy(x => x.Order).ToList(); - if (units.Count == 0) throw Oops.Bah("所选项目组别没有可检录的参赛队伍"); + if (units.Count == 0) throw Oops.Bah("所选项目没有可检录的参赛队伍"); // 记录当前检录进度,供运动员端与投屏读取"当前检录项目"。 task.CurrentEventProjectId = input.EventProjectId; - task.CurrentGroupId = input.GroupId; - task.CurrentGroupName = group.GroupName; - task.GroupOrder = group.Order; + task.CurrentGroupId = null; + task.CurrentGroupName = "全部组别"; + task.GroupOrder = project.Groups.Count == 0 ? 0 : project.Groups.Min(x => x.Order); task.TotalGroups = project.Groups.Count; - task.NextGroupName = project.Groups.FirstOrDefault(x => x.Order > group.Order)?.GroupName; + task.NextGroupName = null; task.CurrentSessionKey = units[0].UnitKey; task.CurrentSessionOrder = units[0].Order; - task.CurrentSessionName = $"{project.ProjectName}-{group.GroupName}"; + task.CurrentSessionName = project.ProjectName; task.CurrentSessionVenue = units[0].VenueName; task.UpdatedUserId = checkerUserId; task.UpdatedTime = DateTime.Now; @@ -179,19 +176,19 @@ public partial class CheckinController : IDynamicApiController x.Id == project.ProjectId && !x.DeleteMark && x.Status == AvailabilityStatus.Enable); if (projectEntity == null) throw Oops.Bah("参赛项目不存在或已停用"); - var noticeName = $"{project.ProjectName}-{group.GroupName}"; + var noticeName = project.ProjectName; (total, success, failed) = await NotifyUnitsAsync( units, projectEntity.ProjectType, options.EventName, noticeName); } - var context = await BuildContextAsync(task, input.EventProjectId, input.GroupId); + var context = await BuildContextAsync(task, input.EventProjectId, null); return new StartCheckinOutput { TaskId = task.Id, EventProjectId = project.EventProjectId, ProjectName = project.ProjectName, - GroupId = group.Id, - GroupName = group.GroupName, + GroupId = 0, + GroupName = "全部组别", UnitCount = units.Count, NoticeTotal = total, SmsSuccessCount = success, @@ -226,9 +223,7 @@ public partial class CheckinController : IDynamicApiController await EnsurePreviousPassedAsync(task, unit.UnitKey); await UpsertRecordAsync(task, unit, checkerUserId, true); - var context = await BuildContextAsync(task, - input.EventProjectId ?? unit.EventProjectId, - input.GroupId ?? unit.GroupId ?? 0); + var context = await BuildContextAsync(task, input.EventProjectId ?? unit.EventProjectId, null); return new ScanCheckinOutput { Success = true, @@ -275,7 +270,7 @@ public partial class CheckinController : IDynamicApiController task.UpdatedTime = DateTime.Now; await _taskRepository.UpdateAsync(task); - return await BuildContextAsync(task, input.EventProjectId, input.GroupId); + return await BuildContextAsync(task, input.EventProjectId, null); } /// 按扫码内容定位秩序册列;支持号码布、报名人员ID和姓名。 @@ -588,16 +583,20 @@ public partial class CheckinController : IDynamicApiController : EventStatus.NotStarted; var options = await _scheduleService.GetOptionsAsync(task.EventId); - var selectedProject = options.Projects.FirstOrDefault(x => x.EventProjectId == eventProjectId) - ?? options.Projects.FirstOrDefault(); + var orderedProjects = options.Projects + .OrderBy(project => options.Units + .Where(unit => unit.EventProjectId == project.EventProjectId) + .Select(unit => unit.Order) + .DefaultIfEmpty(int.MaxValue) + .Min()) + .ToList(); + var selectedProject = orderedProjects.FirstOrDefault(x => x.EventProjectId == eventProjectId) + ?? orderedProjects.FirstOrDefault(); if (selectedProject == null) throw Oops.Bah("当前赛事秩序册没有可检录项目"); - var selectedGroup = selectedProject.Groups.FirstOrDefault(x => x.Id == groupId) - ?? selectedProject.Groups.FirstOrDefault(); - if (selectedGroup == null) throw Oops.Bah("所选参赛项目没有可检录组别"); var allUnits = options.Units.OrderBy(x => x.Order).ToList(); var units = allUnits - .Where(x => x.EventProjectId == selectedProject.EventProjectId && x.GroupId == selectedGroup.Id) + .Where(x => x.EventProjectId == selectedProject.EventProjectId) .OrderBy(x => x.Order).ToList(); var allUnitKeys = allUnits.Select(x => x.UnitKey).ToHashSet(); var records = await _recordRepository.AsQueryable() @@ -657,11 +656,11 @@ public partial class CheckinController : IDynamicApiController }; }).ToList(); var statusUnits = allStatusUnits - .Where(x => x.EventProjectId == selectedProject.EventProjectId && x.GroupId == selectedGroup.Id) + .Where(x => x.EventProjectId == selectedProject.EventProjectId) .ToList(); // 为项目、组别选择区计算当前检次概况,全部完成时由小程序显示绿色状态。 - foreach (var project in options.Projects) + foreach (var project in orderedProjects) { var projectUnits = allStatusUnits.Where(x => x.EventProjectId == project.EventProjectId).ToList(); ApplyProgress(projectUnits, out var projectTotal, out var projectChecked, @@ -697,13 +696,13 @@ public partial class CheckinController : IDynamicApiController CurrentRound = task.CheckinNo, RoundName = ToCheckinName(task.CheckinNo), SelectedEventProjectId = selectedProject.EventProjectId, - SelectedGroupId = selectedGroup.Id, - CurrentGroupId = selectedGroup.Id, - CurrentGroupName = selectedGroup.GroupName, - Projects = options.Projects, + SelectedGroupId = 0, + CurrentGroupId = null, + CurrentGroupName = "全部组别", + Projects = orderedProjects, Units = statusUnits, PendingUnits = statusUnits.Where(x => x.CanCheck && !x.Checked).ToList(), - // 已检录跟随当前选中的项目和组别,便于现场聚焦操作。 + // 已检录跟随当前选中的项目,覆盖该项目全部组别。 CheckedUnits = statusUnits.Where(x => x.Checked).ToList(), LockedUnits = statusUnits.Where(x => !x.CanCheck).ToList(), CanCheck = eventCanCheckin, diff --git a/YD_Event.Application/Client/Dtos/CompetitionClientDtos.cs b/YD_Event.Application/Client/Dtos/CompetitionClientDtos.cs index 5ba36a4..f3c6608 100644 --- a/YD_Event.Application/Client/Dtos/CompetitionClientDtos.cs +++ b/YD_Event.Application/Client/Dtos/CompetitionClientDtos.cs @@ -411,8 +411,8 @@ public class StartCheckinInput [Required(ErrorMessage = "赛事项目ID不能为空")] public long EventProjectId { get; set; } - [Required(ErrorMessage = "参赛组别ID不能为空")] - public long GroupId { get; set; } + /// 兼容旧客户端;项目级检录时无需传组别。 + public long? GroupId { get; set; } } ///