U8 产品原型站功能原型演示与产品需求文档 · 供开发与决策快速浏览

U8 Chat 2.0 · 修改手机号(换绑)产品需求文档(PRD)

资料与设置 15815 字 02_PRD-修改手机号.md 更新于 2026-09-22
← 返回功能演示列表
项目内容
文档版本v1.1(2026-09-22)· 流程改造:把「修改手机号」从「输入新号 → 验新号 → 直接换绑」改为「先验证原手机号 → 再验证新手机号」。v1.1 已按客户 Figma 设计稿(section「我的-修改手机号」11 个画板)逐屏对齐:版式、文案、错误提示形式(iOS 系统弹窗)、成功/失败弹窗全部照设计稿
功能模块我的 → 编辑 → 编辑资料 → 手机号(页面标题:更改号码)
适用端iOS / Android(同一个 App,一套规则)。Web / Desktop 本期不做,原因见第八章
演示页同目录 index.html(17 屏可点击:设计稿已有 11 屏 + 本次补充 6 屏)
设计稿Figma 6dsI4eKdAoZr4RP0uILIBq(U8 Chat 2.0)· PAGE「iOS端」· SECTION「我的-修改手机号」node 1076:34256 —— 11 个画板(更改号码 / 输入当前手机号验证码 / 输入新手机号 / 已被占用 / 位数不正确 / 输入新手机号的验证码 / 验证码时返回提示 / 验证码错误 / 更改成功 / 更改失败 / 我的-编辑),演示页 M2–M12 与它们一一对应
实机截图客户另给的 5 张实机图(「我的」页、编辑资料、更改号码、新号码、输入验证码短信)—— 用于核实设计稿没画到的细节(如「我的」页的全貌);演示里 M1 按实机截图还原
参照产品Telegram「Change Number」(两步验证的流程形态与它同源,但换绑规则按 U8 的账号体系定义)
一句话需求修改手机号时,先通过验证码验证原手机号,再验证新手机号,两者都通过才能换绑

本 PRD 做了什么:设计稿已经把界面定完了(11 个画板,连错误提示弹窗都画了),缺的是开发照着画板做不出来的判定规则 —— 两次验证的先后顺序靠什么保证、验证码的位数/时长/次数、中途退出怎么办、换绑之后旧号还能不能登录、失败会不会改到一半、接口怎么保证幂等。 这些补齐在第六、七章;第九、十章给出可直接落地的文案与接口顺序;需要拍板的 7 个点在第十一章。 演示页与设计稿的关系:M2–M12 一一对应 11 个画板(版式、文案、弹窗样式 1:1);M1 与 M13–M17 是设计稿没画、但不做就不闭环的 6 屏,屏上都标了「本次补充」(逐条交代见第十二章)。


一、背景与目标

1.1 背景

U8 Chat 的账号体系里,手机号就是登录账号:注册、登录、找回、加好友都围绕它。用户可以换绑,入口在「我的 → 手机号 → 更改号码」。

现状流程(本次要改掉的):

我的 → 更改号码(截图 1)
        ↓ 点「更改号码」
      新号码(截图 2)── 填新号 ──▶ 验证码 ── 验证码正确 ──▶ 号码当场就换了

整个过程中,原手机号只被展示、从未被验证:用户只要手上有一台已登录的设备,就能把账号挪到任意一个自己能收到短信的号码上。

1.2 现状问题(本次要解决的)

#问题后果
1换绑不验证原号码,只验证新号码账号一旦在别人手里(捡到未锁屏的手机、共享设备的登录态、被诱导登录),对方可以无声地把账号改绑到自己控制的号码上,原号主从此登不进来;连"找回"都要走原号验证,而原号已经被换掉了
2换绑不可逆,且没有"这是你本人吗"的确认用户输错一位数字(133 输成 138),账号就绑到了一个陌生号上,且原号主无法自救
3换绑后没有留痕原号码收不到任何通知(连一条"你的账号手机号已变更"的短信都没有),用户发现账号没了时已经过去很久
4两次验证的异常口径不明验证码几位、多久有效、错几次会怎样、中途退出怎么办 —— 现状没有定义,每个端各做一套

1.3 目标

业务目标

  • 把"账号被悄悄换绑"这一类不可逆的账号风险堵住:换绑必须同时持有原号(收得到短信)与新号。
  • 降低与换绑相关的客诉("我号怎么没了"/"我改错了号找不回来")。

用户目标

  • 换绑过程看得懂:清楚知道现在验的是旧号、下一步验的是新号。
  • 换绑不会改错:改错了能立刻发现(新号填错时就在第二步被拦住)。
  • 换绑后知道发生了什么:成功页明确写出新号码;原号码收到一条变更通知。

成功指标(上线首月,目标值需与数据侧对齐后锁定)

