using System.ComponentModel.DataAnnotations; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; using Tiku.Api.Contracts; using Tiku.Api.OpenApi; using Tiku.Application.Backoffice; using Tiku.Application.PlatformAdmin; using Tiku.Application.Security; namespace Tiku.Api.Controllers; [ApiController] [Tags("平台端-后台权限")] [Route("api/platform/access")] public sealed class PlatformBackofficeController( IBackofficeService backofficeService, IPlatformApprovalService approvalService, ICurrentAccessContext currentAccessContext) : ControllerBase { [HttpGet("ui-bootstrap")] [Authorize(Policy = TikuPolicies.PlatformBackofficeBootstrap)] [EndpointSummary("查询平台后台菜单与权限")] [EndpointDescription("返回当前平台管理员可见的后台菜单、权限和模块启用状态。")] [ProducesResponseType(StatusCodes.Status200OK)] public async Task> GetUiBootstrap(CancellationToken cancellationToken) { return Ok(await backofficeService.GetPlatformUiBootstrapAsync( await currentAccessContext.GetAsync(cancellationToken), cancellationToken)); } [HttpGet("bootstrap")] [Authorize(Policy = BackendPermissions.PlatformRoleManage)] [EndpointSummary("查询平台角色管理初始化数据")] [ProducesResponseType(StatusCodes.Status200OK)] public async Task> GetBootstrap(CancellationToken cancellationToken) { return Ok(await backofficeService.GetPlatformBootstrapAsync(await ResolveActorAsync(cancellationToken), cancellationToken)); } [HttpPost("roles")] [Authorize(Policy = BackendPermissions.PlatformRoleManage)] [EndpointSummary("创建或更新平台后台角色")] [ProducesResponseType(StatusCodes.Status200OK)] public async Task> UpsertRole( UpsertBackofficeRoleDto request, CancellationToken cancellationToken) { return Ok(await backofficeService.UpsertPlatformRoleAsync(await ResolveActorAsync(cancellationToken), request.ToCommand(), cancellationToken)); } [HttpPut("roles/{roleId:guid}/bindings")] [Authorize(Policy = BackendPermissions.PlatformRoleManage)] [EndpointSummary("替换平台后台角色权限绑定")] [PlatformOperationRisk("critical", PlatformApprovalPolicyCodes.SuperAdminGrant)] [ProducesResponseType(StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status202Accepted)] public async Task> ReplaceRoleBindings( Guid roleId, ReplaceRoleBindingsDto request, [FromHeader(Name = "Idempotency-Key")] [Required] string idempotencyKey, CancellationToken cancellationToken) { var result = await approvalService.ReplaceRoleBindingsAsync(await ResolveActorAsync(cancellationToken), request.ToCommand(roleId), idempotencyKey, cancellationToken); return result.ExecutionStatus == "pending_approval" ? Accepted(result) : Ok(result); } [HttpPut("users/{userId:guid}/roles")] [Authorize(Policy = BackendPermissions.PlatformRoleManage)] [EndpointSummary("替换平台用户后台角色")] [ProducesResponseType(StatusCodes.Status204NoContent)] public async Task ReplaceUserRoles( Guid userId, ReplaceUserRolesDto request, CancellationToken cancellationToken) { await backofficeService.ReplacePlatformUserRolesAsync(await ResolveActorAsync(cancellationToken), request.ToCommand(userId), cancellationToken); return NoContent(); } private async Task ResolveActorAsync(CancellationToken cancellationToken) { return BackofficeActor.FromPlatformAccess(await currentAccessContext.GetAsync(cancellationToken)); } }