111
This commit is contained in:
@@ -1,3 +1,4 @@
|
||||
import 'dart:async';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:shadcn_ui/shadcn_ui.dart';
|
||||
@@ -7,6 +8,7 @@ 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/models/account_models.dart';
|
||||
import '../../../data/services/asset_service.dart';
|
||||
import '../../../data/services/bonus_service.dart';
|
||||
@@ -15,6 +17,7 @@ import '../../../providers/auth_provider.dart';
|
||||
import '../../components/glass_panel.dart';
|
||||
import '../../components/neon_glow.dart';
|
||||
import '../main/main_page.dart';
|
||||
import '../mine/welfare_center_page.dart';
|
||||
|
||||
/// 首页
|
||||
class HomePage extends StatefulWidget {
|
||||
@@ -26,8 +29,8 @@ class HomePage extends StatefulWidget {
|
||||
|
||||
class _HomePageState extends State<HomePage>
|
||||
with AutomaticKeepAliveClientMixin {
|
||||
bool _bonusClaimed = false;
|
||||
bool _bonusLoading = false;
|
||||
int _totalClaimable = 0;
|
||||
StreamSubscription<AppEvent>? _eventSub;
|
||||
|
||||
@override
|
||||
bool get wantKeepAlive => true;
|
||||
@@ -35,7 +38,26 @@ class _HomePageState extends State<HomePage>
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
WidgetsBinding.instance.addPostFrameCallback((_) => _loadData());
|
||||
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||
_loadData();
|
||||
_listenEvents();
|
||||
});
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
_eventSub?.cancel();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
void _listenEvents() {
|
||||
final eventBus = context.read<AppEventBus>();
|
||||
_eventSub = eventBus.on(AppEventType.assetChanged, (_) {
|
||||
if (mounted) {
|
||||
context.read<AssetProvider>().loadOverview(force: true);
|
||||
_checkBonusStatus();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void _loadData() {
|
||||
@@ -48,10 +70,10 @@ class _HomePageState extends State<HomePage>
|
||||
Future<void> _checkBonusStatus() async {
|
||||
try {
|
||||
final bonusService = context.read<BonusService>();
|
||||
final response = await bonusService.getStatus();
|
||||
final response = await bonusService.getWelfareStatus();
|
||||
if (response.success && response.data != null) {
|
||||
setState(() {
|
||||
_bonusClaimed = response.data!['claimed'] == true;
|
||||
_totalClaimable = response.data!['totalClaimable'] as int? ?? 0;
|
||||
});
|
||||
}
|
||||
} catch (_) {}
|
||||
@@ -89,11 +111,13 @@ class _HomePageState extends State<HomePage>
|
||||
onDeposit: _showDeposit,
|
||||
),
|
||||
SizedBox(height: AppSpacing.md),
|
||||
// 新人福利卡片
|
||||
_BonusCard(
|
||||
isClaimed: _bonusClaimed,
|
||||
onClaim: _claimBonus,
|
||||
isLoading: _bonusLoading,
|
||||
// 福利中心入口卡片
|
||||
_WelfareCard(
|
||||
totalClaimable: _totalClaimable,
|
||||
onTap: () => Navigator.push(
|
||||
context,
|
||||
MaterialPageRoute(builder: (_) => const WelfareCenterPage()),
|
||||
),
|
||||
),
|
||||
SizedBox(height: AppSpacing.lg),
|
||||
// 持仓
|
||||
@@ -384,64 +408,11 @@ class _HomePageState extends State<HomePage>
|
||||
mainState?.switchToTab(3);
|
||||
}
|
||||
|
||||
Future<void> _claimBonus() async {
|
||||
setState(() => _bonusLoading = true);
|
||||
try {
|
||||
final bonusService = context.read<BonusService>();
|
||||
final response = await bonusService.claim();
|
||||
if (!mounted) return;
|
||||
|
||||
if (response.success) {
|
||||
setState(() => _bonusClaimed = true);
|
||||
context.read<AssetProvider>().refreshAll(force: true);
|
||||
showShadDialog(
|
||||
context: context,
|
||||
builder: (ctx) => ShadDialog.alert(
|
||||
title: const Text('领取成功'),
|
||||
description:
|
||||
Text('50 USDT 已到账,请划转至交易账户后即可开始交易'),
|
||||
actions: [
|
||||
ShadButton(
|
||||
child: const Text('确定'),
|
||||
onPressed: () => Navigator.of(ctx).pop(),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
} else {
|
||||
showShadDialog(
|
||||
context: context,
|
||||
builder: (ctx) => ShadDialog.alert(
|
||||
title: const Text('领取失败'),
|
||||
description: Text(response.message ?? '请稍后重试'),
|
||||
actions: [
|
||||
ShadButton(
|
||||
child: const Text('确定'),
|
||||
onPressed: () => Navigator.of(ctx).pop(),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
} catch (e) {
|
||||
if (mounted) {
|
||||
showShadDialog(
|
||||
context: context,
|
||||
builder: (ctx) => ShadDialog.alert(
|
||||
title: const Text('领取失败'),
|
||||
description: Text(e.toString()),
|
||||
actions: [
|
||||
ShadButton(
|
||||
child: const Text('确定'),
|
||||
onPressed: () => Navigator.of(ctx).pop(),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
} finally {
|
||||
if (mounted) setState(() => _bonusLoading = false);
|
||||
}
|
||||
void _navigateToWelfareCenter() {
|
||||
Navigator.push(
|
||||
context,
|
||||
MaterialPageRoute(builder: (_) => const WelfareCenterPage()),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -963,120 +934,122 @@ class _AssetCardState extends State<_AssetCard> {
|
||||
}
|
||||
}
|
||||
|
||||
/// 新人福利卡片
|
||||
class _BonusCard extends StatelessWidget {
|
||||
final bool isClaimed;
|
||||
final VoidCallback onClaim;
|
||||
final bool isLoading;
|
||||
/// 福利中心入口卡片
|
||||
class _WelfareCard extends StatelessWidget {
|
||||
final int totalClaimable;
|
||||
final VoidCallback onTap;
|
||||
|
||||
const _BonusCard({required this.isClaimed, required this.onClaim, required this.isLoading});
|
||||
const _WelfareCard({required this.totalClaimable, required this.onTap});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final colorScheme = Theme.of(context).colorScheme;
|
||||
final isDark = Theme.of(context).brightness == Brightness.dark;
|
||||
|
||||
return Opacity(
|
||||
opacity: isClaimed ? 0.6 : 1.0,
|
||||
child: GestureDetector(
|
||||
onTap: isClaimed || isLoading ? null : onClaim,
|
||||
child: Container(
|
||||
width: double.infinity,
|
||||
padding: EdgeInsets.all(AppSpacing.lg),
|
||||
decoration: BoxDecoration(
|
||||
gradient: LinearGradient(
|
||||
colors: [
|
||||
colorScheme.primary.withOpacity(0.15),
|
||||
colorScheme.secondary.withOpacity(0.1),
|
||||
],
|
||||
begin: Alignment.topLeft,
|
||||
end: Alignment.bottomRight,
|
||||
),
|
||||
borderRadius: BorderRadius.circular(AppRadius.xl),
|
||||
border: Border.all(color: colorScheme.primary.withOpacity(0.2)),
|
||||
),
|
||||
child: Row(
|
||||
children: [
|
||||
// 左侧图标
|
||||
Container(
|
||||
width: 48,
|
||||
height: 48,
|
||||
decoration: BoxDecoration(
|
||||
color: isClaimed
|
||||
? colorScheme.onSurfaceVariant.withOpacity(0.1)
|
||||
: colorScheme.primary.withOpacity(0.15),
|
||||
borderRadius: BorderRadius.circular(AppRadius.lg),
|
||||
),
|
||||
child: Icon(
|
||||
isClaimed ? LucideIcons.check : LucideIcons.gift,
|
||||
color: isClaimed ? AppColorScheme.up : colorScheme.primary,
|
||||
size: 24,
|
||||
),
|
||||
),
|
||||
SizedBox(width: AppSpacing.md),
|
||||
// 中间文字
|
||||
Expanded(
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
'新人福利',
|
||||
style: GoogleFonts.spaceGrotesk(
|
||||
fontSize: 16,
|
||||
fontWeight: FontWeight.bold,
|
||||
color: colorScheme.onSurface,
|
||||
),
|
||||
),
|
||||
SizedBox(height: AppSpacing.xs),
|
||||
Text(
|
||||
isClaimed ? '50 USDT 体验金已到账' : '领取 50 USDT 体验金,开始您的交易之旅',
|
||||
style: TextStyle(
|
||||
fontSize: 12,
|
||||
color: colorScheme.onSurfaceVariant,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
// 右侧按钮
|
||||
Container(
|
||||
padding: EdgeInsets.symmetric(
|
||||
horizontal: AppSpacing.md,
|
||||
vertical: AppSpacing.sm,
|
||||
),
|
||||
decoration: BoxDecoration(
|
||||
color: isClaimed
|
||||
? colorScheme.onSurfaceVariant.withOpacity(0.15)
|
||||
: null,
|
||||
gradient: isClaimed
|
||||
? null
|
||||
: (isDark
|
||||
? AppColorScheme.darkCtaGradient
|
||||
: AppColorScheme.lightCtaGradient),
|
||||
borderRadius: BorderRadius.circular(AppRadius.full),
|
||||
),
|
||||
child: isLoading
|
||||
? SizedBox(
|
||||
width: 16,
|
||||
height: 16,
|
||||
child: CircularProgressIndicator(
|
||||
strokeWidth: 2,
|
||||
color: isDark ? colorScheme.background : Colors.white,
|
||||
),
|
||||
)
|
||||
: Text(
|
||||
isClaimed ? '已领取' : '立即领取',
|
||||
style: TextStyle(
|
||||
color: isClaimed
|
||||
? colorScheme.onSurfaceVariant
|
||||
: (isDark ? colorScheme.background : Colors.white),
|
||||
fontSize: 13,
|
||||
fontWeight: FontWeight.w700,
|
||||
),
|
||||
),
|
||||
),
|
||||
return GestureDetector(
|
||||
onTap: onTap,
|
||||
child: Container(
|
||||
width: double.infinity,
|
||||
padding: EdgeInsets.all(AppSpacing.lg),
|
||||
decoration: BoxDecoration(
|
||||
gradient: LinearGradient(
|
||||
colors: [
|
||||
colorScheme.primary.withOpacity(0.15),
|
||||
colorScheme.secondary.withOpacity(0.1),
|
||||
],
|
||||
begin: Alignment.topLeft,
|
||||
end: Alignment.bottomRight,
|
||||
),
|
||||
borderRadius: BorderRadius.circular(AppRadius.xl),
|
||||
border: Border.all(color: colorScheme.primary.withOpacity(0.2)),
|
||||
),
|
||||
child: Row(
|
||||
children: [
|
||||
// 左侧图标
|
||||
Container(
|
||||
width: 48,
|
||||
height: 48,
|
||||
decoration: BoxDecoration(
|
||||
color: colorScheme.primary.withOpacity(0.15),
|
||||
borderRadius: BorderRadius.circular(AppRadius.lg),
|
||||
),
|
||||
child: Icon(
|
||||
LucideIcons.gift,
|
||||
color: colorScheme.primary,
|
||||
size: 24,
|
||||
),
|
||||
),
|
||||
SizedBox(width: AppSpacing.md),
|
||||
// 中间文字
|
||||
Expanded(
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
'福利中心',
|
||||
style: GoogleFonts.spaceGrotesk(
|
||||
fontSize: 16,
|
||||
fontWeight: FontWeight.bold,
|
||||
color: colorScheme.onSurface,
|
||||
),
|
||||
),
|
||||
SizedBox(height: AppSpacing.xs),
|
||||
Text(
|
||||
totalClaimable > 0
|
||||
? '您有 $totalClaimable 个奖励待领取'
|
||||
: '首充奖励 + 推广奖励',
|
||||
style: TextStyle(
|
||||
fontSize: 12,
|
||||
color: colorScheme.onSurfaceVariant,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
// 右侧按钮
|
||||
Container(
|
||||
padding: EdgeInsets.symmetric(
|
||||
horizontal: AppSpacing.md,
|
||||
vertical: AppSpacing.sm,
|
||||
),
|
||||
decoration: BoxDecoration(
|
||||
gradient: isDark
|
||||
? AppColorScheme.darkCtaGradient
|
||||
: AppColorScheme.lightCtaGradient,
|
||||
borderRadius: BorderRadius.circular(AppRadius.full),
|
||||
),
|
||||
child: Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
if (totalClaimable > 0)
|
||||
Container(
|
||||
padding: EdgeInsets.symmetric(horizontal: 6, vertical: 2),
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.red,
|
||||
borderRadius: BorderRadius.circular(10),
|
||||
),
|
||||
child: Text(
|
||||
'$totalClaimable',
|
||||
style: TextStyle(
|
||||
color: Colors.white,
|
||||
fontSize: 10,
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
),
|
||||
),
|
||||
SizedBox(width: totalClaimable > 0 ? 6 : 0),
|
||||
Text(
|
||||
'查看',
|
||||
style: TextStyle(
|
||||
color: isDark ? colorScheme.background : Colors.white,
|
||||
fontSize: 13,
|
||||
fontWeight: FontWeight.w700,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user