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'; 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: [ 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'); if (isDeviceLogin) return const SizedBox(); return Text( account ?? '', style: TextStyle( color: Colors.white, fontSize: 20.sp, fontWeight: FontWeight.bold, height: 0.9, ), maxLines: 1, overflow: TextOverflow.ellipsis, ); }), Obx(() { final _ = KRAppRunData.getInstance().kr_isLogin.value; final userId = (KRAppRunData.getInstance().kr_userId.value ?? '').toString(); final deviceId = KRAppRunData.getInstance().deviceId ?? ''; return Text( 'ID: ${userId.isNotEmpty ? userId : deviceId}', style: TextStyle( color: Colors.white.withOpacity(0.85), fontSize: 14.sp, fontWeight: FontWeight.w500, ), ); }), Obx(() { final currentSubscribe = controller.kr_subscribeService.kr_currentSubscribe.value; String expiryText; if (currentSubscribe == null) { expiryText = '尚未购买套餐'; } else { final now = DateTime.now(); DateTime? expireDateTime; try { expireDateTime = DateTime.parse(currentSubscribe.expireTime); } catch (e) { expireDateTime = null; } if (expireDateTime == null) { expiryText = '套餐信息无效'; } else if (expireDateTime.isBefore(now)) { final formattedExpireDate = '${expireDateTime.year}/${expireDateTime.month.toString().padLeft(2, '0')}/${expireDateTime.day.toString().padLeft(2, '0')}'; expiryText = '已于 $formattedExpireDate 到期'; } else { expiryText = '到期时间:${expireDateTime}';final year = expireDateTime.year; final month = expireDateTime.month.toString().padLeft(2, '0'); final day = expireDateTime.day.toString().padLeft(2, '0'); final hour = expireDateTime.hour.toString().padLeft(2, '0'); final minute = expireDateTime.minute.toString().padLeft(2, '0'); final second = expireDateTime.second.toString().padLeft(2, '0'); // 2. 拼接成最终的字符串 final formattedDateTime = '$year/$month/$day $hour:$minute:$second'; expiryText = '到期时间:$formattedDateTime'; } } return Text( expiryText, 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, 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(); } } }