Files
backend/README.md
lafay b23a169925
All checks were successful
Build / build (push) Successful in 7m17s
Build / build-docker (push) Successful in 2m41s
chore: import 分组规范 + 文档同步 + config 修复
2026-06-15 16:52:20 +08:00

185 lines
8.3 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# CarrotSkin Backend
一个功能完善的 Minecraft 皮肤站后端,基于 Go + Gin 构建,覆盖用户认证、材质管理、角色档案、审计日志等核心能力,并提供完整的 Swagger 文档与容器友好的环境变量配置。
## ✨ 功能亮点
- **账号体系**:注册 / 登录 / JWT 鉴权 / Yggdrasil 密码同步 / 用户积分
- **邮箱与验证码**:验证码发送频率控制、邮箱绑定与变更
- **材质中心**:皮肤/披风上传、搜索、收藏、下载统计、Hash 去重
- **角色档案**Minecraft Profile 管理、RSA 密钥对生成、活跃档案切换
- **存储与上传**RustFS/MinIO 预签名 URL减轻服务器带宽压力
- **任务与日志**:登录日志、操作审计、材质下载记录、定时任务
- **权限体系**Casbin RBAC支持细粒度路线授权
- **配置管理**100% 依赖环境变量,`SERVER_SWAGGER_ENABLED` 控制 Swagger
- **可观测性**Zap 结构化日志、统一 API 响应模型
## 🛠 技术栈
| 类型 | 选型 |
| --- | --- |
| 语言 / 运行时 | Go 1.24+ |
| Web 框架 | Gin |
| ORM | GORM (PostgreSQL 驱动) |
| 数据库 | PostgreSQL 15+ |
| 缓存 / 消息 | Redis 6+ |
| 对象存储 | RustFS / MinIOS3 兼容) |
| 权限控制 | Casbin |
| 配置 | Viper + `.env` |
| API 文档 | swaggo / Swagger UI |
| 日志 | Uber Zap |
## 📁 目录结构
```
backend/
├── cmd/server/ # 应用入口main.go极简 fx 装配)
├── internal/
│ ├── app/ # uber-go/fx 装配层(唯一依赖注入入口)
│ │ ├── module.go # 聚合根 Module
│ │ ├── infra_module.go # Logger/DB/Redis/Storage/Email/JWT/Casbin + Lifecycle
│ │ ├── container_module.go # Container 聚合 + 路由/HTTP/任务生命周期
│ │ ├── repository_module.go # Repository Provider占位Container 模式暂未启用)
│ │ ├── service_module.go # Service Provider占位
│ │ ├── handler_module.go # Handler Provider占位
│ │ ├── server_module.go # HTTP 服务器模块(占位)
│ │ └── task_module.go # 后台任务模块(占位)
│ ├── container/ # 过渡期手动 DI 容器fx 迁移期的聚合层)
│ ├── handler/ # HTTP Handler 与 Swagger 注解
│ ├── service/ # 业务逻辑(接口 + 实现)
│ ├── repository/ # 数据访问(接口 + GORM 实现)
│ ├── model/ # GORM 数据模型与响应结构
│ ├── types/ # 请求/响应 DTO
│ ├── errors/ # 统一错误定义apperrors
│ ├── middleware/ # Gin 中间件
│ └── task/ # 定时任务与后台作业
├── pkg/ # 可复用组件config、database、auth、logger、redis、storage、email、utils
├── docs/ # swagger 生成产物docs.go / swagger.json / swagger.yaml
├── start.sh # 启动脚本(自动 swag init
├── docker-compose.yml # 本地容器编排
├── .env.example # 环境变量示例
└── go.mod # Go Module 定义
```
## ✅ 前置要求
- Go 1.24+
- PostgreSQL 15+
- Redis 6+
- RustFS / MinIO或其他兼容 S3 的对象存储,用于皮肤与头像)
## 🚀 快速开始
1. **克隆仓库**
```bash
git clone <repo>
cd backend
```
2. **安装依赖**
```bash
go mod download
```
3. **配置环境变量**
```bash
cp .env.example .env
# 根据实际环境填写数据库、Redis、对象存储、邮件等信息
```
4. **初始化数据库**
```bash
createdb carrotskin
# 或 psql -c "CREATE DATABASE carrotskin;"
```
> 应用启动时会执行 `AutoMigrate`,自动创建 / 更新表结构。
5. **启动服务**
- **推荐**`./start.sh`(自动 `swag init`,随后 `go run cmd/server/main.go`
- **手动启动**
```bash
swag init -g cmd/server/main.go -o docs
go run cmd/server/main.go
```
6. **访问接口**
- API Root: `http://localhost:8080`
- Swagger: `http://localhost:8080/swagger/index.html`(需 `SERVER_SWAGGER_ENABLED=true`
## ⚙️ 关键环境变量
| 变量 | 说明 | 示例 |
| --- | --- | --- |
| `SERVER_PORT` | 服务监听端口 | `8080` |
| `SERVER_MODE` | Gin 模式debug/release | `debug` |
| `SERVER_SWAGGER_ENABLED` | 是否暴露 Swagger UI | `true` |
| `DATABASE_HOST` / `DATABASE_PORT` | PostgreSQL 地址 | `localhost` / `5432` |
| `DATABASE_USERNAME` / `DATABASE_PASSWORD` | 数据库凭据 | `postgres` |
| `DATABASE_NAME` | 数据库名称 | `carrotskin` |
| `REDIS_HOST` / `REDIS_PORT` | Redis 地址 | `localhost` / `6379` |
| `REDIS_PASSWORD` | Redis 密码(无可为空) | `` |
| `RUSTFS_ENDPOINT` | RustFS/MinIO 访问地址 | `127.0.0.1:9000` |
| `RUSTFS_ACCESS_KEY` / `RUSTFS_SECRET_KEY` | 对象存储凭据 | `minioadmin` |
| `RUSTFS_BUCKET_TEXTURES` / `RUSTFS_BUCKET_AVATARS` | 存储桶名称 | `carrotskin-textures` |
| `JWT_SECRET` | JWT 签名密钥 | `change-me` |
| `EMAIL_ENABLED` | 是否开启邮件服务 | `true` |
| `EMAIL_SMTP_HOST` / `EMAIL_SMTP_PORT` | SMTP 配置 | `smtp.example.com` / `587` |
| `ENVIRONMENT` | 应用环境(用于 service 层 `IsTestEnvironment()` 短路) | `production` |
| `SECURITY_ALLOWED_ORIGINS` | CORS 允许的来源(逗号分隔) | `*` |
| `SECURITY_ALLOWED_DOMAINS` | 头像/材质 URL 允许的域名(逗号分隔) | `localhost,127.0.0.1` |
更多变量请参考 `.env.example` 与 `.env.docker.example`。
## 🧪 常用命令
```bash
# 运行单元测试
go test ./...
# 重新生成 swagger
swag init -g cmd/server/main.go -o docs
# 代码格式化 / 静态检查
gofmt -w .
golangci-lint run (若已安装)
```
## 🧱 架构说明
- **分层设计**Handler → Service → Repository → Model层次清晰、职责单一。
- Handler 不得直连 `*gorm.DB` 或 `*Repository`,必须通过 Service。
- Service 不得持有 `*gorm.DB`,所有数据访问通过 Repository 接口。
- **依赖注入uber-go/fx**
- `internal/app/` 是唯一的依赖装配入口。每个基础设施 / 仓储 / 服务作为 `fx.Provider` 注册。
- **生命周期管理**DB / Redis / Storage / Logger / HTTP Server / Task Runner 通过 `fx.Lifecycle` 的 `OnStart` / `OnStop` Hook 统一管理,彻底替代散落在 `main()` 的 `defer Close()` 链。
- **优雅关闭**`fx.New(app.Module(cfg)).Run()` 监听 `SIGINT` / `SIGTERM`,按依赖逆序触发 `OnStop`,先关 HTTP Server30s 超时),再关 Task Runner最后关 DB/Redis。
- **Dev/Test 自动回退**Redis 连接失败且环境为 `development` / `test` / `dev` / `USE_MINIREDIS=true` 时自动启用 `miniredis`。
- **启动时错误检查**:循环依赖、缺失 Provider、Provider 返回 error 全部在 `fx.New()` 阶段立即检测。
- **错误与响应统一**
- 错误统一在 `internal/errors/`(别名 `apperrors`),通过 `errors.Is/As` 匹配。
- 响应统一使用 `model.Response` / `model.PaginationResponse` / `model.NewErrorResponse`。
- Middleware 错误响应也走 `model.NewErrorResponse`,不再使用裸 `gin.H`。
- **配置优先级**`config.Load()` 读取 `.env` → 环境变量 → viper 默认值;`*config.Config` 由 `fx.Supply` 注入。
- **Swagger 注解**:所有 Handler、模型、DTO 均补齐 `@Summary` / `@Description` / `@Success`,可直接生成 OpenAPI 文档。
## 📝 Swagger 说明
- `start.sh` 会在启动前执行 `swag init -g cmd/server/main.go -o docs`
- 若手动运行,需要保证 `docs/` 下的 `docs.go`、`swagger.json`、`swagger.yaml` 与代码同步
- 通过 `SERVER_SWAGGER_ENABLED=false` 可在生产环境关闭 Swagger UI 暴露
## 🤝 贡献指南
1. Fork & Clone
2. 创建特性分支:`git checkout -b feature/xxx`
3. 编写代码并补全测试 / Swagger 注释
4. 提交时附上变更说明
## 📄 许可证
该项目未附带开源许可证,默认保留所有权利。若需对外使用,请先与作者确认协议。
---
如需了解业务细节或 API 调用示例,请参考 `docs/swagger.yaml` 或运行服务后访问 Swagger UI。祝编码愉快🍀