150 lines
4.8 KiB
Markdown
150 lines
4.8 KiB
Markdown
# 币商列表 Flutter 对接
|
||
|
||
本文描述 Flutter App 获取当前用户所在区域启用币商列表的接口。币商身份、状态和区域过滤由 `user-service` 维护;App 只展示 gateway 返回的列表,不传 `region_id`,也不在本地缓存为跨区域通用数据。
|
||
|
||
## 接口
|
||
|
||
`GET /api/v1/wallet/coin-sellers`
|
||
|
||
登录接口,需要 `Authorization: Bearer <access_token>`。接口按当前登录用户的 `users.region_id` 查询同区域、状态为 `active`、资产类型为 `COIN_SELLER_COIN` 的币商。
|
||
|
||
请求头:
|
||
|
||
| Header | 必填 | 说明 |
|
||
| --- | --- | --- |
|
||
| `Authorization` | 是 | App 登录 access token。 |
|
||
| `X-App-Code` | 否 | App 编码,默认 `lalu`。 |
|
||
| `X-Request-ID` | 否 | 客户端链路 ID;服务端也会生成并在响应中返回。 |
|
||
|
||
Query:无。不要传 `region_id`、`country_id` 或 `user_id`。
|
||
|
||
示例:
|
||
|
||
```http
|
||
GET /api/v1/wallet/coin-sellers
|
||
Authorization: Bearer <access_token>
|
||
X-App-Code: lalu
|
||
```
|
||
|
||
成功响应:
|
||
|
||
```json
|
||
{
|
||
"code": "OK",
|
||
"message": "ok",
|
||
"request_id": "req_abc",
|
||
"data": {
|
||
"items": [
|
||
{
|
||
"user_id": "801",
|
||
"display_user_id": "900801",
|
||
"username": "Seller One",
|
||
"avatar": "https://cdn.example/avatar.png",
|
||
"country_id": 86,
|
||
"country_code": "CN",
|
||
"country_name": "China",
|
||
"country_display_name": "中国",
|
||
"region_id": 30,
|
||
"region_code": "east-asia",
|
||
"region_name": "East Asia",
|
||
"status": "active",
|
||
"merchant_asset_type": "COIN_SELLER_COIN",
|
||
"updated_at_ms": 1700000001000
|
||
}
|
||
],
|
||
"total": 1
|
||
}
|
||
}
|
||
```
|
||
|
||
字段规则:
|
||
|
||
| 字段 | 说明 |
|
||
| --- | --- |
|
||
| `user_id` | 币商用户长 ID,JSON 中按字符串返回,避免 Dart/JS 大整数精度问题。 |
|
||
| `display_user_id` | 当前展示短号,可用于转账页展示和输入确认。 |
|
||
| `username` | 币商昵称;为空时客户端可展示短号。 |
|
||
| `avatar` | 币商头像 URL;为空时展示默认头像。 |
|
||
| `country_id` | 币商用户当前国家 ID。 |
|
||
| `country_code` | 国家编码,例如 `CN`。 |
|
||
| `country_name` | 英文或标准国家名。 |
|
||
| `country_display_name` | 客户端展示优先使用的国家名。 |
|
||
| `region_id` | 币商用户当前区域 ID;应与当前用户区域一致。 |
|
||
| `status` | 当前只会返回 `active`。 |
|
||
| `merchant_asset_type` | 当前固定为 `COIN_SELLER_COIN`。 |
|
||
| `updated_at_ms` | 币商身份最近更新时间,Unix epoch milliseconds。 |
|
||
|
||
## Flutter 解析示例
|
||
|
||
```dart
|
||
class CoinSellerList {
|
||
CoinSellerList({
|
||
required this.items,
|
||
required this.total,
|
||
});
|
||
|
||
final List<CoinSeller> items;
|
||
final int total;
|
||
|
||
factory CoinSellerList.fromJson(Map<String, dynamic> json) {
|
||
return CoinSellerList(
|
||
items: (json['items'] as List<dynamic>? ?? const [])
|
||
.map((item) => CoinSeller.fromJson(item as Map<String, dynamic>))
|
||
.toList(),
|
||
total: (json['total'] as num?)?.toInt() ?? 0,
|
||
);
|
||
}
|
||
}
|
||
|
||
class CoinSeller {
|
||
CoinSeller({
|
||
required this.userId,
|
||
required this.displayUserId,
|
||
required this.username,
|
||
required this.avatar,
|
||
required this.countryId,
|
||
required this.countryDisplayName,
|
||
required this.regionId,
|
||
required this.status,
|
||
required this.merchantAssetType,
|
||
required this.updatedAtMs,
|
||
});
|
||
|
||
final String userId;
|
||
final String displayUserId;
|
||
final String username;
|
||
final String avatar;
|
||
final int countryId;
|
||
final String countryDisplayName;
|
||
final int regionId;
|
||
final String status;
|
||
final String merchantAssetType;
|
||
final int updatedAtMs;
|
||
|
||
String get title => username.isNotEmpty ? username : displayUserId;
|
||
|
||
factory CoinSeller.fromJson(Map<String, dynamic> json) {
|
||
return CoinSeller(
|
||
userId: json['user_id'] as String? ?? '',
|
||
displayUserId: json['display_user_id'] as String? ?? '',
|
||
username: json['username'] as String? ?? '',
|
||
avatar: json['avatar'] as String? ?? '',
|
||
countryId: (json['country_id'] as num?)?.toInt() ?? 0,
|
||
countryDisplayName: json['country_display_name'] as String? ?? '',
|
||
regionId: (json['region_id'] as num?)?.toInt() ?? 0,
|
||
status: json['status'] as String? ?? '',
|
||
merchantAssetType: json['merchant_asset_type'] as String? ?? '',
|
||
updatedAtMs: (json['updated_at_ms'] as num?)?.toInt() ?? 0,
|
||
);
|
||
}
|
||
}
|
||
```
|
||
|
||
## 客户端处理
|
||
|
||
1. 先解析外层 envelope,只有 `code == "OK"` 时读取 `data.items`。
|
||
2. 空列表表示当前区域暂无启用币商;展示空状态,不切换到其他区域。
|
||
3. 点击币商进入转账或联系流程时,使用 `display_user_id` 做用户可见确认,实际后续接口仍以服务端解析结果为准。
|
||
4. 用户切换国家或完成资料变更后重新拉取本接口,不复用旧区域列表。
|
||
5. 请求失败时记录 `request_id`,按登录失效、参数错误、服务错误分别处理。
|