import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:lucide_icons_flutter/lucide_icons.dart'; import 'package:provider/provider.dart'; import '../../../core/theme/app_theme.dart'; import '../../../core/theme/app_spacing.dart'; import '../../../core/utils/toast_utils.dart'; import '../../../providers/asset_provider.dart'; import '../../components/material_input.dart'; /// 充值页面 class DepositPage extends StatefulWidget { const DepositPage({super.key}); @override State createState() => _DepositPageState(); } class _DepositPageState extends State { final _amountController = TextEditingController(); final _amountFocus = FocusNode(); bool _isSubmitting = false; // 充值结果 bool _showResult = false; String? _orderNo; String? _amount; String? _walletAddress; String _walletNetwork = 'TRC20'; @override void initState() { super.initState(); _amountController.addListener(() => setState(() {})); } @override void dispose() { _amountController.dispose(); _amountFocus.dispose(); super.dispose(); } // ============================================ // 业务逻辑 // ============================================ Future _submitDeposit() async { final text = _amountController.text; final n = double.tryParse(text); if (text.isEmpty || n == null || n <= 0) { ToastUtils.showError('請輸入有效金額'); return; } if (n < 1000) { ToastUtils.showError('單筆最低充值 1000 USDT'); return; } if (_isSubmitting) return; setState(() => _isSubmitting = true); try { final response = await context.read().deposit( amount: _amountController.text, ); if (!mounted) return; if (response.success && response.data != null) { setState(() { _showResult = true; _orderNo = response.data!['orderNo'] as String? ?? ''; _amount = response.data!['amount']?.toString() ?? '0.00'; _walletAddress = response.data!['walletAddress'] as String? ?? ''; _walletNetwork = response.data!['walletNetwork'] as String? ?? 'TRC20'; }); } else { ToastUtils.showError(response.message ?? '申請失敗'); } } catch (e) { if (mounted) ToastUtils.showError('申請失敗: $e'); } finally { if (mounted) setState(() => _isSubmitting = false); } } Future _confirmPay() async { if (_orderNo == null) return; final confirmed = await showDialog( context: context, builder: (ctx) => AlertDialog( title: const Text('確認已打款'), content: const Text('確認您已完成向指定地址的轉賬?'), actions: [ TextButton( onPressed: () => Navigator.pop(ctx, false), child: const Text('取消'), ), TextButton( onPressed: () => Navigator.pop(ctx, true), child: const Text('確認'), ), ], ), ); if (confirmed != true || !mounted) return; try { final response = await context.read().confirmPay(_orderNo!); if (!mounted) return; if (response.success) { ToastUtils.showSuccess('確認成功,請等待管理員審核'); Navigator.of(context).pop(true); } else { ToastUtils.showError(response.message ?? '確認失敗'); } } catch (e) { if (mounted) ToastUtils.showError('確認失敗: $e'); } } // ============================================ // 构建 UI // ============================================ @override Widget build(BuildContext context) { final colorScheme = Theme.of(context).colorScheme; return Scaffold( backgroundColor: colorScheme.surface, appBar: AppBar( leading: IconButton( icon: Icon(LucideIcons.arrowLeft, color: colorScheme.onSurface, size: 20), onPressed: () => Navigator.of(context).pop(), ), title: Text( '充值', style: AppTextStyles.headlineLarge(context).copyWith( fontWeight: FontWeight.w600, ), ), backgroundColor: Colors.transparent, elevation: 0, scrolledUnderElevation: 0, centerTitle: true, ), body: _showResult ? _buildResultView() : _buildFormView(), ); } // ============================================ // 表单视图 // ============================================ Widget _buildFormView() { final colorScheme = Theme.of(context).colorScheme; return SingleChildScrollView( padding: const EdgeInsets.fromLTRB( AppSpacing.md, AppSpacing.xs, AppSpacing.md, AppSpacing.xl), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ // 币种行 _buildCoinRow(colorScheme), const SizedBox(height: AppSpacing.lg), // 金额输入 _buildAmountInput(colorScheme), const SizedBox(height: AppSpacing.sm), // 最低金额提示 _buildMinTip(colorScheme), const SizedBox(height: AppSpacing.xl), // 操作流程 _buildSteps(colorScheme), const SizedBox(height: AppSpacing.xxl), // 提交按钮 _buildSubmitButton(colorScheme, '下一步', _submitDeposit), const SizedBox(height: AppSpacing.md), // 底部提示 _buildBottomTip(colorScheme), ], ), ); } Widget _buildCoinRow(ColorScheme colorScheme) { return Container( width: double.infinity, padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 14), decoration: BoxDecoration( color: colorScheme.surface, borderRadius: BorderRadius.circular(14), border: Border.all( color: colorScheme.outlineVariant.withValues(alpha: 0.5), width: 1, ), ), child: Row( children: [ Text( 'USDT', style: AppTextStyles.bodyLarge(context).copyWith( fontWeight: FontWeight.w600, ), ), const SizedBox(width: 8), Text( 'Tether USD', style: AppTextStyles.bodySmall(context).copyWith( color: colorScheme.onSurfaceVariant, ), ), ], ), ); } Widget _buildAmountLabel(ColorScheme colorScheme) { return Text( '充值金額', style: AppTextStyles.bodyMedium(context).copyWith( color: colorScheme.onSurfaceVariant, fontWeight: FontWeight.w500, ), ); } Widget _buildAmountInput(ColorScheme colorScheme) { return MaterialInput( controller: _amountController, focusNode: _amountFocus, labelText: '充值金額', hintText: '0.00', keyboardType: const TextInputType.numberWithOptions(decimal: true), inputFormatters: [ FilteringTextInputFormatter.allow(RegExp(r'^\d*\.?\d{0,8}')), ], suffixIcon: Padding( padding: const EdgeInsets.only(right: AppSpacing.md), child: Text( 'USDT', style: AppTextStyles.bodyMedium(context).copyWith( color: colorScheme.onSurfaceVariant, fontWeight: FontWeight.w500, ), ), ), ); } Widget _buildMinTip(ColorScheme colorScheme) { return Padding( padding: const EdgeInsets.symmetric(vertical: 4), child: Row( children: [ Icon(LucideIcons.info, size: 13, color: colorScheme.onSurfaceVariant), const SizedBox(width: 6), Text( '單筆最低充值 1000 USDT', style: AppTextStyles.bodySmall(context).copyWith( color: colorScheme.onSurfaceVariant, ), ), ], ), ); } Widget _buildSteps(ColorScheme colorScheme) { final steps = [ '輸入充值金額並提交申請', '向指定錢包地址轉賬', '點擊「已打款」確認', '等待管理員審核通過', ]; return Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( '操作流程', style: AppTextStyles.bodyMedium(context).copyWith( fontWeight: FontWeight.w500, ), ), const SizedBox(height: 12), ...steps.asMap().entries.map((e) => Padding( padding: const EdgeInsets.only(bottom: 10), child: Row( children: [ Text( '${e.key + 1}.', style: AppTextStyles.bodySmall(context).copyWith( color: colorScheme.onSurfaceVariant, fontWeight: FontWeight.w500, ), ), const SizedBox(width: 8), Expanded( child: Text( e.value, style: AppTextStyles.bodySmall(context).copyWith( color: colorScheme.onSurfaceVariant, ), ), ), ], ), )), ], ); } // ============================================ // 结果视图 // ============================================ Widget _buildResultView() { final colorScheme = Theme.of(context).colorScheme; return SingleChildScrollView( padding: const EdgeInsets.fromLTRB( AppSpacing.md, AppSpacing.xs, AppSpacing.md, AppSpacing.xl), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ // 成功提示 Center( child: Column( children: [ Icon( LucideIcons.circleCheck, size: 48, color: colorScheme.secondary, ), const SizedBox(height: 12), Text( '充值申請成功', style: AppTextStyles.headlineSmall(context).copyWith( fontWeight: FontWeight.w600, ), ), const SizedBox(height: 4), Text( '請向以下地址轉賬完成充值', style: AppTextStyles.bodyMedium(context).copyWith( color: colorScheme.onSurfaceVariant, ), ), ], ), ), const SizedBox(height: AppSpacing.xl), // 订单信息 _buildInfoCard(colorScheme), const SizedBox(height: AppSpacing.lg), // 收款地址 _buildAddressCard(colorScheme), const SizedBox(height: AppSpacing.md), // 提示 Padding( padding: const EdgeInsets.symmetric(vertical: 4), child: Row( crossAxisAlignment: CrossAxisAlignment.start, children: [ Icon(LucideIcons.info, size: 13, color: colorScheme.onSurfaceVariant), const SizedBox(width: 6), Expanded( child: Text( '轉賬完成後請點擊「已打款」確認,管理員審核通過後資金將到賬。', style: AppTextStyles.bodySmall(context).copyWith( color: colorScheme.onSurfaceVariant, ), ), ), ], ), ), const SizedBox(height: AppSpacing.xl), // 操作按钮 Row( children: [ Expanded( child: SizedBox( height: 48, child: OutlinedButton( onPressed: () => Navigator.of(context).pop(), style: OutlinedButton.styleFrom( side: BorderSide(color: colorScheme.outline), shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(14), ), ), child: Text( '稍後確認', style: AppTextStyles.bodyMedium(context).copyWith( fontWeight: FontWeight.w500, ), ), ), ), ), const SizedBox(width: AppSpacing.md), Expanded( child: SizedBox( height: 48, child: ElevatedButton( onPressed: _confirmPay, style: ElevatedButton.styleFrom( backgroundColor: colorScheme.onSurface, foregroundColor: colorScheme.surface, elevation: 0, shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(14), ), ), child: Text( '已打款', style: AppTextStyles.bodyMedium(context).copyWith( fontWeight: FontWeight.w600, color: colorScheme.surface, ), ), ), ), ), ], ), ], ), ); } Widget _buildInfoCard(ColorScheme colorScheme) { return Container( width: double.infinity, padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 14), decoration: BoxDecoration( color: colorScheme.surface, borderRadius: BorderRadius.circular(14), border: Border.all( color: colorScheme.outlineVariant.withValues(alpha: 0.5), width: 1, ), ), child: Column( children: [ Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Text( '訂單號', style: AppTextStyles.bodySmall(context).copyWith( color: colorScheme.onSurfaceVariant, ), ), Text( _orderNo ?? '', style: AppTextStyles.bodySmall(context).copyWith( fontWeight: FontWeight.w500, ), ), ], ), const SizedBox(height: 10), Divider( height: 1, color: colorScheme.outlineVariant.withValues(alpha: 0.3)), const SizedBox(height: 10), Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Text( '充值金額', style: AppTextStyles.bodySmall(context).copyWith( color: colorScheme.onSurfaceVariant, ), ), Text( '${_amount ?? "0.00"} USDT', style: AppTextStyles.bodyMedium(context).copyWith( fontWeight: FontWeight.w600, ), ), ], ), ], ), ); } Widget _buildAddressCard(ColorScheme colorScheme) { return Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( '收款地址', style: AppTextStyles.bodyMedium(context).copyWith( fontWeight: FontWeight.w500, ), ), const SizedBox(height: AppSpacing.sm), Container( width: double.infinity, padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 14), decoration: BoxDecoration( color: colorScheme.surface, borderRadius: BorderRadius.circular(14), border: Border.all( color: colorScheme.outlineVariant.withValues(alpha: 0.5), width: 1, ), ), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Row( children: [ Expanded( child: Text( _walletAddress ?? '', style: AppTextStyles.bodyMedium(context).copyWith( fontFamily: 'monospace', ), ), ), GestureDetector( onTap: () { Clipboard.setData( ClipboardData(text: _walletAddress ?? '')); ToastUtils.showSuccess('地址已複製'); }, child: Padding( padding: const EdgeInsets.all(4), child: Icon( LucideIcons.copy, size: 16, color: colorScheme.onSurfaceVariant, ), ), ), ], ), const SizedBox(height: 8), Text( '網絡: $_walletNetwork', style: AppTextStyles.bodySmall(context).copyWith( color: colorScheme.onSurfaceVariant, ), ), ], ), ), ], ); } // ============================================ // 共享组件 // ============================================ Widget _buildSubmitButton( ColorScheme colorScheme, String text, VoidCallback onPressed) { return SizedBox( width: double.infinity, height: 48, child: ElevatedButton( onPressed: _isSubmitting ? null : onPressed, style: ElevatedButton.styleFrom( backgroundColor: colorScheme.onSurface, foregroundColor: colorScheme.surface, disabledBackgroundColor: colorScheme.surfaceContainerHighest, disabledForegroundColor: colorScheme.onSurfaceVariant, elevation: 0, shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(14), ), ), child: _isSubmitting ? SizedBox( width: 20, height: 20, child: CircularProgressIndicator( strokeWidth: 2, valueColor: AlwaysStoppedAnimation( colorScheme.onSurfaceVariant, ), ), ) : Text( text, style: TextStyle( fontSize: 15, fontWeight: FontWeight.w600, ), ), ), ); } Widget _buildBottomTip(ColorScheme colorScheme) { return Center( child: Row( mainAxisSize: MainAxisSize.min, children: [ Icon(LucideIcons.shieldCheck, size: 13, color: colorScheme.onSurfaceVariant), const SizedBox(width: 4), Text( '資金安全由平台全程保障', style: AppTextStyles.bodySmall(context).copyWith( color: colorScheme.onSurfaceVariant, ), ), ], ), ); } }