hyapp-server/docs/flutter对接/房内猜拳Flutter对接.md
2026-06-11 13:33:44 +08:00

9.4 KiB
Raw Permalink Blame History

房内猜拳 Flutter 对接

本文只记录房内猜拳 App 端 HTTP 接口和腾讯 IM 自定义消息字段。独立猜拳本阶段不接入。

1. 基本约定

  • 所有 HTTP 地址都有 /api/v1 前缀。
  • 所有接口都需要 Authorization: Bearer <access_token>
  • 成功响应统一是 gateway envelope
{
  "code": "OK",
  "message": "ok",
  "request_id": "req_xxx",
  "data": {}
}
  • 所有时间字段都是 Unix epoch milliseconds。
  • Flutter 模型里用户 ID、挑战 ID、礼物 ID 建议统一按 String 保存。
  • HTTP 返回的发起人和应战人资料在 challenge.initiator.userchallenge.challenger.user
  • IM 里的发起人和应战人也必须带 nicknameavatar;客户端不要为了基础展示再查用户资料。

2. 通用挑战单字段

challenge 字段在列表、详情、发起、应战接口中结构一致。

字段 类型 说明
challenge_id string 挑战单 ID。
room_id string 房间 ID。
region_id number 用户语区 ID。
status string pendingmatchedrevealingfinishedtimeoutsettlement_failedcancelled
stake_gift_id string 下注礼物 IDFlutter 优先用这个字段。
stake_gift_id_number number 下注礼物 ID 数字值。
stake_coin number 本局礼物对应金币价值。
initiator object 发起人。
challenger object 应战人;pending 时可能为空用户。
winner_user_id string 胜者用户 ID平局或未结算为空或 0
winner_user_id_number number 胜者用户 ID 数字值。
settlement_status string 结算状态,例如 pendingsettledfailed
failure_reason string 结算失败原因。
timeout_at_ms number 无人应战自动过期时间。
reveal_at_ms number 揭晓时间。
created_at_ms number 创建时间。
matched_at_ms number 应战成功时间。
settled_at_ms number 结算时间。
updated_at_ms number 更新时间。

initiatorchallenger 字段:

字段 类型 说明
user_id string 用户 IDFlutter 优先用这个字段。
user_id_number number 用户 ID 数字值。
gesture string rockpaperscissors
result string winlosedraw;未结算时为空。
balance_after number 结算后的金币余额。
joined_at_ms number 参与时间。
user.user_id string 展示用户 ID。
user.display_user_id string 短号或展示号。
user.nickname string 昵称;发起人和应战人都要有。
user.avatar string 头像;发起人和应战人都要有。

3. 查询配置

地址:

GET /api/v1/games/room-rps/config

参数:无。

返回值:

字段 类型 说明
config.status string activedisabled
config.challenge_timeout_ms number 发起后无人应战的超时时间,默认 10 分钟。
config.reveal_countdown_ms number 双方出拳后的揭晓倒计时,默认 3 秒。
config.stake_gifts array 礼物下注档位,固定 4 档。
server_time_ms number 服务端时间。

stake_gifts 字段:

字段 类型 说明
gift_id string 礼物 IDFlutter 优先用这个字段提交。
gift_id_number number 礼物 ID 数字值。
gift_name string 礼物名称。
gift_icon_url string 礼物图标。
gift_price_coin number 礼物价格金币。
enabled bool 是否启用。
sort_order number 排序。

相关 IM无。

4. 查询房间挑战单

地址:

GET /api/v1/games/room-rps/challenges

参数:

字段 位置 必填 说明
room_id query 房间 ID。
status query 挑战状态。
page_size query 页大小,默认 20。
cursor query 下一页游标。

返回值:

字段 类型 说明
challenges array 挑战单列表,结构见通用挑战单字段。
next_cursor string 下一页游标。
page_size number 本次页大小。
server_time_ms number 服务端时间。

相关 IM无。客户端漏掉 IM 后,用这个接口补拉当前房间挑战单。

5. 发起挑战

地址:

POST /api/v1/games/room-rps/challenges/create
Content-Type: application/json

参数:

字段 类型 必填 说明
room_id string 房间 ID。
gift_id number 后台配置的礼物档位 ID。
gesture string rockpaperscissors

请求示例:

