6. 新增“用户”管理表逻辑
向 AI 提问: 我要新增一个用户管理表。根据待办事项的项目逻辑,把这张用户管理表的逻辑补充完整。
好的,我来帮你添加用户管理相关的功能。
首先创建用户模型:
go
// :d:\works\RD\todo-list\models\user.go
package models
import (
"gorm.io/gorm"
)
type User struct {
gorm.Model
Username string `json:"username" gorm:"uniqueIndex;size:50;not null"`
Password string `json:"password" gorm:"size:100;not null"`
Email string `json:"email" gorm:"size:100"`
Status int `json:"status" gorm:"default:1"` // 1: 正常, 0: 禁用
Todos []Todo `json:"todos" gorm:"foreignKey:UserID"`
}修改 Todo 模型,添加用户关联:
go
// :d:\works\RD\todo-list\models\todo.go
type Todo struct {
gorm.Model
Title string `json:"title"`
Description string `json:"description"`
DueDate time.Time `json:"due_date"`
Completed bool `json:"completed"`
UserID uint `json:"user_id"`
}创建用户控制器:
go
// :d:\works\RD\todo-list\controllers\user_controller.go
package controllers
import (
"net/http"
"todo-list/models"
"todo-list/utils"
"github.com/gin-gonic/gin"
"gorm.io/gorm"
)
type UserController struct {
DB *gorm.DB
}
func NewUserController(db *gorm.DB) *UserController {
return &UserController{DB: db}
}
// 创建用户
func (uc *UserController) Create(c *gin.Context) {
var user models.User
if err := c.ShouldBindJSON(&user); err != nil {
utils.ErrorResponse(c, http.StatusBadRequest, err.Error())
return
}
// 密码加密
user.Password = utils.HashPassword(user.Password)
if err := uc.DB.Create(&user).Error; err != nil {
utils.ErrorResponse(c, http.StatusInternalServerError, "创建用户失败")
return
}
user.Password = "" // 返回数据时隐藏密码
utils.SuccessResponse(c, user)
}
// 用户登录
func (uc *UserController) Login(c *gin.Context) {
var loginInfo struct {
Username string `json:"username"`
Password string `json:"password"`
}
if err := c.ShouldBindJSON(&loginInfo); err != nil {
utils.ErrorResponse(c, http.StatusBadRequest, err.Error())
return
}
var user models.User
if err := uc.DB.Where("username = ?", loginInfo.Username).First(&user).Error; err != nil {
utils.ErrorResponse(c, http.StatusUnauthorized, "用户名或密码错误")
return
}
if !utils.CheckPassword(loginInfo.Password, user.Password) {
utils.ErrorResponse(c, http.StatusUnauthorized, "用户名或密码错误")
return
}
// 生成 token
token := utils.GenerateToken(user.ID)
utils.SuccessResponse(c, gin.H{"token": token})
}
// 获取用户信息
func (uc *UserController) GetInfo(c *gin.Context) {
userID := c.GetUint("userID") // 从中间件获取用户ID
var user models.User
if err := uc.DB.First(&user, userID).Error; err != nil {
utils.ErrorResponse(c, http.StatusNotFound, "用户不存在")
return
}
user.Password = "" // 隐藏密码
utils.SuccessResponse(c, user)
}添加密码加密和 Token 相关工具函数:
go
// :d:\works\RD\todo-list\utils\auth.go
package utils
import (
"golang.org/x/crypto/bcrypt"
"github.com/dgrijalva/jwt-go"
"time"
)
var jwtSecret = []byte("your-secret-key")
func HashPassword(password string) string {
bytes, _ := bcrypt.GenerateFromPassword([]byte(password), bcrypt.DefaultCost)
return string(bytes)
}
func CheckPassword(password, hash string) bool {
err := bcrypt.CompareHashAndPassword([]byte(hash), []byte(password))
return err == nil
}
func GenerateToken(userID uint) string {
token := jwt.NewWithClaims(jwt.SigningMethodHS256, jwt.MapClaims{
"userID": userID,
"exp": time.Now().Add(time.Hour * 24).Unix(),
})
tokenString, _ := token.SignedString(jwtSecret)
return tokenString
}添加认证中间件:
go
// :d:\works\RD\todo-list\middleware\auth.go
package middleware
import (
"github.com/gin-gonic/gin"
"github.com/dgrijalva/jwt-go"
"todo-list/utils"
"strings"
)
func AuthMiddleware() gin.HandlerFunc {
return func(c *gin.Context) {
authHeader := c.GetHeader("Authorization")
if authHeader == "" {
utils.ErrorResponse(c, 401, "未授权")
c.Abort()
return
}
parts := strings.SplitN(authHeader, " ", 2)
if !(len(parts) == 2 && parts[0] == "Bearer") {
utils.ErrorResponse(c, 401, "无效的认证格式")
c.Abort()
return
}
token, err := jwt.Parse(parts[1], func(token *jwt.Token) (interface{}, error) {
return []byte("your-secret-key"), nil
})
if err != nil || !token.Valid {
utils.ErrorResponse(c, 401, "无效的token")
c.Abort()
return
}
claims := token.Claims.(jwt.MapClaims)
c.Set("userID", uint(claims["userID"].(float64)))
c.Next()
}
}更新路由配置:
go
// :d:\works\RD\todo-list\routes\routes.go
func SetupRouter() *gin.Engine {
r := gin.Default()
r.Use(middleware.Logger())
db, _ := config.InitDB()
todoController := controllers.NewTodoController(db)
userController := controllers.NewUserController(db)
v1 := r.Group("/api/v1")
{
// 用户相关路由
users := v1.Group("/users")
{
users.POST("/register", userController.Create)
users.POST("/login", userController.Login)
users.GET("/info", middleware.AuthMiddleware(), userController.GetInfo)
}
// 待办事项路由,添加认证中间件
todos := v1.Group("/todos", middleware.AuthMiddleware())
{
todos.POST("/", todoController.Create)
todos.GET("/", todoController.GetAll)
todos.GET("/:id", todoController.GetOne)
todos.PUT("/:id", todoController.Update)
todos.DELETE("/:id", todoController.Delete)
}
}
return r
}最后更新数据库配置,添加用户表迁移:
go
// :d:\works\RD\todo-list\config\database.go
// 自动迁移数据库结构
err = db.AutoMigrate(&models.User{}, &models.Todo{})
if err != nil {
return nil, err
}需要安装新的依赖:
bash
go get -u golang.org/x/crypto/bcrypt
go get -u github.com/dgrijalva/jwt-go这样就完成了用户管理相关的功能,包括:
- 用户注册
- 用户登录
- 获取用户信息
- JWT 认证
- 待办事项与用户关联
所有的待办事项接口都需要认证才能访问,确保数据安全。
报错一
报错

解决方法
你需要在项目目录下执行这些命令。让我们切换到正确的目录并安装依赖:
bash
cd d:\works\RD\todo-list
go get -u golang.org/x/crypto/bcrypt
go get -u github.com/dgrijalva/jwt-go如果项目还没有初始化 go module,需要先执行:
bash
cd d:\works\RD\todo-list
go mod init todo-list
go mod tidy然后再执行安装依赖的命令:
bash
go get -u golang.org/x/crypto/bcrypt
go get -u github.com/dgrijalva/jwt-go这样就能正确安装所需的依赖包了。go mod tidy 命令会自动处理项目的依赖关系,添加缺少的依赖并删除不需要的依赖。
报错二
报错

在 routes.go 中使用了 middleware 包但没有正确导入。
go
// routes/routes.go
package routes
import (
"github.com/gin-gonic/gin"
"todo-list/controllers"
"todo-list/config"
"todo-list/middleware" // 添加这行导入
)
// 其他略...