2025-12-02 17:46:00 +08:00
2025-12-02 17:40:39 +08:00

CarrotSkin Backend

一个功能完善的Minecraft皮肤站后端系统采用单体架构设计基于Go语言和Gin框架开发。

核心功能

  • 用户认证系统 - 注册、登录、JWT认证、积分系统
  • 邮箱验证系统 - 注册验证、找回密码、更换邮箱基于Redis的验证码
  • 材质管理系统 - 皮肤/披风上传、搜索、收藏、下载统计
  • 角色档案系统 - Minecraft角色创建、管理、RSA密钥生成
  • 文件存储 - MinIO/RustFS对象存储集成、预签名URL上传
  • 缓存系统 - Redis缓存、验证码存储、频率限制
  • 权限管理 - Casbin RBAC权限控制
  • 数据审计 - 登录日志、操作审计、下载记录

项目结构

backend/
├── cmd/                    # 应用程序入口
│   └── server/            # 主服务器入口
│       └── main.go        # 服务初始化、路由注册
├── internal/              # 私有应用代码
│   ├── handler/           # HTTP处理器函数式
│   │   ├── routes.go      # 路由注册
│   │   ├── auth_handler.go
│   │   ├── user_handler.go
│   │   └── ...
│   ├── service/           # 业务逻辑服务(函数式)
│   │   ├── common.go      # 公共声明jsoniter等
│   │   ├── user_service.go
│   │   └── ...
│   ├── repository/        # 数据访问层(函数式)
│   │   ├── user_repository.go
│   │   └── ...
│   ├── model/             # 数据模型GORM
│   ├── middleware/        # 中间件
│   └── types/             # 类型定义
├── pkg/                   # 公共库代码
│   ├── auth/              # 认证授权
│   │   └── manager.go     # JWT服务管理器
│   ├── config/            # 配置管理
│   │   └── manager.go     # 配置管理器
│   ├── database/          # 数据库连接
│   │   ├── manager.go     # 数据库管理器AutoMigrate
│   │   └── postgres.go    # PostgreSQL连接
│   ├── email/             # 邮件服务
│   │   └── manager.go     # 邮件服务管理器
│   ├── logger/            # 日志系统
│   │   └── manager.go     # 日志管理器
│   ├── redis/             # Redis客户端
│   │   └── manager.go     # Redis管理器
│   ├── storage/           # 文件存储(RustFS/MinIO)
│   │   └── manager.go     # 存储管理器
│   ├── utils/             # 工具函数
│   └── validator/         # 数据验证
├── docs/                   # API定义和文档Swagger
├── configs/               # 配置文件
│   └── casbin/            # Casbin权限配置
├── go.mod                 # Go模块依赖
├── go.sum                 # Go模块校验
├── start.sh               # Linux/Mac启动脚本
├── .env                   # 环境变量配置
└── README.md              # 项目说明

技术栈

  • 语言: Go 1.23+
  • 框架: Gin Web Framework
  • 数据库: PostgreSQL 15+ (GORM ORM)
  • 缓存: Redis 6.0+
  • 存储: RustFS/MinIO (S3兼容对象存储)
  • 权限: Casbin RBAC
  • 日志: Zap (结构化日志)
  • 配置: 环境变量 (.env) + Viper
  • JSON: jsoniter (高性能JSON序列化)
  • 文档: Swagger/OpenAPI 3.0

快速开始

环境要求

  • Go 1.21或更高版本
  • PostgreSQL 15或更高版本
  • Redis 6.0或更高版本
  • RustFS 或其他 S3 兼容对象存储服务

安装和运行

  1. 克隆项目
git clone <repository-url>
cd CarrotSkin/backend
  1. 安装依赖
go mod download
  1. 配置环境
# 复制环境变量文件
cp .env.example .env
# 编辑 .env 文件配置数据库、RustFS等服务连接信息

注意:项目完全依赖 .env 文件进行配置,不再使用 YAML 配置文件,便于 Docker 容器化部署。

  1. 初始化数据库
# 创建数据库
createdb carrotskin
# 或者使用PostgreSQL客户端
psql -h localhost -U postgres -c "CREATE DATABASE carrotskin;"

💡 提示: 项目使用 GORM 的 AutoMigrate 功能自动创建和更新数据库表结构无需手动执行SQL脚本。首次启动时会自动创建所有表。

  1. 运行服务

方式一:使用启动脚本(推荐)

# Linux/Mac
chmod +x start.sh
./start.sh

# Windows
start.bat

方式二:直接运行

# 设置环境变量(或使用.env文件
export DATABASE_HOST=localhost
export DATABASE_PORT=5432
# ... 其他环境变量

# 运行服务
go run cmd/server/main.go

💡 提示:

  • 启动脚本会自动加载 .env 文件中的环境变量
  • 首次启动时会自动执行数据库迁移AutoMigrate
  • 如果对象存储未配置,服务仍可启动(相关功能不可用)

