YD_TrainingCompetition_Api/Controllers/CompetitionController.cs

159 lines
5.0 KiB
C#
Raw Normal View History

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