8.8 KiB
8.8 KiB
房内贡献榜 Flutter 对接
本文描述语音房内 day/week/month 三个 tab 的贡献榜接口。客户端按当前 tab 独立请求,不再从进房、心跳或送礼接口里复用同一份榜单数据。
接口地址
本地开发地址:
http://127.0.0.1:13000
GET /api/v1/rooms/{room_id}/contribution-rank?period=day&limit=20
Authorization: Bearer <access_token>
X-App-Code: lalu
说明:
| 项 | 说明 |
|---|---|
| 鉴权 | 必须登录。gateway 使用 token 里的 user_id 作为 viewer。 |
| 房间校验 | viewer 必须仍在当前房间内;不在房间时返回 403。 |
| 响应外壳 | 统一使用 {code,message,request_id,data}。 |
| 时间单位 | 所有 *_ms 都是 Unix epoch milliseconds,统计窗口按 UTC 计算。 |
参数
Path 参数:
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
room_id |
string | 是 | 房间 ID。只支持字母、数字、下划线和中横线,最长 48 位。 |
Query 参数:
| 字段 | 类型 | 必填 | 默认 | 说明 |
|---|---|---|---|---|
period |
string | 否 | day |
榜单周期。可选值:day、week、month。 |
limit |
int32 | 否 | 20 |
返回条数。必须大于 0;服务端最大返回 100。 |
周期含义:
period |
统计窗口 |
|---|---|
day |
UTC 当日 00:00:00 到次日 00:00:00,区间为 [start_at_ms, end_at_ms)。 |
week |
UTC 自然周,周一 00:00:00 到下周一 00:00:00,区间为 [start_at_ms, end_at_ms)。 |
month |
UTC 自然月,1 日 00:00:00 到下月 1 日 00:00:00,区间为 [start_at_ms, end_at_ms)。 |
请求示例:
GET /api/v1/rooms/room_123/contribution-rank?period=week&limit=20
Authorization: Bearer <access_token>
X-App-Code: lalu
返回值
统一外壳:
{
"code": "OK",
"message": "ok",
"request_id": "req_xxx",
"data": {}
}
成功返回示例:
{
"code": "OK",
"message": "ok",
"request_id": "req_room_rank",
"data": {
"room_id": "room_123",
"period": "week",
"start_at_ms": 1780329600000,
"end_at_ms": 1780934400000,
"total": 2,
"contribution_rank": [
{
"rank": 1,
"user_id": "43",
"score": 900,
"gift_value": 900,
"updated_at_ms": 1780400001000,
"profile": {
"user_id": "43",
"username": "Luna",
"avatar": "https://cdn.example/avatar/43.png",
"display_user_id": "10043",
"pretty_id": "888888",
"pretty_display_user_id": "888888",
"gender": "female",
"age": 22,
"country": "US",
"country_name": "United States",
"country_display_name": "United States",
"country_flag": "https://cdn.example/flags/us.png",
"vip": {},
"level": {},
"level_badges": {},
"badges": [],
"avatar_frame": {},
"profile_card": {},
"vehicle": {},
"mic_seat_animation": {},
"charm": 0
}
},
{
"rank": 2,
"user_id": "44",
"score": 520,
"gift_value": 520,
"updated_at_ms": 1780390001000,
"profile": {
"user_id": "44",
"username": "Mia",
"avatar": "https://cdn.example/avatar/44.png",
"display_user_id": "10044",
"gender": "",
"age": 0,
"country": "",
"country_name": "",
"country_display_name": "",
"country_flag": "",
"vip": {},
"level": {},
"level_badges": {},
"badges": [],
"avatar_frame": {},
"profile_card": {},
"vehicle": {},
"mic_seat_animation": {},
"charm": 0
}
}
],
"profiles": [
{
"user_id": "43",
"username": "Luna",
"avatar": "https://cdn.example/avatar/43.png",
"display_user_id": "10043",
"gender": "female",
"age": 22,
"country": "US",
"country_name": "United States",
"country_display_name": "United States",
"country_flag": "https://cdn.example/flags/us.png",
"vip": {},
"level": {},
"level_badges": {},
"badges": [],
"avatar_frame": {},
"profile_card": {},
"vehicle": {},
"mic_seat_animation": {},
"charm": 0
},
{
"user_id": "44",
"username": "Mia",
"avatar": "https://cdn.example/avatar/44.png",
"display_user_id": "10044",
"gender": "",
"age": 0,
"country": "",
"country_name": "",
"country_display_name": "",
"country_flag": "",
"vip": {},
"level": {},
"level_badges": {},
"badges": [],
"avatar_frame": {},
"profile_card": {},
"vehicle": {},
"mic_seat_animation": {},
"charm": 0
}
],
"server_time_ms": 1780400005000
}
}
data 字段:
| 字段 | 类型 | 说明 |
|---|---|---|
room_id |
string | 房间 ID。 |
period |
string | 服务端归一化后的周期:day、week、month。 |
start_at_ms |
int64 | 本次榜单统计窗口开始时间,UTC。 |
end_at_ms |
int64 | 本次榜单统计窗口结束时间,UTC。 |
total |
int64 | 当前房间、当前周期内有贡献的总用户数。 |
contribution_rank |
array | 当前页榜单项。空数组表示当前周期暂无贡献数据。 |
profiles |
array | 榜单用户的展示资料列表,顺序和 contribution_rank 一致。 |
server_time_ms |
int64 | 服务端当前时间,可用于展示更新时间。 |
contribution_rank[] 字段:
| 字段 | 类型 | 说明 |
|---|---|---|
rank |
int64 | 排名,从 1 开始。 |
user_id |
string | 上榜用户 ID,HTTP JSON 固定按字符串解析。 |
score |
int64 | 榜单分值;当前等于 gift_value。 |
gift_value |
int64 | 统计窗口内该用户在本房间送礼贡献总值。 |
updated_at_ms |
int64 | 该用户本周期贡献记录更新时间。 |
profile |
object? | 当前用户展示资料。资料服务异常或用户资料缺失时可能为空。 |
profile / profiles[] 字段:
| 字段 | 类型 | 说明 |
|---|---|---|
user_id |
string | 用户长 ID。 |
username |
string | 昵称。 |
avatar |
string | 头像 URL。 |
display_user_id |
string | 展示 ID。 |
pretty_id |
string | 靓号 ID;没有时为空或不返回。 |
pretty_display_user_id |
string | 靓号展示 ID;没有时为空或不返回。 |
gender |
string | 性别展示值。 |
age |
int32 | 年龄。 |
country |
string | 国家码。 |
country_name |
string | 国家名称。 |
country_display_name |
string | 国家展示名。 |
country_flag |
string | 国家旗帜。 |
vip |
object | VIP 展示资料。 |
level |
object | 等级展示资料。 |
level_badges |
object | 等级徽章资料。 |
badges |
array | 当前佩戴徽章。 |
avatar_frame |
object | 当前佩戴头像框。 |
profile_card |
object | 当前佩戴资料卡。 |
vehicle |
object | 当前佩戴座驾。 |
mic_seat_animation |
object | 当前佩戴麦位动画。 |
charm |
int64 | 魅力值。 |
错误码
| HTTP | code |
场景 |
|---|---|---|
| 400 | INVALID_ARGUMENT |
room_id 格式错误、period 不是 day/week/month、limit<=0 或不是数字。 |
| 401 | UNAUTHORIZED |
未登录或 token 无效。 |
| 403 | PROFILE_REQUIRED |
登录用户未完成资料流程,gateway profile gate 拦截。 |
| 403 | PERMISSION_DENIED |
viewer 当前不在该房间,不能读取房内贡献榜。 |
| 502 | UPSTREAM_ERROR |
room-service 或 user-service 调用失败。 |
失败返回示例:
{
"code": "INVALID_ARGUMENT",
"message": "invalid argument",
"request_id": "req_bad_period"
}
Flutter 调用规则
| 场景 | 处理 |
|---|---|
| 进入房间后首次展示 | POST /api/v1/rooms/join 成功、房间页建立后,请求当前默认 tab,例如 period=day。 |
| tab 切换 | 按 room_id + period 单独请求本接口;不要把 day 的数据复制给 week/month。 |
| 送礼成功后 | 刷新当前展示的 period,或收到本地送礼成功事件后延迟刷新;不要依赖送礼接口返回榜单。 |
| 心跳 | POST /api/v1/rooms/heartbeat 只维护在线状态,不用它刷新榜单。 |
| 进房首包 | 新版进房继续传 response_mode=lite;贡献榜由本接口独立拉取。 |
| 空榜 | contribution_rank=[]、profiles=[]、total=0 时展示空状态。 |
相关 IM
本接口没有独立 IM 消息。房间内送礼动效、公屏礼物消息仍按现有送礼链路和房间 IM 事件处理;本接口只用于 Flutter 在面板打开、tab 切换或送礼后重拉榜单快照。