using MediatR;
using TakeoutSaaS.Application.App.Tenants.Commands;
using TakeoutSaaS.Application.App.Tenants.Dto;
using TakeoutSaaS.Application.Messaging.Abstractions;
using TakeoutSaaS.Domain.Tenants.Enums;
using TakeoutSaaS.Domain.Tenants.Events;
using TakeoutSaaS.Domain.Tenants.Repositories;
using TakeoutSaaS.Shared.Abstractions.Constants;
using TakeoutSaaS.Shared.Abstractions.Exceptions;
using TakeoutSaaS.Shared.Abstractions.Tenancy;
namespace TakeoutSaaS.Application.App.Tenants.Handlers;
///
/// 撤销公告处理器。
///
public sealed class RevokeAnnouncementCommandHandler(
ITenantAnnouncementRepository announcementRepository,
ITenantProvider tenantProvider,
IEventPublisher eventPublisher)
: IRequestHandler
{
///
public async Task Handle(RevokeAnnouncementCommand request, CancellationToken cancellationToken)
{
// 1. 查询公告
var tenantId = tenantProvider.GetCurrentTenantId();
var announcement = await announcementRepository.FindByIdAsync(tenantId, request.AnnouncementId, cancellationToken);
if (announcement == null)
{
return null;
}
// 2. 校验状态
if (announcement.Status != AnnouncementStatus.Published)
{
if (announcement.Status == AnnouncementStatus.Revoked)
{
throw new BusinessException(ErrorCodes.Conflict, "公告已撤销");
}
throw new BusinessException(ErrorCodes.Conflict, "仅已发布公告允许撤销");
}
// 3. 撤销公告
announcement.Status = AnnouncementStatus.Revoked;
announcement.RevokedAt = DateTime.UtcNow;
announcement.IsActive = false;
announcement.RowVersion = request.RowVersion;
await announcementRepository.UpdateAsync(announcement, cancellationToken);
await announcementRepository.SaveChangesAsync(cancellationToken);
// 4. 发布领域事件
await eventPublisher.PublishAsync(
"tenant-announcement.revoked",
new AnnouncementRevoked
{
AnnouncementId = announcement.Id,
RevokedAt = announcement.RevokedAt ?? DateTime.UtcNow
},
cancellationToken);
return announcement.ToDto(false, null);
}
}