feat: add bootstrap entry badges
This commit is contained in:
@@ -0,0 +1,446 @@
|
||||
# IM bootstrap 入口与未读数改造需求文档
|
||||
|
||||
## 1. 背景
|
||||
|
||||
当前 `GET /v1/im/bootstrap` 已返回登录后的功能开关、权限、工作台模块、系统 Topic 和安全摘要。前端同事在接入时提出以下问题:
|
||||
|
||||
1. 新朋友未处理数、群列表、文件助手和系统消息入口是否都由 bootstrap 控制显示。
|
||||
2. 未读数字段分别从哪里读取。
|
||||
3. 工作台是否需要总未读数。
|
||||
4. 文件助手和系统消息是否完全依赖 WebSocket Topic 推送,还是 bootstrap 也要返回入口和初始未读。
|
||||
5. 文档需要给出完整响应示例,避免入口字段和里层结构继续口头确认。
|
||||
|
||||
现有前后端对接文档已有基础约定:
|
||||
|
||||
1. 登录后客户端必须执行 `sub me`,从 `meta.sub` 获取每个会话 Topic 的 `seq/read/recv`。
|
||||
2. 普通聊天会话未读数使用 `max(seq - read, 0)`。
|
||||
3. `bootstrap` 返回固定入口、功能开关、权限和系统 Topic。
|
||||
4. `workbench.modules[].unread_count` 已在结构中定义,但当前实现固定为 0。
|
||||
|
||||
缺口在于:bootstrap 没有明确返回通讯录入口、系统消息入口、文件助手入口、工作台总未读和业务 badge;文档也没有明确哪些未读来自 Topic,哪些未读来自业务表统计。
|
||||
|
||||
## 2. 目标
|
||||
|
||||
1. 明确 `bootstrap` 是登录后首屏入口配置和初始 badge 的聚合接口。
|
||||
2. 明确 Topic 类未读和业务类未读的分工。
|
||||
3. 为前端提供稳定响应结构,减少后续沟通成本。
|
||||
4. 保持聊天实时链路轻量:普通聊天、群聊、文件助手和系统消息的实时增量仍通过 Tinode WebSocket Topic 更新。
|
||||
5. 为后续工作台 badge、系统通知和好友申请的实时事件留出兼容空间。
|
||||
|
||||
## 3. 非目标
|
||||
|
||||
1. 不把所有会话列表塞入 bootstrap;普通会话列表仍通过 `sub me` 和会话搜索/列表能力获取。
|
||||
2. 不用 bootstrap 替代 WebSocket 增量更新。
|
||||
3. 不让客户端根据本地按钮状态绕过服务端权限校验。
|
||||
4. 不要求本期实现复杂实时聚合服务;可先返回准确初始值,再通过已有 Topic 或系统事件增量更新。
|
||||
|
||||
## 4. 概念定义
|
||||
|
||||
| 名称 | 含义 |
|
||||
| --- | --- |
|
||||
| 入口 entry | 登录后首页、通讯录、工作台等固定可见入口配置 |
|
||||
| Topic 未读 | 由 Tinode Topic 的 `seq/read/recv` 推导出的消息未读 |
|
||||
| 业务 badge | 不能用 Topic `seq/read` 表达的业务待处理数量,例如新朋友待处理申请 |
|
||||
| 工作台模块未读 | `modules[].unread_count`,表示单个工作台模块的业务未读 |
|
||||
| 工作台总未读 | 所有可见工作台模块未读汇总,供底部 Tab 或一级入口展示 |
|
||||
| 系统消息 | 服务端可信系统通知,展示页可查 HTTP 列表,实时通知可走系统 Topic 或系统事件 |
|
||||
| 文件助手 | 用户自己的固定会话入口,用于收藏/文件转发/个人文件消息;若实现为 Topic,则未读遵循 Topic 规则 |
|
||||
|
||||
## 5. 未读数来源规则
|
||||
|
||||
### 5.1 Topic 类未读
|
||||
|
||||
以下未读原则上来自 Tinode Topic:
|
||||
|
||||
1. 单聊会话。
|
||||
2. 群聊会话。
|
||||
3. 系统消息入口,如果系统消息以 `system_topic.topic` 作为可信 Topic 承载。
|
||||
4. 文件助手入口,如果文件助手以固定 Topic 承载。
|
||||
|
||||
计算规则:
|
||||
|
||||
```text
|
||||
topic_unread_count = max(seq - read, 0)
|
||||
```
|
||||
|
||||
客户端登录后必须执行:
|
||||
|
||||
```text
|
||||
WebSocket Upgrade -> hi -> token login -> sub me -> get sub/data
|
||||
```
|
||||
|
||||
初始会话列表从 `meta.sub` 获取,后续通过 `{data}`、`{meta}`、`{pres}`、`{info}` 和 `note read/recv` 更新本地状态。
|
||||
|
||||
### 5.2 业务类未读
|
||||
|
||||
以下未读不适合用 Topic `seq/read` 计算,应由 HTTP 业务接口或 bootstrap 返回:
|
||||
|
||||
1. 新朋友待处理申请数。
|
||||
2. 工作台模块待处理数,例如会议、日报、月报、总经理信箱。
|
||||
3. 未来的审批、公告、任务等非聊天会话类 badge。
|
||||
|
||||
业务类未读的真源在业务表,bootstrap 返回登录后的初始聚合值;后续增量可通过系统事件通知前端刷新或局部更新。
|
||||
|
||||
## 6. bootstrap 响应结构扩展
|
||||
|
||||
### 6.1 顶层新增字段
|
||||
|
||||
`GET /v1/im/bootstrap` 的 `data` 建议新增:
|
||||
|
||||
```json
|
||||
{
|
||||
"entry_badges": {
|
||||
"contacts_total_unread": 2,
|
||||
"new_friends_pending_count": 2,
|
||||
"groups_unread_count": 0,
|
||||
"file_assistant_unread_count": 0,
|
||||
"system_unread_count": 0,
|
||||
"workbench_total_unread": 5
|
||||
},
|
||||
"entries": {
|
||||
"new_friends": {
|
||||
"enabled": true,
|
||||
"route": "/contacts/new-friends",
|
||||
"unread_count": 2
|
||||
},
|
||||
"groups": {
|
||||
"enabled": true,
|
||||
"route": "/contacts/groups",
|
||||
"unread_count": 0
|
||||
},
|
||||
"file_assistant": {
|
||||
"enabled": true,
|
||||
"route": "/chat/file-assistant",
|
||||
"topic": "slf",
|
||||
"unread_count": 0,
|
||||
"unread_source": "topic"
|
||||
},
|
||||
"system_messages": {
|
||||
"enabled": true,
|
||||
"route": "/chat/system",
|
||||
"topic": "sys",
|
||||
"unread_count": 0,
|
||||
"unread_source": "business"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
字段说明:
|
||||
|
||||
| 字段 | 类型 | 说明 |
|
||||
| --- | --- | --- |
|
||||
| `entry_badges.contacts_total_unread` | int | 通讯录一级入口红点总数;本期可等于 `new_friends_pending_count` |
|
||||
| `entry_badges.new_friends_pending_count` | int | 当前用户待处理入站好友申请数 |
|
||||
| `entry_badges.groups_unread_count` | int | 群入口业务未读;若只是群聊消息未读,则可为 0,由会话列表负责 |
|
||||
| `entry_badges.file_assistant_unread_count` | int | 文件助手入口初始未读 |
|
||||
| `entry_badges.system_unread_count` | int | 系统消息入口初始未读 |
|
||||
| `entry_badges.workbench_total_unread` | int | 工作台可见模块未读总和 |
|
||||
| `entries.*.enabled` | bool | 是否展示入口 |
|
||||
| `entries.*.route` | string | 前端内部路由,只允许白名单内部路径 |
|
||||
| `entries.*.topic` | string | 若入口对应 Topic,则返回 Topic 名;没有 Topic 时省略 |
|
||||
| `entries.*.unread_count` | int | 当前入口初始未读或待处理数 |
|
||||
| `entries.*.unread_source` | string | `topic` 或 `business`,用于前端判断后续更新来源 |
|
||||
|
||||
### 6.2 unread_source 约定
|
||||
|
||||
| unread_source | 含义 | 后续更新方式 |
|
||||
| --- | --- | --- |
|
||||
| `topic` | 未读来自 Topic `seq/read` | WebSocket Topic 增量和 `note read/recv` |
|
||||
| `business` | 未读来自业务表统计 | 业务 HTTP 刷新或系统事件 |
|
||||
| `none` | 入口无未读概念 | 不展示 badge |
|
||||
|
||||
`new_friends.unread_source` 可省略,默认按 `business` 处理。若为了统一,也可以显式返回:
|
||||
|
||||
```json
|
||||
{
|
||||
"enabled": true,
|
||||
"route": "/contacts/new-friends",
|
||||
"unread_count": 2,
|
||||
"unread_source": "business"
|
||||
}
|
||||
```
|
||||
|
||||
## 7. 工作台 unread 规则
|
||||
|
||||
当前 `modules` 结构保留:
|
||||
|
||||
```json
|
||||
{
|
||||
"code": "meetings",
|
||||
"name": "会议通知",
|
||||
"icon_file_id": "",
|
||||
"route": "/meetings",
|
||||
"unread_count": 3,
|
||||
"enabled": true,
|
||||
"permission": "enabled"
|
||||
}
|
||||
```
|
||||
|
||||
新增规则:
|
||||
|
||||
1. `modules[].unread_count` 是模块级业务未读。
|
||||
2. `entry_badges.workbench_total_unread` 是所有可见且 `enabled=true` 模块的未读总和。
|
||||
3. 隐藏或无权限模块不计入总未读。
|
||||
4. 后续增量事件使用 `workbench.badge.updated`:
|
||||
|
||||
```json
|
||||
{
|
||||
"type": "system_event",
|
||||
"event_type": "workbench.badge.updated",
|
||||
"event_id": "evt_...",
|
||||
"created_at": "2026-08-20T12:00:00.000Z",
|
||||
"params": {
|
||||
"module_code": "meetings",
|
||||
"unread_count": 4,
|
||||
"workbench_total_unread": 6,
|
||||
"workbench_version": 1787153039
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
前端收到后只更新对应模块和工作台总未读;如果 `workbench_version` 大于本地版本,应重新调用 `GET /v1/im/workbench` 或 `GET /v1/im/bootstrap`。
|
||||
|
||||
## 8. 系统消息规则
|
||||
|
||||
系统消息有两个视角:
|
||||
|
||||
1. 列表查询:`GET /v1/im/system-notifications?cursor=` 返回历史通知列表。
|
||||
2. 实时增量:通过服务端可信系统事件推送。
|
||||
|
||||
bootstrap 返回:
|
||||
|
||||
```json
|
||||
{
|
||||
"system_topic": {
|
||||
"topic": "sys",
|
||||
"type": "system"
|
||||
},
|
||||
"entries": {
|
||||
"system_messages": {
|
||||
"enabled": true,
|
||||
"route": "/chat/system",
|
||||
"topic": "sys",
|
||||
"unread_count": 0,
|
||||
"unread_source": "business"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
实现要求:
|
||||
|
||||
1. 普通用户不能向系统 Topic 发布可信系统消息。
|
||||
2. 客户端不能把普通用户伪造的 `system_event` 渲染为可信通知。
|
||||
3. 本期系统消息未读使用 `im_system_notifications.read_at` 统计,`unread_source` 固定为 `business`,并由服务端返回准确 `system_unread_count`。
|
||||
|
||||
本期约定:系统消息入口保留 `topic:"sys"` 作为入口标识和后续事件通道标识,初始未读数以系统通知业务表为准。若后续确认普通用户不能订阅 `sys`,应改为每用户系统通知 Topic 或纯 HTTP 通知列表 + business badge。
|
||||
|
||||
## 9. 文件助手规则
|
||||
|
||||
文件助手需要先明确产品实现形态:
|
||||
|
||||
### 9.1 Topic 形态
|
||||
|
||||
如果文件助手是用户自己的固定 Topic,例如 `slf` 或专用 `file_assistant_topic`:
|
||||
|
||||
```json
|
||||
{
|
||||
"file_assistant": {
|
||||
"enabled": true,
|
||||
"route": "/chat/file-assistant",
|
||||
"topic": "slf",
|
||||
"unread_count": 0,
|
||||
"unread_source": "topic"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
未读通过 `sub me` 中该 Topic 的 `seq/read` 计算。
|
||||
|
||||
### 9.2 纯入口形态
|
||||
|
||||
如果文件助手只是本地入口,不对应消息 Topic:
|
||||
|
||||
```json
|
||||
{
|
||||
"file_assistant": {
|
||||
"enabled": true,
|
||||
"route": "/files/assistant",
|
||||
"unread_count": 0,
|
||||
"unread_source": "none"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
此时不展示消息未读,只展示入口。
|
||||
|
||||
本期建议采用 Topic 形态,便于复用消息、文件、转发、未读和多端同步能力。
|
||||
|
||||
## 10. 通讯录入口规则
|
||||
|
||||
通讯录页包含以下固定入口:
|
||||
|
||||
1. 新朋友。
|
||||
2. 群聊。
|
||||
3. 文件助手。
|
||||
4. 系统消息。
|
||||
|
||||
bootstrap 控制入口展示和初始 badge。具体列表仍由各自接口负责:
|
||||
|
||||
| 入口 | 展示控制 | 初始 badge | 列表数据 |
|
||||
| --- | --- | --- | --- |
|
||||
| 新朋友 | `entries.new_friends.enabled` | `new_friends_pending_count` | `GET /v1/im/friend-requests` |
|
||||
| 群聊 | `entries.groups.enabled` | 群业务 badge,群消息未读走 Topic | 群列表接口或 `sub me` 中群 Topic |
|
||||
| 文件助手 | `entries.file_assistant.enabled` | Topic 或 none | Topic 消息或文件助手专用接口 |
|
||||
| 系统消息 | `entries.system_messages.enabled` | Topic 或 business | `GET /v1/im/system-notifications` |
|
||||
|
||||
## 11. 完整 bootstrap 示例
|
||||
|
||||
```json
|
||||
{
|
||||
"code": 0,
|
||||
"data": {
|
||||
"features": {
|
||||
"create_group": true,
|
||||
"message_edit": true,
|
||||
"message_recall": true,
|
||||
"scan_qr": true,
|
||||
"system_notifications": true,
|
||||
"user_search": true
|
||||
},
|
||||
"permissions": {
|
||||
"create_group": true,
|
||||
"scan_qr": true,
|
||||
"user_search": true
|
||||
},
|
||||
"entry_badges": {
|
||||
"contacts_total_unread": 2,
|
||||
"new_friends_pending_count": 2,
|
||||
"groups_unread_count": 0,
|
||||
"file_assistant_unread_count": 0,
|
||||
"system_unread_count": 1,
|
||||
"workbench_total_unread": 5
|
||||
},
|
||||
"entries": {
|
||||
"new_friends": {
|
||||
"enabled": true,
|
||||
"route": "/contacts/new-friends",
|
||||
"unread_count": 2,
|
||||
"unread_source": "business"
|
||||
},
|
||||
"groups": {
|
||||
"enabled": true,
|
||||
"route": "/contacts/groups",
|
||||
"unread_count": 0,
|
||||
"unread_source": "business"
|
||||
},
|
||||
"file_assistant": {
|
||||
"enabled": true,
|
||||
"route": "/chat/file-assistant",
|
||||
"topic": "slf",
|
||||
"unread_count": 0,
|
||||
"unread_source": "topic"
|
||||
},
|
||||
"system_messages": {
|
||||
"enabled": true,
|
||||
"route": "/chat/system",
|
||||
"topic": "sys",
|
||||
"unread_count": 1,
|
||||
"unread_source": "business"
|
||||
}
|
||||
},
|
||||
"modules": [
|
||||
{
|
||||
"code": "organization",
|
||||
"enabled": true,
|
||||
"icon_file_id": "",
|
||||
"name": "组织架构",
|
||||
"permission": "enabled",
|
||||
"route": "/organization",
|
||||
"unread_count": 0
|
||||
},
|
||||
{
|
||||
"code": "meetings",
|
||||
"enabled": true,
|
||||
"icon_file_id": "",
|
||||
"name": "会议通知",
|
||||
"permission": "enabled",
|
||||
"route": "/meetings",
|
||||
"unread_count": 3
|
||||
}
|
||||
],
|
||||
"workbench_version": 1787153039,
|
||||
"system_topic": {
|
||||
"topic": "sys",
|
||||
"type": "system"
|
||||
},
|
||||
"message_policy": {
|
||||
"edit_window_seconds": 300,
|
||||
"recall_window_seconds": 120,
|
||||
"supported_actions": ["copy", "quote", "delete", "recall", "edit"]
|
||||
},
|
||||
"security": {
|
||||
"realname": {
|
||||
"allow_skip": true,
|
||||
"remind_after": "24h",
|
||||
"required": false,
|
||||
"status": "unverified"
|
||||
}
|
||||
}
|
||||
},
|
||||
"request_id": "req_xxx",
|
||||
"server_time": "2026-08-20T12:00:00.000Z"
|
||||
}
|
||||
```
|
||||
|
||||
## 12. 前端处理规则
|
||||
|
||||
1. bootstrap 成功后,先渲染固定入口和初始 badge。
|
||||
2. 随后完成 WebSocket `sub me`,用 Topic `seq/read` 覆盖 Topic 类入口未读。
|
||||
3. `unread_source=topic` 的入口以后以 Topic 状态为准。
|
||||
4. `unread_source=business` 的入口以后以业务接口刷新或系统事件为准。
|
||||
5. 切租户、退出登录、切账号时必须清空本地入口和 badge 缓存。
|
||||
6. 前端不得把 `tenant_id`、内部数据库 ID 或未在白名单中的 route 写入跳转。
|
||||
|
||||
## 13. 服务端实现要求
|
||||
|
||||
1. `serveIMBootstrap` 增加 `entry_badges` 和 `entries`。
|
||||
2. `serveIMBootstrap` 的入口数据必须按当前 Token 的租户和用户权限裁剪。
|
||||
3. `route` 必须走服务端白名单,不能从数据库任意透传外部 URL。
|
||||
4. 新朋友待处理数按当前租户、当前用户、入站、待处理状态统计。
|
||||
5. 工作台 `modules[].unread_count` 从业务统计或模块 unread provider 获取,不再固定为 0。
|
||||
6. `workbench_total_unread` 只汇总当前用户可见模块。
|
||||
7. 文件助手和系统消息的 `topic` 必须是当前租户和当前用户有权限访问的 Topic。
|
||||
8. 如果某入口当前未实现,仍可返回 `enabled:false`,前端隐藏入口。
|
||||
|
||||
## 14. 后端建议实现顺序
|
||||
|
||||
1. 扩展 bootstrap 响应结构,先返回固定入口和 0 badge,确保前端结构稳定。
|
||||
2. 增加新朋友待处理数统计。
|
||||
3. 增加工作台模块 unread provider 和总未读。
|
||||
4. 明确文件助手 Topic,补齐入口 topic 和未读来源。
|
||||
5. 明确系统消息未读来源;若 `sys` 不适合普通用户订阅,则改为业务 unread。
|
||||
6. 增加系统事件 `workbench.badge.updated` 和入口 badge 更新事件。
|
||||
7. 更新前后端对接文档,把本需求中的响应示例合并到 bootstrap 章节。
|
||||
|
||||
## 15. 验收用例
|
||||
|
||||
1. 新用户登录调用 bootstrap,返回 `entries`、`entry_badges`、`modules`、`workbench_version`。
|
||||
2. 有 2 条待处理好友申请时,`new_friends_pending_count=2`,`entries.new_friends.unread_count=2`。
|
||||
3. 没有待处理好友申请时,新朋友入口仍展示但 unread 为 0。
|
||||
4. 工作台有两个可见模块未读分别为 3 和 2 时,`workbench_total_unread=5`。
|
||||
5. 隐藏模块未读不计入 `workbench_total_unread`。
|
||||
6. `unread_source=topic` 的入口在 `sub me` 返回后可用 Topic `seq/read` 覆盖初始 unread。
|
||||
7. 切换租户后 bootstrap 返回另一租户入口和 badge,本地旧 badge 不复用。
|
||||
8. 普通用户构造外部 route 或系统消息字段不能影响 bootstrap 返回。
|
||||
9. 未实现入口返回 `enabled:false` 时前端隐藏入口。
|
||||
10. 接口响应字段保持向后兼容,旧客户端忽略新增字段仍可正常工作。
|
||||
|
||||
## 16. 待确认问题
|
||||
|
||||
1. 文件助手最终使用 `slf` Topic,还是新增专用文件助手 Topic。
|
||||
2. 普通用户系统消息入口是否继续使用 `sys`,还是改为每用户系统通知 Topic 或纯 HTTP 通知列表。
|
||||
3. 群聊入口是否需要业务未读,还是完全由群 Topic 会话列表承担。
|
||||
4. 工作台每个模块的 unread provider 由 IM 直接查库,还是由 HotGo/业务库提供统计。
|
||||
5. 是否需要新增统一 badge 增量事件,例如 `entry.badge.updated`。
|
||||
+4
-3
@@ -519,7 +519,7 @@ X-Tinode-APIKey: <预置的普通 API Key>
|
||||
|
||||
- 登录后发送 `sub me`,再通过 `get` 拉取 `sub` 元数据;每项使用 `topic`、`public`、`private`、`updated`、`seq/read/recv` 计算名称、摘要和未读数。
|
||||
- 消息增量通过各 Topic 的 `{data}` 更新;未读数为 `max(seq-read,0)`,回执以服务端游标为准,不能只用本地计数。
|
||||
- `GET /v1/im/bootstrap` 返回固定入口、功能开关、权限和系统 Topic;搜索调用 `GET /v1/im/search/conversations?q=&cursor=`。
|
||||
- `GET /v1/im/bootstrap` 返回固定入口、功能开关、权限、系统 Topic、`entry_badges` 和 `entries`;搜索调用 `GET /v1/im/search/conversations?q=&cursor=`。
|
||||
- 本地缓存按 `tenant_code + user_id` 隔离。切租户、退出或账号变化时不得复用另一身份的会话摘要。
|
||||
|
||||
### 2.2 消息-无网络状态.png
|
||||
@@ -890,7 +890,7 @@ X-Tinode-APIKey: <预置的普通 API Key>
|
||||
- 好友列表:`GET /v1/im/friends?query=&initial=&cursor=`,返回 `user_id,display_name,remark,avatar_file_id,initial,online_visibility`;显示名优先级为备注名、昵称、账号。
|
||||
- 分页:`next_cursor` 当前按最后一条好友的 `peer_id` 生成,客户端必须作为不透明字符串原样回传,不要自行解析、排序或拼接。
|
||||
- 组织成员:`GET /v1/im/organization/members?query=&department_id=&cursor=`;好友和组织成员是两种关系,前端不得混为一个可发消息权限。
|
||||
- 新朋友未处理数、群列表、文件助手和系统消息入口由 `GET /v1/im/bootstrap` 返回。列表缓存以租户和用户隔离。
|
||||
- 新朋友、群列表、文件助手和系统消息入口由 `GET /v1/im/bootstrap` 的 `entries` 控制显示,初始红点由 `entry_badges` 和各入口 `unread_count` 返回。新朋友待处理数使用业务统计;文件助手当前返回 `topic:"slf", unread_source:"topic"`;系统消息当前返回 `topic:"sys", unread_source:"business"`,未读来自系统通知业务表。列表缓存以租户和用户隔离。
|
||||
|
||||
### 5.2 新朋友.png
|
||||
|
||||
@@ -1031,7 +1031,7 @@ X-Tinode-APIKey: <预置的普通 API Key>
|
||||
**状态:Tinode 群 Topic 已实现基础能力;产品群列表与配额需改造。**
|
||||
|
||||
- 列表:`GET /v1/im/groups?category=owned|managed|joined&query=&cursor=`,返回 `topic,name,avatar_file_id,member_count,my_role,updated_at`。
|
||||
- 创建:`POST /v1/im/groups`,Body `{"name":"...","member_user_ids":[],"avatar_file_id":"..."}`;原子校验租户群数上限和群成员上限,返回 `topic`。
|
||||
- 创建:`POST /v1/im/groups`,Body `{"name":"...","description":"...","member_user_ids":[],"avatar_file_id":"..."}`;`description` 可省略或传空字符串,最长 200 字符;原子校验租户群数上限和群成员上限,返回 `topic,name,avatar_file_id,description,owner,member_count,version,permissions`。
|
||||
- 分类由服务端 `my_role` 决定;创建成功或角色变化后通过系统事件刷新,不由前端自行移动分组。
|
||||
|
||||
### 6.2 空白页.png
|
||||
@@ -1570,6 +1570,7 @@ X-Tinode-APIKey: <预置的普通 API Key>
|
||||
**状态:新增。**
|
||||
|
||||
- `GET /v1/im/workbench` 返回 `modules[{code,name,icon_file_id,route,unread_count,enabled,permission}]`、布局版本和企业配置。
|
||||
- `GET /v1/im/bootstrap` 返回 `entry_badges.workbench_total_unread`,用于工作台一级入口总红点;总数只汇总当前用户可见且 `enabled=true` 的工作台模块。
|
||||
- 服务端按当前 Token 的租户、组织角色和功能开关裁剪;前端只接受白名单内部 `route`,禁止直接执行服务端任意 URL。
|
||||
- 未读数通过 `workbench.badge.updated` 系统事件增量更新;切租户必须重新加载,不复用另一企业工作台。
|
||||
|
||||
|
||||
Reference in New Issue
Block a user