Files
tiku-backend.net/Tiku.Api/Controllers/PlatformQuestionBanksController.cs
xiong 33375a38d7
Some checks failed
ci / release-gate (push) Has been cancelled
refactor(architecture): harden module boundaries
2026-08-04 12:10:36 +08:00

171 lines
6.9 KiB
C#

using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Tiku.Api.Contracts;
using Tiku.Application.Assets;
using Tiku.Application.PlatformAdmin;
using Tiku.Application.Security;
namespace Tiku.Api.Controllers;
[ApiController]
[Tags("平台端-公共题库")]
[Authorize(Policy = BackendPermissions.PlatformQuestionBankManage)]
[Produces("application/json")]
[Route("api/platform/question-banks")]
public sealed class PlatformQuestionBanksController(
IPlatformQuestionBankCatalogService catalogService,
IPlatformQuestionBankNodeService nodeService,
IPlatformQuestionAdministrationService questionService,
IPlatformQuestionImportService importService,
IPlatformQuestionAssetService assetService,
ICurrentUser currentUser) : ControllerBase
{
[HttpGet]
[EndpointSummary("查询平台公共题库")]
public async Task<ActionResult<IReadOnlyCollection<PlatformQuestionBankItem>>> GetBanks(
[FromQuery] string? keyword,
[FromQuery] string? status,
CancellationToken cancellationToken)
{
return Ok(await catalogService.GetBanksAsync(ResolveActor(),
new PlatformQuestionBankFilter(Keyword: keyword, Status: status), cancellationToken));
}
[HttpPut]
[EndpointSummary("新增或更新平台公共题库")]
public async Task<ActionResult<PlatformQuestionBankItem>> UpsertBank(
UpsertPlatformQuestionBankCommand request,
CancellationToken cancellationToken)
{
return Ok(await catalogService.UpsertBankAsync(ResolveActor(), request, cancellationToken));
}
[HttpPost("{bankId:guid}/archive")]
[EndpointSummary("归档平台公共题库")]
public async Task<ActionResult<PlatformQuestionBankItem>> ArchiveBank(Guid bankId,
CancellationToken cancellationToken)
{
return Ok(await catalogService.ArchiveBankAsync(ResolveActor(), bankId, cancellationToken));
}
[HttpGet("{bankId:guid}/nodes")]
[EndpointSummary("查询公共题库内容结构")]
public async Task<ActionResult<IReadOnlyCollection<PlatformQuestionBankNodeItem>>> GetNodes(Guid bankId,
CancellationToken cancellationToken)
{
return Ok(await nodeService.GetNodesAsync(ResolveActor(), bankId, cancellationToken));
}
[HttpPut("nodes")]
[EndpointSummary("新增或更新公共题库内容节点")]
public async Task<ActionResult<PlatformQuestionBankNodeItem>> UpsertNode(
UpsertPlatformQuestionBankNodeCommand request,
CancellationToken cancellationToken)
{
return Ok(await nodeService.UpsertNodeAsync(ResolveActor(), request, cancellationToken));
}
[HttpPost("nodes/batch")]
[EndpointSummary("批量创建公共题库章节或试卷")]
public async Task<ActionResult<IReadOnlyCollection<PlatformQuestionBankNodeItem>>> BatchCreateNodes(
BatchCreatePlatformQuestionBankNodesCommand request,
CancellationToken cancellationToken)
{
return Ok(await nodeService.BatchCreateNodesAsync(ResolveActor(), request, cancellationToken));
}
[HttpPost("nodes/{nodeId:guid}/archive")]
[EndpointSummary("归档公共题库内容节点")]
public async Task<ActionResult<PlatformQuestionBankNodeItem>> ArchiveNode(Guid nodeId,
CancellationToken cancellationToken)
{
return Ok(await nodeService.ArchiveNodeAsync(ResolveActor(), nodeId, cancellationToken));
}
[HttpGet("questions")]
[EndpointSummary("分页查询公共题库题目")]
public async Task<ActionResult<PlatformQuestionPage>> GetQuestions(
[FromQuery] Guid questionBankId,
[FromQuery] Guid? contentNodeId,
[FromQuery] string? keyword,
[FromQuery] string? type,
[FromQuery] int? difficulty,
[FromQuery] string? status,
[FromQuery] int page = 1,
[FromQuery] int pageSize = 20,
CancellationToken cancellationToken = default)
{
return Ok(await questionService.GetQuestionsAsync(ResolveActor(), new PlatformQuestionBankFilter(
questionBankId, contentNodeId, keyword, type, difficulty, status, page, pageSize), cancellationToken));
}
[HttpPut("questions")]
[EndpointSummary("新增或更新公共题库题目并保留版本")]
public async Task<ActionResult<PlatformQuestionItem>> UpsertQuestion(
UpsertPlatformQuestionCommand request,
CancellationToken cancellationToken)
{
return Ok(await questionService.UpsertQuestionAsync(ResolveActor(), request, cancellationToken));
}
[HttpPost("questions/archive")]
[EndpointSummary("批量归档公共题库题目")]
public async Task<ActionResult<int>> ArchiveQuestions(
ArchivePlatformQuestionsCommand request,
CancellationToken cancellationToken)
{
return Ok(await questionService.ArchiveQuestionsAsync(ResolveActor(), request, cancellationToken));
}
[HttpPost("imports/preview")]
[EndpointSummary("预检公共题库 JSON 导入")]
public async Task<ActionResult<PlatformQuestionImportResult>> PreviewImport(
PlatformQuestionImportCommand request,
CancellationToken cancellationToken)
{
return Ok(await importService.PreviewImportAsync(ResolveActor(), request, cancellationToken));
}
[HttpPost("imports")]
[EndpointSummary("执行公共题库 JSON 导入")]
public async Task<ActionResult<PlatformQuestionImportResult>> ExecuteImport(
PlatformQuestionImportCommand request,
CancellationToken cancellationToken)
{
return Ok(await importService.ExecuteImportAsync(ResolveActor(), request, cancellationToken));
}
[HttpGet("imports/{jobId:guid}")]
[EndpointSummary("查询公共题库导入结果")]
public async Task<ActionResult<ContentImportJobDetail>> GetImport(Guid jobId, CancellationToken cancellationToken)
{
return Ok(await importService.GetImportAsync(ResolveActor(), jobId, cancellationToken));
}
[HttpPost("assets/upload-sign")]
[EndpointSummary("签发公共题库图片上传地址")]
public async Task<ActionResult<AssetUploadSignResult>> SignAssetUpload(
AssetUploadSignDto request,
CancellationToken cancellationToken)
{
return Ok(await assetService.SignQuestionAssetUploadAsync(ResolveActor(), request.ToCommand(), cancellationToken));
}
[HttpPost("assets/upload-confirm")]
[EndpointSummary("确认公共题库图片上传结果")]
public async Task<ActionResult<AssetUploadConfirmResult>> ConfirmAssetUpload(
AssetUploadConfirmDto request,
CancellationToken cancellationToken)
{
return Ok(await assetService.ConfirmQuestionAssetUploadAsync(ResolveActor(), request.ToCommand(),
cancellationToken));
}
private PlatformAdminActor ResolveActor()
{
return currentUser.UserId is { } userId
? new PlatformAdminActor(userId)
: throw new PlatformAdminException("无法识别当前平台员工。", "platform_access_denied");
}
}