# U8 Chat 2.0 · 会话列表搜索（聊天历史）产品需求文档 PRD

| 项目 | 内容 |
|---|---|
| 文档版本 | v1.0（评审稿） |
| 功能名称 | 会话列表搜索 / 聊天历史搜索 |
| 端 | iOS（本期）；Android / iPad 不在本期 |
| 设计稿 | Figma `U8 Chat 2.0` → 页面 `iOS端` → 画布 `搜索功能`（node `515-989`，已交付 18 屏） |
| 竞品基线 | Telegram iOS 会话列表顶部搜索（交互与页面表现对齐，范围收敛为 5 类） |
| 关联文档 | 《01_查缺补漏-页面清单与比对.md》 |

---

## 一、背景与目标

### 1.1 背景
用户在 U8 Chat 里积累的聊天记录无法被检索，找一条历史消息只能手动翻聊天列表。本次在**会话列表顶部**新增搜索能力，让用户能按关键词找到聊天、媒体、链接、文件、语音。

### 1.2 目标
1. 用户从会话列表顶部 1 次点击进入搜索，输入关键词即可跨全部会话检索。
2. 结果可按 5 类收敛：**聊天 / 媒体 / 链接 / 文件 / 语音**。
3. 结果能直接二次消费：查看、转发、批量选择、删除、跳回原会话定位。

### 1.3 不做（本期范围外）
- 会话内搜索（进入某个聊天后再搜该聊天的历史）——独立需求，另开文档。
- 音乐 / 音频文件独立 tab（Telegram 有"音乐"tab，我们本期不做，音频类内容归入"文件"与"语音"）。
- 模糊/拼音/错字纠错搜索、语义搜索。
- 全局跨设备云端搜索结果（仅搜本机 + 已同步服务端的消息，具体范围由研发确认）。

---

## 二、名词定义（避免评审扯皮）

| 名词 | 定义 |
|---|---|
| 会话列表搜索 | 在聊天列表页顶部触发的**全局**搜索，跨所有会话 |
| 最近联系人 | 空态顶部横滑头像行，按最近聊天时间排序的联系人/群 |
| 最近搜索 | 空态下方的搜索历史记录列表（用户历史上搜过的关键词） |
| 聊天结果 | 「聊天」tab 中命中的会话（含"聊天和联系人"分区与"消息"分区） |
| 消息结果 | 「聊天」tab 的"消息"分区：命中的具体聊天记录（带上下文一行） |
| 在聊天中查看 | 从搜索结果跳转回原会话并定位高亮该条消息 |
| 多选态 | 长按结果后进入的批量操作状态 |

---

## 三、功能地图

```
聊天列表页
  └─ 顶部搜索框（点击）
       └─ 【搜索页·空态】最近联系人 + 最近搜索 + 清空
            ├─ 输入关键词
            │    └─ 【搜索结果页】5 个 tab
            │         ├─ 聊天：分区「最近」「聊天和联系人」「消息」+ 筛选（所有聊天/私聊/群聊）
            │         ├─ 媒体：网格 + 滚动时间浮层
            │         ├─ 链接：列表
            │         ├─ 文件：列表
            │         └─ 语音：列表
            │              ├─ 长按 → 菜单（转发 / 在聊天中查看 / 选择 / 类型专属项）
            │              ├─ 选择 → 多选态 → 操作栏
            │              │      ├─ 转发 → 转发会话选择页 → 发送
            │              │      └─ 删除 → 二次确认
            │              └─ 在聊天中查看 → 跳回会话并定位高亮
            └─ 清空 → 确认弹窗 → 清空历史
```

---

## 四、页面清单

### 4.1 设计稿已覆盖（18 屏，可直接开发）
见《01_查缺补漏-页面清单与比对.md》第一节完整对照表。

### 4.2 待补页面（设计需出稿，编号与查缺补漏报告一致）

| 优先级 | 新增页面 | 数量 |
|---|---|---|
| P0 | 无结果空态（通用 + 5 个 tab） | 6 |
| P0 | 加载中（整页骨架 / 媒体网格骨架 / 底部翻页） | 2~3 |
| P0 | 失败 / 无网络 + 重试 | 1 |
| P0 | 搜索历史为空 / 最近联系人为空（或改为默认隐藏规则） | 1 |
| P0 | 多选态操作栏（媒体 / 链接 / 文件 / 语音） | 4 |
| P0 | 删除确认弹窗（批量 / 单条） | 2 |
| P0 | 转发结果 Toast（成功 / 部分失败） | 2 |
| P0 | 会话内定位态（"在聊天中查看"落点） | 1 |
| P0 | 列表到底 / 翻页加载中 | 2 |
| P1 | 会话结果长按菜单、筛选空态、转发页空态、搜索历史单条删除、媒体预览完整交互… | 见查缺补漏报告第三节 |

