import 'package:flutter/material.dart'; import 'package:flutter/gestures.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:go_router/go_router.dart'; import '../../../../routes/route_paths.dart'; import '../../../../routes/app_router.dart'; import '../../../../core/di/injection_container.dart'; /// 创建账号页面 - 用户首次进入应用时的引导页面 /// 提供创建钱包和导入助记词两种选项 class OnboardingPage extends ConsumerStatefulWidget { const OnboardingPage({super.key}); @override ConsumerState createState() => _OnboardingPageState(); } class _OnboardingPageState extends ConsumerState { // 用户协议勾选状态 bool _isAgreed = false; // 创建钱包加载状态 bool _isCreating = false; // 钱包是否已创建 bool _isWalletCreated = false; // 是否正在加载状态 bool _isLoading = true; // 已创建的钱包数据 String? _mnemonic; String? _kavaAddress; String? _dstAddress; String? _bscAddress; String? _serialNumber; String? _referralCode; @override void initState() { super.initState(); _checkWalletStatus(); } /// 检查钱包是否已创建 Future _checkWalletStatus() async { try { final accountService = ref.read(accountServiceProvider); // 检查是否已创建钱包 final hasAccount = await accountService.hasAccount(); if (hasAccount) { // 读取已保存的钱包数据 final mnemonic = await accountService.getMnemonic(); final addresses = await accountService.getWalletAddresses(); final sequence = await accountService.getAccountSequence(); final referralCode = await accountService.getReferralCode(); if (mounted) { setState(() { _isWalletCreated = true; _mnemonic = mnemonic; _kavaAddress = addresses?.kava; _dstAddress = addresses?.dst; _bscAddress = addresses?.bsc; _serialNumber = sequence?.toString(); _referralCode = referralCode; _isLoading = false; // 如果钱包已创建,自动勾选协议 _isAgreed = true; }); } } else { if (mounted) { setState(() { _isWalletCreated = false; _isLoading = false; }); } } } catch (e) { debugPrint('检查钱包状态失败: $e'); if (mounted) { setState(() { _isWalletCreated = false; _isLoading = false; }); } } } /// 创建钱包并跳转到备份页面 /// /// 调用后端 API 使用 MPC 2-of-3 协议生成钱包地址 Future _createWallet() async { if (!_isAgreed) { _showAgreementTip(); return; } setState(() { _isCreating = true; }); try { // 获取 AccountService final accountService = ref.read(accountServiceProvider); // 调用后端 API 创建账号 debugPrint('开始创建账号...'); final response = await accountService.createAccount(); debugPrint('账号创建成功: 序列号=${response.accountSequence}'); if (!mounted) return; // MPC 模式下,检查是否有客户端分片数据 // 如果有分片数据,需要提示用户妥善保管 final hasMpcData = response.clientShareData != null && response.clientShareData!.isNotEmpty; // 跳转到钱包创建成功页面 context.push( RoutePaths.backupMnemonic, extra: BackupMnemonicParams( // MPC 模式下助记词为空,显示账号信息即可 mnemonicWords: response.mnemonic?.isNotEmpty == true ? response.mnemonic!.split(' ') : [], // MPC 模式下为空 kavaAddress: response.walletAddresses.kava, dstAddress: response.walletAddresses.dst, bscAddress: response.walletAddresses.bsc, serialNumber: response.accountSequence.toString(), referralCode: response.referralCode, publicKey: response.publicKey, isMpcMode: hasMpcData, // 标记是否为 MPC 模式 ), ); } catch (e) { debugPrint('创建账号失败: $e'); if (!mounted) return; ScaffoldMessenger.of(context).showSnackBar( SnackBar( content: Text('创建账号失败: ${e.toString().replaceAll('Exception: ', '')}'), backgroundColor: Colors.red, duration: const Duration(seconds: 5), ), ); } finally { if (mounted) { setState(() => _isCreating = false); } } } /// 显示需要同意协议的提示 void _showAgreementTip() { ScaffoldMessenger.of(context).showSnackBar( const SnackBar( content: Text('请先阅读并同意用户协议和隐私政策'), backgroundColor: Color(0xFFD4AF37), ), ); } /// 显示用户协议 void _showUserAgreement() { // TODO: 跳转到用户协议页面 debugPrint('显示用户协议'); } /// 显示隐私政策 void _showPrivacyPolicy() { // TODO: 跳转到隐私政策页面 debugPrint('显示隐私政策'); } /// 导入助记词 void _importMnemonic() { // TODO: 跳转到导入助记词页面 debugPrint('导入助记词'); } /// 跳转到备份助记词页面(钱包已创建的情况) void _goToBackupMnemonic() { if (_mnemonic == null || _kavaAddress == null || _dstAddress == null || _bscAddress == null || _serialNumber == null) { ScaffoldMessenger.of(context).showSnackBar( const SnackBar( content: Text('钱包数据不完整,请重新创建'), backgroundColor: Colors.red, ), ); return; } context.push( RoutePaths.backupMnemonic, extra: BackupMnemonicParams( mnemonicWords: _mnemonic!.split(' '), kavaAddress: _kavaAddress!, dstAddress: _dstAddress!, bscAddress: _bscAddress!, serialNumber: _serialNumber!, referralCode: _referralCode, isMpcMode: false, ), ); } /// 处理按钮点击 void _handleButtonTap() { if (_isWalletCreated) { // 钱包已创建,跳转到备份页面 _goToBackupMnemonic(); } else { // 钱包未创建,创建新钱包 _createWallet(); } } @override Widget build(BuildContext context) { return Scaffold( body: Container( width: double.infinity, height: double.infinity, // 渐变背景 - 从浅米色到金黄色 decoration: const BoxDecoration( gradient: LinearGradient( begin: Alignment.topCenter, end: Alignment.bottomCenter, colors: [ Color(0xFFFFF5E6), // 浅米色 Color(0xFFFFE4B5), // 金黄色 ], ), ), child: SafeArea( child: Padding( padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 15), child: Column( children: [ // 顶部 Logo 和标题区域 _buildHeader(), const SizedBox(height: 48), // 创建账户说明区域 _buildDescription(), const Spacer(), // 底部操作区域 _buildActionSection(), const SizedBox(height: 9), ], ), ), ), ), ); } /// 构建顶部 Logo 和标题 Widget _buildHeader() { return Column( children: [ const SizedBox(height: 32), // Logo 容器 Container( width: 100, height: 80, decoration: BoxDecoration( color: Colors.white, borderRadius: BorderRadius.circular(8), boxShadow: [ BoxShadow( color: Colors.black.withValues(alpha: 0.05), blurRadius: 10, offset: const Offset(0, 2), ), ], ), child: const Center( child: Text( 'ap', style: TextStyle( fontSize: 32, fontWeight: FontWeight.w600, color: Color(0xFF2E7D32), // 绿色 ), ), ), ), const SizedBox(height: 24), // 应用标题 const Text( '榴莲女皇', style: TextStyle( fontSize: 32, fontFamily: 'Inter', fontWeight: FontWeight.w700, height: 1.25, color: Color(0xFF5D4037), // 深棕色 ), ), ], ); } /// 构建创建账户说明区域 Widget _buildDescription() { return Column( children: [ // 标题 const Text( '创建账户', style: TextStyle( fontSize: 22, fontFamily: 'Inter', fontWeight: FontWeight.w700, height: 1.25, letterSpacing: -0.33, color: Color(0xFF5D4037), ), ), const SizedBox(height: 16), // 说明文字 const Padding( padding: EdgeInsets.symmetric(horizontal: 20), child: Text( '我们将为你创建三个链的钱包地址:KAVA / DST / BSC,同时生成唯一序列号用于推荐与权益。', style: TextStyle( fontSize: 16, fontFamily: 'Inter', height: 1.5, color: Color(0xFF5D4037), ), textAlign: TextAlign.center, ), ), ], ); } /// 构建底部操作区域 Widget _buildActionSection() { return Column( children: [ // 生成钱包按钮 _buildCreateButton(), const SizedBox(height: 20), // 用户协议勾选 _buildAgreementCheckbox(), const SizedBox(height: 24), // 导入助记词链接 _buildImportLink(), ], ); } /// 构建创建钱包按钮 Widget _buildCreateButton() { // 加载中显示骨架 if (_isLoading) { return Container( width: double.infinity, height: 48, decoration: BoxDecoration( color: const Color(0xFFD4AF37).withValues(alpha: 0.5), borderRadius: BorderRadius.circular(8), ), child: const Center( child: SizedBox( width: 24, height: 24, child: CircularProgressIndicator( strokeWidth: 2, valueColor: AlwaysStoppedAnimation(Colors.white), ), ), ), ); } // 根据钱包状态决定按钮文字和行为 final buttonText = _isWalletCreated ? '钱包已创建(点击备份助记词)' : '生成钱包(创建账户)'; // 钱包已创建时,不需要勾选协议 final isEnabled = _isWalletCreated || _isAgreed; return GestureDetector( onTap: (_isCreating || !isEnabled) ? null : _handleButtonTap, child: Opacity( opacity: isEnabled ? 1.0 : 0.5, child: Container( width: double.infinity, height: 48, decoration: BoxDecoration( color: _isWalletCreated ? const Color(0xFF52C41A) // 绿色表示已创建 : const Color(0xFFD4AF37), // 金色表示待创建 borderRadius: BorderRadius.circular(8), ), child: Center( child: _isCreating ? const SizedBox( width: 24, height: 24, child: CircularProgressIndicator( strokeWidth: 2, valueColor: AlwaysStoppedAnimation(Colors.white), ), ) : Row( mainAxisAlignment: MainAxisAlignment.center, children: [ if (_isWalletCreated) ...[ const Icon( Icons.check_circle, color: Colors.white, size: 20, ), const SizedBox(width: 8), ], Text( buttonText, style: const TextStyle( fontSize: 16, fontFamily: 'Inter', fontWeight: FontWeight.w700, height: 1.5, letterSpacing: 0.24, color: Colors.white, ), ), ], ), ), ), ), ); } /// 构建用户协议勾选框 Widget _buildAgreementCheckbox() { return Row( mainAxisAlignment: MainAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.start, children: [ // 勾选框 SizedBox( width: 20, height: 20, child: Checkbox( value: _isAgreed, onChanged: (value) { setState(() { _isAgreed = value ?? false; }); }, activeColor: const Color(0xFFD4AF37), side: const BorderSide(color: Color(0xFF5D4037)), shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(4), ), ), ), const SizedBox(width: 8), // 协议文字 Flexible( child: RichText( text: TextSpan( style: const TextStyle( fontSize: 14, fontFamily: 'Inter', fontWeight: FontWeight.w500, height: 1.43, color: Color(0xFF5D4037), ), children: [ const TextSpan(text: '我已阅读并同意 '), TextSpan( text: '《用户协议》', style: const TextStyle(color: Color(0xFFD4AF37)), recognizer: TapGestureRecognizer()..onTap = _showUserAgreement, ), TextSpan( text: '《隐私政策》', style: const TextStyle(color: Color(0xFFD4AF37)), recognizer: TapGestureRecognizer()..onTap = _showPrivacyPolicy, ), ], ), ), ), ], ); } /// 构建导入助记词链接 Widget _buildImportLink() { return GestureDetector( onTap: _importMnemonic, child: const Text( '已有账号? 导入助记词', style: TextStyle( fontSize: 14, fontFamily: 'Inter', fontWeight: FontWeight.w500, height: 1.43, color: Color(0xFFD4AF37), ), ), ); } }