feat: 新增租户审核领取和审核日志接口

- 新增 TenantReviewClaim 和 TenantAuditLog 实体
- 新增 TenantAuditAction 枚举
- 新增审核领取相关接口:GET/POST /review/claim, /review/force-claim, /review/release
- 新增审核日志接口:GET /audits
- 更新 ITenantRepository 和 EfTenantRepository
- 更新 TakeoutAppDbContext 添加 DbSet

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
MSuMshk
2026-02-02 20:22:03 +08:00
parent a586407e60
commit 6ffcc09c26
19 changed files with 865 additions and 0 deletions

View File

@@ -0,0 +1,50 @@
using TakeoutSaaS.Domain.Tenants.Enums;
using TakeoutSaaS.Shared.Abstractions.Entities;
namespace TakeoutSaaS.Domain.Tenants.Entities;
/// <summary>
/// 租户审核日志。
/// </summary>
public sealed class TenantAuditLog : AuditableEntityBase
{
/// <summary>
/// 租户 ID。
/// </summary>
public long TenantId { get; set; }
/// <summary>
/// 操作类型。
/// </summary>
public TenantAuditAction Action { get; set; }
/// <summary>
/// 操作标题。
/// </summary>
public string Title { get; set; } = string.Empty;
/// <summary>
/// 操作描述。
/// </summary>
public string? Description { get; set; }
/// <summary>
/// 操作人 ID。
/// </summary>
public long? OperatorId { get; set; }
/// <summary>
/// 操作人名称。
/// </summary>
public string? OperatorName { get; set; }
/// <summary>
/// 操作前状态。
/// </summary>
public TenantStatus? PreviousStatus { get; set; }
/// <summary>
/// 操作后状态。
/// </summary>
public TenantStatus? CurrentStatus { get; set; }
}

View File

@@ -0,0 +1,34 @@
using TakeoutSaaS.Shared.Abstractions.Entities;
namespace TakeoutSaaS.Domain.Tenants.Entities;
/// <summary>
/// 租户审核领取记录。
/// </summary>
public sealed class TenantReviewClaim : AuditableEntityBase
{
/// <summary>
/// 租户 ID。
/// </summary>
public long TenantId { get; set; }
/// <summary>
/// 领取人 ID。
/// </summary>
public long ClaimedBy { get; set; }
/// <summary>
/// 领取人名称。
/// </summary>
public string ClaimedByName { get; set; } = string.Empty;
/// <summary>
/// 领取时间。
/// </summary>
public DateTime ClaimedAt { get; set; }
/// <summary>
/// 释放时间(为空表示未释放)。
/// </summary>
public DateTime? ReleasedAt { get; set; }
}

View File

@@ -0,0 +1,52 @@
namespace TakeoutSaaS.Domain.Tenants.Enums;
/// <summary>
/// 租户审核操作类型。
/// </summary>
public enum TenantAuditAction
{
/// <summary>
/// 创建租户。
/// </summary>
Created = 0,
/// <summary>
/// 领取审核。
/// </summary>
ReviewClaimed = 1,
/// <summary>
/// 释放审核。
/// </summary>
ReviewReleased = 2,
/// <summary>
/// 强制接管审核。
/// </summary>
ReviewForceClaimed = 3,
/// <summary>
/// 审核通过。
/// </summary>
Approved = 4,
/// <summary>
/// 审核驳回。
/// </summary>
Rejected = 5,
/// <summary>
/// 冻结租户。
/// </summary>
Frozen = 6,
/// <summary>
/// 解冻租户。
/// </summary>
Unfrozen = 7,
/// <summary>
/// 更新信息。
/// </summary>
Updated = 8
}

View File

@@ -137,6 +137,44 @@ public interface ITenantRepository
/// <param name="cancellationToken">取消标记。</param>
/// <returns>异步操作任务。</returns>
Task SaveChangesAsync(CancellationToken cancellationToken = default);
/// <summary>
/// 获取租户当前有效的审核领取记录。
/// </summary>
/// <param name="tenantId">租户 ID。</param>
/// <param name="cancellationToken">取消标记。</param>
/// <returns>审核领取记录,未找到返回 null。</returns>
Task<TenantReviewClaim?> GetActiveReviewClaimAsync(long tenantId, CancellationToken cancellationToken = default);
/// <summary>
/// 新增审核领取记录。
/// </summary>
/// <param name="claim">审核领取记录。</param>
/// <param name="cancellationToken">取消标记。</param>
/// <returns>异步操作任务。</returns>
Task AddReviewClaimAsync(TenantReviewClaim claim, CancellationToken cancellationToken = default);
/// <summary>
/// 新增审核日志。
/// </summary>
/// <param name="auditLog">审核日志。</param>
/// <param name="cancellationToken">取消标记。</param>
/// <returns>异步操作任务。</returns>
Task AddAuditLogAsync(TenantAuditLog auditLog, CancellationToken cancellationToken = default);
/// <summary>
/// 获取租户审核日志列表(分页)。
/// </summary>
/// <param name="tenantId">租户 ID。</param>
/// <param name="page">页码(从 1 开始)。</param>
/// <param name="pageSize">每页条数。</param>
/// <param name="cancellationToken">取消标记。</param>
/// <returns>审核日志列表和总数。</returns>
Task<(IReadOnlyList<TenantAuditLog> Items, int TotalCount)> GetAuditLogsAsync(
long tenantId,
int page,
int pageSize,
CancellationToken cancellationToken = default);
}
/// <summary>