# Mock Service Worker 使用指南 本项目已集成 **Mock Service Worker (MSW)**,提供本地 Mock API 能力,无需依赖后端即可进行前端开发和测试。 ## 📖 目录 1. [快速开始](#快速开始) 2. [启动方式](#启动方式) 3. [环境配置](#环境配置) 4. [Mock 数据说明](#mock-数据说明) 5. [如何添加新的 Mock API](#如何添加新的-mock-api) 6. [调试技巧](#调试技巧) 7. [常见问题](#常见问题) --- ## 🚀 快速开始 ### 方式一:启动 Mock 环境(使用本地 Mock 数据) ```bash npm run start:mock ``` 启动后,浏览器控制台会显示: ``` [MSW] Mock Service Worker 已启动 🎭 提示: 所有 API 请求将使用本地 Mock 数据 要禁用 Mock,请设置 REACT_APP_ENABLE_MOCK=false ``` ### 方式二:启动开发环境(连接真实后端) ```bash npm run start:dev # 或者直接使用 npm start ``` --- ## 📝 启动方式 | 命令 | 环境文件 | Mock 状态 | 用途 | |------|---------|----------|------| | `npm run start:mock` | `.env.mock` | ✅ 启用 | 本地开发,使用 Mock 数据 | | `npm run start:dev` | `.env.development` | ❌ 禁用 | 连接真实后端 API | | `npm start` | `.env` | ❌ 禁用 | 默认启动(连接后端) | --- ## ⚙️ 环境配置 ### `.env.mock` - Mock 测试环境 ```env # 启用 Mock 数据 REACT_APP_ENABLE_MOCK=true # Mock 模式下不需要真实的后端地址 REACT_APP_API_URL=http://localhost:3000 # Mock 环境标识 REACT_APP_ENV=mock ``` ### `.env.development` - 开发环境 ```env # 禁用 Mock 数据 REACT_APP_ENABLE_MOCK=false # 真实的后端 API 地址 REACT_APP_API_URL=http://49.232.185.254:5001 # 开发环境标识 REACT_APP_ENV=development ``` ### 如何切换环境? 只需修改 `.env` 文件中的 `REACT_APP_ENABLE_MOCK` 参数: ```env # 启用 Mock REACT_APP_ENABLE_MOCK=true # 禁用 Mock,使用真实 API REACT_APP_ENABLE_MOCK=false ``` --- ## 📦 Mock 数据说明 ### 已实现的 Mock API #### 1. **认证相关 API** | API | 方法 | Mock 说明 | |-----|------|----------| | `/api/auth/send-verification-code` | POST | 发送验证码(控制台会打印验证码) | | `/api/auth/login-with-code` | POST | 验证码登录(自动设置当前登录用户) | | `/api/auth/wechat/qrcode` | GET | 获取微信二维码(10秒后自动模拟扫码) | | `/api/auth/wechat/check-status` | POST | 检查微信扫码状态 | | `/api/auth/wechat/login` | POST | 微信登录确认(自动设置当前登录用户) | | `/api/auth/wechat/h5-auth-url` | POST | 获取微信 H5 授权链接 | | `/api/auth/session` | GET | 检查 Session 状态(返回当前登录用户) | | `/api/auth/check-session` | GET | 检查 Session 状态(旧端点,保留兼容) | | `/api/auth/logout` | POST | 退出登录(清除当前登录用户) | **登录状态管理**: - Mock 系统会跟踪当前登录的用户 - 登录成功后,用户信息会保存到 Mock 状态中 - `/api/auth/session` 会返回当前登录用户的真实信息 - 退出登录会清除登录状态,下次检查 Session 返回未登录 #### 2. **账户管理 API** | API | 方法 | Mock 说明 | |-----|------|----------| | `/api/account/profile-completeness` | GET | 获取用户资料完整度(需要登录) | | `/api/account/profile` | GET | 获取用户资料(需要登录) | | `/api/account/profile` | PUT | 更新用户资料(需要登录) | | `/api/subscription/info` | GET | 获取订阅信息(会员类型、状态、到期时间) | | `/api/subscription/permissions` | GET | 获取订阅权限(各功能的访问权限) | **资料完整度说明**: - 返回用户资料的完整度百分比(0-100%) - 包含缺失项列表(密码、手机号、邮箱) - 对微信登录用户,如果资料不完整会提示需要完善 - Mock 模式会根据当前登录用户的真实信息计算完整度 **订阅信息说明**: - 返回当前用户的会员类型(free/pro/max) - 包含订阅状态(active/expired) - 返回到期时间和剩余天数 - 未登录用户默认返回 free 类型 ### 测试账号 **手机号登录测试账号**: | 手机号 | 验证码 | 用户昵称 | 会员类型 | 状态 | 到期时间 | 剩余天数 | 功能权限 | |--------|--------|---------|---------|------|---------|---------|----------| | `13800138000` | 控制台查看 | 测试用户 | **Free**(免费) | ✅ 激活 | - | - | 基础功能 | | `13900139000` | 控制台查看 | Pro会员 | **Pro** | ✅ 激活 | 2025-12-31 | 90天 | 高级功能(除传导链外) | | `13700137000` | 控制台查看 | Max会员 | **Max** | ✅ 激活 | 2026-12-31 | 365天 | 🎉 全部功能 | | `13600136000` | 控制台查看 | 过期会员 | Pro(已过期) | ❌ 过期 | 2024-01-01 | -300天 | 基础功能 | **会员权限对比**: | 功能 | Free | Pro | Max | |------|------|-----|-----| | 相关标的 | ❌ | ✅ | ✅ | | 相关概念 | ❌ | ✅ | ✅ | | 事件传导链 | ❌ | ❌ | ✅ | | 历史事件对比 | 🔒 限制版 | ✅ 完整版 | ✅ 完整版 | | 概念详情 | ❌ | ✅ | ✅ | | 概念统计中心 | ❌ | ✅ | ✅ | | 概念相关股票 | ❌ | ✅ | ✅ | | 概念历史时间轴 | ❌ | ❌ | ✅ | | 热门个股 | ❌ | ✅ | ✅ | **验证码说明**: - 发送验证码后,控制台会打印验证码 - 示例:`[Mock] 验证码已生成: 13800138000 -> 123456` - 验证码有效期:5分钟 - 所有测试账号都可以使用相同的验证码登录 **微信登录测试**: 1. 点击"获取二维码" 2. 等待 10 秒,自动模拟用户扫码 3. 再等待 5 秒,自动模拟用户确认 4. 登录成功 --- ## 🛠️ 如何添加新的 Mock API ### 步骤 1:创建新的 Handler 文件 在 `src/mocks/handlers/` 目录下创建新文件,例如 `user.js`: ```javascript // src/mocks/handlers/user.js import { http, HttpResponse, delay } from 'msw'; const NETWORK_DELAY = 500; export const userHandlers = [ // 获取用户信息 http.get('/api/user/profile', async () => { await delay(NETWORK_DELAY); return HttpResponse.json({ success: true, data: { id: 1, nickname: '测试用户', email: 'test@example.com', avatar_url: 'https://i.pravatar.cc/150?img=1' } }); }), // 更新用户信息 http.put('/api/user/profile', async ({ request }) => { await delay(NETWORK_DELAY); const body = await request.json(); return HttpResponse.json({ success: true, message: '更新成功', data: body }); }) ]; ``` ### 步骤 2:注册 Handler 在 `src/mocks/handlers/index.js` 中导入并注册: ```javascript // src/mocks/handlers/index.js import { authHandlers } from './auth'; import { userHandlers } from './user'; // 导入新的 handler export const handlers = [ ...authHandlers, ...userHandlers, // 注册新的 handler ]; ``` ### 步骤 3:重启应用 ```bash # 停止当前服务(Ctrl+C) # 重新启动 npm run start:mock ``` --- ## 🐛 调试技巧 ### 1. 查看 Mock 日志 所有 Mock API 请求都会在浏览器控制台打印日志: ``` [Mock] 发送验证码: {credential: "13800138000", type: "phone", purpose: "login"} [Mock] 验证码已生成: 13800138000 -> 654321 [Mock] 登录成功: {id: 1, phone: "13800138000", nickname: "测试用户", ...} ``` ### 2. 检查 MSW 是否启动 打开浏览器控制台,查找以下消息: ``` [MSW] Mock Service Worker 已启动 🎭 ``` 如果没有看到此消息,检查: 1. `.env.mock` 文件中 `REACT_APP_ENABLE_MOCK=true` 2. 是否使用 `npm run start:mock` 启动 ### 3. 网络面板调试 打开浏览器开发者工具 → Network 标签页: - Mock 的请求会显示 `(from ServiceWorker)` 标签 - 可以查看请求和响应的详细信息 ### 4. 模拟网络延迟 在 `src/mocks/handlers/*.js` 文件中修改延迟时间: ```javascript const NETWORK_DELAY = 2000; // 改为 2 秒 ``` ### 5. 模拟错误响应 ```javascript http.post('/api/some-endpoint', async () => { await delay(NETWORK_DELAY); // 返回 400 错误 return HttpResponse.json({ success: false, error: '参数错误' }, { status: 400 }); }); ``` --- ## ❓ 常见问题 ### Q1: Mock 没有生效,请求仍然发送到真实服务器 **解决方案**: 1. 检查 `.env.mock` 文件中 `REACT_APP_ENABLE_MOCK=true` 2. 确保使用 `npm run start:mock` 启动 3. 清除浏览器缓存并刷新页面 4. 检查控制台是否有 MSW 启动消息 ### Q2: 控制台显示 `[MSW] 启动失败` **解决方案**: 1. 确保 `public/mockServiceWorker.js` 文件存在 2. 重新初始化 MSW: ```bash npx msw init public/ --save ``` 3. 重启开发服务器 ### Q3: 如何禁用某个特定 API 的 Mock? 在 `src/mocks/handlers/index.js` 中注释掉相应的 handler: ```javascript export const handlers = [ ...authHandlers, // ...userHandlers, // 禁用 user 相关的 Mock ]; ``` ### Q4: 验证码是什么? 发送验证码后,控制台会打印验证码: ``` [Mock] 验证码已生成: 13800138000 -> 123456 ``` 复制 `123456` 并填入验证码输入框即可。 ### Q5: 微信登录如何测试? 1. 点击"获取二维码" 2. 等待 10 秒(自动模拟扫码) 3. 再等待 5 秒(自动模拟确认) 4. 自动完成登录 或者在控制台查看 Mock 日志: ``` [Mock] 生成微信二维码: {sessionId: "wx_abc123", ...} [Mock] 模拟用户扫码: wx_abc123 [Mock] 模拟用户确认登录: wx_abc123 ``` ### Q6: 生产环境会使用 Mock 数据吗? **不会**。Mock 只在以下情况启用: 1. `NODE_ENV === 'development'`(开发环境) 2. `REACT_APP_ENABLE_MOCK === 'true'` 生产环境 (`npm run build`) 会自动排除 MSW 代码。 --- ## 📁 项目结构 ``` src/ ├── mocks/ │ ├── handlers/ │ │ ├── auth.js # 认证相关 Mock │ │ ├── index.js # Handler 总入口 │ │ └── ... # 其他 Handler 文件 │ ├── data/ │ │ └── users.js # Mock 用户数据 │ └── browser.js # MSW 浏览器 Worker ├── index.js # 应用入口(集成 MSW) └── ... public/ └── mockServiceWorker.js # MSW Service Worker 文件 ``` --- ## 📚 相关资源 - [MSW 官方文档](https://mswjs.io/) - [MSW 快速开始](https://mswjs.io/docs/getting-started) - [MSW API 参考](https://mswjs.io/docs/api) --- ## 🎯 最佳实践 1. **使用真实的响应结构**:Mock 数据应与真实 API 返回的数据结构一致 2. **添加网络延迟**:模拟真实的网络请求延迟,测试加载状态 3. **测试边界情况**:创建错误响应的 Mock,测试错误处理逻辑 4. **保持 Mock 数据更新**:当真实 API 变化时,及时更新 Mock handlers 5. **团队协作**:将 Mock 配置提交到 Git,团队成员共享 --- **提示**:如有任何问题或建议,请联系开发团队。Happy Mocking! 🎭