赛事成绩

This commit is contained in:
马梓彭 2026-04-15 14:28:22 +08:00
parent 9bca004d2b
commit b98fa869e3
3 changed files with 58 additions and 26 deletions

View File

@ -20,7 +20,12 @@ public class ScoreQueryInput : Pagination
public long? ProjectId { get; set; }
/// <summary>
/// 组别名称
/// 赛事项目组别ID (优先使用)
/// </summary>
public long? EventProjectGroupId { get; set; }
/// <summary>
/// 组别名称 (备用,当没有EventProjectGroupId时使用)
/// </summary>
public string? GroupName { get; set; }
@ -184,9 +189,10 @@ public class IssueCertificateInput
public long EventId { get; set; }
/// <summary>
/// 证书模板ID(可选)
/// 证书ID(必选)
/// </summary>
public long? TemplateId { get; set; }
[Required(ErrorMessage = "请选择证书")]
public long CertificateId { get; set; }
}
/// <summary>

View File

@ -166,7 +166,7 @@ public class EventRegistrationService : BaseService<EventRegistration>, ITransie
{
var myPersons = persons.Where(p => p.RegistrationItemId == item.Id).ToList();
// 构造参与人信息字符串,可以使用关联的 User 信息
// 构造参与人信息字符串,统一格式为:姓名/性别/年龄/手机号
var personInfo = string.Join(";", myPersons.Select(p =>
{
// 将性别转换为中文显示
@ -177,12 +177,11 @@ public class EventRegistrationService : BaseService<EventRegistration>, ITransie
_ => "未知"
};
// 如果有关联的用户信息,可以使用更完整的信息
if (p.User != null)
{
return $"{p.Name}({p.User.Mobile})/{genderText}/{p.Age}";
}
return $"{p.Name}/{genderText}/{p.Age}/{p.IdCard}";
// 获取手机号,优先使用关联用户信息,否则使用自身的 Phone 字段
var mobile = p.User?.Mobile ?? p.Phone ?? "";
// 统一格式:姓名/性别/年龄/手机号
return $"{p.Name}/{genderText}/{p.Age}/{mobile}";
}));
if (personInfo.Length > 100) personInfo = personInfo.Substring(0, 97) + "..."; // 截断

View File

