Files
airz-uniapp/docs/superpowers/specs/2026-10-21-wechat-sms-login-design.md
T
hujun 2c9d3feab5 feat: 完善登录流程、UI适配及协议文档更新
本次提交包含以下修改:
1. 新增微信登录相关服务及页面逻辑,实现首次微信绑定手机号流程
2. 优化产品匹配卡片 UI,移除不必要状态显示
3. 调整首页 scroll-view 属性及 banner 背景样式
4. 完善积分规则校验逻辑,增加时区及策略格式验证
5. 更新协议草案文档,补充资料清单及功能说明
6. 修复分析结果路由路径,适配新的匹配结果页面
7. 调整品牌 Logo 安卓端字体对齐样式
2026-10-22 11:24:15 +08:00

5.4 KiB
Raw Blame History

微信首次绑定手机号与跨端统一账户

用户已确认:微信首次登录必须绑定手机号;各端保留统一的手输手机号和短信验证码流程;2026-10-21明确授权开始本地开发。后续用户明确要求保留Android/iOS运营商本机号码一键登录,作为App待接入功能,与短信登录共用现有账户;本轮小程序首次微信绑定仍使用手输手机号及短信验证。

范围与约束

  • 首期接通微信小程序授权和公共后端;Android/iOS继续复用手机号登录,微信原生授权另行配置接入,不冒充已完成真机验收。
  • Android/iOS保留运营商本机号码一键登录需求;按用户最新要求,当前先还原登录页图标和文字入口,点击展示原“暂未开放”提示,接通认证服务、服务端取号核验及真机验收后启用实际认证。手输手机号和短信验证码作为其他号码及不可用设备的登录方式。运营商认证手机号与现有账户按同一userId关联,不另建账户体系。本次恢复入口不代表服务已经接通,也未选择或开通付费供应商。
  • 沿用PHP7.4/FastAdmin/ThinkPHP、MySQL5.7、Redis及uni-app x/UTS,不新增运行依赖。
  • 两个当前工作区均含用户既有改动。保留所有改动,新建codex功能分支并在仓库外保存逐文件基线;不提交、推送、发布或访问生产数据库/Redis/worker,不发送真实短信或调用真实模型。
  • 后端默认配置关闭;凭据来自环境,不在客户端、日志或验证回执中保存。真实渠道联调另行进行。

账户和登录规则

所有业务继续以现有userId归属。手机号验证码登录和密码登录保留。微信身份只作为登录凭据:小程序应用与openid共同定位身份,不假设App与小程序openid相同,不依赖必然存在的unionid。

微信身份由服务端向微信code2Session验证,拒绝客户端提供openid/appid。首次授权只返回短时绑定票据,不创建会员或业务Token。手输手机号并验证本次绑定用途的验证码后:手机号存在则关联原账户,不存在才创建;同一微信身份或同一应用下的账户绑定冲突均拒绝覆盖。账户禁用时拒绝登录,换绑手机号保持userId,业务资料/积分/额度不重置。

新增独立微信身份映射表,身份和同一应用下账户双唯一;不复用现有无唯一约束的user.openid列。迁移单独提供,仅在本轮隔离库执行,正式迁移未授权。

接口契约

全部为POST,前缀/api/v1,拒绝未知字段与查询参数。

  1. /auth/wechat-login:{platform:'mp-weixin',code,agreements:[{agreementCode,agreementVersion,contentHash,requestId}, ...]}。agreements必须恰好包含terms/privacy当前版本及摘要,requestId各自独立且稳定。绑定有效则返回认证结果;否则返回{status:'bind_required',bindingTicket,expiresIn:600}。
  2. /auth/wechat/sms-code:{bindingTicket,phone}。返回既有retryAfter/expiresIn,专用wechat-bind用途、票据上下文;正常登录验证码不能用于绑定,其他票据验证码不能串用。
  3. /auth/wechat/bind-phone:{bindingTicket,phone,code}。验证票据、当前协议及验证码,在事务内关联或创建会员、保存映射和两份协议同意记录;完成后返回认证结果。

认证结果:{status:'authenticated',token,userId,phone,expiresAt,profile,consentsConfirmed:true}。微信会话密钥不下发。协议确认失败不得返回Token;事务或Token故障撤销新会话。原有手机号/密码登录接口兼容。

票据随机生成、只在内存页面和有过期时间的Redis保存,TTL600秒。按票据加短时互斥锁,验证码原子消费;数据库唯一约束兜底并发。成功作废票据;网络结果未知不自动重发或重新注册,用户重新微信登录可恢复已完成绑定。失败时不给客户端数据库、微信原始响应或身份信息。

页面行为

复用现有登录页,不新建分包页面。微信入口仅在本轮支持的小程序端展示;一键登录按用户最新要求恢复原占位入口,未接通时点击仅提示“暂未开放”,实际运营商认证留待Android/iOS接入。进入微信绑号或已认证状态时不展示其他登录方式,防止干扰当前流程。微信首次授权后显示绑定说明、手机号/验证码及取消入口;取消回到手机号登录。协议尚未发布时保留已有账户密码登录,不能走微信/验证码新入口绕过门禁。

客户端只在页面代次与原会话仍有效时接受认证结果并保存会话,离页或切换账户后的迟到响应不覆盖新会话。票据过期提示重新微信授权;验证码失败可手动重试;结果未知不自动重放。登录后保留现有白名单返回路径。

验证与交付

先写失败测试,再实现。后端用全新本机隔离ROOT/MySQL/Redis及显式bootstrap,微信和短信仅在测试中注入供应商替身,模型端点锁至127.0.0.1:1。验证新/老账户关联、跨用途/跨票据、过期/冲突/并发、禁用、协议变更、事务失败与Token回收;回归现有短信和密码登录。前端执行UTS行为测试、协议回归、小程序编译和受控H5渲染检查;受控测试不冒充微信真机或真实发送。完成后清理仅归属本轮的测试数据与进程,记录结果和未验收范围。