using Fake.Application; using Fake.Domain.Exceptions; using Oms.Domain.CustomersAggregate.Entities; using Oms.Domain.CustomersAggregate.Enums; using Oms.Domain.CustomersAggregate.Repositories; using Oms.Domain.MarketingAggregate.Entities; using Oms.Domain.MarketingAggregate.Repositories; using Oms.Domain.Shared.Enums; namespace Oms.Application.Shared; /// /// 营销域主客户解析与价区键。 /// public static class MarketingCustomerHelper { /// 缺省/空价区键回落(卖价 JSON 标准键)。 public const string FallbackPriceTierKey = "普通客户"; /// 新注册客户默认价区键(与会员等级名称对齐为「普通会员」)。 public const string DefaultNewCustomerPriceTierKey = "普通会员"; /// 新注册客户默认会员等级编码/名称。 public const string DefaultMemberLevelName = "普通会员"; public static async Task ResolveMarketingMainCustomerAsync( ICustomerRepository customerRepository, Customer sessionCustomer, CancellationToken cancellationToken = default) { ArgumentNullException.ThrowIfNull(sessionCustomer); if (!sessionCustomer.ParentCustomerId.HasValue) { return sessionCustomer; } var mainCustomer = await customerRepository.FirstOrDefaultAsync( x => x.Id == sessionCustomer.ParentCustomerId.Value, cancellationToken); if (mainCustomer == null) { throw new BusinessException("主客户不存在"); } return mainCustomer; } public static async Task ResolveMarketingMainCustomerIdAsync( ICustomerRepository customerRepository, Customer sessionCustomer, CancellationToken cancellationToken = default) { var main = await ResolveMarketingMainCustomerAsync(customerRepository, sessionCustomer, cancellationToken); return main.Id; } /// /// 解析用于计价的价区键:主客户.PriceTierKey;空则回落「普通客户」。与会员等级无关。 /// public static async Task ResolvePriceTierKeyAsync( ICustomerRepository customerRepository, IMemberLevelRepository memberLevelRepository, int? customerId, CancellationToken cancellationToken = default) { // memberLevelRepository 保留参数以兼容既有调用方签名;价区已与等级解耦。 _ = memberLevelRepository; if (!customerId.HasValue || customerId.Value <= 0) { return FallbackPriceTierKey; } var sessionCustomer = await customerRepository.FirstOrDefaultAsync(x => x.Id == customerId.Value, cancellationToken); if (sessionCustomer == null) { return FallbackPriceTierKey; } var mainCustomer = sessionCustomer.ParentCustomerId.HasValue ? await customerRepository.FirstOrDefaultAsync(x => x.Id == sessionCustomer.ParentCustomerId.Value, cancellationToken) : sessionCustomer; if (mainCustomer == null) { return FallbackPriceTierKey; } if (!string.IsNullOrWhiteSpace(mainCustomer.PriceTierKey)) { return mainCustomer.PriceTierKey.Trim(); } // 兼容未回填客户:短暂回退遗留 CustomerGroup,最终仍归一到标准键 return MapCustomerGroupToPriceTierKey(mainCustomer.CustomerGroup) ?? FallbackPriceTierKey; } public static string NormalizePriceTierKeyOrDefault(string? priceTierKey) { return string.IsNullOrWhiteSpace(priceTierKey) ? FallbackPriceTierKey : priceTierKey.Trim(); } /// 新客默认价区键。 public static string ResolveNewCustomerPriceTierKey(string? input) => string.IsNullOrWhiteSpace(input) ? DefaultNewCustomerPriceTierKey : input.Trim(); /// /// 解析默认「普通会员」等级 Id;不存在则取启用等级中 MinPoints 最低者。 /// public static async Task ResolveDefaultMemberLevelIdAsync( IMemberLevelRepository memberLevelRepository, CancellationToken cancellationToken = default) { var named = await memberLevelRepository.FirstOrDefaultAsync( x => x.Status == EnableStatus.Enabled && (x.LevelCode == "V0" || x.LevelCode == "normal" || x.LevelName == DefaultMemberLevelName), cancellationToken); if (named != null) { return named.Id; } var levels = await memberLevelRepository.GetAllEnabledOrderedAsync(cancellationToken); return levels.OrderBy(x => x.MinPoints).ThenBy(x => x.Sort).ThenBy(x => x.Id).FirstOrDefault()?.Id; } public static string? MapCustomerGroupToPriceTierKey(CustomerGroup? customerGroup) { if (!customerGroup.HasValue) { return FallbackPriceTierKey; } return customerGroup.Value switch { CustomerGroup.Normal => FallbackPriceTierKey, CustomerGroup.Vip1 => "客户组1", CustomerGroup.Vip2 => "客户组2", CustomerGroup.Vip3 => "客户组3", CustomerGroup.Vip4 => "客户组4", CustomerGroup.Vip5 => "客户组5", _ => FallbackPriceTierKey }; } }