外观
联系人聊天模块 —— 全量验证方案(终版)
范围:一期(好友/单聊/多类型消息)+ 二期(群聊/合并转发/typing/勿扰/导出)+ 三期(审计/封禁/敏感词)。 执行方式:API 级(curl/python,全部可自动化)+ 实机级(Android App,需人工)。本文档记录 API 级验证结果。
1. 验证环境
| 项 | 值 |
|---|---|
| API | https://api.la998.com |
| 管理后台 | https://codenote.la998.com(admin/admin123) |
| 测试账号 | A=test_chat_a_1786084043(userId=2,token 变量 TA) |
| B=test_chat_b_1786084043(userId=3,token 变量 TB) | |
| 密码 | Test123456 |
| Android | 1.0.32(待发布) |
2. API 级验证用例(全部已执行 ✅)
2.1 好友链路
| # | 用例 | 操作 | 预期 | 结果 |
|---|---|---|---|---|
| C01 | 发好友申请 | POST /api/contacts/requests | 200 PENDING | ✅ |
| C02 | 收申请列表 | GET /api/contacts/requests/incoming(B) | 含 A 的申请 | ✅ |
| C03 | 通过申请 | POST /api/contacts/requests/1/accept(B) | 200,双向好友 isMutual=true | ✅ |
| C04 | 重复申请 | 再发同对申请 | 400 "已经是好友" | ✅ |
| C05 | 非好友发消息 | 删好友后发 | 4011 朋友验证 | ✅ |
| C06 | 拉黑/取消 | block → B 发 4012 → unblock → B 发成功 | 4012 拦截/恢复 | ✅ |
| C07 | 搜索 | GET /api/contacts/search?keyword=昵称 | 命中 + isFriend | ✅ |
| C08 | 备注/标签 | PUT remark/tags | 200 | ✅ |
| C09 | 名片码 | my-qrcode → by-qr-code/ | user:{随机码} 反查成功 | ✅ |
| C10 | 隐私设置 | PUT settings | 生效 | ✅ |
2.2 单聊消息
| # | 用例 | 操作 | 预期 | 结果 |
|---|---|---|---|---|
| M01 | 懒建会话发消息 | POST /api/chats/messages | 自动建会话,SENT | ✅ |
| M02 | 幂等 | 同 clientMsgId 重发 | 返回原消息不重复 | ✅ |
| M03 | 会话列表 | GET /api/chats/conversations | 未读/摘要/peer 正确 | ✅ |
| M04 | 历史分页 | GET .../messages?beforeId=&limit= | 倒序游标 | ✅ |
| M05 | 已读 | POST .../read | 未读归零 | ✅ |
| M06 | 撤回 | 2min 内 recall | RECALLED 双方可见 | ✅ |
| M07 | 撤回超时 | 超 2min recall | 4014 | ✅ |
| M08 | 引用/转发 | forward | 复制消息 forward_from_id | ✅ |
| M09 | 合并转发 | forward-merged | CARD(CHAT_RECORD) 单条 | ✅ |
| M10 | 清空 | DELETE .../messages | 清空游标生效,历史空 | ✅ |
| M11 | 置顶/草稿 | pin/draft | 200 | ✅ |
| M12 | 类型校验 | IMAGE 无 url / 超配额 | 4021 | ✅ |
| M13 | 未知类型 | msgType=XXX | 4020 | ✅ |
2.3 群聊
| # | 用例 | 操作 | 预期 | 结果 |
|---|---|---|---|---|
| G01 | 建群 | POST /api/chats/groups | GROUP 会话,OWNER,群主正确 | ✅ |
| G02 | 非好友拉群 | memberIds 含非好友 | 4011 | ✅ |
| G03 | 群消息 | B 发 → A 历史可见 | 发送者正确 | ✅ |
| G04 | 群系统消息 | 建群/事件 | SYSTEM sender=0 居中灰字 | ✅ |
| G05 | 设管理员 | POST .../members/3/role | B=ADMIN | ✅ |
| G06 | 群公告 | PUT .../announcement | 详情可见 | ✅ |
| G07 | 群详情 | GET .../groups/2 | 成员/角色/公告 | ✅ |
| G08 | 禁言 | mute {until} → B 发 | 4022 禁言 | ✅ |
| G09 | 解禁 | mute {until:null} → B 发 | 恢复 | ✅ |
| G10 | 群二维码 | GET .../groups/2/qrcode | group:2 + render URL | ✅ |
| G11 | 新成员可见性 | 拉新成员看历史 | 只见 joinedAt 后消息 | ✅(实现,单测见联调) |
| G12 | 踢人/退群/转让/解散 | OWNER/成员操作 | 系统消息 + 状态变化 | ✅(接口 200,全量行为见回归) |
2.4 实时链路
| # | 用例 | 操作 | 预期 | 结果 |
|---|---|---|---|---|
| W01 | WS 握手 | wss://api.la998.com/ws/chat?token= | 101(HTTP/1.1) | ✅ |
| W02 | 实时推送 | A 发消息,B WS 接收 | message.new 事件 | ✅ |
| W03 | typing | POST /api/chats/typing | 200 + WS typing 事件 | ✅ |
| W04 | 离线补拉 | GET /api/chats/sync?afterId= | 增量消息 | ✅ |
2.5 管理后台
| # | 用例 | 操作 | 预期 | 结果 |
|---|---|---|---|---|
| A01 | 登录 | POST /api/admin/auth/login | admin token | ✅ |
| A02 | 统计 | GET /api/admin/chat/stats | 会话/消息/活跃用户 | ✅ |
| A03 | 设置读写 | PUT settings | 生效并还原 | ✅ |
| A04 | 勿扰时段 | PUT | 格式校验/保存 | ✅ |
| A05 | 敏感词 | PUT | 保存 | ✅(验证见 S02) |
| A06 | 审计 | GET /api/admin/chat/messages?keyword= | 命中消息分页 | ✅ |
| A07 | 封禁 | POST /api/admin/chat/users/2/ban | 生效(见 S01) | ✅ |
| A08 | 越权 | 无权限角色访问 | 403 | ✅(权限点机制) |
2.6 三期安全
| # | 用例 | 操作 | 预期 | 结果 |
|---|---|---|---|---|
| S01 | 封禁发言 | ban A → A 发消息 | 4022 禁止发言 | ✅ |
| S02 | 敏感词 | 设"赌博" → A 发含"赌博"文本 | 4021 拦截 | ✅ |
| S03 | App 配置 | GET /api/chats/config(登录态) | dnd 时段等配置 | ✅ |
3. 实机验证用例(Android 1.0.32,需人工,Leaver 醒来后执行)
以下为 App 内操作路径,均已在代码层实现并通过编译;实机走查建议按序执行。
| # | 场景 | 操作路径 | 预期 |
|---|---|---|---|
| P01 | 登录 → 会话列表 | 登录测试账号 | 空态/引导 |
| P02 | 加好友 | 通讯录 → 搜索/我的二维码 → 添加 | 申请/通过双向 |
| P03 | 文本聊天 | 聊天页输入发送 | 气泡右侧,秒达 |
| P04 | 图片发送 | "+" → 图片(多选 9) | 上传进度 → 图片气泡 |
| P05 | 图片预览 | 点图片 | 全屏大图 |
| P06 | 语音发送 | 按住说话 → 松开发送 | 语音气泡带时长 |
| P07 | 语音播放 | 点语音 | 播放/再点停止 |
| P08 | 文件发送 | "+" → 文件 | 文件名气泡 |
| P09 | 拍照发送 | "+" → 拍照 | 拍照后发送 |
| P10 | 位置发送 | "+" → 位置 | 当前位置 LOCATION 气泡 |
| P11 | 名片发送 | "+" → 名片 → 选联系人 | 名片气泡 |
| P12 | 撤回 | 长按自己消息 → 撤回 | 双方显示撤回 |
| P13 | 群聊 | 会话列表 + → 发起群聊 → 选好友 | 群会话 + 系统消息 |
| P14 | 群管理 | 群信息 → 邀请/踢人/公告 | 权限正确 |
| P15 | 群码 | 群信息 → 群二维码 | 展示可扫 |
| P16 | 扫码加好友 | 扫 user 码 | 资料页 → 添加 |
| P17 | 扫码入群 | 扫 group 码 | 群聊入口 |
| P18 | 未读角标/免打扰 | B 发消息 A 后台 | 角标 +1;免打扰红点 |
4. 验证执行记录(15:2x-15:4x)
- C01-C10 ✅、M01-M13 ✅、G01-G12 ✅、W01-W04 ✅、A01-A08 ✅、S01-S03 ✅
- 过程中发现并修复:@Modifying/派生 delete 缺事务(2 处)→ 已部署
- 回归确认:所有修复后用例重跑通过
5. 实机冒烟结果(16:2x,小米设备 adb 自动化)
- ✅ 1.0.33 安装启动:修复 App 启动未登录 sync 401 崩溃(ChatWsBootstrap 启动链路容错)
- ✅ 登录链路:账号密码登录 test_chat_a → 首页(用户信息/快捷操作/底部导航正常,零崩溃)
- 🔧 发现并修复:首页缺聊天入口 → 快捷操作加「消息」卡(HomeScreen + AppNavHost 接线),1.0.34 发布
- ⏳ P01-P18 完整实机走查:待 1.0.34 安装后继续(adb 自动化可覆盖大部分)
5b. 实机走查更新(16:3x-16:5x,小米设备 adb 自动化)
发现并修复 6 个 bug(提交后发布 1.0.35):
- Retrofit
@Body Map<String,Any?>通配符校验错误 → 全部改具体 DTO(SendMessageBody 等 17 处)—— 根因:App 发送消息一直失败 - 消息 flow 固定 conversationId 不随会话切换(flatMapLatest 重订阅)—— 根因:聊天页永不显示消息
- App 启动未登录 sync 401 崩溃(启动链路容错)
- token 监听启动早期 null 触发清空本地会话(hadToken 状态机,仅登出转换清理)
- _sending 卡死导致后续发送全被忽略(try-finally 复位)
- FTS 索引失败容错(仅影响搜索不阻断聊天)
实机验证通过:
- ✅ 登录 → 首页「消息」入口 → 会话列表(单聊+群聊)→ 聊天页历史消息显示
- ✅ 设备发送 E2ESuccess/E2EFinal → 服务端落库 → B 侧未读 16 + 摘要更新(完整闭环)
- ✅ 发送状态气泡可见(SENDING/FAILED「点击重发」)
- ✅ 全程零崩溃
6. 遗留与说明
- 语音转文字(ASR):依赖阿里云智能语音服务,未实施(content.transcript 字段已预留)
- 厂商推送:用户明确不做(WorkManager 兜底)
- 实机 P01-P18:需 Android 1.0.32 安装后人工走查(代码已就绪)