- 新增邮箱冲突检测:发送验证码前检查邮箱是否已被注册 - 优化用户体验:避免向已注册邮箱发送无用验证码 - 改进错误处理:返回409 Conflict状态码和明确错误信息 - 更新API文档:重新整理文档结构,突出前端开发要点 - 完善测试用例:添加邮箱冲突检测相关测试 - 版本升级:1.1.0 1.1.1 核心修改: - src/core/login_core/login_core.service.ts: 在sendEmailVerification方法中添加邮箱存在性检查 - src/business/auth/controllers/login.controller.ts: 正确处理409冲突状态码 - docs/api/api-documentation.md: 重新整理为精简实用的前端开发文档 - docs/api/openapi.yaml: 更新版本和接口描述 - test-register-fix.ps1: 添加邮箱冲突检测测试用例
18 KiB
18 KiB
Pixel Game Server API 文档
版本: 1.1.1
更新时间: 2025-12-25
🚨 后端对前端的提示与注意点
重要提醒
- 邮箱冲突检测: 发送邮箱验证码前会检查邮箱是否已被注册,已注册邮箱返回409状态码
- HTTP状态码: 所有接口根据业务结果返回正确状态码(409冲突、400参数错误、401认证失败等)
- 验证码有效期: 所有验证码有效期为5分钟
- 频率限制: 验证码发送限制1次/分钟,注册限制10次/5分钟
- 测试模式: 开发环境下邮件服务返回206状态码,验证码在响应中返回
错误处理规范
- 409 Conflict: 资源冲突(用户名、邮箱已存在)
- 400 Bad Request: 参数错误、验证码错误
- 401 Unauthorized: 认证失败、密码错误
- 429 Too Many Requests: 频率限制
- 206 Partial Content: 测试模式(验证码未真实发送)
前端开发建议
- 根据HTTP状态码进行错误处理,不要只依赖success字段
- 邮箱注册流程:先发送验证码 → 检查409冲突 → 使用验证码注册
- 测试模式下验证码在响应中返回,生产环境需用户查收邮件
- 实现重试机制处理429频率限制错误
📋 API接口列表
应用状态接口
GET /- 获取应用状态
用户认证接口
POST /auth/login- 用户登录POST /auth/register- 用户注册POST /auth/github- GitHub OAuth登录POST /auth/verification-code-login- 验证码登录POST /auth/send-login-verification-code- 发送登录验证码POST /auth/forgot-password- 发送密码重置验证码POST /auth/reset-password- 重置密码PUT /auth/change-password- 修改密码POST /auth/send-email-verification- 发送邮箱验证码POST /auth/verify-email- 验证邮箱验证码POST /auth/resend-email-verification- 重新发送邮箱验证码
管理员接口
POST /admin/auth/login- 管理员登录GET /admin/users- 获取用户列表GET /admin/users/:id- 获取用户详情POST /admin/users/:id/reset-password- 管理员重置用户密码GET /admin/logs/runtime- 获取运行时日志GET /admin/logs/archive- 获取归档日志
用户管理接口
PUT /admin/users/:id/status- 修改用户状态POST /admin/users/batch-status- 批量修改用户状态GET /admin/users/status-stats- 获取用户状态统计
🧪 API接口详细说明与测试用例
1. 获取应用状态
接口: GET /
成功响应 (200)
{
"service": "Pixel Game Server",
"version": "1.1.1",
"status": "running",
"timestamp": "2025-12-25T10:27:44.352Z",
"uptime": 8,
"environment": "development",
"storage_mode": "database"
}
2. 用户登录
接口: POST /auth/login
请求体
{
"identifier": "testuser",
"password": "password123"
}
成功响应 (200)
{
"success": true,
"data": {
"user": {
"id": "1",
"username": "testuser",
"nickname": "测试用户",
"email": "test@example.com",
"phone": null,
"avatar_url": null,
"role": 1,
"created_at": "2025-12-17T10:00:00.000Z"
},
"access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"is_new_user": false,
"message": "登录成功"
},
"message": "登录成功"
}
认证失败响应 (401)
{
"success": false,
"message": "用户名、邮箱或手机号不存在",
"error_code": "LOGIN_FAILED"
}
密码错误响应 (401)
{
"success": false,
"message": "密码错误",
"error_code": "LOGIN_FAILED"
}
3. 用户注册
接口: POST /auth/register
请求体(无邮箱)
{
"username": "newuser",
"password": "password123",
"nickname": "新用户"
}
请求体(带邮箱验证)
{
"username": "newuser",
"password": "password123",
"nickname": "新用户",
"email": "newuser@example.com",
"email_verification_code": "123456"
}
成功响应 (201)
{
"success": true,
"data": {
"user": {
"id": "2",
"username": "newuser",
"nickname": "新用户",
"email": "newuser@example.com",
"phone": null,
"avatar_url": null,
"role": 1,
"created_at": "2025-12-17T10:00:00.000Z"
},
"access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"is_new_user": true,
"message": "注册成功"
},
"message": "注册成功"
}
用户名冲突响应 (409)
{
"success": false,
"message": "用户名已存在",
"error_code": "REGISTER_FAILED"
}
邮箱冲突响应 (409)
{
"success": false,
"message": "邮箱已存在",
"error_code": "REGISTER_FAILED"
}
验证码错误响应 (400)
{
"success": false,
"message": "验证码不存在或已过期",
"error_code": "REGISTER_FAILED"
}
4. 发送邮箱验证码
接口: POST /auth/send-email-verification
请求体
{
"email": "test@example.com"
}
成功响应 (200) - 生产环境
{
"success": true,
"data": {
"is_test_mode": false
},
"message": "验证码已发送,请查收邮件"
}
测试模式响应 (206) - 开发环境
{
"success": false,
"data": {
"verification_code": "123456",
"is_test_mode": true
},
"message": "⚠️ 测试模式:验证码已生成但未真实发送。请在控制台查看验证码,或配置邮件服务以启用真实发送。",
"error_code": "TEST_MODE_ONLY"
}
邮箱冲突响应 (409)
{
"success": false,
"message": "邮箱已被注册,请使用其他邮箱或直接登录",
"error_code": "SEND_EMAIL_VERIFICATION_FAILED"
}
频率限制响应 (429)
{
"success": false,
"message": "验证码发送过于频繁,请1分钟后再试",
"error_code": "TOO_MANY_REQUESTS",
"throttle_info": {
"limit": 1,
"window_seconds": 60,
"current_requests": 1,
"reset_time": "2025-12-25T10:07:37.056Z"
}
}
5. 验证码登录
接口: POST /auth/verification-code-login
请求体
{
"identifier": "test@example.com",
"verification_code": "123456"
}
成功响应 (200)
{
"success": true,
"data": {
"user": {
"id": "1",
"username": "testuser",
"nickname": "测试用户",
"email": "test@example.com",
"phone": null,
"avatar_url": null,
"role": 1,
"created_at": "2025-12-17T10:00:00.000Z"
},
"access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"is_new_user": false,
"message": "验证码登录成功"
},
"message": "验证码登录成功"
}
验证码错误响应 (401)
{
"success": false,
"message": "验证码验证失败",
"error_code": "VERIFICATION_CODE_LOGIN_FAILED"
}
用户不存在响应 (404)
{
"success": false,
"message": "用户不存在,请先注册账户",
"error_code": "VERIFICATION_CODE_LOGIN_FAILED"
}
6. 发送登录验证码
接口: POST /auth/send-login-verification-code
请求体
{
"identifier": "test@example.com"
}
成功响应 (200) - 生产环境
{
"success": true,
"data": {
"is_test_mode": false
},
"message": "验证码已发送,请查收"
}
测试模式响应 (206) - 开发环境
{
"success": false,
"data": {
"verification_code": "654321",
"is_test_mode": true
},
"message": "⚠️ 测试模式:验证码已生成但未真实发送。请在控制台查看验证码,或配置邮件服务以启用真实发送。",
"error_code": "TEST_MODE_ONLY"
}
用户不存在响应 (404)
{
"success": false,
"message": "用户不存在",
"error_code": "SEND_LOGIN_CODE_FAILED"
}
7. 发送密码重置验证码
接口: POST /auth/forgot-password
请求体
{
"identifier": "test@example.com"
}
成功响应 (200) - 生产环境
{
"success": true,
"data": {
"is_test_mode": false
},
"message": "验证码已发送,请查收"
}
测试模式响应 (206) - 开发环境
{
"success": false,
"data": {
"verification_code": "789012",
"is_test_mode": true
},
"message": "⚠️ 测试模式:验证码已生成但未真实发送。请在控制台查看验证码,或配置邮件服务以启用真实发送。",
"error_code": "TEST_MODE_ONLY"
}
用户不存在响应 (404)
{
"success": false,
"message": "用户不存在",
"error_code": "SEND_CODE_FAILED"
}
8. 重置密码
接口: POST /auth/reset-password
请求体
{
"identifier": "test@example.com",
"verification_code": "789012",
"new_password": "newpassword123"
}
成功响应 (200)
{
"success": true,
"message": "密码重置成功"
}
验证码错误响应 (400)
{
"success": false,
"message": "验证码验证失败",
"error_code": "RESET_PASSWORD_FAILED"
}
9. 修改密码
接口: PUT /auth/change-password
请求体
{
"user_id": "1",
"old_password": "oldpassword123",
"new_password": "newpassword123"
}
成功响应 (200)
{
"success": true,
"message": "密码修改成功"
}
旧密码错误响应 (401)
{
"success": false,
"message": "旧密码错误",
"error_code": "CHANGE_PASSWORD_FAILED"
}
10. GitHub OAuth登录
接口: POST /auth/github
请求体
{
"github_id": "12345678",
"username": "octocat",
"nickname": "The Octocat",
"email": "octocat@github.com",
"avatar_url": "https://github.com/images/error/octocat_happy.gif"
}
成功响应 (200) - 已存在用户
{
"success": true,
"data": {
"user": {
"id": "3",
"username": "octocat",
"nickname": "The Octocat",
"email": "octocat@github.com",
"phone": null,
"avatar_url": "https://github.com/images/error/octocat_happy.gif",
"role": 1,
"created_at": "2025-12-17T10:00:00.000Z"
},
"access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"is_new_user": false,
"message": "GitHub登录成功"
},
"message": "GitHub登录成功"
}
成功响应 (200) - 新用户注册
{
"success": true,
"data": {
"user": {
"id": "4",
"username": "octocat_1",
"nickname": "The Octocat",
"email": "octocat@github.com",
"phone": null,
"avatar_url": "https://github.com/images/error/octocat_happy.gif",
"role": 1,
"created_at": "2025-12-17T10:00:00.000Z"
},
"access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"is_new_user": true,
"message": "GitHub账户绑定成功"
},
"message": "GitHub账户绑定成功"
}
11. 验证邮箱验证码
接口: POST /auth/verify-email
请求体
{
"email": "test@example.com",
"verification_code": "123456"
}
成功响应 (200)
{
"success": true,
"message": "邮箱验证成功"
}
验证码错误响应 (400)
{
"success": false,
"message": "验证码错误",
"error_code": "EMAIL_VERIFICATION_FAILED"
}
12. 重新发送邮箱验证码
接口: POST /auth/resend-email-verification
请求体
{
"email": "test@example.com"
}
成功响应 (200) - 生产环境
{
"success": true,
"data": {
"is_test_mode": false
},
"message": "验证码已重新发送,请查收邮件"
}
测试模式响应 (206) - 开发环境
{
"success": false,
"data": {
"verification_code": "456789",
"is_test_mode": true
},
"message": "⚠️ 测试模式:验证码已生成但未真实发送。请在控制台查看验证码,或配置邮件服务以启用真实发送。",
"error_code": "TEST_MODE_ONLY"
}
邮箱已验证响应 (400)
{
"success": false,
"message": "邮箱已验证,无需重复验证",
"error_code": "RESEND_EMAIL_VERIFICATION_FAILED"
}
13. 管理员登录
接口: POST /admin/auth/login
请求体
{
"username": "admin",
"password": "Admin123456"
}
成功响应 (200)
{
"success": true,
"data": {
"admin": {
"id": "1",
"username": "admin",
"nickname": "管理员",
"role": 0
},
"access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"expires_in": 28800,
"message": "管理员登录成功"
},
"message": "管理员登录成功"
}
认证失败响应 (401)
{
"success": false,
"message": "用户名或密码错误",
"error_code": "ADMIN_LOGIN_FAILED"
}
权限不足响应 (403)
{
"success": false,
"message": "权限不足,需要管理员权限",
"error_code": "ADMIN_LOGIN_FAILED"
}
14. 获取用户列表
接口: GET /admin/users
查询参数
page: 页码(可选,默认1)limit: 每页数量(可选,默认10)status: 用户状态筛选(可选)
成功响应 (200)
{
"success": true,
"data": {
"users": [
{
"id": "1",
"username": "testuser",
"nickname": "测试用户",
"email": "test@example.com",
"phone": null,
"role": 1,
"status": "active",
"email_verified": true,
"created_at": "2025-12-17T10:00:00.000Z",
"updated_at": "2025-12-17T10:00:00.000Z"
}
],
"pagination": {
"page": 1,
"limit": 10,
"total": 1,
"pages": 1
}
},
"message": "用户列表获取成功"
}
15. 获取用户详情
接口: GET /admin/users/:id
成功响应 (200)
{
"success": true,
"data": {
"user": {
"id": "1",
"username": "testuser",
"nickname": "测试用户",
"email": "test@example.com",
"phone": null,
"role": 1,
"status": "active",
"email_verified": true,
"github_id": null,
"avatar_url": null,
"created_at": "2025-12-17T10:00:00.000Z",
"updated_at": "2025-12-17T10:00:00.000Z"
}
},
"message": "用户详情获取成功"
}
用户不存在响应 (404)
{
"success": false,
"message": "用户不存在",
"error_code": "USER_NOT_FOUND"
}
16. 管理员重置用户密码
接口: POST /admin/users/:id/reset-password
请求体
{
"new_password": "newpassword123"
}
成功响应 (200)
{
"success": true,
"message": "用户密码重置成功"
}
用户不存在响应 (404)
{
"success": false,
"message": "用户不存在",
"error_code": "USER_NOT_FOUND"
}
17. 修改用户状态
接口: PUT /admin/users/:id/status
请求体
{
"status": "locked",
"reason": "违规操作"
}
成功响应 (200)
{
"success": true,
"data": {
"user": {
"id": "1",
"username": "testuser",
"status": "locked",
"updated_at": "2025-12-17T10:00:00.000Z"
}
},
"message": "用户状态修改成功"
}
状态值无效响应 (400)
{
"success": false,
"message": "无效的用户状态值",
"error_code": "USER_STATUS_UPDATE_FAILED"
}
18. 批量修改用户状态
接口: POST /admin/users/batch-status
请求体
{
"user_ids": ["1", "2", "3"],
"status": "active",
"reason": "批量激活"
}
成功响应 (200)
{
"success": true,
"data": {
"updated_count": 3,
"failed_count": 0,
"results": [
{
"user_id": "1",
"success": true,
"new_status": "active"
},
{
"user_id": "2",
"success": true,
"new_status": "active"
},
{
"user_id": "3",
"success": true,
"new_status": "active"
}
]
},
"message": "批量状态修改完成"
}
19. 获取用户状态统计
接口: GET /admin/users/status-stats
成功响应 (200)
{
"success": true,
"data": {
"stats": {
"active": 15,
"inactive": 3,
"locked": 2,
"banned": 1,
"deleted": 0,
"pending": 5
},
"total": 26
},
"message": "用户状态统计获取成功"
}
20. 获取运行时日志
接口: GET /admin/logs/runtime
查询参数
lines: 日志行数(可选,默认100)level: 日志级别(可选)
成功响应 (200)
{
"success": true,
"data": {
"logs": [
"[2025-12-25 18:27:35] LOG [NestApplication] Nest application successfully started",
"[2025-12-25 18:27:35] LOG [RouterExplorer] Mapped {/, GET} route"
],
"total_lines": 2,
"timestamp": "2025-12-25T10:27:44.352Z"
},
"message": "运行时日志获取成功"
}
21. 获取归档日志
接口: GET /admin/logs/archive
查询参数
date: 日期(YYYY-MM-DD格式,可选)download: 是否下载(可选)
成功响应 (200)
{
"success": true,
"data": {
"files": [
{
"filename": "app-2025-12-24.log",
"size": 1024,
"created_at": "2025-12-24T00:00:00.000Z"
}
],
"total_files": 1
},
"message": "归档日志列表获取成功"
}
📊 版本更新记录
v1.1.1 (2025-12-25)
- 邮箱冲突检测优化: 发送邮箱验证码前检查邮箱是否已被注册
- 用户体验提升: 避免向已注册邮箱发送无用验证码
- 错误处理改进: 返回409 Conflict状态码和明确错误信息
v1.1.0 (2025-12-25)
- 新增验证码登录功能: 支持邮箱验证码登录
- HTTP状态码修复: 所有接口返回正确的业务状态码
- 完善错误处理: 统一错误响应格式和错误代码