using Microsoft.AspNetCore.Mvc; using YD_TrainingCompetition_Api.Competition; namespace YD_TrainingCompetition_Api.Controllers; [ApiController] [Route("api/[controller]")] // CompetitionController 是前端比赛页使用的主控制器, // 负责暴露“建会话、切场次、下载本场、开始/停止/清零、手工改分”等接口。 public sealed class CompetitionController : ControllerBase { private readonly ICompetitionSessionService _competition; public CompetitionController(ICompetitionSessionService competition) { _competition = competition; } // 获取当前比赛会话快照,页面初始化和重连后都会读取它。 [HttpGet("session")] public IActionResult GetSession() => Ok(_competition.GetState()); // 根据配置页提交的秩序册、场次和人员列表创建新的比赛会话。 [HttpPost("session")] public async Task CreateSession([FromBody] CreateCompetitionSessionRequest request, CancellationToken cancellationToken) { try { return Ok(await _competition.CreateAsync(request, cancellationToken)); } catch (Exception ex) { return BadRequest(new { message = ex.Message }); } } [HttpPost("rounds/{roundIndex:int}/select")] public async Task SelectRound(int roundIndex, CancellationToken cancellationToken) { try { return Ok(await _competition.SelectRoundAsync(roundIndex, cancellationToken)); } catch (Exception ex) { return BadRequest(new { message = ex.Message }); } } [HttpPost("rounds/next")] public async Task NextRound(CancellationToken cancellationToken) { try { return Ok(await _competition.SelectNextRoundAsync(cancellationToken)); } catch (Exception ex) { return BadRequest(new { message = ex.Message }); } } [HttpPost("rounds/previous")] public async Task PreviousRound(CancellationToken cancellationToken) { try { return Ok(await _competition.SelectPreviousRoundAsync(cancellationToken)); } catch (Exception ex) { return BadRequest(new { message = ex.Message }); } } [HttpPost("rounds/current/download")] public async Task DownloadCurrentRound(CancellationToken cancellationToken) { try { return Ok(await _competition.DownloadCurrentRoundAsync(cancellationToken)); } catch (Exception ex) { return BadRequest(new { message = ex.Message }); } } // 下发开始命令,让已下载本场的终端进入正式测试。 [HttpPost("test/start")] public async Task Start(CancellationToken cancellationToken) { try { return Ok(await _competition.StartAsync(cancellationToken)); } catch (Exception ex) { return BadRequest(new { message = ex.Message }); } } // 下发停止命令,但保留终端当前成绩。 [HttpPost("test/stop")] public async Task Stop(CancellationToken cancellationToken) { try { return Ok(await _competition.StopAsync(cancellationToken)); } catch (Exception ex) { return BadRequest(new { message = ex.Message }); } } // 下发清零命令,并把当前场次的本地成绩也一起清空。 [HttpPost("test/reset")] public async Task Reset(CancellationToken cancellationToken) { try { return Ok(await _competition.ResetCurrentRoundAsync(cancellationToken)); } catch (Exception ex) { return BadRequest(new { message = ex.Message }); } } // 手工指定某名选手成绩,主要用于裁判修正。 [HttpPost("participants/{participantId:int}/count")] public async Task SetCount(int participantId, [FromBody] CompetitionParticipantCountRequest request, CancellationToken cancellationToken) { try { return Ok(await _competition.SetParticipantCountAsync(participantId, request.Count, cancellationToken)); } catch (Exception ex) { return BadRequest(new { message = ex.Message }); } } // 在现有成绩基础上增减,适合前端 +/- 按钮。 [HttpPost("participants/{participantId:int}/delta")] public async Task ChangeCount(int participantId, [FromBody] CompetitionParticipantDeltaRequest request, CancellationToken cancellationToken) { try { return Ok(await _competition.ChangeParticipantCountAsync(participantId, request.Delta, cancellationToken)); } catch (Exception ex) { return BadRequest(new { message = ex.Message }); } } }