using MediatR; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; using System.ComponentModel.DataAnnotations; using TakeoutSaaS.Application.App.QuotaPackages.Commands; using TakeoutSaaS.Application.App.QuotaPackages.Dto; using TakeoutSaaS.Application.App.QuotaPackages.Queries; using TakeoutSaaS.Module.Authorization.Attributes; using TakeoutSaaS.Shared.Abstractions.Results; using TakeoutSaaS.Shared.Web.Api; namespace TakeoutSaaS.AdminApi.Controllers; /// /// 配额包管理。 /// [ApiVersion("1.0")] [Authorize] [Route("api/admin/v{version:apiVersion}/quota-packages")] public sealed class QuotaPackagesController(IMediator mediator) : BaseApiController { /// /// 配额包列表。 /// /// 查询条件。 /// 取消标记。 /// 配额包分页结果。 [HttpGet] [PermissionAuthorize("quota-package:read")] [ProducesResponseType(typeof(ApiResponse>), StatusCodes.Status200OK)] public async Task>> List([FromQuery] GetQuotaPackageListQuery query, CancellationToken cancellationToken) { // 1. 查询配额包分页 var result = await mediator.Send(query, cancellationToken); // 2. 返回结果 return ApiResponse>.Ok(result); } /// /// 创建配额包。 /// /// 创建命令。 /// 取消标记。 /// 创建后的配额包。 [HttpPost] [PermissionAuthorize("quota-package:create")] [ProducesResponseType(typeof(ApiResponse), StatusCodes.Status200OK)] public async Task> Create([FromBody, Required] CreateQuotaPackageCommand command, CancellationToken cancellationToken) { // 1. 执行创建 var result = await mediator.Send(command, cancellationToken); // 2. 返回创建结果 return ApiResponse.Ok(result); } /// /// 更新配额包。 /// /// 配额包 ID。 /// 更新命令。 /// 取消标记。 /// 更新后的配额包或未找到。 [HttpPut("{quotaPackageId:long}")] [PermissionAuthorize("quota-package:update")] [ProducesResponseType(typeof(ApiResponse), StatusCodes.Status200OK)] [ProducesResponseType(typeof(ApiResponse), StatusCodes.Status404NotFound)] public async Task> Update(long quotaPackageId, [FromBody, Required] UpdateQuotaPackageCommand command, CancellationToken cancellationToken) { // 1. 绑定路由 ID command = command with { QuotaPackageId = quotaPackageId }; // 2. 执行更新 var result = await mediator.Send(command, cancellationToken); // 3. 返回更新结果或 404 return result is null ? ApiResponse.Error(StatusCodes.Status404NotFound, "配额包不存在") : ApiResponse.Ok(result); } /// /// 删除配额包。 /// /// 配额包 ID。 /// 取消标记。 /// 删除结果。 [HttpDelete("{quotaPackageId:long}")] [PermissionAuthorize("quota-package:delete")] [ProducesResponseType(typeof(ApiResponse), StatusCodes.Status200OK)] public async Task> Delete(long quotaPackageId, CancellationToken cancellationToken) { // 1. 构建删除命令 var command = new DeleteQuotaPackageCommand { QuotaPackageId = quotaPackageId }; // 2. 执行删除并返回 var result = await mediator.Send(command, cancellationToken); return ApiResponse.Ok(result); } /// /// 上架/下架配额包。 /// /// 配额包 ID。 /// 状态更新命令。 /// 取消标记。 /// 更新结果。 [HttpPut("{quotaPackageId:long}/status")] [PermissionAuthorize("quota-package:update")] [ProducesResponseType(typeof(ApiResponse), StatusCodes.Status200OK)] public async Task> UpdateStatus(long quotaPackageId, [FromBody, Required] UpdateQuotaPackageStatusCommand command, CancellationToken cancellationToken) { // 1. 绑定路由 ID command = command with { QuotaPackageId = quotaPackageId }; // 2. 执行状态更新 var result = await mediator.Send(command, cancellationToken); // 3. 返回结果 return ApiResponse.Ok(result); } /// /// 为租户购买配额包。 /// /// 租户 ID。 /// 购买命令。 /// 取消标记。 /// 购买记录。 [HttpPost("~/api/admin/v{version:apiVersion}/tenants/{tenantId:long}/quota-packages")] [PermissionAuthorize("tenant:quota:purchase")] [ProducesResponseType(typeof(ApiResponse), StatusCodes.Status200OK)] public async Task> PurchaseForTenant( long tenantId, [FromBody, Required] PurchaseQuotaPackageCommand command, CancellationToken cancellationToken) { // 1. 绑定租户 ID command = command with { TenantId = tenantId }; // 2. 执行购买 var result = await mediator.Send(command, cancellationToken); // 3. 返回购买结果 return ApiResponse.Ok(result); } /// /// 租户配额使用情况。 /// /// 租户 ID。 /// 查询条件。 /// 取消标记。 /// 配额使用情况列表。 [HttpGet("~/api/admin/v{version:apiVersion}/tenants/{tenantId:long}/quota-usage")] [PermissionAuthorize("tenant:quota:read")] [ProducesResponseType(typeof(ApiResponse>), StatusCodes.Status200OK)] public async Task>> GetTenantQuotaUsage( long tenantId, [FromQuery] GetTenantQuotaUsageQuery query, CancellationToken cancellationToken) { // 1. 绑定租户 ID query = query with { TenantId = tenantId }; // 2. 查询配额使用情况 var result = await mediator.Send(query, cancellationToken); // 3. 返回结果 return ApiResponse>.Ok(result); } /// /// 租户配额购买记录。 /// /// 租户 ID。 /// 查询条件。 /// 取消标记。 /// 购买记录分页结果。 [HttpGet("~/api/admin/v{version:apiVersion}/tenants/{tenantId:long}/quota-purchases")] [PermissionAuthorize("tenant:quota:read")] [ProducesResponseType(typeof(ApiResponse>), StatusCodes.Status200OK)] public async Task>> GetTenantQuotaPurchases( long tenantId, [FromQuery] GetTenantQuotaPurchasesQuery query, CancellationToken cancellationToken) { // 1. 绑定租户 ID query = query with { TenantId = tenantId }; // 2. 查询购买记录 var result = await mediator.Send(query, cancellationToken); // 3. 返回结果 return ApiResponse>.Ok(result); } }