From 61309a897443e7f46409e951467804da4f1106fa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=A9=AC=E6=A2=93=E5=BD=AD?= Date: Tue, 1 Sep 2026 14:16:11 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BC=98=E5=8C=96=E6=A3=80=E5=BD=95=E8=BF=94?= =?UTF-8?q?=E5=9B=9E=E6=95=B0=E6=8D=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Client/CheckinController.Progress.cs | 34 ++++++++++++++++++- .../Client/Dtos/CompetitionClientDtos.cs | 9 +++++ 2 files changed, 42 insertions(+), 1 deletion(-) diff --git a/YD_Event.Application/Client/CheckinController.Progress.cs b/YD_Event.Application/Client/CheckinController.Progress.cs index 9ef96e9..1fc93d0 100644 --- a/YD_Event.Application/Client/CheckinController.Progress.cs +++ b/YD_Event.Application/Client/CheckinController.Progress.cs @@ -102,8 +102,21 @@ public partial class CheckinController .Where(x => taskIds.Contains(x.TaskId) && x.SessionKey != null && x.Checked && !x.DeleteMark) .ToListAsync(); + // 检录员姓名按 CheckerUserId 批量查一次,避免逐条检录记录反查用户; + // AppUser.Name 为实名认证姓名,未认证的检录员退回昵称展示。 + var checkerIds = records.Select(x => x.CheckerUserId).Distinct().ToList(); + var checkers = checkerIds.Count == 0 + ? new List() + : await _userRepository.AsQueryable() + .Where(x => checkerIds.Contains(x.Id) && !x.DeleteMark) + .ToListAsync(); + var checkerNameMap = checkers.ToDictionary( + x => x.Id, + x => !string.IsNullOrWhiteSpace(x.Name) ? x.Name! : x.NickName ?? string.Empty); + var taskCheckinNoMap = activeTasks.ToDictionary(x => x.Id, x => x.CheckinNo); var passedByKey = new Dictionary>(); + var checkerNameByKey = new Dictionary>(); foreach (var record in records.Where(x => validUnitKeys.Contains(x.SessionKey!))) { if (!taskCheckinNoMap.TryGetValue(record.TaskId, out var checkinNo)) continue; @@ -113,6 +126,13 @@ public partial class CheckinController passedByKey[record.SessionKey!] = rounds; } rounds[checkinNo] = record.CheckedTime; + + if (!checkerNameByKey.TryGetValue(record.SessionKey!, out var checkerNames)) + { + checkerNames = new Dictionary(); + checkerNameByKey[record.SessionKey!] = checkerNames; + } + checkerNames[checkinNo] = checkerNameMap.GetValueOrDefault(record.CheckerUserId) ?? string.Empty; } var firstCheckinNo = activeTasks.Count == 0 ? 1 : activeTasks.Min(x => x.CheckinNo); @@ -120,6 +140,7 @@ public partial class CheckinController var context = new CheckinProgressContext { PassedByKey = passedByKey, + CheckerNameByKey = checkerNameByKey, FirstCheckinNo = firstCheckinNo, LastCheckinNo = lastCheckinNo, ActiveCheckinNumbers = activeTasks.Select(x => x.CheckinNo).OrderBy(x => x).ToList() @@ -179,6 +200,9 @@ public partial class CheckinController StageStatus = 1, StageStatusText = "比赛中", TeamName = ResolveTeamName(competingUnit), + UnitName = string.IsNullOrWhiteSpace(competingUnit.UnitName) ? "/" : competingUnit.UnitName, + // 秩序册列没有独立的报名类型字段,以 TeamName 是否为空区分个人与团队报名。 + RegistrationTypeText = string.IsNullOrWhiteSpace(competingUnit.TeamName) ? "个人报名" : "团队报名", AthleteNames = competingUnit.Athletes.Select(x => x.Name).ToList() }; } @@ -230,7 +254,8 @@ public partial class CheckinController CheckinNo = checkinNo, CheckinName = ToCheckinName(checkinNo), Passed = context.IsPassed(unit.UnitKey, checkinNo), - CheckedTime = context.GetCheckedTime(unit.UnitKey, checkinNo) + CheckedTime = context.GetCheckedTime(unit.UnitKey, checkinNo), + CheckerName = context.GetCheckerName(unit.UnitKey, checkinNo) }).ToList(), Notice = status switch { @@ -311,7 +336,9 @@ public partial class CheckinController /// 检录进度计算的中间上下文,避免重复查询检录记录。 private sealed class CheckinProgressContext { + // 两个字典的键结构一致:外层为秩序册列 UnitKey,内层为检次号。 public Dictionary> PassedByKey { get; init; } = new(); + public Dictionary> CheckerNameByKey { get; init; } = new(); public int FirstCheckinNo { get; init; } = 1; public int LastCheckinNo { get; init; } = 1; public List ActiveCheckinNumbers { get; init; } = new(); @@ -326,5 +353,10 @@ public partial class CheckinController PassedByKey.TryGetValue(unitKey, out var rounds) && rounds.TryGetValue(checkinNo, out var time) ? time : null; + + public string GetCheckerName(string unitKey, int checkinNo) => + CheckerNameByKey.TryGetValue(unitKey, out var rounds) && rounds.TryGetValue(checkinNo, out var name) + ? name + : string.Empty; } } diff --git a/YD_Event.Application/Client/Dtos/CompetitionClientDtos.cs b/YD_Event.Application/Client/Dtos/CompetitionClientDtos.cs index 07ed59f..4e1bce8 100644 --- a/YD_Event.Application/Client/Dtos/CompetitionClientDtos.cs +++ b/YD_Event.Application/Client/Dtos/CompetitionClientDtos.cs @@ -416,6 +416,12 @@ public class CheckinProgressStageDto /// 该阶段正在比赛的队伍名称。 public string TeamName { get; set; } = string.Empty; + /// 该阶段正在比赛的单位名称。 + public string UnitName { get; set; } = string.Empty; + + /// 报名类型展示文本:个人报名或团队报名。 + public string RegistrationTypeText { get; set; } = string.Empty; + /// 该阶段正在比赛的队员名称列表。 public List AthleteNames { get; set; } = new(); } @@ -457,6 +463,9 @@ public class CheckinProgressRoundDto public string CheckinName { get; set; } = string.Empty; public bool Passed { get; set; } public DateTime? CheckedTime { get; set; } + + /// 执行本次检录的检录员姓名。 + public string CheckerName { get; set; } = string.Empty; } /// 检录投屏数据。