feat: 完善裁判成绩修正与画板附件闭环
This commit is contained in:
parent
c95f85f99f
commit
3277a76730
@ -75,6 +75,9 @@ public class JudgeBoardSheetScoreOutput
|
||||
/// 是否由该裁判判定取消比赛资格
|
||||
/// </summary>
|
||||
public bool IsDisqualified { get; set; }
|
||||
|
||||
/// <summary>裁判记录画板地址。</summary>
|
||||
public string? AnnotationUrl { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@ -62,6 +62,7 @@ public class JudgeScoreService : IDynamicApiController, ITransient
|
||||
private readonly ISqlSugarRepository<EventJudgeScoreSheet> _sheetRepository;
|
||||
private readonly ISqlSugarRepository<EventScoreCorrection> _correctionRepository;
|
||||
private readonly ISqlSugarRepository<EventJudgeMessage> _messageRepository;
|
||||
private readonly ISqlSugarRepository<EventJudgeScoreAttachment> _attachmentRepository;
|
||||
private readonly ISqlSugarRepository<YD_Event.Core.Entities.Referee> _refereeRepository;
|
||||
private readonly ISqlSugarRepository<EventResult> _resultRepository;
|
||||
private readonly EventScoreCalculationService _calculationService;
|
||||
@ -75,6 +76,7 @@ public class JudgeScoreService : IDynamicApiController, ITransient
|
||||
ISqlSugarRepository<EventJudgeScoreSheet> sheetRepository,
|
||||
ISqlSugarRepository<EventScoreCorrection> correctionRepository,
|
||||
ISqlSugarRepository<EventJudgeMessage> messageRepository,
|
||||
ISqlSugarRepository<EventJudgeScoreAttachment> attachmentRepository,
|
||||
ISqlSugarRepository<YD_Event.Core.Entities.Referee> refereeRepository,
|
||||
ISqlSugarRepository<EventResult> resultRepository,
|
||||
EventScoreCalculationService calculationService, IIdGenerator idGenerator, AuthManager authManager)
|
||||
@ -82,6 +84,7 @@ public class JudgeScoreService : IDynamicApiController, ITransient
|
||||
_sessionRepository = sessionRepository; _entryRepository = entryRepository; _venueRepository = venueRepository;
|
||||
_ruleRepository = ruleRepository; _assignmentRepository = assignmentRepository; _sheetRepository = sheetRepository;
|
||||
_correctionRepository = correctionRepository; _messageRepository = messageRepository;
|
||||
_attachmentRepository = attachmentRepository;
|
||||
_refereeRepository = refereeRepository; _resultRepository = resultRepository;
|
||||
_calculationService = calculationService; _idGenerator = idGenerator; _authManager = authManager;
|
||||
}
|
||||
@ -387,6 +390,13 @@ public class JudgeScoreService : IDynamicApiController, ITransient
|
||||
var entryIds = outcomes.Select(x => (long?)x.SessionEntryId).ToList();
|
||||
var results = await _resultRepository.GetListAsync(x => entryIds.Contains(x.SessionEntryId)
|
||||
&& x.ResultStatus != EventScoreCalculationService.ResultStatusVoided);
|
||||
var sheetIds = outcomes.SelectMany(x => x.Aggregate?.Symbols ?? new List<EntrySymbolScore>())
|
||||
.SelectMany(x => x.Judges).Select(x => x.ScoreSheetId).Distinct().ToList();
|
||||
var annotationUrls = sheetIds.Count == 0
|
||||
? new Dictionary<long, string>()
|
||||
: (await _attachmentRepository.GetListAsync(x => sheetIds.Contains(x.ScoreSheetId)
|
||||
&& x.IsCurrent && x.AttachmentType == "score_annotation_png"))
|
||||
.GroupBy(x => x.ScoreSheetId).ToDictionary(x => x.Key, x => x.OrderByDescending(y => y.CreatedTime).First().FileUrl);
|
||||
// 一个出场(队伍)的多名运动员共享同一名次,取任意一条即可。
|
||||
var resultByEntry = results.Where(x => x.SessionEntryId.HasValue)
|
||||
.GroupBy(x => x.SessionEntryId!.Value).ToDictionary(x => x.Key, x => x.First());
|
||||
@ -428,7 +438,8 @@ public class JudgeScoreService : IDynamicApiController, ITransient
|
||||
ScoreSheetId = judge.ScoreSheetId, RefereeId = judge.RefereeId,
|
||||
RefereeName = judge.JudgeName ?? string.Empty, JudgeRole = judge.JudgeRole,
|
||||
JudgeRoleType = judge.JudgeRoleType, Value = ctx.Config.Format(judge.Value),
|
||||
IsDisqualified = judge.IsDisqualified
|
||||
IsDisqualified = judge.IsDisqualified,
|
||||
AnnotationUrl = annotationUrls.GetValueOrDefault(judge.ScoreSheetId)
|
||||
}).ToList()
|
||||
}).ToList();
|
||||
}
|
||||
|
||||
@ -173,8 +173,14 @@ public class EventScoreCalculationService : ITransient
|
||||
// 已提交裁判分配即本场的应到裁判名单,只统计计分规则里参与计分的类型。
|
||||
var assignments = await _assignmentRepository.GetListAsync(x => x.SessionId == sessionId && x.AssignmentStatus == 1);
|
||||
var entryIds = entries.Select(x => x.Id).ToList();
|
||||
var sheets = await _sheetRepository.GetListAsync(x => entryIds.Contains(x.SessionEntryId)
|
||||
&& x.IsCurrent && x.SheetStatus >= SheetStatusSubmitted);
|
||||
var assignmentIds = assignments.Select(x => x.Id).ToList();
|
||||
// 历史席位被替换后,其旧评分单仍需留档,但不能继续参与当前场次汇总。
|
||||
// 否则同一角色会出现超过规则席位数的评分,并污染平均分与最终成绩。
|
||||
var sheets = assignmentIds.Count == 0
|
||||
? new List<EventJudgeScoreSheet>()
|
||||
: await _sheetRepository.GetListAsync(x => entryIds.Contains(x.SessionEntryId)
|
||||
&& assignmentIds.Contains(x.JudgeAssignmentId)
|
||||
&& x.IsCurrent && x.SheetStatus >= SheetStatusSubmitted);
|
||||
var judgeNames = await LoadJudgeNamesAsync(assignments);
|
||||
var sheetsByEntry = sheets.GroupBy(x => x.SessionEntryId).ToDictionary(x => x.Key, x => x.ToList());
|
||||
|
||||
|
||||
@ -426,6 +426,9 @@ public class JudgeScoreSheetOutput
|
||||
/// </summary>
|
||||
public long ScoreSheetId { get; set; }
|
||||
|
||||
/// <summary>评分单版本;未产生评分单时为下一待提交版本。</summary>
|
||||
public int SheetVersion { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 评分单状态:0-草稿,10-已提交,20-已确认,30-已被修正,90-已作废
|
||||
/// </summary>
|
||||
@ -817,6 +820,9 @@ public class JudgeSymbolScoreDto
|
||||
/// </summary>
|
||||
public class JudgeSymbolJudgeDto
|
||||
{
|
||||
/// <summary>评分单ID。</summary>
|
||||
public long ScoreSheetId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 裁判席位编码
|
||||
/// </summary>
|
||||
@ -831,6 +837,9 @@ public class JudgeSymbolJudgeDto
|
||||
/// 该裁判的得分
|
||||
/// </summary>
|
||||
public string Value { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>该评分单当前记录画板地址。</summary>
|
||||
public string? AnnotationUrl { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -838,6 +847,9 @@ public class JudgeSymbolJudgeDto
|
||||
/// </summary>
|
||||
public class JudgeCorrectionCandidateDto
|
||||
{
|
||||
/// <summary>最近一次修正流程ID。</summary>
|
||||
public long? CorrectionId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 评分单ID
|
||||
/// </summary>
|
||||
@ -878,6 +890,12 @@ public class JudgeCorrectionCandidateDto
|
||||
/// </summary>
|
||||
public string CorrectionStatusName { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>修正申请原因。</summary>
|
||||
public string? ApplyReason { get; set; }
|
||||
|
||||
/// <summary>审批意见。</summary>
|
||||
public string? ApproveRemark { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 是否可以申请修正
|
||||
/// </summary>
|
||||
@ -940,6 +958,15 @@ public class JudgeMessageDto
|
||||
/// </summary>
|
||||
public long? RelationId { get; set; }
|
||||
|
||||
/// <summary>关联场次ID。</summary>
|
||||
public long? SessionId { get; set; }
|
||||
|
||||
/// <summary>关联出场记录ID。</summary>
|
||||
public long? SessionEntryId { get; set; }
|
||||
|
||||
/// <summary>关联评分单ID。</summary>
|
||||
public long? ScoreSheetId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 是否已读
|
||||
/// </summary>
|
||||
@ -961,3 +988,23 @@ public class ReadJudgeMessageInput
|
||||
/// </summary>
|
||||
public List<long> MessageIds { get; set; } = new();
|
||||
}
|
||||
|
||||
/// <summary>记录画板 PNG 上传输入。</summary>
|
||||
public class UploadJudgeScoreAnnotationInput
|
||||
{
|
||||
public long ScoreSheetId { get; set; }
|
||||
public string IdempotencyKey { get; set; } = null!;
|
||||
public IFormFile File { get; set; } = null!;
|
||||
}
|
||||
|
||||
/// <summary>记录画板附件。</summary>
|
||||
public class JudgeScoreAttachmentDto
|
||||
{
|
||||
public long Id { get; set; }
|
||||
public long ScoreSheetId { get; set; }
|
||||
public string AttachmentType { get; set; } = string.Empty;
|
||||
public string FileName { get; set; } = string.Empty;
|
||||
public string FileUrl { get; set; } = string.Empty;
|
||||
public long FileSize { get; set; }
|
||||
public DateTime UploadedTime { get; set; }
|
||||
}
|
||||
|
||||
@ -1,5 +1,7 @@
|
||||
using YD_Event.Application.Auth;
|
||||
using YD_Event.Application.Common;
|
||||
using YD_Event.Application.Scoring.Dtos;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace YD_Event.Application.Scoring;
|
||||
|
||||
@ -15,6 +17,7 @@ namespace YD_Event.Application.Scoring;
|
||||
/// 裁判提交的分值一律在服务端按计分规则重算,客户端上传的合计值不参与落库。
|
||||
/// </summary>
|
||||
[ApiDescriptionSettings("打分系统")]
|
||||
[Route("api")]
|
||||
[Authorize]
|
||||
public class JudgeScoringController : IDynamicApiController
|
||||
{
|
||||
@ -33,11 +36,13 @@ public class JudgeScoringController : IDynamicApiController
|
||||
private readonly ISqlSugarRepository<EventJudgeScoreDetail> _detailRepository;
|
||||
private readonly ISqlSugarRepository<EventScoreCorrection> _correctionRepository;
|
||||
private readonly ISqlSugarRepository<EventJudgeMessage> _messageRepository;
|
||||
private readonly ISqlSugarRepository<EventJudgeScoreAttachment> _attachmentRepository;
|
||||
private readonly ISqlSugarRepository<EventResult> _resultRepository;
|
||||
private readonly ISqlSugarRepository<EventRegistrationPerson> _personRepository;
|
||||
private readonly EventScoreCalculationService _calculationService;
|
||||
private readonly AuthManager _authManager;
|
||||
private readonly IIdGenerator _idGenerator;
|
||||
private readonly FileService _fileService;
|
||||
|
||||
public JudgeScoringController(
|
||||
ISqlSugarRepository<YD_Event.Core.Entities.AppUser> userRepository,
|
||||
@ -55,11 +60,13 @@ public class JudgeScoringController : IDynamicApiController
|
||||
ISqlSugarRepository<EventJudgeScoreDetail> detailRepository,
|
||||
ISqlSugarRepository<EventScoreCorrection> correctionRepository,
|
||||
ISqlSugarRepository<EventJudgeMessage> messageRepository,
|
||||
ISqlSugarRepository<EventJudgeScoreAttachment> attachmentRepository,
|
||||
ISqlSugarRepository<EventResult> resultRepository,
|
||||
ISqlSugarRepository<EventRegistrationPerson> personRepository,
|
||||
EventScoreCalculationService calculationService,
|
||||
AuthManager authManager,
|
||||
IIdGenerator idGenerator)
|
||||
IIdGenerator idGenerator,
|
||||
FileService fileService)
|
||||
{
|
||||
_userRepository = userRepository;
|
||||
_refereeRepository = refereeRepository;
|
||||
@ -76,11 +83,13 @@ public class JudgeScoringController : IDynamicApiController
|
||||
_detailRepository = detailRepository;
|
||||
_correctionRepository = correctionRepository;
|
||||
_messageRepository = messageRepository;
|
||||
_attachmentRepository = attachmentRepository;
|
||||
_resultRepository = resultRepository;
|
||||
_personRepository = personRepository;
|
||||
_calculationService = calculationService;
|
||||
_authManager = authManager;
|
||||
_idGenerator = idGenerator;
|
||||
_fileService = fileService;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -253,6 +262,7 @@ public class JudgeScoringController : IDynamicApiController
|
||||
SessionId = ctx.Session.Id,
|
||||
JudgeTaskId = draft?.JudgeTaskId ?? submitted?.JudgeTaskId ?? 0,
|
||||
ScoreSheetId = source?.Id ?? 0,
|
||||
SheetVersion = source?.SheetVersion ?? nextVersion,
|
||||
SheetStatus = source?.SheetStatus ?? SheetStatusDraft,
|
||||
CanEdit = canEdit,
|
||||
LockReason = canEdit ? null : "已提交评分,如需修改请先申请成绩修正",
|
||||
@ -346,6 +356,19 @@ public class JudgeScoringController : IDynamicApiController
|
||||
var nextVersion = (submitted?.SheetVersion ?? 0) + 1;
|
||||
await UpsertSheetAsync(draft, entry, ctx, assignment, roleType, task, calculation,
|
||||
SheetStatusDraft, nextVersion, $"{assignment.Id}-{entry.Id}-v{nextVersion}-draft", null, null, null);
|
||||
if (submitted != null)
|
||||
{
|
||||
var correction = await _correctionRepository.GetFirstAsync(x => x.OriginalScoreSheetId == submitted.Id
|
||||
&& x.CorrectionStatus == CorrectionStatusApproved);
|
||||
if (correction != null)
|
||||
{
|
||||
correction.CorrectionTaskId = task.Id;
|
||||
correction.CorrectionStatus = CorrectionStatusEditing;
|
||||
correction.UpdatedUserId = _authManager.UserId;
|
||||
correction.UpdatedTime = DateTime.Now;
|
||||
await _correctionRepository.UpdateAsync(correction);
|
||||
}
|
||||
}
|
||||
return ToPreviewDto(calculation, ctx.Config);
|
||||
}
|
||||
|
||||
@ -387,23 +410,24 @@ public class JudgeScoringController : IDynamicApiController
|
||||
var draft = await _sheetRepository.GetFirstAsync(x => x.SessionEntryId == entry.Id
|
||||
&& x.JudgeAssignmentId == assignment.Id && x.SheetStatus == SheetStatusDraft);
|
||||
var nextVersion = (submitted?.SheetVersion ?? 0) + 1;
|
||||
var sheet = await UpsertSheetAsync(draft, entry, ctx, assignment, roleType, task, calculation,
|
||||
EventScoreCalculationService.SheetStatusSubmitted, nextVersion,
|
||||
idempotencyKey ?? $"{assignment.Id}-{entry.Id}-v{nextVersion}",
|
||||
input.DisqualifyRemark, submitted?.Id, correction?.ApplyReason);
|
||||
|
||||
var now = DateTime.Now;
|
||||
if (submitted != null)
|
||||
{
|
||||
// 修正后的评分单接替原评分单,原评分单留档但不再参与计分。
|
||||
// 当前版本唯一索引要求先让原评分单退出当前态;UnitOfWork 会在后续失败时整体回滚。
|
||||
submitted.IsCurrent = false;
|
||||
submitted.SheetStatus = SheetStatusCorrected;
|
||||
submitted.UpdatedUserId = _authManager.UserId;
|
||||
submitted.UpdatedTime = now;
|
||||
await _sheetRepository.UpdateAsync(submitted);
|
||||
}
|
||||
var sheet = await UpsertSheetAsync(draft, entry, ctx, assignment, roleType, task, calculation,
|
||||
EventScoreCalculationService.SheetStatusSubmitted, nextVersion,
|
||||
idempotencyKey ?? $"{assignment.Id}-{entry.Id}-v{nextVersion}",
|
||||
input.DisqualifyRemark, submitted?.Id, correction?.ApplyReason);
|
||||
|
||||
if (correction != null)
|
||||
{
|
||||
correction.CorrectionTaskId = task.Id;
|
||||
correction.NewScoreSheetId = sheet.Id;
|
||||
correction.CorrectionStatus = CorrectionStatusCompleted;
|
||||
correction.CompletedTime = now;
|
||||
@ -432,13 +456,24 @@ public class JudgeScoringController : IDynamicApiController
|
||||
public async Task<List<JudgeEntryResultDto>> GetResults(long sessionId)
|
||||
{
|
||||
var referee = await EnsureRefereeAsync();
|
||||
await GetMyAssignmentAsync(sessionId, referee.Id);
|
||||
var assignment = await GetMyAssignmentAsync(sessionId, referee.Id);
|
||||
var roleType = JudgeRoleSchemaService.NormalizeRoleType(
|
||||
string.IsNullOrWhiteSpace(assignment.JudgeRoleType) ? assignment.JudgeRole : assignment.JudgeRoleType);
|
||||
if (!string.Equals(roleType, JudgeRoleSchemaService.RoleChief, StringComparison.OrdinalIgnoreCase))
|
||||
throw Oops.Bah("仅主裁判可查看场次最终成绩");
|
||||
var ctx = await _calculationService.LoadContextAsync(sessionId);
|
||||
var outcomes = await _calculationService.EvaluateSessionAsync(sessionId, ctx);
|
||||
var entryIds = outcomes.Select(x => (long?)x.SessionEntryId).ToList();
|
||||
var results = entryIds.Count == 0
|
||||
? new List<EventResult>()
|
||||
: await _resultRepository.GetListAsync(x => entryIds.Contains(x.SessionEntryId));
|
||||
var scoreSheetIds = outcomes.SelectMany(x => x.Aggregate?.Symbols ?? new List<EntrySymbolScore>())
|
||||
.SelectMany(x => x.Judges).Select(x => x.ScoreSheetId).Distinct().ToList();
|
||||
var annotationUrls = scoreSheetIds.Count == 0
|
||||
? new Dictionary<long, string>()
|
||||
: (await _attachmentRepository.GetListAsync(x => scoreSheetIds.Contains(x.ScoreSheetId)
|
||||
&& x.IsCurrent && x.AttachmentType == AnnotationAttachmentType))
|
||||
.GroupBy(x => x.ScoreSheetId).ToDictionary(x => x.Key, x => x.OrderByDescending(y => y.CreatedTime).First().FileUrl);
|
||||
|
||||
return outcomes.Select(outcome =>
|
||||
{
|
||||
@ -461,9 +496,11 @@ public class JudgeScoringController : IDynamicApiController
|
||||
Value = ctx.Config.Format(symbol.Value),
|
||||
Judges = symbol.Judges.Select(judge => new JudgeSymbolJudgeDto
|
||||
{
|
||||
ScoreSheetId = judge.ScoreSheetId,
|
||||
JudgeRole = judge.JudgeRole,
|
||||
JudgeName = judge.JudgeName ?? string.Empty,
|
||||
Value = ctx.Config.Format(judge.Value)
|
||||
Value = ctx.Config.Format(judge.Value),
|
||||
AnnotationUrl = annotationUrls.GetValueOrDefault(judge.ScoreSheetId)
|
||||
}).ToList()
|
||||
}).ToList(),
|
||||
Factors = !ctx.Config.IsFactorTotal || outcome.Aggregate == null
|
||||
@ -497,18 +534,22 @@ public class JudgeScoringController : IDynamicApiController
|
||||
if (sheets.Count == 0) return new List<JudgeCorrectionCandidateDto>();
|
||||
|
||||
var sheetIds = sheets.Select(x => x.Id).ToList();
|
||||
var corrections = await _correctionRepository.GetListAsync(x => sheetIds.Contains(x.OriginalScoreSheetId));
|
||||
var corrections = await _correctionRepository.GetListAsync(x => sheetIds.Contains(x.OriginalScoreSheetId)
|
||||
|| (x.NewScoreSheetId.HasValue && sheetIds.Contains(x.NewScoreSheetId.Value)));
|
||||
var entryIds = sheets.Select(x => x.SessionEntryId).Distinct().ToList();
|
||||
var entries = (await _entryRepository.GetListAsync(x => entryIds.Contains(x.Id))).ToDictionary(x => x.Id);
|
||||
|
||||
return sheets.Select(sheet =>
|
||||
{
|
||||
var entry = entries.GetValueOrDefault(sheet.SessionEntryId);
|
||||
var correction = corrections.Where(x => x.OriginalScoreSheetId == sheet.Id)
|
||||
// 修正完成后当前评分单已经变成 NewScoreSheetId,仍需返回最近一次流程状态,
|
||||
// 否则 App 会把刚完成的修正误显示成“可首次申请”。
|
||||
var correction = corrections.Where(x => x.OriginalScoreSheetId == sheet.Id || x.NewScoreSheetId == sheet.Id)
|
||||
.OrderByDescending(x => x.CreatedTime).FirstOrDefault();
|
||||
var status = correction?.CorrectionStatus ?? -1;
|
||||
return new JudgeCorrectionCandidateDto
|
||||
{
|
||||
CorrectionId = correction?.Id,
|
||||
ScoreSheetId = sheet.Id,
|
||||
SessionEntryId = sheet.SessionEntryId,
|
||||
EntryNo = entry?.EntryNo ?? string.Empty,
|
||||
@ -518,6 +559,8 @@ public class JudgeScoringController : IDynamicApiController
|
||||
SubmittedTime = sheet.SubmittedTime,
|
||||
CorrectionStatus = status,
|
||||
CorrectionStatusName = CorrectionStatusName(status),
|
||||
ApplyReason = correction?.ApplyReason,
|
||||
ApproveRemark = correction?.ApproveRemark,
|
||||
// 已在流程中的评分单不能重复申请,被拒绝或已完成的可以再次申请。
|
||||
CanApply = status is -1 or CorrectionStatusRejected or CorrectionStatusCompleted or CorrectionStatusCancelled
|
||||
};
|
||||
@ -552,7 +595,7 @@ public class JudgeScoringController : IDynamicApiController
|
||||
OriginalScoreSheetId = sheet.Id,
|
||||
JudgeAssignmentId = sheet.JudgeAssignmentId,
|
||||
JudgeRole = sheet.JudgeRole,
|
||||
ApplyUserId = _authManager.UserId,
|
||||
ApplyRefereeId = referee.Id,
|
||||
ApplyReason = input.ApplyReason.Trim(),
|
||||
CorrectionStatus = ctx.Config.CorrectionNeedApproval ? CorrectionStatusApplied : CorrectionStatusApproved,
|
||||
CreatedUserId = _authManager.UserId,
|
||||
@ -581,10 +624,21 @@ public class JudgeScoringController : IDynamicApiController
|
||||
.WhereIF(onlyUnread == true, x => !x.IsRead)
|
||||
.ToListAsync())
|
||||
.OrderByDescending(x => x.CreatedTime).ToList();
|
||||
var correctionIds = messages
|
||||
.Where(x => string.Equals(x.RelationType, nameof(EventScoreCorrection), StringComparison.OrdinalIgnoreCase)
|
||||
&& x.RelationId.HasValue)
|
||||
.Select(x => x.RelationId!.Value).Distinct().ToList();
|
||||
var corrections = correctionIds.Count == 0
|
||||
? new Dictionary<long, EventScoreCorrection>()
|
||||
: (await _correctionRepository.GetListAsync(x => correctionIds.Contains(x.Id))).ToDictionary(x => x.Id);
|
||||
return messages.Select(x => new JudgeMessageDto
|
||||
{
|
||||
Id = x.Id, EventId = x.EventId, MessageType = x.MessageType, Title = x.Title, Content = x.Content,
|
||||
RelationType = x.RelationType, RelationId = x.RelationId, IsRead = x.IsRead, CreatedTime = x.CreatedTime
|
||||
RelationType = x.RelationType, RelationId = x.RelationId,
|
||||
SessionId = x.RelationId.HasValue ? corrections.GetValueOrDefault(x.RelationId.Value)?.SessionId : null,
|
||||
SessionEntryId = x.RelationId.HasValue ? corrections.GetValueOrDefault(x.RelationId.Value)?.SessionEntryId : null,
|
||||
ScoreSheetId = x.RelationId.HasValue ? corrections.GetValueOrDefault(x.RelationId.Value)?.OriginalScoreSheetId : null,
|
||||
IsRead = x.IsRead, CreatedTime = x.CreatedTime
|
||||
}).ToList();
|
||||
}
|
||||
|
||||
@ -607,6 +661,82 @@ public class JudgeScoringController : IDynamicApiController
|
||||
await _messageRepository.UpdateRangeAsync(messages);
|
||||
}
|
||||
|
||||
/// <summary>上传当前裁判评分单的记录画板 PNG。</summary>
|
||||
[HttpPost("judge-scoring/annotations/upload")]
|
||||
[DisplayName("上传裁判记录画板")]
|
||||
[UnitOfWork]
|
||||
public async Task<JudgeScoreAttachmentDto> UploadAnnotation([FromForm] UploadJudgeScoreAnnotationInput input)
|
||||
{
|
||||
var referee = await EnsureRefereeAsync();
|
||||
var sheet = await _sheetRepository.GetFirstAsync(x => x.Id == input.ScoreSheetId && x.RefereeId == referee.Id);
|
||||
if (sheet == null) throw Oops.Bah("评分单不存在或不属于当前裁判");
|
||||
if (sheet.SheetStatus < EventScoreCalculationService.SheetStatusSubmitted)
|
||||
throw Oops.Bah("请先提交成绩,再上传记录画板");
|
||||
var key = input.IdempotencyKey?.Trim() ?? string.Empty;
|
||||
if (key.Length is < 8 or > 64 || !Regex.IsMatch(key, "^[A-Za-z0-9_-]+$"))
|
||||
throw Oops.Bah("画板上传幂等键无效");
|
||||
var replay = await _attachmentRepository.GetFirstAsync(x => x.ScoreSheetId == sheet.Id && x.IdempotencyKey == key);
|
||||
if (replay != null) return ToAttachmentDto(replay);
|
||||
|
||||
var file = input.File;
|
||||
if (file == null || file.Length == 0) throw Oops.Bah("请选择画板 PNG 文件");
|
||||
if (file.Length > MaxAnnotationBytes) throw Oops.Bah("画板图片不能超过5MB");
|
||||
if (!string.Equals(Path.GetExtension(file.FileName), ".png", StringComparison.OrdinalIgnoreCase)
|
||||
|| !string.Equals(file.ContentType, "image/png", StringComparison.OrdinalIgnoreCase))
|
||||
throw Oops.Bah("画板仅支持PNG格式");
|
||||
await using var stream = file.OpenReadStream();
|
||||
var signature = new byte[8];
|
||||
if (await stream.ReadAsync(signature.AsMemory(0, signature.Length)) != signature.Length
|
||||
|| !signature.SequenceEqual(PngSignature))
|
||||
throw Oops.Bah("上传文件不是有效的PNG图片");
|
||||
stream.Position = 0;
|
||||
var objectName = $"judge-score-annotations/{sheet.EventId}/{sheet.Id}/{key}.png";
|
||||
var url = await _fileService.UploadFileStreamAsync(objectName, stream);
|
||||
|
||||
var now = DateTime.Now;
|
||||
var current = await _attachmentRepository.GetListAsync(x => x.ScoreSheetId == sheet.Id
|
||||
&& x.AttachmentType == AnnotationAttachmentType && x.IsCurrent);
|
||||
foreach (var old in current)
|
||||
{
|
||||
old.IsCurrent = false;
|
||||
old.UpdatedUserId = _authManager.UserId;
|
||||
old.UpdatedTime = now;
|
||||
}
|
||||
if (current.Count > 0) await _attachmentRepository.UpdateRangeAsync(current);
|
||||
var attachment = new EventJudgeScoreAttachment
|
||||
{
|
||||
Id = _idGenerator.NextId(), EventId = sheet.EventId, SessionId = sheet.SessionId,
|
||||
SessionEntryId = sheet.SessionEntryId, ScoreSheetId = sheet.Id,
|
||||
JudgeAssignmentId = sheet.JudgeAssignmentId, RefereeId = referee.Id,
|
||||
AttachmentType = AnnotationAttachmentType, FileName = Path.GetFileName(file.FileName),
|
||||
FileUrl = url, FileSize = file.Length, ContentType = "image/png", IdempotencyKey = key,
|
||||
IsCurrent = true, CreatedUserId = _authManager.UserId, CreatedTime = now
|
||||
};
|
||||
await _attachmentRepository.InsertAsync(attachment);
|
||||
return ToAttachmentDto(attachment);
|
||||
}
|
||||
|
||||
/// <summary>查询评分单当前记录画板。</summary>
|
||||
[HttpGet("judge-scoring/annotations/{scoreSheetId}")]
|
||||
[DisplayName("查询裁判记录画板")]
|
||||
public async Task<JudgeScoreAttachmentDto?> GetAnnotation(long scoreSheetId)
|
||||
{
|
||||
var referee = await EnsureRefereeAsync();
|
||||
var sheet = await _sheetRepository.GetFirstAsync(x => x.Id == scoreSheetId);
|
||||
if (sheet == null) throw Oops.Bah("评分单不存在");
|
||||
if (sheet.RefereeId != referee.Id)
|
||||
{
|
||||
var assignment = await GetMyAssignmentAsync(sheet.SessionId, referee.Id);
|
||||
var roleType = JudgeRoleSchemaService.NormalizeRoleType(
|
||||
string.IsNullOrWhiteSpace(assignment.JudgeRoleType) ? assignment.JudgeRole : assignment.JudgeRoleType);
|
||||
if (!string.Equals(roleType, JudgeRoleSchemaService.RoleChief, StringComparison.OrdinalIgnoreCase))
|
||||
throw Oops.Bah("无权查看该评分单画板");
|
||||
}
|
||||
var attachment = await _attachmentRepository.GetFirstAsync(x => x.ScoreSheetId == scoreSheetId
|
||||
&& x.AttachmentType == AnnotationAttachmentType && x.IsCurrent);
|
||||
return attachment == null ? null : ToAttachmentDto(attachment);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 校验当前登录用户的裁判身份并取出裁判档案
|
||||
/// </summary>
|
||||
@ -668,6 +798,17 @@ public class JudgeScoringController : IDynamicApiController
|
||||
|| x.CorrectionStatus == CorrectionStatusApproved
|
||||
|| x.CorrectionStatus == CorrectionStatusEditing));
|
||||
|
||||
private static JudgeScoreAttachmentDto ToAttachmentDto(EventJudgeScoreAttachment attachment) => new()
|
||||
{
|
||||
Id = attachment.Id,
|
||||
ScoreSheetId = attachment.ScoreSheetId,
|
||||
AttachmentType = attachment.AttachmentType,
|
||||
FileName = attachment.FileName,
|
||||
FileUrl = attachment.FileUrl,
|
||||
FileSize = attachment.FileSize,
|
||||
UploadedTime = attachment.CreatedTime
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// 取(或按需创建)本裁判在该出场上的评分任务
|
||||
/// </summary>
|
||||
@ -675,7 +816,8 @@ public class JudgeScoringController : IDynamicApiController
|
||||
EventJudgeAssignment assignment, string roleType, int taskType)
|
||||
{
|
||||
var task = await _taskRepository.GetFirstAsync(x => x.SessionEntryId == entry.Id
|
||||
&& x.JudgeAssignmentId == assignment.Id && x.TaskType == taskType && x.TaskStatus != TaskStatusVoided);
|
||||
&& x.JudgeAssignmentId == assignment.Id && x.TaskType == taskType && x.TaskStatus != TaskStatusVoided
|
||||
&& (taskType != TaskTypeCorrection || x.TaskStatus != TaskStatusSubmitted));
|
||||
var now = DateTime.Now;
|
||||
if (task != null)
|
||||
{
|
||||
@ -690,6 +832,9 @@ public class JudgeScoringController : IDynamicApiController
|
||||
return task;
|
||||
}
|
||||
|
||||
var taskHistory = await _taskRepository.GetListAsync(x => x.SessionEntryId == entry.Id
|
||||
&& x.JudgeAssignmentId == assignment.Id && !x.DeleteMark);
|
||||
var previousTask = taskHistory.OrderByDescending(x => x.TaskVersion).FirstOrDefault();
|
||||
task = new EventJudgeTask
|
||||
{
|
||||
Id = _idGenerator.NextId(),
|
||||
@ -718,6 +863,8 @@ public class JudgeScoringController : IDynamicApiController
|
||||
scope = ctx.Scope
|
||||
}),
|
||||
TaskType = taskType,
|
||||
TaskVersion = (previousTask?.TaskVersion ?? 0) + 1,
|
||||
OriginalTaskId = taskType == TaskTypeCorrection ? previousTask?.Id : null,
|
||||
TaskStatus = TaskStatusAccepted,
|
||||
DispatchedTime = now,
|
||||
AcceptedTime = now,
|
||||
@ -826,7 +973,9 @@ public class JudgeScoringController : IDynamicApiController
|
||||
IsDuplicate = isDuplicate,
|
||||
MyScore = ctx.Config.Format(sheet.TotalScore),
|
||||
ResultCompleted = outcome?.IsCompleted ?? false,
|
||||
TotalScore = outcome == null || !outcome.IsCompleted ? null
|
||||
TotalScore = !string.Equals(JudgeRoleSchemaService.NormalizeRoleType(sheet.JudgeRoleType),
|
||||
JudgeRoleSchemaService.RoleChief, StringComparison.OrdinalIgnoreCase)
|
||||
|| outcome == null || !outcome.IsCompleted ? null
|
||||
: outcome.IsDisqualified ? "取消资格" : ctx.Config.Format(outcome.TotalScore),
|
||||
Progress = (outcome?.Roles ?? new List<EntryRoleProgress>()).Select(ToProgressDto).ToList()
|
||||
};
|
||||
@ -938,6 +1087,10 @@ public class JudgeScoringController : IDynamicApiController
|
||||
/// </summary>
|
||||
private const int CorrectionStatusCancelled = 90;
|
||||
|
||||
private const string AnnotationAttachmentType = "score_annotation_png";
|
||||
private const long MaxAnnotationBytes = 5L * 1024 * 1024;
|
||||
private static readonly byte[] PngSignature = [137, 80, 78, 71, 13, 10, 26, 10];
|
||||
|
||||
/// <summary>
|
||||
/// 出场状态:退赛
|
||||
/// </summary>
|
||||
|
||||
@ -601,7 +601,10 @@ public class WorkbenchController : IDynamicApiController
|
||||
|
||||
var sessionIds = corrections.Select(c => c.SessionId).Distinct().ToList();
|
||||
var entryIds = corrections.Select(c => c.SessionEntryId).Distinct().ToList();
|
||||
var applyUserIds = corrections.Select(c => c.ApplyUserId).Distinct().ToList();
|
||||
var applyUserIds = corrections.Where(c => c.ApplyUserId.HasValue)
|
||||
.Select(c => c.ApplyUserId!.Value).Distinct().ToList();
|
||||
var applyRefereeIds = corrections.Where(c => c.ApplyRefereeId.HasValue)
|
||||
.Select(c => c.ApplyRefereeId!.Value).Distinct().ToList();
|
||||
var approveUserIds = corrections.Where(c => c.ApproveUserId.HasValue).Select(c => c.ApproveUserId!.Value).Distinct().ToList();
|
||||
|
||||
var sessions = (await _sessionRepository.AsQueryable()
|
||||
@ -619,11 +622,16 @@ public class WorkbenchController : IDynamicApiController
|
||||
var eventInfo = await _eventRepository.GetFirstAsync(e => e.Id == input.EventId);
|
||||
|
||||
var allUserIds = applyUserIds.Concat(approveUserIds).Distinct().ToList();
|
||||
var users = (await _userRepository.AsQueryable()
|
||||
var users = (await _sysUserRepository.AsQueryable()
|
||||
.Where(u => allUserIds.Contains(u.Id))
|
||||
.Select(u => new { u.Id, u.Name })
|
||||
.ToListAsync())
|
||||
.ToDictionary(u => u.Id, u => u.Name);
|
||||
var applyingReferees = (await _refereeRepository.AsQueryable()
|
||||
.Where(r => applyRefereeIds.Contains(r.Id))
|
||||
.Select(r => new { r.Id, r.Name })
|
||||
.ToListAsync())
|
||||
.ToDictionary(r => r.Id, r => r.Name);
|
||||
|
||||
return corrections.Select(c =>
|
||||
{
|
||||
@ -636,7 +644,9 @@ public class WorkbenchController : IDynamicApiController
|
||||
EntryNo = entry?.EntryNo ?? "",
|
||||
ParticipantName = entry?.ParticipantName ?? "",
|
||||
JudgeRole = c.JudgeRole,
|
||||
ApplyUserName = users.GetValueOrDefault(c.ApplyUserId, ""),
|
||||
ApplyUserName = c.ApplyRefereeId.HasValue
|
||||
? applyingReferees.GetValueOrDefault(c.ApplyRefereeId.Value, "")
|
||||
: c.ApplyUserId.HasValue ? users.GetValueOrDefault(c.ApplyUserId.Value, "") : "",
|
||||
ApplyReason = c.ApplyReason,
|
||||
CreatedTime = c.CreatedTime,
|
||||
CorrectionStatus = c.CorrectionStatus,
|
||||
@ -679,7 +689,12 @@ public class WorkbenchController : IDynamicApiController
|
||||
var eventProject = await _eventProjectRepository.GetByIdAsync(session.EventProjectId);
|
||||
var project = eventProject != null ? await _projectRepository.GetByIdAsync(eventProject.ProjectId) : null;
|
||||
|
||||
var applyUser = await _userRepository.GetByIdAsync(correction.ApplyUserId);
|
||||
var applyUser = correction.ApplyUserId.HasValue
|
||||
? await _sysUserRepository.GetByIdAsync(correction.ApplyUserId.Value)
|
||||
: null;
|
||||
var applyReferee = correction.ApplyRefereeId.HasValue
|
||||
? await _refereeRepository.GetByIdAsync(correction.ApplyRefereeId.Value)
|
||||
: null;
|
||||
var approveUser = correction.ApproveUserId.HasValue
|
||||
? await _userRepository.GetByIdAsync(correction.ApproveUserId.Value)
|
||||
: null;
|
||||
@ -765,7 +780,7 @@ public class WorkbenchController : IDynamicApiController
|
||||
SubmittedTime = newSheet.SubmittedTime,
|
||||
HasPendingCorrection = false
|
||||
} : null,
|
||||
ApplyUserName = applyUser?.Name ?? "",
|
||||
ApplyUserName = applyReferee?.Name ?? applyUser?.Name ?? "",
|
||||
ApplyReason = correction.ApplyReason,
|
||||
CreatedTime = correction.CreatedTime,
|
||||
CorrectionStatus = correction.CorrectionStatus,
|
||||
|
||||
@ -10614,6 +10614,9 @@
|
||||
是否由该裁判判定取消比赛资格
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:YD_Event.Application.Scoring.Dtos.JudgeBoardSheetScoreOutput.AnnotationUrl">
|
||||
<summary>裁判记录画板地址。</summary>
|
||||
</member>
|
||||
<member name="T:YD_Event.Application.Scoring.Dtos.JudgeSymbolScoreOutput">
|
||||
<summary>
|
||||
后台记分台:单个计分符号的聚合得分
|
||||
@ -12326,6 +12329,9 @@
|
||||
评分单ID(尚未保存过时为0)
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:YD_Event.Application.Scoring.Dtos.JudgeScoreSheetOutput.SheetVersion">
|
||||
<summary>评分单版本;未产生评分单时为下一待提交版本。</summary>
|
||||
</member>
|
||||
<member name="P:YD_Event.Application.Scoring.Dtos.JudgeScoreSheetOutput.SheetStatus">
|
||||
<summary>
|
||||
评分单状态:0-草稿,10-已提交,20-已确认,30-已被修正,90-已作废
|
||||
@ -12706,6 +12712,9 @@
|
||||
参与聚合的单个裁判得分
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:YD_Event.Application.Scoring.Dtos.JudgeSymbolJudgeDto.ScoreSheetId">
|
||||
<summary>评分单ID。</summary>
|
||||
</member>
|
||||
<member name="P:YD_Event.Application.Scoring.Dtos.JudgeSymbolJudgeDto.JudgeRole">
|
||||
<summary>
|
||||
裁判席位编码
|
||||
@ -12721,11 +12730,17 @@
|
||||
该裁判的得分
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:YD_Event.Application.Scoring.Dtos.JudgeSymbolJudgeDto.AnnotationUrl">
|
||||
<summary>该评分单当前记录画板地址。</summary>
|
||||
</member>
|
||||
<member name="T:YD_Event.Application.Scoring.Dtos.JudgeCorrectionCandidateDto">
|
||||
<summary>
|
||||
可申请成绩修正的评分单
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:YD_Event.Application.Scoring.Dtos.JudgeCorrectionCandidateDto.CorrectionId">
|
||||
<summary>最近一次修正流程ID。</summary>
|
||||
</member>
|
||||
<member name="P:YD_Event.Application.Scoring.Dtos.JudgeCorrectionCandidateDto.ScoreSheetId">
|
||||
<summary>
|
||||
评分单ID
|
||||
@ -12766,6 +12781,12 @@
|
||||
修正申请状态名称
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:YD_Event.Application.Scoring.Dtos.JudgeCorrectionCandidateDto.ApplyReason">
|
||||
<summary>修正申请原因。</summary>
|
||||
</member>
|
||||
<member name="P:YD_Event.Application.Scoring.Dtos.JudgeCorrectionCandidateDto.ApproveRemark">
|
||||
<summary>审批意见。</summary>
|
||||
</member>
|
||||
<member name="P:YD_Event.Application.Scoring.Dtos.JudgeCorrectionCandidateDto.CanApply">
|
||||
<summary>
|
||||
是否可以申请修正
|
||||
@ -12826,6 +12847,15 @@
|
||||
关联业务ID
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:YD_Event.Application.Scoring.Dtos.JudgeMessageDto.SessionId">
|
||||
<summary>关联场次ID。</summary>
|
||||
</member>
|
||||
<member name="P:YD_Event.Application.Scoring.Dtos.JudgeMessageDto.SessionEntryId">
|
||||
<summary>关联出场记录ID。</summary>
|
||||
</member>
|
||||
<member name="P:YD_Event.Application.Scoring.Dtos.JudgeMessageDto.ScoreSheetId">
|
||||
<summary>关联评分单ID。</summary>
|
||||
</member>
|
||||
<member name="P:YD_Event.Application.Scoring.Dtos.JudgeMessageDto.IsRead">
|
||||
<summary>
|
||||
是否已读
|
||||
@ -12846,6 +12876,12 @@
|
||||
消息ID,为空表示全部标记已读
|
||||
</summary>
|
||||
</member>
|
||||
<member name="T:YD_Event.Application.Scoring.Dtos.UploadJudgeScoreAnnotationInput">
|
||||
<summary>记录画板 PNG 上传输入。</summary>
|
||||
</member>
|
||||
<member name="T:YD_Event.Application.Scoring.Dtos.JudgeScoreAttachmentDto">
|
||||
<summary>记录画板附件。</summary>
|
||||
</member>
|
||||
<member name="T:YD_Event.Application.Scoring.Dtos.ScoringContext">
|
||||
<summary>
|
||||
一个场次的计分上下文:场次、项目、计分规则与评分项。裁判端取评分表、后台算成绩都基于同一份上下文。
|
||||
@ -13330,6 +13366,12 @@
|
||||
标记消息已读,不传消息ID表示全部标记已读
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:YD_Event.Application.Scoring.JudgeScoringController.UploadAnnotation(YD_Event.Application.Scoring.Dtos.UploadJudgeScoreAnnotationInput)">
|
||||
<summary>上传当前裁判评分单的记录画板 PNG。</summary>
|
||||
</member>
|
||||
<member name="M:YD_Event.Application.Scoring.JudgeScoringController.GetAnnotation(System.Int64)">
|
||||
<summary>查询评分单当前记录画板。</summary>
|
||||
</member>
|
||||
<member name="M:YD_Event.Application.Scoring.JudgeScoringController.EnsureRefereeAsync">
|
||||
<summary>
|
||||
校验当前登录用户的裁判身份并取出裁判档案
|
||||
@ -15568,34 +15610,54 @@
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:YD_Event.Application.OrderBook.Dtos.OrderBookEntryRow.Seq">
|
||||
<summary>序号(仅便于人工核对,导入时不参与落库)</summary>
|
||||
<summary>
|
||||
序号(仅便于人工核对,导入时不参与落库)
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:YD_Event.Application.OrderBook.Dtos.OrderBookEntryRow.VenueName">
|
||||
<summary>场地名称(必填)</summary>
|
||||
<summary>
|
||||
场地名称(必填)
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:YD_Event.Application.OrderBook.Dtos.OrderBookEntryRow.ProjectName">
|
||||
<summary>项目名称(必填,需与赛事已配置项目一致,不存在将自动建档)</summary>
|
||||
<summary>
|
||||
项目名称(必填,需与赛事已配置项目一致,不存在将自动建档)
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:YD_Event.Application.OrderBook.Dtos.OrderBookEntryRow.GroupName">
|
||||
<summary>组别名称(可空,空则归入“公开组”)</summary>
|
||||
<summary>
|
||||
组别名称(可空,空则归入"公开组")
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:YD_Event.Application.OrderBook.Dtos.OrderBookEntryRow.EntryNo">
|
||||
<summary>出场编号(可空,空则按同场次顺序自动生成)</summary>
|
||||
<summary>
|
||||
出场编号(可空,空则按同场次顺序自动生成)
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:YD_Event.Application.OrderBook.Dtos.OrderBookEntryRow.ParticipantName">
|
||||
<summary>姓名/队名(必填)</summary>
|
||||
<summary>
|
||||
姓名/队名(必填)
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:YD_Event.Application.OrderBook.Dtos.OrderBookEntryRow.UnitName">
|
||||
<summary>所属单位(可空,仅用于核对展示)</summary>
|
||||
<summary>
|
||||
所属单位(可空,仅用于核对展示)
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:YD_Event.Application.OrderBook.Dtos.OrderBookEntryRow.Mobile">
|
||||
<summary>联系电话(可空)</summary>
|
||||
<summary>
|
||||
联系电话(可空)
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:YD_Event.Application.OrderBook.Dtos.OrderBookEntryRow.IdCard">
|
||||
<summary>证件号(可空)</summary>
|
||||
<summary>
|
||||
证件号(可空)
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:YD_Event.Application.OrderBook.Dtos.OrderBookEntryRow.Remark">
|
||||
<summary>备注(可空)</summary>
|
||||
<summary>
|
||||
备注(可空)
|
||||
</summary>
|
||||
</member>
|
||||
<member name="T:YD_Event.Application.OrderBook.Dtos.OrderBookRefereeRow">
|
||||
<summary>
|
||||
@ -15603,25 +15665,39 @@
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:YD_Event.Application.OrderBook.Dtos.OrderBookRefereeRow.Seq">
|
||||
<summary>序号(仅便于人工核对)</summary>
|
||||
<summary>
|
||||
序号(仅便于人工核对)
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:YD_Event.Application.OrderBook.Dtos.OrderBookRefereeRow.Name">
|
||||
<summary>裁判姓名(必填)</summary>
|
||||
<summary>
|
||||
裁判姓名(必填)
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:YD_Event.Application.OrderBook.Dtos.OrderBookRefereeRow.Mobile">
|
||||
<summary>手机号(必填,用于匹配/创建裁判档案及打分账号)</summary>
|
||||
<summary>
|
||||
手机号(必填,用于匹配/创建裁判档案及打分账号)
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:YD_Event.Application.OrderBook.Dtos.OrderBookRefereeRow.RoleText">
|
||||
<summary>裁判角色(可空,如:主裁/难度裁判/表现裁判)</summary>
|
||||
<summary>
|
||||
裁判角色(可空,如:主裁/难度裁判/表现裁判)
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:YD_Event.Application.OrderBook.Dtos.OrderBookRefereeRow.LevelText">
|
||||
<summary>裁判等级(可空,如:国际级/国家级/一级/二级/三级)</summary>
|
||||
<summary>
|
||||
裁判等级(可空,如:国际级/国家级/一级/二级/三级)
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:YD_Event.Application.OrderBook.Dtos.OrderBookRefereeRow.VenueName">
|
||||
<summary>负责场地(可空,对应出场秩序中的场地名称)</summary>
|
||||
<summary>
|
||||
负责场地(可空,对应出场秩序中的场地名称)
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:YD_Event.Application.OrderBook.Dtos.OrderBookRefereeRow.ProjectName">
|
||||
<summary>负责项目(可空)</summary>
|
||||
<summary>
|
||||
负责项目(可空)
|
||||
</summary>
|
||||
</member>
|
||||
<member name="T:YD_Event.Application.OrderBook.Dtos.OrderBookImportOutput">
|
||||
<summary>
|
||||
@ -15629,28 +15705,44 @@
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:YD_Event.Application.OrderBook.Dtos.OrderBookImportOutput.BatchId">
|
||||
<summary>导入批次ID(用于确认导入)</summary>
|
||||
<summary>
|
||||
导入批次ID(用于确认导入)
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:YD_Event.Application.OrderBook.Dtos.OrderBookImportOutput.Status">
|
||||
<summary>解析状态:0-解析中,10-待确认,20-存在错误</summary>
|
||||
<summary>
|
||||
解析状态:0-解析中,10-待确认,20-存在错误
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:YD_Event.Application.OrderBook.Dtos.OrderBookImportOutput.TotalRows">
|
||||
<summary>原始数据行数(不含表头)</summary>
|
||||
<summary>
|
||||
原始数据行数(不含表头)
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:YD_Event.Application.OrderBook.Dtos.OrderBookImportOutput.ValidRows">
|
||||
<summary>有效行数</summary>
|
||||
<summary>
|
||||
有效行数
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:YD_Event.Application.OrderBook.Dtos.OrderBookImportOutput.ErrorCount">
|
||||
<summary>错误数量(存在错误时不可确认)</summary>
|
||||
<summary>
|
||||
错误数量(存在错误时不可确认)
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:YD_Event.Application.OrderBook.Dtos.OrderBookImportOutput.WarningCount">
|
||||
<summary>警告数量(不阻断确认)</summary>
|
||||
<summary>
|
||||
警告数量(不阻断确认)
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:YD_Event.Application.OrderBook.Dtos.OrderBookImportOutput.Preview">
|
||||
<summary>解析预览统计</summary>
|
||||
<summary>
|
||||
解析预览统计
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:YD_Event.Application.OrderBook.Dtos.OrderBookImportOutput.Errors">
|
||||
<summary>问题清单(错误/警告)</summary>
|
||||
<summary>
|
||||
问题清单(错误/警告)
|
||||
</summary>
|
||||
</member>
|
||||
<member name="T:YD_Event.Application.OrderBook.Dtos.OrderBookPreview">
|
||||
<summary>
|
||||
@ -15658,16 +15750,24 @@
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:YD_Event.Application.OrderBook.Dtos.OrderBookPreview.VenueCount">
|
||||
<summary>场地数量</summary>
|
||||
<summary>
|
||||
场地数量
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:YD_Event.Application.OrderBook.Dtos.OrderBookPreview.SessionCount">
|
||||
<summary>场次数量(项目×组别×场地)</summary>
|
||||
<summary>
|
||||
场次数量(项目×组别×场地)
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:YD_Event.Application.OrderBook.Dtos.OrderBookPreview.EntryCount">
|
||||
<summary>出场记录数量</summary>
|
||||
<summary>
|
||||
出场记录数量
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:YD_Event.Application.OrderBook.Dtos.OrderBookPreview.RefereeCount">
|
||||
<summary>裁判数量</summary>
|
||||
<summary>
|
||||
裁判数量
|
||||
</summary>
|
||||
</member>
|
||||
<member name="T:YD_Event.Application.OrderBook.Dtos.OrderBookParseIssue">
|
||||
<summary>
|
||||
@ -15675,16 +15775,24 @@
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:YD_Event.Application.OrderBook.Dtos.OrderBookParseIssue.Row">
|
||||
<summary>所在行号(Excel 物理行号,含表头)</summary>
|
||||
<summary>
|
||||
所在行号(Excel 物理行号,含表头)
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:YD_Event.Application.OrderBook.Dtos.OrderBookParseIssue.Column">
|
||||
<summary>所在列名</summary>
|
||||
<summary>
|
||||
所在列名
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:YD_Event.Application.OrderBook.Dtos.OrderBookParseIssue.Message">
|
||||
<summary>问题描述</summary>
|
||||
<summary>
|
||||
问题描述
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:YD_Event.Application.OrderBook.Dtos.OrderBookParseIssue.Level">
|
||||
<summary>级别:error-错误(阻断确认),warning-警告(不阻断)</summary>
|
||||
<summary>
|
||||
级别:error-错误(阻断确认),warning-警告(不阻断)
|
||||
</summary>
|
||||
</member>
|
||||
<member name="T:YD_Event.Application.OrderBook.Dtos.OrderBookConfirmInput">
|
||||
<summary>
|
||||
@ -15692,13 +15800,19 @@
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:YD_Event.Application.OrderBook.Dtos.OrderBookConfirmInput.BatchId">
|
||||
<summary>导入批次ID(必填,由导入接口返回)</summary>
|
||||
<summary>
|
||||
导入批次ID(必填,由导入接口返回)
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:YD_Event.Application.OrderBook.Dtos.OrderBookConfirmInput.GenerateJudgeAccount">
|
||||
<summary>是否为裁判生成小程序打分账号</summary>
|
||||
<summary>
|
||||
是否为裁判生成小程序打分账号
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:YD_Event.Application.OrderBook.Dtos.OrderBookConfirmInput.DefaultPassword">
|
||||
<summary>打分账号初始密码(生成账号时必填,长度6-32位)</summary>
|
||||
<summary>
|
||||
打分账号初始密码(生成账号时必填,长度6-32位)
|
||||
</summary>
|
||||
</member>
|
||||
<member name="T:YD_Event.Application.OrderBook.Dtos.OrderBookConfirmOutput">
|
||||
<summary>
|
||||
@ -15706,19 +15820,29 @@
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:YD_Event.Application.OrderBook.Dtos.OrderBookConfirmOutput.OrderBookVersion">
|
||||
<summary>秩序册版本号</summary>
|
||||
<summary>
|
||||
秩序册版本号
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:YD_Event.Application.OrderBook.Dtos.OrderBookConfirmOutput.VenueCount">
|
||||
<summary>生成场地数量</summary>
|
||||
<summary>
|
||||
生成场地数量
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:YD_Event.Application.OrderBook.Dtos.OrderBookConfirmOutput.SessionCount">
|
||||
<summary>生成场次数量</summary>
|
||||
<summary>
|
||||
生成场次数量
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:YD_Event.Application.OrderBook.Dtos.OrderBookConfirmOutput.EntryCount">
|
||||
<summary>生成出场记录数量</summary>
|
||||
<summary>
|
||||
生成出场记录数量
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:YD_Event.Application.OrderBook.Dtos.OrderBookConfirmOutput.RefereeCount">
|
||||
<summary>纳入裁判数量</summary>
|
||||
<summary>
|
||||
纳入裁判数量
|
||||
</summary>
|
||||
</member>
|
||||
<member name="T:YD_Event.Application.OrderBook.Dtos.OrderBookDraft">
|
||||
<summary>
|
||||
@ -15726,28 +15850,44 @@
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:YD_Event.Application.OrderBook.Dtos.OrderBookDraft.BatchId">
|
||||
<summary>批次ID</summary>
|
||||
<summary>
|
||||
批次ID
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:YD_Event.Application.OrderBook.Dtos.OrderBookDraft.CreatedUserId">
|
||||
<summary>创建该导入批次的后台用户ID</summary>
|
||||
<summary>
|
||||
创建该导入批次的后台用户ID
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:YD_Event.Application.OrderBook.Dtos.OrderBookDraft.HasErrors">
|
||||
<summary>解析结果是否包含阻断确认的错误</summary>
|
||||
<summary>
|
||||
解析结果是否包含阻断确认的错误
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:YD_Event.Application.OrderBook.Dtos.OrderBookDraft.EventId">
|
||||
<summary>赛事ID(当前版本要求赛事已预先创建)</summary>
|
||||
<summary>
|
||||
赛事ID(当前版本要求赛事已预先创建)
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:YD_Event.Application.OrderBook.Dtos.OrderBookDraft.ImportMode">
|
||||
<summary>导入模式:append-追加(默认),overwrite-覆盖该赛事既有编排</summary>
|
||||
<summary>
|
||||
导入模式:append-追加(默认),overwrite-覆盖该赛事既有编排
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:YD_Event.Application.OrderBook.Dtos.OrderBookDraft.CreatedAt">
|
||||
<summary>解析时间</summary>
|
||||
<summary>
|
||||
解析时间
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:YD_Event.Application.OrderBook.Dtos.OrderBookDraft.Entries">
|
||||
<summary>出场明细(已通过基础校验)</summary>
|
||||
<summary>
|
||||
出场明细(已通过基础校验)
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:YD_Event.Application.OrderBook.Dtos.OrderBookDraft.Referees">
|
||||
<summary>裁判明细</summary>
|
||||
<summary>
|
||||
裁判明细
|
||||
</summary>
|
||||
</member>
|
||||
<member name="T:YD_Event.Application.OrderBook.Dtos.OrderBookDraftEntry">
|
||||
<summary>
|
||||
@ -15755,28 +15895,44 @@
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:YD_Event.Application.OrderBook.Dtos.OrderBookDraftEntry.Row">
|
||||
<summary>Excel 物理行号</summary>
|
||||
<summary>
|
||||
Excel 物理行号
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:YD_Event.Application.OrderBook.Dtos.OrderBookDraftEntry.VenueName">
|
||||
<summary>场地名称</summary>
|
||||
<summary>
|
||||
场地名称
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:YD_Event.Application.OrderBook.Dtos.OrderBookDraftEntry.ProjectName">
|
||||
<summary>项目名称</summary>
|
||||
<summary>
|
||||
项目名称
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:YD_Event.Application.OrderBook.Dtos.OrderBookDraftEntry.GroupName">
|
||||
<summary>组别名称</summary>
|
||||
<summary>
|
||||
组别名称
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:YD_Event.Application.OrderBook.Dtos.OrderBookDraftEntry.EntryNo">
|
||||
<summary>原始出场编号(可空)</summary>
|
||||
<summary>
|
||||
原始出场编号(可空)
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:YD_Event.Application.OrderBook.Dtos.OrderBookDraftEntry.ParticipantName">
|
||||
<summary>姓名/队名</summary>
|
||||
<summary>
|
||||
姓名/队名
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:YD_Event.Application.OrderBook.Dtos.OrderBookDraftEntry.UnitName">
|
||||
<summary>单位</summary>
|
||||
<summary>
|
||||
单位
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:YD_Event.Application.OrderBook.Dtos.OrderBookDraftEntry.Mobile">
|
||||
<summary>联系电话</summary>
|
||||
<summary>
|
||||
联系电话
|
||||
</summary>
|
||||
</member>
|
||||
<member name="T:YD_Event.Application.OrderBook.Dtos.OrderBookDraftReferee">
|
||||
<summary>
|
||||
@ -15784,25 +15940,39 @@
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:YD_Event.Application.OrderBook.Dtos.OrderBookDraftReferee.Row">
|
||||
<summary>Excel 物理行号</summary>
|
||||
<summary>
|
||||
Excel 物理行号
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:YD_Event.Application.OrderBook.Dtos.OrderBookDraftReferee.Name">
|
||||
<summary>裁判姓名</summary>
|
||||
<summary>
|
||||
裁判姓名
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:YD_Event.Application.OrderBook.Dtos.OrderBookDraftReferee.Mobile">
|
||||
<summary>手机号</summary>
|
||||
<summary>
|
||||
手机号
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:YD_Event.Application.OrderBook.Dtos.OrderBookDraftReferee.RoleText">
|
||||
<summary>裁判角色文本</summary>
|
||||
<summary>
|
||||
裁判角色文本
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:YD_Event.Application.OrderBook.Dtos.OrderBookDraftReferee.LevelText">
|
||||
<summary>裁判等级文本</summary>
|
||||
<summary>
|
||||
裁判等级文本
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:YD_Event.Application.OrderBook.Dtos.OrderBookDraftReferee.VenueName">
|
||||
<summary>负责场地名称</summary>
|
||||
<summary>
|
||||
负责场地名称
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:YD_Event.Application.OrderBook.Dtos.OrderBookDraftReferee.ProjectName">
|
||||
<summary>负责项目名称</summary>
|
||||
<summary>
|
||||
负责项目名称
|
||||
</summary>
|
||||
</member>
|
||||
<member name="T:YD_Event.Application.OrderBook.OrderBookService">
|
||||
<summary>
|
||||
@ -15813,31 +15983,24 @@
|
||||
<summary>
|
||||
下载秩序册导入模板
|
||||
</summary>
|
||||
<param name="projectMode"></param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:YD_Event.Application.OrderBook.OrderBookService.Import(System.Nullable{System.Int64},System.String,Microsoft.AspNetCore.Http.IFormFile)">
|
||||
<summary>
|
||||
上传并同步解析秩序册(不产生业务数据,结果缓存待确认)
|
||||
</summary>
|
||||
<param name="eventId"></param>
|
||||
<param name="importMode"></param>
|
||||
<param name="file"></param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:YD_Event.Application.OrderBook.OrderBookService.Confirm(YD_Event.Application.OrderBook.Dtos.OrderBookConfirmInput)">
|
||||
<summary>
|
||||
确认导入:按解析结果生成场地、场次、出场及裁判名单(幂等,同一批次只生成一次)
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:YD_Event.Application.OrderBook.OrderBookService.EnsureProjectsAsync(YD_Event.Application.OrderBook.Dtos.OrderBookDraft,System.Int64,System.Int64,System.DateTime)">
|
||||
<summary>项目(含赛事项目、组别)建档,返回 (项目名,组别名) -> 上下文 的映射</summary>
|
||||
</member>
|
||||
<member name="M:YD_Event.Application.OrderBook.OrderBookService.EnsureVenuesAsync(YD_Event.Application.OrderBook.Dtos.OrderBookDraft,System.Int64,System.Int64,System.DateTime)">
|
||||
<summary>场地建档(追加模式按名称复用),返回场地名 -> 场地上下文 的映射</summary>
|
||||
</member>
|
||||
<member name="M:YD_Event.Application.OrderBook.OrderBookService.EnsureSessionsAsync(YD_Event.Application.OrderBook.Dtos.OrderBookDraft,System.Int64,System.Collections.Generic.Dictionary{System.String,YD_Event.Application.OrderBook.OrderBookService.OrderBookProjectContext},System.Collections.Generic.Dictionary{System.String,YD_Event.Application.OrderBook.OrderBookService.OrderBookVenueContext},System.Int64,System.DateTime)">
|
||||
<summary>按 项目×组别×场地 生成场次,返回组合键 -> 场次 的映射</summary>
|
||||
</member>
|
||||
<member name="M:YD_Event.Application.OrderBook.OrderBookService.CreateEntriesAsync(YD_Event.Application.OrderBook.Dtos.OrderBookDraft,System.Collections.Generic.Dictionary{System.String,YD_Event.Application.OrderBook.OrderBookService.OrderBookProjectContext},System.Collections.Generic.Dictionary{System.String,YD_Event.Application.OrderBook.OrderBookService.OrderBookVenueContext},System.Collections.Generic.Dictionary{System.String,YD_Event.Core.Entities.EventSession},System.Int64,System.DateTime)">
|
||||
<summary>生成出场记录,返回数量</summary>
|
||||
</member>
|
||||
<member name="M:YD_Event.Application.OrderBook.OrderBookService.EnsureRefereesAsync(YD_Event.Application.OrderBook.Dtos.OrderBookDraft,System.Int64,YD_Event.Application.OrderBook.Dtos.OrderBookConfirmInput,System.Int64,System.DateTime)">
|
||||
<summary>裁判档案 / 赛事裁判关系 / 可选打分账号,返回纳入的裁判数量</summary>
|
||||
<param name="input"></param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="T:YD_Event.Application.OrderBook.OrderBookTemplateExporter">
|
||||
<summary>
|
||||
@ -19237,19 +19400,29 @@
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:YD_Event.Application.Workbench.Dtos.ResultExportQueryInput.EventId">
|
||||
<summary>赛事ID(必填)</summary>
|
||||
<summary>
|
||||
赛事ID(必填)
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:YD_Event.Application.Workbench.Dtos.ResultExportQueryInput.EventProjectId">
|
||||
<summary>赛事项目ID(可选)</summary>
|
||||
<summary>
|
||||
赛事项目ID(可选)
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:YD_Event.Application.Workbench.Dtos.ResultExportQueryInput.GroupName">
|
||||
<summary>组别名称(可选,模糊匹配)</summary>
|
||||
<summary>
|
||||
组别名称(可选,模糊匹配)
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:YD_Event.Application.Workbench.Dtos.ResultExportQueryInput.ResultStatus">
|
||||
<summary>成绩状态(可选,默认20-已确认;0-计算中,10-待复核,20-已确认,90-已作废)</summary>
|
||||
<summary>
|
||||
成绩状态(可选,默认20-已确认;0-计算中,10-待复核,20-已确认,90-已作废)
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:YD_Event.Application.Workbench.Dtos.ResultExportQueryInput.IncludeDq">
|
||||
<summary>是否包含被取消比赛资格(DQ)的记录,默认不包含</summary>
|
||||
<summary>
|
||||
是否包含被取消比赛资格(DQ)的记录,默认不包含
|
||||
</summary>
|
||||
</member>
|
||||
<member name="T:YD_Event.Application.Workbench.Dtos.ScoreSheetExportQueryInput">
|
||||
<summary>
|
||||
@ -19257,13 +19430,19 @@
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:YD_Event.Application.Workbench.Dtos.ScoreSheetExportQueryInput.EventId">
|
||||
<summary>赛事ID(必填)</summary>
|
||||
<summary>
|
||||
赛事ID(必填)
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:YD_Event.Application.Workbench.Dtos.ScoreSheetExportQueryInput.SessionId">
|
||||
<summary>场次ID(与赛事项目ID至少传一个)</summary>
|
||||
<summary>
|
||||
场次ID(与赛事项目ID至少传一个)
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:YD_Event.Application.Workbench.Dtos.ScoreSheetExportQueryInput.EventProjectId">
|
||||
<summary>赛事项目ID(与场次ID至少传一个)</summary>
|
||||
<summary>
|
||||
赛事项目ID(与场次ID至少传一个)
|
||||
</summary>
|
||||
</member>
|
||||
<member name="T:YD_Event.Application.Workbench.Dtos.AuditExportQueryInput">
|
||||
<summary>
|
||||
@ -19271,19 +19450,29 @@
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:YD_Event.Application.Workbench.Dtos.AuditExportQueryInput.EventId">
|
||||
<summary>赛事ID(必填,按请求参数中的赛事ID匹配)</summary>
|
||||
<summary>
|
||||
赛事ID(必填,按请求参数中的赛事ID匹配)
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:YD_Event.Application.Workbench.Dtos.AuditExportQueryInput.SessionId">
|
||||
<summary>场次ID(可选)</summary>
|
||||
<summary>
|
||||
场次ID(可选)
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:YD_Event.Application.Workbench.Dtos.AuditExportQueryInput.StartTime">
|
||||
<summary>开始时间(可选)</summary>
|
||||
<summary>
|
||||
开始时间(可选)
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:YD_Event.Application.Workbench.Dtos.AuditExportQueryInput.EndTime">
|
||||
<summary>结束时间(可选)</summary>
|
||||
<summary>
|
||||
结束时间(可选)
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:YD_Event.Application.Workbench.Dtos.AuditExportQueryInput.OperatorId">
|
||||
<summary>操作人ID(可选)</summary>
|
||||
<summary>
|
||||
操作人ID(可选)
|
||||
</summary>
|
||||
</member>
|
||||
<member name="T:YD_Event.Application.Workbench.WorkbenchController">
|
||||
<summary>
|
||||
|
||||
39
YD_Event.Core/Entities/EventJudgeScoreAttachment.cs
Normal file
39
YD_Event.Core/Entities/EventJudgeScoreAttachment.cs
Normal file
@ -0,0 +1,39 @@
|
||||
namespace YD_Event.Core.Entities;
|
||||
|
||||
/// <summary>
|
||||
/// 裁判评分单附件。每次上传保留一个版本,IsCurrent 指向评分单当前画板。
|
||||
/// </summary>
|
||||
[SugarTable("EventJudgeScoreAttachment")]
|
||||
public class EventJudgeScoreAttachment : Entity<long>, ISoftDelete, ICreatedUserId, ICreatedTime, IUpdatedUserId, IUpdatedTime
|
||||
{
|
||||
public long EventId { get; set; }
|
||||
public long SessionId { get; set; }
|
||||
public long SessionEntryId { get; set; }
|
||||
public long ScoreSheetId { get; set; }
|
||||
public long JudgeAssignmentId { get; set; }
|
||||
public long RefereeId { get; set; }
|
||||
|
||||
[SugarColumn(Length = 32)]
|
||||
public string AttachmentType { get; set; } = "score_annotation_png";
|
||||
|
||||
[SugarColumn(Length = 128)]
|
||||
public string FileName { get; set; } = null!;
|
||||
|
||||
[SugarColumn(Length = 1000)]
|
||||
public string FileUrl { get; set; } = null!;
|
||||
|
||||
public long FileSize { get; set; }
|
||||
|
||||
[SugarColumn(Length = 64)]
|
||||
public string ContentType { get; set; } = "image/png";
|
||||
|
||||
[SugarColumn(Length = 64)]
|
||||
public string IdempotencyKey { get; set; } = null!;
|
||||
|
||||
public bool IsCurrent { get; set; } = true;
|
||||
public bool DeleteMark { get; set; }
|
||||
public long CreatedUserId { get; set; }
|
||||
public DateTime CreatedTime { get; set; }
|
||||
[SugarColumn(IsNullable = true)] public long? UpdatedUserId { get; set; }
|
||||
[SugarColumn(IsNullable = true)] public DateTime? UpdatedTime { get; set; }
|
||||
}
|
||||
@ -50,9 +50,16 @@ public class EventScoreCorrection : Entity<long>, ISoftDelete, ICreatedUserId, I
|
||||
public long? NewScoreSheetId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 申请人ID
|
||||
/// 后台申请人ID(SysUser)。裁判端申请时为空。
|
||||
/// </summary>
|
||||
public long ApplyUserId { get; set; }
|
||||
[SugarColumn(IsNullable = true)]
|
||||
public long? ApplyUserId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 裁判端申请人ID(Referee)。后台发起时为空。
|
||||
/// </summary>
|
||||
[SugarColumn(IsNullable = true)]
|
||||
public long? ApplyRefereeId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 申请修正原因
|
||||
|
||||
@ -1873,6 +1873,11 @@
|
||||
更新时间
|
||||
</summary>
|
||||
</member>
|
||||
<member name="T:YD_Event.Core.Entities.EventJudgeScoreAttachment">
|
||||
<summary>
|
||||
裁判评分单附件。每次上传保留一个版本,IsCurrent 指向评分单当前画板。
|
||||
</summary>
|
||||
</member>
|
||||
<member name="T:YD_Event.Core.Entities.EventJudgeScoreDetail">
|
||||
<summary>
|
||||
裁判评分明细表
|
||||
@ -3580,7 +3585,12 @@
|
||||
</member>
|
||||
<member name="P:YD_Event.Core.Entities.EventScoreCorrection.ApplyUserId">
|
||||
<summary>
|
||||
申请人ID
|
||||
后台申请人ID(SysUser)。裁判端申请时为空。
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:YD_Event.Core.Entities.EventScoreCorrection.ApplyRefereeId">
|
||||
<summary>
|
||||
裁判端申请人ID(Referee)。后台发起时为空。
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:YD_Event.Core.Entities.EventScoreCorrection.ApplyReason">
|
||||
@ -8638,6 +8648,11 @@
|
||||
拦截器
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:SqlSugar.SqlSugarExtensions.ResolveUpdatedUserId(System.String,System.Nullable{System.Int64})">
|
||||
<summary>
|
||||
有有效登录用户时以当前用户为准;无用户上下文时保留后台任务显式传入的操作者。
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:SqlSugar.SqlSugarExtensions.InitData(SqlSugar.SqlSugarScope)">
|
||||
<summary>
|
||||
初始化基础数据
|
||||
|
||||
29
二期需求/20260903_add_score_attachments.sql
Normal file
29
二期需求/20260903_add_score_attachments.sql
Normal file
@ -0,0 +1,29 @@
|
||||
SET XACT_ABORT ON;
|
||||
BEGIN TRANSACTION;
|
||||
|
||||
IF OBJECT_ID(N'dbo.[EventJudgeScoreAttachment]','U') IS NULL
|
||||
BEGIN
|
||||
CREATE TABLE dbo.[EventJudgeScoreAttachment] (
|
||||
[Id] BIGINT NOT NULL CONSTRAINT [PK_EventJudgeScoreAttachment] PRIMARY KEY,
|
||||
[EventId] BIGINT NOT NULL, [SessionId] BIGINT NOT NULL,
|
||||
[SessionEntryId] BIGINT NOT NULL, [ScoreSheetId] BIGINT NOT NULL,
|
||||
[JudgeAssignmentId] BIGINT NOT NULL, [RefereeId] BIGINT NOT NULL,
|
||||
[AttachmentType] NVARCHAR(32) NOT NULL, [FileName] NVARCHAR(128) NOT NULL,
|
||||
[FileUrl] NVARCHAR(1000) NOT NULL, [FileSize] BIGINT NOT NULL,
|
||||
[ContentType] NVARCHAR(64) NOT NULL, [IdempotencyKey] NVARCHAR(64) NOT NULL,
|
||||
[IsCurrent] BIT NOT NULL CONSTRAINT [DF_EventJudgeScoreAttachment_IsCurrent] DEFAULT (1),
|
||||
[DeleteMark] BIT NOT NULL CONSTRAINT [DF_EventJudgeScoreAttachment_DeleteMark] DEFAULT (0),
|
||||
[CreatedUserId] BIGINT NOT NULL, [CreatedTime] DATETIME2(3) NOT NULL,
|
||||
[UpdatedUserId] BIGINT NULL, [UpdatedTime] DATETIME2(3) NULL
|
||||
);
|
||||
END;
|
||||
|
||||
IF OBJECT_ID(N'dbo.[FK_EventJudgeScoreAttachment_Sheet]','F') IS NULL
|
||||
ALTER TABLE dbo.[EventJudgeScoreAttachment] WITH CHECK
|
||||
ADD CONSTRAINT [FK_EventJudgeScoreAttachment_Sheet] FOREIGN KEY([ScoreSheetId]) REFERENCES dbo.[EventJudgeScoreSheet]([Id]);
|
||||
IF NOT EXISTS(SELECT 1 FROM sys.indexes WHERE object_id=OBJECT_ID(N'dbo.[EventJudgeScoreAttachment]') AND name=N'UX_EventJudgeScoreAttachment_Idempotency')
|
||||
CREATE UNIQUE NONCLUSTERED INDEX [UX_EventJudgeScoreAttachment_Idempotency] ON dbo.[EventJudgeScoreAttachment]([ScoreSheetId],[IdempotencyKey]);
|
||||
IF NOT EXISTS(SELECT 1 FROM sys.indexes WHERE object_id=OBJECT_ID(N'dbo.[EventJudgeScoreAttachment]') AND name=N'UX_EventJudgeScoreAttachment_Current')
|
||||
CREATE UNIQUE NONCLUSTERED INDEX [UX_EventJudgeScoreAttachment_Current] ON dbo.[EventJudgeScoreAttachment]([ScoreSheetId],[AttachmentType]) WHERE [IsCurrent]=1 AND [DeleteMark]=0;
|
||||
|
||||
COMMIT TRANSACTION;
|
||||
28
二期需求/20260904_support_referee_score_corrections.sql
Normal file
28
二期需求/20260904_support_referee_score_corrections.sql
Normal file
@ -0,0 +1,28 @@
|
||||
SET XACT_ABORT ON;
|
||||
BEGIN TRANSACTION;
|
||||
|
||||
IF COL_LENGTH(N'dbo.EventScoreCorrection', N'ApplyRefereeId') IS NULL
|
||||
EXEC(N'ALTER TABLE dbo.EventScoreCorrection ADD ApplyRefereeId BIGINT NULL;');
|
||||
|
||||
IF EXISTS (
|
||||
SELECT 1
|
||||
FROM sys.columns
|
||||
WHERE object_id = OBJECT_ID(N'dbo.EventScoreCorrection')
|
||||
AND name = N'ApplyUserId'
|
||||
AND is_nullable = 0
|
||||
)
|
||||
ALTER TABLE dbo.EventScoreCorrection ALTER COLUMN ApplyUserId BIGINT NULL;
|
||||
|
||||
IF OBJECT_ID(N'dbo.FK_EventScoreCorrection_ApplyReferee', N'F') IS NULL
|
||||
EXEC(N'ALTER TABLE dbo.EventScoreCorrection WITH CHECK
|
||||
ADD CONSTRAINT FK_EventScoreCorrection_ApplyReferee
|
||||
FOREIGN KEY (ApplyRefereeId) REFERENCES dbo.Referee(Id);');
|
||||
|
||||
IF OBJECT_ID(N'dbo.CK_EventScoreCorrection_Applicant', N'C') IS NULL
|
||||
EXEC(N'ALTER TABLE dbo.EventScoreCorrection WITH CHECK
|
||||
ADD CONSTRAINT CK_EventScoreCorrection_Applicant CHECK (
|
||||
(ApplyUserId IS NOT NULL AND ApplyRefereeId IS NULL)
|
||||
OR (ApplyUserId IS NULL AND ApplyRefereeId IS NOT NULL)
|
||||
);');
|
||||
|
||||
COMMIT TRANSACTION;
|
||||
25
二期需求/20260907_fix_score_correction_open_index.sql
Normal file
25
二期需求/20260907_fix_score_correction_open_index.sql
Normal file
@ -0,0 +1,25 @@
|
||||
SET ANSI_NULLS ON;
|
||||
SET ANSI_PADDING ON;
|
||||
SET ANSI_WARNINGS ON;
|
||||
SET ARITHABORT ON;
|
||||
SET CONCAT_NULL_YIELDS_NULL ON;
|
||||
SET QUOTED_IDENTIFIER ON;
|
||||
SET NUMERIC_ROUNDABORT OFF;
|
||||
SET XACT_ABORT ON;
|
||||
BEGIN TRANSACTION;
|
||||
|
||||
IF EXISTS (
|
||||
SELECT 1 FROM sys.indexes
|
||||
WHERE object_id = OBJECT_ID(N'dbo.EventScoreCorrection')
|
||||
AND name = N'UX_EventScoreCorrection_OriginalSheet_Open'
|
||||
)
|
||||
DROP INDEX UX_EventScoreCorrection_OriginalSheet_Open ON dbo.EventScoreCorrection;
|
||||
|
||||
CREATE UNIQUE NONCLUSTERED INDEX UX_EventScoreCorrection_OriginalSheet_Open
|
||||
ON dbo.EventScoreCorrection(OriginalScoreSheetId)
|
||||
WHERE DeleteMark = 0
|
||||
AND CorrectionStatus >= 0
|
||||
AND CorrectionStatus <= 30
|
||||
AND CorrectionStatus <> 20;
|
||||
|
||||
COMMIT TRANSACTION;
|
||||
49
二期需求/dbo.sql
49
二期需求/dbo.sql
@ -34,6 +34,14 @@ BEGIN TRY
|
||||
EXEC @LockResult=sys.sp_getapplock @Resource=N'YD_Event_Phase2_Production_Deployment_v3',@LockMode='Exclusive',@LockOwner='Transaction',@LockTimeout=10000;
|
||||
IF @LockResult<0 THROW 51002,N'无法取得二期部署排他锁,可能有另一个部署正在执行。',1;
|
||||
|
||||
/* EventScoreCorrection:同时支持后台账号与裁判账号发起修正。 */
|
||||
IF OBJECT_ID(N'dbo.EventScoreCorrection','U') IS NOT NULL AND COL_LENGTH(N'dbo.EventScoreCorrection', N'ApplyRefereeId') IS NULL
|
||||
ALTER TABLE dbo.EventScoreCorrection ADD ApplyRefereeId BIGINT NULL;
|
||||
IF OBJECT_ID(N'dbo.EventScoreCorrection','U') IS NOT NULL AND EXISTS (
|
||||
SELECT 1 FROM sys.columns WHERE object_id=OBJECT_ID(N'dbo.EventScoreCorrection') AND name=N'ApplyUserId' AND is_nullable=0
|
||||
)
|
||||
ALTER TABLE dbo.EventScoreCorrection ALTER COLUMN ApplyUserId BIGINT NULL;
|
||||
|
||||
/* ====================================================================================
|
||||
[1/9] 新增表 · 创建二期业务表(共 19 张;IF OBJECT_ID 判空,可重复执行)
|
||||
说明:新表外键只引用一期已有表主键(Id),不依赖 [2/9] 新增列,因此置于“改表结构”之前。
|
||||
@ -441,6 +449,32 @@ BEGIN TRY
|
||||
);
|
||||
END;
|
||||
|
||||
/* EventJudgeScoreAttachment:评分单记录画板,按上传版本留档。 */
|
||||
IF OBJECT_ID(N'dbo.[EventJudgeScoreAttachment]','U') IS NULL
|
||||
BEGIN
|
||||
CREATE TABLE dbo.[EventJudgeScoreAttachment] (
|
||||
[Id] BIGINT NOT NULL CONSTRAINT [PK_EventJudgeScoreAttachment] PRIMARY KEY,
|
||||
[EventId] BIGINT NOT NULL,
|
||||
[SessionId] BIGINT NOT NULL,
|
||||
[SessionEntryId] BIGINT NOT NULL,
|
||||
[ScoreSheetId] BIGINT NOT NULL,
|
||||
[JudgeAssignmentId] BIGINT NOT NULL,
|
||||
[RefereeId] BIGINT NOT NULL,
|
||||
[AttachmentType] NVARCHAR(32) NOT NULL,
|
||||
[FileName] NVARCHAR(128) NOT NULL,
|
||||
[FileUrl] NVARCHAR(1000) NOT NULL,
|
||||
[FileSize] BIGINT NOT NULL,
|
||||
[ContentType] NVARCHAR(64) NOT NULL,
|
||||
[IdempotencyKey] NVARCHAR(64) NOT NULL,
|
||||
[IsCurrent] BIT NOT NULL CONSTRAINT [DF_EventJudgeScoreAttachment_IsCurrent] DEFAULT (1),
|
||||
[DeleteMark] BIT NOT NULL CONSTRAINT [DF_EventJudgeScoreAttachment_DeleteMark] DEFAULT (0),
|
||||
[CreatedUserId] BIGINT NOT NULL,
|
||||
[CreatedTime] DATETIME2(3) NOT NULL,
|
||||
[UpdatedUserId] BIGINT NULL,
|
||||
[UpdatedTime] DATETIME2(3) NULL
|
||||
);
|
||||
END;
|
||||
|
||||
/* EventJudgeScoreDetail:评分单逐项录入和计算明细。 */
|
||||
IF OBJECT_ID(N'dbo.[EventJudgeScoreDetail]','U') IS NULL
|
||||
BEGIN
|
||||
@ -514,7 +548,8 @@ BEGIN TRY
|
||||
[JudgeRole] NVARCHAR(32) NOT NULL, -- 裁判席位编码
|
||||
[CorrectionTaskId] BIGINT NULL, -- 修正任务Id
|
||||
[NewScoreSheetId] BIGINT NULL, -- 修正完成后产生的新评分单Id
|
||||
[ApplyUserId] BIGINT NOT NULL, -- 申请人Id
|
||||
[ApplyUserId] BIGINT NULL, -- 后台申请人Id(SysUser),裁判端申请时为空
|
||||
[ApplyRefereeId] BIGINT NULL, -- 裁判端申请人Id(Referee),后台发起时为空
|
||||
[ApplyReason] NVARCHAR(512) NOT NULL, -- 申请修正原因
|
||||
[ApproveUserId] BIGINT NULL, -- 审批人Id
|
||||
[ApproveRemark] NVARCHAR(512) NULL, -- 审批意见
|
||||
@ -637,6 +672,7 @@ BEGIN TRY
|
||||
IF OBJECT_ID('CK_EventSession_Time','C') IS NULL ALTER TABLE dbo.EventSession WITH CHECK ADD CONSTRAINT CK_EventSession_Time CHECK(EndTime IS NULL OR StartTime IS NULL OR EndTime>=StartTime);
|
||||
IF OBJECT_ID('CK_ScoreRule_Version','C') IS NULL ALTER TABLE dbo.ScoreRule WITH CHECK ADD CONSTRAINT CK_ScoreRule_Version CHECK(RuleVersion>=1);
|
||||
IF OBJECT_ID('CK_EventJudgeScoreSheet_Version','C') IS NULL ALTER TABLE dbo.EventJudgeScoreSheet WITH CHECK ADD CONSTRAINT CK_EventJudgeScoreSheet_Version CHECK(RuleVersion>=1 AND SheetVersion>=1);
|
||||
IF OBJECT_ID('CK_EventScoreCorrection_Applicant','C') IS NULL ALTER TABLE dbo.EventScoreCorrection WITH CHECK ADD CONSTRAINT CK_EventScoreCorrection_Applicant CHECK((ApplyUserId IS NOT NULL AND ApplyRefereeId IS NULL) OR (ApplyUserId IS NULL AND ApplyRefereeId IS NOT NULL));
|
||||
/* 3.2 外键:二期表引用一期表主键、以及二期表之间的引用关系 */
|
||||
IF OBJECT_ID(N'dbo.[FK_RefereeApplication_Event]','F') IS NULL ALTER TABLE dbo.[RefereeApplication] WITH CHECK ADD CONSTRAINT [FK_RefereeApplication_Event] FOREIGN KEY([EventId]) REFERENCES dbo.[EventInfo]([Id]);
|
||||
IF OBJECT_ID(N'dbo.[FK_RefereeApplication_AppUser]','F') IS NULL ALTER TABLE dbo.[RefereeApplication] WITH CHECK ADD CONSTRAINT [FK_RefereeApplication_AppUser] FOREIGN KEY([RefereeUserId]) REFERENCES dbo.[AppUser]([Id]);
|
||||
@ -658,12 +694,14 @@ BEGIN TRY
|
||||
IF OBJECT_ID(N'dbo.[FK_EventJudgeScoreSheet_Task]','F') IS NULL ALTER TABLE dbo.[EventJudgeScoreSheet] WITH CHECK ADD CONSTRAINT [FK_EventJudgeScoreSheet_Task] FOREIGN KEY([JudgeTaskId]) REFERENCES dbo.[EventJudgeTask]([Id]);
|
||||
IF OBJECT_ID(N'dbo.[FK_EventJudgeScoreSheet_Entry]','F') IS NULL ALTER TABLE dbo.[EventJudgeScoreSheet] WITH CHECK ADD CONSTRAINT [FK_EventJudgeScoreSheet_Entry] FOREIGN KEY([SessionEntryId]) REFERENCES dbo.[EventSessionEntry]([Id]);
|
||||
IF OBJECT_ID(N'dbo.[FK_EventJudgeScoreSheet_Rule]','F') IS NULL ALTER TABLE dbo.[EventJudgeScoreSheet] WITH CHECK ADD CONSTRAINT [FK_EventJudgeScoreSheet_Rule] FOREIGN KEY([ScoreRuleId]) REFERENCES dbo.[ScoreRule]([Id]);
|
||||
IF OBJECT_ID(N'dbo.[FK_EventJudgeScoreAttachment_Sheet]','F') IS NULL ALTER TABLE dbo.[EventJudgeScoreAttachment] WITH CHECK ADD CONSTRAINT [FK_EventJudgeScoreAttachment_Sheet] FOREIGN KEY([ScoreSheetId]) REFERENCES dbo.[EventJudgeScoreSheet]([Id]);
|
||||
IF OBJECT_ID(N'dbo.[FK_EventJudgeScoreDetail_Sheet]','F') IS NULL ALTER TABLE dbo.[EventJudgeScoreDetail] WITH CHECK ADD CONSTRAINT [FK_EventJudgeScoreDetail_Sheet] FOREIGN KEY([ScoreSheetId]) REFERENCES dbo.[EventJudgeScoreSheet]([Id]);
|
||||
IF OBJECT_ID(N'dbo.[FK_EventResultVersion_Result]','F') IS NULL ALTER TABLE dbo.[EventResultVersion] WITH CHECK ADD CONSTRAINT [FK_EventResultVersion_Result] FOREIGN KEY([EventResultId]) REFERENCES dbo.[EventResult]([Id]);
|
||||
IF OBJECT_ID(N'dbo.[FK_EventResultVersion_Entry]','F') IS NULL ALTER TABLE dbo.[EventResultVersion] WITH CHECK ADD CONSTRAINT [FK_EventResultVersion_Entry] FOREIGN KEY([SessionEntryId]) REFERENCES dbo.[EventSessionEntry]([Id]);
|
||||
IF OBJECT_ID(N'dbo.[FK_EventResultVersion_Rule]','F') IS NULL ALTER TABLE dbo.[EventResultVersion] WITH CHECK ADD CONSTRAINT [FK_EventResultVersion_Rule] FOREIGN KEY([ScoreRuleId]) REFERENCES dbo.[ScoreRule]([Id]);
|
||||
IF OBJECT_ID(N'dbo.[FK_EventScoreCorrection_Entry]','F') IS NULL ALTER TABLE dbo.[EventScoreCorrection] WITH CHECK ADD CONSTRAINT [FK_EventScoreCorrection_Entry] FOREIGN KEY([SessionEntryId]) REFERENCES dbo.[EventSessionEntry]([Id]);
|
||||
IF OBJECT_ID(N'dbo.[FK_EventScoreCorrection_OriginalSheet]','F') IS NULL ALTER TABLE dbo.[EventScoreCorrection] WITH CHECK ADD CONSTRAINT [FK_EventScoreCorrection_OriginalSheet] FOREIGN KEY([OriginalScoreSheetId]) REFERENCES dbo.[EventJudgeScoreSheet]([Id]);
|
||||
IF OBJECT_ID(N'dbo.[FK_EventScoreCorrection_ApplyReferee]','F') IS NULL ALTER TABLE dbo.[EventScoreCorrection] WITH CHECK ADD CONSTRAINT [FK_EventScoreCorrection_ApplyReferee] FOREIGN KEY([ApplyRefereeId]) REFERENCES dbo.[Referee]([Id]);
|
||||
IF OBJECT_ID(N'dbo.[FK_EventResultScreenCast_Event]','F') IS NULL ALTER TABLE dbo.[EventResultScreenCast] WITH CHECK ADD CONSTRAINT [FK_EventResultScreenCast_Event] FOREIGN KEY([EventId]) REFERENCES dbo.[EventInfo]([Id]);
|
||||
/* 3.3 索引:UX_ 唯一索引 / IX_ 非聚集索引;WHERE DeleteMark=0 的过滤索引仅约束有效数据 */
|
||||
IF NOT EXISTS(SELECT 1 FROM sys.indexes WHERE object_id=OBJECT_ID(N'dbo.[Referee]') AND name=N'UX_Referee_Mobile_Active') CREATE UNIQUE NONCLUSTERED INDEX [UX_Referee_Mobile_Active] ON dbo.[Referee]([Mobile]) WHERE [DeleteMark]=0;
|
||||
@ -680,10 +718,13 @@ BEGIN TRY
|
||||
IF NOT EXISTS(SELECT 1 FROM sys.indexes WHERE object_id=OBJECT_ID(N'dbo.[EventJudgeAssignment]') AND name=N'UX_EventJudgeAssignment_Session_Role_Active') CREATE UNIQUE NONCLUSTERED INDEX [UX_EventJudgeAssignment_Session_Role_Active] ON dbo.[EventJudgeAssignment]([SessionId],[JudgeRole]) WHERE [DeleteMark]=0 AND [Status]=0;
|
||||
IF NOT EXISTS(SELECT 1 FROM sys.indexes WHERE object_id=OBJECT_ID(N'dbo.[EventJudgeTask]') AND name=N'IX_EventJudgeTask_User_Status') CREATE NONCLUSTERED INDEX [IX_EventJudgeTask_User_Status] ON dbo.[EventJudgeTask]([JudgeUserId],[TaskStatus],[ExpiresTime]) WHERE [DeleteMark]=0;
|
||||
IF NOT EXISTS(SELECT 1 FROM sys.indexes WHERE object_id=OBJECT_ID(N'dbo.[EventJudgeTask]') AND name=N'UX_EventJudgeTask_Business_Version') CREATE UNIQUE NONCLUSTERED INDEX [UX_EventJudgeTask_Business_Version] ON dbo.[EventJudgeTask]([SessionEntryId],[JudgeAssignmentId],[TaskVersion]) WHERE [DeleteMark]=0;
|
||||
IF NOT EXISTS(SELECT 1 FROM sys.indexes WHERE object_id=OBJECT_ID(N'dbo.[EventScoreCorrection]') AND name=N'UX_EventScoreCorrection_OriginalSheet_Open') CREATE UNIQUE NONCLUSTERED INDEX [UX_EventScoreCorrection_OriginalSheet_Open] ON dbo.[EventScoreCorrection]([OriginalScoreSheetId]) WHERE [DeleteMark]=0 AND [CorrectionStatus]>=0 AND [CorrectionStatus]<=30 AND [CorrectionStatus]<>20;
|
||||
IF NOT EXISTS(SELECT 1 FROM sys.indexes WHERE object_id=OBJECT_ID(N'dbo.[ScoreRule]') AND name=N'UX_ScoreRule_Code_Active') CREATE UNIQUE NONCLUSTERED INDEX [UX_ScoreRule_Code_Active] ON dbo.[ScoreRule]([RuleCode]) WHERE [DeleteMark]=0;
|
||||
IF NOT EXISTS(SELECT 1 FROM sys.indexes WHERE object_id=OBJECT_ID(N'dbo.[ScoreRuleItem]') AND name=N'UX_ScoreRuleItem_Rule_Role_Code_Active') CREATE UNIQUE NONCLUSTERED INDEX [UX_ScoreRuleItem_Rule_Role_Code_Active] ON dbo.[ScoreRuleItem]([ScoreRuleId],[JudgeRoleType],[ItemCode]) WHERE [DeleteMark]=0;
|
||||
IF NOT EXISTS(SELECT 1 FROM sys.indexes WHERE object_id=OBJECT_ID(N'dbo.[EventJudgeScoreSheet]') AND name=N'UX_EventJudgeScoreSheet_Idempotency') CREATE UNIQUE NONCLUSTERED INDEX [UX_EventJudgeScoreSheet_Idempotency] ON dbo.[EventJudgeScoreSheet]([IdempotencyKey]);
|
||||
IF NOT EXISTS(SELECT 1 FROM sys.indexes WHERE object_id=OBJECT_ID(N'dbo.[EventJudgeScoreSheet]') AND name=N'UX_EventJudgeScoreSheet_Current') CREATE UNIQUE NONCLUSTERED INDEX [UX_EventJudgeScoreSheet_Current] ON dbo.[EventJudgeScoreSheet]([SessionEntryId],[JudgeAssignmentId]) WHERE [IsCurrent]=1 AND [DeleteMark]=0;
|
||||
IF NOT EXISTS(SELECT 1 FROM sys.indexes WHERE object_id=OBJECT_ID(N'dbo.[EventJudgeScoreAttachment]') AND name=N'UX_EventJudgeScoreAttachment_Idempotency') CREATE UNIQUE NONCLUSTERED INDEX [UX_EventJudgeScoreAttachment_Idempotency] ON dbo.[EventJudgeScoreAttachment]([ScoreSheetId],[IdempotencyKey]);
|
||||
IF NOT EXISTS(SELECT 1 FROM sys.indexes WHERE object_id=OBJECT_ID(N'dbo.[EventJudgeScoreAttachment]') AND name=N'UX_EventJudgeScoreAttachment_Current') CREATE UNIQUE NONCLUSTERED INDEX [UX_EventJudgeScoreAttachment_Current] ON dbo.[EventJudgeScoreAttachment]([ScoreSheetId],[AttachmentType]) WHERE [IsCurrent]=1 AND [DeleteMark]=0;
|
||||
IF NOT EXISTS(SELECT 1 FROM sys.indexes WHERE object_id=OBJECT_ID(N'dbo.[EventJudgeScoreDetail]') AND name=N'IX_EventJudgeScoreDetail_Sheet') CREATE NONCLUSTERED INDEX [IX_EventJudgeScoreDetail_Sheet] ON dbo.[EventJudgeScoreDetail]([ScoreSheetId],[Sort]);
|
||||
IF NOT EXISTS(SELECT 1 FROM sys.indexes WHERE object_id=OBJECT_ID(N'dbo.[EventResultVersion]') AND name=N'UX_EventResultVersion_Result_Version') CREATE UNIQUE NONCLUSTERED INDEX [UX_EventResultVersion_Result_Version] ON dbo.[EventResultVersion]([EventResultId],[ResultVersion]) WHERE [DeleteMark]=0;
|
||||
IF NOT EXISTS(SELECT 1 FROM sys.indexes WHERE object_id=OBJECT_ID(N'dbo.[EventJudgeMessage]') AND name=N'IX_EventJudgeMessage_Receiver_Unread') CREATE NONCLUSTERED INDEX [IX_EventJudgeMessage_Receiver_Unread] ON dbo.[EventJudgeMessage]([ReceiverUserId],[IsRead],[CreatedTime]) WHERE [DeleteMark]=0;
|
||||
@ -1047,7 +1088,7 @@ BEGIN SET NOCOUNT ON; SELECT * FROM dbo.vw_Phase2_SessionScoreProgress WHERE Ses
|
||||
EXEC(N'CREATE OR ALTER PROCEDURE dbo.usp_Phase2_ValidateDeployment AS
|
||||
BEGIN SET NOCOUNT ON;
|
||||
SELECT N''Table'' AS ObjectType,t.name AS ObjectName FROM sys.tables t WHERE t.name IN
|
||||
(''RefereeApplication'',''CheckinTask'',''CheckinRecord'',''Referee'',''EventReferee'',''EventJudgeAssignment'',''EventJudgeTask'',''EventVenue'',''EventSession'',''EventSessionEntry'',''EventSessionEntryRematch'',''EventJudgeMessage'',''ScoreRule'',''ScoreRuleItem'',''EventJudgeScoreSheet'',''EventJudgeScoreDetail'',''EventResultVersion'',''EventScoreCorrection'',''EventResultScreenCast'')
|
||||
(''RefereeApplication'',''CheckinTask'',''CheckinRecord'',''Referee'',''EventReferee'',''EventJudgeAssignment'',''EventJudgeTask'',''EventVenue'',''EventSession'',''EventSessionEntry'',''EventSessionEntryRematch'',''EventJudgeMessage'',''ScoreRule'',''ScoreRuleItem'',''EventJudgeScoreSheet'',''EventJudgeScoreAttachment'',''EventJudgeScoreDetail'',''EventResultVersion'',''EventScoreCorrection'',''EventResultScreenCast'')
|
||||
UNION ALL SELECT N''View'',name FROM sys.views WHERE name LIKE ''vw_Phase2[_]%''
|
||||
UNION ALL SELECT N''Routine'',name FROM sys.objects WHERE type IN(''P'',''FN'') AND (name LIKE ''usp_Phase2[_]%'' OR name LIKE ''fn_Phase2[_]%'');
|
||||
SELECT r.RuleCode,COUNT(i.Id) AS ItemCount FROM dbo.ScoreRule r LEFT JOIN dbo.ScoreRuleItem i ON i.ScoreRuleId=r.Id AND i.DeleteMark=0 WHERE r.RuleCode IN(''ROPE_PRESCRIBED'',''ROPE_FREESTYLE_WHEEL'',''ROPE_FREESTYLE_WIRE'',''ROPE_SHOWCASE'') AND r.DeleteMark=0 GROUP BY r.RuleCode; END');
|
||||
@ -1085,7 +1126,7 @@ SELECT r.RuleCode,COUNT(i.Id) AS ItemCount FROM dbo.ScoreRule r LEFT JOIN dbo.Sc
|
||||
DECLARE business_tables CURSOR LOCAL FAST_FORWARD FOR SELECT [Name] FROM (VALUES
|
||||
(N'RefereeApplication'),(N'CheckinTask'),(N'CheckinRecord'),(N'Referee'),(N'EventReferee'),(N'EventJudgeAssignment'),
|
||||
(N'EventJudgeTask'),(N'EventVenue'),(N'EventSession'),(N'EventSessionEntry'),(N'EventSessionEntryRematch'),
|
||||
(N'EventJudgeMessage'),(N'ScoreRule'),(N'ScoreRuleItem'),(N'EventJudgeScoreSheet'),(N'EventJudgeScoreDetail'),
|
||||
(N'EventJudgeMessage'),(N'ScoreRule'),(N'ScoreRuleItem'),(N'EventJudgeScoreSheet'),(N'EventJudgeScoreAttachment'),(N'EventJudgeScoreDetail'),
|
||||
(N'EventResultVersion'),(N'EventScoreCorrection'),(N'EventResultScreenCast'))x([Name]);
|
||||
OPEN business_tables; FETCH NEXT FROM business_tables INTO @BusinessTable;
|
||||
WHILE @@FETCH_STATUS=0
|
||||
@ -1104,7 +1145,7 @@ SELECT r.RuleCode,COUNT(i.Id) AS ItemCount FROM dbo.ScoreRule r LEFT JOIN dbo.Sc
|
||||
PRINT N'[7/9] 执行后置校验';
|
||||
DECLARE @Validation TABLE([Category] NVARCHAR(32),[Item] NVARCHAR(128),[Passed] BIT,[Actual] NVARCHAR(1000));
|
||||
DECLARE @ExpectedTables TABLE(Name SYSNAME);
|
||||
INSERT @ExpectedTables VALUES(N'RefereeApplication'),(N'CheckinTask'),(N'CheckinRecord'),(N'Referee'),(N'EventReferee'),(N'EventJudgeAssignment'),(N'EventJudgeTask'),(N'EventVenue'),(N'EventSession'),(N'EventSessionEntry'),(N'EventSessionEntryRematch'),(N'EventJudgeMessage'),(N'ScoreRule'),(N'ScoreRuleItem'),(N'EventJudgeScoreSheet'),(N'EventJudgeScoreDetail'),(N'EventResultVersion'),(N'EventScoreCorrection'),(N'EventResultScreenCast');
|
||||
INSERT @ExpectedTables VALUES(N'RefereeApplication'),(N'CheckinTask'),(N'CheckinRecord'),(N'Referee'),(N'EventReferee'),(N'EventJudgeAssignment'),(N'EventJudgeTask'),(N'EventVenue'),(N'EventSession'),(N'EventSessionEntry'),(N'EventSessionEntryRematch'),(N'EventJudgeMessage'),(N'ScoreRule'),(N'ScoreRuleItem'),(N'EventJudgeScoreSheet'),(N'EventJudgeScoreAttachment'),(N'EventJudgeScoreDetail'),(N'EventResultVersion'),(N'EventScoreCorrection'),(N'EventResultScreenCast');
|
||||
INSERT @Validation SELECT N'TABLE',Name,CASE WHEN OBJECT_ID(N'dbo.'+QUOTENAME(Name),'U') IS NOT NULL THEN 1 ELSE 0 END,N'dbo.'+Name FROM @ExpectedTables;
|
||||
|
||||
DECLARE @ExpectedColumns TABLE(TableName SYSNAME,ColumnName SYSNAME);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user