指标目标
换绑流程完成率(进入「更改号码」→ 提交成功)≥ 65%(改造前基线需先取数)
因"号码被改成陌生号"产生的账号找回 / 客诉降到 ≈ 0
换绑中途放弃率(进入第 1 步旧号验证后离开)≤ 30%(超过就要看是否被"多一步"劝退)
原号码收到变更通知的到达率≥ 99%
旧号验证步骤的首次校验通过率≥ 90%(低于此值说明用户困惑"为什么要验旧号",见待确认 ②)

二、范围

2.1 本期做

模块内容演示屏
入口我的 → 右上角「编辑」 → 编辑资料 → 「手机号」行(右侧显示当前号码),点进「更改号码」M1、M2
入口页「更改号码」页(设计稿 02,1:1),点按钮进入换绑流程M3
旧号验证(本次新增)短信发到当前号码,5 位验证码,填在 5 个方框里;通过后服务端下发一次性 change_tokenM4
新号码填写「新号码」页(设计稿 04,1:1),填 11 位号码M5
新号验证短信发到新号码,5 位验证码,填在 5 个方框里;输满 5 位自动提交换绑M6(设计稿 07)
结果更改成功弹窗(设计稿 10)+ 失败弹窗(设计稿 11)M7、M12
异常与边界验证码错误 / 过期 / 重发 / 次数超限 / 新号已被占用 / 新号=旧号 / 提交中 / 提交失败M8–M12

2.2 本期不做(明确划出,防止开发自由发挥)

不做的事原因
国家 / 地区选择截图里的「🇨🇳 中国」是展示态,本期只支持 +86。国际号涉及运营商、计费、格式校验一整套,单独立项
邮箱 / 第三方账号绑定与本功能无关;账号体系里只有手机号一个登录标识
旧号验证的白名单(比如"常用设备免验")一旦有例外,这个例外就是攻击面。换绑永远要验旧号,没有例外
弹窗二次确认("确定要更改吗?")只增加点击不增加安全性;安全性由旧号验证码保证
断点续传(中途退出后接着上次继续)换绑是低频高危操作,流程状态不落盘,退出即重来(见 7.5)
换绑后强制所有设备下线本期保持原登录状态,只推送安全通知(见 7.4)。是否强制下线见待确认 ⑥
自动解绑原号码 / 注销原号码不触碰用户的号码归属,只解绑与本账号的关系
换绑历史记录页本期只在设备/安全消息里留一条通知,不做专门的记录页
Web / Desktop 端的换绑见第八章
深色模式、超大字号的适配随全局一起排期

2.3 端一致性

本期只有移动端。iOS 与 Android 同一套规则、同一套文案、同一套验证码参数(位数、时长、次数)。唯一差异是按系统习惯的键盘唤起与短信自动填充(iOS 支持"从短信中填入验证码",Android 走 sms_retriever)。


三、名词定义(务必与开发对齐,避免和现有功能混名)

名词定义
原手机号 / 旧号当前绑定在该账号上的手机号(示例:+86 183 1134 8215)。就是当前的登录账号
新手机号 / 新号用户希望绑上来的号码(示例:+86 133 4455 6678)
旧号验证把验证码短信发到原手机号、由用户回填的这一步(M4)。本次新增
新号验证把验证码短信发到新手机号、由用户回填的这一步(M6)。现状已有,本次位置不变
change_token旧号验证通过后,服务端下发的一次性凭证(有效期 10 分钟)。新号验证码的发送与最终提交都必须带它 —— 这是"顺序不可颠倒、不可跳过"的技术保证
换绑 / 更号把账号与手机号的绑定关系从旧号改到新号。账号本身没有变(账号 ID 不变)
数据转移截图里"你的账号和所有数据都将转移到新的手机号"是用户视角的说法。技术上不存在数据迁移:账号 ID 不变,聊天记录、联系人、群关系、资产本来就在这个账号上,改的只是登录标识(见 7.4)
登录验证码登录时用的短信验证码。与换绑验证码是两套用途,不可互相顶替(见 6.8)
锁定验证码错误次数超限后,对该号码/账号暂停换绑一段时间(不是封号)

⚠️ 开发注意:「数据转移」不要真的写迁移逻辑。换绑 = 更新账号的 phone 字段 + 写一条安全日志 + 发通知。任何"把 A 账号的数据搬到 B 账号"的实现都是错的。


四、用户与场景

角色只有两类:账号持有者与拿到账号的他人(这是本功能的存在理由)。

场景 A · 换手机号(主场景,正常用户)

用户换了运营商号码,从 183 换到 133。他进「我的 → 右上角编辑 → 编辑资料 → 手机号 → 更改号码」, 先收到旧号(183)的验证码并在 M4 填入 → 进入 M5 填新号(133)→ 收到新号(133)的验证码并在 M6 填入 → M7 弹出「手机号码已更改」,点「完成」回「我的」,手机号已经是 133 了。

场景 B · 旧号已经不能用了(最尴尬的真实情况)

用户想把号换掉,是因为旧号卡已经丢了 / 停机了 —— 他收不到旧号的验证码。 这是本次改造必须正面回答的场景:走账号找回流程(申诉 / 人工),不在本流程里开免验证的口子。 ⚠️ 本期没有客服入口,所以这个场景目前没有可点的出口 —— 这正是待确认 ⑤ 必须先拍板的地方。

