import 'package:flutter/material.dart'; import 'package:get/get.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:font_awesome_flutter/font_awesome_flutter.dart'; import '../controllers/login_controller.dart'; import '../controllers/facebookLogin.dart'; import '../controllers/googleLogin.dart'; import '../controllers/weixinLogin.dart'; import '../../../core/themes/app_theme.dart'; class LoginView extends GetView { const LoginView({Key? key}) : super(key: key); @override Widget build(BuildContext context) { final isDarkMode = Theme.of(context).brightness == Brightness.dark; return Scaffold( backgroundColor: isDarkMode ? Colors.black : Colors.grey[50], body: SafeArea( child: Obx(() => controller.viewState == LoginViewState.welcome ? _buildWelcomeView(isDarkMode) : _buildVerificationView(context, isDarkMode)), ), ); } // 欢迎页面 Widget _buildWelcomeView(bool isDarkMode) { return Padding( padding: EdgeInsets.all(24.w), child: SingleChildScrollView( physics: const BouncingScrollPhysics(), child: Column( children: [ // 应用标志和标题 SizedBox(height: 32.h), _buildAppLogo(isDarkMode), // 欢迎文本 SizedBox(height: 32.h), _buildWelcomeText(isDarkMode), // 输入框和继续按钮 SizedBox(height: 24.h), _buildInputField(isDarkMode), SizedBox(height: 16.h), _buildVerificationInputField(isDarkMode), SizedBox(height: 16.h), _buildContinueButton(isDarkMode), // 社交媒体登录 SizedBox(height: 32.h), _buildSocialLoginSection(isDarkMode), // 用户协议 SizedBox(height: 40.h), _buildTermsAndPrivacy(isDarkMode), SizedBox(height: 24.h), ], ), ), ); } // 验证码页面 Widget _buildVerificationView(BuildContext context, bool isDarkMode) { return Padding( padding: EdgeInsets.all(24.w), child: SingleChildScrollView( physics: const BouncingScrollPhysics(), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ // 返回按钮 _buildBackButton(isDarkMode), // 验证码标题 SizedBox(height: 24.h), _buildVerificationTitle(isDarkMode), // 验证码输入框 SizedBox(height: 32.h), _buildVerificationInputs(context, isDarkMode), // 重新发送验证码 SizedBox(height: 16.h), _buildResendButton(isDarkMode), // 登录按钮 SizedBox(height: 32.h), _buildLoginButton(isDarkMode), // 使用密码登录 SizedBox(height: 16.h), _buildUsePasswordButton(isDarkMode), SizedBox(height: 24.h), ], ), ), ); } // 应用标志和标题 Widget _buildAppLogo(bool isDarkMode) { return Column( children: [ Container( width: 80.w, height: 80.w, decoration: BoxDecoration( gradient: const LinearGradient( begin: Alignment.topLeft, end: Alignment.bottomRight, colors: [Color(0xFF0066CC), Color(0xFF5E5CE6)], ), borderRadius: BorderRadius.circular(24.r), boxShadow: [ BoxShadow( color: const Color(0xFF0066CC).withOpacity(0.3), blurRadius: 10, offset: const Offset(0, 4), ), ], ), child: Icon( Icons.headset, size: 40.sp, color: Colors.white, ), ), SizedBox(height: 16.h), Text( 'DeepVoice', style: TextStyle( fontSize: 24.sp, fontWeight: FontWeight.bold, color: isDarkMode ? Colors.white : Colors.black, ), ), SizedBox(height: 8.h), Text( '连接世界,超越声音', style: TextStyle( fontSize: 14.sp, color: isDarkMode ? Colors.grey[400] : Colors.black54, ), ), ], ); } // 欢迎文本 Widget _buildWelcomeText(bool isDarkMode) { return Column( children: [ Text( '欢迎使用', style: TextStyle( fontSize: 20.sp, fontWeight: FontWeight.w600, color: isDarkMode ? Colors.white : Colors.black, ), ), SizedBox(height: 4.h), Text( '请使用手机号或邮箱登录/注册', style: TextStyle( fontSize: 14.sp, color: isDarkMode ? Colors.grey[400] : Colors.black54, ), ), ], ); } // 输入框 Widget _buildInputField(bool isDarkMode) { return Container( decoration: BoxDecoration( color: isDarkMode ? Colors.grey[900]!.withOpacity(0.4) : Colors.grey.withOpacity(0.1), borderRadius: BorderRadius.circular(16.r), ), child: Padding( padding: EdgeInsets.symmetric(horizontal: 16.w, vertical: 4.h), child: Row( children: [ Icon( Icons.person_outline, color: isDarkMode ? Colors.grey[400] : Colors.black54, size: 20.sp, ), SizedBox(width: 12.w), Expanded( child: TextField( controller: controller.contactController, decoration: InputDecoration( hintText: '手机号码或邮箱', hintStyle: TextStyle( fontSize: 14.sp, color: isDarkMode ? Colors.grey[600] : Colors.black38, ), border: InputBorder.none, fillColor: Colors.transparent, filled: true, ), style: TextStyle( fontSize: 14.sp, color: isDarkMode ? Colors.white : Colors.black, ), ), ), ], ), ), ); } // 验证码输入框 Widget _buildVerificationInputField(bool isDarkMode) { return Container( decoration: BoxDecoration( color: isDarkMode ? Colors.grey[900]!.withOpacity(0.4) : Colors.grey.withOpacity(0.1), borderRadius: BorderRadius.circular(16.r), ), child: Padding( padding: EdgeInsets.only(left: 16.w, right: 4.w, top: 4.h, bottom: 4.h), child: Row( children: [ Icon( Icons.lock_outline, color: isDarkMode ? Colors.grey[400] : Colors.black54, size: 20.sp, ), SizedBox(width: 12.w), Expanded( child: TextField( controller: controller.verificationCodeController, keyboardType: TextInputType.number, maxLength: 6, decoration: InputDecoration( hintText: '验证码', hintStyle: TextStyle( fontSize: 14.sp, color: isDarkMode ? Colors.grey[600] : Colors.black38, ), border: InputBorder.none, counterText: '', fillColor: Colors.transparent, filled: true, ), style: TextStyle( fontSize: 14.sp, color: isDarkMode ? Colors.white : Colors.black, ), ), ), Obx(() => TextButton( onPressed: controller.countdownSeconds > 0 ? null : controller.getVerificationCode, style: TextButton.styleFrom( padding: EdgeInsets.symmetric(horizontal: 16.w), foregroundColor: const Color(0xFF3B82F6), backgroundColor: Colors.transparent, disabledForegroundColor: isDarkMode ? Colors.grey[600] : Colors.grey[400], ), child: Text( controller.countdownSeconds > 0 ? '${controller.countdownSeconds}s后重新获取' : '获取验证码', style: TextStyle( fontSize: 14.sp, fontWeight: FontWeight.w500, ), ), )), ], ), ), ); } // 继续按钮 Widget _buildContinueButton(bool isDarkMode) { return SizedBox( width: double.infinity, child: Obx(() => ElevatedButton( onPressed: controller.isLoading ? null : () => controller.login(), style: ElevatedButton.styleFrom( backgroundColor: const Color(0xFF0066CC), foregroundColor: Colors.white, padding: EdgeInsets.symmetric(vertical: 14.h), shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(16.r), ), elevation: 0, disabledBackgroundColor: const Color(0xFF0066CC).withOpacity(0.7), disabledForegroundColor: Colors.white, ), child: controller.isLoading ? SizedBox( height: 20.h, width: 20.h, child: CircularProgressIndicator( strokeWidth: 2.w, valueColor: const AlwaysStoppedAnimation(Colors.white), ), ) : Text( '继续', style: TextStyle( fontSize: 16.sp, fontWeight: FontWeight.w600, ), ), )), ); } // 社交媒体登录部分 Widget _buildSocialLoginSection(bool isDarkMode) { return Column( children: [ Row( children: [ Expanded( child: Divider( color: isDarkMode ? Colors.grey[800] : Colors.grey[300])), Padding( padding: EdgeInsets.symmetric(horizontal: 16.w), child: Text( '或使用以下方式登录', style: TextStyle( fontSize: 12.sp, color: isDarkMode ? Colors.grey[500] : Colors.grey[600], ), ), ), Expanded( child: Divider( color: isDarkMode ? Colors.grey[800] : Colors.grey[300])), ], ), SizedBox(height: 24.h), Row( mainAxisAlignment: MainAxisAlignment.center, children: [ _buildSocialButton(FontAwesomeIcons.google, Colors.red, isDarkMode), SizedBox(width: 24.w), _buildSocialButton( FontAwesomeIcons.weixin, Colors.green, isDarkMode), SizedBox(width: 24.w), _buildSocialButton( FontAwesomeIcons.facebook, Colors.blue, isDarkMode), ], ), ], ); } // 社交媒体按钮 Widget _buildSocialButton(IconData icon, Color color, bool isDarkMode) { return Container( width: 48.w, height: 48.w, decoration: BoxDecoration( color: isDarkMode ? Colors.grey[800] : Colors.white, borderRadius: BorderRadius.circular(24.r), boxShadow: isDarkMode ? [] : [ BoxShadow( color: Colors.grey.withOpacity(0.2), blurRadius: 4, offset: const Offset(0, 2), ), ], ), child: IconButton( icon: FaIcon( icon, color: color, size: 20.sp, ), onPressed: () => SocialLogin(icon)), ); } Future SocialLogin(IconData icon) async { switch (icon) { case FontAwesomeIcons.facebook: { print("数据获取Facebook"); bool authResult = await Facebook().signInWithFacebook(); print("数据获取Facebook().token${authResult}"); if (authResult) { print("数据获取_Facebook.token${Facebook().token}"); controller.login(); } break; } case FontAwesomeIcons.google: { print("数据获取_Google()"); bool authResult = await Google().signInWithGoogle(); print("数据获取_Google().token${authResult}"); if (authResult) { controller.login(); } break; } case FontAwesomeIcons.weixin: { print("数据获取_FlWX()"); bool authResult = await FlWX().authBy( NormalAuth( scope: "snsapi_userinfo", state: "wechat_sdk_demo_test", ), ); if (authResult) { // 确保 FlWX() 返回的是同一个实例,并且 token 已经被设置 // 这里假设 FlWX().token 在 authBy 成功后被设置 print("数据获取_FlWX().token${FlWX().token}"); controller.login(); } break; } } } // 用户协议和隐私政策 Widget _buildTermsAndPrivacy(bool isDarkMode) { return Column( children: [ Text( '登录/注册即表示你同意', style: TextStyle( fontSize: 12.sp, color: isDarkMode ? Colors.grey[500] : Colors.grey[600], ), ), SizedBox(height: 4.h), Row( mainAxisAlignment: MainAxisAlignment.center, children: [ GestureDetector( onTap: () {}, child: Text( '《用户协议》', style: TextStyle( fontSize: 12.sp, color: const Color(0xFF3B82F6), ), ), ), Text( ' 和 ', style: TextStyle( fontSize: 12.sp, color: isDarkMode ? Colors.grey[500] : Colors.grey[600], ), ), GestureDetector( onTap: () {}, child: Text( '《隐私政策》', style: TextStyle( fontSize: 12.sp, color: const Color(0xFF3B82F6), ), ), ), ], ), ], ); } // 返回按钮 Widget _buildBackButton(bool isDarkMode) { return Container( width: 40.w, height: 40.w, decoration: BoxDecoration( color: isDarkMode ? Colors.grey[800] : Colors.grey.withOpacity(0.1), borderRadius: BorderRadius.circular(20.r), ), child: IconButton( icon: Icon( Icons.arrow_back, color: isDarkMode ? Colors.grey[400] : Colors.grey[600], size: 20.sp, ), onPressed: () => controller.showWelcomeView(), ), ); } // 验证码标题 Widget _buildVerificationTitle(bool isDarkMode) { return Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( '输入验证码', style: TextStyle( fontSize: 20.sp, fontWeight: FontWeight.w600, color: isDarkMode ? Colors.white : Colors.black, ), ), SizedBox(height: 8.h), Obx(() => Text( '验证码已发送至 ${controller.displayContact}', style: TextStyle( fontSize: 14.sp, color: isDarkMode ? Colors.grey[400] : Colors.grey[600], ), )), ], ); } // 验证码输入框 Widget _buildVerificationInputs(BuildContext context, bool isDarkMode) { return Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: List.generate( 4, (index) => _buildVerificationInput(index, context, isDarkMode)), ); } // 单个验证码输入框 Widget _buildVerificationInput( int index, BuildContext context, bool isDarkMode) { return Container( width: 60.w, height: 60.w, decoration: BoxDecoration( color: isDarkMode ? Colors.grey[900]!.withOpacity(0.3) : Colors.grey.withOpacity(0.1), borderRadius: BorderRadius.circular(12.r), border: Border.all( color: isDarkMode ? Colors.grey[700]! : Colors.grey[300]!, width: 1, ), ), child: Center( child: TextField( textAlign: TextAlign.center, keyboardType: TextInputType.number, maxLength: 1, onChanged: (value) { controller.updateVerificationCode(index, value); if (value.isNotEmpty && index < 3) { FocusScope.of(context).nextFocus(); } }, decoration: InputDecoration( counterText: '', border: InputBorder.none, fillColor: Colors.transparent, filled: true, ), style: TextStyle( fontSize: 24.sp, fontWeight: FontWeight.w600, color: isDarkMode ? Colors.white : Colors.black, ), ), ), ); } // 重新发送验证码按钮 Widget _buildResendButton(bool isDarkMode) { return Center( child: Obx(() => TextButton.icon( onPressed: controller.countdownSeconds > 0 ? null : controller.resendVerificationCode, icon: Icon( Icons.refresh, size: 14.sp, color: controller.countdownSeconds > 0 ? (isDarkMode ? Colors.grey[600] : Colors.grey[500]) : const Color(0xFF3B82F6), ), label: Text( controller.countdownSeconds > 0 ? '重新发送验证码 (${controller.countdownSeconds}s)' : '重新发送验证码', style: TextStyle( fontSize: 14.sp, color: controller.countdownSeconds > 0 ? (isDarkMode ? Colors.grey[600] : Colors.grey[500]) : const Color(0xFF3B82F6), ), ), )), ); } // 登录按钮 Widget _buildLoginButton(bool isDarkMode) { return SizedBox( width: double.infinity, child: Obx(() => ElevatedButton( onPressed: controller.isLoading ? null : controller.login, style: ElevatedButton.styleFrom( backgroundColor: const Color(0xFF3B82F6), foregroundColor: Colors.white, padding: EdgeInsets.symmetric(vertical: 14.h), shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(16.r), ), elevation: 0, disabledBackgroundColor: const Color(0xFF3B82F6).withOpacity(0.7), disabledForegroundColor: Colors.white, ), child: controller.isLoading ? SizedBox( height: 20.h, width: 20.h, child: CircularProgressIndicator( strokeWidth: 2.w, valueColor: const AlwaysStoppedAnimation(Colors.white), ), ) : Text( '登录', style: TextStyle( fontSize: 16.sp, fontWeight: FontWeight.w600, ), ), )), ); } // 使用密码登录按钮 Widget _buildUsePasswordButton(bool isDarkMode) { return Center( child: TextButton( onPressed: controller.usePasswordLogin, child: Text( '使用密码登录', style: TextStyle( fontSize: 14.sp, color: isDarkMode ? const Color(0xFF3B82F6) : const Color(0xFF3B82F6), ), ), ), ); } }