package auth import ( "context" "crypto/rand" "fmt" "math/big" "time" "haixun-backend/internal/library/clock" "haixun-backend/internal/logic/authz" memberusecase "haixun-backend/internal/model/member/domain/usecase" "haixun-backend/internal/svc" "haixun-backend/internal/types" "github.com/zeromicro/go-zero/core/logx" ) type RegisterLogic struct { ctx context.Context svcCtx *svc.ServiceContext } func NewRegisterLogic(ctx context.Context, svcCtx *svc.ServiceContext) *RegisterLogic { return &RegisterLogic{ctx: ctx, svcCtx: svcCtx} } func (l *RegisterLogic) Register(req *types.AuthRegisterReq) (*types.AuthTokenData, error) { if err := authz.RequireAdmin(l.ctx, l.svcCtx); err != nil { return nil, err } member, token, err := l.svcCtx.Member.Register(l.ctx, memberusecase.RegisterRequest{ TenantID: req.TenantID, Email: req.Email, Password: req.Password, DisplayName: req.DisplayName, Language: req.Language, }) if err != nil { return nil, err } verifyCode, err := newVerifyCode() if err != nil { return nil, err } expiresAt := clock.NowUnixNano() + int64(15*time.Minute) if err := l.svcCtx.Member.SetEmailVerificationCode(l.ctx, member.TenantID, member.UID, verifyCode, expiresAt); err != nil { return nil, err } if l.svcCtx.Mailer != nil { body := fmt.Sprintf("你的巡樓 Console 驗證碼是:%s\n\n此驗證碼 15 分鐘內有效。", verifyCode) if err := l.svcCtx.Mailer.Send(l.ctx, member.Email, "巡樓 Console 帳號驗證碼", body); err != nil { logx.WithContext(l.ctx).Errorf("send verification email failed: uid=%s err=%v", member.UID, err) } } return toAuthTokenData(token), nil } func newVerifyCode() (string, error) { n, err := rand.Int(rand.Reader, big.NewInt(1000000)) if err != nil { return "", err } return fmt.Sprintf("%06d", n.Int64()), nil }