hyapp-server/docs/用户装扮Flutter对接文档.md
2026-06-16 17:00:06 +08:00

13 KiB
Raw Permalink Blame History

用户装扮 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_urlpreview_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_frameprofile_cardvehiclechat_bubblebadgemic_seat_animation
  • badgemic_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_topcontent_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 幂等 IDFlutter 每次进房动作生成一个
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 调用建议

  1. 个人装扮页进入时调 /api/v1/appearance
  2. 背包页调 /api/v1/users/me/resources?resource_type=xxx
  3. 点击佩戴调 POST /api/v1/users/me/resources/{resource_id}/equip,成功后刷新 /appearance
  4. 点击取消佩戴调 DELETE /api/v1/users/me/resources/{resource_type}/unequip,成功后刷新 /appearance
  5. 个人主页信息卡背景使用个人资料返回的 profile_bg_img;该字段是用户资料字段,和 profile_card 装扮资源无关。
  6. 房间、公屏、在线用户资料优先使用 room-display-profiles:batchavatar_frameprofile_cardvehiclebadges
  7. 收到 room_user_joined IM 时,只按 entry_vehicle 播放入场座驾。