Files
websopy-mp/.workbuddy/memory/2026-04-11.md
赵忠林 2fe14aa2b4 feat(passport): 重写登录与邀请加入流程,支持微信手机号一键登录
- 完全重写 passport/login.tsx,实现微信手机号一键登录功能
- 支持登录页面携带 redirect 参数,登录后自动跳转回原页面
- 登录成功后自动处理邀请加入应用,支持邀请关系绑定
- 重写 passport/invite/index.tsx,实现扫码邀请加入应用完整流程
- 支持调用 wx.login 获取 code,使用 loginByOpenId 判断注册状态
- 未注册用户自动跳转登录页完成微信手机号登录再加入应用
- 已登录用户直接执行加入应用操作,加入接口支持 Authorization 头
-
2026-04-12 10:51:31 +08:00

254 lines
9.0 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 2026-04-11 工作记录
## 任务:修复邀请加入应用流程
### 问题描述
`passport/invite/index` 页面在新用户扫码加入应用时存在问题:
- 新用户点击"微信手机号快速加入"时,如果未注册,后端返回"用户不存在"
- 页面引导用户去登录,但登录完成后**没有自动执行加入应用的操作**
### 解决方案
参考 `UserCard.tsx``phone-auth/index.tsx` 的实现模式,修改了 `src/passport/invite/index.tsx`
#### 1. 新增功能
- 页面加载时保存邀请 token 到本地存储
- 检测用户登录状态
- 未登录用户点击加入时,保存邀请信息并引导到 `phone-auth` 登录页
- 登录成功后返回邀请页面,自动执行加入操作
- 新增 `clearPendingInviteData` 方法清理临时数据
#### 2. 关键修改点
- 使用 `saveInviteParams` 保存邀请信息
- 使用 `pending_invite_*` 系列 storage key 保存待处理的邀请数据
- 页面显示时通过 `AppShow` 事件监听登录返回
- 登录成功后自动调用 `handleJoinApp` 完成加入
#### 3. 流程优化
```
新用户流程:
1. 扫码进入邀请页面 → 保存 invite token
2. 点击"微信手机号快速加入"
3. 检测到未登录 → 保存 pending 数据 → 跳转到 phone-auth
4. 完成登录/注册 → 返回邀请页面
5. 自动检测 pending 数据 → 自动执行加入
6. 加入成功 → 跳转到首页
已登录用户流程:
1. 扫码进入邀请页面
2. 点击"微信手机号快速加入"
3. 直接执行加入操作
4. 加入成功 → 跳转到首页
```
### 文件修改
- `src/passport/invite/index.tsx` - 完整重构邀请流程
---
## 任务:重写 passport/login 页面
### 问题描述
`passport/login.tsx` 页面只有 UI 框架,没有实现登录逻辑:
- 输入框没有绑定状态
- 登录按钮没有点击事件
- 不支持微信手机号登录
- 无法处理邀请流程的重定向
### 解决方案
基于 `phone-auth/index.tsx` 的实现,重写 `login.tsx`
#### 1. 功能实现
- 微信手机号一键登录(使用 `open-type="getPhoneNumber"`
- 支持 `redirect` 参数,登录后返回原页面
- 未注册用户自动注册
- 支持邀请关系绑定
- 服务协议和隐私政策弹窗
#### 2. 跳转逻辑
```
有 redirect 参数:
- TabBar 页面 → switchTab
- 普通页面 → navigateBack 或 redirectTo
无 redirect 参数:
- 跳转到首页 /pages/index/index
```
#### 3. 统一登录入口
-`invite/index.tsx` 中的登录跳转统一改为 `/passport/login`
- 保持与现有代码引用兼容5处引用无需修改
### 文件修改
- `src/passport/login.tsx` - 完全重写为微信手机号登录页面
- `src/passport/invite/index.tsx` - 更新登录跳转链接
---
## 任务:修复登录后加入应用流程
### 问题描述
用户从邀请页面跳转到登录页面完成注册后,返回邀请页面提示"您尚未注册",无法成功加入应用。
### 问题分析
1. 用户在邀请页面点击"微信手机号快速加入"时保存了微信授权码
2. 跳转到登录页面后,用户**重新**进行了微信授权,获得了新的授权码
3. 登录成功后返回邀请页面,但邀请页面使用的是旧的已失效的授权码
4. 导致加入应用失败
### 解决方案
在登录页面登录成功后,直接使用**当前获取的微信授权码**完成加入应用操作:
#### 1. 登录页面修改 (`login.tsx`)
- 添加 `handleJoinAppAfterLogin` 方法
- 登录成功后检测 `pending_invite_token`
- 如果存在,使用当前授权码调用 `/api/_app/developer/invite/accept` 接口
- 加入成功后清理 pending 数据并跳转到首页
- 加入失败则继续正常登录流程
#### 2. 邀请页面修改 (`invite/index.tsx`)
- 优化从登录页返回的处理逻辑
- 检测 `pending_invite_phone_code` 是否存在
- 延迟检查登录页面是否已处理加入操作
- 如果登录页面已处理token 被清除),则显示成功提示并跳转
- 如果登录页面未处理,则自动执行加入操作
### 新的完整流程
```
新用户扫码加入流程:
1. 扫码进入邀请页面
2. 点击"微信手机号快速加入"
3. 检测到未登录,保存 pending 数据,跳转到登录页面
4. 在登录页面勾选协议,点击"微信手机号一键登录"
5. 获取新的微信授权码,完成登录/注册
6. 登录成功后检测到 pending_invite_token自动执行加入应用
7. 加入成功,清理数据,跳转到首页
已登录用户流程:
1. 扫码进入邀请页面
2. 点击"微信手机号快速加入"
3. 直接执行加入操作
4. 加入成功,跳转到首页
```
### 文件修改
- `src/passport/login.tsx` - 添加登录后自动加入应用逻辑
- `src/passport/invite/index.tsx` - 优化从登录页返回的处理逻辑
---
## 任务:修复"用户创建失败"问题
### 问题描述
后端返回 `"用户创建失败"`,原因是微信授权码失效。
### 问题分析
1. 用户在邀请页面获取了微信授权码
2. 跳转到登录页面后,用户**重新**点击授权按钮获取了新的授权码
3. 但代码逻辑可能混淆了新旧授权码
4. 或者授权码已过期5分钟有效期
### 解决方案
1. **明确使用当前获取的授权码**:在登录页面登录成功后,使用**当前**获取的微信授权码执行加入应用操作
2. **不使用旧的授权码**:从邀请页面带过来的授权码仅作为标记用途,实际使用登录时获取的新授权码
3. **添加错误处理**:加入失败时显示错误信息并延迟跳转
### 关键修改
- `login.tsx`:优化 `handleLogin` 中的邀请流程处理逻辑
- 明确使用当前 `phoneCode` 执行加入操作
- 添加错误处理和用户提示
- 加入失败后延迟跳转,让用户看到错误信息
---
## 任务:修复已登录用户加入应用失败问题
### 问题描述
已登录用户点击"微信手机号快速加入"时,后端返回 `"用户创建失败"`
### 问题分析
1. 用户已经是登录状态(有 `access_token`
2. 但后端接口 `/api/_app/developer/invite/accept` 仍然尝试"创建用户"
3. 原因是后端无法识别当前已登录的用户身份
### 解决方案
为已登录用户在请求头中添加 `Authorization: Bearer {access_token}`,让后端能正确识别用户身份:
#### 1. 邀请页面修改 (`invite/index.tsx`)
-`handleJoinApp` 方法中获取 `access_token`
- 构建请求头时,如果用户已登录,添加 `Authorization`
- 添加日志记录是否使用了认证头
#### 2. 登录页面修改 (`login.tsx`)
-`handleJoinAppAfterLogin` 方法中同样添加 `Authorization`
- 确保登录成功后调用加入接口时携带认证信息
### 文件修改
- `src/passport/invite/index.tsx` - 添加 Authorization 请求头支持
- `src/passport/login.tsx` - 添加 Authorization 请求头支持
---
## 任务:修复 401 认证失败问题
### 问题描述
后端返回 `401``"请退出重新登录"``error: "Username not found"`
### 问题分析
1. 请求带了 `Authorization: Bearer {token}`
2. 但后端验证 token 时发现用户不存在
3. 原因可能是:
- token 已过期
- token 对应的用户已被删除
- `/api/_app` 前缀的接口设计为"免登录",使用 `Authorization` 头反而导致认证失败
### 解决方案
`/api/_app` 前缀的接口是小程序专用免登录接口,应该优先使用微信授权码方式:
#### 策略调整
- **有微信授权码**:使用授权码方式,不传 `Authorization`
- **无授权码但已登录**:使用 `Authorization`
#### 修改内容
- `invite/index.tsx`:调整 `handleJoinApp` 方法中的请求头逻辑
- 优先使用微信授权码,避免使用可能过期的 token
### 文件修改
- `src/passport/invite/index.tsx` - 调整认证策略,优先使用微信授权码
---
## 任务:重写邀请加入应用流程
### 新流程设计
1. 扫码进入邀请页面
2. 调用 `wx.login()` 获取 code
3. 调用 `loginByOpenId` 判断用户是否已注册
4. 已注册:显示邀请页面,用户点击加入
5. 未注册:跳转到 `passport/login` 页面完成登录/注册
6. 登录成功后自动执行加入应用操作
### 实现细节
#### 1. 邀请页面 (`invite/index.tsx`)
- 页面状态管理:`loading``checking``invite`/`login`/`error`
- `initPage()`:解析 token保存到 storage
- `checkLoginStatus()`:调用 `loginByOpenId` 检查登录状态
- `navigateToLogin()`:未登录用户跳转到登录页
- `fetchInviteInfo()`:获取邀请信息
- `handleGetPhoneNumber()`:处理微信授权
- `handleJoinApp()`:执行加入应用操作
#### 2. 登录页面 (`login.tsx`)
- 登录成功后检查 `invite_token`
- 如果存在,使用当前授权码自动执行加入应用
- 加入成功后跳转到首页
### 简化点
- 不再使用复杂的 `pending_invite_*` 系列 storage key
- 只使用 `invite_token` 保存邀请标识
- 登录页面直接使用当前获取的微信授权码
### 文件修改
- `src/passport/invite/index.tsx` - 完全重写
- `src/passport/login.tsx` - 更新为使用 `invite_token`