场景 C · 账号被盗后,攻击者试图换绑

攻击者拿到了用户的登录态(共享设备 / 未锁屏的手机)。他进「更改号码」→ 需要旧号的短信验证码 → 他收不到(短信只发到用户的旧号)→ 流程停在 M4。用户毫无察觉,但账号没有被挪走。 这就是本次改造的全部价值。

场景 D · 用户把新号填错一位

用户在 M5 把 133 输成 138 并继续。因为新号验证码要发到那个错误的号码上,他收不到 → 停留在 M6,可以点「返回」回去改号。账号始终没变。

场景 E · 用户在 M4 反复输错

用户手边没有旧号卡,猜了几次验证码 → 5 次后进入 M15:换绑锁定 24 小时, 但登录、收发消息完全不受影响。文案必须把这一点写出来,否则用户以为账号被封。

场景 F · 换绑中途退出 App

用户在 M6 直接杀掉 App。流程状态不保留:下次进来从「更改号码」(M3)重新开始, 旧号要重新验证一次。理由见 7.5(不做断点续传)。


五、功能总览

我的(M1 · 实机截图 5)
 └─ 右上角「编辑」→ 编辑资料(M2 · 设计稿 01)
     └─ 手机号 +86 183 1134 8215  ›
         └─ 更改号码(M3 · 设计稿 02)
             └─【新增】输入验证码短信(M4 · 设计稿 03)★ 验证当前手机号
                 │     └─ 通过 → 服务端下发 change_token(10 分钟)
                 └─ 新号码(M5 · 设计稿 04)── 填 11 位新号
                     └─ 输入验证码短信(M6 · 设计稿 07)★ 验证新手机号
                         └─ 提交 → 更改成功弹窗(M7 · 设计稿 10)/ 失败弹窗(M12 · 设计稿 11)

异常与边界(M8–M12)
 验证码错误 M8 · 重新发送 M13 · 验证码已过期 M14 · 次数超限(锁定 24h)M15
 新号已被占用 M10 · 新号=当前号 M17 · 提交中 M16 · 更换失败 M12

一条主线(演示页的「▶ 走一遍主流程」就是这个顺序): 我的 → 右上角「编辑」→ 编辑资料 → 手机号 → 更改号码 → 验证当前号码 → 新号码 → 验证新号码 → 更换成功。


六、功能详情

6.1 入口与页面结构

项规则
入口路径我的 → 右上角「编辑」 → 编辑资料 → 「手机号」行(设计稿 01 + 客户实机截图 5 确认)。三屏连起来才是入口:M1「我的」→ M2「编辑资料」→ M3「更改号码」
入口为什么藏在「编辑」里手机号属于资料,与头像 / 姓名 / 简介 / 出生日期 / 账号名同属一页;「编辑资料」里「手机号」这一行右侧直接显示当前号码 + ›,与「账号名」是同一类行(点进去才能改)
「我的」页不放入口行「我的」页顶部那行 +86 183 1134 8215 · @Bosaidong 只做展示、不可点。不要在「我的」页另加「电话 / 手机号」行
导航样式(全流程统一)二级页左上角统一是白色圆形返回按钮(设计稿 01/02/03/04/07 都是它);「编辑资料」右上角另有一个紫色圆形 ✓
页面标题「更改号码」(与设计稿一致,不改)
流程图见第五章。改造后的顺序固定为:验证当前手机号 → 新号码 → 验证新手机号 → 提交,两次验证之间不可插入、不可跳过
返回行为M2 返回 → M1;M3 返回 → M2;M4 返回 → M3;M5 返回 → M4;M6 返回 → M5。<br>验证码页返回要先弹确认(M11「取消手机验证」/ 继续 · 取消),因为它意味着放弃这次换绑;返回不回退验证状态:M4 通过后返回 M3 再进来,要重新验证旧号(change_token 作废)

6.2 入口三屏(M1 我的 / M2 编辑资料 / M3 更改号码)

M1「我的」· 客户实机截图 5

元素规则
右上角「编辑」(紫色文字)进「编辑资料」页(M2)—— 这是本功能真正的入口按钮
左上二维码图标 + 居中大头像(紫光环)+ 昵称 + +86 … · @…纯展示,都不可点
五组卡片(更改个人资料照片 / 我的资料 / 我的收藏 / 通知和声音 · 隐私和安全 · 语言 / 网络诊断 · 关于我们)既有功能,本次不动
底部 Tab聊天(红角标 1)/ 联系人 / 通话 / 我的 —— 是「通话」不是「资产」,未读角标是 1 不是 146

M2「编辑资料」· 设计稿 01,1:1

