feat: 完善手动创建租户功能,添加账单明细和支付记录

1. 手动创建租户时自动生成账单明细(LineItemsJson)
2. 账单状态为已支付时自动创建支付记录
3. 租户列表接口返回联系人信息和认证状态
4. 账单详情接口返回支付记录和解析后的账单明细
5. 管理员账号自动复用租户联系人信息

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
MSuMshk
2026-02-02 17:32:05 +08:00
parent b4a597fe08
commit 59bc3005af
15 changed files with 1513 additions and 6 deletions

View File

@@ -78,6 +78,14 @@ public interface IBillingRepository
/// <param name="cancellationToken">取消标记。</param>
/// <returns>异步操作任务。</returns>
Task AddPaymentAsync(TenantPayment payment, CancellationToken cancellationToken = default);
/// <summary>
/// 获取账单的支付记录列表。
/// </summary>
/// <param name="billingStatementId">账单 ID。</param>
/// <param name="cancellationToken">取消标记。</param>
/// <returns>支付记录列表。</returns>
Task<IReadOnlyList<TenantPayment>> GetPaymentsByBillingIdAsync(long billingStatementId, CancellationToken cancellationToken = default);
}
/// <summary>

View File

@@ -4,7 +4,7 @@ using TakeoutSaaS.Domain.Tenants.Entities;
namespace TakeoutSaaS.Domain.Tenants.Repositories;
/// <summary>
/// 租户只读仓储AdminApi 使用)。
/// 租户仓储AdminApi 使用)。
/// </summary>
public interface ITenantRepository
{
@@ -24,6 +24,15 @@ public interface ITenantRepository
/// <returns>租户列表(仅返回找到的租户)。</returns>
Task<IReadOnlyList<Tenant>> FindByIdsAsync(IReadOnlyCollection<long> tenantIds, CancellationToken cancellationToken = default);
/// <summary>
/// 根据编码查询租户是否存在。
/// </summary>
/// <param name="code">租户编码。</param>
/// <param name="excludeTenantId">排除的租户 ID。</param>
/// <param name="cancellationToken">取消标记。</param>
/// <returns>存在返回 true。</returns>
Task<bool> ExistsByCodeAsync(string code, long? excludeTenantId = null, CancellationToken cancellationToken = default);
/// <summary>
/// 获取所有租户列表(用于下拉选择器)。
/// </summary>
@@ -61,6 +70,73 @@ public interface ITenantRepository
int page,
int pageSize,
CancellationToken cancellationToken = default);
/// <summary>
/// 在事务中批量创建租户及相关数据。
/// </summary>
/// <param name="tenant">租户实体。</param>
/// <param name="subscription">订阅实体。</param>
/// <param name="verification">认证资料实体。</param>
/// <param name="quotaUsages">配额使用记录列表。</param>
/// <param name="billing">账单实体(可选)。</param>
/// <param name="payment">支付记录实体(可选)。</param>
/// <param name="cancellationToken">取消标记。</param>
/// <returns>异步操作任务。</returns>
Task CreateTenantWithRelatedDataAsync(
Tenant tenant,
TenantSubscription subscription,
TenantVerificationProfile verification,
IReadOnlyList<TenantQuotaUsage> quotaUsages,
TenantBillingStatement? billing,
TenantPayment? payment,
CancellationToken cancellationToken = default);
/// <summary>
/// 根据 ID 获取租户(用于更新,带跟踪)。
/// </summary>
/// <param name="tenantId">租户 ID。</param>
/// <param name="cancellationToken">取消标记。</param>
/// <returns>租户实体,不存在则返回 null。</returns>
Task<Tenant?> GetByIdForUpdateAsync(long tenantId, CancellationToken cancellationToken = default);
/// <summary>
/// 根据租户 ID 获取认证资料(用于更新,带跟踪)。
/// </summary>
/// <param name="tenantId">租户 ID。</param>
/// <param name="cancellationToken">取消标记。</param>
/// <returns>认证资料实体,不存在则返回 null。</returns>
Task<TenantVerificationProfile?> GetVerificationForUpdateAsync(long tenantId, CancellationToken cancellationToken = default);
/// <summary>
/// 新增租户。
/// </summary>
/// <param name="tenant">租户实体。</param>
/// <param name="cancellationToken">取消标记。</param>
/// <returns>异步操作任务。</returns>
Task AddAsync(Tenant tenant, CancellationToken cancellationToken = default);
/// <summary>
/// 新增租户订阅。
/// </summary>
/// <param name="subscription">订阅实体。</param>
/// <param name="cancellationToken">取消标记。</param>
/// <returns>异步操作任务。</returns>
Task AddSubscriptionAsync(TenantSubscription subscription, CancellationToken cancellationToken = default);
/// <summary>
/// 新增租户认证资料。
/// </summary>
/// <param name="verification">认证资料实体。</param>
/// <param name="cancellationToken">取消标记。</param>
/// <returns>异步操作任务。</returns>
Task AddVerificationAsync(TenantVerificationProfile verification, CancellationToken cancellationToken = default);
/// <summary>
/// 保存仓储变更。
/// </summary>
/// <param name="cancellationToken">取消标记。</param>
/// <returns>异步操作任务。</returns>
Task SaveChangesAsync(CancellationToken cancellationToken = default);
}
/// <summary>