using Microsoft.EntityFrameworkCore; using TakeoutSaaS.Domain.Membership.Entities; using TakeoutSaaS.Domain.Membership.Repositories; using TakeoutSaaS.Infrastructure.App.Persistence; namespace TakeoutSaaS.Infrastructure.App.Repositories; /// /// 会员聚合 EF Core 仓储实现。 /// public sealed class EfMemberRepository(TakeoutAppDbContext context) : IMemberRepository { /// public async Task> GetProfilesAsync(long tenantId, CancellationToken cancellationToken = default) { return await context.MemberProfiles .Where(x => x.TenantId == tenantId) .OrderByDescending(x => x.UpdatedAt ?? x.CreatedAt) .ThenByDescending(x => x.Id) .ToListAsync(cancellationToken); } /// public async Task> GetProfilesByMobilesAsync( long tenantId, IReadOnlyCollection mobiles, CancellationToken cancellationToken = default) { if (mobiles.Count == 0) { return []; } return await context.MemberProfiles .Where(x => x.TenantId == tenantId && mobiles.Contains(x.Mobile)) .ToListAsync(cancellationToken); } /// public Task FindProfileByIdAsync(long tenantId, long memberId, CancellationToken cancellationToken = default) { return context.MemberProfiles .Where(x => x.TenantId == tenantId && x.Id == memberId) .FirstOrDefaultAsync(cancellationToken); } /// public async Task AddProfilesAsync(IEnumerable profiles, CancellationToken cancellationToken = default) { var profileList = profiles?.ToList() ?? []; if (profileList.Count == 0) { return; } await context.MemberProfiles.AddRangeAsync(profileList, cancellationToken); } /// public Task UpdateProfileAsync(MemberProfile profile, CancellationToken cancellationToken = default) { context.MemberProfiles.Update(profile); return Task.CompletedTask; } /// public async Task> GetTiersAsync(long tenantId, CancellationToken cancellationToken = default) { return await context.MemberTiers .Where(x => x.TenantId == tenantId) .OrderBy(x => x.SortOrder) .ThenBy(x => x.Id) .ToListAsync(cancellationToken); } /// public Task FindTierByIdAsync(long tenantId, long tierId, CancellationToken cancellationToken = default) { return context.MemberTiers .Where(x => x.TenantId == tenantId && x.Id == tierId) .FirstOrDefaultAsync(cancellationToken); } /// public Task AddTierAsync(MemberTier tier, CancellationToken cancellationToken = default) { return context.MemberTiers.AddAsync(tier, cancellationToken).AsTask(); } /// public Task UpdateTierAsync(MemberTier tier, CancellationToken cancellationToken = default) { context.MemberTiers.Update(tier); return Task.CompletedTask; } /// public Task DeleteTierAsync(MemberTier tier, CancellationToken cancellationToken = default) { context.MemberTiers.Remove(tier); return Task.CompletedTask; } /// public Task GetMemberDaySettingAsync(long tenantId, CancellationToken cancellationToken = default) { return context.MemberDaySettings .Where(x => x.TenantId == tenantId) .FirstOrDefaultAsync(cancellationToken); } /// public Task AddMemberDaySettingAsync(MemberDaySetting setting, CancellationToken cancellationToken = default) { return context.MemberDaySettings.AddAsync(setting, cancellationToken).AsTask(); } /// public Task UpdateMemberDaySettingAsync(MemberDaySetting setting, CancellationToken cancellationToken = default) { context.MemberDaySettings.Update(setting); return Task.CompletedTask; } /// public async Task> GetProfileTagsAsync( long tenantId, long memberProfileId, CancellationToken cancellationToken = default) { return await context.MemberProfileTags .AsNoTracking() .Where(x => x.TenantId == tenantId && x.MemberProfileId == memberProfileId) .OrderBy(x => x.TagName) .ToListAsync(cancellationToken); } /// public async Task> GetProfileTagsByMemberIdsAsync( long tenantId, IReadOnlyCollection memberProfileIds, CancellationToken cancellationToken = default) { if (memberProfileIds.Count == 0) { return []; } return await context.MemberProfileTags .AsNoTracking() .Where(x => x.TenantId == tenantId && memberProfileIds.Contains(x.MemberProfileId)) .OrderBy(x => x.MemberProfileId) .ThenBy(x => x.TagName) .ToListAsync(cancellationToken); } /// public async Task ReplaceProfileTagsAsync( long tenantId, long memberProfileId, IReadOnlyCollection tags, CancellationToken cancellationToken = default) { var normalizedTags = (tags ?? Array.Empty()) .Select(x => (x ?? string.Empty).Trim()) .Where(x => !string.IsNullOrWhiteSpace(x)) .Distinct(StringComparer.OrdinalIgnoreCase) .OrderBy(x => x, StringComparer.OrdinalIgnoreCase) .ToList(); var existing = await context.MemberProfileTags .Where(x => x.TenantId == tenantId && x.MemberProfileId == memberProfileId) .ToListAsync(cancellationToken); context.MemberProfileTags.RemoveRange(existing); if (normalizedTags.Count == 0) { return; } var entities = normalizedTags.Select(tag => new MemberProfileTag { MemberProfileId = memberProfileId, TagName = tag }); await context.MemberProfileTags.AddRangeAsync(entities, cancellationToken); } /// public Task SaveChangesAsync(CancellationToken cancellationToken = default) { return context.SaveChangesAsync(cancellationToken); } }