---

## 五、详细功能需求

### 5.1 搜索入口与唤起

| 编号 | 需求 | 说明 |
|---|---|---|
| 5.1.1 | 入口位置 | 会话列表顶部搜索框（聊天列表页已有组件，本次不改入口样式） |
| 5.1.2 | 唤起方式 | 点击搜索框进入搜索页；键盘自动弹起 |
| 5.1.3 | 退出方式 | 点击右上角【取消】→ 清空输入并返回会话列表（**注意：取消不清空搜索历史**） |
| 5.1.4 | 状态保留 | 从搜索结果跳到会话再返回时，保留关键词与所处 tab（建议保留，需研发评估成本） |

### 5.2 搜索页·空态（未输入时）

| 编号 | 需求 | 说明 |
|---|---|---|
| 5.2.1 | 最近联系人 | 顶部横滑头像行，头像下方显示昵称（超长省略号）。点击 → 进入该会话 |
| 5.2.2 | 数量上限 | 建议最多 8 个（需确认，Telegram 约一屏可见数） |
| 5.2.3 | 最近搜索 | 标题行左侧"最近"，右侧"清空"；点击历史词条 → 以该词发起搜索 |
| 5.2.4 | 历史条数 | 建议最多 5 条，超出不展开（本期不做"查看更多"） |
| 5.2.5 | 清空 | 点击"清空" → 二次确认弹窗（已有设计稿 516:1507）→ 确定后仅清空搜索历史，**不影响最近联系人** |
| 5.2.6 | 记入历史时机 | 用户**点击某个结果 / 敲回车**时记入；仅输入未点击不记入（避免脏记录堆叠，需产品确认） |
| 5.2.7 | 重复词处理 | 已存在的词再次搜索时置顶，不产生重复项 |
| 5.2.8 | 空态兜底 | 无历史 → 整块隐藏；无最近联系人 → 整行隐藏 |

### 5.3 搜索结果页·通用

| 编号 | 需求 | 说明 |
|---|---|---|
| 5.3.1 | 触发时机 | 输入 ≥1 个字符即触发；建议 300ms 防抖 |
| 5.3.2 | 清空输入 | 搜索框内出现 ⊗ 图标，点击清空关键词并回到空态 |
| 5.3.3 | tab 栏 | 固定底部：聊天 / 媒体 / 链接 / 文件 / 语音；默认停在「聊天」；是否在 tab 上显示命中数量待确认 |
| 5.3.4 | 结果排序 | 统一按**消息时间倒序**（最新在前） |
| 5.3.5 | 分页 | 滚动到底自动加载下一页，每页建议 20 条；到底提示待确认 |
| 5.3.6 | 关键词高亮 | 命中的关键词在标题/摘要中高亮（设计稿已体现，高亮色值需补标注） |
| 5.3.7 | 三种兜底状态 | 无结果、加载中、加载失败必须在**每个 tab 内**都成立 |

### 5.4 「聊天」tab

| 编号 | 需求 | 说明 |
|---|---|---|
| 5.4.1 | 分区结构 | 自上而下：最近（历史词，与输入内容匹配时展示）→ 聊天和联系人 → 消息 |
| 5.4.2 | 聊天和联系人 | 命中昵称/群名/备注的会话；展示头像 + 名称 + 群成员数或在线状态 |
| 5.4.3 | 消息 | 命中消息内容的记录；展示头像 + 会话名 + 消息摘要 + 时间 |
| 5.4.4 | 筛选（消息区右上） | 下拉：所有聊天 / 私聊 / 群聊；选中项打钩；**筛选是否作用于"聊天和联系人"分区待确认** |
| 5.4.5 | 命中会话的点击 | 进入该会话（不定位） |
| 5.4.6 | 命中消息的点击 | 进入该会话并定位到该条消息（同"在聊天中查看"） |
| 5.4.7 | 长按菜单 | 待设计出稿：置顶 / 标记已读 / 静音 / 删除会话 / 清空聊天记录，建议直接复用聊天列表页长按菜单 |
| 5.4.8 | 状态一致性 | 头像旁状态点、群成员数展示规则需与聊天列表页保持一致 |

