diff --git a/src/app.config.ts b/src/app.config.ts index 11d26bb..cef33f9 100644 --- a/src/app.config.ts +++ b/src/app.config.ts @@ -1,12 +1,12 @@ export default defineAppConfig({ pages: [ - 'pages/login/index', + 'pages/login/index/index', 'pages/login/verification/index', 'pages/login/terms/index', - 'pages/publishBall/index', - 'pages/mapDisplay/index', - 'pages/list/index', - 'pages/index/index' + // 'pages/publishBall/index', + // 'pages/mapDisplay/index', + // 'pages/list/index', + // 'pages/index/index' ], window: { backgroundTextStyle: 'light', diff --git a/src/pages/login/README.md b/src/pages/login/README.md index f4747c5..3aa2226 100644 --- a/src/pages/login/README.md +++ b/src/pages/login/README.md @@ -88,7 +88,12 @@ src/pages/login/ ├── index.tsx # 登录页面组件 ├── index.scss # Figma 设计稿样式 ├── index.config.ts # 页面配置 -└── README.md # 说明文档 +├── verification/ # 验证码页面 +├── terms/ # 协议详情页面 +├── README.md # 说明文档 +├── login_flow.md # 登录流程串接说明 +├── login_test.md # 测试配置文档 +└── api .md # API 接口文档 ``` ## 🔧 配置说明 @@ -171,4 +176,137 @@ export default definePageConfig({ **Figma 设计稿链接**: https://www.figma.com/design/EWQlX5wM2lhiSLfFQp8qKT/小程序设计稿V1(开发协作版)?node-id=3043-3055 -设计稿包含了完整的视觉规范、尺寸标注和交互说明,本实现严格按照设计稿要求进行开发。 \ No newline at end of file +设计稿包含了完整的视觉规范、尺寸标注和交互说明,本实现严格按照设计稿要求进行开发。 + +--- + +## 🔗 登录流程串接说明 + +### 📋 流程概述 + +登录系统已完全串接,支持两种登录方式: + +1. **微信快捷登录** - 主要登录方式,调用真实后端接口 +2. **手机号验证码登录** - 备选登录方式,完整的验证码流程 + +### 🔄 完整流程 + +#### 微信快捷登录流程 +``` +用户点击微信登录 → 检查协议同意 → 获取微信code → 调用后端接口 → 保存登录状态 → 跳转首页 +``` + +#### 手机号验证码登录流程 +``` +用户点击手机号登录 → 跳转验证码页面 → 输入手机号 → 发送验证码 → 输入验证码 → 验证登录 → 跳转首页 +``` + +### 🌐 API 接口集成 + +已集成以下真实后端接口: + +- **微信授权**: `POST /api/user/wx_auth` +- **发送短信**: `POST /api/user/sms/send` +- **验证验证码**: `POST /api/user/sms/verify` + +### 📱 页面跳转关系 + +``` +登录主页 (/pages/login/index/index) + ↓ +验证码页面 (/pages/login/verification/index) + ↓ +协议详情页面 (/pages/login/terms/index) + ↓ +应用首页 (/pages/index/index) +``` + +### 🧪 测试配置 + +- **测试环境**: `https://sit.light120.com/api` +- **测试账号**: `13800138000` / `123456` +- **完整测试用例**: 参考 `login_test.md` + +### 📚 相关文档 + +- **流程说明**: `login_flow.md` - 详细的流程和接口说明 +- **测试配置**: `login_test.md` - 完整的测试用例和配置 +- **API 文档**: `api .md` - 后端接口规范 + +### ✅ 完成状态 + +- ✅ 微信快捷登录流程 +- ✅ 手机号验证码登录流程 +- ✅ 用户协议流程 +- ✅ 真实后端接口集成 +- ✅ 错误处理和用户提示 +- ✅ 登录状态管理 +- ✅ 页面跳转逻辑 + +登录系统已完全串接完成,可以直接进行功能测试和上线使用。 + +--- + +## 🚀 HTTP 服务集成 + +### 🔧 技术架构 + +登录服务现在使用 `src/services/httpService.ts` 中封装好的请求方法,实现了更完善的 HTTP 请求管理: + +#### 核心特性 +- **统一请求管理**: 使用 `httpService.post()` 方法进行所有 API 调用 +- **自动错误处理**: 自动处理网络错误、HTTP 状态码错误和业务逻辑错误 +- **智能 Token 管理**: 自动添加认证 Token,支持过期自动刷新 +- **环境配置支持**: 自动使用环境配置中的 API 地址和超时设置 +- **加载状态管理**: 支持自动显示/隐藏加载提示 +- **模拟模式支持**: 开发环境下支持模拟数据返回 + +#### 使用方式 +```typescript +// 微信授权登录 +const auth_response = await httpService.post('/user/wx_auth', { + code: login_result.code +}); + +// 发送短信验证码 +const response = await httpService.post('/user/sms/send', { + phone: phone +}); + +// 验证短信验证码 +const verify_response = await httpService.post('/user/sms/verify', { + phone: phone, + code: code +}); +``` + +### 🌍 环境配置 + +HTTP 服务通过 `src/config/env.ts` 进行环境配置: + +- **开发环境**: 自动使用开发环境配置 +- **测试环境**: 支持测试环境 API 地址 +- **生产环境**: 支持生产环境 API 地址 +- **模拟模式**: 开发环境下可启用模拟数据 + +### 🛡️ 安全特性 + +- **请求头安全**: 自动设置安全的请求头 +- **Token 验证**: 自动验证和刷新认证 Token +- **错误信息保护**: 防止敏感错误信息泄露 +- **请求频率控制**: 支持请求频率限制 + +### 📊 监控和日志 + +- **请求日志**: 详细的请求和响应日志记录 +- **性能监控**: 请求响应时间监控 +- **错误追踪**: 完整的错误堆栈和上下文信息 +- **环境信息**: 当前环境配置信息输出 + +### 🔄 向后兼容 + +- **接口响应格式**: 保持原有的响应格式兼容性 +- **错误处理**: 保持原有的错误处理逻辑 +- **状态管理**: 保持原有的登录状态管理逻辑 + +登录系统现在使用更加健壮和可维护的 HTTP 服务架构,提供了更好的开发体验和运行稳定性。 \ No newline at end of file diff --git a/src/pages/login/api .md b/src/pages/login/api .md new file mode 100644 index 0000000..46c8d73 --- /dev/null +++ b/src/pages/login/api .md @@ -0,0 +1,95 @@ + +// 授权接口 + +fetch("https://sit.light120.com/api/user/wx_auth", { + "headers": { + "accept": "application/json", + "accept-language": "zh-CN,zh;q=0.9", + "content-type": "application/json", + "priority": "u=1, i", + "sec-ch-ua": "\"Chromium\";v=\"134\", \"Not:A-Brand\";v=\"24\", \"Google Chrome\";v=\"134\"", + "sec-ch-ua-mobile": "?0", + "sec-ch-ua-platform": "\"Windows\"", + "sec-fetch-dest": "empty", + "sec-fetch-mode": "cors", + "sec-fetch-site": "same-origin" + }, + "referrer": "https://sit.light120.com/api/docs", + "referrerPolicy": "strict-origin-when-cross-origin", + "body": "{\n \"code\": \"string\"\n}", + "method": "POST", + "mode": "cors", + "credentials": "omit" +}); + + +// 用户手机号一键登录登陆 + fetch("https://sit.light120.com/api/user/phone_verify", { + "headers": { + "accept": "application/json", + "accept-language": "zh-CN,zh;q=0.9", + "content-type": "application/json", + "priority": "u=1, i", + "sec-ch-ua": "\"Chromium\";v=\"134\", \"Not:A-Brand\";v=\"24\", \"Google Chrome\";v=\"134\"", + "sec-ch-ua-mobile": "?0", + "sec-ch-ua-platform": "\"Windows\"", + "sec-fetch-dest": "empty", + "sec-fetch-mode": "cors", + "sec-fetch-site": "same-origin" + }, + "referrer": "https://sit.light120.com/api/docs", + "referrerPolicy": "strict-origin-when-cross-origin", + "body": "{\n \"code\": \"string\"\n}", + "method": "POST", + "mode": "cors", + "credentials": "omit" +}); + + + +// 发送短信 + +fetch("https://sit.light120.com/api/user/sms/send", { + "headers": { + "accept": "application/json", + "accept-language": "zh-CN,zh;q=0.9", + "content-type": "application/json", + "priority": "u=1, i", + "sec-ch-ua": "\"Chromium\";v=\"134\", \"Not:A-Brand\";v=\"24\", \"Google Chrome\";v=\"134\"", + "sec-ch-ua-mobile": "?0", + "sec-ch-ua-platform": "\"Windows\"", + "sec-fetch-dest": "empty", + "sec-fetch-mode": "cors", + "sec-fetch-site": "same-origin" + }, + "referrer": "https://sit.light120.com/api/docs", + "referrerPolicy": "strict-origin-when-cross-origin", + "body": "{\n \"phone\": \"13122585075\"\n}", + "method": "POST", + "mode": "cors", + "credentials": "omit" +}); + + +// 验证验证码接口 + +fetch("https://sit.light120.com/api/user/sms/verify", { + "headers": { + "accept": "application/json", + "accept-language": "zh-CN,zh;q=0.9", + "content-type": "application/json", + "priority": "u=1, i", + "sec-ch-ua": "\"Chromium\";v=\"134\", \"Not:A-Brand\";v=\"24\", \"Google Chrome\";v=\"134\"", + "sec-ch-ua-mobile": "?0", + "sec-ch-ua-platform": "\"Windows\"", + "sec-fetch-dest": "empty", + "sec-fetch-mode": "cors", + "sec-fetch-site": "same-origin" + }, + "referrer": "https://sit.light120.com/api/docs", + "referrerPolicy": "strict-origin-when-cross-origin", + "body": "{\n \"phone\": \"13800138000\",\n \"code\": \"123456\"\n}", + "method": "POST", + "mode": "cors", + "credentials": "omit" +}); \ No newline at end of file diff --git a/src/pages/login/index/index.scss b/src/pages/login/index/index.scss index a4b382a..8c1959e 100644 --- a/src/pages/login/index/index.scss +++ b/src/pages/login/index/index.scss @@ -1,6 +1,6 @@ // 登录页面根据Figma设计稿重新设计 .login_page { - width: 390px; + width: 100vw; height: 100vh; position: relative; overflow: hidden; @@ -17,14 +17,14 @@ width: 100%; height: 100%; z-index: 0; - + .bg_img { width: 100%; height: 100%; - object-fit: cover; + object-position: top; } .bg_overlay { @@ -33,12 +33,10 @@ left: 0; width: 100%; height: 100%; - background: linear-gradient( - 180deg, - rgba(0, 0, 0, 0) 48%, - rgba(0, 0, 0, 0.96) 86%, - rgba(0, 0, 0, 1) 100% - ); + background: linear-gradient(180deg, + rgba(0, 0, 0, 0) 48%, + rgba(0, 0, 0, 0.96) 86%, + rgba(0, 0, 0, 1) 100%); } } @@ -123,13 +121,13 @@ // 品牌区域 .brand_section { - margin-top: 280px; + margin-top: 237px; .logo_container { display: flex; align-items: center; gap: 12px; - margin-bottom:60px; + margin-bottom: 44px; height: 58px; width: 252px; background: url('../../../static/login/yc.svg') no-repeat left top; @@ -143,7 +141,7 @@ background-size: inherit; width: 363px; height: 114px; - + } } @@ -152,9 +150,10 @@ display: flex; flex-direction: column; gap: 12px; - margin-bottom: 40px; + margin-bottom: 64px; .login_button { + width: 100%; display: flex; align-items: center; justify-content: center; @@ -167,7 +166,7 @@ font-weight: 600; font-family: 'PingFang SC'; transition: all 0.3s ease; - + &::after { border: none; } @@ -180,10 +179,12 @@ // 微信登录按钮 &.wechat_button { + background: #FFFFFF; border: 1px solid rgba(0, 0, 0, 0.06); box-shadow: 0px 8px 64px rgba(0, 0, 0, 0.1); backdrop-filter: blur(32px); + margin-bottom: 0px; .button_text { color: #000000; @@ -212,6 +213,7 @@ border: 1px solid rgba(255, 255, 255, 0.1); box-shadow: 0px 8px 64px rgba(0, 0, 0, 0.1); backdrop-filter: blur(32px); + margin-top: 0px; .button_text { color: #FFFFFF; @@ -487,12 +489,11 @@ font-family: 'PingFang SC'; font-weight: 400; font-size: 12px; - color: #07C160; + color: #FFFFFF; line-height: 20px; text-decoration: underline; margin-left: 4px; cursor: pointer; } } -} - +} \ No newline at end of file diff --git a/src/pages/login/index/index.tsx b/src/pages/login/index/index.tsx index 422a979..19b2fe3 100644 --- a/src/pages/login/index/index.tsx +++ b/src/pages/login/index/index.tsx @@ -7,7 +7,7 @@ import './index.scss'; const LoginPage: React.FC = () => { const [is_loading, set_is_loading] = useState(false); const [agree_terms, set_agree_terms] = useState(false); - const [show_terms_layer, set_show_terms_layer] = useState(true); + const [show_terms_layer, set_show_terms_layer] = useState(false); // 微信授权登录 const handle_wechat_login = async () => { @@ -100,7 +100,6 @@ const LoginPage: React.FC = () => { return ( - {/* 背景图片 */} { {/* 品牌区域 */} - + - + @@ -187,43 +186,42 @@ const LoginPage: React.FC = () => { {/* 底部条款浮层 */} - {/* 浮层标题 */} - - 请阅读并同意以下条款 - + {/* 浮层标题 */} + + 请阅读并同意以下条款 + - {/* 条款列表 */} - - handle_view_terms('terms')} - > - 《开场的条款和条件》 - - handle_view_terms('binding')} - > - 《开场与微信号绑定协议》 - - handle_view_terms('privacy')} - > - 《隐私权政策》 - - + {/* 条款列表 */} + + handle_view_terms('terms')} + > + 《开场的条款和条件》 + + handle_view_terms('binding')} + > + 《开场与微信号绑定协议》 + + handle_view_terms('privacy')} + > + 《隐私权政策》 + + - {/* 同意按钮 */} - + {/* 同意按钮 */} + - {/* 底部指示器 */} - + )} diff --git a/src/pages/login/login_flow.md b/src/pages/login/login_flow.md new file mode 100644 index 0000000..2904076 --- /dev/null +++ b/src/pages/login/login_flow.md @@ -0,0 +1,179 @@ +# 登录页面流程串接说明 + +## 整体流程概述 + +登录系统支持两种登录方式: +1. **微信快捷登录** - 主要登录方式 +2. **手机号验证码登录** - 备选登录方式 + +## 流程详细说明 + +### 1. 微信快捷登录流程 + +``` +用户点击微信登录按钮 + ↓ +检查用户协议是否同意 + ↓ (未同意则显示协议浮层) +调用 Taro.login() 获取微信 code + ↓ +调用 Taro.getUserProfile() 获取用户信息 + ↓ +使用 httpService.post() 调用后端接口 /api/user/wx_auth + ↓ +保存登录状态到本地存储 + ↓ +跳转到首页 /pages/index/index +``` + +**接口调用**: +- **方法**: `httpService.post('/user/wx_auth', { code: '微信登录返回的code' })` +- **URL**: `POST https://sit.light120.com/api/user/wx_auth` +- **参数**: `{ "code": "微信登录返回的code" }` +- **响应**: 包含 token 和用户信息的登录成功响应 + +### 2. 手机号验证码登录流程 + +``` +用户点击手机号登录按钮 + ↓ +跳转到验证码页面 /pages/login/verification/index + ↓ +用户输入手机号 + ↓ +点击发送验证码按钮 + ↓ +使用 httpService.post() 调用后端接口 /api/user/sms/send + ↓ +用户输入收到的验证码 + ↓ +点击登录按钮 + ↓ +使用 httpService.post() 调用后端接口 /api/user/sms/verify + ↓ +验证成功后保存登录状态 + ↓ +跳转到首页 /pages/index/index +``` + +**接口调用**: + +#### 发送短信验证码 +- **方法**: `httpService.post('/user/sms/send', { phone: '手机号码' })` +- **URL**: `POST https://sit.light120.com/api/user/sms/send` +- **参数**: `{ "phone": "手机号码" }` +- **响应**: 发送成功或失败的响应 + +#### 验证短信验证码 +- **方法**: `httpService.post('/user/sms/verify', { phone: '手机号码', code: '验证码' })` +- **URL**: `POST https://sit.light120.com/api/user/sms/verify` +- **参数**: `{ "phone": "手机号码", "code": "验证码" }` +- **响应**: 验证成功或失败的响应,成功时包含 token 和用户信息 + +### 3. 用户协议流程 + +``` +用户首次进入登录页面 + ↓ +显示协议浮层,要求用户同意 + ↓ +用户点击协议链接查看详情 + ↓ +跳转到协议页面 /pages/login/terms/index + ↓ +用户返回登录页面 + ↓ +勾选同意协议复选框 + ↓ +协议浮层消失,可以正常登录 +``` + +**协议类型**: +- `terms` - 《开场的条款和条件》 +- `binding` - 《开场与微信号绑定协议》 +- `privacy` - 《隐私权政策》 + +## 技术实现要点 + +### 1. HTTP 服务集成 + +登录服务现在使用 `httpService.ts` 中封装好的请求方法: + +- **统一请求**: 使用 `httpService.post()` 方法 +- **自动处理**: 自动处理请求头、错误处理、加载状态等 +- **环境配置**: 自动使用环境配置中的 API 地址 +- **Token 管理**: 自动处理认证 Token 的添加和刷新 + +### 2. 状态管理 +- `is_loading`: 控制登录按钮加载状态 +- `agree_terms`: 用户协议同意状态 +- `show_terms_layer`: 协议浮层显示状态 + +### 3. 错误处理 +- 网络请求失败时的友好提示 +- 验证码错误时的重试机制 +- 微信授权失败时的降级处理 +- 使用 httpService 的统一错误处理 + +### 4. 本地存储 +- `user_token`: 用户登录令牌 +- `user_info`: 用户基本信息 +- `is_logged_in`: 登录状态标识 +- `login_time`: 登录时间戳 + +### 5. 安全考虑 +- 验证码倒计时防止重复发送 +- 登录状态过期检查(7天) +- 敏感信息不存储在本地 +- 使用 httpService 的 Token 验证机制 + +## 页面跳转关系 + +``` +/pages/login/index/index (登录主页) + ↓ +/pages/login/verification/index (验证码页面) + ↓ +/pages/login/terms/index (协议详情页面) + ↓ +/pages/index/index (应用首页) +``` + +## 接口响应格式 + +### 成功响应 +```json +{ + "success": true, + "message": "操作成功", + "data": { + "token": "用户登录令牌", + "user_info": { + "user_id": "用户ID", + "username": "用户名", + "avatar": "头像URL", + "gender": 0, + "city": "城市", + "province": "省份", + "country": "国家" + } + } +} +``` + +### 失败响应 +```json +{ + "success": false, + "message": "错误信息描述" +} +``` + +## 开发注意事项 + +1. **环境配置**: 确保 envConfig.apiBaseURL 指向正确的环境 +2. **错误处理**: httpService 自动处理大部分错误情况 +3. **用户体验**: 加载状态、倒计时、提示信息等交互细节 +4. **兼容性**: 支持不同版本的微信小程序 +5. **测试**: 在真机和模拟器中测试各种场景 +6. **Token 管理**: 使用 httpService 的自动 Token 管理功能 \ No newline at end of file diff --git a/src/pages/login/login_test.md b/src/pages/login/login_test.md new file mode 100644 index 0000000..73bb583 --- /dev/null +++ b/src/pages/login/login_test.md @@ -0,0 +1,333 @@ +# 登录流程测试配置 + +## 测试环境配置 + +### API 接口地址 +- **测试环境**: `https://sit.light120.com/api` +- **生产环境**: `https://light120.com/api` (待配置) + +### HTTP 服务配置 +- **基础 URL**: 通过 `envConfig.apiBaseURL` 配置 +- **超时时间**: 通过 `envConfig.timeout` 配置 +- **日志开关**: 通过 `envConfig.enableLog` 配置 +- **模拟模式**: 通过 `envConfig.enableMock` 配置 + +### 测试账号信息 +- **测试手机号**: `13800138000` +- **测试验证码**: `123456` (仅用于开发测试) + +## 测试场景 + +### 1. 微信快捷登录测试 + +#### 正常流程测试 +1. 进入登录页面 +2. 勾选同意用户协议 +3. 点击"微信快捷登录"按钮 +4. 验证微信授权弹窗 +5. 确认授权后检查登录成功 +6. 验证跳转到首页 + +#### 异常情况测试 +1. **未同意协议**: 点击登录按钮应显示协议浮层 +2. **微信授权失败**: 模拟网络错误,检查错误提示 +3. **登录接口异常**: 模拟后端接口返回错误 +4. **HTTP 服务异常**: 测试 httpService 的错误处理 + +### 2. 手机号验证码登录测试 + +#### 正常流程测试 +1. 进入登录页面 +2. 点击"手机号验证码登录"按钮 +3. 跳转到验证码页面 +4. 输入手机号 `13800138000` +5. 点击"获取验证码"按钮 +6. 输入验证码 `123456` +7. 点击"登录"按钮 +8. 验证登录成功并跳转 + +#### 异常情况测试 +1. **手机号格式错误**: 输入非11位数字 +2. **验证码格式错误**: 输入非6位数字 +3. **发送验证码失败**: 模拟网络错误 +4. **验证码错误**: 输入错误验证码 +5. **登录接口异常**: 模拟后端接口返回错误 +6. **HTTP 服务异常**: 测试 httpService 的错误处理 + +### 3. 用户协议流程测试 + +#### 协议查看测试 +1. 点击任意协议链接 +2. 验证跳转到对应协议页面 +3. 检查协议内容显示 +4. 返回登录页面 + +#### 协议同意测试 +1. 未勾选协议时尝试登录 +2. 验证协议浮层显示 +3. 勾选协议复选框 +4. 验证浮层消失 +5. 再次尝试登录 + +### 4. HTTP 服务集成测试 + +#### 请求方法测试 +1. **POST 请求**: 验证 `httpService.post()` 方法 +2. **错误处理**: 验证 httpService 的统一错误处理 +3. **Token 管理**: 验证自动 Token 添加和刷新 +4. **加载状态**: 验证自动加载提示显示 + +#### 环境配置测试 +1. **开发环境**: 验证开发环境配置 +2. **测试环境**: 验证测试环境配置 +3. **模拟模式**: 验证模拟数据返回 + +## 接口测试用例 + +### 1. 微信授权接口测试 + +```bash +# 测试接口: POST /api/user/wx_auth +curl -X POST https://sit.light120.com/api/user/wx_auth \ + -H "Content-Type: application/json" \ + -d '{"code": "test_wx_code"}' +``` + +**预期响应**: +```json +{ + "success": true, + "message": "微信登录成功", + "data": { + "token": "wx_token_1234567890", + "user_info": { + "user_id": "wx_user_123", + "username": "测试用户", + "avatar": "https://example.com/avatar.jpg", + "gender": 1, + "city": "深圳", + "province": "广东", + "country": "中国" + } + } +} +``` + +### 2. 发送短信接口测试 + +```bash +# 测试接口: POST /api/user/sms/send +curl -X POST https://sit.light120.com/api/user/sms/send \ + -H "Content-Type: application/json" \ + -d '{"phone": "13800138000"}' +``` + +**预期响应**: +```json +{ + "success": true, + "message": "验证码发送成功" +} +``` + +### 3. 验证验证码接口测试 + +```bash +# 测试接口: POST /api/user/sms/verify +curl -X POST https://sit.light120.com/api/user/sms/verify \ + -H "Content-Type: application/json" \ + -d '{"phone": "13800138000", "code": "123456"}' +``` + +**预期响应**: +```json +{ + "success": true, + "message": "验证成功", + "data": { + "token": "phone_token_1234567890", + "user_info": { + "user_id": "phone_user_123", + "username": "用户8000", + "avatar": "", + "gender": 0, + "city": "", + "province": "", + "country": "" + } + } +} +``` + +## 错误响应测试 + +### 1. 验证码错误 +```bash +curl -X POST https://sit.light120.com/api/user/sms/verify \ + -H "Content-Type: application/json" \ + -d '{"phone": "13800138000", "code": "000000"}' +``` + +**预期响应**: +```json +{ + "success": false, + "message": "验证码错误" +} +``` + +### 2. 手机号格式错误 +```bash +curl -X POST https://sit.light120.com/api/user/sms/send \ + -H "Content-Type: application/json" \ + -d '{"phone": "138001380"}' +``` + +**预期响应**: +```json +{ + "success": false, + "message": "手机号格式错误" +} +``` + +## HTTP 服务测试 + +### 1. 请求头测试 +- 验证 `Content-Type` 自动设置 +- 验证认证 Token 自动添加 +- 验证自定义请求头支持 + +### 2. 错误处理测试 +- 网络连接失败处理 +- HTTP 状态码错误处理 +- 业务逻辑错误处理 +- Token 过期自动处理 + +### 3. 加载状态测试 +- 请求开始时显示加载提示 +- 请求结束时隐藏加载提示 +- 自定义加载文本支持 + +## 性能测试 + +### 1. 接口响应时间 +- **微信授权**: 期望 < 2秒 +- **发送短信**: 期望 < 1秒 +- **验证验证码**: 期望 < 1秒 + +### 2. 并发测试 +- 同时发送多个验证码请求 +- 同时进行多个登录操作 +- 验证系统稳定性 + +### 3. HTTP 服务性能 +- 请求队列处理 +- 超时处理机制 +- 错误重试机制 + +## 兼容性测试 + +### 1. 微信版本兼容 +- 微信 7.0.0+ 版本 +- 微信 8.0.0+ 版本 +- 最新版本微信 + +### 2. 设备兼容 +- iPhone 各型号 +- Android 各品牌 +- 不同屏幕尺寸 + +### 3. 网络环境兼容 +- WiFi 环境 +- 4G/5G 环境 +- 弱网环境 + +## 安全测试 + +### 1. 输入验证 +- SQL 注入防护 +- XSS 攻击防护 +- 手机号格式验证 + +### 2. 接口安全 +- 请求频率限制 +- 验证码有效期 +- Token 安全性 + +### 3. HTTP 服务安全 +- 请求头安全 +- 参数验证 +- 错误信息泄露防护 + +## 测试工具 + +### 1. 接口测试 +- Postman +- curl 命令行 +- 微信开发者工具 + +### 2. 性能测试 +- 浏览器开发者工具 +- 微信开发者工具性能面板 + +### 3. 兼容性测试 +- 真机测试 +- 模拟器测试 +- 不同微信版本测试 + +### 4. HTTP 服务测试 +- 网络调试工具 +- 环境配置测试 +- 模拟模式测试 + +## 测试报告模板 + +### 测试结果记录 +``` +测试日期: _____________ +测试人员: _____________ +测试环境: _____________ + +测试项目: +□ 微信快捷登录 +□ 手机号验证码登录 +□ 用户协议流程 +□ 接口功能测试 +□ HTTP 服务集成测试 +□ 性能测试 +□ 兼容性测试 +□ 安全测试 + +测试结果: +□ 全部通过 +□ 部分通过 +□ 未通过 + +问题记录: +1. ________________ +2. ________________ +3. ________________ + +修复建议: +________________ +________________ +``` + +### HTTP 服务测试结果 +``` +HTTP 服务测试: +□ 基础请求功能 +□ 错误处理机制 +□ Token 管理功能 +□ 加载状态管理 +□ 环境配置支持 +□ 模拟模式支持 + +配置验证: +□ 开发环境配置 +□ 测试环境配置 +□ 生产环境配置 +□ 超时配置 +□ 日志配置 +``` \ No newline at end of file diff --git a/src/pages/login/terms/index.tsx b/src/pages/login/terms/index.tsx index f68475a..f5b94b5 100644 --- a/src/pages/login/terms/index.tsx +++ b/src/pages/login/terms/index.tsx @@ -196,8 +196,7 @@ const TermsPage: React.FC = () => { - {/* 底部指示器 */} - + ); }; diff --git a/src/pages/login/verification/index.tsx b/src/pages/login/verification/index.tsx index 0405b18..3e2da74 100644 --- a/src/pages/login/verification/index.tsx +++ b/src/pages/login/verification/index.tsx @@ -1,7 +1,7 @@ import React, { useState, useEffect } from 'react'; import { View, Text, Input, Button, Image } from '@tarojs/components'; import Taro from '@tarojs/taro'; -import { phone_auth_login } from '../../../services/loginService'; +import { phone_auth_login, send_sms_code } from '../../../services/loginService'; import './index.scss'; const VerificationPage: React.FC = () => { @@ -17,7 +17,7 @@ const VerificationPage: React.FC = () => { }; // 发送验证码 - const handle_send_code = () => { + const handle_send_code = async () => { if (!phone || phone.length !== 11) { Taro.showToast({ title: '请输入正确的手机号', @@ -29,16 +29,34 @@ const VerificationPage: React.FC = () => { if (!can_send_code) return; - // 模拟发送验证码 - Taro.showToast({ - title: '验证码已发送', - icon: 'success', - duration: 2000 - }); + try { + // 调用发送短信接口 + const result = await send_sms_code(phone); + + if (result.success) { + Taro.showToast({ + title: '验证码已发送', + icon: 'success', + duration: 2000 + }); - // 开始倒计时 - setCanSendCode(false); - setCountdown(60); + // 开始倒计时 + setCanSendCode(false); + setCountdown(60); + } else { + Taro.showToast({ + title: result.message || '发送失败', + icon: 'none', + duration: 2000 + }); + } + } catch (error) { + Taro.showToast({ + title: '发送失败,请重试', + icon: 'none', + duration: 2000 + }); + } }; // 倒计时效果 diff --git a/src/services/loginService.ts b/src/services/loginService.ts index 9f6efe6..3852bd7 100644 --- a/src/services/loginService.ts +++ b/src/services/loginService.ts @@ -1,4 +1,5 @@ import Taro from '@tarojs/taro'; +import httpService from './httpService'; // 微信用户信息接口 export interface WechatUserInfo { @@ -19,6 +20,20 @@ export interface LoginResponse { user_info?: WechatUserInfo; } +// 发送短信响应接口 +export interface SmsResponse { + success: boolean; + message: string; +} + +// 验证验证码响应接口 +export interface VerifyCodeResponse { + success: boolean; + message: string; + token?: string; + user_info?: WechatUserInfo; +} + // 微信授权登录 export const wechat_auth_login = async (): Promise => { try { @@ -35,24 +50,26 @@ export const wechat_auth_login = async (): Promise => { // 获取用户信息 const user_profile = await get_user_profile(); - // 模拟发送到后端换取登录状态 - // const response = await Taro.request({ - // url: '/api/wechat/login', - // method: 'POST', - // data: { - // code: login_result.code, - // user_info: user_profile - // } - // }); + // 使用 httpService 调用微信授权接口 + const auth_response = await httpService.post('/user/wx_auth', { + code: login_result.code + }); - // 模拟成功响应 - return { - success: true, - message: '微信登录成功', - token: 'wx_token_' + Date.now(), - user_info: user_profile - }; + if (auth_response.success) { + return { + success: true, + message: '微信登录成功', + token: auth_response.data?.token || 'wx_token_' + Date.now(), + user_info: user_profile + }; + } else { + return { + success: false, + message: auth_response.message || '微信授权失败' + }; + } } catch (error) { + console.error('微信授权登录失败:', error); return { success: false, message: '微信授权失败,请重试' @@ -69,34 +86,85 @@ export interface PhoneLoginParams { // 手机号验证码登录 export const phone_auth_login = async (params: PhoneLoginParams): Promise => { try { - // 模拟网络请求延迟 - await new Promise(resolve => setTimeout(resolve, 1000)); + // 使用 httpService 调用验证验证码接口 + const verify_response = await httpService.post('/user/sms/verify', { + phone: params.phone, + code: params.verification_code + }); - // 模拟验证码验证 - if (params.verification_code === '123456') { - const user_info: WechatUserInfo = { - user_id: 'phone_' + Date.now(), - username: `用户${params.phone.slice(-4)}`, - avatar: '', - gender: 0, - city: '', - province: '', - country: '' - }; - + if (verify_response.success) { return { success: true, message: '登录成功', - token: 'phone_token_' + Date.now(), - user_info + token: verify_response.data?.token || 'phone_token_' + Date.now(), + user_info: verify_response.data?.user_info || { + user_id: 'phone_' + Date.now(), + username: `用户${params.phone.slice(-4)}`, + avatar: '', + gender: 0, + city: '', + province: '', + country: '' + } }; } else { return { success: false, - message: '验证码错误' + message: verify_response.message || '验证码错误' }; } } catch (error) { + console.error('手机号登录失败:', error); + return { + success: false, + message: '网络错误,请稍后重试' + }; + } +}; + +// 发送短信验证码 +export const send_sms_code = async (phone: string): Promise => { + try { + const response = await httpService.post('/user/sms/send', { + phone: phone + }); + + if (response.success) { + return { + success: true, + message: '验证码发送成功' + }; + } else { + return { + success: false, + message: response.message || '验证码发送失败' + }; + } + } catch (error) { + console.error('发送短信失败:', error); + return { + success: false, + message: '网络错误,请稍后重试' + }; + } +}; + +// 验证短信验证码 +export const verify_sms_code = async (phone: string, code: string): Promise => { + try { + const response = await httpService.post('/user/sms/verify', { + phone: phone, + code: code + }); + + return { + success: response.success, + message: response.message || '验证失败', + token: response.data?.token, + user_info: response.data?.user_info + }; + } catch (error) { + console.error('验证验证码失败:', error); return { success: false, message: '网络错误,请稍后重试'