Files
tiku-backend.net/Tiku.Api/Controllers/PlatformContentV2AuthoringController.cs
xiong 3f5957d744
Some checks failed
ci / release-gate (push) Has been cancelled
feat(content): establish v2 learning delivery foundation
2026-08-06 09:52:18 +08:00

113 lines
4.3 KiB
C#

using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Tiku.Api.Contracts;
using Tiku.Api.Security;
using Tiku.Application.Content;
using Tiku.Application.Security;
namespace Tiku.Api.Controllers;
[ApiController]
[Tags("平台端-公共内容 V2")]
[Authorize(Policy = TikuPolicies.PlatformBackofficeBootstrap)]
[Authorize(Policy = BackendPermissions.PlatformQuestionBankManage)]
[Produces("application/json")]
[Route("api/platform/content-v2")]
public sealed class PlatformContentV2AuthoringController(
IContentV2AuthoringService service,
IContentReleaseCompiler releaseCompiler,
IPlatformContentActorResolver actorResolver,
ICurrentUser currentUser) : ControllerBase
{
[HttpPost("questions/duplicate-search")]
[EndpointSummary("查询平台公共题范围内的精确和相似题")]
public async Task<QuestionDuplicateSearchResult> SearchDuplicates(
QuestionDuplicateSearchDto request,
CancellationToken cancellationToken)
{
return await service.SearchDuplicatesAsync(
await ActorAsync(cancellationToken),
request.Draft.ToCommand(),
request.Limit,
cancellationToken);
}
[HttpPost("questions/execute")]
[EndpointSummary("按审核决策录入平台公共题")]
public async Task<QuestionAuthoringResult> Execute(
ExecuteQuestionAuthoringDto request,
CancellationToken cancellationToken)
{
return await service.ExecuteAsync(
await ActorAsync(cancellationToken), request.ToCommand(), cancellationToken);
}
[HttpPost("questions/{questionAssetId:guid}/revisions")]
[EndpointSummary("为平台公共题创建不可变 Revision")]
public async Task<QuestionAuthoringResult> CreateRevision(
Guid questionAssetId,
CreateQuestionRevisionV2Dto request,
CancellationToken cancellationToken)
{
return await service.CreateRevisionAsync(
await ActorAsync(cancellationToken),
questionAssetId,
request.Draft.ToCommand(),
request.PublishAsset,
cancellationToken);
}
[HttpPost("questions/placements")]
[EndpointSummary("把平台公共题放置到大纲并配置目标规则")]
public async Task<QuestionPlacementItem> CreatePlacement(
CreateQuestionPlacementDto request,
CancellationToken cancellationToken)
{
return await service.CreatePlacementAsync(
await ActorAsync(cancellationToken), request.ToCommand(), cancellationToken);
}
[HttpPost("imports/questions/preview")]
[EndpointSummary("预览平台公共题批量导入")]
public async Task<QuestionImportPreviewResult> PreviewImport(
PreviewQuestionImportV2Dto request,
CancellationToken cancellationToken)
{
return await service.PreviewImportAsync(
await ActorAsync(cancellationToken),
request.Rows.Select(row => (row.RowKey, row.Draft.ToCommand())).ToArray(),
cancellationToken);
}
[HttpPost("imports/questions/execute")]
[EndpointSummary("执行平台公共题批量导入决策")]
public async Task<QuestionImportExecutionResult> ExecuteImport(
ExecuteQuestionImportV2Dto request,
CancellationToken cancellationToken)
{
return await service.ExecuteImportAsync(
await ActorAsync(cancellationToken),
request.Rows.Select(row => new ExecuteQuestionImportRow(row.RowKey, row.Command.ToCommand())).ToArray(),
cancellationToken);
}
[HttpPost("releases/publish")]
[EndpointSummary("校验并发布平台公共不可变 Release")]
public async Task<ContentReleaseCompilationResult> PublishRelease(
PublishContentReleaseDto request,
CancellationToken cancellationToken)
{
var actor = await ActorAsync(cancellationToken);
return await releaseCompiler.PublishAsync(
new PublishContentReleaseCommand(actor.TenantId, actor.UserId, request.CurriculumVersionId, request.Name),
cancellationToken);
}
private Task<ContentAuthorActor> ActorAsync(CancellationToken cancellationToken)
{
return currentUser.UserId is { } userId
? actorResolver.ResolveAsync(userId, cancellationToken)
: throw new ContentV2Exception("platform_access_denied", "The platform actor was not resolved.");
}
}