using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; using Tiku.Api.Contracts; using Tiku.Api.Security; using Tiku.Application.Learning; using Tiku.Application.Security; namespace Tiku.Api.Controllers; [ApiController] [Tags("学生端-学习")] [Authorize(Policy = TikuPolicies.CurrentTenantMember)] [RequireSaasFeature(SaasFeatureCatalog.Practice)] [Produces("application/json")] [Route("api/student/learning")] public sealed class QuestionReviewController( IQuestionReviewService service, LearningActorResolver actorResolver) : ControllerBase { [HttpGet("favorites/questions")] [EndpointSummary("查询收藏题目")] [ProducesResponseType>(StatusCodes.Status200OK)] public async Task>> GetFavoriteQuestions( [FromQuery] LearningLimitQueryDto query, CancellationToken cancellationToken) { return Ok(await service.GetFavoriteQuestionsAsync( actorResolver.Resolve(), query.ToFilter(), cancellationToken)); } [HttpPost("favorites/questions")] [EndpointSummary("收藏或取消收藏题目")] [ProducesResponseType(StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status404NotFound)] public async Task> ToggleFavoriteQuestion( QuestionActionDto request, CancellationToken cancellationToken) { return Ok(await service.ToggleFavoriteQuestionAsync( actorResolver.Resolve(), request.ToCommand(), cancellationToken)); } [HttpGet("wrong-questions")] [EndpointSummary("查询错题列表")] [ProducesResponseType>(StatusCodes.Status200OK)] public async Task>> GetWrongQuestions( [FromQuery] LearningLimitQueryDto query, CancellationToken cancellationToken) { return Ok(await service.GetWrongQuestionsAsync( actorResolver.Resolve(), query.ToFilter(), cancellationToken)); } [HttpGet("wrong-questions/review-plan")] [EndpointSummary("生成错题复习计划")] [ProducesResponseType(StatusCodes.Status200OK)] public async Task> GetWrongQuestionReviewPlan( [FromQuery] LearningLimitQueryDto query, CancellationToken cancellationToken) { return Ok(await service.GetWrongQuestionReviewPlanAsync( actorResolver.Resolve(), query.ToFilter(), cancellationToken)); } [HttpPost("wrong-questions/resolve")] [EndpointSummary("将错题标记为已解决")] [ProducesResponseType(StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status404NotFound)] public async Task> ResolveWrongQuestion( ResolveWrongQuestionDto request, CancellationToken cancellationToken) { return Ok(await service.ResolveWrongQuestionAsync( actorResolver.Resolve(), request.ToCommand(), cancellationToken)); } }