feat: 实现租户管理及套餐流程
This commit is contained in:
137
src/Api/TakeoutSaaS.AdminApi/Controllers/TenantsController.cs
Normal file
137
src/Api/TakeoutSaaS.AdminApi/Controllers/TenantsController.cs
Normal file
@@ -0,0 +1,137 @@
|
||||
using MediatR;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using TakeoutSaaS.Application.App.Tenants.Commands;
|
||||
using TakeoutSaaS.Application.App.Tenants.Dto;
|
||||
using TakeoutSaaS.Application.App.Tenants.Queries;
|
||||
using TakeoutSaaS.Module.Authorization.Attributes;
|
||||
using TakeoutSaaS.Shared.Abstractions.Constants;
|
||||
using TakeoutSaaS.Shared.Abstractions.Results;
|
||||
using TakeoutSaaS.Shared.Web.Api;
|
||||
|
||||
namespace TakeoutSaaS.AdminApi.Controllers;
|
||||
|
||||
/// <summary>
|
||||
/// 租户管理。
|
||||
/// </summary>
|
||||
[ApiVersion("1.0")]
|
||||
[Authorize]
|
||||
[Route("api/admin/v{version:apiVersion}/tenants")]
|
||||
public sealed class TenantsController(IMediator mediator) : BaseApiController
|
||||
{
|
||||
/// <summary>
|
||||
/// 注册租户并初始化套餐。
|
||||
/// </summary>
|
||||
[HttpPost]
|
||||
[PermissionAuthorize("tenant:create")]
|
||||
[ProducesResponseType(typeof(ApiResponse<TenantDto>), StatusCodes.Status200OK)]
|
||||
public async Task<ApiResponse<TenantDto>> Register([FromBody] RegisterTenantCommand command, CancellationToken cancellationToken)
|
||||
{
|
||||
var result = await mediator.Send(command, cancellationToken);
|
||||
return ApiResponse<TenantDto>.Ok(result);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 分页查询租户。
|
||||
/// </summary>
|
||||
[HttpGet]
|
||||
[PermissionAuthorize("tenant:read")]
|
||||
[ProducesResponseType(typeof(ApiResponse<PagedResult<TenantDto>>), StatusCodes.Status200OK)]
|
||||
public async Task<ApiResponse<PagedResult<TenantDto>>> Search([FromQuery] SearchTenantsQuery query, CancellationToken cancellationToken)
|
||||
{
|
||||
var result = await mediator.Send(query, cancellationToken);
|
||||
return ApiResponse<PagedResult<TenantDto>>.Ok(result);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查看租户详情。
|
||||
/// </summary>
|
||||
[HttpGet("{tenantId:long}")]
|
||||
[PermissionAuthorize("tenant:read")]
|
||||
[ProducesResponseType(typeof(ApiResponse<TenantDetailDto>), StatusCodes.Status200OK)]
|
||||
public async Task<ApiResponse<TenantDetailDto>> Detail(long tenantId, CancellationToken cancellationToken)
|
||||
{
|
||||
var result = await mediator.Send(new GetTenantByIdQuery(tenantId), cancellationToken);
|
||||
return ApiResponse<TenantDetailDto>.Ok(result);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 提交或更新实名认证资料。
|
||||
/// </summary>
|
||||
[HttpPost("{tenantId:long}/verification")]
|
||||
[PermissionAuthorize("tenant:review")]
|
||||
[ProducesResponseType(typeof(ApiResponse<TenantVerificationDto>), StatusCodes.Status200OK)]
|
||||
public async Task<ApiResponse<TenantVerificationDto>> SubmitVerification(
|
||||
long tenantId,
|
||||
[FromBody] SubmitTenantVerificationCommand body,
|
||||
CancellationToken cancellationToken)
|
||||
{
|
||||
var command = body with { TenantId = tenantId };
|
||||
var result = await mediator.Send(command, cancellationToken);
|
||||
return ApiResponse<TenantVerificationDto>.Ok(result);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 审核租户。
|
||||
/// </summary>
|
||||
[HttpPost("{tenantId:long}/review")]
|
||||
[PermissionAuthorize("tenant:review")]
|
||||
[ProducesResponseType(typeof(ApiResponse<TenantDto>), StatusCodes.Status200OK)]
|
||||
public async Task<ApiResponse<TenantDto>> Review(long tenantId, [FromBody] ReviewTenantCommand body, CancellationToken cancellationToken)
|
||||
{
|
||||
var command = body with { TenantId = tenantId };
|
||||
var result = await mediator.Send(command, cancellationToken);
|
||||
return ApiResponse<TenantDto>.Ok(result);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 创建或续费租户订阅。
|
||||
/// </summary>
|
||||
[HttpPost("{tenantId:long}/subscriptions")]
|
||||
[PermissionAuthorize("tenant:subscription")]
|
||||
[ProducesResponseType(typeof(ApiResponse<TenantSubscriptionDto>), StatusCodes.Status200OK)]
|
||||
public async Task<ApiResponse<TenantSubscriptionDto>> CreateSubscription(
|
||||
long tenantId,
|
||||
[FromBody] CreateTenantSubscriptionCommand body,
|
||||
CancellationToken cancellationToken)
|
||||
{
|
||||
var command = body with { TenantId = tenantId };
|
||||
var result = await mediator.Send(command, cancellationToken);
|
||||
return ApiResponse<TenantSubscriptionDto>.Ok(result);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 套餐升降配。
|
||||
/// </summary>
|
||||
[HttpPut("{tenantId:long}/subscriptions/{subscriptionId:long}/plan")]
|
||||
[PermissionAuthorize("tenant:subscription")]
|
||||
[ProducesResponseType(typeof(ApiResponse<TenantSubscriptionDto>), StatusCodes.Status200OK)]
|
||||
public async Task<ApiResponse<TenantSubscriptionDto>> ChangePlan(
|
||||
long tenantId,
|
||||
long subscriptionId,
|
||||
[FromBody] ChangeTenantSubscriptionPlanCommand body,
|
||||
CancellationToken cancellationToken)
|
||||
{
|
||||
var command = body with { TenantId = tenantId, TenantSubscriptionId = subscriptionId };
|
||||
var result = await mediator.Send(command, cancellationToken);
|
||||
return ApiResponse<TenantSubscriptionDto>.Ok(result);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查询审核日志。
|
||||
/// </summary>
|
||||
[HttpGet("{tenantId:long}/audits")]
|
||||
[PermissionAuthorize("tenant:read")]
|
||||
[ProducesResponseType(typeof(ApiResponse<PagedResult<TenantAuditLogDto>>), StatusCodes.Status200OK)]
|
||||
public async Task<ApiResponse<PagedResult<TenantAuditLogDto>>> AuditLogs(
|
||||
long tenantId,
|
||||
[FromQuery] int page = 1,
|
||||
[FromQuery] int pageSize = 20,
|
||||
CancellationToken cancellationToken = default)
|
||||
{
|
||||
var query = new GetTenantAuditLogsQuery(tenantId, page, pageSize);
|
||||
var result = await mediator.Send(query, cancellationToken);
|
||||
return ApiResponse<PagedResult<TenantAuditLogDto>>.Ok(result);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user