|
|
|
@ -18,7 +18,6 @@ import (
|
|
|
|
"github.com/veypi/vbase/libs/jwt"
|
|
|
|
"github.com/veypi/vbase/libs/jwt"
|
|
|
|
"github.com/veypi/vbase/models"
|
|
|
|
"github.com/veypi/vbase/models"
|
|
|
|
"github.com/veypi/vigo"
|
|
|
|
"github.com/veypi/vigo"
|
|
|
|
"gorm.io/gorm"
|
|
|
|
|
|
|
|
)
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
// Email 正则表达式
|
|
|
|
// Email 正则表达式
|
|
|
|
@ -72,50 +71,47 @@ func register(x *vigo.X, req *RegisterRequest) (*AuthResponse, error) {
|
|
|
|
return nil, vigo.ErrInvalidArg.WithString("phone is required")
|
|
|
|
return nil, vigo.ErrInvalidArg.WithString("phone is required")
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 使用事务处理注册,防止并发创建多个首个管理员用户
|
|
|
|
// 检查是否是第一个用户(需要在创建用户之前检查)
|
|
|
|
var user *models.User
|
|
|
|
|
|
|
|
err := cfg.DB().Transaction(func(tx *gorm.DB) error {
|
|
|
|
|
|
|
|
// 检查是否是第一个用户(在事务内检查,带锁)
|
|
|
|
|
|
|
|
var userCount int64
|
|
|
|
var userCount int64
|
|
|
|
if err := tx.Model(&models.User{}).Count(&userCount).Error; err != nil {
|
|
|
|
if err := cfg.DB().Model(&models.User{}).Count(&userCount).Error; err != nil {
|
|
|
|
return err
|
|
|
|
return nil, vigo.ErrInternalServer.WithError(err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 检查用户名是否已存在
|
|
|
|
// 检查用户名是否已存在
|
|
|
|
var count int64
|
|
|
|
var count int64
|
|
|
|
if err := tx.Model(&models.User{}).Where("username = ?", req.Username).Count(&count).Error; err != nil {
|
|
|
|
if err := cfg.DB().Model(&models.User{}).Where("username = ?", req.Username).Count(&count).Error; err != nil {
|
|
|
|
return err
|
|
|
|
return nil, vigo.ErrInternalServer.WithError(err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if count > 0 {
|
|
|
|
if count > 0 {
|
|
|
|
return vigo.ErrInvalidArg.WithArgs("username already exists")
|
|
|
|
return nil, vigo.ErrInvalidArg.WithArgs("username already exists")
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 检查邮箱是否已存在
|
|
|
|
// 检查邮箱是否已存在
|
|
|
|
if req.Email != "" {
|
|
|
|
if req.Email != "" {
|
|
|
|
count = 0
|
|
|
|
count = 0 // 重置计数器
|
|
|
|
if err := tx.Model(&models.User{}).Where("email = ?", req.Email).Count(&count).Error; err != nil {
|
|
|
|
if err := cfg.DB().Model(&models.User{}).Where("email = ?", req.Email).Count(&count).Error; err != nil {
|
|
|
|
return err
|
|
|
|
return nil, vigo.ErrInternalServer.WithError(err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if count > 0 {
|
|
|
|
if count > 0 {
|
|
|
|
return vigo.ErrInvalidArg.WithArgs("email already exists")
|
|
|
|
return nil, vigo.ErrInvalidArg.WithArgs("email already exists")
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 检查手机是否已存在
|
|
|
|
// 检查手机是否已存在
|
|
|
|
if req.Phone != "" {
|
|
|
|
if req.Phone != "" {
|
|
|
|
count = 0
|
|
|
|
count = 0 // 重置计数器
|
|
|
|
if err := tx.Model(&models.User{}).Where("phone = ?", req.Phone).Count(&count).Error; err != nil {
|
|
|
|
if err := cfg.DB().Model(&models.User{}).Where("phone = ?", req.Phone).Count(&count).Error; err != nil {
|
|
|
|
return err
|
|
|
|
return nil, vigo.ErrInternalServer.WithError(err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if count > 0 {
|
|
|
|
if count > 0 {
|
|
|
|
return vigo.ErrInvalidArg.WithArgs("phone already exists")
|
|
|
|
return nil, vigo.ErrInvalidArg.WithArgs("phone already exists")
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 哈希密码
|
|
|
|
// 哈希密码
|
|
|
|
hashedPassword, err := crypto.HashPassword(req.Password, 12)
|
|
|
|
hashedPassword, err := crypto.HashPassword(req.Password, 12)
|
|
|
|
if err != nil {
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
return nil, vigo.ErrInternalServer.WithError(err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 创建用户
|
|
|
|
// 创建用户
|
|
|
|
@ -128,7 +124,7 @@ func register(x *vigo.X, req *RegisterRequest) (*AuthResponse, error) {
|
|
|
|
phone = &req.Phone
|
|
|
|
phone = &req.Phone
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
user = &models.User{
|
|
|
|
user := &models.User{
|
|
|
|
Username: req.Username,
|
|
|
|
Username: req.Username,
|
|
|
|
Password: hashedPassword,
|
|
|
|
Password: hashedPassword,
|
|
|
|
Email: email,
|
|
|
|
Email: email,
|
|
|
|
@ -144,27 +140,20 @@ func register(x *vigo.X, req *RegisterRequest) (*AuthResponse, error) {
|
|
|
|
// 生成随机头像
|
|
|
|
// 生成随机头像
|
|
|
|
user.Avatar = fmt.Sprintf("https://public.veypi.com/img/avatar/%04d.jpg", rand.New(rand.NewSource(time.Now().UnixNano())).Intn(220))
|
|
|
|
user.Avatar = fmt.Sprintf("https://public.veypi.com/img/avatar/%04d.jpg", rand.New(rand.NewSource(time.Now().UnixNano())).Intn(220))
|
|
|
|
|
|
|
|
|
|
|
|
// 第一个用户固定 ID 为 admin
|
|
|
|
if err := cfg.DB().Create(user).Error; err != nil {
|
|
|
|
if userCount == 0 {
|
|
|
|
return nil, vigo.ErrInternalServer.WithError(err)
|
|
|
|
user.ID = "admin"
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if err := tx.Create(user).Error; err != nil {
|
|
|
|
|
|
|
|
return err
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return nil
|
|
|
|
|
|
|
|
})
|
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
|
|
return nil, err
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 授予角色(事务外,因为事务已确保用户创建成功)
|
|
|
|
// 第一个用户授予 admin 角色,其他用户授予 user 角色
|
|
|
|
roleCode := "user"
|
|
|
|
roleCode := "user"
|
|
|
|
if user.ID == "admin" {
|
|
|
|
if userCount == 0 {
|
|
|
|
roleCode = "admin"
|
|
|
|
roleCode = "admin"
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if err := cfg.Auth.GrantRole(x.Context(), user.ID, roleCode); err != nil {
|
|
|
|
if err := cfg.Auth.GrantRole(x.Context(), user.ID, roleCode); err != nil {
|
|
|
|
|
|
|
|
// 记录错误但允许注册继续,或者回滚
|
|
|
|
|
|
|
|
// 这里简单处理,继续流程,用户可能需要管理员手动授权
|
|
|
|
|
|
|
|
// 或者返回错误
|
|
|
|
return nil, vigo.ErrInternalServer.WithError(err)
|
|
|
|
return nil, vigo.ErrInternalServer.WithError(err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|