元素规则
结构圆形返回 + 紫色圆形 ✓ + 头像(紫光环)+「设置新照片」+ 五张卡片(姓名 / 简介 / 出生日期 / 手机号 + 账号名 / 退出登录),每张卡片下面一行灰色说明
「手机号」行左侧文案「手机号」+ 右侧当前号码 + ›;点击 → 「更改号码」(M3)。本功能的入口就是这一行
行样式与「账号名」一致(当前值 + ›,点进去才能改);「出生日期」显示「添加」;这三行都不做就地编辑
⚠️ 与实机截图的差异实机截图 4 的导航是「取消 / 完成」文字,设计稿改成了「圆形返回 + 紫色 ✓」。演示按设计稿画(见待确认 ①)

M3「更改号码」· 设计稿 02,1:1

页面结构:圆形返回按钮 + 居中标题「更改号码」+ 插图(黄鸭抱蓝色 SIM 卡 + 紫框绿屏手机)+ 当前号码 + 两行灰字说明 + 白色胶囊按钮「更改号码」。

元素规则
当前号码完整显示、不脱敏(+86 183 1134 8215):这一页本来就是给本人看的
说明文案「你可以在这里更改手机号。你的账号和所有数据都将转移到新的手机号。」一字不改(设计稿原话)——已经把代价讲清楚了
按钮白底紫字(设计稿原样)。点它 → 进入 M4(验证当前手机号),不直接进新号码页

6.3 【新增】验证当前手机号(M4 · 设计稿 03 · 本次改造的核心)

这一屏就是本次需求要加的那一步,设计稿已经画好了。

项规则
进入方式M3 点「更改号码」后自动发送一条验证码到当前手机号并进入本屏
版式圆形返回 + 灰色气泡插图 + 居中标题「输入验证码短信」+ 居中号码 + 一行灰色小字「这是你当前的登录手机号」+ 5 个方框 + 右下「30s后再试」+ 底部圆角数字键盘
那行灰字的作用旧号验证与新号验证的版式完全一样,只靠这一行区分"这次验的是旧号"。这一行是设计稿画的,必须保留
输入5 位数字,填在 5 个方框里:当前要填的框是紫边框,已填数字在框内
提交输满 5 位自动校验:页面上没有确认按钮,所以不做按钮(这是从设计稿反推的交互)
校验时机输满自动提交一次;失败弹系统弹窗(M8),关掉后焦点回第 1 个框
通过后服务端下发一次性 change_token(10 分钟有效)→ 进 M5
重发右下「30s后再试」是冷却态(不可点);归零后变紫色可点的「重新发送验证码」(M13)
键盘系统数字键盘(仅数字),进页面自动唤起;iOS 支持从短信直接填充
短信文案必须与登录验证码、新号验证码可区分(见 9.2)

为什么这一步不能省:M5/M6 验证的是"新号能不能收到短信",只有 M4 验证的是"正在操作的人是不是账号的主人"。

6.4 新号码(M5 · 设计稿 04,1:1)

元素规则
版式圆形返回 + 大标题「新号码」+ 说明「我们将发送一条含验证码的短信到你的新号码。」+ 国家行 + 号码行 + 底部按钮
国家 / 地区行「🇨🇳 中国」是展示态、不可点(本期只支持 +86,见 2.2)
号码行区号 +86 固定;占位 000 0000 0000;输入后按 3-4-4 分组显示
按钮态空输入 = 浅灰置灰(设计稿 04);有输入 = 紫色实心(设计稿 05/06)。注意:不是"输满 11 位才变紫"
点「继续」的三条出路① 合法 → 请求新号验证码 → 进 M6;② 位数不对 → 弹窗 M9;③ 号码已被其它账号绑定 → 弹窗 M10(在发短信之前拦)
返回回 M4(change_token 未过期时不必重验旧号;过期则回 M3 重来)

6.5 验证新手机号(M6 · 设计稿 07,1:1)

项规则
版式与 M4 完全相同,只有两处不同:号码是刚填的新号;没有「这是你当前的登录手机号」那行,改为右下「← 修改手机号」
输入与提交同 M4:5 个方框、输满 5 位自动提交
「← 修改手机号」回「新号码」页(M5)改号;改号后需重新发送新号验证码
提交结果成功弹窗(M7)或失败弹窗(M12),都盖在本屏之上;设计稿没有单独的"提交中"页(实现口径见 M16)
返回同 M4:先弹「取消手机验证」确认(M11)

6.6 更改成功(M7 · 设计稿 10,弹窗)

项规则
形式盖在验证码页之上的弹窗(不是独立页面):整页加深色遮罩,弹窗居中
弹窗内容紫色圆形 ✓ + 标题「手机号码已更改」+ 新号码 + 两行说明「你的账号和所有数据都已转移到新号码;之后请用新号码 + 验证码登录」+ 紫色胶囊按钮「完成」
「完成」回「我的」页(号码已更新)—— 这是弹窗唯一出口。不做自动跳转、不提供"改回去"入口
同时发生的事原号码收到一条变更通知短信;所有在线设备收到一条安全通知(见 7.4)

6.7 错误与提示:统一用 iOS 系统弹窗(设计稿口径,不要再做行内红字)

