374 lines
11 KiB
Dart
374 lines
11 KiB
Dart
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';
|
||
import '../../../../core/services/account_service.dart';
|
||
|
||
/// 创建账号页面 - 用户首次进入应用时的引导页面
|
||
/// 提供创建钱包和导入助记词两种选项
|
||
class OnboardingPage extends ConsumerStatefulWidget {
|
||
const OnboardingPage({super.key});
|
||
|
||
@override
|
||
ConsumerState<OnboardingPage> createState() => _OnboardingPageState();
|
||
}
|
||
|
||
class _OnboardingPageState extends ConsumerState<OnboardingPage> {
|
||
// 用户协议勾选状态
|
||
bool _isAgreed = false;
|
||
// 创建钱包加载状态
|
||
bool _isCreating = false;
|
||
// 错误信息
|
||
String? _errorMessage;
|
||
|
||
/// 创建钱包并跳转到备份页面
|
||
///
|
||
/// 调用后端 API 使用 MPC 2-of-3 协议生成钱包地址
|
||
Future<void> _createWallet() async {
|
||
if (!_isAgreed) {
|
||
_showAgreementTip();
|
||
return;
|
||
}
|
||
|
||
setState(() {
|
||
_isCreating = true;
|
||
_errorMessage = null;
|
||
});
|
||
|
||
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;
|
||
|
||
setState(() {
|
||
_errorMessage = e.toString();
|
||
});
|
||
|
||
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('导入助记词');
|
||
}
|
||
|
||
@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.withOpacity(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() {
|
||
return GestureDetector(
|
||
onTap: _isCreating ? null : _createWallet,
|
||
child: Opacity(
|
||
opacity: _isAgreed ? 1.0 : 0.5,
|
||
child: Container(
|
||
width: double.infinity,
|
||
height: 48,
|
||
decoration: BoxDecoration(
|
||
color: const Color(0xFFD4AF37), // 金色
|
||
borderRadius: BorderRadius.circular(8),
|
||
),
|
||
child: Center(
|
||
child: _isCreating
|
||
? const SizedBox(
|
||
width: 24,
|
||
height: 24,
|
||
child: CircularProgressIndicator(
|
||
strokeWidth: 2,
|
||
valueColor: AlwaysStoppedAnimation<Color>(Colors.white),
|
||
),
|
||
)
|
||
: const Text(
|
||
'生成钱包(创建账户)',
|
||
style: 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),
|
||
),
|
||
),
|
||
);
|
||
}
|
||
}
|