Files
SproutGate/sproutgate-backend/后端文档.md

124 lines
7.0 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.
# SproutGate 后端文档
## 技术栈
- **语言**Go 1.20+
- **Web 框架**Gin跨域中间件 **`github.com/gin-contrib/cors`**
- **数据存储**MySQL通过 GORM + `gorm.io/driver/mysql`
- **JWT**`github.com/golang-jwt/jwt/v5`
- **密码哈希**`golang.org/x/crypto/bcrypt`
业务数据与配置均保存在 MySQL 中,**不再使用** `data/users/*.json``data/config/*.json` 作为运行时数据源。仓库中的 `data/` 仅可作迁移脚本输入或本地备份参考。
## 目录结构(要点)
| 路径 | 说明 |
|------|------|
| `main.go` | 入口:连接数据库、初始化 `Store`、注册路由 |
| `internal/database/` | MySQL 连接(`DB_DSN``DB_HOST`/`DB_USER`/`DB_PASSWORD`/`DB_NAME`/`DB_PORT`,支持 `.env` 本地加载) |
| `internal/handlers/` | HTTP 处理:认证、资料、签到、公开页、管理端等 |
| `internal/models/` | 领域模型(用户、待激活、重置密码、辅助邮箱等) |
| `internal/storage/` | 持久化:`Store` + GORM 模型与业务方法 |
| `internal/auth/` | JWT 签发与校验 |
| `internal/email/` | 发信 |
| `cmd/migrate/` | 一次性工具:将旧版 JSON `data/` 导入 MySQL |
## 环境与数据库
代码中**不再内置任何数据库地址或账号密码**,连接参数完全来自环境变量,连接字符串优先级:**`DB_DSN` > `DB_HOST`/`DB_PORT`/`DB_USER`/`DB_PASSWORD`/`DB_NAME`**。
1. **若设置 `DB_DSN`**:直接使用该完整 DSN适合 CI、容器或临时切换
2. **否则**:用 `DB_HOST`/`DB_USER`/`DB_PASSWORD` 拼接 DSN`DB_HOST`/`DB_USER`/`DB_PASSWORD` 三者缺一即报错退出;`DB_PORT` 默认 `3306``DB_NAME` 默认 `sproutgate`(开发、生产统一用这个库名,仅 host/账号不同)。
本地开发时,在 `sproutgate-backend/.env`(已在 `.gitignore` 中忽略,不会提交)里写:
```
DB_HOST=10.1.1.100
DB_PORT=3306
DB_USER=sproutgate-test
DB_PASSWORD=sproutgate-test
DB_NAME=sproutgate
```
`go run .` / `go run ./cmd/migrate` 启动时会自动从当前目录读取并加载 `.env`(已存在的环境变量不会被覆盖);生产部署通过容器/`docker-compose` 环境变量注入,不依赖 `.env` 文件。
其它常用环境变量:
| 变量 | 说明 | 默认 |
|------|------|------|
| `PORT` | HTTP 监听端口 | `8080` |
| `APP_ENV` | 仅影响 `/api/health` 返回的 `env` 字段,不再决定数据库选择 | 空则 health 中为 `development` |
| `GIN_MODE` | `release` 时 GORM 日志级别更安静(警告级) | debug 模式 |
| `DB_DSN` | 完整 MySQL DSN覆盖 `DB_HOST` 等单项配置 | 未设置 |
| `DB_HOST` / `DB_PORT` / `DB_USER` / `DB_PASSWORD` / `DB_NAME` | MySQL 连接参数;`DB_HOST`/`DB_USER`/`DB_PASSWORD` 必填,无内置默认值 | `DB_PORT=3306``DB_NAME=sproutgate` |
| `GEO_LOOKUP_URL` | `GET /api/auth/me` 未带 `X-Visit-Location` 时,服务端按 IP 请求该基址反查展示地理位置(实现见 `internal/clientgeo`,会拼接 `?ip=` | 默认 `https://cf-ip-geo.smyhub.com/api` |
**建议**:生产部署通过 `docker-compose.yml` 旁的 `.env`(同样被 `.gitignore` 忽略)注入 `DB_HOST`/`DB_USER`/`DB_PASSWORD`,不要把真实账号密码写进任何会提交到仓库的文件。
## 数据库表AutoMigrate
应用启动与 `migrate` 工具均会同步下列表结构GORM `AutoMigrate`
| 表名 | 用途 |
|------|------|
| `users` | 用户主数据;签到/访问时间列表、`auth_clients` 等以 JSON 文本列存储 |
| `pending_users` | 注册邮箱验证流程中的待激活用户 |
| `password_resets` | 忘记密码验证码 |
| `secondary_email_verifications` | 绑定辅助邮箱验证码 |
| `app_configs` | 键值配置:`admin``auth``email``checkin``registration`JSON |
| `invite_codes` | 注册邀请码 |
| `profile_likes` | 公开用户主页点赞明细(点赞者、被赞者、自然日等) |
| `profile_like_daily_quota` | 点赞者当日已用额度(与代码常量 `MaxProfileLikesPerDay` 配合) |
管理员令牌、JWT Secret、邮件 SMTP、签到奖励、是否强制邀请码等均从 `app_configs` / `invite_codes` 读写,首次无记录时由 `Store` 按逻辑补全默认项。
## 从旧 JSON 迁移到 MySQL
**`sproutgate-backend`** 目录下:
```bash
# 导入到 .env或当前环境变量指向的库
go run ./cmd/migrate --data-dir ./data
```
Windows PowerShell 示例(临时指定生产库连接参数):
```powershell
$env:DB_HOST = "192.168.1.100"
$env:DB_USER = "sproutgate"
$env:DB_PASSWORD = "<生产密码>"
go run ./cmd/migrate --data-dir ./data
Remove-Item Env:DB_HOST, Env:DB_USER, Env:DB_PASSWORD # 可选:清除变量,避免影响本机其它命令
```
迁移内容:`data/config/*.json`(写入 `app_configs``invite_codes`)、`data/users/*.json`(写入 `users`)。对已存在主键执行 **UPSERT**:同账号、同配置键会更新为迁移文件中的值。
## HTTP 路由速览
- **`GET /`**、**`GET /api`**API 简要说明 JSON`main.go` 内嵌字段,含 `version``routePrefixes` 等)。**当前未注册**单独返回 Markdown 的 `/api/docs` 路由;对外长文档见仓库根目录 **`萌芽账户认证中心-第三方应用API接入文档.md`**。
- **`GET /api/health`**`{ "status": "ok", "env": "<APP_ENV 或 development>" }`
- **`/api/auth/*`**:登录、注册、邮箱验证、忘记/重置密码、辅助邮箱、令牌校验、`/me`、签到、更新资料等;可选请求头 `X-Auth-Client``X-Auth-Client-Name`(记录第三方应用接入)。
- **`/api/public/*`**
- **`GET /api/public/users`**:公开用户目录(未封禁;默认按 `createdAt` 升序)。
- **`GET /api/public/users/:account`**:公开资料 + 累计赞数;若带合法 Bearer可附加「是否已赞今日」「当日剩余可点赞人数」等浏览者上下文。
- **`POST /api/public/users/:account/like`**:登录用户给指定主页点赞(不能赞自己;每人每主页每日一次;每自然日每名用户最多给 **5** 位不同用户点赞,常量见 `internal/storage/profile_likes.go`)。
- **`GET /api/public/registration-policy`**:是否强制邀请码等。
- **`/api/admin/*`**:需 **`X-Admin-Token`**(或 Query `token`):用户 CRUD、签到配置、注册策略与邀请码管理。
允许的 CORS 自定义头包含:`Authorization``X-Admin-Token``X-Visit-Ip``X-Visit-Location``X-Auth-Client``X-Auth-Client-Name` 等。
## 本地开发命令
```bash
cd sproutgate-backend
go mod tidy
go run .
```
默认监听 `:8080`。前端开发时请将 `VITE_API_BASE` 指向本服务(详见仓库根目录下 `sproutgate-frontend/前端文档.md`)。
## 安全提示
- 勿将生产 `DB_DSN`、SMTP 密码、真实 `admin` 令牌提交到版本库。
- 旧版 `data/config/email.json` 等若含真实口令,迁移后应以环境或运维密钥管理为准,并限制数据库与 SMTP 账号权限。