feat: add affiliate invite rebate flow and admin rebate-rate setting

This commit is contained in:
VpSanta33
2026-04-24 21:41:26 +08:00
parent d162604f32
commit f03de00cb9
33 changed files with 1744 additions and 42 deletions

View File

@@ -72,6 +72,7 @@ type AuthService struct {
turnstileService *TurnstileService
emailQueueService *EmailQueueService
promoService *PromoService
affiliateService *AffiliateService
defaultSubAssigner DefaultSubscriptionAssigner
}
@@ -121,13 +122,26 @@ func (s *AuthService) EntClient() *dbent.Client {
return s.entClient
}
func (s *AuthService) SetAffiliateService(affiliateService *AffiliateService) {
if s == nil {
return
}
s.affiliateService = affiliateService
}
// Register 用户注册返回token和用户
func (s *AuthService) Register(ctx context.Context, email, password string) (string, *User, error) {
return s.RegisterWithVerification(ctx, email, password, "", "", "")
}
// RegisterWithVerification 用户注册支持邮件验证、优惠码和邀请码返回token和用户
func (s *AuthService) RegisterWithVerification(ctx context.Context, email, password, verifyCode, promoCode, invitationCode string) (string, *User, error) {
// RegisterWithVerification 用户注册(支持邮件验证、优惠码、邀请码和邀请返利返回token和用户
// affiliateCode 使用可选参数以兼容旧调用方。
func (s *AuthService) RegisterWithVerification(ctx context.Context, email, password, verifyCode, promoCode, invitationCode string, affiliateCode ...string) (string, *User, error) {
affiliateCodeRaw := ""
if len(affiliateCode) > 0 {
affiliateCodeRaw = affiliateCode[0]
}
// 检查是否开放注册默认关闭settingService 未配置时不允许注册)
if s.settingService == nil || !s.settingService.IsRegistrationEnabled(ctx) {
return "", nil, ErrRegDisabled
@@ -223,6 +237,17 @@ func (s *AuthService) RegisterWithVerification(ctx context.Context, email, passw
}
s.postAuthUserBootstrap(ctx, user, "email", true)
s.assignSubscriptions(ctx, user.ID, grantPlan.Subscriptions, "auto assigned by signup defaults")
if s.affiliateService != nil {
if _, err := s.affiliateService.EnsureUserAffiliate(ctx, user.ID); err != nil {
logger.LegacyPrintf("service.auth", "[Auth] Failed to initialize affiliate profile for user %d: %v", user.ID, err)
}
if code := strings.TrimSpace(affiliateCodeRaw); code != "" {
if err := s.affiliateService.BindInviterByCode(ctx, user.ID, code); err != nil {
// 邀请返利码绑定失败不影响注册,只记录日志
logger.LegacyPrintf("service.auth", "[Auth] Failed to bind affiliate inviter for user %d: %v", user.ID, err)
}
}
}
// 标记邀请码为已使用(如果使用了邀请码)
if invitationRedeemCode != nil {