hyapp-server/docs/flutter对接/成就徽章Flutter对接.md
2026-05-14 17:44:16 +08:00

10 KiB
Raw Permalink Blame History

成就徽章 Flutter 对接

地址

Base URL

https://<gateway-host>

本地开发:

http://127.0.0.1:13000
功能 Method Path
我的成就列表 GET /api/v1/achievements
我的徽章展示 GET /api/v1/badges/me
设置方形徽章展示槽 POST /api/v1/badges/display

通用请求

Headers

Header 必填 说明
Authorization Bearer <access_token>
Content-Type POST 必填 application/json
X-App-Code App 编码,默认 lalu
X-App-Package 包名解析 App 时使用
X-App-Platform android / ios

统一返回:

{
  "code": "OK",
  "message": "ok",
  "request_id": "req_xxx",
  "data": {}
}

失败返回:

{
  "code": "INVALID_ARGUMENT",
  "message": "invalid argument",
  "request_id": "req_xxx"
}

请求参数

GET /api/v1/achievements

Query

字段 必填 默认 说明
collection_type 全部 普通成就传 ordinary
collection_id 全部 成就集合 ID
page 1 页码,从 1 开始
page_size 20 每页数量

GET /api/v1/badges/me

无 query。

POST /api/v1/badges/display

Body

{
  "slot": "profile_tile",
  "command_id": "cmd_badge_display_1710000000000",
  "items": [
    {
      "position": 1,
      "resource_id": 8001,
      "entitlement_id": "ent_xxx"
    }
  ]
}
字段 必填 说明
slot 当前只允许 profile_tile
command_id 客户端本次操作幂等 ID同一次重试使用同一个值
items 展示槽完整替换;最多 6 个
items[].position 从 1 开始;不传按数组顺序生成
items[].resource_id 必须来自用户已获得的可展示徽章
items[].entitlement_id 有则透传

返回值

以下 JSON 均为统一 envelope 的 data

我的成就列表

{
  "achievements": [
    {
      "definition": {
        "achievement_id": "ach_first_gift",
        "collection_id": "ordinary",
        "collection_type": "ordinary",
        "achievement_type": "ordinary",
        "title": "First Gift",
        "description": "",
        "status": "active",
        "version": 1,
        "primary_badge_resource_id": 8001,
        "primary_badge_resource": {
          "resource_id": 8001,
          "resource_code": "badge_first_gift",
          "resource_type": "badge",
          "name": "First Gift",
          "status": "active",
          "grantable": true,
          "grant_strategy": "new_entitlement",
          "usage_scopes": ["badge"],
          "asset_url": "https://cdn.example/badge.png",
          "preview_url": "",
          "animation_url": "",
          "metadata_json": "{\"badge_form\":\"tile\"}",
          "sort_order": 10,
          "created_at_ms": 1710000000000,
          "updated_at_ms": 1710000000000
        },
        "reward_resource_group_id": 9001,
        "reward_resource_group": {
          "group_id": 9001,
          "group_code": "ach_first_gift_reward",
          "name": "First Gift Reward",
          "status": "active",
          "description": "",
          "sort_order": 10,
          "items": [
            {
              "group_item_id": 1,
              "item_type": "resource",
              "resource_id": 8001,
              "resource": {
                "resource_id": 8001,
                "resource_code": "badge_first_gift",
                "resource_type": "badge",
                "name": "First Gift",
                "status": "active",
                "grantable": true,
                "grant_strategy": "new_entitlement",
                "usage_scopes": ["badge"],
                "asset_url": "https://cdn.example/badge.png",
                "preview_url": "",
                "animation_url": "",
                "metadata_json": "{\"badge_form\":\"tile\"}",
                "sort_order": 10,
                "created_at_ms": 1710000000000,
                "updated_at_ms": 1710000000000
              },
              "quantity": 1,
              "duration_ms": 0,
              "sort_order": 10
            }
          ],
          "created_at_ms": 1710000000000,
          "updated_at_ms": 1710000000000
        },
        "auto_pin_policy": "if_empty",
        "honor_visibility": true,
        "effective_from_ms": 0,
        "effective_to_ms": 0,
        "sort_order": 10,
        "display_config_json": "{}",
        "conditions": [
          {
            "condition_id": "cond_xxx",
            "achievement_id": "ach_first_gift",
            "version": 1,
            "metric_type": "send_gift_count",
            "target_value": 1,
            "target_unit": "count",
            "dimension_filter_json": "{}"
          }
        ],
        "created_by_admin_id": 1,
        "updated_by_admin_id": 1,
        "created_at_ms": 1710000000000,
        "updated_at_ms": 1710000000000
      },
      "cycle_key": "lifetime",
      "progress_value": 1,
      "target_value": 1,
      "user_status": "unlocked",
      "unlocked_at_ms": 1710000000000,
      "reward_status": "granted"
    }
  ],
  "total": 1,
  "page": 1,
  "page_size": 20,
  "server_time_ms": 1710000000000
}