### 5.5 「媒体」tab

| 编号 | 需求 | 说明 |
|---|---|---|
| 5.5.1 | 布局 | 三列正方形网格，图片裁切填充，间距一致 |
| 5.5.2 | 内容范围 | 图片 + 视频（视频显示时长角标或播放图标）；GIF/动图待确认 |
| 5.5.3 | 滚动时间浮层 | 滚动时顶部浮出所属时间标签（如"2026 年 7 月"），延时淡出（已有设计稿 516:3346） |
| 5.5.4 | 点击 | 进入大图预览（左右滑动切换、双指缩放、保存/转发入口） |
| 5.5.5 | 长按 | 弹出大图预览 + 菜单：在聊天中查看 / 转发 / 选择；**建议补"保存到相册"** |
| 5.5.6 | 多选 | 长按后选"选择"进入多选态：勾选圈 + 顶部"已选 N 项" + 底部操作栏（转发 / 保存到相册 / 删除 / 分享） |
| 5.5.7 | 选中态 | 多选态下网格间距是否变化需确认（设计稿 06 屏保持网格不变，仅加勾选圈） |

### 5.6 「链接」tab

| 编号 | 需求 | 说明 |
|---|---|---|
| 5.6.1 | 布局 | 列表：网站 favicon 方块 + 标题 + 链接 + 来源会话 + 右侧时间 |
| 5.6.2 | 长按菜单 | 拷贝链接 / 在聊天中查看 / 转发 / 选择（已有设计稿 516:2651） |
| 5.6.3 | 多选 | 已有设计稿 516:2801，需补底部操作栏（转发 / 删除 / 分享） |
| 5.6.4 | 点击 | 待确认：打开链接还是进入会话（Telegram 为打开链接） |

### 5.7 「文件」tab

| 编号 | 需求 | 说明 |
|---|---|---|
| 5.7.1 | 布局 | 列表：文件类型图标（按扩展名区分 apk/mp4/txt/zip/7z…）+ 文件名 + 文件大小 + 来源会话 + 时间 |
| 5.7.2 | 长按菜单 | 转发 / 在聊天中查看 / 选择；**建议补"保存到文件 / 用其他应用打开"** |
| 5.7.3 | 多选 | 待补（转发 / 删除 / 保存 / 分享） |
| 5.7.4 | 文件大小 | 单位规则：<1MB 用 KB，≥1MB 用 MB 保留 1 位小数 |
| 5.7.5 | 点击 | 待确认：直接打开/下载，还是先进入会话 |

### 5.8 「语音」tab

| 编号 | 需求 | 说明 |
|---|---|---|
| 5.8.1 | 布局 | 列表：播放按钮 +「发送者 > 群名」+ 时长（0:09）+ 时间 |
| 5.8.2 | 播放 | 点击播放/暂停，按钮在播放态切换为暂停图标（设计稿已体现两种态） |
| 5.8.3 | 同时播放 | 全局只允许一条语音在播放（与聊天页规则一致） |
| 5.8.4 | 长按菜单 | 转发 / 在聊天中查看 / 选择；建议补"保存语音"；若后续做语音转文字，"转文字"入口放这里 |
| 5.8.5 | 多选 | 待补 |

### 5.9 长按菜单与多选（跨类型规则）

| 编号 | 需求 | 说明 |
|---|---|---|
| 5.9.1 | 触发 | 长按 ≥0.5s 弹出菜单（半透明遮罩 + 浮层） |
| 5.9.2 | 菜单最小集 | 所有类型都必须有：**转发、在聊天中查看、选择** |
| 5.9.3 | 类型专属项 | 链接＝拷贝链接；媒体＝保存到相册、分享；文件＝保存到文件、用其他应用打开；语音＝保存语音 |
| 5.9.4 | 多选操作栏 | 顶部：已选 N 项 + 取消 + 全选；底部：转发 / 删除 / 分享 / 保存（按类型裁剪） |
| 5.9.5 | 删除 | 必须有二次确认：标题"删除 N 条消息"，正文说明"删除后不可恢复"——**"仅删我的记录"还是"对所有人生效"必须产品明确**，涉及 IM 删除语义 |
| 5.9.6 | 多选上限 | 建议上限 100 条，超限提示 |
| 5.9.7 | 退出多选 | 点"取消"或返回箭头退出，勾选清空 |

