You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

148 lines
4.0 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

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)
}