Files
EchoChat/docs/api/frontend/im.md

263 lines
6.9 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 即时通讯模块 REST API (IM)
> 通用规范(认证方式、响应格式、错误码)见 [README.md](../README.md)
> 消息的实时收发(发送/撤回/标记已读/正在输入)通过 WebSocket 完成,见 [websocket.md](../websocket.md)
> 本文档中的接口用于会话管理和消息历史查询等非实时操作。
> **最后更新:** 2026-03-03Phase 2d 文件上传 API 新增)
---
## 接口列表
| 方法 | 路径 | 权限 | 说明 |
|------|------|------|------|
| GET | /api/v1/im/conversations | 需认证 | 获取会话列表 |
| GET | /api/v1/im/messages | 需认证 | 获取历史消息(游标分页) |
| PUT | /api/v1/im/conversations/:id/pin | 需认证 | 置顶/取消置顶 |
| PUT | /api/v1/im/conversations/:id/dnd | 需认证 | 设置/取消消息免打扰 |
| DELETE | /api/v1/im/conversations/:id | 需认证 | 删除会话(软删除) |
| DELETE | /api/v1/im/conversations/:id/messages | 需认证 | 清空聊天记录(个人视图) |
| GET | /api/v1/im/messages/search | 需认证 | 全局消息搜索 |
| GET | /api/v1/im/unread | 需认证 | 获取全局未读消息总数 |
| GET | /api/v1/im/messages/:id/reads | 需认证 | 获取消息已读详情 |
| POST | /api/v1/upload/image | 需认证 | 图片上传(含缩略图生成)[Phase 2d] |
| POST | /api/v1/upload/voice | 需认证 | 语音上传(含时长校验)[Phase 2d] |
| POST | /api/v1/upload | 需认证 | 通用文件上传(最大 50MB[Phase 2d] |
---
## 1. 获取会话列表
`GET /api/v1/im/conversations`
**权限:** 需认证
**说明:** 返回当前用户的所有会话,排序:置顶优先 → 最后消息时间降序。已软删除的会话不返回。通过 LEFT JOIN 一次获取单聊对方用户 ID避免 N+1 查询。
**成功响应:**
```json
{
"code": 0,
"message": "success",
"data": {
"list": [
{
"id": 1,
"type": 1,
"peer_user_id": 2,
"peer_nickname": "李四",
"peer_avatar": "https://...",
"last_msg_content": "你好",
"last_msg_time": "2026-03-03 10:30:00",
"last_msg_sender_id": 2,
"is_pinned": false,
"unread_count": 3
}
]
}
}
```
---
## 2. 获取历史消息
`GET /api/v1/im/messages`
**权限:** 需认证,且为该会话成员
**查询参数:**
| 参数 | 类型 | 必填 | 默认值 | 说明 |
|------|------|------|--------|------|
| conversation_id | int | 是 | - | 会话 ID |
| before_id | int | 否 | 0 | 游标:查询 ID 小于此值的消息0=最新 |
| limit | int | 否 | 30 | 每次获取数量,最大 100 |
**说明:** 支持 `clear_before_msg_id` 个人视图过滤(清空聊天记录后,仅过滤当前用户视图,不影响对方)。
**成功响应:**
```json
{
"code": 0,
"message": "success",
"data": {
"list": [
{
"id": 99,
"conversation_id": 1,
"sender_id": 2,
"type": 1,
"content": "你好",
"status": 1,
"client_msg_id": "",
"created_at": "2026-03-03 10:29:00"
}
],
"has_more": true
}
}
```
---
## 3. 置顶/取消置顶会话
`PUT /api/v1/im/conversations/:id/pin`
**权限:** 需认证,且为该会话成员
**请求参数:**
| 字段 | 类型 | 必填 | 说明 |
|------|------|------|------|
| is_pinned | bool | 是 | true=置顶, false=取消 |
---
## 3.5 设置/取消消息免打扰
`PUT /api/v1/im/conversations/:id/dnd`
**权限:** 需认证,且为该会话成员
**请求参数:**
| 字段 | 类型 | 必填 | 说明 |
|------|------|------|------|
| is_do_not_disturb | bool | 是 | true=开启免打扰, false=关闭 |
**说明:** 免打扰模式下,新消息仍计入会话 unread_count但不递增 Redis 全局未读数,前端会话列表中以灰色数字展示未读数。
---
## 4. 删除会话
`DELETE /api/v1/im/conversations/:id`
**权限:** 需认证,且为该会话成员
**说明:** 软删除,仅影响当前用户视图,不影响对方。同时清零未读数并更新 Redis 全局未读。
---
## 5. 清空聊天记录
`DELETE /api/v1/im/conversations/:id/messages`
**权限:** 需认证,且为该会话成员
**说明:** 个人视图操作,不影响对方的消息。实现方式:记录清空时的最后消息 ID`clear_before_msg_id`),后续查询历史消息时过滤。同时清零该会话未读数。
---
## 6. 全局消息搜索
`GET /api/v1/im/messages/search`
**权限:** 需认证
**查询参数:**
| 参数 | 类型 | 必填 | 默认值 | 说明 |
|------|------|------|--------|------|
| keyword | string | 是 | - | 搜索关键词 |
| limit | int | 否 | 50 | 返回条数上限 |
**说明:** 使用 PostgreSQL GIN 全文索引(`to_tsvector('simple', content) @@ plainto_tsquery('simple', ?)`),仅搜索用户所在会话的消息。
**成功响应:**
```json
{
"code": 0,
"message": "success",
"data": {
"list": [
{
"id": 99,
"conversation_id": 1,
"sender_id": 2,
"type": 1,
"content": "你好世界",
"status": 1,
"created_at": "2026-03-03 10:29:00",
"sender_nickname": "李四",
"sender_avatar": "https://..."
}
]
}
}
```
---
## 7. 获取全局未读消息总数
`GET /api/v1/im/unread`
**权限:** 需认证
**说明:** 从 Redis STRING 读取全局未读总数,用于 TabBar badge 显示。
**成功响应:**
```json
{
"code": 0,
"message": "success",
"data": {
"total_unread": 5
}
}
```
---
## 8. 获取消息已读详情
`GET /api/v1/im/messages/:id/reads`
**权限:** 需认证,且为该会话成员
**说明:** 返回指定消息的已读/未读用户列表。群聊场景下,已设群昵称的用户会额外返回 `group_nickname` 字段。
**成功响应:**
```json
{
"code": 0,
"message": "success",
"data": {
"read_list": [
{
"user_id": 4,
"user_nickname": "张三",
"user_avatar": "https://...",
"group_nickname": "群昵称A",
"read_at": ""
}
],
"unread_list": [
{
"user_id": 5,
"user_nickname": "李四",
"user_avatar": "https://..."
}
],
"read_count": 1,
"total_count": 3
}
}
```
**字段说明:**
| 字段 | 说明 |
|------|------|
| group_nickname | 群内昵称仅群聊有效且已设置时返回omitempty |
| read_at | 已读时间(当前暂为空,预留字段) |
| total_count | 群成员总数(不含消息发送者本人) |