using MediatR; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; using System.ComponentModel.DataAnnotations; 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.Results; using TakeoutSaaS.Shared.Web.Api; namespace TakeoutSaaS.AdminApi.Controllers; /// /// 租户公告管理。 /// [ApiVersion("1.0")] [Authorize] [Route("api/admin/v{version:apiVersion}/tenants/{tenantId:long}/announcements")] public sealed class TenantAnnouncementsController(IMediator mediator) : BaseApiController { /// /// 分页查询公告。 /// /// 租户公告分页结果。 [HttpGet] [PermissionAuthorize("tenant-announcement:read")] [ProducesResponseType(typeof(ApiResponse>), StatusCodes.Status200OK)] public async Task>> Search(long tenantId, [FromQuery] SearchTenantAnnouncementsQuery query, CancellationToken cancellationToken) { // 1. 绑定租户标识 query = query with { TenantId = tenantId }; // 2. 查询公告列表 var result = await mediator.Send(query, cancellationToken); // 3. 返回分页结果 return ApiResponse>.Ok(result); } /// /// 公告详情。 /// /// 租户公告详情。 [HttpGet("{announcementId:long}")] [PermissionAuthorize("tenant-announcement:read")] [ProducesResponseType(typeof(ApiResponse), StatusCodes.Status200OK)] [ProducesResponseType(typeof(ApiResponse), StatusCodes.Status404NotFound)] public async Task> Detail(long tenantId, long announcementId, CancellationToken cancellationToken) { // 1. 查询指定公告 var result = await mediator.Send(new GetTenantAnnouncementQuery { TenantId = tenantId, AnnouncementId = announcementId }, cancellationToken); // 2. 返回详情或 404 return result is null ? ApiResponse.Error(StatusCodes.Status404NotFound, "公告不存在") : ApiResponse.Ok(result); } /// /// 创建公告。 /// /// 创建的公告信息。 [HttpPost] [PermissionAuthorize("tenant-announcement:create")] [ProducesResponseType(typeof(ApiResponse), StatusCodes.Status200OK)] public async Task> Create(long tenantId, [FromBody, Required] CreateTenantAnnouncementCommand command, CancellationToken cancellationToken) { // 1. 绑定租户标识 command = command with { TenantId = tenantId }; // 2. 创建公告并返回 var result = await mediator.Send(command, cancellationToken); return ApiResponse.Ok(result); } /// /// 更新公告。 /// /// 更新后的公告信息。 [HttpPut("{announcementId:long}")] [PermissionAuthorize("tenant-announcement:update")] [ProducesResponseType(typeof(ApiResponse), StatusCodes.Status200OK)] [ProducesResponseType(typeof(ApiResponse), StatusCodes.Status404NotFound)] public async Task> Update(long tenantId, long announcementId, [FromBody, Required] UpdateTenantAnnouncementCommand command, CancellationToken cancellationToken) { // 1. 绑定租户与公告标识 command = command with { TenantId = tenantId, AnnouncementId = announcementId }; // 2. 执行更新 var result = await mediator.Send(command, cancellationToken); // 3. 返回更新结果或 404 return result is null ? ApiResponse.Error(StatusCodes.Status404NotFound, "公告不存在") : ApiResponse.Ok(result); } /// /// 删除公告。 /// /// 删除结果。 [HttpDelete("{announcementId:long}")] [PermissionAuthorize("tenant-announcement:delete")] [ProducesResponseType(typeof(ApiResponse), StatusCodes.Status200OK)] public async Task> Delete(long tenantId, long announcementId, CancellationToken cancellationToken) { // 1. 删除公告 var result = await mediator.Send(new DeleteTenantAnnouncementCommand { TenantId = tenantId, AnnouncementId = announcementId }, cancellationToken); // 2. 返回执行结果 return ApiResponse.Ok(result); } /// /// 标记公告已读。 /// /// 标记已读后的公告信息。 [HttpPost("{announcementId:long}/read")] [PermissionAuthorize("tenant-announcement:read")] [ProducesResponseType(typeof(ApiResponse), StatusCodes.Status200OK)] [ProducesResponseType(typeof(ApiResponse), StatusCodes.Status404NotFound)] public async Task> MarkRead(long tenantId, long announcementId, CancellationToken cancellationToken) { // 1. 标记公告已读 var result = await mediator.Send(new MarkTenantAnnouncementReadCommand { TenantId = tenantId, AnnouncementId = announcementId }, cancellationToken); // 2. 返回结果或 404 return result is null ? ApiResponse.Error(StatusCodes.Status404NotFound, "公告不存在") : ApiResponse.Ok(result); } }