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

42 lines
5.4 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-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渲染检查;受控测试不冒充微信真机或真实发送。完成后清理仅归属本轮的测试数据与进程,记录结果和未验收范围。