using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; using Tiku.Api.Contracts; using Tiku.Application.Security; using Tiku.Application.Storage; using Tiku.Application.Tenancy; namespace Tiku.Api.Controllers; [ApiController] [Tags("平台端-租户生命周期")] [Route("api/platform/tenants/{tenantId:guid}")] [Authorize(Policy = BackendPermissions.PlatformTenantManage)] public sealed class PlatformTenantLifecycleController( ITenantLifecycleService lifecycleService, ICurrentUser currentUser) : ControllerBase { [HttpGet("archive-preview")] [EndpointSummary("预检租户归档条件")] public async Task> Preview(Guid tenantId, CancellationToken cancellationToken) { return Ok(await lifecycleService.PreviewArchiveAsync(tenantId, cancellationToken)); } [HttpPost("exports")] [EndpointSummary("创建租户数据导出")] public async Task> CreateExport( Guid tenantId, CancellationToken cancellationToken) { return Accepted(await lifecycleService.CreateExportAsync(tenantId, ResolveUserId(), cancellationToken)); } [HttpGet("exports/{operationId:guid}")] [EndpointSummary("查询租户数据导出状态")] public async Task> ExportStatus( Guid tenantId, Guid operationId, CancellationToken cancellationToken) { var operation = await lifecycleService.GetOperationAsync(tenantId, operationId, cancellationToken); return operation is null ? NotFound() : Ok(operation); } [HttpGet("exports/{operationId:guid}/download")] [EndpointSummary("获取租户导出下载地址")] public async Task> DownloadExport( Guid tenantId, Guid operationId, CancellationToken cancellationToken) { return Ok(await lifecycleService.SignExportDownloadAsync(tenantId, operationId, cancellationToken)); } [HttpPost("archive")] [EndpointSummary("逻辑归档租户")] public async Task> Archive( Guid tenantId, TenantLifecycleReasonDto request, CancellationToken cancellationToken) { return Ok(await lifecycleService.ArchiveAsync(tenantId, ResolveUserId(), request.Reason, cancellationToken)); } [HttpPost("restore")] [EndpointSummary("恢复租户到暂停状态")] public async Task> Restore( Guid tenantId, TenantLifecycleReasonDto request, CancellationToken cancellationToken) { return Ok(await lifecycleService.RestoreAsync(tenantId, ResolveUserId(), request.Reason, cancellationToken)); } [HttpPost("owner-transfer")] [EndpointSummary("转移租户所有者")] public async Task> TransferOwner( Guid tenantId, TenantOwnerTransferDto request, CancellationToken cancellationToken) { return Ok(await lifecycleService.TransferOwnerAsync( tenantId, ResolveUserId(), request.TargetUserId, request.Reason, cancellationToken)); } private Guid ResolveUserId() { return currentUser.UserId ?? throw new InvalidOperationException("Current platform user was not resolved."); } }