场景弹窗文案按钮屏
验证码不正确验证码不正确,请重新输入好M8
手机号位数不正确手机号位数不正确,请检查后重新输入好M9
新号已被占用该手机号已被其他账号绑定,请更换其他手机号好M10
验证码页退出确认取消手机验证继续 | 取消(右加粗)M11
换绑失败手机号码更改失败(+「网络异常,手机号没有发生改变,请检查网络后重试」)确定(胶囊按钮)M12

统一要求:所有错误都在弹窗里说,不用行内红字、不用 toast;弹窗出现时整页加遮罩;「好 / 确定」关掉后回到可重试状态,用户输入的内容保留。

6.8 两次验证的关系(本章是开发最容易做错的地方)

规则说明
顺序不可颠倒必须"旧的先、新的后"。新号验证码的发送与最终提交,都要求携带旧号验证产出的 change_token —— 顺序由服务端保证,不靠前端自觉
不可跳过任一步没有 change_token 的"发送新号验证码 / 提交换绑"请求一律拒绝(403),客户端收到 403 即回 M3 重走
凭证不互通两次验证的验证码不互通,也与登录验证码不互通:服务端按 purpose 区分(change_phone_old / change_phone_new / login),用错用途直接判错并计入错误次数
两步之间的时间窗旧号验证通过后有 10 分钟完成新号验证与提交;超时回到 M4 重新验证旧号
重复提交提交接口必须幂等(客户端带 request_id,服务端去重):连点、弱网重发都只生效一次
失败可重试提交失败不消耗验证码,同一验证码在有效期内可重试同一请求(M12 → 关掉弹窗再点一次)

七、异常与边界

7.1 状态对照表(验收时逐条走)

#场景触发方式界面号码是否变化是否消耗错误次数
1验证码错误在 M4 / M6 输满 5 位自动校验后M8(弹窗「验证码不正确,请重新输入」)否是
2验证码过期超过 5 分钟才提交M14(弹窗「验证码已失效,请重新获取」)否否
3重发倒计时中点「重新发送」停留本屏,灰字不可点否否
4重新发送倒计时归零后点5 个方框清空、焦点回到第 1 个框、重新倒计时(M13 就是这个中间态)否否(计发送上限)
5错误次数超限1 小时内错 5 次M15(弹窗:请 24 小时后再试)否—
6新号已被其它账号绑定M5 点「继续」(发短信前拦)M10否否
7新号=当前号M5 点「继续」M17否否
8提交中在 M6 输满 5 位之后M16(键盘收起、方框变灰、下方显示「正在更改手机号…」)未定否
9提交失败网络异常 / 超时 / 5xxM12(弹窗:手机号码更改失败 / 网络异常,手机号没有发生改变)否否
10提交成功服务端返回成功M7是—
11短信发送失败(运营商侧)send_code 返回失败停在 M4 / M6 + 弹窗「短信发送失败,请稍后重试」(不消耗错误次数)否否
12change_token 过期停留超 10 分钟再操作回 M4 + 提示「本次操作已超时,请重新验证当前号码」否否
13多设备同时换绑另一台设备正在进行停留本屏 + 提示「这个账号正在另一台设备上更改手机号,请稍后再试」否否
14账号被风控限制服务端按风险策略拒绝停留本屏 + 提示「账号暂时被限制,请稍后重试」否否

验收口径:除第 10 行以外,任何情况下手机号都不能发生变化。这是本功能唯一不可妥协的验收项。

7.2 两次验证的验证码参数(同一张表,两端照做)

参数旧号验证(M4)新号验证(M6)备注
位数5 位数字5 位数字与登录验证码位数统一(待确认 ③)
有效期5 分钟5 分钟过期按 M14 处理,不算错
重发间隔60 秒60 秒倒计时期间按钮不可点
单次会话重发上限5 次5 次超了提示"请稍后再试"
同一号码每日发送上限10 条10 条防短信轰炸,跨会话累计
错误上限5 次 / 1 小时5 次 / 1 小时按账号累计(不是按设备)
超限后换绑锁定 24 小时同左只锁换绑,登录不受影响
用途隔离(purpose)change_phone_oldchange_phone_new与 login 完全隔离
一次一码每次重发后旧码立即失效同左避免"旧码还能用"的争议

7.3 限流与锁定:锁什么、不锁什么

项规则
按什么维度限流账号维度累计错误次数;号码维度限制发送条数;另加 IP / 设备维度的一层粗限流(阈值由安全侧定)
锁定的范围只锁「更换手机号」这一个功能(以及本次流程内的发送验证码)
不锁什么登录、收发消息、加好友、改资料、设备管理 —— 完全不受影响。文案必须写出来(见 M15)
解锁到期自动解锁;本期不做手动解锁 / 申诉入口(客服能力未上线,见待确认 ④⑤)
锁定期内的界面M4 / M6 方框禁用、「重新发送」不可点;弹窗告知原因与时长(同 M8/M9 的系统弹窗样式)

