forked from datawhale/whale-town-end
* 新增完整的 API 状态码文档,并对测试模式进行特殊处理(`206 Partial Content`) * 重组 DTO 结构,引入 `app.dto.ts` 与 `error_response.dto.ts`,以实现统一、规范的响应格式 * 重构登录相关 DTO,优化命名与结构,提升可维护性 * 实现基于内存的用户服务(`users_memory.service.ts`),用于开发与测试环境 * 更新邮件服务,增强验证码生成逻辑,并支持测试模式自动识别 * 增强登录控制器与服务层的错误处理能力,统一响应行为 * 优化核心登录服务,强化参数校验并集成邮箱验证流程 * 新增 `@types/express` 依赖,提升 TypeScript 类型支持与开发体验 * 改进 `main.ts`,优化应用初始化流程与配置管理 * 在所有服务中统一错误处理机制,采用标准化的错误响应格式 * 实现测试模式(`206`)与生产环境邮件发送(`200`)之间的无缝切换
7.3 KiB
7.3 KiB
API 状态码说明
📊 概述
本文档说明了项目中使用的 HTTP 状态码,特别是针对邮件发送功能的特殊状态码处理。
🔢 标准状态码
| 状态码 | 含义 | 使用场景 |
|---|---|---|
| 200 | OK | 请求成功 |
| 201 | Created | 资源创建成功(如用户注册) |
| 400 | Bad Request | 请求参数错误 |
| 401 | Unauthorized | 未授权(如密码错误) |
| 403 | Forbidden | 权限不足 |
| 404 | Not Found | 资源不存在 |
| 409 | Conflict | 资源冲突(如用户名已存在) |
| 429 | Too Many Requests | 请求频率过高 |
| 500 | Internal Server Error | 服务器内部错误 |
🎯 特殊状态码
206 Partial Content - 测试模式
使用场景: 邮件发送功能在测试模式下使用
含义: 请求部分成功,但未完全达到预期效果
具体应用:
- 验证码已生成,但邮件未真实发送
- 功能正常工作,但处于测试/开发模式
- 用户可以获得验证码进行测试,但需要知道这不是真实发送
响应示例:
{
"success": false,
"data": {
"verification_code": "123456",
"is_test_mode": true
},
"message": "⚠️ 测试模式:验证码已生成但未真实发送。请在控制台查看验证码,或配置邮件服务以启用真实发送。",
"error_code": "TEST_MODE_ONLY"
}
📧 邮件发送接口状态码
发送邮箱验证码 - POST /auth/send-email-verification
| 状态码 | 场景 | 响应 |
|---|---|---|
| 200 | 邮件真实发送成功 | { "success": true, "message": "验证码已发送,请查收邮件" } |
| 206 | 测试模式 | { "success": false, "error_code": "TEST_MODE_ONLY", "data": { "verification_code": "123456", "is_test_mode": true } } |
| 400 | 参数错误 | { "success": false, "message": "邮箱格式错误" } |
| 429 | 发送频率过高 | { "success": false, "message": "发送频率过高,请稍后重试" } |
发送密码重置验证码 - POST /auth/forgot-password
| 状态码 | 场景 | 响应 |
|---|---|---|
| 200 | 邮件真实发送成功 | { "success": true, "message": "验证码已发送,请查收" } |
| 206 | 测试模式 | { "success": false, "error_code": "TEST_MODE_ONLY", "data": { "verification_code": "123456", "is_test_mode": true } } |
| 400 | 参数错误 | { "success": false, "message": "邮箱格式错误" } |
| 404 | 用户不存在 | { "success": false, "message": "用户不存在" } |
重新发送邮箱验证码 - POST /auth/resend-email-verification
| 状态码 | 场景 | 响应 |
|---|---|---|
| 200 | 邮件真实发送成功 | { "success": true, "message": "验证码已重新发送,请查收邮件" } |
| 206 | 测试模式 | { "success": false, "error_code": "TEST_MODE_ONLY", "data": { "verification_code": "123456", "is_test_mode": true } } |
| 400 | 邮箱已验证或用户不存在 | { "success": false, "message": "邮箱已验证,无需重复验证" } |
| 429 | 发送频率过高 | { "success": false, "message": "发送频率过高,请稍后重试" } |
🔄 模式切换
测试模式 → 真实发送模式
配置前(测试模式):
curl -X POST http://localhost:3000/auth/send-email-verification \
-H "Content-Type: application/json" \
-d '{"email": "test@example.com"}'
# 响应:206 Partial Content
{
"success": false,
"data": {
"verification_code": "123456",
"is_test_mode": true
},
"message": "⚠️ 测试模式:验证码已生成但未真实发送...",
"error_code": "TEST_MODE_ONLY"
}
配置后(真实发送模式):
# 同样的请求
curl -X POST http://localhost:3000/auth/send-email-verification \
-H "Content-Type: application/json" \
-d '{"email": "test@example.com"}'
# 响应:200 OK
{
"success": true,
"data": {
"is_test_mode": false
},
"message": "验证码已发送,请查收邮件"
}
💡 前端处理建议
JavaScript 示例
async function sendEmailVerification(email) {
try {
const response = await fetch('/auth/send-email-verification', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({ email }),
});
const data = await response.json();
if (response.status === 200) {
// 真实发送成功
showSuccess('验证码已发送,请查收邮件');
} else if (response.status === 206) {
// 测试模式
showWarning(`测试模式:验证码是 ${data.data.verification_code}`);
showInfo('请配置邮件服务以启用真实发送');
} else {
// 其他错误
showError(data.message);
}
} catch (error) {
showError('网络错误,请稍后重试');
}
}
React 示例
const handleSendVerification = async (email) => {
try {
const response = await fetch('/auth/send-email-verification', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ email }),
});
const data = await response.json();
switch (response.status) {
case 200:
setMessage({ type: 'success', text: '验证码已发送,请查收邮件' });
break;
case 206:
setMessage({
type: 'warning',
text: `测试模式:验证码是 ${data.data.verification_code}`
});
setShowConfigTip(true);
break;
case 400:
setMessage({ type: 'error', text: data.message });
break;
case 429:
setMessage({ type: 'error', text: '发送频率过高,请稍后重试' });
break;
default:
setMessage({ type: 'error', text: '发送失败,请稍后重试' });
}
} catch (error) {
setMessage({ type: 'error', text: '网络错误,请稍后重试' });
}
};
🎨 UI 展示建议
测试模式提示
<!-- 成功状态 (200) -->
<div class="alert alert-success">
✅ 验证码已发送,请查收邮件
</div>
<!-- 测试模式 (206) -->
<div class="alert alert-warning">
⚠️ 测试模式:验证码是 123456
<br>
<small>请配置邮件服务以启用真实发送</small>
</div>
<!-- 错误状态 (400+) -->
<div class="alert alert-danger">
❌ 发送失败:邮箱格式错误
</div>
📝 开发建议
1. 状态码检查
// 推荐:明确检查状态码
if (response.status === 206) {
// 处理测试模式
} else if (response.status === 200) {
// 处理真实发送
}
// 不推荐:只检查 success 字段
if (data.success) {
// 可能遗漏测试模式的情况
}
2. 错误处理
// 推荐:根据 error_code 进行精确处理
switch (data.error_code) {
case 'TEST_MODE_ONLY':
handleTestMode(data);
break;
case 'SEND_CODE_FAILED':
handleSendFailure(data);
break;
default:
handleGenericError(data);
}
3. 用户体验
- 测试模式:清晰提示用户当前处于测试模式
- 配置引导:提供配置邮件服务的链接或说明
- 验证码显示:在测试模式下直接显示验证码
- 状态区分:用不同的颜色和图标区分不同状态