131 lines
3.6 KiB
Go
131 lines
3.6 KiB
Go
// Package user 提供用户相关功能的控制器
|
|
// 实现用户注册、登录等操作
|
|
package user
|
|
|
|
import (
|
|
"net/http"
|
|
|
|
"git.huangwc.com/pig/pig-farm-controller/internal/api/middleware"
|
|
"git.huangwc.com/pig/pig-farm-controller/internal/controller"
|
|
"git.huangwc.com/pig/pig-farm-controller/internal/logs"
|
|
"git.huangwc.com/pig/pig-farm-controller/internal/storage/repository"
|
|
"github.com/gin-gonic/gin"
|
|
"golang.org/x/crypto/bcrypt"
|
|
)
|
|
|
|
// Controller 用户控制器
|
|
type Controller struct {
|
|
userRepo repository.UserRepo
|
|
logger *logs.Logger
|
|
}
|
|
|
|
// NewController 创建用户控制器实例
|
|
func NewController(userRepo repository.UserRepo) *Controller {
|
|
return &Controller{
|
|
userRepo: userRepo,
|
|
logger: logs.NewLogger(),
|
|
}
|
|
}
|
|
|
|
// RegisterRequest 用户注册请求结构体
|
|
type RegisterRequest struct {
|
|
Username string `json:"username" binding:"required"`
|
|
Password string `json:"password" binding:"required"`
|
|
}
|
|
|
|
// LoginRequest 用户登录请求结构体
|
|
type LoginRequest struct {
|
|
Username string `json:"username" binding:"required"`
|
|
Password string `json:"password" binding:"required"`
|
|
}
|
|
|
|
// RegisterResponseData 用户注册响应数据
|
|
type RegisterResponseData struct {
|
|
ID uint `json:"id"`
|
|
Username string `json:"username"`
|
|
}
|
|
|
|
// LoginResponseData 用户登录响应数据
|
|
type LoginResponseData struct {
|
|
ID uint `json:"id"`
|
|
Username string `json:"username"`
|
|
Token string `json:"token"`
|
|
}
|
|
|
|
// Register 用户注册接口
|
|
func (c *Controller) Register(ctx *gin.Context) {
|
|
var req RegisterRequest
|
|
if err := ctx.ShouldBindJSON(&req); err != nil {
|
|
controller.SendErrorResponse(ctx, http.StatusBadRequest, "请求参数错误")
|
|
return
|
|
}
|
|
|
|
// 检查用户名是否已存在
|
|
_, err := c.userRepo.FindByUsername(req.Username)
|
|
if err == nil {
|
|
controller.SendErrorResponse(ctx, http.StatusBadRequest, "用户名已存在")
|
|
return
|
|
}
|
|
|
|
// 对密码进行哈希处理
|
|
hashedPassword, err := bcrypt.GenerateFromPassword([]byte(req.Password), bcrypt.DefaultCost)
|
|
if err != nil {
|
|
c.logger.Error("密码哈希处理失败: " + err.Error())
|
|
controller.SendErrorResponse(ctx, http.StatusInternalServerError, "用户注册失败")
|
|
return
|
|
}
|
|
|
|
// 创建用户
|
|
user, err := c.userRepo.CreateUser(req.Username, string(hashedPassword))
|
|
if err != nil {
|
|
c.logger.Error("创建用户失败: " + err.Error())
|
|
controller.SendErrorResponse(ctx, http.StatusInternalServerError, "用户注册失败")
|
|
return
|
|
}
|
|
|
|
data := RegisterResponseData{
|
|
ID: user.ID,
|
|
Username: user.Username,
|
|
}
|
|
|
|
controller.SendSuccessResponse(ctx, "用户注册成功", data)
|
|
}
|
|
|
|
// Login 用户登录接口
|
|
func (c *Controller) Login(ctx *gin.Context) {
|
|
var req LoginRequest
|
|
if err := ctx.ShouldBindJSON(&req); err != nil {
|
|
controller.SendErrorResponse(ctx, http.StatusBadRequest, "请求参数错误")
|
|
return
|
|
}
|
|
|
|
// 查找用户
|
|
user, err := c.userRepo.FindByUsername(req.Username)
|
|
if err != nil {
|
|
controller.SendErrorResponse(ctx, http.StatusUnauthorized, "用户名或密码错误")
|
|
return
|
|
}
|
|
|
|
// 验证密码
|
|
if err := bcrypt.CompareHashAndPassword([]byte(user.PasswordHash), []byte(req.Password)); err != nil {
|
|
controller.SendErrorResponse(ctx, http.StatusUnauthorized, "用户名或密码错误")
|
|
return
|
|
}
|
|
|
|
// 生成JWT token
|
|
token, err := middleware.NewAuthMiddleware(c.userRepo).GenerateToken(user.ID, user.Username)
|
|
if err != nil {
|
|
c.logger.Error("生成JWT token失败: " + err.Error())
|
|
controller.SendErrorResponse(ctx, http.StatusInternalServerError, "登录失败")
|
|
return
|
|
}
|
|
|
|
data := LoginResponseData{
|
|
ID: user.ID,
|
|
Username: user.Username,
|
|
Token: token,
|
|
}
|
|
|
|
controller.SendSuccessResponse(ctx, "登录成功", data)
|
|
}
|