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);
}
}