7.4 换绑成功之后(本节是最容易被追问的部分)

项口径
账号本身账号 ID 不变、密码/邮箱等其余字段不变,只更新登录标识(手机号)
聊天数据一条都不会动:会话、消息、联系人、群成员关系、收藏、资产、钱包余额等全部随账号走(因为它们本来就属于这个账号)
「数据转移」的说法界面照截图文案说"转移",但实现上没有任何迁移动作。不要为此写迁移逻辑
已登录设备保持在线上(本期不强制下线)。所有在线设备收到一条安全通知:「你的账号手机号已于 {时间} 变更为 {新号}。若非本人操作,请及时检查账号安全与登录设备。」
原号码(旧号)① 立刻不能再登录本账号(登录按新号查账号);② 收到一条变更通知短信:「你的账号已解除与本次号码的绑定。若非本人操作,请及时检查账号安全与登录设备。」——这是留痕,必须有
新号码立刻成为登录标识;下一次登录需要用它 + 验证码(会话内的登录态不受影响)
旧号能否立刻注册新账号建议冷却 30 天(防"换号后旧号被别人拿走再注册、造成混淆与骚扰")—— 见待确认 ⑥
隐私开关「通过手机号找到我 / 手机号对好友可见」等开关保持原值,值本身变成新号(口径见待确认 ⑦)
安全日志记录一条事件:时间、账号 ID、旧号(掩码)、新号(掩码)、设备名 / IP / 位置 —— 与「设备管理」模块复用同一套安全事件通道

7.5 中断、返回与并发

