hyapp-server/docs/注册奖励Flutter对接.md

125 lines
3.6 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 注册奖励 Flutter 对接
## 边界
注册奖励由服务端在三方注册成功后自动发放。Flutter 端不需要、也不能主动发放奖励,只需要在登录态下查询当前用户是否仍满足领取条件,用于展示入口、提示或埋点。
服务端判断条件:
- 用户没有成功领取过注册奖励。
- 注册奖励配置已开启且奖励配置有效。
- UTC 当天每日限制份数未用完;`daily_limit=0` 表示不限量。
## 查询接口
`GET /api/v1/activities/registration-reward/eligibility`
请求头:
```http
Authorization: Bearer <access_token>
X-App-Code: lalu
```
响应仍使用 gateway 统一 envelope
```json
{
"code": 0,
"message": "ok",
"request_id": "req_xxx",
"data": {
"can_receive": false,
"reason": "already_claimed",
"enabled": true,
"reward_type": "coin",
"coin_amount": 100,
"resource_group_id": 0,
"daily_limit": 1000,
"daily_used": 328,
"daily_remaining": 672,
"reward_day": "2026-05-12",
"server_time_ms": 1778563200000
}
}
```
`reason` 取值:
- `eligible`: 当前用户符合条件。
- `already_claimed`: 用户已经领取或正在发放中。
- `daily_limit_reached`: UTC 当天份数已用完。
- `disabled`: 后台关闭注册奖励。
- `not_configured`: 后台还没有配置注册奖励。
- `invalid_config`: 后台配置不完整,例如金币数量为 0 或资源组为空。
## Dart DTO
```dart
class RegistrationRewardEligibility {
const RegistrationRewardEligibility({
required this.canReceive,
required this.reason,
required this.enabled,
required this.rewardType,
required this.coinAmount,
required this.resourceGroupId,
required this.dailyLimit,
required this.dailyUsed,
required this.dailyRemaining,
required this.rewardDay,
required this.serverTimeMs,
});
final bool canReceive;
final String reason;
final bool enabled;
final String rewardType;
final int coinAmount;
final int resourceGroupId;
final int dailyLimit;
final int dailyUsed;
final int dailyRemaining;
final String rewardDay;
final int serverTimeMs;
factory RegistrationRewardEligibility.fromJson(Map<String, dynamic> json) {
return RegistrationRewardEligibility(
canReceive: json['can_receive'] == true,
reason: json['reason'] as String? ?? '',
enabled: json['enabled'] == true,
rewardType: json['reward_type'] as String? ?? '',
coinAmount: (json['coin_amount'] as num? ?? 0).toInt(),
resourceGroupId: (json['resource_group_id'] as num? ?? 0).toInt(),
dailyLimit: (json['daily_limit'] as num? ?? 0).toInt(),
dailyUsed: (json['daily_used'] as num? ?? 0).toInt(),
dailyRemaining: (json['daily_remaining'] as num? ?? 0).toInt(),
rewardDay: json['reward_day'] as String? ?? '',
serverTimeMs: (json['server_time_ms'] as num? ?? 0).toInt(),
);
}
}
```
## 调用示例
```dart
Future<RegistrationRewardEligibility> fetchRegistrationRewardEligibility(
ApiClient api,
) async {
final envelope = await api.get('/api/v1/activities/registration-reward/eligibility');
if (envelope.code != 0) {
throw ApiException(envelope.code, envelope.message);
}
return RegistrationRewardEligibility.fromJson(
envelope.data as Map<String, dynamic>,
);
}
```
## 客户端使用建议
新用户登录成功后可以调用一次该接口刷新展示状态;如果 `can_receive=false``reason=already_claimed`,说明服务端已经成功发放或发放中,不要重复提示用户手动领取。
`reward_day` 按 UTC 日期返回,不使用设备时区;客户端只做展示,不要用本地日期自行判断每日份数。