# U8 Chat 2.0 · 群成员标签（可自定义名称）产品需求文档 PRD

| 项目 | 内容 |
|---|---|
| 文档版本 | **v1.6**（2026-10-09，在 v1.5 基础上把「标签」行的位置定下来：**放在「删除联系人 / 发送消息」的上面**（成员资料页按钮行下方，独立一行））。v1.5（2026-10-09，**成员资料页的版式照实机截图对齐**：居中头像 + 白色按钮行 + 「基础信息 / 成员资料」两个 tab）。v1.4（2026-10-09，纠正**入口路径**：点群成员打开的是**成员资料页**（现有行为），**设置标签的入口放在成员资料页里**（一行「标签」），不是在成员列表里直接弹编辑器）。v1.3（2026-10-09 改权限：**去掉「允许成员设置自己的标签」开关**，权限改为**固定规则** —— 所有者可改所有人、管理员只能改自己的和普通成员的、普通成员不能设标签；并新增**「标签可被覆盖」**的规则）。v1.2（2026-10-08）：上限＝16 个半角宽度、角色只用标签胶囊颜色区分、不拦任何词 |
| 功能模块 | 群聊 → 成员名字旁的「标签」；群资料 → 我的标签；群成员列表 → 给成员设标签 |
| 适用端 | 移动端 iOS / Android（本次交付）。Web / Desktop 见第八章 |
| 入口 | ① **所有者 / 管理员**给自己设：群资料 → 我的标签（**普通成员没有这一行**）　② 给别人设：群成员列表 → 点某人 → 设置标签（**所有者可改任何人；管理员只能改普通成员**）　③ **没有权限开关**（权限是固定规则） |
| 演示与逐屏 | 同目录 `index.html`（**14 屏**：iOS 13 ＋ 安卓 1） |
| 参照产品 | Telegram「Member Tags」（官方博客 2026-03-01 + API 文档 `core.telegram.org/api/rank`）。**除下面两条外照 TG 全抄**：① 上限按**显示宽度**算；② 角色靠**标签胶囊的颜色**区分（紫＝所有者 / 绿＝管理员 / 普通成员无胶囊）、**不拦保留词** |
| 设计稿 | Figma `6dsI4eKdAoZr4RP0uILIBq`。**已有画板**：群消息「聊天详情-群组」（安卓 `803:151938`）、群资料「聊天详情-群组信息」`812:182005`。**⚠️ 标签胶囊、我的标签页在画板里都没有**（**成员资料页有画板**：`umRiEY84pJQmfomeNkbjOf`「群组-管理员查看用户资料」iOS `214:9703` 系列 —— 本次只是往里加一行「标签」） —— 本演示给建议稿 |

> **本演示与 PRD 都是「UI 设计之前的输入」**：讲清楚「有哪些页面、从哪儿进、能写什么、写长了什么样」。已有画板（群消息、群资料）照做；没画的部分由本演示给出建议稿。**最终视觉以 UI 设计为准**，按钮摆放、间距一类版式细节不作为评审与验收项。

---

## 一、背景与目标

### 1.1 背景

群里所有人共用一套固定身份：群主显示「所有者」、管理员显示「管理员」、其余人什么都没有。

问题是这三类标签**说明不了任何人是谁**：一个 49 人的工作群里，「管理员」可能是技术、可能是客服、可能是财务。大家只能靠群昵称自己想办法（把职务写进名字里）。

> **U8 现状（产品 2026-10-08 确认）**：群消息里**已经显示发送者名字**，而且**名字就在气泡里面**（气泡第一行），但**没有标签功能**（既没有自定义标签，也没有「所有者 / 管理员」这类默认标签）。所以本次是**在气泡内的名字右边新增一枚标签胶囊**，名字本身与气泡版式都不动。

### 1.2 目标

