13
This commit is contained in:
210
handlers/auth.go
Normal file
210
handlers/auth.go
Normal file
@@ -0,0 +1,210 @@
|
||||
package handlers
|
||||
|
||||
import (
|
||||
"yuyue/database"
|
||||
"yuyue/middleware"
|
||||
"yuyue/models"
|
||||
"yuyue/utils"
|
||||
|
||||
"github.com/gofiber/fiber/v2"
|
||||
)
|
||||
|
||||
type UserRequest struct {
|
||||
Phone string `json:"phone" validate:"required,e164"`
|
||||
Nickname string `json:"nickname" validate:"required,min=1,max=50"`
|
||||
}
|
||||
|
||||
type LoginRequest struct {
|
||||
Phone string `json:"phone" validate:"required,e164"`
|
||||
Password string `json:"password" validate:"required"`
|
||||
}
|
||||
|
||||
type AuthResponse struct {
|
||||
Token string `json:"token"`
|
||||
User models.User `json:"user"`
|
||||
}
|
||||
|
||||
func Register(c *fiber.Ctx) error {
|
||||
var req UserRequest
|
||||
if err := c.BodyParser(&req); err != nil {
|
||||
return utils.BadRequest(c, "请求数据格式错误")
|
||||
}
|
||||
|
||||
// 检查手机号是否已存在
|
||||
var existingUser models.User
|
||||
if err := database.GetDB().Where("phone = ?", req.Phone).First(&existingUser).Error; err == nil {
|
||||
return utils.BadRequest(c, "该手机号已注册")
|
||||
}
|
||||
|
||||
// 创建新用户
|
||||
user := models.User{
|
||||
Phone: req.Phone,
|
||||
Nickname: req.Nickname,
|
||||
Role: models.RoleUser,
|
||||
}
|
||||
|
||||
if err := database.GetDB().Create(&user).Error; err != nil {
|
||||
return utils.InternalServerError(c, "用户创建失败")
|
||||
}
|
||||
|
||||
// 生成JWT令牌
|
||||
token, err := middleware.GenerateToken(&user)
|
||||
if err != nil {
|
||||
return utils.InternalServerError(c, "令牌生成失败")
|
||||
}
|
||||
|
||||
return utils.Success(c, AuthResponse{
|
||||
Token: token,
|
||||
User: user,
|
||||
})
|
||||
}
|
||||
|
||||
func GetProfile(c *fiber.Ctx) error {
|
||||
userID := middleware.GetUserID(c)
|
||||
|
||||
var user models.User
|
||||
if err := database.GetDB().First(&user, userID).Error; err != nil {
|
||||
return utils.NotFound(c, "用户不存在")
|
||||
}
|
||||
|
||||
return utils.Success(c, user)
|
||||
}
|
||||
|
||||
type VerificationLoginRequest struct {
|
||||
Phone string `json:"phone" validate:"required,e164"`
|
||||
Code string `json:"code" validate:"required,len=6"`
|
||||
}
|
||||
|
||||
type OneClickLoginRequest struct {
|
||||
Phone string `json:"phone" validate:"required,e164"`
|
||||
}
|
||||
|
||||
// 验证码登录
|
||||
func VerificationLogin(c *fiber.Ctx) error {
|
||||
var req VerificationLoginRequest
|
||||
if err := c.BodyParser(&req); err != nil {
|
||||
return utils.BadRequest(c, "请求数据格式错误")
|
||||
}
|
||||
|
||||
// TODO: 验证验证码是否正确
|
||||
// 这里应该从缓存或数据库中验证验证码
|
||||
// if !verifyCode(req.Phone, req.Code) {
|
||||
// return utils.BadRequest(c, "验证码错误或已过期")
|
||||
// }
|
||||
|
||||
// 检查用户是否存在,不存在则自动创建
|
||||
var user models.User
|
||||
err := database.GetDB().Where("phone = ?", req.Phone).First(&user).Error
|
||||
if err != nil {
|
||||
// 用户不存在,自动创建
|
||||
user = models.User{
|
||||
Phone: req.Phone,
|
||||
Nickname: "用户" + req.Phone[len(req.Phone)-4:], // 默认昵称为手机号后四位
|
||||
Role: models.RoleUser,
|
||||
}
|
||||
if err := database.GetDB().Create(&user).Error; err != nil {
|
||||
return utils.InternalServerError(c, "用户创建失败")
|
||||
}
|
||||
}
|
||||
|
||||
// 生成JWT令牌
|
||||
token, err := middleware.GenerateToken(&user)
|
||||
if err != nil {
|
||||
return utils.InternalServerError(c, "令牌生成失败")
|
||||
}
|
||||
|
||||
return utils.Success(c, AuthResponse{
|
||||
Token: token,
|
||||
User: user,
|
||||
})
|
||||
}
|
||||
|
||||
// 一键登录(免验证码,直接登录)
|
||||
func OneClickLogin(c *fiber.Ctx) error {
|
||||
var req OneClickLoginRequest
|
||||
if err := c.BodyParser(&req); err != nil {
|
||||
return utils.BadRequest(c, "请求数据格式错误")
|
||||
}
|
||||
|
||||
// 检查用户是否存在,不存在则自动创建
|
||||
var user models.User
|
||||
err := database.GetDB().Where("phone = ?", req.Phone).First(&user).Error
|
||||
if err != nil {
|
||||
// 用户不存在,自动创建
|
||||
user = models.User{
|
||||
Phone: req.Phone,
|
||||
Nickname: "用户" + req.Phone[len(req.Phone)-4:], // 默认昵称为手机号后四位
|
||||
Role: models.RoleUser,
|
||||
}
|
||||
if err := database.GetDB().Create(&user).Error; err != nil {
|
||||
return utils.InternalServerError(c, "用户创建失败")
|
||||
}
|
||||
}
|
||||
|
||||
// 生成JWT令牌
|
||||
token, err := middleware.GenerateToken(&user)
|
||||
if err != nil {
|
||||
return utils.InternalServerError(c, "令牌生成失败")
|
||||
}
|
||||
|
||||
return utils.Success(c, AuthResponse{
|
||||
Token: token,
|
||||
User: user,
|
||||
})
|
||||
}
|
||||
|
||||
// 发送验证码
|
||||
func SendVerificationCode(c *fiber.Ctx) error {
|
||||
type SendCodeRequest struct {
|
||||
Phone string `json:"phone" validate:"required,e164"`
|
||||
}
|
||||
|
||||
var req SendCodeRequest
|
||||
if err := c.BodyParser(&req); err != nil {
|
||||
return utils.BadRequest(c, "请求数据格式错误")
|
||||
}
|
||||
|
||||
// TODO: 实际发送验证码逻辑
|
||||
// 这里应该调用短信服务发送验证码
|
||||
// 并将验证码存储到缓存中,设置过期时间
|
||||
// sendSMS(req.Phone, code)
|
||||
// cache.Set(req.Phone, code, 5*time.Minute)
|
||||
|
||||
// 模拟生成6位验证码
|
||||
// code := "123456" // 实际应该随机生成
|
||||
|
||||
// 返回成功响应(实际开发中不应返回验证码)
|
||||
return utils.Success(c, fiber.Map{
|
||||
"message": "验证码已发送,请注意查收",
|
||||
"expires_in": 300, // 5分钟过期
|
||||
})
|
||||
}
|
||||
|
||||
func UpdateProfile(c *fiber.Ctx) error {
|
||||
userID := middleware.GetUserID(c)
|
||||
|
||||
type UpdateProfileRequest struct {
|
||||
Nickname string `json:"nickname" validate:"min=1,max=50"`
|
||||
}
|
||||
|
||||
var req UpdateProfileRequest
|
||||
if err := c.BodyParser(&req); err != nil {
|
||||
return utils.BadRequest(c, "请求数据格式错误")
|
||||
}
|
||||
|
||||
var user models.User
|
||||
if err := database.GetDB().First(&user, userID).Error; err != nil {
|
||||
return utils.NotFound(c, "用户不存在")
|
||||
}
|
||||
|
||||
// 更新昵称
|
||||
if req.Nickname != "" {
|
||||
user.Nickname = req.Nickname
|
||||
}
|
||||
|
||||
if err := database.GetDB().Save(&user).Error; err != nil {
|
||||
return utils.InternalServerError(c, "更新用户信息失败")
|
||||
}
|
||||
|
||||
return utils.Success(c, user)
|
||||
}
|
||||
Reference in New Issue
Block a user