79 lines
2.0 KiB
Go
79 lines
2.0 KiB
Go
package users
|
|
|
|
import (
|
|
"context"
|
|
"crypto/rand"
|
|
"encoding/hex"
|
|
|
|
v1 "hotgo/api/api/users/v1"
|
|
"hotgo/internal/consts"
|
|
"hotgo/internal/dao"
|
|
"hotgo/internal/model/entity"
|
|
utility "hotgo/utility/jwt"
|
|
|
|
"github.com/gogf/gf/v2/errors/gcode"
|
|
"github.com/gogf/gf/v2/errors/gerror"
|
|
"github.com/gogf/gf/v2/os/gtime"
|
|
)
|
|
|
|
// 生成随机 salt
|
|
func generateSalt(n int) (string, error) {
|
|
b := make([]byte, n)
|
|
_, err := rand.Read(b)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
return hex.EncodeToString(b), nil
|
|
}
|
|
|
|
func (c *ControllerV1) Register(ctx context.Context, req *v1.RegisterReq) (res *v1.RegisterRes, err error) {
|
|
// 0. 检查两次密码是否一致
|
|
if req.Password != req.ConfirmPassword {
|
|
return nil, gerror.NewCode(gcode.CodeInvalidParameter, "两次密码输入不一致")
|
|
}
|
|
// 1. 检查手机号是否已注册
|
|
count, err := dao.Users.Ctx(ctx).Where("phone = ?", req.Phone).Count()
|
|
if err != nil {
|
|
return nil, gerror.NewCode(gcode.CodeDbOperationError, "数据库错误")
|
|
}
|
|
if count > 0 {
|
|
return nil, gerror.NewCode(consts.CodeUserAlreadyExists, "手机号已注册")
|
|
}
|
|
|
|
// 2. 生成 salt 并加密密码
|
|
salt, err := generateSalt(8)
|
|
if err != nil {
|
|
return nil, gerror.NewCode(gcode.CodeInternalError, "生成salt失败")
|
|
}
|
|
hashedPwd := utility.HashPassword(req.Password, salt)
|
|
|
|
// 3. 写入用户表
|
|
user := entity.Users{
|
|
Phone: req.Phone,
|
|
Password: hashedPwd,
|
|
Salt: salt,
|
|
Nickname: "用户" + req.Phone,
|
|
Avatar: "https://cdn.jsdelivr.net/gh/hotgo-io/hotgo-cdn@main/avatar/default.png",
|
|
Status: 1,
|
|
Introduce: "这个人很懒,什么都没有留下",
|
|
Gender: 0,
|
|
LoginCount: 0,
|
|
LastLogin: gtime.Now(),
|
|
}
|
|
|
|
userId, err := dao.Users.Ctx(ctx).Data(user).InsertAndGetId()
|
|
if err != nil {
|
|
return nil, gerror.NewCode(consts.CodeInternalError, "注册失败")
|
|
}
|
|
|
|
// 4. 返回 JWT Token
|
|
token, err := utility.GenerateToken(userId)
|
|
if err != nil {
|
|
return nil, gerror.NewCode(consts.CodeInternalError, "生成Token失败")
|
|
}
|
|
res = &v1.RegisterRes{
|
|
Token: token,
|
|
}
|
|
return
|
|
}
|