13 KiB
13 KiB
用户装扮 Flutter 对接文档
通用说明
所有需要登录的接口都需要带:
Authorization: Bearer <token>
统一返回外壳:
{
"code": "OK",
"message": "OK",
"request_id": "xxx",
"data": {}
}
下文只描述 data 内部字段。
1. 获取我的装扮聚合
地址:
GET /api/v1/appearance
GET /api/v1/users/me/appearance
参数:无。
返回值:
{
"user_id": "42",
"avatar_frame": {
"resource_id": 8101,
"resource_code": "frame_gold",
"resource_type": "avatar_frame",
"name": "Gold Frame",
"asset_url": "https://cdn.example/frame.png",
"preview_url": "",
"animation_url": "https://cdn.example/frame.svga",
"metadata_json": "{}",
"entitlement_id": "ent-frame",
"expires_at_ms": 1999999999999
},
"profile_card": {},
"vehicle": {
"resource_id": 8102,
"resource_code": "vehicle_gold",
"resource_type": "vehicle",
"name": "Gold Vehicle",
"asset_url": "https://cdn.example/vehicle.png",
"preview_url": "",
"animation_url": "https://cdn.example/vehicle.svga",
"metadata_json": "{}",
"entitlement_id": "ent-vehicle",
"expires_at_ms": 1999999999999
},
"mic_seat_animation": {
"resource_id": 8106,
"resource_code": "mic_seat_wave_gold",
"resource_type": "mic_seat_animation",
"name": "Gold Mic Wave",
"asset_url": "https://cdn.example/mic-seat.png",
"preview_url": "",
"animation_url": "https://cdn.example/mic-seat.svga",
"metadata_json": "{}",
"entitlement_id": "ent-mic-seat-wave",
"expires_at_ms": 1999999999999
},
"equipped_badges": [],
"badges": [
{
"slot": "strip",
"position": 1,
"badge_form": "icon",
"resource_id": 8103,
"resource": {
"resource_id": 8103,
"resource_code": "badge_host",
"resource_type": "badge",
"name": "Host Badge",
"asset_url": "https://cdn.example/badge.png",
"preview_url": "",
"animation_url": "",
"metadata_json": "{}",
"entitlement_id": "",
"expires_at_ms": 0
},
"entitlement_id": "ent-badge",
"source_type": "achievement",
"source_id": "ach-host",
"pin_mode": "auto",
"updated_at_ms": 1778256000000
}
],
"badge_profile": {
"strip_badges": [],
"profile_tile_badges": [],
"honor_badges": [],
"server_time_ms": 1778256000000
},
"resources": [
{
"resource_id": 8106,
"resource_code": "mic_seat_wave_gold",
"resource_type": "mic_seat_animation",
"name": "Gold Mic Wave",
"asset_url": "https://cdn.example/mic-seat.png",
"preview_url": "",
"animation_url": "https://cdn.example/mic-seat.svga",
"metadata_json": "{}",
"entitlement_id": "ent-mic-seat-wave",
"expires_at_ms": 1999999999999
}
],
"server_time_ms": 1778256000000
}
字段说明:
| 字段 | 说明 |
|---|---|
| user_id | 用户 ID,字符串 |
| avatar_frame | 当前佩戴头像框,未佩戴时为 {} |
| profile_card | 当前佩戴背景卡,未佩戴时为 {} |
| vehicle | 当前佩戴入场座驾,未佩戴时为 {} |
| mic_seat_animation | 当前佩戴麦位声波,未佩戴时为 {} |
| equipped_badges | wallet 当前佩戴的 badge 权益 |
| badges | 房间、公屏等高频展示用徽章,取 strip_badges |
| badge_profile | 完整徽章展示配置 |
| resources | 当前佩戴资源的完整列表 |
| server_time_ms | 服务端时间戳 |
说明:
- 过期佩戴不会返回。
- 头像框、背景卡、入场座驾、麦位声波来自 wallet 当前佩戴。
- 徽章展示配置来自 activity。
- 客户端渲染动画优先使用
animation_url,没有动画时用asset_url或preview_url兜底。
2. 获取我的资源背包
地址:
GET /api/v1/users/me/resources
参数:
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| resource_type | string | 否 | avatar_frame / profile_card / vehicle / badge / chat_bubble |
示例:
GET /api/v1/users/me/resources?resource_type=vehicle
返回值:
{
"items": [
{
"entitlement_id": "ent-vehicle",
"resource_id": 8102,
"resource": {
"resource_id": 8102,
"resource_code": "vehicle_gold",
"resource_type": "vehicle",
"name": "Gold Vehicle",
"status": "active",
"usage_scopes": ["room_entry"],
"asset_url": "https://cdn.example/vehicle.png",
"preview_url": "",
"animation_url": "https://cdn.example/vehicle.svga",
"metadata_json": "{}"
},
"status": "active",
"quantity": 1,
"remaining_quantity": 1,
"effective_at_ms": 1778256000000,
"expires_at_ms": 1999999999999,
"source_grant_id": "grant-1",
"created_at_ms": 1778256000000,
"updated_at_ms": 1778256000000,
"equipped": true
}
],
"total": 1
}
字段说明:
| 字段 | 说明 |
|---|---|
| entitlement_id | 用户权益 ID,佩戴时建议传这个值 |
| resource_id | 资源 ID |
| resource | 资源素材和基础信息 |
| status | 权益状态 |
| quantity | 总数量 |
| remaining_quantity | 剩余数量 |
| effective_at_ms | 生效时间 |
| expires_at_ms | 过期时间,0 表示不过期 |
| equipped | 是否当前佩戴 |
3. 佩戴资源
地址:
POST /api/v1/users/me/resources/{resource_id}/equip
路径参数:
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| resource_id | int64 | 是 | 资源 ID |
Body:
{
"entitlement_id": "ent-vehicle"
}
Body 参数:
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| entitlement_id | string | 否 | 用户权益 ID,建议传 |
返回值:
{
"entitlement_id": "ent-vehicle",
"resource_id": 8102,
"resource": {},
"status": "active",
"quantity": 1,
"remaining_quantity": 1,
"effective_at_ms": 1778256000000,
"expires_at_ms": 1999999999999,
"equipped": true
}
说明:
- 可佩戴类型:
avatar_frame、profile_card、vehicle、chat_bubble、badge、mic_seat_animation。 badge、mic_seat_animation发放成功后服务端默认佩戴。- 过期资源不能佩戴。
- 不传
entitlement_id时,服务端会选择当前有效权益。
4. 取消佩戴
地址:
DELETE /api/v1/users/me/resources/{resource_type}/unequip
路径参数:
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| resource_type | string | 是 | avatar_frame / profile_card / vehicle / chat_bubble / badge |
返回值:
{
"resource_type": "vehicle",
"unequipped": true,
"updated_at_ms": 1778256000000
}
说明:
- 重复取消不会报错。
- 用户本来没佩戴该类型时,
unequipped=false。
5. 批量获取房间展示资料
地址:
GET /api/v1/users/room-display-profiles:batch
参数:
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| user_ids | string | 是 | 多个用户 ID,逗号分隔 |
| user_id | string | 否 | 也支持重复传多个 user_id |
示例:
GET /api/v1/users/room-display-profiles:batch?user_ids=42,43
返回值:
{
"profiles": [
{
"user_id": "42",
"username": "Tom",
"avatar": "https://cdn.example/avatar.png",
"display_user_id": "100001",
"gender": "male",
"age": 22,
"country": "CN",
"country_name": "China",
"country_display_name": "China",
"country_flag": "CN",
"vip": {},
"level": {},
"badges": [],
"avatar_frame": {
"resource_id": 8101,
"resource_code": "frame_gold",
"resource_type": "avatar_frame",
"name": "Gold Frame",
"asset_url": "https://cdn.example/frame.png",
"preview_url": "",
"animation_url": "https://cdn.example/frame.svga",
"metadata_json": "{}",
"entitlement_id": "ent-frame",
"expires_at_ms": 1999999999999
},
"profile_card": {
"resource_id": 8104,
"resource_code": "profile_card_gold",
"resource_type": "profile_card",
"name": "Gold Profile Card",
"asset_url": "https://cdn.example/profile-card.png",
"preview_url": "",
"animation_url": "https://cdn.example/profile-card.mp4",
"metadata_json": "{\"profile_card_layout\":{\"source_width\":1136,\"source_height\":1680,\"content_top\":143,\"content_height\":1525}}",
"entitlement_id": "ent-profile-card",
"expires_at_ms": 1999999999999
},
"vehicle": {
"resource_id": 8102,
"resource_code": "vehicle_gold",
"resource_type": "vehicle",
"name": "Gold Vehicle",
"asset_url": "https://cdn.example/vehicle.png",
"preview_url": "",
"animation_url": "https://cdn.example/vehicle.svga",
"metadata_json": "{}",
"entitlement_id": "ent-vehicle",
"expires_at_ms": 1999999999999
},
"mic_seat_animation": {
"resource_id": 8106,
"resource_code": "mic_seat_wave_gold",
"resource_type": "mic_seat_animation",
"name": "Gold Mic Wave",
"asset_url": "https://cdn.example/mic-seat.png",
"preview_url": "",
"animation_url": "https://cdn.example/mic-seat.svga",
"metadata_json": "{}",
"entitlement_id": "ent-mic-seat-wave",
"expires_at_ms": 1999999999999
},
"charm": 0
}
]
}
说明:
- 房间、公屏、在线列表展示头像框用
avatar_frame。 - 房间资料卡展示用
profile_card,从metadata_json.profile_card_layout解析content_top和content_height。 - 入场座驾展示用
vehicle。 - 麦位声波展示用
mic_seat_animation。 - 徽章条展示用
badges。 - 过期佩戴不会返回。
6. 进房
地址:
POST /api/v1/rooms/join
Body:
{
"room_id": "room_1001",
"command_id": "cmd-join-1001",
"role": "audience",
"password": "1234"
}
参数:
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| room_id | string | 是 | 房间 ID |
| command_id | string | 是 | 幂等 ID,Flutter 每次进房动作生成一个 |
| role | string | 否 | 默认 audience |
| password | string | 否 | 锁房密码 |
返回值:
{
"result": {
"applied": true,
"room_version": 9,
"server_time_ms": 1778256000000
},
"room": {},
"viewer": {},
"seats": [],
"contribution_rank": [],
"profiles": [
{
"user_id": "42",
"display_user_id": "100001",
"username": "Tom",
"avatar": "https://cdn.example/avatar.png"
}
],
"im": {
"group_id": "room_1001",
"need_join_group": true
},
"rtc": {
"need_token": true,
"available": true,
"token": {}
},
"server_time_ms": 1778256000000
}
说明:
- Flutter 不需要传入场座驾。
- 服务端会在进房时自动读取当前佩戴的
vehicle,写入房间 IM。 join返回里的profiles是基础资料。- 房间增强资料用
/users/room-display-profiles:batch,或使用房间详情、在线用户列表里内嵌的profile字段。
7. 相关 IM
用户进房
腾讯 IM 群自定义消息:
{
"event_id": "evt_xxx",
"room_id": "room_1001",
"event_type": "room_user_joined",
"actor_user_id": 42,
"target_user_id": 42,
"room_version": 9,
"entry_vehicle": {
"resource_id": 8102,
"resource_code": "vehicle_gold",
"name": "Gold Vehicle",
"asset_url": "https://cdn.example/vehicle.png",
"preview_url": "",
"animation_url": "https://cdn.example/vehicle.svga",
"metadata_json": "{}",
"entitlement_id": "ent-vehicle",
"expires_at_ms": 1999999999999
},
"attributes": {
"role": "audience"
}
}
Flutter 处理:
| 字段 | 说明 |
|---|---|
| event_type | room_user_joined 表示用户进入房间 |
| actor_user_id | 进房用户 ID |
| target_user_id | 进房用户 ID |
| room_version | 房间版本 |
| entry_vehicle | 入场座驾快照 |
| attributes.role | 用户进房角色,仅用于展示 |
处理规则:
entry_vehicle.resource_id > 0:播放入场座驾。entry_vehicle.animation_url:优先用于动画播放。entry_vehicle.asset_url/entry_vehicle.preview_url:动画不可用时兜底展示。entry_vehicle不存在或为空:普通进房,不播放座驾。- 不要收到进房 IM 后再实时请求
/appearance查询座驾,直接使用 IM 中的entry_vehicle快照。
8. Flutter 调用建议
- 个人装扮页进入时调
/api/v1/appearance。 - 背包页调
/api/v1/users/me/resources?resource_type=xxx。 - 点击佩戴调
POST /api/v1/users/me/resources/{resource_id}/equip,成功后刷新/appearance。 - 点击取消佩戴调
DELETE /api/v1/users/me/resources/{resource_type}/unequip,成功后刷新/appearance。 - 个人主页信息卡背景使用个人资料返回的
profile_bg_img;该字段是用户资料字段,和profile_card装扮资源无关。 - 房间、公屏、在线用户资料优先使用
room-display-profiles:batch的avatar_frame、profile_card、vehicle、badges。 - 收到
room_user_joinedIM 时,只按entry_vehicle播放入场座驾。