### 5.10 转发

| 编号 | 需求 | 说明 |
|---|---|---|
| 5.10.1 | 页面 | 转发会话选择页：取消 / 转发 / 选择（未选时）→ 选中后右上变"发送" |
| 5.10.2 | 顶部搜索 | 页内搜索会话与联系人 |
| 5.10.3 | 底部切换 | 聊天 / 联系人 两个 tab（已有设计稿） |
| 5.10.4 | 置顶项 | "我的收藏"固定第一项 |
| 5.10.5 | 多选发送 | 可一次选多个会话，一次性发送 |
| 5.10.6 | 结果反馈 | 成功 → Toast"已转发"并关闭页面；失败 → Toast"转发失败，请重试"；部分失败 → 明确提示 |
| 5.10.7 | 权限 | 群组若限制转发，给出不可转发的置灰或提示 |

### 5.11 在聊天中查看（跳转定位）

| 编号 | 需求 | 说明 |
|---|---|---|
| 5.11.1 | 跳转 | 点击"在聊天中查看"/命中消息 → 回到该会话并滚到该条消息 |
| 5.11.2 | 高亮 | 该条消息短暂高亮（建议 1.5s 渐隐） |
| 5.11.3 | 结果导航 | 会话内顶部显示结果计数 + 上一条/下一条箭头（对齐 Telegram）——**该屏设计稿缺失，需补** |
| 5.11.4 | 返回 | 返回后回到搜索结果页并保留关键词 |
| 5.11.5 | 消息已删除 | 若消息已被删除，提示"该消息已被删除" |

### 5.12 清空搜索历史

| 编号 | 需求 | 说明 |
|---|---|---|
| 5.12.1 | 确认弹窗 | 已有设计稿：标题"清空"，正文"您确定要清空搜索历史记录？"，取消 / 确定（红字） |
| 5.12.2 | 清空范围 | 仅搜索关键词历史，不含最近联系人、不含聊天记录 |
| 5.12.3 | 结果 | 确定后立即清空并回到无历史的空态 |

---

## 六、状态矩阵（每个 tab 都要成立）

| 状态 | 聊天 | 媒体 | 链接 | 文件 | 语音 | 设计稿 |
|---|---|---|---|---|---|---|
| 默认（未输入） | ✅ | ✅ | ✅ | ✅ | ✅ | 516:1093 |
| 有结果 | ✅ | ✅ | ✅ | ✅ | ✅ | 已有 |
| 加载中 | ❌ | ❌ | ❌ | ❌ | ❌ | 待补 |
| 无结果 | ❌ | ❌ | ❌ | ❌ | ❌ | 待补 |
| 加载失败 | ❌ | ❌ | ❌ | ❌ | ❌ | 待补 |
| 分页加载 / 到底 | ❌ | ❌ | ❌ | ❌ | ❌ | 待补 |
| 长按菜单 | ❌ | ✅ | ✅ | ✅ | ✅ | 聊天待补 |
| 多选态 | ❌ | ⚠️ 仅勾选圈 | ✅ | ❌ | ❌ | 待补 |
| 多选操作栏 | ❌ | ❌ | ❌ | ❌ | ❌ | 待补 |

---

## 七、交互规则与边界（研发最关心的一节）

### 7.1 搜索范围与命中规则
- 范围：全部会话（私聊 + 群聊）的历史消息；是否包含已删除会话内的消息待确认。
- 命中字段：会话名、群名、备注名、联系人昵称、消息文本内容。
- 大小写：不区分大小写。
- 不命中：图片里的文字（无 OCR）、语音内容（无转写）。
- 空关键词：不发起请求，直接展示空态。

### 7.2 结果数量
- 单 tab 最多返回建议 200 条（可配置），超出通过翻页加载。
- 是否需要按会话聚合收敛（如"某群有 50 条"折叠）——本期不做，直接平铺。

### 7.3 缓存
- 相同关键词 5 分钟内不发重复请求（可选优化）。
- 搜索页退出后是否保留结果：建议不保留，重进为空态。

### 7.4 时间显示规则（**当前设计稿不统一，需按此收敛**）
| 时间 | 展示 |
|---|---|
| 今天 | `14:53` |
| 昨天 | `昨天` |
| 本周内 | `周一 / 周二 …` |
| 更早（今年） | `07/12`（MM/DD） |
| 跨年 | `2025/07/12` |

