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

9.0 KiB
Raw Permalink Blame History

2026-04-11 工作记录

任务:修复邀请加入应用流程

问题描述

passport/invite/index 页面在新用户扫码加入应用时存在问题:

  • 新用户点击"微信手机号快速加入"时,如果未注册,后端返回"用户不存在"
  • 页面引导用户去登录,但登录完成后没有自动执行加入应用的操作

解决方案

参考 UserCard.tsxphone-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)

  • 页面状态管理:loadingcheckinginvite/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