Files
hi-client/lib/app/modules/kr_login/views/kr_login_view.dart
T
greatsage 4c5763647d refactor: 优化日志输出,仅在调试模式下启用
- 为所有 print 语句添加 kDebugMode 检查
- 更新 KRLogUtil 工具类,Release 模式下禁用日志输出
- 优化 18 个文件中的 335+ 条日志语句
- 提升 Release 版本性能并增强安全性

(cherry picked from commit 301f1510ba81fe94fb08e013ca80b3ca708a2e15)
2025-11-01 23:31:11 -07:00

416 lines
14 KiB
Dart
Executable File

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<KRLoginController> {
const KRLoginView({super.key});
@override
Widget build(BuildContext context) {
final isKeyboardVisible = MediaQuery.of(context).viewInsets.bottom > 0;
final isHideBack = (Get.arguments as Map<String, dynamic>?)?['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 _ = KRAppRunData.getInstance().kr_isLogin.value;
final email = KRAppRunData.getInstance().kr_account.value ?? '';
return Text(
email.isNotEmpty ? email : '',
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<String, dynamic>?)?['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<String, dynamic>?)?['entry'];
if (entry == 'forget_psd') {
controller.kr_setNewPsdByForgetPsd();
} else if (entry == 'bind_email') {
controller.kr_register();
} else if (entry == 'login') {
controller.kr_check();
}
}
}