using Fake.Application; using Fake.Domain.Exceptions; using Oms.Domain.CustomersAggregate.Entities; using Oms.Domain.CustomersAggregate.Repositories; using Oms.Domain.MarketingAggregate.Entities; using Oms.Domain.MarketingAggregate.Enums; using Oms.Domain.MarketingAggregate.Repositories; namespace Oms.Application.Shared; public static class MarketingReferralBinder { public static async Task BindReferrerOnCreateAsync( Customer entity, string? inviteCode, ICustomerReferralCodeRepository referralCodeRepository, ICustomerRepository customerRepository, IMemberLevelRepository? memberLevelRepository = null, IReferralCommissionRuleRepository? commissionRuleRepository = null, CancellationToken cancellationToken = default) { if (entity.ParentCustomerId.HasValue || entity.ReferrerCustomerId.HasValue) { return; } var code = inviteCode?.Trim(); if (string.IsNullOrWhiteSpace(code)) { return; } var referral = await referralCodeRepository.GetByInviteCodeAsync(code, cancellationToken); if (referral == null || referral.Status != ReferralCodeStatus.Enabled) { throw new BusinessException("邀请码无效或已停用"); } // 新建时 entity.Id 多为 0,不能只靠 Id 判自引荐 if (entity.Id > 0 && referral.CustomerId == entity.Id) { throw new BusinessException("不能使用自己的邀请码"); } var referrer = await customerRepository.FirstOrDefaultAsync(x => x.Id == referral.CustomerId, cancellationToken); if (referrer == null || referrer.ParentCustomerId.HasValue) { throw new BusinessException("邀请码对应客户无效"); } if (memberLevelRepository != null) { var minLevel = "V1"; if (commissionRuleRepository != null) { var rule = await commissionRuleRepository.GetActiveRuleAsync(cancellationToken); if (!string.IsNullOrWhiteSpace(rule?.MinInviteLevelCode)) { minLevel = rule.MinInviteLevelCode; } } MemberLevel? level = null; if (referrer.MemberLevelId.HasValue) { level = await memberLevelRepository.FirstOrDefaultAsync( x => x.Id == referrer.MemberLevelId.Value, cancellationToken); } if (!MarketingInviteRewardCalculator.CanInvite(level?.LevelCode, minLevel)) { throw new BusinessException("邀请人暂无邀请资格"); } } if (IsSameIdentity(entity, referrer)) { throw new BusinessException("不能使用自己的邀请码"); } entity.ReferrerCustomerId = referral.CustomerId; entity.ReferralBindTime = DateTime.Now; entity.ReferralChannel = "link"; } private static bool IsSameIdentity(Customer entity, Customer referrer) { if (!string.IsNullOrWhiteSpace(entity.Phone) && !string.IsNullOrWhiteSpace(referrer.Phone) && string.Equals(entity.Phone.Trim(), referrer.Phone.Trim(), StringComparison.OrdinalIgnoreCase)) { return true; } if (!string.IsNullOrWhiteSpace(entity.Email) && !string.IsNullOrWhiteSpace(referrer.Email) && string.Equals(entity.Email.Trim(), referrer.Email.Trim(), StringComparison.OrdinalIgnoreCase)) { return true; } if (!string.IsNullOrWhiteSpace(entity.WechatOpenid) && !string.IsNullOrWhiteSpace(referrer.WechatOpenid) && string.Equals(entity.WechatOpenid.Trim(), referrer.WechatOpenid.Trim(), StringComparison.Ordinal)) { return true; } if (!string.IsNullOrWhiteSpace(entity.CustomerCode) && !string.IsNullOrWhiteSpace(referrer.CustomerCode) && string.Equals(entity.CustomerCode.Trim(), referrer.CustomerCode.Trim(), StringComparison.OrdinalIgnoreCase)) { return true; } return false; } }