Move skills system documentation from bottom to top of CLAUDE.md for better organization. Refactor Flutter asset page by extracting UI components into separate files and updating import structure for improved modularity.
715 lines
22 KiB
Dart
715 lines
22 KiB
Dart
import 'package:flutter/material.dart';
|
||
import 'package:flutter/services.dart';
|
||
import 'package:shadcn_ui/shadcn_ui.dart';
|
||
import 'package:provider/provider.dart';
|
||
import 'package:google_fonts/google_fonts.dart';
|
||
import '../../../core/theme/app_color_scheme.dart';
|
||
import '../../../core/theme/app_spacing.dart';
|
||
import '../../../core/utils/toast_utils.dart';
|
||
import '../../../core/event/app_event_bus.dart';
|
||
import '../../../data/services/bonus_service.dart';
|
||
import '../../../providers/asset_provider.dart';
|
||
|
||
/// 福利中心页面
|
||
class WelfareCenterPage extends StatefulWidget {
|
||
const WelfareCenterPage({super.key});
|
||
|
||
@override
|
||
State<WelfareCenterPage> createState() => _WelfareCenterPageState();
|
||
}
|
||
|
||
class _WelfareCenterPageState extends State<WelfareCenterPage> {
|
||
Map<String, dynamic>? _welfareData;
|
||
bool _isLoading = true;
|
||
|
||
@override
|
||
void initState() {
|
||
super.initState();
|
||
WidgetsBinding.instance.addPostFrameCallback((_) => _loadData());
|
||
}
|
||
|
||
Future<void> _loadData() async {
|
||
try {
|
||
final bonusService = context.read<BonusService>();
|
||
final response = await bonusService.getWelfareStatus();
|
||
if (mounted) {
|
||
setState(() {
|
||
_welfareData = response.data;
|
||
_isLoading = false;
|
||
});
|
||
}
|
||
} catch (_) {
|
||
if (mounted) setState(() => _isLoading = false);
|
||
}
|
||
}
|
||
|
||
// ============================================
|
||
// 主题感知颜色辅助
|
||
// ============================================
|
||
|
||
bool get _isDark => Theme.of(context).brightness == Brightness.dark;
|
||
|
||
/// 金色强调色 ($gold-accent)
|
||
Color get _goldAccent =>
|
||
_isDark ? AppColorScheme.darkSecondary : const Color(0xFFF59E0B);
|
||
|
||
/// 盈利绿色 ($profit-green)
|
||
Color get _profitGreen =>
|
||
_isDark ? const Color(0xFF4ADE80) : const Color(0xFF16A34A);
|
||
|
||
/// 盈利绿色背景 ($profit-green-bg)
|
||
Color get _profitGreenBg =>
|
||
_isDark ? const Color(0xFF052E16) : const Color(0xFFF0FDF4);
|
||
|
||
/// 文字静默色 ($text-muted)
|
||
Color get _textMuted =>
|
||
_isDark ? const Color(0xFF64748B) : const Color(0xFF94A3B8);
|
||
|
||
/// 第三级背景色 ($bg-tertiary)
|
||
Color get _bgTertiary =>
|
||
_isDark ? AppColorScheme.darkSurfaceContainerHigh : const Color(0xFFF1F5F9);
|
||
|
||
/// 卡片表面色 ($surface-card)
|
||
Color get _surfaceCard =>
|
||
_isDark ? AppColorScheme.darkSurfaceContainer : Colors.white;
|
||
|
||
/// 反色文字 ($text-inverse)
|
||
Color get _textInverse =>
|
||
_isDark ? const Color(0xFF0F172A) : Colors.white;
|
||
|
||
// ============================================
|
||
// 文本样式辅助
|
||
// ============================================
|
||
|
||
TextStyle _inter({
|
||
required double fontSize,
|
||
required FontWeight fontWeight,
|
||
required Color color,
|
||
}) {
|
||
return GoogleFonts.inter(
|
||
fontSize: fontSize,
|
||
fontWeight: fontWeight,
|
||
color: color,
|
||
);
|
||
}
|
||
|
||
// ============================================
|
||
// 容器样式辅助
|
||
// ============================================
|
||
|
||
/// 标准卡片容器
|
||
BoxDecoration _cardDecoration({Color? borderColor}) {
|
||
final scheme = Theme.of(context).colorScheme;
|
||
return BoxDecoration(
|
||
color: _surfaceCard,
|
||
borderRadius: BorderRadius.circular(AppRadius.lg),
|
||
border: Border.all(
|
||
color: borderColor ?? scheme.outlineVariant.withValues(alpha: 0.15),
|
||
),
|
||
);
|
||
}
|
||
|
||
/// 金色渐变卡片容器
|
||
BoxDecoration _goldGradientDecoration() {
|
||
return BoxDecoration(
|
||
borderRadius: BorderRadius.circular(AppRadius.xl),
|
||
gradient: LinearGradient(
|
||
begin: Alignment.topCenter,
|
||
end: Alignment.bottomCenter,
|
||
colors: [
|
||
_goldAccent.withValues(alpha: 0.15),
|
||
_surfaceCard,
|
||
],
|
||
),
|
||
border: Border.all(
|
||
color: _goldAccent.withValues(alpha: 0.3),
|
||
width: 1,
|
||
),
|
||
);
|
||
}
|
||
|
||
/// 状态胶囊标签
|
||
Widget _statusBadge(String text, Color textColor, Color bgColor) {
|
||
return Container(
|
||
padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 4),
|
||
decoration: BoxDecoration(
|
||
color: bgColor,
|
||
borderRadius: BorderRadius.circular(AppRadius.sm),
|
||
),
|
||
child: Text(
|
||
text,
|
||
style: _inter(fontSize: 11, fontWeight: FontWeight.w600, color: textColor),
|
||
),
|
||
);
|
||
}
|
||
|
||
/// 全宽按钮
|
||
Widget _fullWidthButton({
|
||
required String text,
|
||
required Color backgroundColor,
|
||
required Color foregroundColor,
|
||
required VoidCallback? onPressed,
|
||
Color? disabledBackgroundColor,
|
||
}) {
|
||
return SizedBox(
|
||
width: double.infinity,
|
||
height: 44,
|
||
child: ElevatedButton(
|
||
onPressed: onPressed,
|
||
style: ElevatedButton.styleFrom(
|
||
backgroundColor: backgroundColor,
|
||
foregroundColor: foregroundColor,
|
||
elevation: 0,
|
||
shape: RoundedRectangleBorder(
|
||
borderRadius: BorderRadius.circular(AppRadius.lg),
|
||
),
|
||
disabledBackgroundColor:
|
||
disabledBackgroundColor ?? backgroundColor.withValues(alpha: 0.3),
|
||
disabledForegroundColor: foregroundColor.withValues(alpha: 0.7),
|
||
),
|
||
child: Text(
|
||
text,
|
||
style: _inter(fontSize: 14, fontWeight: FontWeight.w700, color: foregroundColor),
|
||
),
|
||
),
|
||
);
|
||
}
|
||
|
||
@override
|
||
Widget build(BuildContext context) {
|
||
final colorScheme = Theme.of(context).colorScheme;
|
||
|
||
return Scaffold(
|
||
backgroundColor: _isDark
|
||
? AppColorScheme.darkBackground
|
||
: const Color(0xFFF8FAFC),
|
||
appBar: AppBar(
|
||
backgroundColor: _isDark
|
||
? AppColorScheme.darkBackground
|
||
: Colors.white,
|
||
elevation: 0,
|
||
scrolledUnderElevation: 0,
|
||
centerTitle: false,
|
||
titleSpacing: 0,
|
||
title: Text(
|
||
'福利中心',
|
||
style: _inter(
|
||
fontSize: 17,
|
||
fontWeight: FontWeight.w600,
|
||
color: colorScheme.onSurface,
|
||
),
|
||
),
|
||
leading: IconButton(
|
||
icon: Icon(LucideIcons.arrowLeft, color: colorScheme.onSurface, size: 24),
|
||
onPressed: () => Navigator.of(context).pop(),
|
||
),
|
||
),
|
||
body: _isLoading
|
||
? Center(
|
||
child: CircularProgressIndicator(
|
||
color: _goldAccent,
|
||
strokeWidth: 2.5,
|
||
),
|
||
)
|
||
: RefreshIndicator(
|
||
onRefresh: _loadData,
|
||
color: _goldAccent,
|
||
child: SingleChildScrollView(
|
||
physics: const AlwaysScrollableScrollPhysics(),
|
||
padding: const EdgeInsets.fromLTRB(16, 8, 16, 32),
|
||
child: Column(
|
||
crossAxisAlignment: CrossAxisAlignment.start,
|
||
children: [
|
||
_buildReferralCodeCard(context),
|
||
const SizedBox(height: 16),
|
||
_buildNewUserBonusCard(context),
|
||
const SizedBox(height: 16),
|
||
_buildReferralRewardsSection(context),
|
||
const SizedBox(height: 16),
|
||
_buildRulesCard(context),
|
||
],
|
||
),
|
||
),
|
||
),
|
||
);
|
||
}
|
||
|
||
// ============================================
|
||
// 推广码卡片(金色渐变边框 Hero Card)
|
||
// ============================================
|
||
|
||
Widget _buildReferralCodeCard(BuildContext context) {
|
||
final colorScheme = Theme.of(context).colorScheme;
|
||
final referralCode = _welfareData?['referralCode'] as String? ?? '';
|
||
|
||
return Container(
|
||
width: double.infinity,
|
||
padding: const EdgeInsets.all(24),
|
||
decoration: _goldGradientDecoration(),
|
||
child: Column(
|
||
crossAxisAlignment: CrossAxisAlignment.start,
|
||
children: [
|
||
// Header Row: gift icon + 标题
|
||
Row(
|
||
children: [
|
||
Icon(LucideIcons.gift, color: _goldAccent, size: 24),
|
||
const SizedBox(width: 10),
|
||
Text(
|
||
'我的邀请码',
|
||
style: _inter(
|
||
fontSize: 16,
|
||
fontWeight: FontWeight.w700,
|
||
color: colorScheme.onSurface,
|
||
),
|
||
),
|
||
],
|
||
),
|
||
const SizedBox(height: 16),
|
||
Text(
|
||
referralCode.isEmpty ? '暂无邀请码' : referralCode,
|
||
style: _inter(
|
||
fontSize: 24,
|
||
fontWeight: FontWeight.w800,
|
||
color: _goldAccent,
|
||
).copyWith(letterSpacing: 2),
|
||
),
|
||
const SizedBox(height: 16),
|
||
SizedBox(
|
||
width: double.infinity,
|
||
height: 40,
|
||
child: ElevatedButton(
|
||
onPressed: referralCode.isEmpty
|
||
? null
|
||
: () {
|
||
Clipboard.setData(ClipboardData(text: referralCode));
|
||
ToastUtils.show('邀请码已复制');
|
||
},
|
||
style: ElevatedButton.styleFrom(
|
||
backgroundColor: _goldAccent,
|
||
foregroundColor: _textInverse,
|
||
elevation: 0,
|
||
shape: RoundedRectangleBorder(
|
||
borderRadius: BorderRadius.circular(AppRadius.lg),
|
||
),
|
||
disabledBackgroundColor: _goldAccent.withValues(alpha: 0.4),
|
||
),
|
||
child: Text(
|
||
'复制邀请码',
|
||
style: _inter(fontSize: 14, fontWeight: FontWeight.w600, color: _textInverse),
|
||
),
|
||
),
|
||
),
|
||
],
|
||
),
|
||
);
|
||
}
|
||
|
||
// ============================================
|
||
// 新人福利卡片
|
||
// ============================================
|
||
|
||
Widget _buildNewUserBonusCard(BuildContext context) {
|
||
final colorScheme = Theme.of(context).colorScheme;
|
||
final newUserBonus = _welfareData?['newUserBonus'] as Map<String, dynamic>?;
|
||
final eligible = newUserBonus?['eligible'] as bool? ?? false;
|
||
final claimed = newUserBonus?['claimed'] as bool? ?? false;
|
||
final deposited = newUserBonus?['deposited'] as bool? ?? false;
|
||
|
||
// 状态判定
|
||
String badgeText;
|
||
bool showAvailableBadge;
|
||
String buttonText;
|
||
bool canClaim;
|
||
String description;
|
||
|
||
if (claimed) {
|
||
badgeText = '已领取';
|
||
showAvailableBadge = false;
|
||
buttonText = '已领取';
|
||
canClaim = false;
|
||
description = '新人福利已领取';
|
||
} else if (eligible) {
|
||
badgeText = '可领取';
|
||
showAvailableBadge = true;
|
||
buttonText = '立即领取';
|
||
canClaim = true;
|
||
description = '完成首次充值即可领取';
|
||
} else {
|
||
badgeText = deposited ? '已充值' : '待解锁';
|
||
showAvailableBadge = false;
|
||
buttonText = '未解锁';
|
||
canClaim = false;
|
||
description = deposited ? '已充值,等待系统确认' : '完成首次充值即可领取';
|
||
}
|
||
|
||
return Container(
|
||
width: double.infinity,
|
||
padding: const EdgeInsets.all(20),
|
||
decoration: _cardDecoration(),
|
||
child: Column(
|
||
crossAxisAlignment: CrossAxisAlignment.start,
|
||
children: [
|
||
// Header: 标题 + 状态标签
|
||
Row(
|
||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||
children: [
|
||
Text(
|
||
'新人福利',
|
||
style: _inter(
|
||
fontSize: 16,
|
||
fontWeight: FontWeight.w700,
|
||
color: colorScheme.onSurface,
|
||
),
|
||
),
|
||
if (showAvailableBadge)
|
||
_statusBadge(badgeText, _profitGreen, _profitGreenBg),
|
||
],
|
||
),
|
||
const SizedBox(height: 12),
|
||
Text(
|
||
'+100 USDT',
|
||
style: _inter(
|
||
fontSize: 28,
|
||
fontWeight: FontWeight.w800,
|
||
color: claimed ? colorScheme.onSurfaceVariant : _profitGreen,
|
||
),
|
||
),
|
||
const SizedBox(height: 8),
|
||
Text(
|
||
description,
|
||
style: _inter(
|
||
fontSize: 13,
|
||
fontWeight: FontWeight.normal,
|
||
color: colorScheme.onSurfaceVariant,
|
||
),
|
||
),
|
||
const SizedBox(height: 16),
|
||
_fullWidthButton(
|
||
text: buttonText,
|
||
backgroundColor: _profitGreen,
|
||
foregroundColor: Colors.white,
|
||
onPressed: canClaim ? () => _claimNewUserBonus() : null,
|
||
),
|
||
],
|
||
),
|
||
);
|
||
}
|
||
|
||
// ============================================
|
||
// 推广奖励列表
|
||
// ============================================
|
||
|
||
Widget _buildReferralRewardsSection(BuildContext context) {
|
||
final colorScheme = Theme.of(context).colorScheme;
|
||
final referralRewards =
|
||
_welfareData?['referralRewards'] as List<dynamic>? ?? [];
|
||
|
||
return Column(
|
||
crossAxisAlignment: CrossAxisAlignment.start,
|
||
children: [
|
||
// Section Header
|
||
Text(
|
||
'推广奖励',
|
||
style: _inter(
|
||
fontSize: 16,
|
||
fontWeight: FontWeight.w600,
|
||
color: colorScheme.onSurface,
|
||
),
|
||
),
|
||
const SizedBox(height: 4),
|
||
Text(
|
||
'每邀请一位好友充值达标,奖励100 USDT',
|
||
style: _inter(
|
||
fontSize: 11,
|
||
fontWeight: FontWeight.normal,
|
||
color: _textMuted,
|
||
),
|
||
),
|
||
const SizedBox(height: 12),
|
||
|
||
// 推广列表卡片
|
||
Container(
|
||
width: double.infinity,
|
||
decoration: _cardDecoration(),
|
||
child: referralRewards.isEmpty
|
||
? _buildEmptyReferralList(context)
|
||
: _buildReferralListItems(context, referralRewards),
|
||
),
|
||
],
|
||
);
|
||
}
|
||
|
||
Widget _buildEmptyReferralList(BuildContext context) {
|
||
final colorScheme = Theme.of(context).colorScheme;
|
||
return Padding(
|
||
padding: const EdgeInsets.all(32),
|
||
child: Center(
|
||
child: Column(
|
||
children: [
|
||
Icon(
|
||
LucideIcons.users,
|
||
size: 36,
|
||
color: _textMuted.withValues(alpha: 0.4),
|
||
),
|
||
const SizedBox(height: 8),
|
||
Text(
|
||
'暂无推广用户',
|
||
style: _inter(
|
||
fontSize: 13,
|
||
fontWeight: FontWeight.normal,
|
||
color: colorScheme.onSurfaceVariant,
|
||
),
|
||
),
|
||
],
|
||
),
|
||
),
|
||
);
|
||
}
|
||
|
||
Widget _buildReferralListItems(BuildContext context, List<dynamic> referralRewards) {
|
||
final colorScheme = Theme.of(context).colorScheme;
|
||
|
||
return Column(
|
||
children: List.generate(referralRewards.length, (index) {
|
||
final data = referralRewards[index] as Map<String, dynamic>;
|
||
final username = data['username'] as String? ?? '';
|
||
final totalDeposit = data['totalDeposit']?.toString() ?? '0';
|
||
final claimableCount = data['claimableCount'] as int? ?? 0;
|
||
final milestones = data['milestones'] as List<dynamic>? ?? [];
|
||
final isLast = index == referralRewards.length - 1;
|
||
|
||
// 进度计算
|
||
final progress = _computeProgress(milestones, totalDeposit);
|
||
// 操作按钮
|
||
final actionWidget = _buildReferralAction(
|
||
data: data,
|
||
claimableCount: claimableCount,
|
||
milestones: milestones,
|
||
progress: progress,
|
||
);
|
||
// 进度条颜色
|
||
final progressColor = _referralProgressColor(claimableCount, progress);
|
||
|
||
return Column(
|
||
children: [
|
||
Padding(
|
||
padding: const EdgeInsets.all(16),
|
||
child: Column(
|
||
children: [
|
||
Row(
|
||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||
children: [
|
||
Row(
|
||
children: [
|
||
_buildAvatar(username),
|
||
const SizedBox(width: 10),
|
||
Text(
|
||
username,
|
||
style: _inter(fontSize: 13, fontWeight: FontWeight.w500, color: colorScheme.onSurface),
|
||
),
|
||
const SizedBox(width: 10),
|
||
Text(
|
||
'充值: \u00A5$totalDeposit',
|
||
style: _inter(fontSize: 11, fontWeight: FontWeight.normal, color: colorScheme.onSurfaceVariant),
|
||
),
|
||
],
|
||
),
|
||
if (actionWidget != null) actionWidget,
|
||
],
|
||
),
|
||
const SizedBox(height: 10),
|
||
ClipRRect(
|
||
borderRadius: BorderRadius.circular(3),
|
||
child: SizedBox(
|
||
height: 6,
|
||
child: LinearProgressIndicator(
|
||
value: progress,
|
||
backgroundColor: _bgTertiary,
|
||
valueColor: AlwaysStoppedAnimation<Color>(progressColor),
|
||
minHeight: 6,
|
||
),
|
||
),
|
||
),
|
||
],
|
||
),
|
||
),
|
||
if (!isLast)
|
||
Divider(
|
||
height: 1,
|
||
thickness: 1,
|
||
color: colorScheme.outlineVariant.withValues(alpha: 0.15),
|
||
),
|
||
],
|
||
);
|
||
}),
|
||
);
|
||
}
|
||
|
||
Widget _buildAvatar(String username) {
|
||
final colorScheme = Theme.of(context).colorScheme;
|
||
return Container(
|
||
width: 32,
|
||
height: 32,
|
||
decoration: BoxDecoration(
|
||
color: _bgTertiary,
|
||
shape: BoxShape.circle,
|
||
),
|
||
child: Center(
|
||
child: Text(
|
||
username.isNotEmpty ? username[0].toUpperCase() : '?',
|
||
style: _inter(
|
||
fontSize: 13,
|
||
fontWeight: FontWeight.w500,
|
||
color: colorScheme.onSurfaceVariant,
|
||
),
|
||
),
|
||
),
|
||
);
|
||
}
|
||
|
||
/// 计算推荐奖励进度
|
||
double _computeProgress(List<dynamic> milestones, String totalDeposit) {
|
||
if (milestones.isNotEmpty) {
|
||
int earnedCount = milestones.where((m) {
|
||
final milestone = m as Map<String, dynamic>;
|
||
return milestone['earned'] as bool? ?? false;
|
||
}).length;
|
||
return earnedCount / milestones.length;
|
||
}
|
||
final deposit = double.tryParse(totalDeposit) ?? 0;
|
||
return (deposit / 1000).clamp(0.0, 1.0);
|
||
}
|
||
|
||
/// 根据状态获取进度条颜色
|
||
Color _referralProgressColor(int claimableCount, double progress) {
|
||
if (claimableCount > 0) return _profitGreen;
|
||
if (progress > 0) return _goldAccent;
|
||
return _bgTertiary;
|
||
}
|
||
|
||
/// 构建推荐奖励的操作按钮
|
||
Widget? _buildReferralAction({
|
||
required Map<String, dynamic> data,
|
||
required int claimableCount,
|
||
required List<dynamic> milestones,
|
||
required double progress,
|
||
}) {
|
||
if (claimableCount > 0) {
|
||
final int milestoneValue = milestones.isNotEmpty
|
||
? (milestones.firstWhere(
|
||
(m) => (m as Map<String, dynamic>)['claimable'] == true,
|
||
orElse: () => milestones.first,
|
||
) as Map<String, dynamic>)['milestone'] as int? ?? 1
|
||
: 1;
|
||
|
||
return GestureDetector(
|
||
onTap: () => _claimReferralBonus(data['userId'] as int, milestoneValue),
|
||
child: _statusBadge('领取', _profitGreen, _profitGreenBg),
|
||
);
|
||
}
|
||
if (progress > 0) {
|
||
return _statusBadge('进行中', const Color(0xFFD97706), const Color(0xFFFEF3C7));
|
||
}
|
||
return Text(
|
||
'待达标',
|
||
style: _inter(fontSize: 12, fontWeight: FontWeight.w500, color: _textMuted),
|
||
);
|
||
}
|
||
|
||
// ============================================
|
||
// 奖励规则卡片
|
||
// ============================================
|
||
|
||
Widget _buildRulesCard(BuildContext context) {
|
||
final colorScheme = Theme.of(context).colorScheme;
|
||
|
||
return Container(
|
||
width: double.infinity,
|
||
padding: const EdgeInsets.fromLTRB(20, 16, 20, 16),
|
||
decoration: BoxDecoration(
|
||
color: _bgTertiary,
|
||
borderRadius: BorderRadius.circular(AppRadius.lg),
|
||
),
|
||
child: Column(
|
||
crossAxisAlignment: CrossAxisAlignment.start,
|
||
children: [
|
||
Text(
|
||
'奖励规则',
|
||
style: _inter(
|
||
fontSize: 13,
|
||
fontWeight: FontWeight.w600,
|
||
color: colorScheme.onSurface,
|
||
),
|
||
),
|
||
const SizedBox(height: 8),
|
||
_buildRuleItem('新用户注册完成实名认证奖励 100 USDT'),
|
||
_buildRuleItem('邀请好友充值每达 1000 USDT,双方各获得 100 USDT'),
|
||
_buildRuleItem('奖励直接发放至资金账户'),
|
||
],
|
||
),
|
||
);
|
||
}
|
||
|
||
Widget _buildRuleItem(String text) {
|
||
final ruleTextColor = _isDark
|
||
? AppColorScheme.darkOnSurfaceVariant
|
||
: const Color(0xFF475569);
|
||
return Padding(
|
||
padding: const EdgeInsets.symmetric(vertical: 3),
|
||
child: Text(
|
||
'\u2022 $text',
|
||
style: _inter(
|
||
fontSize: 12,
|
||
fontWeight: FontWeight.normal,
|
||
color: ruleTextColor,
|
||
),
|
||
),
|
||
);
|
||
}
|
||
|
||
// ============================================
|
||
// 业务逻辑
|
||
// ============================================
|
||
|
||
Future<void> _claimNewUserBonus() async {
|
||
try {
|
||
final bonusService = context.read<BonusService>();
|
||
final response = await bonusService.claimNewUserBonus();
|
||
if (!mounted) return;
|
||
|
||
if (response.success) {
|
||
context.read<AssetProvider>().refreshAll(force: true);
|
||
context.read<AppEventBus>().fire(AppEventType.assetChanged);
|
||
ToastUtils.show('领取成功!100 USDT 已到账');
|
||
_loadData();
|
||
} else {
|
||
ToastUtils.show(response.message ?? '领取失败');
|
||
}
|
||
} catch (e) {
|
||
ToastUtils.show('领取失败: $e');
|
||
}
|
||
}
|
||
|
||
Future<void> _claimReferralBonus(int referredUserId, int milestone) async {
|
||
try {
|
||
final bonusService = context.read<BonusService>();
|
||
final response = await bonusService.claimReferralBonus(
|
||
referredUserId,
|
||
milestone,
|
||
);
|
||
if (!mounted) return;
|
||
|
||
if (response.success) {
|
||
context.read<AssetProvider>().refreshAll(force: true);
|
||
context.read<AppEventBus>().fire(AppEventType.assetChanged);
|
||
ToastUtils.show('领取成功!100 USDT 已到账');
|
||
_loadData();
|
||
} else {
|
||
ToastUtils.show(response.message ?? '领取失败');
|
||
}
|
||
} catch (e) {
|
||
ToastUtils.show('领取失败: $e');
|
||
}
|
||
}
|
||
}
|