package luckygift import ( "chatapp3-golang/internal/config" "chatapp3-golang/internal/model" "context" "net/http" "strconv" "strings" "gorm.io/gorm" ) type luckyGiftRuntimeAccount struct { URL string AppID string AppChannel string AppKey string } func (s *LuckyGiftService) resolveProviderConfig(ctx context.Context, req LuckyGiftDrawRequest) (config.LuckyGiftProviderConfig, error) { base, ok := findLuckyGiftConfig(s.cfg.LuckyGift.Providers, req.StandardID) if !ok { return config.LuckyGiftProviderConfig{}, NewAppError( http.StatusServiceUnavailable, "lucky_gift_config_missing", "lucky gift provider config is missing", ) } runtimeAccount, err := s.resolveRuntimeAccount(ctx, req.SysOrigin) if err != nil { return config.LuckyGiftProviderConfig{}, NewAppError( http.StatusInternalServerError, "lucky_gift_runtime_config_failed", err.Error(), ) } return mergeLuckyGiftProviderConfig(base, runtimeAccount), nil } func (s *LuckyGiftService) resolveRuntimeAccount(ctx context.Context, sysOrigin string) (luckyGiftRuntimeAccount, error) { account := defaultLuckyGiftRuntimeAccount(s.cfg) if s.repo.DB == nil { return account, nil } normalizedSysOrigin := normalizeLuckyGiftSysOrigin(sysOrigin) profile, err := s.resolveActiveBaishunProfile(ctx, normalizedSysOrigin) if err != nil { return luckyGiftRuntimeAccount{}, err } var row model.BaishunProviderConfig err = s.repo.DB.WithContext(ctx). Where("sys_origin = ? AND profile = ?", normalizedSysOrigin, profile). Limit(1). First(&row).Error if err == nil { return applyLuckyGiftRuntimeAccount(account, row), nil } if err == gorm.ErrRecordNotFound { return account, nil } return luckyGiftRuntimeAccount{}, err } func (s *LuckyGiftService) resolveActiveBaishunProfile(ctx context.Context, sysOrigin string) (string, error) { var row model.BaishunProviderConfig err := s.repo.DB.WithContext(ctx). Where("sys_origin = ? AND active = ?", normalizeLuckyGiftSysOrigin(sysOrigin), true). Order("update_time DESC"). Limit(1). First(&row).Error if err == nil { return normalizeLuckyGiftBaishunProfile(row.Profile), nil } if err == gorm.ErrRecordNotFound { return luckyGiftBaishunProfileProd, nil } return "", err } func defaultLuckyGiftRuntimeAccount(cfg config.Config) luckyGiftRuntimeAccount { account := luckyGiftRuntimeAccount{ URL: strings.TrimSpace(cfg.Baishun.LuckyGiftURL), AppChannel: strings.TrimSpace(cfg.Baishun.AppChannel), AppKey: strings.TrimSpace(cfg.Baishun.AppKey), } if account.URL == "" { account.URL = strings.TrimSpace(cfg.Baishun.PlatformBaseURL) } if cfg.Baishun.AppID > 0 { account.AppID = strconv.FormatInt(cfg.Baishun.AppID, 10) } return account } func applyLuckyGiftRuntimeAccount(base luckyGiftRuntimeAccount, row model.BaishunProviderConfig) luckyGiftRuntimeAccount { if strings.TrimSpace(row.LuckyGiftURL) != "" { base.URL = strings.TrimSpace(row.LuckyGiftURL) } else if strings.TrimSpace(row.PlatformBaseURL) != "" { base.URL = strings.TrimSpace(row.PlatformBaseURL) } if row.AppID > 0 { base.AppID = strconv.FormatInt(row.AppID, 10) } if strings.TrimSpace(row.AppChannel) != "" { base.AppChannel = strings.TrimSpace(row.AppChannel) } if strings.TrimSpace(row.AppKey) != "" { base.AppKey = strings.TrimSpace(row.AppKey) } return base } func mergeLuckyGiftProviderConfig( base config.LuckyGiftProviderConfig, runtime luckyGiftRuntimeAccount, ) config.LuckyGiftProviderConfig { merged := base if runtime.URL != "" { merged.URL = runtime.URL } if runtime.AppID != "" { merged.AppID = runtime.AppID } if runtime.AppChannel != "" { merged.AppChannel = runtime.AppChannel } if runtime.AppKey != "" { merged.AppKey = runtime.AppKey } return merged } func normalizeLuckyGiftSysOrigin(sysOrigin string) string { sysOrigin = strings.ToUpper(strings.TrimSpace(sysOrigin)) if sysOrigin == "" { return "LIKEI" } return sysOrigin } const luckyGiftBaishunProfileProd = "PROD" func normalizeLuckyGiftBaishunProfile(profile string) string { switch strings.ToUpper(strings.TrimSpace(profile)) { case "", "PROD", "PRODUCT", "PRODUCTION", "ONLINE", "OFFICIAL", "FORMAL": return luckyGiftBaishunProfileProd case "TEST", "TESTING", "SANDBOX", "DEV": return "TEST" default: return strings.ToUpper(strings.TrimSpace(profile)) } }