Files
suixinkan_uikit/docs/消息中心未读数量与全部已读接口需求.md
汉秋 caeeb9a1cf feat: 接入消息未读数、全部已读与首页红点角标同步。
固定消息中心为首页入口,并在推送到达、已读后刷新桌面角标。

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-21 18:02:43 +08:00

6.3 KiB

消息中心未读数量与全部已读接口需求

1. 需求背景

iOS App 需要实现以下功能:

  1. 首页展示消息中心入口,有未读消息时显示红点。
  2. 获取最新未读消息数量后,同步更新 App 桌面图标右上角的角标数量。
  3. 用户点击某条未读消息并成功标记已读后,立即更新最新未读数量和桌面角标。
  4. 消息中心导航栏右上角提供“全部已读”按钮。
  5. 全部标记已读成功后,更新首页红点,并将桌面角标更新为服务端返回的最新未读数量。

2. 当前已有接口

2.1 获取消息列表

GET /api/app/msg/list

当前参数:

参数 类型 必填 说明
last_id int 分页游标,首次请求传 0
limit int 每页数量
unread int 0 获取全部消息,1 只获取未读消息

该接口仅返回分页消息,没有返回未读消息总数。客户端若通过分页遍历全部未读消息来统计数量,请求次数和数据流量都会随着未读消息数量增长,因此不适合作为桌面角标的常规数据来源。

2.2 标记单条消息已读

POST /api/app/msg/read?id={message_id}

当前接口可以标记单条消息已读,但成功响应没有返回操作后的最新未读数量。

3. 需要新增或调整的接口

3.1 获取未读消息总数

建议新增:

GET /api/app/msg/unread-count

请求说明

  • 不需要业务请求参数。
  • 根据当前登录 Token 识别用户及业务账号。
  • 返回当前账号下尚未读取的消息总数。

成功响应示例

{
  "code": 100000,
  "msg": "success",
  "data": {
    "unread_count": 12
  }
}

字段说明

字段 类型 必有 说明
unread_count int 当前账号的最新未读消息数量,最小值为 0

3.2 全部标记为已读

建议新增:

POST /api/app/msg/read-all

请求说明

  • 不需要业务请求参数和请求体。
  • 根据当前登录 Token 识别用户及业务账号。
  • 将当前账号下请求执行时已经存在的所有未读消息标记为已读。
  • 接口需要支持幂等调用;没有未读消息时仍返回成功。

成功响应示例

{
  "code": 100000,
  "msg": "success",
  "data": {
    "updated_count": 12,
    "unread_count": 0
  }
}

字段说明

字段 类型 必有 说明
updated_count int 本次实际被更新为已读的消息数量
unread_count int 操作完成后的最新未读消息数量

客户端应以响应中的 unread_count 为准,不应直接假定其一定为 0。例如“全部已读”执行期间如果有新消息到达,操作完成后仍可能存在新的未读消息。

3.3 调整单条已读接口响应

保留现有接口:

POST /api/app/msg/read?id={message_id}

建议成功响应增加最新未读数量:

{
  "code": 100000,
  "msg": "success",
  "data": {
    "unread_count": 11
  }
}

字段说明

字段 类型 必有 说明
unread_count int 单条消息标记已读后的最新未读消息数量

幂等要求

  • 对已经处于已读状态的消息重复调用时,接口仍返回成功和最新 unread_count
  • 消息不存在或不属于当前账号时,返回明确的业务错误,不能修改其他账号的消息。

4. 统一约定

4.1 账号范围

  • 所有接口必须根据登录 Token 限定当前用户及当前业务账号的数据范围。
  • 景区账号、门店账号等不同业务账号之间的未读数量不能互相污染。
  • 切换账号后,客户端会重新调用未读数量接口。

4.2 数值约束

  • unread_countupdated_count 必须返回 JSON 整数。
  • 数值不得为负数。
  • 即使数量为 0,字段也必须存在,不能返回 null、空字符串或省略字段。

4.3 一致性与并发

  • 单条已读或全部已读操作及其响应中的 unread_count 应基于同一账号范围。
  • read-all 应尽量在事务内完成批量更新和剩余未读数统计。
  • 如果操作期间有新消息写入,响应应返回操作完成时数据库中的真实 unread_count
  • 客户端始终以最近一次成功接口响应中的 unread_count 更新首页红点和桌面角标。

4.4 错误响应

沿用现有统一业务响应结构,例如:

{
  "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. 所有接口继续使用项目现有统一鉴权、业务状态码和响应信封格式。