import 'package:flutter/material.dart'; import 'package:get/get.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:kaer_with_panels/app/utils/kr_log_util.dart'; import '../controllers/kr_login_controller.dart'; import 'package:kaer_with_panels/app/widgets/kr_app_text_style.dart'; import 'package:kaer_with_panels/app/localization/app_translations.dart'; import 'package:kaer_with_panels/app/widgets/kr_local_image.dart'; import 'package:kaer_with_panels/app/widgets/hi_base_scaffold.dart'; import 'package:kaer_with_panels/app/widgets/hi_help_entrance.dart'; import 'package:kaer_with_panels/app/common/app_run_data.dart'; import 'package:kaer_with_panels/app/modules/kr_home/controllers/kr_home_controller.dart'; import 'package:kaer_with_panels/app/services/kr_site_config_service.dart'; import 'package:flutter/foundation.dart'; import 'package:kaer_with_panels/app/widgets/kr_subscription_expiry_text.dart'; import 'package:flutter/services.dart'; class KRLoginView extends GetView { const KRLoginView({super.key}); @override Widget build(BuildContext context) { final isKeyboardVisible = MediaQuery.of(context).viewInsets.bottom > 0; final isHideBack = (Get.arguments as Map?)?['is-back'] ?? false; return HIBaseScaffold( showBack: !isHideBack, resizeToAvoidBottomInset: true, child: Stack( children: [ GestureDetector( behavior: HitTestBehavior.translucent, onTap: () { FocusScope.of(context).unfocus(); }, child: SingleChildScrollView( child: Padding( padding: EdgeInsets.symmetric( horizontal: 40.w, ), child: Column( children: [ // Text( // '${controller.kr_loginStatus.value}', // style: TextStyle(color: Colors.white), // 使用 TextStyle() // ), SizedBox(height: 20.w), _buildUserInfoSection(), SizedBox(height: 12.w), _buildContentByEntry(), SizedBox(height: 100.w), // 为底部帮助按钮留出空间 ], ), ), ), ), if (!isKeyboardVisible) const HIHelpEntrance(), ], ), ); } Widget _buildUserInfoSection() { return Row( children: [ Container( width: 60.w, height: 60.w, decoration: BoxDecoration( color: Colors.white, borderRadius: BorderRadius.circular(18.r), ), alignment: Alignment.center, child: KrLocalImage( imageName: 'hi-home-logo', imageType: ImageType.svg, width: 30.w, height: 30.w, color: Colors.black, ), ), SizedBox(width: 12.w), Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, mainAxisAlignment: MainAxisAlignment.center, children: [ Obx(() { final account = KRAppRunData.getInstance().kr_account.value; final isDeviceLogin = account != null && account.startsWith('9000'); final accountText = (account ==null || isDeviceLogin) ? '待绑定' : '${KRAppRunData.getInstance().kr_account.value.toString()}'; return Text( accountText, style: TextStyle( color: Colors.white.withOpacity(0.85), fontSize: 14.sp, fontWeight: FontWeight.w500, ), ); }), KRSubscriptionExpiryText( expireTimeProvider: () => controller .kr_subscribeService.kr_currentSubscribe.value?.expireTime, style: TextStyle( color: Colors.white, fontSize: 12.sp, ), ), ], ), ), ], ); } Widget _buildContentByEntry() { final entry = (Get.arguments as Map?)?['entry']; if (entry == 'forget_psd') { return _buildForgetPasswordLayout(); } else if (entry == 'bind_email') { return _buildBindEmailLayout(); } else if (entry == 'login') { return _buildLoginEmailLayout(); } return _buildForgetPasswordLayout(); // 默认显示修改密码 } Widget _buildForgetPasswordLayout() { return Column( children: [ Container( constraints: BoxConstraints(minHeight: 300.w), child: Column( children: [ _buildStandardInputField( controller: controller.psdController, hintText: '新密码', isPassword: true, ), SizedBox(height: 10.w), _buildStandardInputField( controller: controller.agPsdController, hintText: '确认密码', isPassword: true, ), ], ), ), SizedBox(height: 30.h), _buildSaveButton(), ], ); } Widget _buildBindEmailLayout() { return Column( children: [ Container( constraints: BoxConstraints(minHeight: 300.w), child: Column( children: [ _buildStandardInputField( controller: controller.accountController, hintText: 'Email', ), // SizedBox(height: 10.w), // _buildStandardInputField( // controller: controller.psdController, // hintText: '新密码', // isPassword: true, // ), // SizedBox(height: 10.w), // _buildStandardInputField( // controller: controller.agPsdController, // hintText: '确认密码', // isPassword: true, // ), SizedBox(height: 10.w), // 👇 核心改动:使用新的验证码输入框 _buildVerificationCodeField(), ], ), ), SizedBox(height: 30.h), _buildSaveButton(), ], ); } Widget _buildLoginEmailLayout() { return Column( children: [ Container( constraints: BoxConstraints(minHeight: 300.w), child: Column( children: [ _buildStandardInputField( controller: controller.accountController, hintText: 'Email', ), SizedBox(height: 10.w), _buildStandardInputField( controller: controller.psdController, hintText: '密码', isPassword: true, ), SizedBox(height: 10.w), ], ), ), SizedBox(height: 30.h), _buildSaveButton(), ], ); } /// 构建标准输入框 Widget _buildStandardInputField({ required TextEditingController controller, required String hintText, bool isPassword = false, }) { return SizedBox( height: 50.w, // 固定高度 child: TextField( controller: controller, obscureText: isPassword, style: KrAppTextStyle( fontSize: 16, color: Colors.white, ), decoration: InputDecoration( hintText: hintText, hintStyle: KrAppTextStyle( fontSize: 16, color: const Color(0xFFA6A6A6), fontWeight: FontWeight.w600, ), contentPadding: EdgeInsets.symmetric(horizontal: 16.w, vertical: 10.w), border: OutlineInputBorder( borderRadius: BorderRadius.circular(25.w), // 调整为更圆的角 borderSide: BorderSide(color: Colors.white, width: 2), ), enabledBorder: OutlineInputBorder( borderRadius: BorderRadius.circular(25.w), borderSide: BorderSide(color: Colors.white, width: 2), ), focusedBorder: OutlineInputBorder( borderRadius: BorderRadius.circular(25.w), borderSide: BorderSide(color: Colors.white, width: 2), ), ), ), ); } /// 构建注册页面的验证码输入框(包含间距) Widget _buildVerificationCodeField() { // 从站点配置服务获取验证配置(站点配置不是响应式的,不需要 Obx) // final siteConfig = KRSiteConfigService(); // final needVerification = siteConfig.isEmailVerificationEnabled() || // siteConfig.isRegisterVerificationEnabled(); // // // 如果不需要验证码,返回空容器 // if (!needVerification) { // return SizedBox.shrink(); // } return SizedBox( height: 50.w, // 固定高度 child: TextField( controller: controller.codeController, keyboardType: TextInputType.number, textInputAction: TextInputAction.done, autofillHints: const [AutofillHints.oneTimeCode], enableSuggestions: false, autocorrect: false, inputFormatters: [FilteringTextInputFormatter.digitsOnly], onChanged: (value) { var v = value.replaceAll(RegExp("\\s+"), ""); if (v.length % 2 == 0 && v.isNotEmpty) { final half = v.length ~/ 2; final first = v.substring(0, half); final second = v.substring(half); if (first == second) { v = first; } } const maxLen = 6; if (v.length > maxLen) { v = v.substring(0, maxLen); } if (controller.codeController.text != v) { controller.codeController.value = controller.codeController.value.copyWith( text: v, selection: TextSelection.collapsed(offset: v.length), composing: TextRange.empty, ); } if (v.isNotEmpty && (v.length >= 6)) { FocusScope.of(Get.context!).unfocus(); } }, onSubmitted: (_) { FocusScope.of(Get.context!).unfocus(); }, style: KrAppTextStyle( fontSize: 16, color: Colors.white, ), decoration: InputDecoration( hintText: '验证码', hintStyle: KrAppTextStyle( fontSize: 16, color: const Color(0xFFA6A6A6), fontWeight: FontWeight.w600, ), contentPadding: EdgeInsets.symmetric(horizontal: 16.w, vertical: 10.w), border: OutlineInputBorder( borderRadius: BorderRadius.circular(25.w), borderSide: BorderSide(color: Colors.white, width: 2), ), enabledBorder: OutlineInputBorder( borderRadius: BorderRadius.circular(25.w), borderSide: BorderSide(color: Colors.white, width: 2), ), focusedBorder: OutlineInputBorder( borderRadius: BorderRadius.circular(25.w), borderSide: BorderSide(color: Colors.white, width: 2), ), isDense: true, suffixIconConstraints: BoxConstraints( maxHeight: 50.w, // 限制最大高度 ), suffixIcon: Padding( padding: EdgeInsets.symmetric(horizontal: 5.w, vertical: 5.w), child: Obx(() { return GestureDetector( onTap: controller.kr_canSendCode.value ? () => controller.kr_sendCode() : null, child: Container( width: 100.w, alignment: Alignment.center, decoration: BoxDecoration( color: controller.kr_canSendCode.value ? Theme.of(Get.context!).primaryColor : const Color(0xFFD5D5D5), borderRadius: BorderRadius.circular(100.r), // 药丸状 ), child: Text( controller.kr_countdownText.value, style: KrAppTextStyle( fontSize: 14, fontWeight: FontWeight.w600, color: controller.kr_canSendCode.value ? Colors.black : const Color(0xFF464655), ), ), ), ); }), ), ), ), ); } Widget _buildSaveButton() { return GestureDetector( onTap: () { _handleSave(); }, child: Container( width: double.infinity, height: 50.w, decoration: BoxDecoration( color: Theme.of(Get.context!).primaryColor, borderRadius: BorderRadius.circular(100.r), ), child: Center( child: Text( controller.kr_getNextBtnText(), style: KrAppTextStyle( fontSize: 16, fontWeight: FontWeight.w600, color: Colors.black, ), ), ), ), ); } void _handleSave() { final entry = (Get.arguments as Map?)?['entry']; if (entry == 'forget_psd') { controller.kr_setNewPsdByForgetPsd(); } else if (entry == 'bind_email') { controller.kr_register(); } else if (entry == 'login') { controller.kr_check(); } } }