小清洗

This commit is contained in:
Mikuisnotavailable
2025-10-16 02:30:29 +08:00
parent 167c51b20d
commit 7a36c87ff0
5 changed files with 0 additions and 1205 deletions

View File

@@ -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}` - 获取指定角色及其属性(需要登录)
通过以上测试方法,您可以全面验证前端与后端的连接状态和数据读取能力。

View File

@@ -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` 文件中的相关代码。

View File

@@ -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位数字
- 验证码存储Redis10分钟有效期
- 发送频率限制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
```

View File

@@ -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密钥操作耗时

View File

@@ -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控制台查看文件状态
- 监控数据库: 使用慢查询日志分析性能问题