字段值:

字段
achievement_type ordinary / activity_limited
collection_type ordinary
user_status 空字符串表示未完成;unlocked 表示已达成
reward_status 空字符串 / pending / running / granted / failed
auto_pin_policy none / if_empty / always
primary_badge_resource 成就主徽章素材,可直接渲染
reward_resource_group.items[].resource 成就奖励资源素材,可直接渲染

我的徽章展示

{
  "strip_badges": [
    {
      "slot": "profile_strip",
      "position": 1,
      "badge_form": "strip",
      "resource_id": 8101,
      "resource": {
        "resource_id": 8101,
        "resource_code": "vip_gold_strip",
        "resource_type": "badge",
        "name": "VIP Gold",
        "status": "active",
        "grantable": true,
        "grant_strategy": "new_entitlement",
        "usage_scopes": ["badge"],
        "asset_url": "https://cdn.example/vip-strip.png",
        "preview_url": "",
        "animation_url": "",
        "metadata_json": "{\"badge_form\":\"strip\"}",
        "sort_order": 10,
        "created_at_ms": 1710000000000,
        "updated_at_ms": 1710000000000
      },
      "entitlement_id": "ent_strip_1",
      "source_type": "vip",
      "source_id": "vip_gold",
      "pin_mode": "system",
      "updated_at_ms": 1710000000000
    }
  ],
  "profile_tile_badges": [
    {
      "slot": "profile_tile",
      "position": 1,
      "badge_form": "tile",
      "resource_id": 8001,
      "resource": {
        "resource_id": 8001,
        "resource_code": "badge_first_gift",
        "resource_type": "badge",
        "name": "First Gift",
        "status": "active",
        "grantable": true,
        "grant_strategy": "new_entitlement",
        "usage_scopes": ["badge"],
        "asset_url": "https://cdn.example/badge.png",
        "preview_url": "",
        "animation_url": "",
        "metadata_json": "{\"badge_form\":\"tile\"}",
        "sort_order": 10,
        "created_at_ms": 1710000000000,
        "updated_at_ms": 1710000000000
      },
      "entitlement_id": "ent_tile_1",
      "source_type": "achievement",
      "source_id": "ach_first_gift",
      "pin_mode": "user",
      "updated_at_ms": 1710000000000
    }
  ],
  "honor_badges": [
    {
      "slot": "honor_wall",
      "position": 1,
      "badge_form": "tile",
      "resource_id": 8001,
      "resource": {
        "resource_id": 8001,
        "resource_code": "badge_first_gift",
        "resource_type": "badge",
        "name": "First Gift",
        "status": "active",
        "grantable": true,
        "grant_strategy": "new_entitlement",
        "usage_scopes": ["badge"],
        "asset_url": "https://cdn.example/badge.png",
        "preview_url": "",
        "animation_url": "",
        "metadata_json": "{\"badge_form\":\"tile\"}",
        "sort_order": 10,
        "created_at_ms": 1710000000000,
        "updated_at_ms": 1710000000000
      },
      "entitlement_id": "ent_tile_1",
      "source_type": "achievement",
      "source_id": "ach_first_gift",
      "pin_mode": "auto",
      "updated_at_ms": 1710000000000
    }
  ],
  "server_time_ms": 1710000000000
}

字段值:

字段 说明
strip_badges 长徽章身份、等级、VIP 等系统展示
profile_tile_badges 用户主页方形展示槽;用户可通过 POST /badges/display 调整
honor_badges 荣誉墙方形徽章;成就或系统赠送
badge_form strip 长徽章 / tile 方形徽章
slot profile_strip / profile_tile / honor_wall
source_type achievement / system_grant / level / vip / identity
resource 徽章素材,可直接渲染

错误处理

HTTP code 处理
200 OK 读取 data
400 INVALID_JSON 请求体不是合法 JSON
400 INVALID_ARGUMENT 参数错误;不自动重试
401 UNAUTHORIZED 刷新 token失败则重新登录
403 PROFILE_REQUIRED 跳转资料补全
403 PERMISSION_DENIED 停止当前操作
404 NOT_FOUND 资源不存在或徽章不可展示
429 RATE_LIMITED 延迟重试
500 INTERNAL_ERROR 提示重试,记录 request_id
502 UPSTREAM_ERROR 提示重试,记录 request_id

POST /api/v1/badges/display

场景 处理
网络超时 使用同一个 command_id 重试
用户重新调整排序 生成新的 command_id
NOT_FOUND 当前用户未获得该 resource_id 对应徽章,刷新 /api/v1/badges/me
INVALID_ARGUMENT 检查 slotitems.length <= 6resource_id > 0、重复 resource_id