diff --git a/frontend/mobile-app/lib/features/auth/presentation/pages/guide_page.dart b/frontend/mobile-app/lib/features/auth/presentation/pages/guide_page.dart index 42cde51f..d5f81826 100644 --- a/frontend/mobile-app/lib/features/auth/presentation/pages/guide_page.dart +++ b/frontend/mobile-app/lib/features/auth/presentation/pages/guide_page.dart @@ -283,7 +283,7 @@ class _WelcomePageContent extends ConsumerStatefulWidget { } class _WelcomePageContentState extends ConsumerState<_WelcomePageContent> { - bool _hasReferrer = true; + // 移除 _hasReferrer,推荐码现在是必填的 final TextEditingController _referralCodeController = TextEditingController(); @override @@ -326,12 +326,9 @@ class _WelcomePageContentState extends ConsumerState<_WelcomePageContent> { return trimmed.length >= 3; } - /// 判断按钮是否可点击 + /// 判断按钮是否可点击(推荐码必填) bool get _canProceed { - // 如果选择"没有推荐人",按钮可点击 - if (!_hasReferrer) return true; - - // 如果选择"有推荐人",需要填写有效的推荐码 + // 必须填写有效的推荐码才能继续 return _isValidReferralCode(_referralCodeController.text); } @@ -341,44 +338,19 @@ class _WelcomePageContentState extends ConsumerState<_WelcomePageContent> { context.push(RoutePaths.importMnemonic); } - /// 手机号注册 - Future _goToPhoneRegister() async { - debugPrint('[GuidePage] _goToPhoneRegister - 跳转到手机号注册页面'); - - // 如果有推荐人且推荐码有效,先保存到本地存储 - String? inviterCode; - if (_hasReferrer && _referralCodeController.text.trim().isNotEmpty) { - inviterCode = _referralCodeController.text.trim(); - final secureStorage = ref.read(secureStorageProvider); - await secureStorage.write( - key: StorageKeys.inviterReferralCode, - value: inviterCode, - ); - debugPrint('[GuidePage] 保存邀请人推荐码: $inviterCode'); - } - - if (!mounted) return; - context.push( - RoutePaths.phoneRegister, - extra: PhoneRegisterParams(inviterReferralCode: inviterCode), - ); - } /// 保存推荐码并继续下一步 (跳转到手机号注册页面) Future _saveReferralCodeAndProceed() async { if (!_canProceed) return; - // 如果有推荐人且推荐码有效,保存到本地存储 - String? inviterCode; - if (_hasReferrer && _referralCodeController.text.trim().isNotEmpty) { - inviterCode = _referralCodeController.text.trim(); - final secureStorage = ref.read(secureStorageProvider); - await secureStorage.write( - key: StorageKeys.inviterReferralCode, - value: inviterCode, - ); - debugPrint('[GuidePage] 保存邀请人推荐码: $inviterCode'); - } + // 推荐码必填,保存到本地存储 + final inviterCode = _referralCodeController.text.trim(); + final secureStorage = ref.read(secureStorageProvider); + await secureStorage.write( + key: StorageKeys.inviterReferralCode, + value: inviterCode, + ); + debugPrint('[GuidePage] 保存邀请人推荐码: $inviterCode'); if (!mounted) return; @@ -401,7 +373,6 @@ class _WelcomePageContentState extends ConsumerState<_WelcomePageContent> { final referralCode = _extractReferralCode(result); setState(() { _referralCodeController.text = referralCode; - _hasReferrer = true; }); } } @@ -545,7 +516,7 @@ class _WelcomePageContentState extends ConsumerState<_WelcomePageContent> { SizedBox(height: 12.h), // 副标题 Text( - '创建账号前的最后一步 · 请选择是否有推荐人', + '创建账号前的最后一步 · 请输入推荐码', style: TextStyle( fontSize: 14.sp, height: 1.43, @@ -606,122 +577,57 @@ class _WelcomePageContentState extends ConsumerState<_WelcomePageContent> { ); } - /// 构建推荐人选项 (透明背景,白色文字) + /// 构建推荐码输入区域 (透明背景,白色文字) Widget _buildReferrerOptions() { return Column( + crossAxisAlignment: CrossAxisAlignment.start, children: [ - // 有推荐人选项 - GestureDetector( - onTap: () { - setState(() { - _hasReferrer = true; - }); - }, + // 推荐码输入框 - 支持手动输入和扫码 + Container( + padding: EdgeInsets.symmetric(vertical: 12.h, horizontal: 16.w), + decoration: BoxDecoration( + color: Colors.white.withValues(alpha: 0.15), + borderRadius: BorderRadius.circular(12.r), + border: Border.all( + color: Colors.white.withValues(alpha: 0.3), + width: 1, + ), + ), child: Row( children: [ - _buildRadio(_hasReferrer), - SizedBox(width: 12.w), - Text( - '我有推荐人', - style: TextStyle( - fontSize: 16.sp, - height: 1.5, - color: Colors.white, - shadows: [ - Shadow( - color: Colors.black.withValues(alpha: 0.5), - blurRadius: 4, + Expanded( + child: TextField( + controller: _referralCodeController, + decoration: InputDecoration( + hintText: '请输入推荐码或点击右侧扫码', + hintStyle: TextStyle( + fontSize: 15.sp, + color: Colors.white.withValues(alpha: 0.5), ), - ], + border: InputBorder.none, + isDense: true, + contentPadding: EdgeInsets.zero, + ), + style: TextStyle( + fontSize: 16.sp, + color: Colors.white, + ), ), ), - ], - ), - ), - SizedBox(height: 14.h), - // 推荐码输入框 - 使用 AnimatedSize 平滑过渡 - AnimatedSize( - duration: const Duration(milliseconds: 200), - curve: Curves.easeInOut, - child: _hasReferrer - ? Container( - padding: EdgeInsets.symmetric(vertical: 8.h, horizontal: 4.w), + // 扫码按钮 + GestureDetector( + onTap: _openQrScanner, + child: Container( + padding: EdgeInsets.all(8.w), decoration: BoxDecoration( - border: Border( - bottom: BorderSide( - width: 1, - color: Colors.white.withValues(alpha: 0.5), - ), - ), + color: Colors.white.withValues(alpha: 0.2), + borderRadius: BorderRadius.circular(8.r), ), - child: Row( - children: [ - Expanded( - child: GestureDetector( - onTap: _openQrScanner, - child: AbsorbPointer( - child: TextField( - controller: _referralCodeController, - readOnly: true, - decoration: InputDecoration( - hintText: '点击扫描推荐码', - hintStyle: TextStyle( - fontSize: 16.sp, - color: Colors.black.withValues(alpha: 0.4), - ), - border: InputBorder.none, - isDense: true, - contentPadding: EdgeInsets.zero, - ), - style: TextStyle( - fontSize: 16.sp, - color: Colors.black, - ), - ), - ), - ), - ), - // 扫码按钮 - GestureDetector( - onTap: _openQrScanner, - child: Padding( - padding: EdgeInsets.only(left: 8.w), - child: Icon( - Icons.camera_alt_outlined, - size: 20.sp, - color: Colors.white.withValues(alpha: 0.8), - ), - ), - ), - ], + child: Icon( + Icons.qr_code_scanner, + size: 20.sp, + color: Colors.white, ), - ) - : const SizedBox.shrink(), - ), - SizedBox(height: 24.h), - // 没有推荐人选项 - GestureDetector( - onTap: () { - setState(() { - _hasReferrer = false; - }); - }, - child: Row( - children: [ - _buildRadio(!_hasReferrer), - SizedBox(width: 12.w), - Text( - '我没有推荐人', - style: TextStyle( - fontSize: 16.sp, - height: 1.5, - color: Colors.white, - shadows: [ - Shadow( - color: Colors.black.withValues(alpha: 0.5), - blurRadius: 4, - ), - ], ), ), ], @@ -740,7 +646,7 @@ class _WelcomePageContentState extends ConsumerState<_WelcomePageContent> { Padding( padding: EdgeInsets.symmetric(horizontal: 16.w), child: Text( - '或', + '已有账号', style: TextStyle( fontSize: 14.sp, color: Colors.white.withValues(alpha: 0.7), @@ -756,9 +662,12 @@ class _WelcomePageContentState extends ConsumerState<_WelcomePageContent> { ], ), SizedBox(height: 24.h), - // 手机号注册入口 + // 恢复账号入口(手机号+密码登录) GestureDetector( - onTap: _goToPhoneRegister, + onTap: () { + debugPrint('[GuidePage] 跳转到恢复账号页面'); + context.push(RoutePaths.phoneLogin); + }, child: Container( width: double.infinity, padding: EdgeInsets.symmetric(vertical: 14.h), @@ -774,13 +683,13 @@ class _WelcomePageContentState extends ConsumerState<_WelcomePageContent> { mainAxisAlignment: MainAxisAlignment.center, children: [ Icon( - Icons.phone_android, + Icons.login, size: 20.sp, color: Colors.white, ), SizedBox(width: 8.w), Text( - '使用手机号注册', + '恢复账号(手机号+密码登录)', style: TextStyle( fontSize: 15.sp, fontWeight: FontWeight.w500, @@ -791,62 +700,49 @@ class _WelcomePageContentState extends ConsumerState<_WelcomePageContent> { ), ), ), - SizedBox(height: 12.h), - // 导入助记词入口 - GestureDetector( - onTap: _importMnemonic, - child: Container( - width: double.infinity, - padding: EdgeInsets.symmetric(vertical: 14.h), - decoration: BoxDecoration( - color: Colors.white.withValues(alpha: 0.15), - borderRadius: BorderRadius.circular(12.r), - border: Border.all( - color: Colors.white.withValues(alpha: 0.3), - width: 1, + // 导入助记词入口 - 保留代码但隐藏 + if (false) // 设置为 false 隐藏,需要时改为 true + Padding( + padding: EdgeInsets.only(top: 12.h), + child: GestureDetector( + onTap: _importMnemonic, + child: Container( + width: double.infinity, + padding: EdgeInsets.symmetric(vertical: 14.h), + decoration: BoxDecoration( + color: Colors.white.withValues(alpha: 0.15), + borderRadius: BorderRadius.circular(12.r), + border: Border.all( + color: Colors.white.withValues(alpha: 0.3), + width: 1, + ), + ), + child: Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Icon( + Icons.restore, + size: 20.sp, + color: Colors.white, + ), + SizedBox(width: 8.w), + Text( + '已有账号?导入助记词恢复', + style: TextStyle( + fontSize: 15.sp, + fontWeight: FontWeight.w500, + color: Colors.white, + ), + ), + ], + ), ), ), - child: Row( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Icon( - Icons.restore, - size: 20.sp, - color: Colors.white, - ), - SizedBox(width: 8.w), - Text( - '已有账号?导入助记词恢复', - style: TextStyle( - fontSize: 15.sp, - fontWeight: FontWeight.w500, - color: Colors.white, - ), - ), - ], - ), ), - ), ], ); } - /// 构建单选按钮 (白色系,适配深色背景) - Widget _buildRadio(bool isSelected) { - return Container( - width: 20.w, - height: 20.w, - decoration: BoxDecoration( - shape: BoxShape.circle, - border: Border.all( - width: isSelected ? 6.w : 2.w, - color: isSelected - ? Colors.white - : Colors.white.withValues(alpha: 0.5), - ), - ), - ); - } } /// 二维码扫描页面 diff --git a/frontend/mobile-app/lib/routes/route_paths.dart b/frontend/mobile-app/lib/routes/route_paths.dart index 1820a656..4a7554bc 100644 --- a/frontend/mobile-app/lib/routes/route_paths.dart +++ b/frontend/mobile-app/lib/routes/route_paths.dart @@ -12,6 +12,7 @@ class RoutePaths { static const importWallet = '/auth/import'; static const importMnemonic = '/auth/import-mnemonic'; static const phoneRegister = '/auth/phone-register'; + static const phoneLogin = '/auth/phone-login'; static const smsVerify = '/auth/sms-verify'; static const setPassword = '/auth/set-password';