服务启动后:

API接口

认证相关

  • POST /api/v1/auth/register - 用户注册(需邮箱验证码)
  • POST /api/v1/auth/login - 用户登录(支持用户名/邮箱)
  • POST /api/v1/auth/send-code - 发送验证码(注册/重置密码/更换邮箱)
  • POST /api/v1/auth/reset-password - 重置密码(需验证码)

用户相关(需认证)

  • GET /api/v1/user/profile - 获取用户信息
  • PUT /api/v1/user/profile - 更新用户信息(头像、密码)
  • POST /api/v1/user/avatar/upload-url - 生成头像上传URL
  • PUT /api/v1/user/avatar - 更新头像
  • POST /api/v1/user/change-email - 更换邮箱(需验证码)

材质管理

公开接口:

  • GET /api/v1/texture - 搜索材质
  • GET /api/v1/texture/:id - 获取材质详情

认证接口:

  • POST /api/v1/texture/upload-url - 生成材质上传URL
  • POST /api/v1/texture - 创建材质记录
  • PUT /api/v1/texture/:id - 更新材质
  • DELETE /api/v1/texture/:id - 删除材质
  • POST /api/v1/texture/:id/favorite - 切换收藏状态
  • GET /api/v1/texture/my - 我的材质列表
  • GET /api/v1/texture/favorites - 我的收藏列表

角色档案

公开接口:

  • GET /api/v1/profile/:uuid - 获取档案详情

认证接口:

  • POST /api/v1/profile - 创建角色档案UUID由后端生成
  • GET /api/v1/profile - 我的档案列表
  • PUT /api/v1/profile/:uuid - 更新档案
  • DELETE /api/v1/profile/:uuid - 删除档案
  • POST /api/v1/profile/:uuid/activate - 设置活跃档案

系统配置

  • GET /api/v1/system/config - 获取系统配置

配置管理

环境变量配置

项目完全依赖环境变量进行配置,不使用 YAML 配置文件,便于容器化部署:

  1. 配置来源: 环境变量 或 .env 文件
  2. 环境变量格式: 使用下划线分隔,全大写,如 DATABASE_HOST
  3. 容器部署: 直接在容器运行时设置环境变量即可

主要环境变量:

# 数据库配置
DATABASE_HOST=localhost
DATABASE_PORT=5432
DATABASE_USERNAME=postgres
DATABASE_PASSWORD=your_password
DATABASE_NAME=carrotskin

# Redis配置
REDIS_HOST=localhost
REDIS_PORT=6379
REDIS_PASSWORD=your_redis_password
REDIS_DATABASE=0
REDIS_POOL_SIZE=10

# RustFS对象存储配置 (S3兼容)
RUSTFS_ENDPOINT=127.0.0.1:9000
RUSTFS_ACCESS_KEY=your_access_key
RUSTFS_SECRET_KEY=your_secret_key
RUSTFS_USE_SSL=false
RUSTFS_BUCKET_TEXTURES=carrot-skin-textures
RUSTFS_BUCKET_AVATARS=carrot-skin-avatars

# JWT配置
JWT_SECRET=your-jwt-secret-key
JWT_EXPIRE_HOURS=168

# 邮件配置
EMAIL_ENABLED=true
EMAIL_SMTP_HOST=smtp.example.com
EMAIL_SMTP_PORT=587
EMAIL_USERNAME=noreply@example.com
EMAIL_PASSWORD=your_email_password
EMAIL_FROM_NAME=CarrotSkin

动态配置(存储在数据库中):

  • 积分系统配置(注册奖励、签到积分等)
  • 用户限制配置(最大材质数、最大角色数等)
  • 网站设置(站点名称、公告、维护模式等)

完整的环境变量列表请参考 .env.example 文件。

数据库自动迁移

项目使用 GORM 的 AutoMigrate 功能自动管理数据库表结构:

  • 首次启动: 自动创建所有表结构
  • 模型更新: 自动添加新字段、索引等
  • 类型转换: 自动处理字段类型变更如枚举类型转为varchar
  • 外键管理: 自动管理外键关系

注意事项:

  • 生产环境建议先备份数据库再执行迁移
  • 某些复杂变更(如删除字段)可能需要手动处理
  • 枚举类型在PostgreSQL中存储为varchar避免类型兼容问题

架构设计

面向过程的函数式架构

项目采用面向过程的函数式架构,摒弃不必要的面向对象抽象,使用独立函数和单例管理器模式,代码更简洁、可维护性更强:

