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 配额包仓储实现。 /// public sealed class EfQuotaPackageRepository(TakeoutAppDbContext context) : IQuotaPackageRepository { #region 配额包定义 /// public Task FindByIdAsync(long id, CancellationToken cancellationToken = default) { return context.QuotaPackages .FirstOrDefaultAsync(x => x.Id == id && x.DeletedAt == null, cancellationToken); } /// public async Task<(IReadOnlyList Items, int Total)> SearchPagedAsync( TenantQuotaType? quotaType, bool? isActive, int page, int pageSize, CancellationToken cancellationToken = default) { var query = context.QuotaPackages.AsNoTracking() .Where(x => x.DeletedAt == null); if (quotaType.HasValue) { query = query.Where(x => x.QuotaType == quotaType.Value); } if (isActive.HasValue) { query = query.Where(x => x.IsActive == isActive.Value); } var total = await query.CountAsync(cancellationToken); var items = await query .OrderBy(x => x.SortOrder) .ThenBy(x => x.CreatedAt) .Skip((page - 1) * pageSize) .Take(pageSize) .ToListAsync(cancellationToken); return (items, total); } /// public Task AddAsync(QuotaPackage quotaPackage, CancellationToken cancellationToken = default) { return context.QuotaPackages.AddAsync(quotaPackage, cancellationToken).AsTask(); } /// public Task UpdateAsync(QuotaPackage quotaPackage, CancellationToken cancellationToken = default) { context.QuotaPackages.Update(quotaPackage); return Task.CompletedTask; } /// public async Task SoftDeleteAsync(long id, CancellationToken cancellationToken = default) { var quotaPackage = await context.QuotaPackages .FirstOrDefaultAsync(x => x.Id == id && x.DeletedAt == null, cancellationToken); if (quotaPackage == null) { return false; } quotaPackage.DeletedAt = DateTime.UtcNow; return true; } #endregion #region 配额包购买记录 /// public async Task<(IReadOnlyList<(TenantQuotaPackagePurchase Purchase, QuotaPackage Package)> Items, int Total)> GetPurchasesPagedAsync( long tenantId, int page, int pageSize, CancellationToken cancellationToken = default) { var query = context.TenantQuotaPackagePurchases.AsNoTracking() .Where(x => x.TenantId == tenantId && x.DeletedAt == null); var total = await query.CountAsync(cancellationToken); var items = await query .OrderByDescending(x => x.PurchasedAt) .Skip((page - 1) * pageSize) .Take(pageSize) .Join(context.QuotaPackages.AsNoTracking(), purchase => purchase.QuotaPackageId, package => package.Id, (purchase, package) => new { Purchase = purchase, Package = package }) .ToListAsync(cancellationToken); return (items.Select(x => (x.Purchase, x.Package)).ToList(), total); } /// public Task AddPurchaseAsync(TenantQuotaPackagePurchase purchase, CancellationToken cancellationToken = default) { return context.TenantQuotaPackagePurchases.AddAsync(purchase, cancellationToken).AsTask(); } #endregion #region 配额使用情况 /// public async Task> GetUsageByTenantAsync( long tenantId, TenantQuotaType? quotaType, CancellationToken cancellationToken = default) { var query = context.TenantQuotaUsages.AsNoTracking() .Where(x => x.TenantId == tenantId); if (quotaType.HasValue) { query = query.Where(x => x.QuotaType == quotaType.Value); } return await query.ToListAsync(cancellationToken); } /// public Task FindUsageAsync( long tenantId, TenantQuotaType quotaType, CancellationToken cancellationToken = default) { return context.TenantQuotaUsages .FirstOrDefaultAsync(x => x.TenantId == tenantId && x.QuotaType == quotaType, cancellationToken); } /// public Task UpdateUsageAsync(TenantQuotaUsage usage, CancellationToken cancellationToken = default) { context.TenantQuotaUsages.Update(usage); return Task.CompletedTask; } #endregion /// public Task SaveChangesAsync(CancellationToken cancellationToken = default) { return context.SaveChangesAsync(cancellationToken); } }