user-management/
├── cmd/
│ └── server/
│ └── main.go # 应用入口
├── internal/
│ ├── config/ # 配置管理
│ ├── handler/ # HTTP处理器
│ ├── middleware/ # 中间件
│ ├── model/ # 数据模型
│ ├── repository/ # 数据访问层
│ ├── service/ # 业务逻辑层
│ └── utils/ # 工具函数
├── pkg/
│ ├── auth/ # 认证模块
│ ├── database/ # 数据库连接
│ └── logger/ # 日志模块
├── api/
│ └── docs/ # API文档
├── scripts/ # 部署脚本
├── docker-compose.yml # Docker配置
├── go.mod # 依赖管理
└── README.md # 项目说明
package config
type Config struct {
Server ServerConfig `mapstructure:"server"`
Database DatabaseConfig `mapstructure:"database"`
JWT JWTConfig `mapstructure:"jwt"`
}
type ServerConfig struct {
Port string `mapstructure:"port"`
Mode string `mapstructure:"mode"`
}
type DatabaseConfig struct {
Host string `mapstructure:"host"`
Port string `mapstructure:"port"`
User string `mapstructure:"user"`
Password string `mapstructure:"password"`
DBName string `mapstructure:"dbname"`
}
type JWTConfig struct {
Secret string `mapstructure:"secret"`
Expire int `mapstructure:"expire"`
}
func Load() (*Config, error) {
// 实现配置加载逻辑
}
package model
import "time"
type User struct {
ID uint `gorm:"primaryKey" json:"id"`
Username string `gorm:"uniqueIndex;not null" json:"username"`
Email string `gorm:"uniqueIndex;not null" json:"email"`
Password string `gorm:"not null" json:"-"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
}
type CreateUserRequest struct {
Username string `json:"username" binding:"required,min=3,max=50"`
Email string `json:"email" binding:"required,email"`
Password string `json:"password" binding:"required,min=6"`
}
type LoginRequest struct {
Username string `json:"username" binding:"required"`
Password string `json:"password" binding:"required"`
}
type UserResponse struct {
ID uint `json:"id"`
Username string `json:"username"`
Email string `json:"email"`
}
package service
import (
"user-management/internal/model"
"user-management/internal/repository"
"golang.org/x/crypto/bcrypt"
)
type UserService struct {
userRepo repository.UserRepository
}
func NewUserService(repo repository.UserRepository) *UserService {
return &UserService{userRepo: repo}
}
func (s *UserService) CreateUser(req model.CreateUserRequest) (*model.UserResponse, error) {
// 密码加密
hashedPassword, err := bcrypt.GenerateFromPassword([]byte(req.Password), bcrypt.DefaultCost)
if err != nil {
return nil, err
}
user := &model.User{
Username: req.Username,
Email: req.Email,
Password: string(hashedPassword),
}
if err := s.userRepo.Create(user); err != nil {
return nil, err
}
return &model.UserResponse{
ID: user.ID,
Username: user.Username,
Email: user.Email,
}, nil
}
func (s *UserService) Authenticate(req model.LoginRequest) (*model.User, error) {
user, err := s.userRepo.FindByUsername(req.Username)
if err != nil {
return nil, err
}
if err := bcrypt.CompareHashAndPassword([]byte(user.Password), []byte(req.Password)); err != nil {
return nil, err
}
return user, nil
}
package handler
import (
"net/http"
"user-management/internal/model"
"user-management/internal/service"
"github.com/gin-gonic/gin"
)
type UserHandler struct {
userService *service.UserService
authService *service.AuthService
}
func NewUserHandler(userService *service.UserService, authService *service.AuthService) *UserHandler {
return &UserHandler{
userService: userService,
authService: authService,
}
}
// Register 用户注册
// @Summary 用户注册
// @Tags users
// @Accept json
// @Produce json
// @Param user body model.CreateUserRequest true "用户信息"
// @Success 201 {object} model.UserResponse
// @Router /api/v1/register [post]
func (h *UserHandler) Register(c *gin.Context) {
var req model.CreateUserRequest
if err := c.ShouldBindJSON(&req); err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
return
}
user, err := h.userService.CreateUser(req)
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
return
}
c.JSON(http.StatusCreated, user)
}
// Login 用户登录
// @Summary 用户登录
// @Tags users
// @Accept json
// @Produce json
// @Param credentials body model.LoginRequest true "登录凭证"
// @Success 200 {object} gin.H
// @Router /api/v1/login [post]
func (h *UserHandler) Login(c *gin.Context) {
var req model.LoginRequest
if err := c.ShouldBindJSON(&req); err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
return
}
user, err := h.userService.Authenticate(req)
if err != nil {
c.JSON(http.StatusUnauthorized, gin.H{"error": "用户名或密码错误"})
return
}
token, err := h.authService.GenerateToken(user.ID)
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
return
}
c.JSON(http.StatusOK, gin.H{
"token": token,
"user": model.UserResponse{
ID: user.ID,
Username: user.Username,
Email: user.Email,
},
})
}
package middleware
import (
"net/http"
"strings"
"user-management/pkg/auth"
"github.com/gin-gonic/gin"
)
func AuthMiddleware(jwtService *auth.JWTService) gin.HandlerFunc {
return func(c *gin.Context) {
authHeader := c.GetHeader("Authorization")
if authHeader == "" {
c.JSON(http.StatusUnauthorized, gin.H{"error": "缺少认证令牌"})
c.Abort()
return
}
parts := strings.Split(authHeader, " ")
if len(parts) != 2 || parts[0] != "Bearer" {
c.JSON(http.StatusUnauthorized, gin.H{"error": "令牌格式错误"})
c.Abort()
return
}
token := parts[1]
claims, err := jwtService.ValidateToken(token)
if err != nil {
c.JSON(http.StatusUnauthorized, gin.H{"error": "无效令牌"})
c.Abort()
return
}
c.Set("userID", claims.UserID)
c.Next()
}
}
| 方法 | 路径 | 描述 | 认证 |
|---|---|---|---|
| POST | /api/v1/register | 用户注册 | 否 |
| POST | /api/v1/login | 用户登录 | 否 |
| GET | /api/v1/users | 获取用户列表 | 是 |
| GET | /api/v1/users/:id | 获取用户详情 | 是 |
| PUT | /api/v1/users/:id | 更新用户信息 | 是 |
| DELETE | /api/v1/users/:id | 删除用户 | 是 |
version: '3.8'
services:
app:
build: .
ports:
- "8080:8080"
environment:
- DB_HOST=db
- DB_PORT=3306
- DB_USER=user
- DB_PASSWORD=password
- DB_NAME=user_management
depends_on:
- db
db:
image: mysql:8.0
environment:
- MYSQL_ROOT_PASSWORD=root
- MYSQL_DATABASE=user_management
- MYSQL_USER=user
- MYSQL_PASSWORD=password
ports:
- "3306:3306"
volumes:
- db_data:/var/lib/mysql
volumes:
db_data:
func TestUserService_CreateUser(t *testing.T) {
// 测试用户创建逻辑
}
func TestUserService_Authenticate(t *testing.T) {
// 测试用户认证逻辑
}
func TestUserAPI(t *testing.T) {
// 测试完整的API流程
}
func BenchmarkUserCreation(b *testing.B) {
// 性能基准测试
}
完成本项目后,您将拥有:
这个项目将为您后续的Go开发工作奠定坚实的基础!