@ -47,6 +47,7 @@ public class EventScoreService : BaseService<EventResult>, ITransient
private readonly ISqlSugarRepository<EventCertificate> _certificateRepository;
private readonly ISqlSugarRepository<EventRegistration> _registrationRepository;
private readonly ISqlSugarRepository<CertificateTemplate> _templateRepository;
private readonly ISqlSugarRepository<YD_Event.Core.Entities.Certificate> _certificateMasterRepository;
private readonly ISqlSugarRepository<YD_Event.Core.Entities.Project> _projectRepository;
private readonly ISqlSugarRepository<TeamMember> _teamMemberRepository;
private readonly ISqlSugarRepository<EventInfo> _eventRepository;
@ -54,6 +55,7 @@ public class EventScoreService : BaseService<EventResult>, ITransient
private readonly ISqlSugarRepository<PointsRuleDetail> _pointsRuleDetailRepository;
private readonly ISqlSugarRepository<PointsRecord> _pointsRecordRepository;
private readonly ISqlSugarRepository<YD_Event.Core.Entities.AppUser> _appUserRepository;
private readonly CertificateGenerateService _certificateGenerateService;
private readonly IIdGenerator _idGenerator;
private readonly ILogger<EventScoreService> _logger;
@ -63,6 +65,7 @@ public class EventScoreService : BaseService<EventResult>, ITransient
ISqlSugarRepository<EventCertificate> certificateRepository,
ISqlSugarRepository<EventRegistration> registrationRepository,
ISqlSugarRepository<CertificateTemplate> templateRepository,
ISqlSugarRepository<YD_Event.Core.Entities.Certificate> certificateMasterRepository,
ISqlSugarRepository<YD_Event.Core.Entities.Project> projectRepository,
ISqlSugarRepository<TeamMember> teamMemberRepository,
ISqlSugarRepository<EventInfo> eventRepository,
@ -70,6 +73,7 @@ public class EventScoreService : BaseService<EventResult>, ITransient
ISqlSugarRepository<PointsRuleDetail> pointsRuleDetailRepository,
ISqlSugarRepository<PointsRecord> pointsRecordRepository,
ISqlSugarRepository<YD_Event.Core.Entities.AppUser> appUserRepository,
CertificateGenerateService certificateGenerateService,
IIdGenerator idGenerator,
ILogger<EventScoreService> logger) : base(resultRepository)
{
@ -78,6 +82,7 @@ public class EventScoreService : BaseService<EventResult>, ITransient
_certificateRepository = certificateRepository;
_registrationRepository = registrationRepository;
_templateRepository = templateRepository;
_certificateMasterRepository = certificateMasterRepository;
_projectRepository = projectRepository;
_teamMemberRepository = teamMemberRepository;
_eventRepository = eventRepository;
@ -85,6 +90,7 @@ public class EventScoreService : BaseService<EventResult>, ITransient
_pointsRuleDetailRepository = pointsRuleDetailRepository;
_pointsRecordRepository = pointsRecordRepository;
_appUserRepository = appUserRepository;
_certificateGenerateService = certificateGenerateService;
_idGenerator = idGenerator;
_logger = logger;
}
@ -95,8 +101,8 @@ public class EventScoreService : BaseService<EventResult>, ITransient
[DisplayName("运动员成绩列表")]
public async Task<PageResult<ScoreListOutput>> PageAthlete(ScoreQueryInput input)
{
_logger.LogInformation("开始查询运动员成绩列表,赛事ID={EventId}, 项目ID={ProjectId}, 组别={GroupName}",
input.EventId, input.ProjectId, input.GroupName);
_logger.LogInformation("开始查询运动员成绩列表,赛事ID={EventId}, 项目ID={ProjectId}, 赛事项目组别ID={EventProjectGroupId}, 组别名称={GroupName}",
input.EventId, input.ProjectId, input.EventProjectGroupId, input.GroupName);
var query = _personRepository.AsQueryable()
.LeftJoin<EventRegistration>((p, r) => p.RegistrationId == r.Id)
@ -110,7 +116,12 @@ public class EventScoreService : BaseService<EventResult>, ITransient
query = query.Where(p => p.ProjectId == input.ProjectId.Value);
}
if (!string.IsNullOrWhiteSpace(input.GroupName))
// 优先使用 EventProjectGroupId,如果没有则使用 GroupName
if (input.EventProjectGroupId.HasValue)
{
query = query.Where(p => p.EventProjectGroupId == input.EventProjectGroupId.Value);
}
else if (!string.IsNullOrWhiteSpace(input.GroupName))
{
query = query.Where(p => p.GroupName == input.GroupName);
}
@ -383,18 +394,27 @@ public class EventScoreService : BaseService<EventResult>, ITransient
var result = new IssueCertificateResult();
var now = DateTime.Now;
// 如果指定了模板,验证模板是否存在
CertificateTemplate? template = null;
if (input.TemplateId.HasValue)
// 验证证书是否存在并获取证书信息
var certificate = await _certificateMasterRepository.GetFirstAsync(x =>
x.Id == input.CertificateId &&
x.Status == AvailabilityStatus.Enable &&
!x.DeleteMark);
if (certificate == null)
{
template = await _templateRepository.GetFirstAsync(x =>
x.Id == input.TemplateId.Value &&
x.Status == AvailabilityStatus.Enable &&
!x.DeleteMark);
if (template == null)
{
throw Oops.Bah("指定的证书模板不存在或不可用");
}
throw Oops.Bah("指定的证书不存在或不可用");
}
// 根据证书获取对应的模板ID
var templateId = certificate.TemplateId;
// 验证模板是否存在
var template = await _templateRepository.GetFirstAsync(x =>
x.Id == templateId &&
x.Status == AvailabilityStatus.Enable &&
!x.DeleteMark);
if (template == null)
{
throw Oops.Bah("证书关联的模板不存在或不可用");
}
// 批量预加载所有需要的数据
@ -450,7 +470,8 @@ public class EventScoreService : BaseService<EventResult>, ITransient
GeneratedTime = now,
CertificateNo = $"C{now:yyyyMMdd}{person.Id}",
CreatedTime = now,
TemplateId = input.TemplateId
TemplateId = templateId,
CertificateUrl = string.Empty // 暂时设置为空字符串,避免 null
};
certsToInsert.Add(cert);
}
@ -475,7 +496,8 @@ public class EventScoreService : BaseService<EventResult>, ITransient
GeneratedTime = now,
CertificateNo = $"CC{now:yyyyMMdd}{person.Id}",
CreatedTime = now,
TemplateId = input.TemplateId
TemplateId = templateId,
CertificateUrl = string.Empty // 暂时设置为空字符串,避免 null
};
certsToInsert.Add(cert);
}
@ -485,6 +507,11 @@ public class EventScoreService : BaseService<EventResult>, ITransient
cert.CertificateStatus = 2;
cert.IssuedTime = now;
cert.UpdatedTime = now;
// 确保 CertificateUrl 不为 null
if (string.IsNullOrEmpty(cert.CertificateUrl))
{
cert.CertificateUrl = string.Empty;
}
result.SuccessCount++;
}