211 lines
5.3 KiB
Go
211 lines
5.3 KiB
Go
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)
|
|
}
|