10 KiB
10 KiB
成就徽章 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 |
检查 slot、items.length <= 6、resource_id > 0、重复 resource_id |