import 'dart:async'; import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; import '../../../core/theme/app_spacing.dart'; import '../../../core/theme/app_theme.dart'; import '../../../core/event/app_event_bus.dart'; import '../../../providers/asset_provider.dart'; import 'components/account_tab_switcher.dart'; import 'components/action_buttons_row.dart'; import 'components/asset_dialogs.dart'; import 'components/balance_card.dart'; import 'components/holdings_section.dart'; import 'components/records_link_row.dart'; import '../orders/fund_orders_page.dart'; import 'transfer_page.dart'; /// 资产页面 - Matching .pen design spec (CMcqs) class AssetPage extends StatefulWidget { const AssetPage({super.key}); @override State createState() => _AssetPageState(); } class _AssetPageState extends State with AutomaticKeepAliveClientMixin { int _activeTab = 0; StreamSubscription? _eventSub; @override bool get wantKeepAlive => true; @override void initState() { super.initState(); WidgetsBinding.instance.addPostFrameCallback((_) { _loadData(); _listenEvents(); }); } @override void dispose() { _eventSub?.cancel(); super.dispose(); } void _listenEvents() { final eventBus = context.read(); _eventSub = eventBus.on(AppEventType.assetChanged, (_) { if (mounted) { context.read().refreshAll(force: true); } }); } void _loadData() { context.read().refreshAll(force: true); } @override Widget build(BuildContext context) { super.build(context); final colorScheme = Theme.of(context).colorScheme; return Scaffold( backgroundColor: colorScheme.background, body: Consumer( builder: (context, provider, _) { return RefreshIndicator( onRefresh: () => provider.refreshAll(force: true), color: colorScheme.primary, backgroundColor: colorScheme.surfaceContainerHighest, child: SingleChildScrollView( physics: const AlwaysScrollableScrollPhysics(), padding: const EdgeInsets.fromLTRB(AppSpacing.md, AppSpacing.md + 8, AppSpacing.md, 32), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ // Page title: "资产" 22px bold — matching .pen titleFrame padding [16,0,8,0] Padding( padding: const EdgeInsets.only(top: 16, bottom: 8), child: Text( '资产', style: AppTextStyles.displaySmall(context), ), ), const SizedBox(height: AppSpacing.sm), // Account tab switcher — pill-style matching .pen UE6xC AccountTabSwitcher( selectedIndex: _activeTab, onChanged: (index) => setState(() => _activeTab = index), ), const SizedBox(height: AppSpacing.md), // Balance card — matching .pen 59637 (cornerRadius lg, stroke, padding 20, gap 12) BalanceCard( provider: provider, activeTab: _activeTab, ), const SizedBox(height: AppSpacing.md), // Action buttons row — matching .pen pIpHe (gap 12) ActionButtonsRow( onDeposit: () => showDepositDialog(context), onWithdraw: () => showWithdrawDialog(context, provider.fundAccount?.balance), onTransfer: () => _navigateToTransfer(context), ), const SizedBox(height: AppSpacing.md), // Records link row — matching .pen fLHtq (cornerRadius lg, padding [14,16], stroke) RecordsLinkRow( onTap: () => Navigator.push( context, MaterialPageRoute(builder: (_) => const FundOrdersPage()), ), ), const SizedBox(height: AppSpacing.md), // Holdings section — matching .pen th9BG + 6X6tC HoldingsSection(holdings: _activeTab == 1 ? provider.holdings : []), ], ), ), ); }, ), ); } void _navigateToTransfer(BuildContext context) async { final result = await Navigator.push( context, MaterialPageRoute(builder: (_) => const TransferPage()), ); if (result == true && context.mounted) { context.read().refreshAll(force: true); } } }