package handlers import ( "net/http" "strconv" "goblog/database" "goblog/models" "github.com/gin-gonic/gin" ) // 创建用户请求 type CreateUserRequest struct { Username string `json:"username" binding:"required,min=3,max=50"` Password string `json:"password" binding:"required,min=6"` Nickname string `json:"nickname"` Email string `json:"email" binding:"required,email"` Role string `json:"role"` Status *int `json:"status"` } // 更新用户请求 type AdminUpdateUserRequest struct { Nickname string `json:"nickname"` Email string `json:"email"` Role string `json:"role"` Status *int `json:"status"` } // 重置密码请求 type ResetPasswordRequest struct { NewPassword string `json:"new_password" binding:"required,min=6"` } // 获取用户列表(管理员) func GetUsers(c *gin.Context) { page, _ := strconv.Atoi(c.DefaultQuery("page", "1")) pageSize, _ := strconv.Atoi(c.DefaultQuery("page_size", "20")) keyword := c.Query("keyword") if page < 1 { page = 1 } if pageSize < 1 || pageSize > 100 { pageSize = 20 } query := database.DB.Model(&models.User{}) if keyword != "" { like := "%" + keyword + "%" query = query.Where("username LIKE ? OR nickname LIKE ? OR email LIKE ?", like, like, like) } var total int64 query.Count(&total) var users []models.User if err := query.Order("id ASC").Offset((page - 1) * pageSize).Limit(pageSize).Find(&users).Error; err != nil { c.JSON(http.StatusInternalServerError, gin.H{"error": "获取用户列表失败"}) return } c.JSON(http.StatusOK, gin.H{ "data": users, "total": total, "page": page, "page_size": pageSize, }) } // 创建用户(管理员) func CreateUser(c *gin.Context) { var req CreateUserRequest if err := c.ShouldBindJSON(&req); err != nil { c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) return } // 检查用户名是否已存在 var count int64 database.DB.Model(&models.User{}).Where("username = ?", req.Username).Count(&count) if count > 0 { c.JSON(http.StatusBadRequest, gin.H{"error": "用户名已存在"}) return } // 检查邮箱是否已存在 database.DB.Model(&models.User{}).Where("email = ?", req.Email).Count(&count) if count > 0 { c.JSON(http.StatusBadRequest, gin.H{"error": "邮箱已被注册"}) return } role := req.Role if role != "admin" { role = "user" } status := 1 if req.Status != nil { status = *req.Status } user := models.User{ Username: req.Username, Nickname: req.Nickname, Email: req.Email, Role: role, Status: status, IsActive: true, } if err := user.SetPassword(req.Password); err != nil { c.JSON(http.StatusInternalServerError, gin.H{"error": "密码加密失败"}) return } if err := database.DB.Create(&user).Error; err != nil { c.JSON(http.StatusInternalServerError, gin.H{"error": "创建用户失败"}) return } c.JSON(http.StatusCreated, gin.H{"data": user}) } // 更新用户信息(管理员) func AdminUpdateUser(c *gin.Context) { id := c.Param("id") operatorID, _ := c.Get("userID") var user models.User if err := database.DB.First(&user, id).Error; err != nil { c.JSON(http.StatusNotFound, gin.H{"error": "用户不存在"}) return } var req AdminUpdateUserRequest if err := c.ShouldBindJSON(&req); err != nil { c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) return } isSelf := operatorID == user.ID updates := map[string]interface{}{ "nickname": req.Nickname, } if req.Email != "" && req.Email != user.Email { // 检查邮箱是否已被其他用户使用 var count int64 database.DB.Model(&models.User{}).Where("email = ? AND id != ?", req.Email, user.ID).Count(&count) if count > 0 { c.JSON(http.StatusBadRequest, gin.H{"error": "邮箱已被其他用户使用"}) return } updates["email"] = req.Email } if req.Role != "" && req.Role != user.Role { if isSelf { c.JSON(http.StatusBadRequest, gin.H{"error": "不能修改自己的角色"}) return } if req.Role != "admin" && req.Role != "user" { c.JSON(http.StatusBadRequest, gin.H{"error": "无效的角色"}) return } updates["role"] = req.Role } if req.Status != nil && *req.Status != user.Status { if isSelf { c.JSON(http.StatusBadRequest, gin.H{"error": "不能禁用自己的账号"}) return } updates["status"] = *req.Status } if err := database.DB.Model(&user).Updates(updates).Error; err != nil { c.JSON(http.StatusInternalServerError, gin.H{"error": "更新用户失败"}) return } c.JSON(http.StatusOK, gin.H{"data": user}) } // 重置用户密码(管理员) func AdminResetPassword(c *gin.Context) { id := c.Param("id") var user models.User if err := database.DB.First(&user, id).Error; err != nil { c.JSON(http.StatusNotFound, gin.H{"error": "用户不存在"}) return } var req ResetPasswordRequest if err := c.ShouldBindJSON(&req); err != nil { c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) return } if err := user.SetPassword(req.NewPassword); err != nil { c.JSON(http.StatusInternalServerError, gin.H{"error": "密码加密失败"}) return } if err := database.DB.Save(&user).Error; err != nil { c.JSON(http.StatusInternalServerError, gin.H{"error": "重置密码失败"}) return } c.JSON(http.StatusOK, gin.H{"message": "密码重置成功"}) } // 删除用户(管理员) func DeleteUser(c *gin.Context) { id := c.Param("id") operatorID, _ := c.Get("userID") var user models.User if err := database.DB.First(&user, id).Error; err != nil { c.JSON(http.StatusNotFound, gin.H{"error": "用户不存在"}) return } if operatorID == user.ID { c.JSON(http.StatusBadRequest, gin.H{"error": "不能删除自己的账号"}) return } // 检查该用户是否有文章 var count int64 database.DB.Model(&models.Post{}).Where("author_id = ?", user.ID).Count(&count) if count > 0 { c.JSON(http.StatusBadRequest, gin.H{"error": "该用户名下还有文章,无法删除"}) return } // 检查该用户是否有页面 database.DB.Model(&models.Page{}).Where("author_id = ?", user.ID).Count(&count) if count > 0 { c.JSON(http.StatusBadRequest, gin.H{"error": "该用户名下还有页面,无法删除"}) return } if err := database.DB.Delete(&user).Error; err != nil { c.JSON(http.StatusInternalServerError, gin.H{"error": "删除用户失败"}) return } c.JSON(http.StatusOK, gin.H{"message": "删除成功"}) }