package bootstrap import ( "context" redisx "spark-server/internal/infrastructure/redis" smsinfra "spark-server/internal/infrastructure/sms" smtpinfra "spark-server/internal/infrastructure/smtp" smsentity "spark-server/internal/module/sms/entity" smslogic "spark-server/internal/module/sms/logic" smsmodel "spark-server/internal/module/sms/model" userlogic "spark-server/internal/module/user/logic" ) type repoEmailLookup struct { repo userlogic.Repository } func (r repoEmailLookup) EmailByUserID(ctx context.Context, userID int64) (string, error) { if r.repo == nil { return "", nil } return r.repo.GetEmail(ctx, userID) } func wireSMS(cfg *Config, rdb *redisx.Client, repo userlogic.Repository) *smslogic.Service { var store smslogic.CodeStore if rdb != nil && rdb.Ready() { store = smsmodel.NewRedisStore(rdb.RDB()) } else { store = smsmodel.NewMemoryStore() } var mail smslogic.EmailSender if m := smtpinfra.New(smtpinfra.Options{ Host: cfg.SMS.SMTP.Host, Port: cfg.SMS.SMTP.Port, Username: cfg.SMS.SMTP.Username, Password: cfg.SMS.SMTP.Password, From: cfg.SMS.SMTP.From, }); m.Ready() { mail = m } return smslogic.NewService(store, mail, wirePhoneProviders(cfg), repoEmailLookup{repo: repo}) } func wirePhoneProviders(cfg *Config) []smslogic.PhoneCarrierSender { a := cfg.SMS.AliyunSMS if a.AccessKeyID == "" || a.AccessKeySecret == "" || a.SignName == "" { return nil } opts := smsinfra.AliyunOptions{ AccessKeyID: a.AccessKeyID, AccessKeySecret: a.AccessKeySecret, SignName: a.SignName, } loginTpl := a.Templates.Login delTpl := a.Templates.AccountDelete return []smslogic.PhoneCarrierSender{ smsinfra.NewCarrierGateway(smsentity.CarrierMobile, opts, smsinfra.TemplateSet{ Login: loginTpl.Mobile, AccountDelete: delTpl.Mobile, }), smsinfra.NewCarrierGateway(smsentity.CarrierUnicom, opts, smsinfra.TemplateSet{ Login: loginTpl.Unicom, AccountDelete: delTpl.Unicom, }), smsinfra.NewCarrierGateway(smsentity.CarrierTelecom, opts, smsinfra.TemplateSet{ Login: loginTpl.Telecom, AccountDelete: delTpl.Telecom, }), } }