294 lines
13 KiB
C#
294 lines
13 KiB
C#
using Microsoft.AspNetCore.Authorization;
|
|
using Microsoft.AspNetCore.Mvc;
|
|
using Tiku.Api.Contracts;
|
|
using Tiku.Application.PlatformAdmin;
|
|
using Tiku.Application.Security;
|
|
using Tiku.Domain.Platform;
|
|
|
|
namespace Tiku.Api.Controllers;
|
|
|
|
[ApiController]
|
|
[Authorize(Policy = BackendPermissions.PlatformDashboardView)]
|
|
[Produces("application/json")]
|
|
[Route("api/platform-admin")]
|
|
public sealed class PlatformAdminController(
|
|
IPlatformAdminService platformAdminService,
|
|
ICurrentUser currentUser) : ControllerBase
|
|
{
|
|
[HttpGet("overview")]
|
|
[EndpointSummary("查询平台经营概览")]
|
|
[ProducesResponseType<PlatformOverview>(StatusCodes.Status200OK)]
|
|
public async Task<ActionResult<PlatformOverview>> Overview(CancellationToken cancellationToken)
|
|
{
|
|
return Ok(await platformAdminService.GetOverviewAsync(ResolveActor(), cancellationToken));
|
|
}
|
|
|
|
[HttpGet("tenants")]
|
|
[Authorize(Policy = BackendPermissions.PlatformTenantManage)]
|
|
[EndpointSummary("查询平台租户列表")]
|
|
[ProducesResponseType<PlatformTenantList>(StatusCodes.Status200OK)]
|
|
public async Task<ActionResult<PlatformTenantList>> Tenants(
|
|
[FromQuery] PlatformAdminQueryDto query,
|
|
CancellationToken cancellationToken)
|
|
{
|
|
return Ok(await platformAdminService.GetTenantsAsync(ResolveActor(), query.ToQuery(), cancellationToken));
|
|
}
|
|
|
|
[HttpPost("tenants")]
|
|
[Authorize(Policy = BackendPermissions.PlatformTenantManage)]
|
|
[EndpointSummary("创建平台租户")]
|
|
[ProducesResponseType<PlatformTenantItem>(StatusCodes.Status200OK)]
|
|
public async Task<ActionResult<PlatformTenantItem>> CreateTenant(
|
|
CreatePlatformTenantDto request,
|
|
CancellationToken cancellationToken)
|
|
{
|
|
return Ok(await platformAdminService.CreateTenantAsync(ResolveActor(), request.ToCommand(), cancellationToken));
|
|
}
|
|
|
|
[HttpGet("tenants/detail")]
|
|
[Authorize(Policy = BackendPermissions.PlatformTenantManage)]
|
|
[EndpointSummary("查询平台租户详情")]
|
|
[ProducesResponseType<PlatformTenantDetail>(StatusCodes.Status200OK)]
|
|
public async Task<ActionResult<PlatformTenantDetail>> TenantDetail(
|
|
[FromQuery] Guid tenantId,
|
|
CancellationToken cancellationToken)
|
|
{
|
|
return Ok(await platformAdminService.GetTenantDetailAsync(ResolveActor(), tenantId, cancellationToken));
|
|
}
|
|
|
|
[HttpPatch("tenants/status")]
|
|
[Authorize(Policy = BackendPermissions.PlatformTenantManage)]
|
|
[EndpointSummary("更新租户业务与账务状态")]
|
|
[ProducesResponseType<PlatformTenantItem>(StatusCodes.Status200OK)]
|
|
public async Task<ActionResult<PlatformTenantItem>> TenantStatus(
|
|
UpdatePlatformTenantStatusDto request,
|
|
CancellationToken cancellationToken)
|
|
{
|
|
return Ok(await platformAdminService.UpdateTenantStatusAsync(ResolveActor(), request.ToCommand(), cancellationToken));
|
|
}
|
|
|
|
[HttpPut("tenants/billing-profile")]
|
|
[Authorize(Policy = BackendPermissions.PlatformTenantManage)]
|
|
[EndpointSummary("保存租户账务与开票资料")]
|
|
[ProducesResponseType<TenantBillingProfileItem>(StatusCodes.Status200OK)]
|
|
public async Task<ActionResult<TenantBillingProfileItem>> BillingProfile(
|
|
UpsertPlatformTenantBillingProfileDto request,
|
|
CancellationToken cancellationToken)
|
|
{
|
|
return Ok(await platformAdminService.UpsertTenantBillingProfileAsync(ResolveActor(), request.ToCommand(), cancellationToken));
|
|
}
|
|
|
|
[HttpGet("plans")]
|
|
[Authorize(Policy = BackendPermissions.PlatformTenantManage)]
|
|
[EndpointSummary("查询平台 SaaS 套餐")]
|
|
[ProducesResponseType<PlatformPlanList>(StatusCodes.Status200OK)]
|
|
public async Task<ActionResult<PlatformPlanList>> Plans(
|
|
[FromQuery] PlatformAdminQueryDto query,
|
|
CancellationToken cancellationToken)
|
|
{
|
|
return Ok(await platformAdminService.GetPlansAsync(ResolveActor(), query.ToQuery(), cancellationToken));
|
|
}
|
|
|
|
[HttpPut("plans/{planCode}/modules")]
|
|
[Authorize(Policy = BackendPermissions.PlatformTenantManage)]
|
|
[EndpointSummary("替换 SaaS 套餐模块权益")]
|
|
[ProducesResponseType<PlatformPlanModuleEntitlements>(StatusCodes.Status200OK)]
|
|
public async Task<ActionResult<PlatformPlanModuleEntitlements>> ReplacePlanModules(
|
|
string planCode,
|
|
ReplacePlatformPlanModulesDto request,
|
|
CancellationToken cancellationToken)
|
|
{
|
|
return Ok(await platformAdminService.ReplacePlanModulesAsync(
|
|
ResolveActor(), request.ToCommand(planCode), cancellationToken));
|
|
}
|
|
|
|
[HttpPost("subscriptions")]
|
|
[Authorize(Policy = BackendPermissions.PlatformTenantManage)]
|
|
[EndpointSummary("创建或调整租户订阅")]
|
|
[ProducesResponseType<PlatformTenantSubscriptionItem>(StatusCodes.Status200OK)]
|
|
public async Task<ActionResult<PlatformTenantSubscriptionItem>> UpsertSubscription(
|
|
UpsertPlatformSubscriptionDto request,
|
|
CancellationToken cancellationToken)
|
|
{
|
|
return Ok(await platformAdminService.UpsertSubscriptionAsync(ResolveActor(), request.ToCommand(), cancellationToken));
|
|
}
|
|
|
|
[HttpPut("tenants/{tenantId:guid}/module-overrides/{moduleCode}")]
|
|
[Authorize(Policy = BackendPermissions.PlatformTenantManage)]
|
|
[EndpointSummary("设置租户模块覆盖")]
|
|
[ProducesResponseType<PlatformTenantModuleOverrideItem>(StatusCodes.Status200OK)]
|
|
public async Task<ActionResult<PlatformTenantModuleOverrideItem>> UpsertTenantModuleOverride(
|
|
Guid tenantId,
|
|
string moduleCode,
|
|
UpsertPlatformTenantModuleOverrideDto request,
|
|
CancellationToken cancellationToken)
|
|
{
|
|
return Ok(await platformAdminService.UpsertTenantModuleOverrideAsync(
|
|
ResolveActor(), request.ToCommand(tenantId, moduleCode), cancellationToken));
|
|
}
|
|
|
|
[HttpGet("domains")]
|
|
[Authorize(Policy = BackendPermissions.PlatformTenantManage)]
|
|
[EndpointSummary("查询租户域名状态")]
|
|
[ProducesResponseType<PlatformDomainList>(StatusCodes.Status200OK)]
|
|
public async Task<ActionResult<PlatformDomainList>> Domains(
|
|
[FromQuery] PlatformAdminQueryDto query,
|
|
CancellationToken cancellationToken)
|
|
{
|
|
return Ok(await platformAdminService.GetDomainsAsync(ResolveActor(), query.ToQuery(), cancellationToken));
|
|
}
|
|
|
|
[HttpPost("domains/{domainId:guid}/recheck")]
|
|
[Authorize(Policy = BackendPermissions.PlatformTenantManage)]
|
|
[EndpointSummary("重新触发租户域名 DNS/TLS 验证")]
|
|
[ProducesResponseType<PlatformDomainRecheckResult>(StatusCodes.Status200OK)]
|
|
public async Task<ActionResult<PlatformDomainRecheckResult>> RecheckDomain(
|
|
Guid domainId,
|
|
CancellationToken cancellationToken)
|
|
{
|
|
return Ok(await platformAdminService.RecheckDomainAsync(ResolveActor(), domainId, cancellationToken));
|
|
}
|
|
|
|
[HttpGet("staff")]
|
|
[Authorize(Policy = BackendPermissions.PlatformStaffManage)]
|
|
[EndpointSummary("查询平台员工列表")]
|
|
[ProducesResponseType<PlatformStaffList>(StatusCodes.Status200OK)]
|
|
public async Task<ActionResult<PlatformStaffList>> Staff(
|
|
[FromQuery] PlatformAdminQueryDto query,
|
|
CancellationToken cancellationToken)
|
|
{
|
|
return Ok(await platformAdminService.GetStaffAsync(ResolveActor(), query.ToQuery(), cancellationToken));
|
|
}
|
|
|
|
[HttpPut("staff")]
|
|
[Authorize(Policy = BackendPermissions.PlatformStaffManage)]
|
|
[EndpointSummary("创建或更新平台员工")]
|
|
[ProducesResponseType<PlatformStaffItem>(StatusCodes.Status200OK)]
|
|
public async Task<ActionResult<PlatformStaffItem>> UpsertStaff(
|
|
UpsertPlatformStaffDto request,
|
|
CancellationToken cancellationToken)
|
|
{
|
|
return Ok(await platformAdminService.UpsertStaffAsync(ResolveActor(), request.ToCommand(), cancellationToken));
|
|
}
|
|
|
|
[HttpPatch("staff/status")]
|
|
[Authorize(Policy = BackendPermissions.PlatformStaffManage)]
|
|
[EndpointSummary("启用或禁用平台员工")]
|
|
[ProducesResponseType<PlatformStaffItem>(StatusCodes.Status200OK)]
|
|
public async Task<ActionResult<PlatformStaffItem>> StaffStatus(
|
|
UpdatePlatformStaffStatusDto request,
|
|
CancellationToken cancellationToken)
|
|
{
|
|
return Ok(await platformAdminService.UpdateStaffStatusAsync(ResolveActor(), request.ToCommand(), cancellationToken));
|
|
}
|
|
|
|
[HttpGet("audit-logs")]
|
|
[Authorize(Policy = BackendPermissions.PlatformAuditView)]
|
|
[EndpointSummary("查询平台审计日志")]
|
|
[ProducesResponseType<PlatformAuditLogList>(StatusCodes.Status200OK)]
|
|
public async Task<ActionResult<PlatformAuditLogList>> AuditLogs(
|
|
[FromQuery] PlatformAdminQueryDto query,
|
|
CancellationToken cancellationToken)
|
|
{
|
|
return Ok(await platformAdminService.GetAuditLogsAsync(ResolveActor(), query.ToQuery(), cancellationToken));
|
|
}
|
|
|
|
[HttpGet("audit-alerts")]
|
|
[Authorize(Policy = BackendPermissions.PlatformAuditView)]
|
|
[EndpointSummary("查询平台审计告警")]
|
|
[ProducesResponseType<PlatformAuditAlertList>(StatusCodes.Status200OK)]
|
|
public async Task<ActionResult<PlatformAuditAlertList>> AuditAlerts(
|
|
[FromQuery] PlatformAdminQueryDto query,
|
|
CancellationToken cancellationToken)
|
|
{
|
|
return Ok(await platformAdminService.GetAuditAlertsAsync(ResolveActor(), query.ToQuery(), cancellationToken));
|
|
}
|
|
|
|
[HttpPost("audit-alerts/status")]
|
|
[Authorize(Policy = BackendPermissions.PlatformAuditView)]
|
|
[EndpointSummary("更新平台审计告警状态")]
|
|
[ProducesResponseType<PlatformAuditAlert>(StatusCodes.Status200OK)]
|
|
public async Task<ActionResult<PlatformAuditAlert>> AuditAlertStatus(
|
|
UpdatePlatformAuditAlertStatusDto request,
|
|
CancellationToken cancellationToken)
|
|
{
|
|
return Ok(await platformAdminService.UpdateAuditAlertStatusAsync(ResolveActor(), request.ToCommand(), cancellationToken));
|
|
}
|
|
|
|
[HttpGet("dunning-notification-channels")]
|
|
[Authorize(Policy = BackendPermissions.PlatformBillingNotification)]
|
|
[EndpointSummary("查询平台催缴通知渠道")]
|
|
[ProducesResponseType<PlatformDunningChannelList>(StatusCodes.Status200OK)]
|
|
public async Task<ActionResult<PlatformDunningChannelList>> DunningChannels(
|
|
[FromQuery] PlatformAdminQueryDto query,
|
|
CancellationToken cancellationToken)
|
|
{
|
|
return Ok(await platformAdminService.GetDunningChannelsAsync(ResolveActor(), query.ToQuery(), cancellationToken));
|
|
}
|
|
|
|
[HttpPut("dunning-notification-channels")]
|
|
[Authorize(Policy = BackendPermissions.PlatformBillingNotification)]
|
|
[EndpointSummary("创建或更新平台催缴通知渠道")]
|
|
[ProducesResponseType<PlatformDunningChannelItem>(StatusCodes.Status200OK)]
|
|
public async Task<ActionResult<PlatformDunningChannelItem>> UpsertDunningChannel(
|
|
UpsertPlatformDunningChannelDto request,
|
|
CancellationToken cancellationToken)
|
|
{
|
|
return Ok(await platformAdminService.UpsertDunningChannelAsync(ResolveActor(), request.ToCommand(), cancellationToken));
|
|
}
|
|
|
|
[HttpPost("dunning-notification-channels/disable")]
|
|
[Authorize(Policy = BackendPermissions.PlatformBillingNotification)]
|
|
[EndpointSummary("禁用平台催缴通知渠道")]
|
|
[ProducesResponseType<PlatformDunningChannelItem>(StatusCodes.Status200OK)]
|
|
public async Task<ActionResult<PlatformDunningChannelItem>> DisableDunningChannel(
|
|
DisablePlatformDunningChannelDto request,
|
|
CancellationToken cancellationToken)
|
|
{
|
|
return Ok(await platformAdminService.DisableDunningChannelAsync(ResolveActor(), request.ToCommand(), cancellationToken));
|
|
}
|
|
|
|
[HttpGet("dunning-notification-events")]
|
|
[Authorize(Policy = BackendPermissions.PlatformBillingNotification)]
|
|
[EndpointSummary("查询平台催缴通知事件")]
|
|
[ProducesResponseType<PlatformDunningEventList>(StatusCodes.Status200OK)]
|
|
public async Task<ActionResult<PlatformDunningEventList>> DunningEvents(
|
|
[FromQuery] PlatformAdminQueryDto query,
|
|
CancellationToken cancellationToken)
|
|
{
|
|
return Ok(await platformAdminService.GetDunningEventsAsync(ResolveActor(), query.ToQuery(), cancellationToken));
|
|
}
|
|
|
|
[HttpGet("dunning-notification-events/detail")]
|
|
[Authorize(Policy = BackendPermissions.PlatformBillingNotification)]
|
|
[EndpointSummary("查询平台催缴通知事件详情")]
|
|
[ProducesResponseType<PlatformDunningEventItem>(StatusCodes.Status200OK)]
|
|
public async Task<ActionResult<PlatformDunningEventItem>> DunningEventDetail(
|
|
[FromQuery] Guid eventId,
|
|
CancellationToken cancellationToken)
|
|
{
|
|
return Ok(await platformAdminService.GetDunningEventDetailAsync(ResolveActor(), eventId, cancellationToken));
|
|
}
|
|
|
|
[HttpPost("dunning-notification-events/retry")]
|
|
[Authorize(Policy = BackendPermissions.PlatformBillingNotification)]
|
|
[EndpointSummary("重新标记平台催缴通知事件待发送")]
|
|
[ProducesResponseType<PlatformDunningEventItem>(StatusCodes.Status200OK)]
|
|
public async Task<ActionResult<PlatformDunningEventItem>> RetryDunningEvent(
|
|
RetryPlatformDunningEventDto request,
|
|
CancellationToken cancellationToken)
|
|
{
|
|
return Ok(await platformAdminService.RetryDunningEventAsync(ResolveActor(), request.ToCommand(), cancellationToken));
|
|
}
|
|
|
|
private PlatformAdminActor ResolveActor()
|
|
{
|
|
if (currentUser.UserId is not { } userId)
|
|
{
|
|
throw new PlatformAdminException("Platform admin actor was not resolved.", "platform_access_denied");
|
|
}
|
|
|
|
return new PlatformAdminActor(userId);
|
|
}
|
|
}
|