场景规则
中途退出 App / 杀进程流程状态不落盘(本地不存"已验证旧号"这种状态)。下次进来从 M3 重新开始,旧号重新验证一次。理由:换绑是低频高危操作,不做断点续传可以少一个可被利用的状态
返回上一屏M4→M3、M5→M4、M6→M5 都可以返回。返回 M3 会作废 change_token,再进来要重新验证旧号
停留在 M4 / M6 太久验证码 5 分钟过期(M14);change_token 10 分钟过期(回 M4)
来电 / 短信打断不做特殊处理,回来继续(倒计时按服务端时间算,不按本地)
同一账号多设备并发以"先进入旧号验证"的会话为准:第二台设备发起时提示"正在另一台设备上更改手机号"(见 7.1 #13)。若第一台 10 分钟未完成(token 过期),第二台可继续
提交中杀进程服务端仍会完成本次换绑(请求已发出)。用户重新打开 App 看到的是新号码 —— 因此提交中的返回拦截很重要(避免用户以为已取消)
重复触发提交(输满自动提交后误触 / 弱网重发)幂等(request_id),只生效一次

7.6 号码合法性与输入格式

项规则
合法格式11 位、以 1[3-9] 开头(+86 区段)
输入只接受数字;粘贴内容里的 +86、空格、-、()自动清洗
显示按 3-4-4 分组(133 4455 6678),与截图一致
不合法时按钮保持置灰,不弹错误提示(输入过程中不打扰)。点了也不发短信
国际号本期不支持(国家/地区行是展示态)
号码变更后存服务端时统一存 +86 + 11 位纯数字

八、跨端差异(Web / Desktop)

端本期安排
iOS / Android本期做,规则、文案、参数完全一致
Web本期不做。Web 的登录形态与移动端不同(扫码 / 密码),换绑入口与验证链路要单独定义
Desktop本期不做。如果 Desktop 上已经有"更改手机号"的入口,本期必须先下线或置灰它 —— 安全改造必须同时堵住所有端,否则旧流程仍然是一个可被利用的口子(这条是硬要求,不是建议)
服务端接口按"通用换绑"设计(purpose + change_token + 幂等),未来 Web / Desktop 直接复用,不需要再改协议

九、文案(全部按设计稿,逐条可复制)

9.1 界面文案

屏位置文案来源
M1右上角编辑实机截图 5
M2标题行手机号 → +86 183 1134 8215 ›设计稿 01
M2卡片说明输入您的姓名并添加可选的个人资料照片 / 你可以添加几行关于自己的信息 / 完善生日信息,结识更多有缘的朋友设计稿 01
M3标题 / 说明 / 按钮更改号码 / 你可以在这里更改手机号。你的账号和所有数据都将转移到新的手机号。/ 更改号码设计稿 02
M4标题 / 号码输入验证码短信 / +86 183 1134 8215设计稿 03
M4号码下方灰字这是你当前的登录手机号设计稿 03(旧号验证的专用标识)
M4 / M6重发(冷却中)30s后再试({n}s后再试)设计稿 03 / 07
M4 / M6重发(可点)重新发送验证码本次补充(倒计时归零后)
M5标题 / 说明 / 占位新号码 / 我们将发送一条含验证码的短信到你的新号码。/ 000 0000 0000设计稿 04
M5按钮继续设计稿 04
M6底部链接← 修改手机号设计稿 07
M7弹窗(成功)手机号码已更改 / {新号码} / 你的账号和所有数据都已转移到新号码;之后请用新号码 + 验证码登录 / 完成设计稿 10
M8弹窗(错误)验证码不正确,请重新输入 / 好设计稿 09
M9弹窗(错误)手机号位数不正确,请检查后重新输入 / 好设计稿 06
M10弹窗(错误)该手机号已被其他账号绑定,请更换其他手机号 / 好设计稿 05
M11弹窗(确认)取消手机验证 / 继续 | 取消设计稿 08
M12弹窗(失败)手机号码更改失败 / 网络异常,手机号没有发生改变,请检查网络后重试 / 确定设计稿 11
M13重发(可点)重新发送验证码本次补充
M14弹窗验证码已失效,请重新获取 / 好本次补充
M15弹窗验证码错误次数过多,请 24 小时后再试。你当前的号码仍可正常使用 / 好本次补充
M16进度提示正在更改手机号… / 请不要关闭 App,通常 3 秒内完成。本次补充
M17弹窗这就是你当前的号码,无需更改 / 好本次补充
通用change_token 过期本次操作已超时,请重新验证当前号码本次补充
通用短信发送失败短信发送失败,请稍后重试本次补充
通用多设备并发这个账号正在另一台设备上更改手机号,请稍后再试本次补充
通用风控限制账号暂时被限制,请稍后重试本次补充(无客服入口,文案里不出现「联系客服」)

9.2 短信模板(三条都必须能互相区分)

用途发给谁文案
旧号验证码原手机号【U8 Chat】验证码 {code},用于更改你账号的手机号。5 分钟内有效。若非本人操作,请勿泄露此验证码。
新号验证码新手机号【U8 Chat】验证码 {code},用于把它绑定为你的新手机号。5 分钟内有效。
变更完成通知原手机号【U8 Chat】你的账号已解除与本次号码的绑定,当前绑定的手机号为 {新号掩码}。若非本人操作,请及时检查账号安全与登录设备。

三条短信的目的不同:前两条是"你要做一件事",第三条是"有人做了一个动作,这是给你留的痕"。第三条是本改造配套的必备项。

⚠️ 本期没有客服功能:短信与通知里的「请联系客服」已统一改为「请及时检查账号安全与登录设备」;等客服入口上线后再补回客服引导(见待确认 ⑤)。

9.3 站内安全通知(所有已登录设备)

你的账号手机号已于 {时间} 变更为 {新号}。若非本人操作,请及时检查账号安全与登录设备。

十、接口顺序、幂等与埋点

10.1 接口顺序(顺序即安全边界)

#接口(建议命名)入参要点出参要点备注
1POST /account/change_phone/old/send_code账号 ID(从登录态取,不接受客户端传号码)掩码后的旧号、倒计时秒数短信只发到服务端记录的当前号码
2POST /account/change_phone/old/check_codecodechange_token(10 分钟)、过期时间校验通过才发 token;失败返剩余次数
3POST /account/change_phone/new/check_numberchange_token、new_phone可用 / 已被占用 / 与当前号相同发短信前先拦(M10 / M17)
4POST /account/change_phone/new/send_codechange_token、new_phone倒计时、掩码新号必须带合法 token,否则 403
5POST /account/change_phone/commitchange_token、new_phone、code、request_id成功 / 各类失败码幂等;成功后作废 token、发通知、写安全日志

硬性要求:接口 1、2 不接受客户端传入的手机号(一律以服务端的当前绑定为准)。否则"先验旧号"就形同虚设。

10.2 幂等与并发

项要求
commit 幂等以 request_id(客户端生成 UUID)+ 账号 ID 去重;重复请求返回同一结果
change_token 一次性提交成功后立即作废;重复提交返回"已完成"而不是报错
账号级互斥同一账号同时只允许一个换绑会话(见 7.5)
验证码一次性校验成功后该码立即失效(防重放)

10.3 埋点

事件触发时机关键参数
change_phone_entry_click点「我的 → 电话」来源页
change_phone_start点「更改号码」—
change_phone_old_code_sent旧号验证码下发是否重发、第几次
change_phone_old_code_fail旧号验证码校验失败剩余次数、错误码
change_phone_old_verified旧号验证通过耗时(从 start 起)
change_phone_new_number_submitM5 点「继续」是否被拦(占用 / 同号 / 格式)
change_phone_new_code_sent新号验证码下发是否重发
change_phone_commit验证码输满 5 位自动提交(M6)—
change_phone_commit_result提交换绑返回success / fail + 失败码 + 耗时
change_phone_done到达 M7总耗时、重发次数、错误次数
change_phone_locked触发锁定错误次数
change_phone_abandon中途离开(M4 / M5 / M6 退出)停在哪个屏、停留时长

关键看板:改造前后完成率对比 + 卡在哪一步放弃最多。如果 M4 的放弃率异常高,说明"为什么多一步"没讲清楚(对应待确认 ②)。


十一、待确认(需要产品拍板,开发据此实现)

#问题建议
①点「编辑资料」里的「手机号」行后,是跳「更改号码」页,还是像「账号名」那样就地编辑?建议跳页(当前设计,与截图 1 一致):换绑要「先验旧号、再验新号」,就地编辑放不下这条流程。入口按截图 4 不动:路径=我的 → 编辑 → 手机号,行内文案就叫「手机号」
②M3 是否需要一行"为什么要先验旧号"的说明?建议加:「为保护账号安全,需要先验证你当前的手机号。」这是新增步骤唯一的解释入口,缺了会有"怎么多一步"的困惑
③换绑验证码用几位?验证码页要不要「确认按钮」?位数与登录验证码一致(演示按 5 位画;若登录是 6 位就同步改 6 位,同一套验证码服务)。截图 3 上没有确认按钮,因此按输满 5 位自动提交实现 —— 若产品希望「输满后还要再点一下」,需要改截图 3 的版式:这是本 PRD 唯一一处从截图反推的交互,请先确认
④错误次数上限与锁定时长?建议 5 次 / 1 小时 → 锁定 24 小时;本期不做申诉通道(没有客服入口),到期自动解锁
⑤旧号已经停机 / 丢失、收不到旧号验证码的用户走哪条路?走账号找回(申诉 + 人工核验),不在换绑流程里开免验证口子。⚠️ 本期没有客服功能:M4 只能先给「没收到?请检查信号与短信拦截」这类自助提示;等客服 / 申诉入口上线后,再补「旧号收不到验证码怎么办」的引导(这件事必须先有结论,否则这部分用户会卡死在 M4)
⑥换绑成功后:① 原号码能否立即注册新账号?② 已登录设备是否强制下线?① 建议冷却 30 天;② 建议不强制下线,只推送安全通知(强制下线会让"在别的设备上正常使用"的用户突然被踢,体验代价大)
⑦换绑后,「通过手机号找到我 / 手机号对好友可见」等隐私开关如何取值?建议开关保持原值,值变为新号;但要在成功页或通知里提醒一句"新号码现在可以被搜到"(若开关是开着的)

十二、相对设计稿改了什么(逐条交代,没有偷偷加功能)

#改动性质
1「更改号码」按钮的下一步:从「新号码」页改成「验证当前手机号」页本次唯一的功能改动(就是需求本身)。设计稿已经画好这一屏(画板 03)
2新增 M1「我的」页(按实机截图 5 还原)补齐入口路径的第一屏;设计稿 section 里没有这一屏
3新增 M13–M17:重新发送可点态 / 验证码已过期 / 次数超限锁定 / 提交中 / 新号=当前号设计稿未画。属于"必须有但不能只是瞬时一闪"的实现细节与安全边界,按 PRD 第七、十章执行;屏上标注了「本次补充」
4弹窗样式按设计稿(iOS 系统弹窗 + 成功/失败结果弹窗)上一版我自造的"行内红字提示条 / 独立成功页"已全部删掉
5上一版自造的「我的 → 电话」入口行已删除入口以设计稿 01 为准:我的 → 编辑 → 手机号
6截图 1 / 2 / 3 / 5 与设计稿 01–11 的版式、文案、按钮位置:一字未改视觉零改动(唯一例外:演示里的插图与头像用 SVG / 首字占位重绘,不是设计稿的位图素材)
7去掉所有「联系客服」入口,短信与通知里「请联系客服」的表述一并改掉本期没有客服功能,先隐藏
8短信模板从 1 条变成 3 条(旧号验证码 / 新号验证码 / 变更通知)配套改造(见 9.2)
9Desktop 端若已有换绑入口,本期必须先下线配套改造(见第八章)

附:演示页怎么用

  1. 打开同目录 index.html。
  2. 点页面上的虚线框(鼠标悬停会显示它会跳到哪一屏),就能沿真实流程一步步走;也可以用 <kbd>←</kbd> <kbd>→</kbd> 切屏、按 <kbd>H</kbd> 显示 / 隐藏热区。
  3. 左栏可以按「设计稿已有 / 本次补充」筛屏:
    • 设计稿已有(11 屏,M2–M12):与 Figma 设计稿的 11 个画板一一对应(更改号码 / 输入当前手机号验证码 / 输入新手机号 / 已被占用 / 位数不正确 / 输入新手机的验证码 / 返回提示 / 验证码错误 / 更改成功 / 更改失败 / 我的-编辑),版式、文案、弹窗样式 1:1;
    • 本次补充(6 屏,M1、M13–M17):设计稿没画、但不做就不闭环的部分(入口路径第一屏 + 重新发送 / 过期 / 锁定 / 提交中 / 新号=当前号),屏上都标了「本次补充」。
  4. 点「▶ 走一遍主流程」自动按顺序演示:我的 → 编辑资料 → 更改号码 → 验证当前手机号 → 新号码 → 验证新手机号 → 更改成功。
  5. 每一屏右侧的说明面板里,「待确认」黄框就是需要拍板的问题(与第十一章一一对应)。