# 消息中心未读数量与全部已读接口需求 ## 1. 需求背景 iOS App 需要实现以下功能: 1. 首页展示消息中心入口,有未读消息时显示红点。 2. 获取最新未读消息数量后,同步更新 App 桌面图标右上角的角标数量。 3. 用户点击某条未读消息并成功标记已读后,立即更新最新未读数量和桌面角标。 4. 消息中心导航栏右上角提供“全部已读”按钮。 5. 全部标记已读成功后,更新首页红点,并将桌面角标更新为服务端返回的最新未读数量。 ## 2. 当前已有接口 ### 2.1 获取消息列表 ```http GET /api/app/msg/list ``` 当前参数: | 参数 | 类型 | 必填 | 说明 | | --- | --- | --- | --- | | `last_id` | int | 否 | 分页游标,首次请求传 `0` | | `limit` | int | 否 | 每页数量 | | `unread` | int | 否 | `0` 获取全部消息,`1` 只获取未读消息 | 该接口仅返回分页消息,没有返回未读消息总数。客户端若通过分页遍历全部未读消息来统计数量,请求次数和数据流量都会随着未读消息数量增长,因此不适合作为桌面角标的常规数据来源。 ### 2.2 标记单条消息已读 ```http POST /api/app/msg/read?id={message_id} ``` 当前接口可以标记单条消息已读,但成功响应没有返回操作后的最新未读数量。 ## 3. 需要新增或调整的接口 ### 3.1 获取未读消息总数 建议新增: ```http GET /api/app/msg/unread-count ``` #### 请求说明 - 不需要业务请求参数。 - 根据当前登录 Token 识别用户及业务账号。 - 返回当前账号下尚未读取的消息总数。 #### 成功响应示例 ```json { "code": 100000, "msg": "success", "data": { "unread_count": 12 } } ``` #### 字段说明 | 字段 | 类型 | 必有 | 说明 | | --- | --- | --- | --- | | `unread_count` | int | 是 | 当前账号的最新未读消息数量,最小值为 `0` | ### 3.2 全部标记为已读 建议新增: ```http POST /api/app/msg/read-all ``` #### 请求说明 - 不需要业务请求参数和请求体。 - 根据当前登录 Token 识别用户及业务账号。 - 将当前账号下请求执行时已经存在的所有未读消息标记为已读。 - 接口需要支持幂等调用;没有未读消息时仍返回成功。 #### 成功响应示例 ```json { "code": 100000, "msg": "success", "data": { "updated_count": 12, "unread_count": 0 } } ``` #### 字段说明 | 字段 | 类型 | 必有 | 说明 | | --- | --- | --- | --- | | `updated_count` | int | 是 | 本次实际被更新为已读的消息数量 | | `unread_count` | int | 是 | 操作完成后的最新未读消息数量 | > 客户端应以响应中的 `unread_count` 为准,不应直接假定其一定为 `0`。例如“全部已读”执行期间如果有新消息到达,操作完成后仍可能存在新的未读消息。 ### 3.3 调整单条已读接口响应 保留现有接口: ```http POST /api/app/msg/read?id={message_id} ``` 建议成功响应增加最新未读数量: ```json { "code": 100000, "msg": "success", "data": { "unread_count": 11 } } ``` #### 字段说明 | 字段 | 类型 | 必有 | 说明 | | --- | --- | --- | --- | | `unread_count` | int | 是 | 单条消息标记已读后的最新未读消息数量 | #### 幂等要求 - 对已经处于已读状态的消息重复调用时,接口仍返回成功和最新 `unread_count`。 - 消息不存在或不属于当前账号时,返回明确的业务错误,不能修改其他账号的消息。 ## 4. 统一约定 ### 4.1 账号范围 - 所有接口必须根据登录 Token 限定当前用户及当前业务账号的数据范围。 - 景区账号、门店账号等不同业务账号之间的未读数量不能互相污染。 - 切换账号后,客户端会重新调用未读数量接口。 ### 4.2 数值约束 - `unread_count` 和 `updated_count` 必须返回 JSON 整数。 - 数值不得为负数。 - 即使数量为 `0`,字段也必须存在,不能返回 `null`、空字符串或省略字段。 ### 4.3 一致性与并发 - 单条已读或全部已读操作及其响应中的 `unread_count` 应基于同一账号范围。 - `read-all` 应尽量在事务内完成批量更新和剩余未读数统计。 - 如果操作期间有新消息写入,响应应返回操作完成时数据库中的真实 `unread_count`。 - 客户端始终以最近一次成功接口响应中的 `unread_count` 更新首页红点和桌面角标。 ### 4.4 错误响应 沿用现有统一业务响应结构,例如: ```json { "code": 100001, "msg": "消息不存在或无权操作", "data": null } ``` 建议至少区分以下情况: - Token 无效或登录已过期。 - 单条消息不存在。 - 单条消息不属于当前账号。 - 数据库更新失败。 ## 5. 客户端调用时机 | 场景 | 调用接口 | 客户端处理 | | --- | --- | --- | | 登录后首次进入首页 | `GET /msg/unread-count` | 更新首页红点和桌面角标 | | App 回到前台 | `GET /msg/unread-count` | 校准最新未读数量 | | 前台收到新消息推送 | `GET /msg/unread-count` | 更新首页红点和桌面角标 | | 点击一条未读消息 | `POST /msg/read` | 使用返回的 `unread_count` 更新红点和桌面角标 | | 点击“全部已读” | `POST /msg/read-all` | 刷新消息列表,使用返回的 `unread_count` 更新红点和桌面角标 | | 切换业务账号 | `GET /msg/unread-count` | 使用新账号的数量覆盖旧账号角标 | | 退出登录 | 无 | 客户端将桌面角标清零 | ## 6. 验收标准 1. 未读数量为 `0` 时,接口稳定返回 `{"unread_count": 0}`。 2. 存在多页未读消息时,未读数量接口返回完整总数,而不是当前页数量。 3. 单条未读消息标记成功后,返回的 `unread_count` 与数据库实际剩余未读数一致。 4. 对同一消息重复调用单条已读接口不会重复扣减未读数量。 5. 全部已读接口可一次处理当前账号的所有未读消息,并返回实际更新数量。 6. 重复调用全部已读接口仍成功,返回 `updated_count = 0`。 7. 不同业务账号的未读数量相互隔离。 8. 并发到达新消息时,响应中的 `unread_count` 能反映操作完成时的真实剩余数量。 9. 所有接口继续使用项目现有统一鉴权、业务状态码和响应信封格式。