import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:yumi/app_localizations.dart'; import 'package:yumi/ui_kit/components/sc_debounce_widget.dart'; import 'package:yumi/ui_kit/components/text/sc_text.dart'; import 'package:yumi/shared/data_sources/sources/local/data_persistence.dart'; import 'package:yumi/shared/data_sources/sources/local/user_manager.dart'; import 'package:yumi/ui_kit/components/sc_tts.dart'; import 'package:yumi/app/constants/sc_screen.dart'; import 'package:yumi/app/constants/sc_global_config.dart'; import 'package:yumi/app/config/business_logic_strategy.dart'; import 'package:yumi/app/routes/sc_routes.dart'; import 'package:yumi/app/routes/sc_fluro_navigator.dart'; import 'package:yumi/shared/tools/sc_loading_manager.dart'; import 'package:yumi/shared/tools/sc_version_utils.dart'; import 'package:yumi/shared/data_sources/sources/repositories/sc_user_repository_impl.dart'; import 'package:yumi/shared/business_logic/models/res/login_res.dart'; import 'package:provider/provider.dart'; import 'package:yumi/services/audio/rtc_manager.dart'; import 'package:yumi/services/audio/rtm_manager.dart'; ///密码账户登录 class SCLoginWithAccountPage extends StatefulWidget { const SCLoginWithAccountPage({super.key}); @override SCLoginWithAccountPageState createState() => SCLoginWithAccountPageState(); } class SCLoginWithAccountPageState extends State with WidgetsBindingObserver { ///显示密码 bool showPass = false; String account = ""; ///账户控制器 TextEditingController accountController = TextEditingController(); ///密码控制器 TextEditingController passController = TextEditingController(); @override void initState() { super.initState(); String account = DataPersistence.getString("Login_Account"); String pwd = DataPersistence.getString("Login_Pwd"); // String account = DataPersistence.getString( // "Login_Account", // defaultValue: "123456", // ); // String pwd = DataPersistence.getString( // "Login_Pwd", // defaultValue: "123456", // ); // if (account.isEmpty) { // account = "123456"; // } // if (pwd.isEmpty) { // pwd = "123456"; // } accountController.text = account; passController.text = pwd; } @override Widget build(BuildContext context) { final businessLogicStrategy = SCGlobalConfig.businessLogicStrategy; final pagePadding = businessLogicStrategy.getLoginPagePadding(); return Scaffold( resizeToAvoidBottomInset: false, body: GestureDetector( onTap: () { FocusScope.of(context).unfocus(); }, child: Stack( alignment: Alignment.topCenter, children: [ Image.asset( businessLogicStrategy.getLoginBackgroundImage(), width: ScreenUtil().screenWidth, height: ScreenUtil().screenHeight, fit: BoxFit.cover, ), SingleChildScrollView( // 添加滚动视图 padding: EdgeInsets.only( bottom: MediaQuery.of(context).viewInsets.bottom + 20, // 添加底部内边距 ), child: Column( children: [ SizedBox(height: pagePadding.top), Image.asset( businessLogicStrategy.getLoginAppIcon(), width: 107.w, height: 159.w, ), SizedBox(height: 35.w), Container( margin: EdgeInsetsDirectional.only(start: 65.w), alignment: AlignmentDirectional.centerStart, child: text( SCAppLocalizations.of(context)!.account, fontSize: 16.sp, textColor: businessLogicStrategy.getLoginLabelTextColor(), fontWeight: FontWeight.bold, ), ), SizedBox(height: 10.w), _buildAccountInput(businessLogicStrategy), SizedBox(height: 10.w), Container( margin: EdgeInsetsDirectional.only(start: 65.w), alignment: AlignmentDirectional.centerStart, child: text( SCAppLocalizations.of(context)!.password, fontSize: 16.sp, textColor: businessLogicStrategy.getLoginLabelTextColor(), fontWeight: FontWeight.bold, ), ), SizedBox(height: 10.w), _buildPassInput(businessLogicStrategy), SizedBox(height: 80.w), _buildLoginBtn(businessLogicStrategy), ], ), ), ], ), ), ); } ///登录按钮 Widget _buildLoginBtn(BusinessLogicStrategy strategy) { final buttonColor = strategy.getLoginButtonColor(); final buttonGradient = strategy.getLoginButtonGradient(); BoxDecoration buttonDecoration; if (buttonGradient != null && buttonGradient.isNotEmpty) { // 使用渐变 buttonDecoration = BoxDecoration( gradient: LinearGradient( colors: buttonGradient, begin: Alignment.centerRight, end: Alignment.centerLeft, ), border: Border.all(color: Color(0xff077142), width: 1.w), borderRadius: BorderRadius.circular(12), // 马甲包设计使用70px圆角 ); } else { // 使用纯色 buttonDecoration = BoxDecoration( color: buttonColor, borderRadius: BorderRadius.all(Radius.circular(height(8))), // 原始应用8px圆角 ); } return Row( children: [ Expanded( child: SCDebounceWidget( child: Container( alignment: Alignment.center, margin: EdgeInsets.symmetric(horizontal: 60.w), height: 42.w, decoration: buttonDecoration, child: text( SCAppLocalizations.of(context)!.logIn, textColor: strategy.getLoginButtonTextColor(), fontSize: 16.sp, fontWeight: FontWeight.w600, ), ), onTap: () { _login(); }, ), ), ], ); } ///账户输入框 Widget _buildAccountInput(BusinessLogicStrategy strategy) { return Row( children: [ Expanded( child: Container( margin: EdgeInsets.symmetric(horizontal: 60.w), padding: EdgeInsetsDirectional.only( start: width(12), end: width(12), ), alignment: AlignmentDirectional.centerStart, height: 45.w, width: ScreenUtil().screenWidth, decoration: strategy.getLoginInputDecoration(), child: TextField( controller: accountController, onChanged: (text) { setState(() { account = text; }); }, maxLength: 30, keyboardType: TextInputType.number, inputFormatters: [ FilteringTextInputFormatter.allow(RegExp("[0-9]")), ], decoration: InputDecoration( isDense: true, filled: false, focusColor: Colors.transparent, hoverColor: Colors.transparent, hintText: SCAppLocalizations.of(context)!.enterAccount, hintStyle: TextStyle( color: strategy.getLoginHintTextColor(), fontSize: 14.sp, fontWeight: FontWeight.w600, ), contentPadding: EdgeInsets.only(top: 0.w), counterText: '', border: InputBorder.none, enabledBorder: InputBorder.none, focusedBorder: InputBorder.none, disabledBorder: InputBorder.none, errorBorder: InputBorder.none, focusedErrorBorder: InputBorder.none, // enabledBorder: UnderlineInputBorder( // borderSide: BorderSide(width: 0.5,color: Colors.white,style: BorderStyle.solid),), // focusedBorder: UnderlineInputBorder( // borderSide: BorderSide(width: 0.5,color: Colors.white,style: BorderStyle.solid),), // prefixIcon: Padding(padding: EdgeInsets.all(8.w), child: Image.asset("images/login/sc_icon_phone.png",width: 20.w, height: 20.w,fit: BoxFit.fill,),), suffix: _buildPhoneCancel(), ), style: TextStyle( fontSize: 14.sp, color: strategy.getLoginInputTextColor(), fontWeight: FontWeight.w600, textBaseline: TextBaseline.alphabetic, ), ), ), ), ], ); } _buildPhoneCancel() { return Offstage( offstage: accountController.text == "", child: GestureDetector( onTap: () { setState(() { accountController.text = ''; }); }, child: Padding( padding: const EdgeInsets.symmetric(horizontal: 8), child: Image.asset( "sc_images/login/sc_icon_sc.png", width: 15.w, color: Colors.white, ), ), ), ); } ///密码输入框 Widget _buildPassInput(BusinessLogicStrategy strategy) { return Row( children: [ Expanded( child: Container( margin: EdgeInsets.symmetric(horizontal: 60.w), padding: REdgeInsetsDirectional.only( start: width(12), end: width(12), ), alignment: AlignmentDirectional.centerStart, height: 45.w, width: ScreenUtil().screenWidth, decoration: strategy.getLoginInputDecoration(), child: TextField( controller: passController, maxLength: 30, maxLines: 1, inputFormatters: [ FilteringTextInputFormatter.deny("[\u4e00-\u9fa5]"), ], obscureText: !showPass, textInputAction: TextInputAction.done, onChanged: (s) { setState(() {}); }, decoration: InputDecoration( isDense: true, filled: false, focusColor: Colors.transparent, hoverColor: Colors.transparent, hintText: SCAppLocalizations.of(context)!.enterPassword, hintStyle: TextStyle( color: strategy.getLoginHintTextColor(), fontSize: 14.sp, fontWeight: FontWeight.w600, ), counterText: '', contentPadding: EdgeInsets.only(top: 0.w), border: InputBorder.none, enabledBorder: InputBorder.none, focusedBorder: InputBorder.none, disabledBorder: InputBorder.none, errorBorder: InputBorder.none, focusedErrorBorder: InputBorder.none, // enabledBorder: UnderlineInputBorder( // borderSide: BorderSide(width: 0.5,color: Colors.white,style: BorderStyle.solid),), // focusedBorder: UnderlineInputBorder( // borderSide: BorderSide(width: 0.5,color: Colors.white,style: BorderStyle.solid),), // prefixIcon: Padding(padding: EdgeInsets.all(8.w), child: Image.asset("images/login/sc_icon_pwd.png",width: 20.w, height: 20.w,fit: BoxFit.fill,),), suffix: GestureDetector( behavior: HitTestBehavior.opaque, onTap: () { setState(() { showPass = !showPass; }); }, child: Padding( padding: const EdgeInsets.symmetric(horizontal: 8), child: Image.asset( !showPass ? "sc_images/login/sc_icon_pass.png" : "sc_images/login/sc_icon_pass1.png", gaplessPlayback: true, color: Colors.white, width: 15.w, ), ), ), ), style: TextStyle( fontSize: 14.sp, color: strategy.getLoginInputTextColor(), fontWeight: FontWeight.w600, ), ), ), ), ], ); } ///登录 _login() async { String account = accountController.text; String pass = passController.text; if (account.isEmpty || pass.isEmpty) { SCTts.show( SCAppLocalizations.of(context)!.theAccountPasswordCannotBeEmpty, ); return; } SCLoadingManager.show(context: context); try { final results = await Future.wait([ SCAccountRepository().loginForAccount(account, pass), SCVersionUtils.checkReview(), ]); var user = (results[0] as SocialChatLoginRes); if (!mounted) { return; } await Provider.of( context, listen: false, ).resetLocalRoomState( fallbackRtmProvider: Provider.of(context, listen: false), ); if (!mounted) { return; } AccountStorage().setCurrentUser(user); SCLoadingManager.hide(); DataPersistence.setString("Login_Account", account); DataPersistence.setString("Login_Pwd", pass); if (mounted) { SCNavigatorUtils.push(context, SCRoutes.home, clearStack: true); } } catch (e) { SCLoadingManager.hide(); // 可以添加错误处理逻辑 rethrow; } } }