# 微信首次绑定手机号与跨端统一账户 用户已确认:微信首次登录必须绑定手机号;各端保留统一的手输手机号和短信验证码流程;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渲染检查;受控测试不冒充微信真机或真实发送。完成后清理仅归属本轮的测试数据与进程,记录结果和未验收范围。