{
  "room_id": "room_1001",
  "gift_id": 10001,
  "gesture": "rock"
}

返回值:

字段 类型 说明
challenge object 挑战单,结构见通用挑战单字段。
server_time_ms number 服务端时间。

相关 IMroom_rps_challenge_created

6. 应战

地址:

POST /api/v1/games/room-rps/challenges/{challenge_id}/accept
Content-Type: application/json

参数:

字段 位置 必填 说明
challenge_id path 挑战单 ID。
gesture body rockpaperscissors

请求示例:

{
  "gesture": "paper"
}

返回值:

字段 类型 说明
challenge object 应战后的挑战单,结构见通用挑战单字段。
server_time_ms number 服务端时间。

相关 IM

  • room_rps_challenge_accepted
  • room_rps_reveal_countdown
  • room_rps_finished

7. 查询挑战详情

地址:

GET /api/v1/games/room-rps/challenges/{challenge_id}

参数:

字段 位置 必填 说明
challenge_id path 挑战单 ID。

返回值:

字段 类型 说明
challenge object 挑战单,结构见通用挑战单字段。
server_time_ms number 服务端时间。

相关 IM无。客户端收到 IM 后,可以用这个接口刷新挑战事实。

8. 腾讯 IM 字段

房间群消息使用腾讯 IM TIMCustomElemdata 是 JSON 字符串。Flutter 只需要解析下面字段。

通用字段:

字段 类型 说明
event_id string IM 事件 ID客户端用它去重。
event_type string 事件类型。
room_id string 房间 ID。
challenge_id string 挑战单 ID。
server_time_ms number 服务端时间。
challenge object 挑战单快照,结构见通用挑战单字段。

challenge.initiator.user 字段:

字段 类型 必填 说明
user_id string 发起人用户 ID。
display_user_id string 发起人展示号。
nickname string 发起人昵称。
avatar string 发起人头像。

challenge.challenger.user 字段:

字段 类型 必填 说明
user_id string 应战后是 应战人用户 ID。
display_user_id string 应战人展示号。
nickname string 应战后是 应战人昵称。
avatar string 应战后是 应战人头像。

IM 事件:

event_type 触发时机 Flutter 处理
room_rps_challenge_created 用户发起挑战后 展示 [PK] 入口、发起人头像昵称、礼物和倒计时。此时 challenger 可以为空。
room_rps_challenge_accepted 有用户应战后 锁定挑战入口,展示双方头像昵称。
room_rps_reveal_countdown 双方出拳后 播放 3 秒揭晓动画,展示双方头像昵称。
room_rps_finished 结算完成或平局退款后 展示胜负、双方头像昵称、余额或失败提示。

IM 示例:

{
  "event_id": "room_rps_finished:rps_10001",
  "event_type": "room_rps_finished",
  "room_id": "room_1001",
  "challenge_id": "rps_10001",
  "server_time_ms": 1780000003000,
  "challenge": {
    "challenge_id": "rps_10001",
    "room_id": "room_1001",
    "status": "finished",
    "stake_gift_id": "10001",
    "stake_gift_id_number": 10001,
    "stake_coin": 100,
    "initiator": {
      "user_id": "10001",
      "user_id_number": 10001,
      "gesture": "rock",
      "result": "lose",
      "balance_after": 900,
      "joined_at_ms": 1780000000000,
      "user": {
        "user_id": "10001",
        "display_user_id": "880001",
        "nickname": "Alice",
        "avatar": "https://cdn.example/alice.png"
      }
    },
    "challenger": {
      "user_id": "10002",
      "user_id_number": 10002,
      "gesture": "paper",
      "result": "win",
      "balance_after": 1200,
      "joined_at_ms": 1780000001000,
      "user": {
        "user_id": "10002",
        "display_user_id": "880002",
        "nickname": "Bob",
        "avatar": "https://cdn.example/bob.png"
      }
    },
    "winner_user_id": "10002",
    "winner_user_id_number": 10002,
    "settlement_status": "settled",
    "timeout_at_ms": 1780000600000,
    "reveal_at_ms": 1780000003000,
    "created_at_ms": 1780000000000,
    "matched_at_ms": 1780000001000,
    "settled_at_ms": 1780000003000,
    "updated_at_ms": 1780000003000
  }
}