package login import ( "epur-pay/cache" "epur-pay/model" "epur-pay/pkg/dapi" "epur-pay/pkg/logger" "epur-pay/pkg/redis" "epur-pay/pkg/utils" "fmt" redigo "github.com/gomodule/redigo/redis" "golang.org/x/crypto/bcrypt" "regexp" ) type SsoRegisterParams struct { Password string `json:"password"` // 密码 Mobile string `json:"mobile"` // 手机号 Email string `json:"email"` // 邮箱(可选) Invite string `json:"invite"` // 邀请码(可选) Captcha string `json:"captcha"` // 验证码 } type SsoRegisterResponse struct { *dapi.ResponseCommon Data struct { Token string `json:"token"` } `json:"data"` } // SsoRegister 用户注册接口 // @Summary 用户注册 // @Description 该接口用于用户通过手机号、密码、验证码等信息进行注册。如果注册成功,返回用户的Token。 // @Tags register // @Accept json // @Produce json // @Param body body SsoRegisterParams true "用户注册信息" // @Success 200 {object} SsoRegisterResponse "注册成功返回Token" // @Router /api/v1/login/register [post] func SsoRegister(a *dapi.ApiBase, data *SsoRegisterParams) error { if len(data.Mobile) == 0 { return a.ReturnPublicErrorResponse(a.Translate("mobile_required")) } if len(data.Captcha) == 0 { return a.ReturnPublicErrorResponse(a.Translate("captcha_required")) } mobileRegex := `^1[3-9]\d{9}$` matched, err := regexp.MatchString(mobileRegex, data.Mobile) if err != nil || !matched { return a.ReturnPublicErrorResponse(a.Translate("invalid_mobile")) } if len(data.Password) < 6 || len(data.Password) > 72 { return a.ReturnPublicErrorResponse(a.Translate("password_length_invalid")) } hasLetter := false hasNumber := false for _, char := range data.Password { if char >= 'a' && char <= 'z' || char >= 'A' && char <= 'Z' { hasLetter = true } if char >= '0' && char <= '9' { hasNumber = true } } if !hasLetter || !hasNumber { return a.ReturnPublicErrorResponse(a.Translate("password_complexity_invalid")) } if len(data.Email) > 0 { emailRegex := `^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$` matched, err := regexp.MatchString(emailRegex, data.Email) if err != nil || !matched { return a.ReturnPublicErrorResponse(a.Translate("invalid_email")) } } redisCodeKey := fmt.Sprintf("smscode:%s", data.Mobile) conn := redis.RPool.Get() defer func() { if err := conn.Close(); err != nil { logger.ErrorLogger.Infoln(err.Error()) } }() storedCaptcha, err := redigo.String(conn.Do("GET", redisCodeKey)) if err != nil || storedCaptcha != data.Captcha { return a.ReturnPublicErrorResponse(a.Translate("invalid_captcha")) } //_, _ = conn.Do("DEL", redisCodeKey) var count int64 user := model.User{} err = a.Ts.Table(user.TableName()).Where("mobile", data.Mobile).Count(&count).Error if err != nil { utils.Error(err) } if count > 0 { return a.ReturnPublicErrorResponse(a.Translate("account_exists")) } hashedPass, err := bcrypt.GenerateFromPassword([]byte(data.Password), bcrypt.DefaultCost) if err != nil { utils.Error(err) } currentTime := utils.Time2StampSecond() clientIp := a.ClientIp() newUser := model.User{ Mobile: data.Mobile, Email: data.Email, Invite: data.Invite, Status: "0", // 状态 0-正常 1-拉黑 Role: model.ArryString{}, } newUser.Detail = model.UserDetail{ PassWord: string(hashedPass), CreateTime: currentTime, RegisterIp: clientIp, RegisterIpAddress: cache.GetIpAddress(clientIp), Nickname: data.Mobile, // 默认昵称与手机号一致 } err = a.Ts.Table(newUser.TableName()).Create(&newUser).Error if err != nil { utils.Error(err) } token := dapi.EncryptToken(newUser.Uid) newUser.Detail.Token = token err = a.Ts.Table(newUser.TableName()).Where("uid", newUser.Uid). Updates(map[string]interface{}{"detail": newUser.Detail}).Error if err != nil { utils.Error(err) } response := SsoRegisterResponse{} response.ResponseCommon = a.NewSuccessResponseCommon() response.Data.Token = token return a.ReturnSuccessCustomResponse(response) }