feat: tenants 列表支持名称/联系人/电话/认证状态过滤

This commit is contained in:
2025-12-14 16:12:25 +08:00
parent 456b575596
commit c5a3243bd8
5 changed files with 260 additions and 21 deletions

View File

@@ -41,7 +41,8 @@ public sealed class EfTenantRepository(TakeoutAppDbContext context) : ITenantRep
query = query.Where(x =>
EF.Functions.ILike(x.Name, $"%{keyword}%") ||
EF.Functions.ILike(x.Code, $"%{keyword}%") ||
EF.Functions.ILike(x.ContactName ?? string.Empty, $"%{keyword}%"));
EF.Functions.ILike(x.ContactName ?? string.Empty, $"%{keyword}%") ||
EF.Functions.ILike(x.ContactPhone ?? string.Empty, $"%{keyword}%"));
}
// 4. 排序返回
@@ -50,6 +51,82 @@ public sealed class EfTenantRepository(TakeoutAppDbContext context) : ITenantRep
.ToListAsync(cancellationToken);
}
/// <inheritdoc />
public async Task<(IReadOnlyList<Tenant> Items, int Total)> SearchPagedAsync(
TenantStatus? status,
TenantVerificationStatus? verificationStatus,
string? name,
string? contactName,
string? contactPhone,
string? keyword,
int page,
int pageSize,
CancellationToken cancellationToken = default)
{
var query = context.Tenants.AsNoTracking();
// 1. 按租户状态过滤
if (status.HasValue)
{
query = query.Where(x => x.Status == status.Value);
}
// 2. 按实名认证状态过滤(未提交视为 Draft
if (verificationStatus.HasValue)
{
query = from tenant in query
join profile in context.TenantVerificationProfiles.AsNoTracking()
on tenant.Id equals profile.TenantId into profiles
from profile in profiles.DefaultIfEmpty()
where (profile == null ? TenantVerificationStatus.Draft : profile.Status) == verificationStatus.Value
select tenant;
}
// 3. 按名称/联系人/电话过滤(模糊匹配)
if (!string.IsNullOrWhiteSpace(name))
{
var normalizedName = name.Trim();
query = query.Where(x => EF.Functions.ILike(x.Name, $"%{normalizedName}%"));
}
// 4. (空行后) 按联系人过滤(模糊匹配)
if (!string.IsNullOrWhiteSpace(contactName))
{
var normalizedContactName = contactName.Trim();
query = query.Where(x => EF.Functions.ILike(x.ContactName ?? string.Empty, $"%{normalizedContactName}%"));
}
// 5. (空行后) 按联系电话过滤(模糊匹配)
if (!string.IsNullOrWhiteSpace(contactPhone))
{
var normalizedContactPhone = contactPhone.Trim();
query = query.Where(x => EF.Functions.ILike(x.ContactPhone ?? string.Empty, $"%{normalizedContactPhone}%"));
}
// 6. (空行后) 兼容关键字查询:名称/编码/联系人/电话
if (!string.IsNullOrWhiteSpace(keyword))
{
var normalizedKeyword = keyword.Trim();
query = query.Where(x =>
EF.Functions.ILike(x.Name, $"%{normalizedKeyword}%") ||
EF.Functions.ILike(x.Code, $"%{normalizedKeyword}%") ||
EF.Functions.ILike(x.ContactName ?? string.Empty, $"%{normalizedKeyword}%") ||
EF.Functions.ILike(x.ContactPhone ?? string.Empty, $"%{normalizedKeyword}%"));
}
// 7. (空行后) 先统计总数,再按创建时间倒序分页
var total = await query.CountAsync(cancellationToken);
// 8. (空行后) 查询当前页数据
var items = await query
.OrderByDescending(x => x.CreatedAt)
.Skip((page - 1) * pageSize)
.Take(pageSize)
.ToListAsync(cancellationToken);
return (items, total);
}
/// <inheritdoc />
public Task AddTenantAsync(Tenant tenant, CancellationToken cancellationToken = default)
{
@@ -97,6 +174,24 @@ public sealed class EfTenantRepository(TakeoutAppDbContext context) : ITenantRep
.FirstOrDefaultAsync(x => x.TenantId == tenantId, cancellationToken);
}
/// <inheritdoc />
public async Task<IReadOnlyList<TenantVerificationProfile>> GetVerificationProfilesAsync(
IReadOnlyCollection<long> tenantIds,
CancellationToken cancellationToken = default)
{
// 1. tenantIds 为空直接返回
if (tenantIds.Count == 0)
{
return Array.Empty<TenantVerificationProfile>();
}
// 2. 批量查询实名资料
return await context.TenantVerificationProfiles
.AsNoTracking()
.Where(x => tenantIds.Contains(x.TenantId))
.ToListAsync(cancellationToken);
}
/// <inheritdoc />
public async Task UpsertVerificationProfileAsync(TenantVerificationProfile profile, CancellationToken cancellationToken = default)
{
@@ -126,6 +221,25 @@ public sealed class EfTenantRepository(TakeoutAppDbContext context) : ITenantRep
.FirstOrDefaultAsync(cancellationToken);
}
/// <inheritdoc />
public async Task<IReadOnlyList<TenantSubscription>> GetSubscriptionsAsync(
IReadOnlyCollection<long> tenantIds,
CancellationToken cancellationToken = default)
{
// 1. tenantIds 为空直接返回
if (tenantIds.Count == 0)
{
return Array.Empty<TenantSubscription>();
}
// 2. 批量查询订阅数据
return await context.TenantSubscriptions
.AsNoTracking()
.Where(x => tenantIds.Contains(x.TenantId))
.OrderByDescending(x => x.EffectiveTo)
.ToListAsync(cancellationToken);
}
/// <inheritdoc />
public Task<TenantSubscription?> FindSubscriptionByIdAsync(long tenantId, long subscriptionId, CancellationToken cancellationToken = default)
{