> 设计稿现存问题：1 屏出现 `07/19/26`（带年份格式不一致），2 屏出现 `16/13`（非法日期），需回改。

### 7.5 搜索历史规则
- 上限 5 条（超出丢弃最旧）。
- 单条左滑删除（若本期不做则只支持整体清空）。
- 保留时长：永久保留，直到用户手动清空（待确认）。

---

## 八、文案表（评审时逐条确认）

| 场景 | 文案 |
|---|---|
| 搜索框占位 | 搜索 |
| 空态标题 | 最近 |
| 清空入口 | 清空 |
| 清空确认标题 | 清空 |
| 清空确认正文 | 您确定要清空搜索历史记录？ |
| 清空确认按钮 | 取消 / 确定 |
| 分区标题 | 聊天和联系人 / 消息 |
| 筛选 | 所有聊天 / 私聊 / 群聊 |
| 无结果 | 没有找到结果 |
| 加载失败 | 网络异常，请重试 |
| 到底 | 没有更多了 |
| 长按菜单 | 转发 / 在聊天中查看 / 选择 / 拷贝链接 / 保存到相册 / 保存到文件 |
| 转发页 | 取消 / 转发 / 选择 / 发送 |
| 转发成功 | 已转发 |
| 删除确认 | 删除 N 条消息 / 删除后不可恢复 |

---

## 九、埋点建议

| 事件 | 参数 | 用途 |
|---|---|---|
| search_enter | 入口=会话列表 | 搜索渗透率 |
| search_submit | 关键词长度、是否历史词 | 搜索可用性 |
| search_result_view | 命中数、耗时 | 召回质量 |
| search_result_click | tab、结果类型、位置 | 结果有效性 |
| search_tab_switch | 切到 tab | 哪类结果最有价值 |
| search_longpress_action | 类型、菜单项 | 功能使用率 |
| search_forward | 结果类型、数量、目标会话数 | 转发链路 |
| search_history_clear | - | 历史是否有用 |
| search_jump_to_chat | 结果类型 | 定位链路闭环 |

---

## 十、验收标准

1. 会话列表点击搜索框 → 200ms 内进入搜索页且键盘弹起。
2. 输入关键词 → 1s 内返回结果（网络正常），有 loading 过渡。
3. 5 个 tab 均可切换，且每个 tab 在"有结果 / 无结果 / 加载中 / 失败"四种状态下都有正确表现。
4. 媒体网格滚动时正确显示时间浮层。
5. 长按任一结果均可弹出对应菜单；菜单项按类型正确。
6. 多选态可正确计数、可转发、可删除（有二次确认）。
7. "在聊天中查看"能准确定位并高亮目标消息。
8. 清空搜索历史仅清历史，不动聊天记录与最近联系人。
9. 弱网/断网有明确提示与重试。
10. 所有时间显示符合第 7.4 节规则。

---

## 十一、待确认问题（需要产品/设计/研发拍板）

| # | 问题 | 影响 |
|---|---|---|
| Q1 | 长按菜单里的"删除"，是"仅删除我的设备记录"还是"对所有人生效"？ | 决定弹窗文案与后端接口 |
| Q2 | 「聊天」tab 的"私聊/群聊"筛选，是否也作用于"聊天和联系人"分区？ | 决定交互与开发量 |
| Q3 | "消息"筛选是否需要"频道/群组"维度（Telegram 有），我们是否需要第三项？ | 影响筛选项列表 |
| Q4 | 18 屏（默认状态 + 键盘）与 1 屏的关系，是否只是键盘展开态？ | 避免研发重复实现 |
| Q5 | 本期是否出深色模式设计稿？ | 影响设计排期 |
| Q6 | 点击「链接」结果是打开网页还是进入会话？点击「文件」是下载还是进会话？ | 影响交互定义 |
| Q7 | 搜索结果是否需要在 tab 上显示命中数量（如"媒体（23）"）？ | 影响 tab 设计 |
| Q8 | 搜索历史条数与最近联系人数量是否按本文建议（5 / 8）？ | 影响设计稿内容 |
| Q9 | 从搜索结果跳转到会话再返回，是否保留搜索状态？ | 影响实现复杂度 |
| Q10 | 会话内定位态的"上一条/下一条"结果导航，由聊天模块出稿还是搜索模块出稿？ | 职责边界 |
