Files
urldb/handlers/user_handler.go
2025-07-18 09:42:07 +08:00

281 lines
6.5 KiB
Go

package handlers
import (
"net/http"
"strconv"
"github.com/ctwj/urldb/db/converter"
"github.com/ctwj/urldb/db/dto"
"github.com/ctwj/urldb/db/entity"
"github.com/ctwj/urldb/middleware"
"github.com/gin-gonic/gin"
)
// Login 用户登录
func Login(c *gin.Context) {
var req dto.LoginRequest
if err := c.ShouldBindJSON(&req); err != nil {
ErrorResponse(c, err.Error(), http.StatusBadRequest)
return
}
user, err := repoManager.UserRepository.FindByUsername(req.Username)
if err != nil {
ErrorResponse(c, "用户名或密码错误", http.StatusUnauthorized)
return
}
if !user.IsActive {
ErrorResponse(c, "账户已被禁用", http.StatusUnauthorized)
return
}
if !middleware.CheckPassword(req.Password, user.Password) {
ErrorResponse(c, "用户名或密码错误", http.StatusUnauthorized)
return
}
// 更新最后登录时间
repoManager.UserRepository.UpdateLastLogin(user.ID)
// 生成JWT令牌
token, err := middleware.GenerateToken(user)
if err != nil {
ErrorResponse(c, "生成令牌失败", http.StatusInternalServerError)
return
}
response := dto.LoginResponse{
Token: token,
User: converter.ToUserResponse(user),
}
SuccessResponse(c, response)
}
// Register 用户注册
func Register(c *gin.Context) {
var req dto.RegisterRequest
if err := c.ShouldBindJSON(&req); err != nil {
ErrorResponse(c, err.Error(), http.StatusBadRequest)
return
}
// 检查用户名是否已存在
existingUser, _ := repoManager.UserRepository.FindByUsername(req.Username)
if existingUser != nil {
ErrorResponse(c, "用户名已存在", http.StatusBadRequest)
return
}
// 检查邮箱是否已存在
existingEmail, _ := repoManager.UserRepository.FindByEmail(req.Email)
if existingEmail != nil {
ErrorResponse(c, "邮箱已存在", http.StatusBadRequest)
return
}
// 哈希密码
hashedPassword, err := middleware.HashPassword(req.Password)
if err != nil {
ErrorResponse(c, "密码加密失败", http.StatusInternalServerError)
return
}
user := &entity.User{
Username: req.Username,
Password: hashedPassword,
Email: req.Email,
Role: "user",
IsActive: true,
}
err = repoManager.UserRepository.Create(user)
if err != nil {
ErrorResponse(c, err.Error(), http.StatusInternalServerError)
return
}
SuccessResponse(c, gin.H{
"message": "注册成功",
"user": converter.ToUserResponse(user),
})
}
// GetUsers 获取用户列表(管理员)
func GetUsers(c *gin.Context) {
users, err := repoManager.UserRepository.FindAll()
if err != nil {
ErrorResponse(c, err.Error(), http.StatusInternalServerError)
return
}
responses := converter.ToUserResponseList(users)
SuccessResponse(c, responses)
}
// CreateUser 创建用户(管理员)
func CreateUser(c *gin.Context) {
var req dto.CreateUserRequest
if err := c.ShouldBindJSON(&req); err != nil {
ErrorResponse(c, err.Error(), http.StatusBadRequest)
return
}
// 检查用户名是否已存在
existingUser, _ := repoManager.UserRepository.FindByUsername(req.Username)
if existingUser != nil {
ErrorResponse(c, "用户名已存在", http.StatusBadRequest)
return
}
// 检查邮箱是否已存在
existingEmail, _ := repoManager.UserRepository.FindByEmail(req.Email)
if existingEmail != nil {
ErrorResponse(c, "邮箱已存在", http.StatusBadRequest)
return
}
// 哈希密码
hashedPassword, err := middleware.HashPassword(req.Password)
if err != nil {
ErrorResponse(c, "密码加密失败", http.StatusInternalServerError)
return
}
user := &entity.User{
Username: req.Username,
Password: hashedPassword,
Email: req.Email,
Role: req.Role,
IsActive: req.IsActive,
}
err = repoManager.UserRepository.Create(user)
if err != nil {
ErrorResponse(c, err.Error(), http.StatusInternalServerError)
return
}
SuccessResponse(c, gin.H{
"message": "用户创建成功",
"user": converter.ToUserResponse(user),
})
}
// UpdateUser 更新用户(管理员)
func UpdateUser(c *gin.Context) {
idStr := c.Param("id")
id, err := strconv.ParseUint(idStr, 10, 32)
if err != nil {
ErrorResponse(c, "无效的ID", http.StatusBadRequest)
return
}
var req dto.UpdateUserRequest
if err := c.ShouldBindJSON(&req); err != nil {
ErrorResponse(c, err.Error(), http.StatusBadRequest)
return
}
user, err := repoManager.UserRepository.FindByID(uint(id))
if err != nil {
ErrorResponse(c, "用户不存在", http.StatusNotFound)
return
}
if req.Username != "" {
user.Username = req.Username
}
if req.Email != "" {
user.Email = req.Email
}
if req.Role != "" {
user.Role = req.Role
}
user.IsActive = req.IsActive
err = repoManager.UserRepository.Update(user)
if err != nil {
ErrorResponse(c, err.Error(), http.StatusInternalServerError)
return
}
SuccessResponse(c, gin.H{"message": "用户更新成功"})
}
// ChangePassword 修改用户密码(管理员)
func ChangePassword(c *gin.Context) {
idStr := c.Param("id")
id, err := strconv.ParseUint(idStr, 10, 32)
if err != nil {
ErrorResponse(c, "无效的ID", http.StatusBadRequest)
return
}
var req dto.ChangePasswordRequest
if err := c.ShouldBindJSON(&req); err != nil {
ErrorResponse(c, err.Error(), http.StatusBadRequest)
return
}
user, err := repoManager.UserRepository.FindByID(uint(id))
if err != nil {
ErrorResponse(c, "用户不存在", http.StatusNotFound)
return
}
// 哈希新密码
hashedPassword, err := middleware.HashPassword(req.NewPassword)
if err != nil {
ErrorResponse(c, "密码加密失败", http.StatusInternalServerError)
return
}
user.Password = hashedPassword
err = repoManager.UserRepository.Update(user)
if err != nil {
ErrorResponse(c, err.Error(), http.StatusInternalServerError)
return
}
SuccessResponse(c, gin.H{"message": "密码修改成功"})
}
// DeleteUser 删除用户(管理员)
func DeleteUser(c *gin.Context) {
idStr := c.Param("id")
id, err := strconv.ParseUint(idStr, 10, 32)
if err != nil {
ErrorResponse(c, "无效的ID", http.StatusBadRequest)
return
}
err = repoManager.UserRepository.Delete(uint(id))
if err != nil {
ErrorResponse(c, err.Error(), http.StatusInternalServerError)
return
}
SuccessResponse(c, gin.H{"message": "用户删除成功"})
}
// GetProfile 获取用户资料
func GetProfile(c *gin.Context) {
userID, exists := c.Get("user_id")
if !exists {
ErrorResponse(c, "未认证", http.StatusUnauthorized)
return
}
user, err := repoManager.UserRepository.FindByID(userID.(uint))
if err != nil {
ErrorResponse(c, "用户不存在", http.StatusNotFound)
return
}
response := converter.ToUserResponse(user)
SuccessResponse(c, response)
}