using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; using Tiku.Api.Contracts; using Tiku.Application.Assets; using Tiku.Application.Catalog; using Tiku.Application.Security; namespace Tiku.Api.Controllers; [ApiController] [Authorize(Policy = TikuPolicies.TenantAdmin)] [Produces("application/json")] [Route("api/tenant-content")] public sealed class TenantContentController( IAssetManagementService assetManagementService, ICurrentUser currentUser, ICurrentTenant currentTenant) : ControllerBase { [HttpGet("assets")] [EndpointSummary("查询租户内容资产")] [ProducesResponseType>(StatusCodes.Status200OK)] public async Task>> GetAssets( [FromQuery] AssetManagementQueryDto query, CancellationToken cancellationToken) { return Ok(await assetManagementService.GetAssetsAsync( ResolveActor(), query.ToFilter(), cancellationToken)); } [HttpPost("assets/uploads/sign")] [EndpointSummary("创建资产上传签名")] [ProducesResponseType(StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status401Unauthorized)] [ProducesResponseType(StatusCodes.Status403Forbidden)] public async Task> SignAssetUpload( AssetUploadSignDto request, CancellationToken cancellationToken) { return Ok(await assetManagementService.SignUploadAsync( ResolveActor(), request.ToCommand(), cancellationToken)); } [HttpPost("assets/uploads/confirm")] [EndpointSummary("确认资产上传完成")] [ProducesResponseType(StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status404NotFound)] [ProducesResponseType(StatusCodes.Status409Conflict)] public async Task> ConfirmAssetUpload( AssetUploadConfirmDto request, CancellationToken cancellationToken) { return Ok(await assetManagementService.ConfirmUploadAsync( ResolveActor(), request.ToCommand(), cancellationToken)); } [HttpGet("import-jobs")] [EndpointSummary("查询内容导入任务")] [ProducesResponseType>(StatusCodes.Status200OK)] public async Task>> GetImportJobs( [FromQuery] ImportJobQueryDto query, CancellationToken cancellationToken) { return Ok(await assetManagementService.GetImportJobsAsync( ResolveActor(), query.ToFilter(), cancellationToken)); } [HttpGet("import-jobs/{jobId:guid}")] [EndpointSummary("查询内容导入任务详情")] [ProducesResponseType(StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status404NotFound)] public async Task> GetImportJob( Guid jobId, CancellationToken cancellationToken) { return Ok(await assetManagementService.GetImportJobAsync( ResolveActor(), jobId, cancellationToken)); } private AssetManagementActor ResolveActor() { if (currentTenant.TenantId is null || currentUser.UserId is null) { throw new AssetManagementException("Tenant content actor was not resolved.", "tenant_content_access_denied"); } return new AssetManagementActor(currentTenant.TenantId.Value, currentUser.UserId.Value); } }