diff --git a/YD_Event.Application/OrderBook/OrderBookService.cs b/YD_Event.Application/OrderBook/OrderBookService.cs index ea791f6..41d5cec 100644 --- a/YD_Event.Application/OrderBook/OrderBookService.cs +++ b/YD_Event.Application/OrderBook/OrderBookService.cs @@ -80,7 +80,19 @@ public class OrderBookService : IDynamicApiController, ITransient [HttpGet("template")] public async Task DownloadTemplate([FromQuery] string? projectMode) { - var bytes = await new OrderBookTemplateExporter().ExportAsync(); + var scoreRuleNames = await _scoreRuleRepository.AsQueryable() + .Where(x => !x.DeleteMark && x.Status == AvailabilityStatus.Enable) + .Select(x => x.RuleName) + .ToListAsync(); + scoreRuleNames = scoreRuleNames + .Where(x => !string.IsNullOrWhiteSpace(x)) + .Distinct(StringComparer.Ordinal) + .OrderBy(x => x, StringComparer.Ordinal) + .ToList(); + if (scoreRuleNames.Count == 0) + throw Oops.Bah("当前没有已启用的计分规则,请先配置计分规则后再下载模板"); + + var bytes = await new OrderBookTemplateExporter(scoreRuleNames).ExportAsync(); return new FileContentResult(bytes, "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet") { FileDownloadName = "秩序册导入模板.xlsx" @@ -303,7 +315,8 @@ public class OrderBookService : IDynamicApiController, ITransient .Select(x => x.RuleName).ToListAsync(); foreach (var entry in entries.Where(x => !string.IsNullOrWhiteSpace(x.ScoreRuleName) && !existingNames.Contains(x.ScoreRuleName))) - issues.Add(Issue(entry.Row, "计分规则", $"计分规则【{entry.ScoreRuleName}】不存在或已停用")); + issues.Add(Issue(entry.Row, "计分规则", + $"计分规则【{entry.ScoreRuleName}】不存在或已停用,请从最新版模板的「计分规则参考」工作表选择")); } private async Task ValidateRefereesAsync( @@ -816,10 +829,18 @@ public class OrderBookService : IDynamicApiController, ITransient } /// -/// 秩序册导入模板导出器:出场秩序 + 裁判名单 两个工作表 +/// 秩序册导入模板导出器:出场秩序 + 裁判名单 + 计分规则参考 /// internal sealed class OrderBookTemplateExporter : ExcelExportBase { + private const int EntryInputEndRow = 1000; + private readonly IReadOnlyList _scoreRuleNames; + + public OrderBookTemplateExporter(IReadOnlyList scoreRuleNames) + { + _scoreRuleNames = scoreRuleNames; + } + public override Task ExportAsync() { var headerColor = Color.FromArgb(217, 225, 242); @@ -827,12 +848,18 @@ internal sealed class OrderBookTemplateExporter : ExcelExportBase #region 出场秩序 CreateWorksheet("出场秩序"); var entryHeaders = new[] { "项目名称*", "计分规则*", "组别名称*", "姓名*", "队伍名称", "单位", "场次*", "场地*" }; - SetMergeTitle("秩序册 - 出场秩序(带*为必填,队伍名称和单位可不填)", 1, 1, 1, entryHeaders.Length, headerColor, 12); + SetMergeTitle("秩序册 - 出场秩序(带*为必填;计分规则请从下拉列表选择)", 1, 1, 1, entryHeaders.Length, headerColor, 12); SetHeaders(entryHeaders, 2, headerColor); - var sample = new[] { "个人花样", "个人花样(精英级)", "B", "崔一,崔二", "", "某某单位", "个人花样-1号场地", "1号场地" }; - for (var c = 0; c < sample.Length; c++) - Worksheet.Cells[3, c + 1].Value = sample[c]; SetDataRowStyle(3, entryHeaders.Length); + var scoreRuleValidation = Worksheet.DataValidations.AddListValidation($"B3:B{EntryInputEndRow}"); + scoreRuleValidation.Formula.ExcelFormula = $"'计分规则参考'!$B$3:$B${_scoreRuleNames.Count + 2}"; + scoreRuleValidation.AllowBlank = false; + scoreRuleValidation.ShowInputMessage = true; + scoreRuleValidation.PromptTitle = "请选择计分规则"; + scoreRuleValidation.Prompt = "下拉列表来自当前已启用的计分规则。"; + scoreRuleValidation.ShowErrorMessage = true; + scoreRuleValidation.ErrorTitle = "计分规则无效"; + scoreRuleValidation.Error = "请选择下拉列表中的计分规则。"; SetColumnWidths(new double[] { 18, 22, 14, 22, 18, 22, 22, 16 }); FreezePanes(3, 1); #endregion @@ -840,13 +867,25 @@ internal sealed class OrderBookTemplateExporter : ExcelExportBase #region 裁判名单 CreateWorksheet("裁判名单"); var refereeHeaders = new[] { "序号", "姓名*", "手机号*" }; - SetMergeTitle("秩序册 - 裁判名单(裁判须先完成注册认证;无裁判可不填本工作表)", 1, 1, 1, refereeHeaders.Length, headerColor, 12); + SetMergeTitle("秩序册 - 裁判名单(须完成注册认证;无裁判可留空)", 1, 1, 1, refereeHeaders.Length, headerColor, 12); SetHeaders(refereeHeaders, 2, headerColor); - var refereeSample = new[] { "1", "李四", "13900000000" }; - for (var c = 0; c < refereeSample.Length; c++) - Worksheet.Cells[3, c + 1].Value = refereeSample[c]; SetDataRowStyle(3, refereeHeaders.Length); - SetColumnWidths(new double[] { 8, 16, 18 }); + SetColumnWidths(new double[] { 10, 18, 22 }); + FreezePanes(3, 1); + #endregion + + #region 计分规则参考 + CreateWorksheet("计分规则参考"); + var scoreRuleHeaders = new[] { "序号", "计分规则名称" }; + SetMergeTitle("当前已启用的计分规则", 1, 1, 1, scoreRuleHeaders.Length, headerColor, 12); + SetHeaders(scoreRuleHeaders, 2, headerColor); + for (var i = 0; i < _scoreRuleNames.Count; i++) + { + Worksheet.Cells[i + 3, 1].Value = i + 1; + Worksheet.Cells[i + 3, 2].Value = _scoreRuleNames[i]; + SetDataRowStyle(i + 3, scoreRuleHeaders.Length); + } + SetColumnWidths(new double[] { 8, 36 }); FreezePanes(3, 1); #endregion