import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:go_router/go_router.dart'; import 'package:qr_flutter/qr_flutter.dart'; import '../../../../core/di/injection_container.dart'; /// 分享页面 - 显示邀请链接和二维码 /// 进入页面时自动调用 API 生成短链,显示二维码 class SharePage extends ConsumerStatefulWidget { /// 初始分享链接 (fallback) final String shareLink; /// 邀请码 final String? referralCode; const SharePage({ super.key, required this.shareLink, this.referralCode, }); @override ConsumerState createState() => _SharePageState(); } class _SharePageState extends ConsumerState { /// 实际显示的分享链接 (API 返回的短链) late String _displayLink; /// 是否正在加载 bool _isLoading = true; /// 错误信息 String? _errorMessage; /// 推荐码(从 API 获取后保存) String? _referralCode; @override void initState() { super.initState(); _displayLink = widget.shareLink; // 默认使用传入的链接 _loadShareLink(); } /// APK 下载基础链接 static const String _apkDownloadUrl = 'https://s3.szaiai.com/rwadurian/app-release.apk'; /// 加载分享链接 (使用 APK 下载链接 + 推荐码) Future _loadShareLink() async { try { setState(() { _isLoading = true; _errorMessage = null; }); final referralService = ref.read(referralServiceProvider); // 调用 API 获取推荐码 final linkResponse = await referralService.generateReferralLink(); if (mounted) { setState(() { // 使用 APK 下载链接 + 推荐码参数 _referralCode = linkResponse.referralCode; _displayLink = '$_apkDownloadUrl?ref=$_referralCode'; _isLoading = false; }); } } catch (e) { debugPrint('加载分享链接失败: $e'); if (mounted) { setState(() { _isLoading = false; // 失败时使用传入的推荐码构造链接 if (widget.referralCode != null && widget.referralCode!.isNotEmpty) { _referralCode = widget.referralCode; _displayLink = '$_apkDownloadUrl?ref=${widget.referralCode}'; } else { _displayLink = _apkDownloadUrl; } _errorMessage = '加载失败,使用默认链接'; }); } } } /// 复制链接到剪贴板 void _copyLink() { Clipboard.setData(ClipboardData(text: _displayLink)); ScaffoldMessenger.of(context).showSnackBar( const SnackBar( content: Text('链接已复制'), backgroundColor: Color(0xFFD4A84B), duration: Duration(seconds: 2), ), ); } /// 返回上一页 void _goBack() { context.pop(); } /// 确认按钮点击 void _onConfirm() { context.pop(); } @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(0xFFFFF7E6), // 浅黄色顶部 Color(0xFFFFFDF8), // 接近白色底部 ], ), ), child: SafeArea( child: Column( children: [ // 顶部导航栏 _buildAppBar(), // 内容区域 Expanded( child: Center( child: SingleChildScrollView( child: Padding( padding: const EdgeInsets.symmetric(vertical: 24), child: Column( mainAxisSize: MainAxisSize.min, children: [ // QR 码区域 _buildQrCodeSection(), const SizedBox(height: 32), // 链接输入框 _buildLinkSection(), ], ), ), ), ), ), // 底部确认按钮 _buildFooter(), ], ), ), ), ); } /// 构建顶部导航栏 Widget _buildAppBar() { return Container( padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 14), child: Row( children: [ // 返回按钮 GestureDetector( onTap: _goBack, child: Container( width: 28, height: 28, alignment: Alignment.center, child: const Icon( Icons.arrow_back_ios, color: Color(0xFF8C6A3E), size: 20, ), ), ), const SizedBox(width: 8), // 标题 const Expanded( child: Text( '分享页面', style: TextStyle( fontSize: 18, fontFamily: 'Segoe UI', fontWeight: FontWeight.w600, height: 1.56, color: Color(0xFF8C6A3E), ), ), ), ], ), ); } /// 构建 QR 码区域 Widget _buildQrCodeSection() { return Column( children: [ Container( width: 256, height: 256, decoration: BoxDecoration( color: const Color(0xFFFAF3E3), borderRadius: BorderRadius.circular(24), boxShadow: const [ BoxShadow( color: Color(0x1A8C6A3E), // rgba(140, 106, 62, 0.1) blurRadius: 30, offset: Offset(0, 8), ), ], ), child: Center( child: _isLoading ? const CircularProgressIndicator( color: Color(0xFFD4A84B), strokeWidth: 2, ) : QrImageView( data: _displayLink, version: QrVersions.auto, size: 200, backgroundColor: Colors.transparent, eyeStyle: const QrEyeStyle( eyeShape: QrEyeShape.square, color: Color(0xFF8C6A3E), ), dataModuleStyle: const QrDataModuleStyle( dataModuleShape: QrDataModuleShape.square, color: Color(0xFF8C6A3E), ), ), ), ), // 推荐码显示 if (_referralCode != null && _referralCode!.isNotEmpty) ...[ const SizedBox(height: 16), Container( padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 10), decoration: BoxDecoration( color: const Color(0xFFF8F1E2), borderRadius: BorderRadius.circular(20), ), child: Row( mainAxisSize: MainAxisSize.min, children: [ const Text( '我的推荐码:', style: TextStyle( fontSize: 14, fontFamily: 'Segoe UI', color: Color(0xFF8C6A3E), ), ), Text( _referralCode!, style: const TextStyle( fontSize: 16, fontFamily: 'Segoe UI', fontWeight: FontWeight.w700, color: Color(0xFFD4A84B), letterSpacing: 1, ), ), const SizedBox(width: 8), GestureDetector( onTap: _copyReferralCode, child: const Icon( Icons.copy_outlined, color: Color(0xFF8C6A3E), size: 18, ), ), ], ), ), ], ], ); } /// 复制推荐码 void _copyReferralCode() { if (_referralCode != null && _referralCode!.isNotEmpty) { Clipboard.setData(ClipboardData(text: _referralCode!)); ScaffoldMessenger.of(context).showSnackBar( const SnackBar( content: Text('推荐码已复制'), backgroundColor: Color(0xFFD4A84B), duration: Duration(seconds: 2), ), ); } } /// 构建链接显示区域 Widget _buildLinkSection() { return Padding( padding: const EdgeInsets.symmetric(horizontal: 32), child: Column( children: [ Container( width: double.infinity, constraints: const BoxConstraints(maxWidth: 296), padding: const EdgeInsets.fromLTRB(16, 8, 12, 8), decoration: BoxDecoration( color: const Color(0xFFF8F1E2), borderRadius: BorderRadius.circular(9999), // 胶囊形状 ), child: Row( children: [ // 链接文本 Expanded( child: _isLoading ? const Text( '加载中...', style: TextStyle( fontSize: 13.7, fontFamily: 'Segoe UI', height: 1.5, color: Color(0xFFB0A090), ), ) : Text( _displayLink, style: const TextStyle( fontSize: 13.7, fontFamily: 'Segoe UI', height: 1.5, color: Color(0xFF8C6A3E), ), overflow: TextOverflow.ellipsis, ), ), const SizedBox(width: 8), // 复制按钮 GestureDetector( onTap: _isLoading ? null : _copyLink, child: Container( width: 32, height: 32, decoration: BoxDecoration( color: Colors.white, borderRadius: BorderRadius.circular(9999), boxShadow: const [ BoxShadow( color: Color(0x0D000000), // rgba(0, 0, 0, 0.05) blurRadius: 2, offset: Offset(0, 1), ), ], ), child: Center( child: Icon( Icons.copy_outlined, color: _isLoading ? const Color(0xFFB0A090) : const Color(0xFF8C6A3E), size: 18, ), ), ), ), ], ), ), // 错误提示 if (_errorMessage != null) ...[ const SizedBox(height: 8), Text( _errorMessage!, style: const TextStyle( fontSize: 12, color: Color(0xFFB0A090), ), ), ], ], ), ); } /// 构建底部确认按钮 Widget _buildFooter() { return Container( padding: const EdgeInsets.all(24), child: GestureDetector( onTap: _onConfirm, child: Container( width: double.infinity, height: 60, decoration: BoxDecoration( color: const Color(0xFFD1A45B), borderRadius: BorderRadius.circular(12), boxShadow: const [ BoxShadow( color: Color(0x4DD1A45B), // rgba(209, 164, 91, 0.3) blurRadius: 15, offset: Offset(0, 10), ), BoxShadow( color: Color(0x4DD1A45B), // rgba(209, 164, 91, 0.3) blurRadius: 6, offset: Offset(0, 4), ), ], ), child: const Center( child: Text( '确认', style: TextStyle( fontSize: 18, fontFamily: 'Segoe UI', fontWeight: FontWeight.w700, height: 1.56, color: Colors.white, ), ), ), ), ), ); } }