1. 让**每个群成员**都能给自己名字旁加一段文字（标签），说明自己在这个群里的身份。
2. 让**群主 / 管理员**的身份**一眼可辨**：**所有者＝紫色胶囊、管理员＝绿色胶囊**，而**普通成员没有胶囊、只有一行文字**。
3. 让群主能**一键决定**「标签是人人可写，还是只有管理员能写」。
4. 规则与限制照 Telegram，只有两处按 U8 调整：**上限按显示宽度算**（中文 8 字 / 英文 16 字符）、**不拦保留词**（靠胶囊颜色区分）。

### 1.3 不做什么（一句话）

**不动个人资料**（标签不是个人资料的字段）、**不做分组/多标签**、**不做标签颜色或排序自定义**、**不做标签审核**、**不用词表拦「所有者/管理员」**。

---

## 二、范围

### 2.1 本期做

| # | 模块 | 内容 |
|---|---|---|
| ① | 标签展示 | 群消息**气泡内的第一行**是「发送者名字 + 标签」，在**名字右边**新增一枚标签胶囊（名字 U8 已有，不动）；**自己发的消息也显示**；群成员列表每行显示该成员标签 |
| ② | 角色标识 | **所有者＝紫色胶囊、管理员＝绿色胶囊、普通成员＝没有胶囊只有文字**（颜色由客户端按角色渲染，用户改不掉）；**不加任何图标/徽章** |
| ③ | 自己设标签 | 群资料 →「我的标签」→ 编辑页（输入 + 宽度计数 + 保存 + 清除）。**只有所有者 / 管理员有这一行** |
| ④ | 给别人设标签 | 群成员列表 → 点某人 → **成员资料页** →「标签」行 → 编辑器。**所有者可改任何人；管理员只能改普通成员** |
| ⑤ | 权限（固定规则，无开关） | 所有者＝可改所有群成员；管理员＝可改自己的 ＋ 普通成员（**改不了其他管理员、改不了所有者**）；**普通成员不能设任何标签**（见 4.4） |
| ⑥ | 标签可被覆盖 | 后设的盖掉先设的（同一个人只有一个标签值）；被覆盖的人若自己有权限**仍可再改**（见 4.5） |
| ⑦ | 默认标签 | 群主/管理员没写标签时显示默认的「**所有者**」/「**管理员**」；普通成员没写就什么都不显示 |
| ⑧ | 校验 | ① 超过**16 个半角宽度**（中文 8 个字）→ 拦；② 含 **emoji** → 拦（前端提前拦，不靠服务端报错） |

### 2.2 本期不做

| 不做的事 | 说明 |
|---|---|
| 个人资料里加标签字段 | 标签是「我在这个群里的身份」，只在本群生效（见 3.4） |
| 一个成员多个标签 / 标签分组 | TG 也是每个群里一个标签 |
| 标签颜色、字号自定义 | 胶囊颜色只区分角色，**用户不能改色** |
| **用词表拦「所有者 / 管理员 / 群主」** | **不做** —— 词表拦不住繁体、英文、加空格等变体，只拦得住老实人；改用**胶囊颜色**区分（见 5.2） |
| 标签历史 / 修改记录 | 不留痕，改了就是改了 |
| 群成员搜索里按标签搜 | 本期不做（是否要在搜索结果里**显示**标签见待确认 ⑤） |
| 频道（广播）里的成员标签 | 频道没有「成员」概念，本次不涉及 |
| 深色模式、大字号无障碍 | 随全局一起排期 |

---

## 三、名词与统一口径

### 3.1 标签（Tag / Rank）

- 每个群成员可以有的**一段短文字**，显示在群里自己名字旁边；**每个群各自一份**。
- 服务端字段名沿用 TG：`rank`（官方描述：*just an arbitrary string*）。
- **空 = 没有标签**：普通成员不显示任何东西；群主/管理员回落到**默认标签**。

### 3.2 默认标签（不是数据，是客户端渲染的）

