using System.Linq; using Microsoft.EntityFrameworkCore; using TakeoutSaaS.Domain.Tenants.Entities; using TakeoutSaaS.Domain.Tenants.Enums; using TakeoutSaaS.Domain.Tenants.Repositories; using TakeoutSaaS.Infrastructure.App.Persistence; namespace TakeoutSaaS.Infrastructure.App.Repositories; /// /// 租户聚合的 EF Core 仓储实现。 /// public sealed class EfTenantRepository(TakeoutAppDbContext context) : ITenantRepository { /// public Task FindByIdAsync(long tenantId, CancellationToken cancellationToken = default) { return context.Tenants .AsNoTracking() .FirstOrDefaultAsync(x => x.Id == tenantId, cancellationToken); } /// public async Task> SearchAsync( TenantStatus? status, string? keyword, CancellationToken cancellationToken = default) { var query = context.Tenants.AsNoTracking(); if (status.HasValue) { query = query.Where(x => x.Status == status.Value); } if (!string.IsNullOrWhiteSpace(keyword)) { keyword = keyword.Trim(); query = query.Where(x => EF.Functions.ILike(x.Name, $"%{keyword}%") || EF.Functions.ILike(x.Code, $"%{keyword}%") || EF.Functions.ILike(x.ContactName ?? string.Empty, $"%{keyword}%")); } return await query .OrderByDescending(x => x.CreatedAt) .ToListAsync(cancellationToken); } /// public Task AddTenantAsync(Tenant tenant, CancellationToken cancellationToken = default) { return context.Tenants.AddAsync(tenant, cancellationToken).AsTask(); } /// public Task UpdateTenantAsync(Tenant tenant, CancellationToken cancellationToken = default) { context.Tenants.Update(tenant); return Task.CompletedTask; } /// public Task ExistsByCodeAsync(string code, CancellationToken cancellationToken = default) { var normalized = code.Trim(); return context.Tenants.AnyAsync(x => x.Code == normalized, cancellationToken); } /// public Task GetVerificationProfileAsync(long tenantId, CancellationToken cancellationToken = default) { return context.TenantVerificationProfiles .AsNoTracking() .FirstOrDefaultAsync(x => x.TenantId == tenantId, cancellationToken); } /// public async Task UpsertVerificationProfileAsync(TenantVerificationProfile profile, CancellationToken cancellationToken = default) { var existing = await context.TenantVerificationProfiles .FirstOrDefaultAsync(x => x.TenantId == profile.TenantId, cancellationToken); if (existing == null) { await context.TenantVerificationProfiles.AddAsync(profile, cancellationToken); return; } profile.Id = existing.Id; context.Entry(existing).CurrentValues.SetValues(profile); } /// public Task GetActiveSubscriptionAsync(long tenantId, CancellationToken cancellationToken = default) { return context.TenantSubscriptions .AsNoTracking() .Where(x => x.TenantId == tenantId) .OrderByDescending(x => x.EffectiveTo) .FirstOrDefaultAsync(cancellationToken); } /// public Task FindSubscriptionByIdAsync(long tenantId, long subscriptionId, CancellationToken cancellationToken = default) { return context.TenantSubscriptions .FirstOrDefaultAsync(x => x.TenantId == tenantId && x.Id == subscriptionId, cancellationToken); } /// public Task AddSubscriptionAsync(TenantSubscription subscription, CancellationToken cancellationToken = default) { return context.TenantSubscriptions.AddAsync(subscription, cancellationToken).AsTask(); } /// public Task UpdateSubscriptionAsync(TenantSubscription subscription, CancellationToken cancellationToken = default) { context.TenantSubscriptions.Update(subscription); return Task.CompletedTask; } /// public Task AddSubscriptionHistoryAsync(TenantSubscriptionHistory history, CancellationToken cancellationToken = default) { return context.TenantSubscriptionHistories.AddAsync(history, cancellationToken).AsTask(); } /// public async Task> GetSubscriptionHistoryAsync(long tenantId, CancellationToken cancellationToken = default) { return await context.TenantSubscriptionHistories .AsNoTracking() .Where(x => x.TenantId == tenantId) .OrderByDescending(x => x.EffectiveFrom) .ToListAsync(cancellationToken); } /// public Task AddAuditLogAsync(TenantAuditLog log, CancellationToken cancellationToken = default) { return context.TenantAuditLogs.AddAsync(log, cancellationToken).AsTask(); } /// public async Task> GetAuditLogsAsync(long tenantId, CancellationToken cancellationToken = default) { return await context.TenantAuditLogs .AsNoTracking() .Where(x => x.TenantId == tenantId) .OrderByDescending(x => x.CreatedAt) .ToListAsync(cancellationToken); } /// public Task SaveChangesAsync(CancellationToken cancellationToken = default) { return context.SaveChangesAsync(cancellationToken); } }