小清洗
This commit is contained in:
114
API测试指南.md
114
API测试指南.md
@@ -1,114 +0,0 @@
|
||||
# API连接测试指南
|
||||
|
||||
本指南将帮助您测试前端是否能够成功读取后端数据,以及验证登录和注册功能的实现状态。
|
||||
|
||||
## 登录和注册功能实现状态
|
||||
|
||||
根据代码分析,**登录和注册功能已经实现并连接到了真实的后端API**。系统采用了以下实现方式:
|
||||
|
||||
### 登录功能
|
||||
- 支持使用用户名或邮箱登录
|
||||
- 集成了NextAuth.js进行身份验证管理
|
||||
- 在测试环境中提供测试账号(用户名: `test`, 密码: `test`)
|
||||
- 非测试账号会调用真实的后端API进行认证:`https://code.littlelan.cn/CarrotSkin/APIgateway/api/v1/auth/login`
|
||||
- 包含验证码验证机制(非测试账号需要)
|
||||
|
||||
### 注册功能
|
||||
- 完整的表单验证逻辑(用户名、密码、邮箱、Minecraft用户名不能为空)
|
||||
- 密码强度检查(至少6位)
|
||||
- 邮箱格式验证
|
||||
- 验证码验证
|
||||
- 调用真实的后端注册API:`https://code.littlelan.cn/CarrotSkin/APIgateway/api/v1/auth/register`
|
||||
|
||||
## 如何测试后端数据连接
|
||||
|
||||
### 方法一:使用API测试页面
|
||||
|
||||
1. 访问 `http://localhost:3000/api-tester` 打开API测试工具(已修复)
|
||||
2. 点击"开始API测试"按钮
|
||||
3. 查看测试结果,了解各个API端点的连接状态
|
||||
|
||||
### 方法二:使用简化API测试页面
|
||||
|
||||
1. 访问 `http://localhost:3000/simple-api-test` 打开简化的API测试工具
|
||||
2. 选择要测试的API端点
|
||||
3. 输入必要的参数(如用户ID、角色ID等)
|
||||
4. 点击"测试API"按钮查看返回结果
|
||||
|
||||
### 方法三:使用浏览器控制台进行测试
|
||||
|
||||
打开浏览器开发者工具(F12),切换到控制台(Console)选项卡,执行以下代码:
|
||||
|
||||
```javascript
|
||||
// 测试材质列表API(无需登录)
|
||||
fetch('/api/textures')
|
||||
.then(response => response.json())
|
||||
.then(data => console.log('材质列表数据:', data))
|
||||
.catch(error => console.error('获取材质列表失败:', error));
|
||||
|
||||
// 如果已登录,可以测试需要认证的API
|
||||
// 测试用户角色列表
|
||||
fetch('/api/user-profiles?userId=1', { credentials: 'include' })
|
||||
.then(response => response.json())
|
||||
.then(data => console.log('用户角色列表数据:', data))
|
||||
.catch(error => console.error('获取用户角色列表失败:', error));
|
||||
```
|
||||
|
||||
## 测试登录功能
|
||||
|
||||
### 测试测试账号登录
|
||||
|
||||
1. 访问 `http://localhost:3000/login` 登录页面
|
||||
2. 输入用户名:`test`,密码:`test`
|
||||
3. 点击登录按钮
|
||||
4. 成功后会自动跳转到用户主页 `http://localhost:3000/user-home`
|
||||
|
||||
### 测试注册功能
|
||||
|
||||
1. 访问 `http://localhost:3000/register` 注册页面
|
||||
2. 填写完整的注册信息:
|
||||
- 用户名:自定义
|
||||
- 密码:至少6位
|
||||
- 邮箱:有效的邮箱地址
|
||||
- Minecraft用户名:自定义
|
||||
3. 点击获取验证码,输入收到的验证码
|
||||
4. 点击注册按钮
|
||||
5. 成功后会提示注册成功并自动跳转到登录页面
|
||||
|
||||
## 常见问题排查
|
||||
|
||||
1. **API请求失败**
|
||||
- 检查网络连接是否正常
|
||||
- 确认后端服务器是否正在运行
|
||||
- 查看浏览器控制台是否有错误信息
|
||||
- 检查API端点URL是否正确
|
||||
|
||||
2. **登录失败**
|
||||
- 确认用户名和密码是否正确
|
||||
- 检查验证码是否输入正确
|
||||
- 查看是否有网络错误提示
|
||||
|
||||
3. **注册失败**
|
||||
- 确认所有必填项都已填写
|
||||
- 检查密码是否满足长度要求
|
||||
- 确认邮箱格式是否正确
|
||||
- 检查用户名或邮箱是否已被注册
|
||||
|
||||
## 高级测试技巧
|
||||
|
||||
### 查看API请求详情
|
||||
|
||||
1. 打开浏览器开发者工具(F12)
|
||||
2. 切换到网络(Network)选项卡
|
||||
3. 刷新页面或执行API操作
|
||||
4. 查看请求和响应详情,包括状态码、请求头、响应内容等
|
||||
|
||||
### 测试特定API端点
|
||||
|
||||
使用API测试页面,您可以测试以下主要端点:
|
||||
- **材质列表**: `/api/textures` - 获取所有材质数据(无需登录)
|
||||
- **用户角色列表**: `/api/user-profiles?userId={id}` - 获取指定用户的角色列表(需要登录)
|
||||
- **角色详情**: `/api/profile?profileId={id}` - 获取指定角色的详细信息(需要登录)
|
||||
- **角色及属性**: `/api/profile-props?profileId={id}` - 获取指定角色及其属性(需要登录)
|
||||
|
||||
通过以上测试方法,您可以全面验证前端与后端的连接状态和数据读取能力。
|
||||
41
API连接说明.md
41
API连接说明.md
@@ -1,41 +0,0 @@
|
||||
# API后端连接说明
|
||||
|
||||
## 配置已完成
|
||||
|
||||
✅ 已将前端项目配置为连接到您提供的API后端服务:
|
||||
- **API后端地址**: `https://code.littlelan.cn/CarrotSkin/APIgateway`
|
||||
|
||||
## 配置详情
|
||||
|
||||
环境变量已在 `.env.local` 文件中更新:
|
||||
```
|
||||
NEXT_PUBLIC_API_URL=https://code.littlelan.cn/CarrotSkin/APIgateway
|
||||
```
|
||||
|
||||
## 如何测试连接
|
||||
|
||||
1. 确保开发服务器正在运行:
|
||||
```bash
|
||||
npm run dev
|
||||
```
|
||||
|
||||
2. 访问应用并尝试登录或上传皮肤等功能,系统将自动连接到配置的API后端。
|
||||
|
||||
3. 前端项目中的主要API调用位于:
|
||||
- `src/lib/api/actions.ts` - 包含登录、注册等用户操作
|
||||
- `src/lib/api/auth.ts` - 包含认证相关配置
|
||||
|
||||
## 注意事项
|
||||
|
||||
- **CORS配置**: 请确保您的API后端已正确配置CORS,允许来自前端域名的请求
|
||||
- **API路径映射**: 前端默认会在API URL后添加相应端点,例如登录API路径为 `/auth/login`
|
||||
- **环境变量**: `.env.local` 文件不会被Git跟踪,如需在其他环境部署,请确保复制此配置
|
||||
- **开发调试**: 您可以在浏览器控制台查看API调用情况,以便调试连接问题
|
||||
|
||||
## 测试账号
|
||||
|
||||
前端项目内置了测试账号功能(用于开发环境):
|
||||
- 用户名: `test`
|
||||
- 密码: `test`
|
||||
|
||||
如果您希望禁用测试账号功能,请修改 `src/lib/api/actions.ts` 和 `src/lib/api/auth.ts` 文件中的相关代码。
|
||||
@@ -1,440 +0,0 @@
|
||||
# CarrotSkin Backend
|
||||
|
||||
一个功能完善的Minecraft皮肤站后端系统,采用单体架构设计,基于Go语言和Gin框架开发。
|
||||
|
||||
## ✨ 核心功能
|
||||
|
||||
- ✅ **用户认证系统** - 注册、登录、JWT认证、积分系统
|
||||
- ✅ **邮箱验证系统** - 注册验证、找回密码、更换邮箱(基于Redis的验证码)
|
||||
- ✅ **材质管理系统** - 皮肤/披风上传、搜索、收藏、下载统计
|
||||
- ✅ **角色档案系统** - Minecraft角色创建、管理、RSA密钥生成
|
||||
- ✅ **文件存储** - MinIO/RustFS对象存储集成、预签名URL上传
|
||||
- ✅ **缓存系统** - Redis缓存、验证码存储、频率限制
|
||||
- ✅ **权限管理** - Casbin RBAC权限控制
|
||||
- ✅ **数据审计** - 登录日志、操作审计、下载记录
|
||||
|
||||
## 项目结构
|
||||
|
||||
```
|
||||
backend/
|
||||
├── cmd/ # 应用程序入口
|
||||
│ └── server/ # 主服务器
|
||||
├── internal/ # 私有应用代码
|
||||
│ ├── handler/ # HTTP处理器
|
||||
│ ├── service/ # 业务逻辑服务
|
||||
│ ├── model/ # 数据模型
|
||||
│ ├── repository/ # 数据访问层
|
||||
│ ├── middleware/ # 中间件
|
||||
│ └── types/ # 类型定义
|
||||
├── pkg/ # 公共库代码
|
||||
│ ├── auth/ # 认证授权
|
||||
│ ├── config/ # 配置管理
|
||||
│ ├── database/ # 数据库连接
|
||||
│ ├── email/ # 邮件服务
|
||||
│ ├── logger/ # 日志系统
|
||||
│ ├── redis/ # Redis客户端
|
||||
│ ├── storage/ # 文件存储(RustFS/MinIO)
|
||||
│ ├── utils/ # 工具函数
|
||||
│ └── validator/ # 数据验证
|
||||
├── docs/ # API定义和文档
|
||||
├── configs/ # 配置文件
|
||||
│ ├── casbin/ # Casbin权限配置
|
||||
├── scripts/ # 脚本文件
|
||||
│ ├── carrotskin.sql # 数据库初始化
|
||||
├── go.mod # Go模块依赖
|
||||
├── go.sum # Go模块校验
|
||||
├── run.bat # Windows启动脚本
|
||||
├── .env # 环境变量配置
|
||||
└── README.md # 项目说明
|
||||
```
|
||||
|
||||
## 技术栈
|
||||
|
||||
- **语言**: Go 1.21+
|
||||
- **框架**: Gin Web Framework
|
||||
- **数据库**: PostgreSQL 15+
|
||||
- **缓存**: Redis 6.0+
|
||||
- **存储**: RustFS (S3兼容对象存储)
|
||||
- **权限**: Casbin RBAC
|
||||
- **日志**: Zap
|
||||
- **配置**: 环境变量 (.env)
|
||||
- **文档**: Swagger/OpenAPI 3.0
|
||||
|
||||
## 快速开始
|
||||
|
||||
### 环境要求
|
||||
|
||||
- Go 1.21或更高版本
|
||||
- PostgreSQL 15或更高版本
|
||||
- Redis 6.0或更高版本
|
||||
- RustFS 或其他 S3 兼容对象存储服务
|
||||
|
||||
### 安装和运行
|
||||
|
||||
1. **克隆项目**
|
||||
```bash
|
||||
git clone <repository-url>
|
||||
cd CarrotSkin/backend
|
||||
```
|
||||
|
||||
2. **安装依赖**
|
||||
```bash
|
||||
go mod download
|
||||
```
|
||||
|
||||
3. **配置环境**
|
||||
```bash
|
||||
# 复制环境变量文件
|
||||
cp .env.example .env
|
||||
# 编辑 .env 文件配置数据库、RustFS等服务连接信息
|
||||
```
|
||||
|
||||
**注意**:项目完全依赖 `.env` 文件进行配置,不再使用 YAML 配置文件,便于 Docker 容器化部署。
|
||||
|
||||
4. **初始化数据库**
|
||||
```bash
|
||||
# 创建数据库
|
||||
createdb carrotskin
|
||||
# 初始化表结构
|
||||
psql -d carrotskin -f scripts/carrotskin_postgres.sql
|
||||
```
|
||||
|
||||
5. **运行服务**
|
||||
|
||||
Windows系统:
|
||||
```bash
|
||||
run.bat
|
||||
```
|
||||
|
||||
Linux/Mac系统:
|
||||
```bash
|
||||
chmod +x run.sh
|
||||
./run.sh
|
||||
```
|
||||
|
||||
> 💡 **提示**: 启动脚本会自动检查并安装 `swag` 工具,然后生成Swagger API文档,最后启动服务器。
|
||||
|
||||
服务启动后:
|
||||
- **服务地址**: http://localhost:8080
|
||||
- **Swagger文档**: http://localhost:8080/swagger/index.html
|
||||
- **健康检查**: http://localhost:8080/health
|
||||
|
||||
## 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. **容器部署**: 直接在容器运行时设置环境变量即可
|
||||
|
||||
**主要环境变量**:
|
||||
```bash
|
||||
# 数据库配置
|
||||
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` 文件。
|
||||
|
||||
## 架构设计
|
||||
|
||||
### 三层架构
|
||||
|
||||
项目采用标准的三层架构设计,职责清晰,便于维护:
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────┐
|
||||
│ Handler 层 (HTTP) │ ← 路由、参数验证、响应格式化
|
||||
├─────────────────────────────────────┤
|
||||
│ Service 层 (业务逻辑) │ ← 业务规则、权限检查、数据验证
|
||||
├─────────────────────────────────────┤
|
||||
│ Repository 层 (数据访问) │ ← 数据库操作、关联查询
|
||||
├──────────────┬──────────────────────┤
|
||||
│ PostgreSQL │ Redis │ RustFS │ ← 数据存储层
|
||||
└──────────────┴──────────────────────┘
|
||||
```
|
||||
|
||||
### 核心模块
|
||||
|
||||
1. **认证模块** (`internal/handler/auth_handler.go`)
|
||||
- JWT令牌生成和验证
|
||||
- bcrypt密码加密
|
||||
- 邮箱验证码注册
|
||||
- 密码重置功能
|
||||
- 登录日志记录(支持用户名/邮箱登录)
|
||||
|
||||
2. **用户模块** (`internal/handler/user_handler.go`)
|
||||
- 用户信息管理
|
||||
- 头像上传(预签名URL)
|
||||
- 密码修改(需原密码验证)
|
||||
- 邮箱更换(需验证码)
|
||||
- 积分系统
|
||||
|
||||
3. **邮箱验证模块** (`internal/service/verification_service.go`)
|
||||
- 验证码生成(6位数字)
|
||||
- 验证码存储(Redis,10分钟有效期)
|
||||
- 发送频率限制(1分钟)
|
||||
- 邮件发送(HTML格式)
|
||||
|
||||
4. **材质模块** (`internal/handler/texture_handler.go`)
|
||||
- 材质上传(预签名URL)
|
||||
- 材质搜索和收藏
|
||||
- Hash去重
|
||||
- 下载统计
|
||||
|
||||
5. **档案模块** (`internal/handler/profile_handler.go`)
|
||||
- Minecraft角色管理
|
||||
- RSA密钥生成(RSA-2048)
|
||||
- 活跃状态管理
|
||||
- 档案数量限制
|
||||
|
||||
### 技术特性
|
||||
|
||||
- **安全性**:
|
||||
- bcrypt密码加密、JWT令牌认证
|
||||
- 邮箱验证码(注册/重置密码/更换邮箱)
|
||||
- Casbin RBAC权限控制
|
||||
- 频率限制(防暴力破解)
|
||||
|
||||
- **性能**:
|
||||
- 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. **错误处理**: 使用统一的错误响应格式 (`model.NewErrorResponse`)
|
||||
3. **日志记录**: 使用 Zap 结构化日志,包含关键字段
|
||||
4. **依赖注入**: Repository → Service → Handler 的依赖链
|
||||
5. **RESTful API**: 遵循 REST 设计原则,合理使用HTTP方法
|
||||
|
||||
### 添加新功能
|
||||
|
||||
1. 在 `internal/model/` 定义数据模型
|
||||
2. 在 `internal/repository/` 实现数据访问
|
||||
3. 在 `internal/service/` 实现业务逻辑
|
||||
4. 在 `internal/handler/` 实现HTTP处理
|
||||
5. 在 `internal/handler/routes.go` 注册路由
|
||||
|
||||
## 部署
|
||||
|
||||
### 本地开发
|
||||
|
||||
```bash
|
||||
# 安装依赖
|
||||
go mod download
|
||||
|
||||
# 启动服务 (Windows)
|
||||
run.bat
|
||||
|
||||
# 启动服务 (Linux/Mac)
|
||||
go run cmd/server/main.go
|
||||
```
|
||||
|
||||
### 生产部署
|
||||
|
||||
```bash
|
||||
# 构建二进制文件
|
||||
go build -o carrotskin-server cmd/server/main.go
|
||||
|
||||
# 运行服务
|
||||
./carrotskin-server
|
||||
```
|
||||
|
||||
### Docker部署
|
||||
|
||||
```bash
|
||||
# 构建镜像
|
||||
docker build -t carrotskin-backend:latest .
|
||||
|
||||
# 启动服务
|
||||
docker-compose up -d
|
||||
```
|
||||
|
||||
## 故障排查
|
||||
|
||||
### 常见问题
|
||||
|
||||
1. **数据库连接失败**
|
||||
- 检查 `.env` 中的数据库配置
|
||||
- 确认PostgreSQL服务已启动
|
||||
- 验证数据库用户权限
|
||||
- 确认数据库已创建:`createdb carrotskin`
|
||||
|
||||
2. **Redis连接失败**
|
||||
- 检查Redis服务是否运行:`redis-cli ping`
|
||||
- 验证 `.env` 中的Redis配置
|
||||
- 确认Redis密码是否正确
|
||||
- 检查防火墙规则
|
||||
|
||||
3. **RustFS/MinIO连接失败**
|
||||
- 检查存储服务是否运行
|
||||
- 验证访问密钥是否正确
|
||||
- 确认存储桶是否已创建
|
||||
- 检查网络连接和端口
|
||||
|
||||
4. **邮件发送失败**
|
||||
- 检查 `EMAIL_ENABLED=true`
|
||||
- 验证SMTP服务器地址和端口
|
||||
- 确认邮箱用户名和密码正确
|
||||
- 检查邮件服务商是否需要开启SMTP
|
||||
- 查看日志获取详细错误信息
|
||||
|
||||
5. **验证码相关问题**
|
||||
- 验证码过期(10分钟有效期)
|
||||
- 发送过于频繁(1分钟限制)
|
||||
- Redis存储失败(检查Redis连接)
|
||||
- 邮件未收到(检查垃圾邮件)
|
||||
|
||||
6. **JWT验证失败**
|
||||
- 检查 `JWT_SECRET` 是否配置
|
||||
- 验证令牌是否过期(默认168小时)
|
||||
- 确认请求头中包含 `Authorization: Bearer <token>`
|
||||
- Token格式是否正确
|
||||
|
||||
### 调试技巧
|
||||
|
||||
1. **查看日志**
|
||||
```bash
|
||||
# 实时查看日志
|
||||
tail -f logs/app.log
|
||||
|
||||
# 搜索错误日志
|
||||
grep "ERROR" logs/app.log
|
||||
```
|
||||
|
||||
2. **测试Redis连接**
|
||||
```bash
|
||||
redis-cli -h localhost -p 6379 -a your_password
|
||||
> PING
|
||||
> KEYS *
|
||||
```
|
||||
|
||||
3. **测试数据库连接**
|
||||
```bash
|
||||
psql -h localhost -U postgres -d carrotskin
|
||||
\dt # 查看所有表
|
||||
```
|
||||
|
||||
4. **测试邮件配置**
|
||||
- 使用Swagger文档测试 `/api/v1/auth/send-code` 接口
|
||||
- 检查邮件服务商是否限制发送频率
|
||||
|
||||
### 开发调试
|
||||
|
||||
启用详细日志:
|
||||
```bash
|
||||
# 在 .env 中设置
|
||||
LOG_LEVEL=debug
|
||||
SERVER_MODE=debug
|
||||
```
|
||||
@@ -1,291 +0,0 @@
|
||||
# ProfileService - 角色管理服务
|
||||
|
||||
ProfileService是CarrotSkin皮肤站的角色管理微服务,负责处理Minecraft角色的创建、管理、RSA密钥生成和签名验证等核心功能。
|
||||
|
||||
## 📋 目录
|
||||
|
||||
- [功能特性](#功能特性)
|
||||
- [技术架构](#技术架构)
|
||||
- [数据模型](#数据模型)
|
||||
- [API接口](#api接口)
|
||||
- [部署指南](#部署指南)
|
||||
- [开发指南](#开发指南)
|
||||
- [故障排查](#故障排查)
|
||||
|
||||
## 🚀 功能特性
|
||||
|
||||
### 核心功能
|
||||
- **角色管理**: 创建、查询、更新、删除Minecraft角色
|
||||
- **RSA密钥管理**: 自动生成RSA-2048密钥对,支持数据签名和验证
|
||||
- **皮肤/披风关联**: 管理角色与皮肤、披风的关联关系
|
||||
- **用户角色列表**: 支持查询用户下的所有角色
|
||||
- **数据验证**: 完整的参数验证和业务逻辑检查
|
||||
|
||||
### 安全特性
|
||||
- **RSA签名**: 支持使用私钥对数据进行签名
|
||||
- **签名验证**: 支持使用公钥验证数据签名
|
||||
- **权限控制**: 确保用户只能操作自己的角色
|
||||
- **数据完整性**: 完整的事务处理和数据一致性保证
|
||||
|
||||
## 🏗️ 技术架构
|
||||
|
||||
### 技术栈
|
||||
- **框架**: go-zero微服务框架
|
||||
- **数据库**: MySQL 8.0+
|
||||
- **缓存**: Redis (通过go-zero集成)
|
||||
- **通信协议**: gRPC
|
||||
- **密钥算法**: RSA-2048
|
||||
|
||||
### 服务架构
|
||||
```
|
||||
ProfileService
|
||||
├── internal/
|
||||
│ ├── config/ # 配置管理
|
||||
│ ├── handler/ # gRPC处理器
|
||||
│ ├── logic/ # 业务逻辑层
|
||||
│ ├── model/ # 数据模型层
|
||||
│ └── svc/ # 服务上下文
|
||||
├── pb/ # Protocol Buffers定义
|
||||
└── docs/ # 文档和SQL脚本
|
||||
```
|
||||
|
||||
## 📊 数据模型
|
||||
|
||||
### 数据库表结构
|
||||
|
||||
```sql
|
||||
CREATE TABLE `profiles` (
|
||||
`uuid` VARCHAR(36) NOT NULL COMMENT '角色的UUID,通常为Minecraft玩家的UUID',
|
||||
`user_id` BIGINT UNSIGNED NOT NULL COMMENT '关联的用户ID',
|
||||
`name` VARCHAR(16) NOT NULL COMMENT '角色名 (Minecraft In-Game Name)',
|
||||
`skin_id` BIGINT UNSIGNED NULL DEFAULT NULL COMMENT '当前使用的皮肤ID',
|
||||
`cape_id` BIGINT UNSIGNED NULL DEFAULT NULL COMMENT '当前使用的披风ID',
|
||||
`rsa_private_key` TEXT NOT NULL COMMENT 'RSA-2048私钥 (PEM格式)',
|
||||
`created_at` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
`updated_at` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
PRIMARY KEY (`uuid`),
|
||||
INDEX `idx_user_id` (`user_id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
```
|
||||
|
||||
### 数据类型映射
|
||||
|
||||
| 字段 | SQL类型 | Go Model类型 | Proto类型 | 说明 |
|
||||
|------|---------|-------------|-----------|------|
|
||||
| uuid | VARCHAR(36) | string | string | 角色UUID |
|
||||
| user_id | BIGINT UNSIGNED | uint64 | int64 | 用户ID |
|
||||
| name | VARCHAR(16) | string | string | 角色名 |
|
||||
| skin_id | BIGINT UNSIGNED NULL | sql.NullInt64 | int64 | 皮肤ID (0表示无皮肤) |
|
||||
| cape_id | BIGINT UNSIGNED NULL | sql.NullInt64 | int64 | 披风ID (0表示无披风) |
|
||||
| rsa_private_key | TEXT | string | string | RSA私钥 |
|
||||
| created_at | TIMESTAMP | time.Time | string | 创建时间 |
|
||||
| updated_at | TIMESTAMP | time.Time | string | 更新时间 |
|
||||
|
||||
## 🔌 API接口
|
||||
|
||||
### 对外接口 (Public APIs)
|
||||
|
||||
#### 1. CreateProfile - 创建角色
|
||||
```protobuf
|
||||
rpc CreateProfile(CreateProfileRequest) returns (CreateProfileResponse);
|
||||
```
|
||||
- **功能**: 创建新的Minecraft角色
|
||||
- **验证**: UUID格式、角色名格式、用户权限
|
||||
- **特性**: 自动生成RSA密钥对、角色名去重检查
|
||||
|
||||
#### 2. GetProfile - 获取角色信息
|
||||
```protobuf
|
||||
rpc GetProfile(GetProfileRequest) returns (GetProfileResponse);
|
||||
```
|
||||
- **功能**: 根据UUID获取角色基本信息
|
||||
- **返回**: 不包含私钥的公开信息
|
||||
|
||||
#### 3. GetProfilesByUserId - 获取用户角色列表
|
||||
```protobuf
|
||||
rpc GetProfilesByUserId(GetProfilesByUserIdRequest) returns (GetProfilesByUserIdResponse);
|
||||
```
|
||||
- **功能**: 获取指定用户的所有角色列表
|
||||
- **特性**: 支持空结果返回
|
||||
|
||||
#### 4. UpdateProfile - 更新角色信息
|
||||
```protobuf
|
||||
rpc UpdateProfile(UpdateProfileRequest) returns (UpdateProfileResponse);
|
||||
```
|
||||
- **功能**: 更新角色名、皮肤ID、披风ID
|
||||
- **验证**: 角色名重复检查、权限验证
|
||||
- **特性**: 支持NULL值处理 (0表示移除)
|
||||
|
||||
#### 5. DeleteProfile - 删除角色
|
||||
```protobuf
|
||||
rpc DeleteProfile(DeleteProfileRequest) returns (DeleteProfileResponse);
|
||||
```
|
||||
- **功能**: 删除指定角色
|
||||
- **验证**: 权限检查
|
||||
|
||||
#### 6. GetProfilePublicKey - 获取角色公钥
|
||||
```protobuf
|
||||
rpc GetProfilePublicKey(GetProfilePublicKeyRequest) returns (GetProfilePublicKeyResponse);
|
||||
```
|
||||
- **功能**: 获取角色的RSA公钥
|
||||
- **用途**: 用于验证角色签名
|
||||
|
||||
#### 7. VerifyProfileSignature - 验证角色签名
|
||||
```protobuf
|
||||
rpc VerifyProfileSignature(VerifyProfileSignatureRequest) returns (VerifyProfileSignatureResponse);
|
||||
```
|
||||
- **功能**: 验证使用角色私钥生成的签名
|
||||
- **算法**: RSA-2048 + SHA-256
|
||||
|
||||
#### 8. GetProfileWithProperties - 查询角色属性
|
||||
```protobuf
|
||||
rpc GetProfileWithProperties(GetProfileWithPropertiesRequest) returns (GetProfileWithPropertiesResponse);
|
||||
```
|
||||
- **功能**: 查询角色完整信息,包含Minecraft协议兼容的属性和签名
|
||||
- **用途**: 用于游戏客户端获取皮肤、披风等信息
|
||||
- **特性**: 支持生成带签名和不带签名的属性
|
||||
|
||||
#### 9. GetProfilesByNames - 批量查询角色
|
||||
```protobuf
|
||||
rpc GetProfilesByNames(GetProfilesByNamesRequest) returns (GetProfilesByNamesResponse);
|
||||
```
|
||||
- **功能**: 根据角色名称列表批量查询角色信息
|
||||
- **返回**: 简化的角色信息列表(UUID和名称)
|
||||
|
||||
#### 10. GetUserIdByProfileName - 根据角色名获取用户ID
|
||||
```protobuf
|
||||
rpc GetUserIdByProfileName(GetUserIdByProfileNameRequest) returns (GetUserIdByProfileNameResponse);
|
||||
```
|
||||
- **功能**: 根据角色名称查找关联的用户ID
|
||||
- **用途**: 支持使用角色名进行登录等操作
|
||||
|
||||
### 对内接口 (Internal APIs)
|
||||
|
||||
#### 11. GetProfileInternalInfo - 获取角色内部信息
|
||||
```protobuf
|
||||
rpc GetProfileInternalInfo(GetProfileInternalInfoRequest) returns (ProfileInternalInfo);
|
||||
```
|
||||
- **功能**: 获取包含私钥的完整角色信息
|
||||
- **权限**: 仅供内部微服务调用
|
||||
- **安全**: 包含敏感信息,需要严格权限控制
|
||||
|
||||
#### 12. SignData - 使用私钥签名数据
|
||||
```protobuf
|
||||
rpc SignData(SignDataRequest) returns (SignDataResponse);
|
||||
```
|
||||
- **功能**: 使用角色私钥对数据进行签名
|
||||
- **算法**: RSA-2048 + SHA-256
|
||||
- **返回**: Base64编码的签名结果
|
||||
|
||||
## 🚀 部署指南
|
||||
|
||||
### 环境要求
|
||||
- Go 1.19+
|
||||
- MySQL 8.0+
|
||||
- Redis 6.0+
|
||||
|
||||
### 配置文件示例
|
||||
|
||||
```yaml
|
||||
# etc/profile.yaml
|
||||
Name: profile.rpc
|
||||
ListenOn: 0.0.0.0:8082
|
||||
|
||||
#Etcd:
|
||||
# Hosts:
|
||||
# - 127.0.0.1:2379
|
||||
# Key: profile.rpc
|
||||
|
||||
DataSource: root:password@tcp(localhost:3306)/carrot_skin?charset=utf8mb4&parseTime=true&loc=Asia%2FShanghai
|
||||
|
||||
CacheConf:
|
||||
- Host: 127.0.0.1:6379
|
||||
Pass: ""
|
||||
Type: node
|
||||
```
|
||||
|
||||
### 部署步骤
|
||||
|
||||
1. **数据库初始化**
|
||||
```bash
|
||||
mysql -u root -p carrot_skin < docs/profiles.sql
|
||||
```
|
||||
|
||||
2. **编译服务**
|
||||
```bash
|
||||
go build -o profile-service .
|
||||
```
|
||||
|
||||
3. **启动服务**
|
||||
```bash
|
||||
./profile-service -f etc/profile.yaml
|
||||
```
|
||||
|
||||
## 🛠️ 开发指南
|
||||
|
||||
### 代码生成
|
||||
|
||||
使用提供的脚本重新生成代码:
|
||||
|
||||
```bash
|
||||
# Windows
|
||||
generate.bat
|
||||
|
||||
# Linux/Mac
|
||||
chmod +x generate.sh
|
||||
./generate.sh
|
||||
```
|
||||
|
||||
### 业务逻辑扩展
|
||||
|
||||
所有业务逻辑都在 `internal/logic/` 目录下:
|
||||
|
||||
- `createProfileLogic.go` - 角色创建逻辑
|
||||
- `getProfileLogic.go` - 角色查询逻辑
|
||||
- `updateProfileLogic.go` - 角色更新逻辑
|
||||
- `deleteProfileLogic.go` - 角色删除逻辑
|
||||
- 等等...
|
||||
|
||||
### 数据模型扩展
|
||||
|
||||
如需添加新的数据库方法,在 `internal/model/profilesmodel.go` 中扩展:
|
||||
|
||||
```go
|
||||
type ProfilesModel interface {
|
||||
profilesModel
|
||||
// 添加自定义方法
|
||||
FindByUserId(ctx context.Context, userId uint64) ([]*Profiles, error)
|
||||
}
|
||||
```
|
||||
|
||||
## 🔧 故障排查
|
||||
|
||||
### 常见问题
|
||||
|
||||
#### 1. 数据类型转换错误
|
||||
**问题**: `sql.NullInt64` 类型处理错误
|
||||
**解决**: 使用 `nullInt64ToValue()` 函数进行正确转换
|
||||
|
||||
#### 2. RSA密钥生成失败
|
||||
**问题**: RSA密钥生成或解析失败
|
||||
**解决**: 检查系统随机数生成器,确保有足够的熵
|
||||
|
||||
#### 3. 角色名重复
|
||||
**问题**: 同一用户下角色名重复
|
||||
**解决**: 创建和更新时都会进行重复检查
|
||||
|
||||
#### 4. UUID格式错误
|
||||
**问题**: UUID格式不符合标准
|
||||
**解决**: 确保UUID为36位标准格式 (xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx)
|
||||
|
||||
### 日志级别
|
||||
|
||||
- **INFO**: 正常业务操作
|
||||
- **ERROR**: 业务错误和系统错误
|
||||
- **DEBUG**: 详细的调试信息
|
||||
|
||||
### 性能监控
|
||||
|
||||
- 数据库连接池状态
|
||||
- Redis缓存命中率
|
||||
- gRPC请求响应时间
|
||||
- RSA密钥操作耗时
|
||||
@@ -1,319 +0,0 @@
|
||||
# 皮肤服务 (SkinService)
|
||||
|
||||
此项目是一个使用 **Go-zero** 框架构建的、专注于材质管理的纯 RPC 微服务。它为CarrotSkin皮肤站提供了完整的材质上传、存储、查询和管理功能,并集成了基于 MinIO 的高效文件存储系统。
|
||||
|
||||
## 核心功能
|
||||
|
||||
- **安全材质上传**: 利用 MinIO 预签名 POST URL,实现客户端直传,支持PNG格式限制和文件大小控制(1KB-1MB)
|
||||
- **智能去重机制**: 基于 SHA-256 哈希值自动检测并复用相同材质,节省存储空间
|
||||
- **完整材质管理**: 提供材质的增、删、改、查(CRUD)等全套操作
|
||||
- **分类存储**: 支持皮肤(SKIN)和披风(CAPE)两种材质类型的分类管理
|
||||
- **个人皮肤库**: 用户可查看和管理自己上传的所有材质
|
||||
- **皮肤广场**: 公开材质展示平台,支持按类型浏览和搜索
|
||||
- **收藏夹功能**: 支持用户收藏和管理自己的收藏列表
|
||||
- **高性能查询**: 支持分页查询、批量获取和条件搜索
|
||||
- **权限控制**: 严格的材质所有权验证,确保用户只能操作自己的材质
|
||||
|
||||
## 技术特性
|
||||
|
||||
- **微服务架构**: 基于 gRPC 的高性能服务间通信
|
||||
- **对象存储**: MinIO 分布式存储,支持海量文件管理
|
||||
- **数据库缓存**: go-zero 内置缓存机制,提升查询性能
|
||||
- **类型安全**: 完整的 protobuf 定义和数据验证
|
||||
- **容错设计**: 优雅的错误处理和日志记录
|
||||
- **代码生成**: 使用 `goctl` 从 `.proto` 和 `.sql` 文件自动生成代码
|
||||
|
||||
## API 接口参考
|
||||
|
||||
服务通过 gRPC 暴露,接口定义于 `docs/textures.proto`。
|
||||
|
||||
### 材质上传流程
|
||||
|
||||
| 方法名 | 功能描述 | 请求类型 | 响应类型 |
|
||||
|--------|----------|----------|----------|
|
||||
| `GenerateTextureUploadURL` | 生成材质上传预签名URL | `GenerateTextureUploadURLRequest` | `GenerateTextureUploadURLResponse` |
|
||||
| `CreateTexture` | 创建材质记录(上传完成后调用) | `CreateTextureRequest` | `CreateTextureResponse` |
|
||||
|
||||
**上传流程说明**:
|
||||
1. 客户端调用 `GenerateTextureUploadURL` 获取预签名上传URL和表单数据
|
||||
2. 客户端使用返回的 `post_url` 和 `form_data` 直接向MinIO上传文件
|
||||
3. 上传成功后,客户端调用 `CreateTexture` 将材质信息记录到数据库
|
||||
|
||||
### 材质管理接口
|
||||
|
||||
| 方法名 | 功能描述 | 请求类型 | 响应类型 |
|
||||
|--------|----------|----------|----------|
|
||||
| `GetTexture` | 获取单个材质信息 | `GetTextureRequest` | `GetTextureResponse` |
|
||||
| `UpdateTexture` | 更新材质信息(公开/私有状态) | `UpdateTextureRequest` | `UpdateTextureResponse` |
|
||||
| `DeleteTexture` | 删除材质(含MinIO文件清理) | `DeleteTextureRequest` | `DeleteTextureResponse` |
|
||||
|
||||
### 查询接口
|
||||
|
||||
| 方法名 | 功能描述 | 请求类型 | 响应类型 |
|
||||
|--------|----------|----------|----------|
|
||||
| `GetUserTextures` | 获取用户个人材质库 | `GetUserTexturesRequest` | `GetUserTexturesResponse` |
|
||||
| `GetPublicTextures` | 获取皮肤广场公开材质 | `GetPublicTexturesRequest` | `GetPublicTexturesResponse` |
|
||||
| `SearchTextures` | 搜索材质 | `SearchTexturesRequest` | `SearchTexturesResponse` |
|
||||
|
||||
### 高级功能接口
|
||||
|
||||
| 方法名 | 功能描述 | 请求类型 | 响应类型 |
|
||||
|--------|----------|----------|----------|
|
||||
| `GetTextureByHash` | 根据哈希值查找材质(防重复上传) | `GetTextureByHashRequest` | `GetTextureByHashResponse` |
|
||||
| `GetTexturesByIds` | 批量获取材质信息 | `GetTexturesByIdsRequest` | `GetTexturesByIdsResponse` |
|
||||
|
||||
### 收藏夹功能接口
|
||||
|
||||
| 方法名 | 功能描述 | 请求类型 | 响应类型 |
|
||||
|---|---|---|---|
|
||||
| `AddFavorite` | 添加材质到收藏夹 | `AddFavoriteRequest` | `AddFavoriteResponse` |
|
||||
| `RemoveFavorite` | 从收藏夹移除材质 | `RemoveFavoriteRequest` | `RemoveFavoriteResponse` |
|
||||
| `GetUserFavorites` | 获取用户收藏列表 | `GetUserFavoritesRequest` | `GetUserFavoritesResponse` |
|
||||
| `CheckFavoriteStatus` | 检查材质收藏状态 | `CheckFavoriteStatusRequest` | `CheckFavoriteStatusResponse` |
|
||||
|
||||
## 数据模型
|
||||
|
||||
### 材质信息 (TextureInfo)
|
||||
|
||||
```protobuf
|
||||
message TextureInfo {
|
||||
int64 id = 1; // 材质ID
|
||||
int64 uploader_id = 2; // 上传者用户ID
|
||||
TextureType type = 3; // 材质类型(SKIN/CAPE)
|
||||
string url = 4; // MinIO中的永久访问URL
|
||||
string hash = 5; // SHA-256哈希值
|
||||
bool is_public = 6; // 是否公开到皮肤广场
|
||||
string created_at = 7; // 创建时间
|
||||
string updated_at = 8; // 更新时间
|
||||
}
|
||||
```
|
||||
|
||||
### 材质类型枚举
|
||||
|
||||
```protobuf
|
||||
enum TextureType {
|
||||
SKIN = 0; // 皮肤
|
||||
CAPE = 1; // 披风
|
||||
}
|
||||
```
|
||||
|
||||
### 收藏夹相关数据模型
|
||||
|
||||
#### 收藏材质信息 (FavoriteTextureInfo)
|
||||
|
||||
```protobuf
|
||||
message FavoriteTextureInfo {
|
||||
TextureInfo texture = 1; // 材质信息
|
||||
string favorite_at = 2; // 收藏时间
|
||||
}
|
||||
```
|
||||
|
||||
## 存储结构
|
||||
|
||||
### MinIO 对象存储结构
|
||||
|
||||
```
|
||||
textures/ # 存储桶根目录
|
||||
├── skins/ # 皮肤材质目录
|
||||
│ └── user_{userId}/ # 按用户分组
|
||||
│ └── {timestamp}_{filename}.png
|
||||
└── capes/ # 披风材质目录
|
||||
└── user_{userId}/ # 按用户分组
|
||||
└── {timestamp}_{filename}.png
|
||||
```
|
||||
|
||||
### 数据库表结构
|
||||
|
||||
```sql
|
||||
CREATE TABLE textures (
|
||||
id BIGINT PRIMARY KEY AUTO_INCREMENT,
|
||||
uploader_id BIGINT NOT NULL,
|
||||
type VARCHAR(10) NOT NULL, -- 'SKIN' 或 'CAPE'
|
||||
url VARCHAR(500) NOT NULL, -- MinIO访问URL
|
||||
hash VARCHAR(64) NOT NULL UNIQUE, -- SHA-256哈希值
|
||||
is_public BOOLEAN DEFAULT FALSE, -- 是否公开
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
|
||||
INDEX idx_uploader_type (uploader_id, type),
|
||||
INDEX idx_hash (hash),
|
||||
INDEX idx_public_type (is_public, type, created_at)
|
||||
);
|
||||
```
|
||||
|
||||
### `user_texture_favorites` 表
|
||||
|
||||
```sql
|
||||
-- 用户材质收藏表
|
||||
CREATE TABLE `user_texture_favorites` (
|
||||
`id` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '收藏记录的唯一ID',
|
||||
`user_id` BIGINT UNSIGNED NOT NULL COMMENT '用户ID (对应UserService中的users.id)',
|
||||
`texture_id` BIGINT UNSIGNED NOT NULL COMMENT '收藏的材质ID (对应textures.id)',
|
||||
`created_at` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '收藏时间',
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `uk_user_texture` (`user_id`, `texture_id`),
|
||||
INDEX `idx_user_id` (`user_id`),
|
||||
INDEX `idx_texture_id` (`texture_id`),
|
||||
INDEX `idx_created_at` (`created_at`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='用户材质收藏表';
|
||||
```
|
||||
|
||||
## 配置说明
|
||||
|
||||
### 服务配置 (etc/textures.yaml)
|
||||
|
||||
```yaml
|
||||
Name: textures.rpc
|
||||
ListenOn: 0.0.0.0:8080
|
||||
|
||||
# 数据库配置
|
||||
DataSource: root:password@tcp(localhost:3306)/carrot_skin?charset=utf8mb4&parseTime=true&loc=Local
|
||||
|
||||
# 缓存配置
|
||||
CacheRedis:
|
||||
- Host: localhost:6379
|
||||
Pass: ""
|
||||
Type: node
|
||||
|
||||
# MinIO配置
|
||||
MinIO:
|
||||
Endpoint: "localhost:9000"
|
||||
AccessKeyID: "minioadmin"
|
||||
SecretAccessKey: "minioadmin"
|
||||
UseSSL: false
|
||||
Buckets:
|
||||
Textures: "carrot-skin-textures"
|
||||
```
|
||||
|
||||
## 安全特性
|
||||
|
||||
### 文件上传安全
|
||||
|
||||
- **格式限制**: 仅允许PNG格式文件
|
||||
- **大小限制**: 文件大小限制在1KB-1MB之间
|
||||
- **时效控制**: 预签名URL 15分钟过期
|
||||
- **内容验证**: MinIO层面的Content-Type验证
|
||||
|
||||
### 权限控制
|
||||
|
||||
- **所有权验证**: 用户只能删除/更新自己上传的材质
|
||||
- **参数校验**: 所有接口都有完整的输入验证
|
||||
- **错误处理**: 不暴露敏感的系统信息
|
||||
|
||||
### 数据完整性
|
||||
|
||||
- **哈希去重**: SHA-256确保文件唯一性
|
||||
- **事务处理**: 数据库操作的原子性保证
|
||||
- **文件同步**: 删除材质时同步清理MinIO文件
|
||||
|
||||
## 性能优化
|
||||
|
||||
### 查询优化
|
||||
|
||||
- **分页查询**: 支持高效的大数据量分页
|
||||
- **索引优化**: 针对常用查询场景建立复合索引
|
||||
- **缓存机制**: go-zero内置的Redis缓存层
|
||||
|
||||
### 存储优化
|
||||
|
||||
- **智能去重**: 相同文件自动复用,节省存储空间
|
||||
- **分类存储**: 按材质类型和用户分目录存储
|
||||
|
||||
## 部署说明
|
||||
|
||||
### 环境要求
|
||||
|
||||
- Go 1.19+
|
||||
- MySQL 8.0+
|
||||
- Redis 6.0+
|
||||
- MinIO Server
|
||||
|
||||
### 启动服务
|
||||
|
||||
```bash
|
||||
# 1. 安装依赖
|
||||
go mod tidy
|
||||
|
||||
# 2. 生成代码(如果修改了proto或sql文件)
|
||||
goctl rpc protoc docs/textures.proto --go_out=./pb --go-grpc_out=./pb --zrpc_out=.
|
||||
goctl model mysql ddl --src="docs/textures.sql" --dir="./internal/model"
|
||||
|
||||
# 3. 启动服务
|
||||
go run textures.go -f etc/textures.yaml
|
||||
```
|
||||
|
||||
### Docker 部署
|
||||
|
||||
```dockerfile
|
||||
FROM golang:1.19-alpine AS builder
|
||||
WORKDIR /app
|
||||
COPY . .
|
||||
RUN go mod tidy && go build -o textures textures.go
|
||||
|
||||
FROM alpine:latest
|
||||
RUN apk --no-cache add ca-certificates
|
||||
WORKDIR /root/
|
||||
COPY --from=builder /app/textures .
|
||||
COPY --from=builder /app/etc ./etc
|
||||
CMD ["./textures", "-f", "etc/textures.yaml"]
|
||||
```
|
||||
|
||||
## 监控与日志
|
||||
|
||||
### 日志记录
|
||||
|
||||
- **操作日志**: 记录所有材质操作的详细信息
|
||||
- **错误日志**: 详细的错误堆栈和上下文信息
|
||||
- **性能日志**: 查询耗时和系统性能指标
|
||||
|
||||
### 监控指标
|
||||
|
||||
- **接口调用量**: 各接口的QPS统计
|
||||
- **存储使用量**: MinIO存储空间使用情况
|
||||
- **缓存命中率**: Redis缓存效果监控
|
||||
- **错误率统计**: 接口错误率和错误类型分析
|
||||
|
||||
## 开发指南
|
||||
|
||||
### 添加新接口
|
||||
|
||||
1. 在 `docs/textures.proto` 中定义新的RPC方法
|
||||
2. 运行 `goctl rpc protoc` 生成代码
|
||||
3. 在 `internal/logic/` 中实现业务逻辑
|
||||
4. 添加相应的数据库查询方法(如需要)
|
||||
|
||||
### 自定义数据库查询
|
||||
|
||||
在 `internal/model/texturesModel.go` 中添加自定义查询方法:
|
||||
|
||||
```go
|
||||
// 在 TexturesModel 接口中添加方法声明
|
||||
type TexturesModel interface {
|
||||
texturesModel
|
||||
// 自定义方法
|
||||
FindByCustomCondition(ctx context.Context, condition string) ([]*Textures, error)
|
||||
}
|
||||
|
||||
// 在 customTexturesModel 中实现方法
|
||||
func (m *customTexturesModel) FindByCustomCondition(ctx context.Context, condition string) ([]*Textures, error) {
|
||||
query := `SELECT * FROM textures WHERE custom_field = ?`
|
||||
var resp []*Textures
|
||||
err := m.QueryRowsNoCacheCtx(ctx, &resp, query, condition)
|
||||
return resp, err
|
||||
}
|
||||
```
|
||||
|
||||
## 故障排查
|
||||
|
||||
### 常见问题
|
||||
|
||||
1. **上传失败**: 检查MinIO连接和存储桶配置
|
||||
2. **查询缓慢**: 检查数据库索引和Redis缓存
|
||||
3. **文件不一致**: 检查MinIO文件清理逻辑
|
||||
4. **权限错误**: 检查用户ID和材质所有权
|
||||
|
||||
### 调试技巧
|
||||
|
||||
- 启用详细日志: 设置日志级别为 `debug`
|
||||
- 检查MinIO状态: 使用MinIO控制台查看文件状态
|
||||
- 监控数据库: 使用慢查询日志分析性能问题
|
||||
Reference in New Issue
Block a user