package auth import ( "context" "fmt" "strings" "hyapp/pkg/xerr" authdomain "hyapp/services/user-service/internal/domain/auth" ) type edgeCountryProvider struct{} type staticCountryProvider struct { name string countryCode string } type unavailableIPGeoProvider struct { name string } func BuildIPGeoProviders(names []string) []IPGeoProvider { providers := make([]IPGeoProvider, 0, len(names)) for _, name := range names { name = strings.TrimSpace(name) if name == "" { continue } switch { case strings.EqualFold(name, "edge_country"): providers = append(providers, edgeCountryProvider{}) case strings.HasPrefix(strings.ToLower(name), "static:"): country := normalizeCountryCode(strings.TrimPrefix(name, "static:")) providers = append(providers, staticCountryProvider{name: name, countryCode: country}) default: // 未配置具体 provider 适配器时显式降级为 unavailable,worker 会按顺序继续尝试下一个。 providers = append(providers, unavailableIPGeoProvider{name: name}) } } return providers } func (p edgeCountryProvider) Name() string { return "edge_country" } func (p edgeCountryProvider) ResolveCountry(_ context.Context, job authdomain.LoginIPRiskJob) (IPGeoResult, error) { country := normalizeCountryCode(job.EdgeCountryCode) if country == "" { return IPGeoResult{}, xerr.New(xerr.Unavailable, "edge country is empty") } return IPGeoResult{CountryCode: country, Confidence: 60}, nil } func (p staticCountryProvider) Name() string { return p.name } func (p staticCountryProvider) ResolveCountry(_ context.Context, _ authdomain.LoginIPRiskJob) (IPGeoResult, error) { if p.countryCode == "" { return IPGeoResult{}, xerr.New(xerr.Unavailable, "static country is empty") } return IPGeoResult{CountryCode: p.countryCode, Confidence: 100}, nil } func (p unavailableIPGeoProvider) Name() string { return p.name } func (p unavailableIPGeoProvider) ResolveCountry(_ context.Context, _ authdomain.LoginIPRiskJob) (IPGeoResult, error) { return IPGeoResult{}, fmt.Errorf("ip geo provider %s is not configured", p.name) }