| 身份 | 没写标签时显示 | 说明 |
|---|---|---|
| 群主 | **所有者** | 由客户端按「你是群主」渲染，**不存在服务端数据里**（所以能跟着语言变；TG 官方：*clients should default to showing "Owner"/"Admin" … if the rank flag is not set*） |
| 管理员 | **管理员** | 同上 |
| 普通成员 | （什么都不显示） | 不留空占位 |

### 3.3 角色标识（U8 的区分手段：只用标签胶囊的颜色）

| 身份 | 标签外观 | 演示 |
|---|---|---|
| **所有者（群主）** | **紫色胶囊**（浅紫底 + 深紫字） | [`#A1`](index.html#A1) |
| **管理员** | **绿色胶囊**（浅绿底 + 深绿字） | [`#A2`](index.html#A2) |
| 普通成员 | **没有胶囊，只有一行灰色文字** | [`#A2`](index.html#A2) |

- 颜色由**客户端按角色渲染**，**用户改不掉、也不存在标签文本里** —— 所以不管成员把标签写成什么（哪怕写成「所有者」），系统都能准确区分真角色。
- **不额外加图标或徽章**（产品 2026-10-08 拍板）：角色只靠胶囊颜色区分，界面更干净。
- **自己发的消息同样显示**（[`#A1`](index.html#A1) / [`#A2`](index.html#A2) 最后一条）：自己的气泡是深紫底，名字用半透明白；标签在深底上换成**白底 + 对应色字**（所有者紫字 / 管理员绿字），普通成员则是**白字、无胶囊** —— 换底不换语义。

### 3.4 作用域与可见性

- **本群可见**：标签出现在**这个群**的每条消息上（TG 的超级群把标签随消息一起下发：`message.from_rank`）与**这个群的成员列表**里。
- **私聊、别的群、个人资料页都不显示**；同一个人可以在 A 群叫「技术支持」、在 B 群叫「打杂的」。
- 标签**不影响任何权限**（TG 的 `channels.editAdmin` 把「权限」和「标签」当两个独立参数）——写成「管理员」不会获得管理权限。

### 3.5 谁能改谁（★ U8 是固定规则，与 TG 不同）

| 操作者 | 能改谁 |
|---|---|
| **所有者**（群主） | **所有群成员**（含管理员、含自己） |
| **管理员** | **自己的 ＋ 普通群成员的**（**改不了其他管理员、改不了所有者**） |
| **普通群成员** | **谁都不能改**（连自己的也不行） |

> **与 TG 的差别（重要）**：TG 里「谁能改标签」是**群主可配置的权限**（`manage_ranks` 权限 +「允许成员设置自己的标签」开关），成员默认能改自己的。**U8 不做开关，直接写死成上表**（产品 2026-10-09 拍板）。详见 4.4。

---

## 四、功能详情

### 4.1 展示位一：群消息

- 位置：**气泡里面的第一行** —— `[名字] [标签]`，下面才是消息内容（U8 现在就是「名字在气泡里」，本次只在名字右边加标签，气泡版式不动）。
- 样式：**所有者＝紫色胶囊、管理员＝绿色胶囊、普通成员＝没有胶囊只有文字**。
- ★ **自己发的消息也显示名字 + 标签**（U8 要求，与别人发的一样在气泡第一行）。
  - 自己的气泡是深紫底，所以配色要反过来：**名字用半透明白**；自己的标签若是普通成员 → **白字、无胶囊**；自己若是所有者 / 管理员 → **白底 + 对应色字（紫 / 绿）**，保证在深底上仍然分得清。
- 标签**永远不会被截断**：上限按显示宽度算（见 5.1），写到上限也能在气泡里完整显示。
- 对应演示屏：[`#A1`](index.html#A1)（默认标签「所有者」）/ [`#A2`](index.html#A2)（三档配色，含"普通成员写成『所有者』"的对照）/ [`#A3`](index.html#A3)（写到上限 8 个汉字，完整显示）。

### 4.2 展示位二：群成员列表

- 成员列表每行 = 头像 + 名字 + 标签（**同一套胶囊配色**）。
- 没设标签的普通成员**只有名字**，不留空占位。
- ★ **点某一行 → 进这个人的「成员资料页」**（现有行为，本次不改）。**设置标签的入口在成员资料页里**（一行「标签」），**不在列表里直接弹编辑器** —— 见 4.6。
- 对应演示屏：[`#A4`](index.html#A4)。

### 4.3 设置自己的标签

**入口**：群资料 →「**我的标签**」（右侧显示当前标签；没设过显示「未设置」）——[`#B1`](index.html#B1)

> **谁能看到这一行**：**所有者、管理员**（[`#B1`](index.html#B1)）；**普通成员看不到**（[`#C1`](index.html#C1)）—— 因为普通成员不能设置标签（见 4.4）。

**编辑页**：[`#B2`](index.html#B2)

| 元素 | 规则 |
|---|---|
| 输入框 | 单行文本，可空 |
| 字数计数 | 右下角「当前宽度/16」；**超过上限时变红**。计数按**显示宽度**：中文（全角）算 2、英文（半角）算 1 |
| **中英混排** | **允许**，且走同一套宽度算法 —— 如「技术支持 Support」＝ 8 ＋ 1（空格）＋ 7 ＝ **16**，正好到上限（演示 [`#B2`](index.html#B2)） |
| 保存 | 有改动才可点；保存成功回群资料页，右侧值同步更新 |
| 清除标签 | 清空内容并保存 = 删除标签 → 回默认（见 4.7）；**不需要二次确认** |
| 校验① | 超过 **16 个半角宽度**（中文 8 个字 / 英文 16 个字符）→ 拦，计数变红 |
| 校验② | 含 **emoji** → 拦（[`#B3`](index.html#B3)，红字「标签不能包含表情符号」） |

### 4.4 谁能改标签（★ 固定规则，没有开关）

**产品 2026-10-09 拍板**：不再做「允许成员设置自己的标签」这个开关，权限直接写死成下面这套。

| 操作者 | 改自己的 | 改普通成员 | 改其他管理员 | 改所有者 |
|---|---|---|---|---|
| **所有者**（群主） | ✅ | ✅ | ✅ | ✅（自己） |
| **管理员** | ✅ | ✅ | ❌ | ❌ |
| **普通群成员** | ❌ | ❌ | ❌ | ❌ |

- **普通成员连自己的标签也不能设** —— 所以他的群资料页里**根本没有「我的标签」这一行**（[`#C1`](index.html#C1)）：不是置灰、更不是点了报错。
- **管理员改不了其他管理员、也改不了所有者** —— 在成员列表里点这类人时，**没有「设置标签」入口**（[`#C3`](index.html#C3)）。
- 「能改谁」**只按角色定**，与标签内容无关；**不拦任何词**（见 5.2）。

### 4.5 标签可以被覆盖（★ 后设的盖掉先设的）

**规则**：同一个人身上只有一个标签值，**最后一次写入生效** —— 谁改都算一次写入。

- 产品给的例子（演示里走完了整条链）：管理员**小王**自己设 `AAA` → **所有者**改成 `BBB`（[`#C2`](index.html#C2)）→ **小王自己再改成 `CCC`**（[`#C4`](index.html#C4)）。
- **覆盖只改变值、不改变权限**：小王是管理员，被覆盖后**他仍然能改自己的**；普通成员被覆盖后，只能等所有者 / 管理员再改。
- **不显示来源、不留历史**：群里只显示当前标签，用户看不出「这是谁设的、有没有被改过」。
- **被改的人不会收到通知**（沿用既有口径）。

### 4.6 给成员设标签（入口在「成员资料页」）

**先纠正一个落点**：点群成员打开的是**成员资料页**（现有行为）—— 头像 + 名字 + 操作按钮 + 资料信息 + 成员资料区。**设置标签的入口就放在这一页里**，不影响任何既有结构。

| 项 | 规则 |
|---|---|
| 入口路径 | 群成员列表 → **点某个成员** → **成员资料页** → 按钮行下方的一行「**标签**」（右侧显示当前值）→ 编辑器 |
| 这一行在哪 | 成员资料页的**按钮行下面、「删除联系人 / 发送消息」的上面**（独立一行）。理由：它是「这个人在本群的角色」，既不是对他执行的操作，也不该埋在 tab 里要切一下才看到；样式与群资料页的「我的标签」**同一套、同一个编辑器** |
| 谁能看到这一行 | **所有者**（对任何人都显示）· **管理员**（只对普通成员显示；看其他管理员 / 所有者时没有）· **普通成员看不到**（见 4.4）|
| 页面 | 与「我的标签」**同一个编辑器**，只是改的是别人的值 |
- 权限照 4.4：**管理员能改普通成员**；**所有者能改任何成员**（含管理员）。
- **写成「所有者」「管理员」是允许的** —— U8 **不做保留词校验**（理由见 5.2），保存后群里会出现两枚「所有者」，但**没有紫胶囊的那一枚一眼就能看出是普通成员写的**（[`#A2`](index.html#A2)）。

### 4.7 清空与回退

| 谁 | 清空标签后 | 演示屏 |
|---|---|---|
| 群主 | 回到默认「**所有者**」（紫色胶囊） | [`#D1`](index.html#D1) |
| 管理员 | 回到默认「**管理员**」（绿色胶囊） | [`#D1`](index.html#D1) |
| 普通成员 | **不再显示标签**（只有名字） | [`#D1`](index.html#D1) |

### 4.8 安卓端差异

| 点 | iOS | 安卓 |
|---|---|---|
| 编辑页 | 圆形返回 + 居中标题 + 底部「保存」 | 标题左对齐 + **右上角「保存」**，输入区更宽 —— [`#E1`](index.html#E1) |
| 规则 / 校验 / 胶囊配色 | — | **与 iOS 完全一致** |

---

## 五、限制（★ 本章是本文档的重点）

| # | 限制 | 内容 | 出处 |
|---|---|---|---|
| ① | **长度（U8 调整）** | **最多 16 个半角宽度** = **中文 8 个字 / 英文 16 个字符**（中文 1 个字算 2）。写到上限**一定显示得完** | U8 自定；TG 原规则是「16 个字符」（见 5.1） |
| ② | **字符** | **不能包含 emoji** | `/api/rank`：`rank: The new tag (max 16 chars, no emojis)`；错误码 `ADMIN_RANK_EMOJI_NOT_ALLOWED` |
| ③ | **保留词** | **不拦** —— 写成「所有者」「管理员」都允许，靠 3.3 的**胶囊颜色**区分真角色 | U8 决定（TG 同样不拦，见 5.2） |
| ④ | **与权限的关系** | **无关**：标签不影响任何管理权限（权限是 `admin_rights`，标签是独立的 `rank` 参数） | `/method/channels.editAdmin` 参数表 |
| ⑤ | **谁能改谁** | **U8 固定规则**（与 TG 不同）：所有者可改所有群成员；管理员只能改自己的 ＋ 普通成员；普通成员不能设置标签。**没有开关** | 产品 2026-10-09 拍板 |
| ⑥ | **作用域** | 每个群一份；私聊、别的群、个人资料都不显示 | `/api/rank` |
| ⑦ | **清空** | 清空 = 取消自定义，回落到默认（群主「所有者」、管理员「管理员」、普通成员不显示） | `/api/rank` |
| ⑧ | **取数方式（给开发）** | 超级群：标签随消息下发（`message.from_rank`）；普通群：**消息不带标签**，客户端要从群成员数据（`ChatParticipant.rank`）里取，并靠 `updateChatParticipantRank` 增量更新 | `/api/rank` |

### 5.1 上限为什么是「16 个半角宽度」而不是「16 个字符」

- TG 的规则是**16 个字符**，**不区分语言** —— 中文里 1 个汉字算 1 个字符，所以**中文能写 16 个汉字**。
- 但**能写 ≠ 能显示**：名字和标签挤在**气泡内的同一行** —— 气泡最宽 252pt、左右内边距 24pt，一行可用约 **228pt**；减去发送者名字（按最长 120pt）与 6pt 间距，标签可用宽度约 **100–110pt**。
  - 8 个汉字 ≈ 96pt（含内边距）→ **刚好放得下**；
  - 16 个汉字 ≈ 180pt → **远超气泡宽度，必然被截断**成省略号。
- 用户写完发现自己写的字**看不到全**，会当成 bug 来报。所以 U8 把上限换算成**显示宽度**：**16 个半角宽度**（中文 8 个字 / 英文 16 个字符），**从输入环节就保证能显示完**。
- **影响范围**：这条规则**只作用于标签这一个输入框**，不改动任何已有字段（个人简介 100 个字符等照旧）。代价是前端与服务端各需要**同一个宽度计数函数**（全角 2 / 半角 1），两边必须一致。
- **边界情况**：名字特别长时，名字自己会先被截断（名字行限宽），标签仍有 8 个汉字的空间。

### 5.2 为什么**不拦**「所有者 / 管理员」这类词，改用胶囊颜色区分

**先看 TG 为什么不做**（我们的判断，非官方原话）：

1. TG 已用**颜色**解决这个问题 —— 官方文档原话是「管理员的标签**始终着色**，以区别于非管理员」。它的"专属标识"就是那身颜色。
2. **词表拦不住，只能拦老实人**：拦了「管理员」，还能写「管理員」（繁体）、`Admin`、`Administrator`、`管理 员`（加空格）、`群管`、`客服主管`…… 而且 U8 是全球化产品，词表要按语言维护。
3. TG 的默认标签是**客户端按角色渲染**的，系统里"谁是群主"从来不靠那串文字判定，所以它觉得没必要做这层校验。

**U8 的做法：把 TG 的颜色机制明确成三档**

| | 胶囊颜色区分（U8 采用） | 拦词表（不采用） |
|---|---|---|
| 防变体（繁体 / 英文 / 加空格） | ✅ 系统判定，与文字无关 | ❌ 拦不完 |
| 误伤正常词 | ✅ 不拦任何词（「管理员助理」照用） | ❌ 容易误伤 |
| 维护成本 | ✅ 一次实现 | ❌ 按语言维护词表 |
| 用户困惑 | ✅ 不用解释"为什么不能叫这个" | ❌ 要额外写一句解释文案 |

**效果**：普通成员把标签写成「所有者」时，显示为**一行灰字、没有胶囊**；真群主是**紫色胶囊** —— 用户一眼分得清（演示 [`#A2`](index.html#A2) 就是这个对照）。

---

## 六、屏清单（15 屏，与 `index.html` 锚点一一对应）

| 分组 | 屏 | 名称 | 优先级 | 锚点 |
|---|---|---|---|---|
| A · 标签长什么样（4） | A1 | 群消息 · 群主没设标签 → 显示「所有者」 | P0 | [`#A1`](index.html#A1) |
| | A2 | 群消息 · 怎么改都分得清：紫胶囊 = 所有者 / 绿胶囊 = 管理员 | P0 | [`#A2`](index.html#A2) |
| | A3 | 群消息 · 标签写到上限（8 个汉字）—— 一行刚好放下 | P1 | [`#A3`](index.html#A3) |
| | A4 | 群成员列表 · 标签的第二个展示位 | P0 | [`#A4`](index.html#A4) |
| B · 设自己的标签（3） | B1 | 群资料页 · 入口「我的标签」（**管理员 / 所有者才有这一行**） | P0 | [`#B1`](index.html#B1) |
| | B2 | 设置我的标签（编辑页） | P0 | [`#B2`](index.html#B2) |
| | B3 | 输入不合理 · 含表情符号被拦 | P1 | [`#B3`](index.html#B3) |
| C · 谁能改标签（5） | C1 | 普通成员 · **两处都没有改标签的入口**（群资料页 + 成员资料页） | P0 | [`#C1`](index.html#C1) |
| | C2 | **成员资料页 · 设置标签的入口在这**（一行「标签」）★ | P0 | [`#C2`](index.html#C2) |
| | C3 | 所有者改管理员的标签（**覆盖**：AAA → BBB） | P0 | [`#C3`](index.html#C3) |
| | C4 | 被覆盖之后 · 小王**仍然可以再改自己的**（BBB → CCC） | P1 | [`#C4`](index.html#C4) |
| | C5 | 管理员给**普通成员**设标签（改不了其他管理员） | P0 | [`#C5`](index.html#C5) |
| D · 边界（2） | D1 | 清空标签 → 回到默认 | P1 | [`#D1`](index.html#D1) |
| | D2 | 私聊里不显示标签 | P0 | [`#D2`](index.html#D2) |
| E · 安卓端（1） | E1 | 安卓 · 设置我的标签 | P1 | [`#E1`](index.html#E1) |

---

## 七、异常与边界

| # | 情况 | 处理 |
|---|---|---|
| ① | 保存时断网 / 失败 | 提示「标签保存失败，请检查网络后重试」；**页面保留输入内容**，不静默丢弃 |
| ② | 输入含 emoji | 前端即时标红「标签不能包含表情符号」，保存置灰（不提交服务端） |
| ③ | 输入超过宽度上限 | 计数变红 + 保存置灰；**不做自动截断**（避免用户以为存进去了） |
| ④ | 只输入空格 | 视同空 → 清除标签（保存前 trim） |
| ⑤ | 两个人写了同一个标签 | **允许**（TG 无唯一性要求）；不去重、不提示 |
| ⑦ | 成员被踢出群 / 退群 | 标签随之消失（属于该群的数据） |
| ⑧ | 管理员改别人的标签，对方正在看群 | 下次拉取成员 / 消息时更新（标签随消息下发） |

---

## 八、跨端

| 端 | 现状 | 本次 |
|---|---|---|
| iOS / Android | 有群消息页、群资料页画板 | ★ **本次交付**（同一套规则，两套版式） |
| Web / Desktop | — | **本次不出屏**。规则一致（标签跟在气泡内的名字右边、同一套胶囊配色），等排期时直接落 |
| 频道（广播） | — | 不涉及（频道没有成员标签） |

---

## 九、文案（建议稿，最终以 UI 为准）

| 位置 | 文案 |
|---|---|
| 群资料页入口行 | **我的标签**（未设置时右侧显示「未设置」） |
| 编辑页标题 | 我的标签 / 设置标签（改别人时） |
| 编辑页说明 | 这个标签会显示在你的名字旁边，群里的所有人都能看到。**中英文可以混着写。** |
| 编辑页底部说明 | **最多 8 个汉字（或 16 个英文字符），不支持表情符号。** |
| 编辑页操作 | 保存 / 清除标签 |
| 校验① | 标签不能包含表情符号，请去掉后再保存。 |
| 校验② | 标签最多 8 个汉字（或 16 个英文字符），请删减后再保存。 |
| 默认标签 | **所有者** / **管理员**（客户端按角色渲染，不来自服务端） |
| 标签配色 | **紫色胶囊 = 所有者；绿色胶囊 = 管理员；普通成员＝无胶囊、只有文字** |

> **没有**「该名称不可用 / 该名称为保留字」这类文案 —— U8 不拦保留词（见 5.2）。

---

## 十、接口与埋点（建议）

| # | 能力 | 说明 |
|---|---|---|
| ① | 读 | 群成员列表 / 群消息里随数据带回每人当前标签（`tag` 字段）<br>群主/管理员回一个角色标记（由客户端渲染**胶囊颜色**与默认文案）；**标签文本不存在角色信息** |
| ② | 写（自己） | `设定我的标签(群 id, 文本)`；空字符串 = 清除；**幂等** |
| ③ | 写（他人） | `设定某成员标签(群 id, 成员 id, 文本)`；**服务端必须再校验一次权限**：按 4.4 的角色规则 —— 所有者可改任何人，管理员只能改普通成员，普通成员不能调 |
| ④ | 校验 | 服务端兜底：**按显示宽度 ≤ 16**（全角算 2、半角算 1，与前端同一套函数）、不含 emoji |
| ⑤ | 埋点 | 进入编辑页 / 保存成功（记录宽度桶：1–8、9–16）/ 校验被拦（emoji · 超宽）/ 给别人设标签（记录操作者角色）/ 标签被覆盖 |

---

## 十一、待确认（需要产品 / UI 拍板）

| # | 问题 | 影响 |
|---|---|---|
| ① | **三档配色的具体色值**：紫（所有者）/ 绿（管理员）/ 无胶囊（普通成员）—— 本演示用的是建议色值，最终由 UI 给（注意普通成员那一档**没有底色**，只靠文字颜色区分，要和群昵称的灰度拉开） | UI 出图 |
| ② | 「清除标签」已定为**不二次确认**（可逆）；清完的即时反馈用 toast 还是回到群资料页即可？ | 交互细节 |
| ③ | 标签还要出现在哪些地方：**@提及**、**转发消息**、**群成员搜索结果**、**会话列表**？（本演示只做群消息 + 成员列表） | 展示位清单 |
| ④ | 标签编辑页里那句**说明文案**怎么措辞（所有者看到的 / 管理员看到的，是否要不一样） | 文案 |
| ⑤ | 上限已定为 16 个半角宽度 —— 实施时以**半角宽度**为准，还是改成更直观的「中文 8 个字 / 英文 16 个字符」两句话？ | 校验提示文案 |

> **已拍板（2026-10-08）**：上限＝**16 个半角宽度**（中文 8 个字 / 英文 16 字符，**中英混排**）；角色区分＝**标签胶囊颜色：紫＝所有者、绿＝管理员、普通成员无胶囊**，**不加图标**，**不拦任何保留词**；**自己发的消息也显示标签**。
>
> **已拍板（2026-10-09）**：**不做权限开关** —— 权限＝固定规则：**所有者**可改所有群成员、**管理员**可改自己的 ＋ 普通成员（改不了其他管理员、改不了所有者）、**普通成员不能设置任何标签**；**标签可被覆盖**（后设的盖先设的，被覆盖者若自己有权限仍可再改）。

---

## 十二、相对设计稿改了什么

| 画板 | 本次怎么动 |
|---|---|
| 群消息「聊天详情-群组」（安卓 `803:151938`） | 气泡内的名字**已有**，★ 只在名字右边**加一枚标签**（胶囊 + 文字）；气泡本体、时间、输入栏照画板不动 |
| 群资料「聊天详情-群组信息」`812:182005` | ★ 新增 1 行：「**我的标签**」；群名 / 成员数 / 静音·搜索·退出·更多**照画板不动** |
| 群成员列表 | 版式沿用既有成员列表，★ 每行右侧新增标签 |
| 成员资料页（照实机，本次只加一行「标签」）/ 我的标签 / 设置标签 | **设计稿里没有**，本演示给建议稿（**成员资料页照实机版式**：居中头像 + 白色按钮行 + 两个 tab）。**权限页不做了**（权限是固定规则） |

---

*本 PRD 与同目录 `index.html` 配套使用：PRD 讲规则与限制，演示讲「这屏长什么样、点哪儿去哪」。*