┌─────────────────────────────────────┐
│         Handler 层 (函数)            │  ← 路由处理、参数验证、响应格式化
├─────────────────────────────────────┤
│         Service 层 (函数)            │  ← 业务逻辑、权限检查、数据验证
├─────────────────────────────────────┤
│       Repository 层 (函数)           │  ← 数据库操作、关联查询
├─────────────────────────────────────┤
│       Manager 层 (单例模式)          │  ← 核心依赖管理(线程安全)
│  - database.MustGetDB()             │
│  - logger.MustGetLogger()           │
│  - auth.MustGetJWTService()         │
│  - redis.MustGetClient()            │
│  - email.MustGetService()           │
│  - storage.MustGetClient()          │
│  - config.MustGetConfig()           │
├──────────────┬──────────────────────┤
│  PostgreSQL  │  Redis  │  RustFS   │  ← 数据存储层
└──────────────┴──────────────────────┘

架构特点

  1. 函数式设计: 所有业务逻辑以独立函数形式实现,无结构体方法,降低耦合度
  2. 管理器模式: 使用 sync.Once 实现线程安全的单例管理器,统一管理核心依赖
  3. 按需获取: 通过管理器函数按需获取依赖,避免链式传递,代码更清晰
  4. 自动迁移: 使用 GORM AutoMigrate 自动管理数据库表结构
  5. 高性能: 使用 jsoniter 替代标准库 json提升序列化性能

核心模块

  1. 认证模块 (internal/handler/auth_handler.go)

    • JWT令牌生成和验证通过 auth.MustGetJWTService() 获取)
    • bcrypt密码加密
    • 邮箱验证码注册
    • 密码重置功能
    • 登录日志记录(支持用户名/邮箱登录)
  2. 用户模块 (internal/handler/user_handler.go)

    • 用户信息管理
    • 头像上传预签名URL通过 storage.MustGetClient() 获取)
    • 密码修改(需原密码验证)
    • 邮箱更换(需验证码)
    • 积分系统
  3. 邮箱验证模块 (internal/service/verification_service.go)

    • 验证码生成6位数字
    • 验证码存储Redis10分钟有效期通过 redis.MustGetClient() 获取)
    • 发送频率限制1分钟
    • 邮件发送HTML格式通过 email.MustGetService() 获取)
  4. 材质模块 (internal/handler/texture_handler.go)

    • 材质上传预签名URL
    • 材质搜索和收藏
    • Hash去重
    • 下载统计
  5. 档案模块 (internal/handler/profile_handler.go)

    • Minecraft角色管理
    • RSA密钥生成RSA-2048
    • 活跃状态管理
    • 档案数量限制
  6. 管理器模块 (pkg/*/manager.go)

    • 数据库管理器:database.MustGetDB() - 线程安全的数据库连接
    • 日志管理器:logger.MustGetLogger() - 结构化日志实例
    • JWT管理器auth.MustGetJWTService() - JWT服务实例
    • Redis管理器redis.MustGetClient() - Redis客户端
    • 邮件管理器:email.MustGetService() - 邮件服务
    • 存储管理器:storage.MustGetClient() - 对象存储客户端
    • 配置管理器:config.MustGetConfig() - 应用配置

技术特性

  • 架构优势:

    • 面向过程的函数式设计,代码简洁清晰
    • 单例管理器模式,线程安全的依赖管理
    • 按需获取依赖,避免链式传递
    • 自动数据库迁移AutoMigrate
  • 安全性:

    • bcrypt密码加密、JWT令牌认证
    • 邮箱验证码(注册/重置密码/更换邮箱)
    • Casbin RBAC权限控制
    • 频率限制(防暴力破解)
  • 性能:

    • jsoniter 高性能JSON序列化替代标准库
    • PostgreSQL索引优化
    • Redis缓存验证码、会话等
    • 预签名URL减轻服务器压力
    • 连接池管理
  • 可靠性:

    • 事务保证数据一致性
    • 完整的错误处理和日志记录
    • 优雅关闭和资源清理
    • 对象存储连接失败时服务仍可启动
  • 可扩展:

    • 清晰的函数式架构
    • 管理器模式统一管理依赖
    • 环境变量配置(便于容器化)
  • 审计:

    • 登录日志(成功/失败)
    • 操作审计
    • 下载记录

开发指南

代码结构

  • cmd/server/ - 应用入口,初始化服务
  • internal/handler/ - HTTP请求处理
  • internal/service/ - 业务逻辑实现
  • internal/repository/ - 数据库操作
  • internal/model/ - 数据模型定义
  • internal/types/ - 请求/响应类型定义
  • internal/middleware/ - 中间件JWT、CORS、日志等
  • pkg/ - 可复用的公共库

开发规范

  1. 代码风格: 遵循Go官方代码规范使用 gofmt 格式化
  2. 架构模式: 使用函数式设计,避免不必要的结构体和方法
  3. 依赖管理: 通过管理器函数获取依赖(如 database.MustGetDB()),避免链式传递
  4. 错误处理: 使用统一的错误响应格式 (model.NewErrorResponse)
  5. 日志记录: 使用 Zap 结构化日志,通过 logger.MustGetLogger() 获取实例
  6. JSON序列化: 使用 jsoniter 替代标准库 json提升性能
  7. RESTful API: 遵循 REST 设计原则合理使用HTTP方法

添加新功能

  1. internal/model/ 定义数据模型GORM会自动迁移
  2. internal/repository/ 实现数据访问函数(使用 database.MustGetDB() 获取数据库)
  3. internal/service/ 实现业务逻辑函数(按需使用管理器获取依赖)
  4. internal/handler/ 实现HTTP处理函数使用管理器获取logger、jwtService等
  5. internal/handler/routes.go 注册路由

示例:

// Repository层
func FindUserByID(id uint) (*model.User, error) {
    db := database.MustGetDB()
    var user model.User
    err := db.First(&user, id).Error
    return &user, err
}

// Service层
func GetUserProfile(userID uint) (*model.User, error) {
    logger := logger.MustGetLogger()
    user, err := repository.FindUserByID(userID)
    if err != nil {
        logger.Error("获取用户失败", zap.Error(err))
        return nil, err
    }
    return user, nil
}

// Handler层
func GetUserProfile(c *gin.Context) {
    logger := logger.MustGetLogger()
    jwtService := auth.MustGetJWTService()
    // ... 处理逻辑
}

部署

本地开发

# 安装依赖
go mod download

# 配置环境变量(创建.env文件或直接export
cp .env.example .env
# 编辑 .env 文件

# 启动服务
# 方式1: 使用启动脚本
./start.sh  # Linux/Mac
start.bat   # Windows

# 方式2: 直接运行
go run cmd/server/main.go

首次启动:

  • 会自动执行数据库迁移AutoMigrate创建所有表结构
  • 如果对象存储未配置,会记录警告但服务仍可启动
  • 检查日志确认所有服务初始化成功

生产部署

# 构建二进制文件
go build -o carrotskin-server cmd/server/main.go

# 运行服务
./carrotskin-server

Docker部署

# 构建镜像
docker build -t carrotskin-backend:latest .

# 启动服务
docker-compose up -d

故障排查

常见问题

  1. 数据库连接失败

    • 检查 .env 中的数据库配置(DATABASE_HOST, DATABASE_PORT, DATABASE_USERNAME, DATABASE_PASSWORD, DATABASE_NAME
    • 确认PostgreSQL服务已启动
    • 验证数据库用户权限
    • 确认数据库已创建:createdb carrotskinpsql -c "CREATE DATABASE carrotskin;"
    • 检查数据库迁移日志,确认表结构创建成功
  2. Redis连接失败

    • 检查Redis服务是否运行redis-cli ping
    • 验证 .env 中的Redis配置
    • 确认Redis密码是否正确
    • 检查防火墙规则
  3. RustFS/MinIO连接失败

    • 检查存储服务是否运行
    • 验证访问密钥是否正确(RUSTFS_ACCESS_KEY, RUSTFS_SECRET_KEY
    • 确认存储桶是否已创建(RUSTFS_BUCKET_TEXTURES, RUSTFS_BUCKET_AVATARS
    • 检查网络连接和端口(RUSTFS_ENDPOINT
    • 注意: 如果对象存储连接失败,服务仍可启动,但上传功能不可用
  4. 邮件发送失败

    • 检查 EMAIL_ENABLED=true
    • 验证SMTP服务器地址和端口
    • 确认邮箱用户名和密码正确
    • 检查邮件服务商是否需要开启SMTP
    • 查看日志获取详细错误信息
  5. 验证码相关问题

    • 验证码过期10分钟有效期
    • 发送过于频繁1分钟限制
    • Redis存储失败检查Redis连接
    • 邮件未收到(检查垃圾邮件)
  6. JWT验证失败

    • 检查 JWT_SECRET 是否配置
    • 验证令牌是否过期默认168小时
    • 确认请求头中包含 Authorization: Bearer <token>
    • Token格式是否正确

调试技巧

  1. 查看日志
# 实时查看日志
tail -f logs/app.log

# 搜索错误日志
grep "ERROR" logs/app.log
  1. 测试Redis连接
redis-cli -h localhost -p 6379 -a your_password
> PING
> KEYS *
  1. 测试数据库连接
psql -h localhost -U postgres -d carrotskin
\dt  # 查看所有表
  1. 测试邮件配置
    • 使用Swagger文档测试 /api/v1/auth/send-code 接口
    • 检查邮件服务商是否限制发送频率

开发调试

启用详细日志:

# 在 .env 中设置
LOG_LEVEL=debug
SERVER_MODE=debug
Description
No description provided
Readme 962 KiB
Languages
Go 97.4%
Python 2.5%
Dockerfile 0.1%