hi-client/lib/app/modules/kr_login/views/kr_login_view.dart
2025-10-13 18:08:02 +08:00

1099 lines
39 KiB
Dart
Executable File
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import 'package:flutter/material.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:get/get.dart';
import 'package:kaer_with_panels/app/model/enum/kr_request_type.dart';
import 'package:kaer_with_panels/app/model/kr_area_code.dart';
import 'package:kaer_with_panels/app/modules/kr_login/views/kr_search_area_code_view.dart';
import 'package:kaer_with_panels/app/widgets/kr_app_text_style.dart';
import 'package:kaer_with_panels/app/widgets/kr_local_image.dart';
import '../../../routes/app_pages.dart';
import '../controllers/kr_login_controller.dart';
import 'package:kaer_with_panels/app/localization/app_translations.dart';
import 'package:kaer_with_panels/app/services/api_service/api.dart';
import 'package:kaer_with_panels/app/common/app_config.dart';
class KRLoginView extends GetView<KRLoginController> {
const KRLoginView({super.key});
@override
Widget build(BuildContext context) {
final theme = Theme.of(context);
return GestureDetector(
onTap: () {
if (!FocusScope.of(context).hasPrimaryFocus) {
FocusScope.of(context).unfocus();
}
_hideDropdown();
},
child: Container(
color: theme.scaffoldBackgroundColor,
child: SingleChildScrollView(
padding: EdgeInsets.symmetric(horizontal: 20.w),
child: Obx(() {
switch (controller.kr_loginStatus.value) {
case KRLoginProgressStatus.kr_check:
return _buildCheckView(context);
case KRLoginProgressStatus.kr_loginByCode:
return _buildLoginByCodeView(context);
case KRLoginProgressStatus.kr_loginByPsd:
return _buildLoginByPsdView(context);
case KRLoginProgressStatus.kr_registerSendCode:
return _buildRegisterSendCodeView(context);
case KRLoginProgressStatus.kr_registerSetPsd:
return _buildRegisterSetPsdView(context);
case KRLoginProgressStatus.kr_forgetPsdSendCode:
return _buildForgetPsdSendCodeView(context);
case KRLoginProgressStatus.kr_forgetPsdSetPsd:
return _buildForgetPsdSetPsdView(context);
default:
return Container();
}
}),
),
),
);
}
Widget _buildCheckView(BuildContext context) {
// 构建检查视图的代码
return Column(
mainAxisSize: MainAxisSize.min,
children: [
Obx(() => Visibility(
visible: controller.kr_loginStatus.value != KRLoginProgressStatus.kr_check,
child: _buildBackButton(Theme.of(context)),
)),
_buildHeaderSection(Theme.of(context)),
_buildInputSection(context, Theme.of(context)),
_buildDynamicContent(Theme.of(context)),
_buildNextButton(controller.kr_getNextBtnText(), Theme.of(context)),
SizedBox(height: _getBottomPadding()),
],
);
}
/// 获取底部间距
double _getBottomPadding() {
switch (controller.kr_loginStatus.value) {
case KRLoginProgressStatus.kr_check:
case KRLoginProgressStatus.kr_loginByCode:
case KRLoginProgressStatus.kr_loginByPsd:
// 这些状态内容较少,减小底部间距
return 48.w;
case KRLoginProgressStatus.kr_registerSetPsd:
case KRLoginProgressStatus.kr_forgetPsdSetPsd:
// 这些状态有额外的输入框,保持原有间距
return 48.w;
default:
// 其他状态使用中等间距
return 48.w;
}
}
Widget _buildLoginByCodeView(BuildContext context) {
// 构建验证码登录视图的代码
return Column(
mainAxisSize: MainAxisSize.min,
children: [
Obx(() => Visibility(
visible: controller.kr_loginStatus.value != KRLoginProgressStatus.kr_check,
child: _buildBackButton(Theme.of(context)),
)),
_buildHeaderSection(Theme.of(context)),
_buildInputSection(context, Theme.of(context)),
_buildDynamicContent(Theme.of(context)),
_buildNextButton(controller.kr_getNextBtnText(), Theme.of(context)),
SizedBox(height: _getBottomPadding()),
],
);
}
Widget _buildLoginByPsdView(BuildContext context) {
// 构建密码登录视图的代码
return Column(
mainAxisSize: MainAxisSize.min,
children: [
Obx(() => Visibility(
visible: controller.kr_loginStatus.value != KRLoginProgressStatus.kr_check,
child: _buildBackButton(Theme.of(context)),
)),
_buildHeaderSection(Theme.of(context)),
_buildInputSection(context, Theme.of(context)),
_buildDynamicContent(Theme.of(context)),
_buildNextButton(controller.kr_getNextBtnText(), Theme.of(context)),
SizedBox(height: _getBottomPadding()),
],
);
}
Widget _buildRegisterSendCodeView(BuildContext context) {
// 构建注册发送验证码视图的代码
return Column(
mainAxisSize: MainAxisSize.min,
children: [
Obx(() => Visibility(
visible: controller.kr_loginStatus.value != KRLoginProgressStatus.kr_check,
child: _buildBackButton(Theme.of(context)),
)),
_buildHeaderSection(Theme.of(context)),
_buildInputSection(context, Theme.of(context)),
_buildDynamicContent(Theme.of(context)),
_buildNextButton(controller.kr_getNextBtnText(), Theme.of(context)),
SizedBox(height: _getBottomPadding()),
],
);
}
Widget _buildRegisterSetPsdView(BuildContext context) {
// 构建注册设置密码视图的代码
return Column(
mainAxisSize: MainAxisSize.min,
children: [
Obx(() => Visibility(
visible: controller.kr_loginStatus.value != KRLoginProgressStatus.kr_check,
child: _buildBackButton(Theme.of(context)),
)),
_buildHeaderSection(Theme.of(context)),
_buildInputSection(context, Theme.of(context)),
Column(
children: [
SizedBox(height: 8.w),
_buildInputContainer(context, true, Theme.of(context)),
SizedBox(height: 8.w),
_buildInviteCodeInput(Theme.of(context)),
],
),
_buildDynamicContent(Theme.of(context)),
_buildNextButton(controller.kr_getNextBtnText(), Theme.of(context)),
SizedBox(height: _getBottomPadding()),
],
);
}
Widget _buildForgetPsdSendCodeView(BuildContext context) {
// 构建忘记密码发送验证码视图的代码
return Column(
mainAxisSize: MainAxisSize.min,
children: [
Obx(() => Visibility(
visible: controller.kr_loginStatus.value != KRLoginProgressStatus.kr_check,
child: _buildBackButton(Theme.of(context)),
)),
_buildHeaderSection(Theme.of(context)),
_buildInputSection(context, Theme.of(context)),
_buildDynamicContent(Theme.of(context)),
_buildNextButton(controller.kr_getNextBtnText(), Theme.of(context)),
SizedBox(height: _getBottomPadding()),
],
);
}
Widget _buildForgetPsdSetPsdView(BuildContext context) {
// 构建忘记密码设置密码视图的代码
return Column(
mainAxisSize: MainAxisSize.min,
children: [
Obx(() => Visibility(
visible: controller.kr_loginStatus.value != KRLoginProgressStatus.kr_check,
child: _buildBackButton(Theme.of(context)),
)),
_buildHeaderSection(Theme.of(context)),
_buildInputSection(context, Theme.of(context)),
if (controller.kr_loginStatus.value == KRLoginProgressStatus.kr_forgetPsdSetPsd)
Column(
children: [
SizedBox(height: 8.w),
_buildInputContainer(context, true, Theme.of(context)),
],
),
_buildDynamicContent(Theme.of(context)),
_buildNextButton(controller.kr_getNextBtnText(), Theme.of(context)),
SizedBox(height: _getBottomPadding()),
],
);
}
/// 构建头部文本部分
Widget _buildHeaderSection(ThemeData theme) {
// 根据不同状态决定是否显示额外信息
switch (controller.kr_loginStatus.value) {
case KRLoginProgressStatus.kr_loginByCode:
case KRLoginProgressStatus.kr_registerSendCode:
case KRLoginProgressStatus.kr_forgetPsdSendCode:
// 验证码相关状态
if (!controller.kr_canSendCode.value) {
// 已发送验证码状态
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
children: [
SizedBox(height: 24.w),
_buildHeaderText(AppTranslations.kr_login.welcome, theme),
SizedBox(height: 8.w),
_buildHeaderText(
_isSendPhone()
? AppTranslations.kr_login.verifyPhone
: AppTranslations.kr_login.verifyEmail,
theme
),
SizedBox(height: 8.w),
Text(
AppTranslations.kr_login.codeSent(controller.accountController.text),
style: theme.textTheme.bodySmall?.copyWith(
fontSize: 13.sp,
fontFamily: 'AlibabaPuHuiTi-Regular',
color: const Color(0xFF666666),
),
),
SizedBox(height: 24.w),
],
);
}
// 未发送验证码状态,显示简单标题
return Padding(
padding: EdgeInsets.only(top: 24.w, bottom: 24.w),
child: _buildHeaderText(AppTranslations.kr_login.welcome, theme),
);
case KRLoginProgressStatus.kr_loginByPsd:
// 密码登录状态
return Padding(
padding: EdgeInsets.only(top: 24.w, bottom: 24.w),
child: _buildHeaderText(AppTranslations.kr_login.welcome, theme),
);
case KRLoginProgressStatus.kr_registerSetPsd:
// 注册设置密码状态
return Padding(
padding: EdgeInsets.only(top: 24.w, bottom: 24.w),
child: _buildHeaderText(AppTranslations.kr_login.welcome, theme),
);
case KRLoginProgressStatus.kr_forgetPsdSetPsd:
// 忘记密码设置新密码状态
return Padding(
padding: EdgeInsets.only(top: 24.w, bottom: 24.w),
child: _buildHeaderText(AppTranslations.kr_login.welcome, theme),
);
case KRLoginProgressStatus.kr_check:
default:
// 初始状态和其他状态
return Padding(
padding: EdgeInsets.only(top: 24.w, bottom: 24.w),
child: _buildHeaderText(AppTranslations.kr_login.welcome, theme),
);
}
}
/// 判断是否为验证码输入状态
bool _isCodeInput() {
switch (controller.kr_loginStatus.value) {
case KRLoginProgressStatus.kr_loginByCode:
case KRLoginProgressStatus.kr_registerSendCode:
case KRLoginProgressStatus.kr_forgetPsdSendCode:
return true;
default:
return false;
}
}
/// 判断是否手机号验证
bool _isSendPhone() {
return controller.kr_loginType == KRLoginType.kr_telephone;
}
/// 修改 _buildInputSection 方法
Widget _buildInputSection(BuildContext context, ThemeData theme) {
return Obx(() {
final loginStatus = controller.kr_loginStatus.value;
if (loginStatus == KRLoginProgressStatus.kr_check) {
return CompositedTransformTarget(
link: controller.kr_layerLink,
child: Container(
width: double.infinity,
child: Row(
children: [
Obx(() => Visibility(
visible: controller.kr_loginType.value == KRLoginType.kr_telephone,
maintainState: true,
maintainSize: false,
maintainAnimation: true,
child: Row(
mainAxisSize: MainAxisSize.min,
children: [
_buildAreaSelector(theme),
SizedBox(width: 8.w),
],
),
)),
Expanded(
child: Container(
height: 52.w,
padding: EdgeInsets.symmetric(horizontal: 12.w),
decoration: ShapeDecoration(
color: theme.cardColor,
shape: RoundedRectangleBorder(
side: BorderSide(width: 0.5, color: const Color(0xFFD2D2D2)),
borderRadius: BorderRadius.circular(10.r),
),
),
child: Row(
children: [
Obx(() => Visibility(
visible: controller.kr_loginType.value != KRLoginType.kr_telephone,
maintainState: true,
maintainAnimation: true,
child: Row(
mainAxisSize: MainAxisSize.min,
children: [
_buildIcon("login_account"),
SizedBox(width: 8.w),
],
),
)),
Expanded(
child: TextField(
focusNode: controller.kr_accountFocusNode,
controller: controller.accountController,
keyboardType: TextInputType.text,
decoration: InputDecoration(
hintText: 'login.enterEmailOrPhone'.tr,
hintStyle: theme.textTheme.bodySmall?.copyWith(
fontSize: 14.sp,
fontFamily: 'AlibabaPuHuiTi-Regular',
),
border: InputBorder.none,
),
style: theme.textTheme.bodyMedium?.copyWith(
fontSize: 14.sp,
fontFamily: 'AlibabaPuHuiTi-Regular',
),
onChanged: (value) {
if (controller.kr_emailList.isNotEmpty) {
_showDropdown(context);
} else {
_hideDropdown();
}
},
),
),
_buildClearButton(),
],
),
),
),
],
),
),
);
}
return _buildInputContainer(context, false, theme);
});
}
/// 构建输入容器
Widget _buildInputContainer(BuildContext context, bool isNewPsd, ThemeData theme) {
if (controller.kr_loginStatus.value == KRLoginProgressStatus.kr_check &&
controller.kr_loginType.value == KRLoginType.kr_telephone) {
return Row(
children: [
_buildAreaSelector(theme),
SizedBox(width: 8.w),
Expanded(
child: _buildPhoneInput(context, theme),
),
],
);
}
return CompositedTransformTarget(
link: controller.kr_layerLink,
child: Container(
width: double.infinity,
height: 52.w,
decoration: ShapeDecoration(
color: theme.cardColor,
shape: RoundedRectangleBorder(
side: BorderSide(width: 0.5, color: const Color(0xFFD2D2D2)),
borderRadius: BorderRadius.circular(10.r),
),
),
child: Row(
children: [
Padding(
padding: EdgeInsets.only(left: 12.w),
child: _buildInputLeftWideget(theme),
),
SizedBox(width: 8.w),
Expanded(
child: TextField(
controller: controller.kr_loginStatus.value == KRLoginProgressStatus.kr_check
? controller.accountController
: controller.kr_loginStatus.value == KRLoginProgressStatus.kr_loginByCode ||
controller.kr_loginStatus.value == KRLoginProgressStatus.kr_registerSendCode ||
controller.kr_loginStatus.value == KRLoginProgressStatus.kr_forgetPsdSendCode
? controller.codeController
: isNewPsd
? controller.agPsdController
: controller.psdController,
keyboardType: (controller.kr_loginStatus.value == KRLoginProgressStatus.kr_loginByCode ||
controller.kr_loginStatus.value == KRLoginProgressStatus.kr_registerSendCode ||
controller.kr_loginStatus.value == KRLoginProgressStatus.kr_forgetPsdSendCode)
? TextInputType.number
: TextInputType.text,
decoration: InputDecoration(
hintText: controller.kr_loginStatus.value == KRLoginProgressStatus.kr_check
? 'login.enterEmailOrPhone'.tr
: controller.kr_loginStatus.value == KRLoginProgressStatus.kr_loginByCode ||
controller.kr_loginStatus.value == KRLoginProgressStatus.kr_registerSendCode ||
controller.kr_loginStatus.value == KRLoginProgressStatus.kr_forgetPsdSendCode
? 'login.enterCode'.tr
: isNewPsd
? 'login.reenterPassword'.tr
: 'login.enterPassword'.tr,
hintStyle: theme.textTheme.bodySmall?.copyWith(
fontSize: 14.sp,
fontFamily: 'AlibabaPuHuiTi-Regular',
),
border: InputBorder.none,
contentPadding: EdgeInsets.symmetric(vertical: 16.w),
suffixIcon: (controller.kr_loginStatus.value == KRLoginProgressStatus.kr_loginByPsd ||
controller.kr_loginStatus.value == KRLoginProgressStatus.kr_registerSetPsd ||
controller.kr_loginStatus.value == KRLoginProgressStatus.kr_forgetPsdSetPsd) &&
(isNewPsd ? controller.kr_agPsdHasText.value : controller.kr_psdHasText.value)
? IconButton(
icon: Icon(
controller.kr_obscureText.value ? Icons.visibility_off : Icons.visibility,
color: const Color(0xFF999999),
),
onPressed: () {
controller.kr_obscureText.value = !controller.kr_obscureText.value;
},
)
: null,
),
style: theme.textTheme.bodyMedium?.copyWith(
fontSize: 14.sp,
fontFamily: 'AlibabaPuHuiTi-Regular',
),
obscureText: (controller.kr_loginStatus.value == KRLoginProgressStatus.kr_loginByPsd ||
controller.kr_loginStatus.value == KRLoginProgressStatus.kr_registerSetPsd ||
controller.kr_loginStatus.value == KRLoginProgressStatus.kr_forgetPsdSetPsd) &&
controller.kr_obscureText.value,
onChanged: (value) {
if (controller.kr_emailList.length > 0) {
_showDropdown(context);
} else {
_hideDropdown();
}
},
),
),
if (controller.kr_loginStatus.value == KRLoginProgressStatus.kr_loginByCode ||
controller.kr_loginStatus.value == KRLoginProgressStatus.kr_registerSendCode ||
controller.kr_loginStatus.value == KRLoginProgressStatus.kr_forgetPsdSendCode) ...[
if (controller.kr_codeHasText.value)
GestureDetector(
onTap: () {
controller.codeController.clear();
},
child: Container(
height: double.infinity,
padding: EdgeInsets.symmetric(horizontal: 8.w),
child: _buildIcon("login_close"),
),
),
_buildSendCodeButton(theme),
] else if (controller.kr_loginStatus.value == KRLoginProgressStatus.kr_check
? controller.kr_accountHasText.value
: isNewPsd
? controller.kr_agPsdHasText.value
: controller.kr_psdHasText.value) ...[
GestureDetector(
onTap: () {
if (controller.kr_loginStatus.value == KRLoginProgressStatus.kr_check) {
controller.kr_emailList.clear();
_hideDropdown();
}
if (controller.kr_loginStatus.value == KRLoginProgressStatus.kr_check) {
controller.accountController.clear();
} else if (isNewPsd) {
controller.agPsdController.clear();
} else {
controller.psdController.clear();
}
},
child: Container(
height: double.infinity,
padding: EdgeInsets.symmetric(horizontal: 8.w),
child: _buildIcon("login_close"),
),
),
],
],
),
),
);
}
/// 构建发送验证码按钮
Widget _buildSendCodeButton(ThemeData theme) {
return Obx(() => GestureDetector(
onTap: controller.kr_canSendCode.value ? () => controller.kr_sendCode() : null,
child: Container(
alignment: Alignment.center,
width: 100.w,
padding: EdgeInsets.only(right: 4.w),
child: Text(
controller.kr_countdownText.value,
style: theme.textTheme.bodySmall?.copyWith(
fontSize: 14.sp,
color: controller.kr_canSendCode.value
? const Color(0xFF1797FF)
: const Color(0xFF999999),
fontFamily: 'AlibabaPuHuiTi-Regular',
),
),
),
));
}
/// 显示悬浮框
void _showDropdown(BuildContext context) {
final theme = Theme.of(context);
if (controller.isDropdownVisible) return;
controller.overlayEntry = OverlayEntry(
builder: (_) => Positioned(
width: MediaQuery.of(context).size.width - 40.w,
child: CompositedTransformFollower(
link: controller.kr_layerLink,
showWhenUnlinked: false,
offset: Offset(0, 54.w),
child: Material(
elevation: 4,
borderRadius: BorderRadius.circular(10.r),
child: Obx(() {
return Container(
constraints: BoxConstraints(maxHeight: 216.w),
decoration: ShapeDecoration(
color: theme.cardColor,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10.r),
),
),
child: ListView.builder(
padding: EdgeInsets.zero,
shrinkWrap: true,
itemCount: controller.kr_emailList.length,
itemBuilder: (context, index) {
final email = controller.kr_emailList[index];
return InkWell(
onTap: () {
controller.accountController.text = email;
controller.accountController.selection = TextSelection.fromPosition(
TextPosition(offset: email.length),
);
_hideDropdown();
},
child: Container(
padding: EdgeInsets.symmetric(
vertical: 12.w,
horizontal: 15.w,
),
child: Text(
email,
style: theme.textTheme.bodyMedium?.copyWith(
fontSize: 14.sp,
fontFamily: 'AlibabaPuHuiTi-Regular',
),
),
),
);
},
),
);
}),
),
),
),
);
Overlay.of(context).insert(controller.overlayEntry!);
controller.isDropdownVisible = true;
}
/// 隐藏悬浮框
void _hideDropdown() {
if (controller.isDropdownVisible) {
controller.overlayEntry?.remove();
controller.overlayEntry = null;
controller.isDropdownVisible = false;
}
}
/// 构建输入框左侧组件
Widget _buildInputLeftWideget(ThemeData theme) {
return Obx(() {
switch (controller.kr_loginStatus.value) {
case KRLoginProgressStatus.kr_check:
// 检查状态下,根据登录类型判断返回内容
return controller.kr_loginType.value == KRLoginType.kr_telephone
? _buildChoiceCode(theme)
: _buildIcon("login_account");
case KRLoginProgressStatus.kr_loginByCode:
case KRLoginProgressStatus.kr_registerSendCode:
case KRLoginProgressStatus.kr_forgetPsdSendCode:
// 验证码相关状态,返回通用图标
return _buildIcon("login_code");
case KRLoginProgressStatus.kr_registerSetPsd:
case KRLoginProgressStatus.kr_forgetPsdSetPsd:
// 设置密码相关状态,返回通用图标
return _buildIcon("login_psd");
default:
// 默认返回通用图标
return SizedBox();
}
});
}
/// 动态显示内容部分
Widget _buildDynamicContent(ThemeData theme) {
// 先确定内容
Widget? content;
switch (controller.kr_loginStatus.value) {
case KRLoginProgressStatus.kr_check:
content = _buildAgreementText(theme);
case KRLoginProgressStatus.kr_loginByCode:
case KRLoginProgressStatus.kr_loginByPsd:
content = _buildLoginBtns(theme);
default:
return SizedBox(height: 17.w); // 移除 const因为使用了扩展方法
}
// 有内容时的布局
return Column(
mainAxisSize: MainAxisSize.min,
children: [
SizedBox(height: 12.w), // 与输入框的间距
content,
SizedBox(height: 17.w), // 与下一步按钮的间距
],
);
}
/// 构建协议文本
Widget _buildAgreementText(ThemeData theme) {
return Row(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
KrLocalImage(
imageName: "selete_s",
width: 20.w,
height: 20.w,
),
SizedBox(width: 4.w),
Expanded(
child: Wrap(
alignment: WrapAlignment.start,
spacing: 4.w,
runSpacing: 4.w,
crossAxisAlignment: WrapCrossAlignment.center,
children: [
Text(
'login.agreeTerms'.tr,
style: _commonTextStyle(fontSize: 13),
),
GestureDetector(
onTap: () => Get.toNamed(Routes.KR_WEBVIEW, arguments: {
'url': Api.kr_getSiteTos,
'title': 'login.termsOfService'.tr,
}),
child: Text(
'login.termsOfService'.tr,
style: _commonTextStyle(fontSize: 13, color: const Color(0xFF1796FF)),
),
),
Text(
AppTranslations.kr_login.and,
style: _commonTextStyle(fontSize: 13),
),
GestureDetector(
onTap: () => Get.toNamed(Routes.KR_WEBVIEW, arguments: {
'url': Api.kr_getSitePrivacy,
'title': 'login.privacyPolicy'.tr,
}),
child: Text(
'login.privacyPolicy'.tr,
style: _commonTextStyle(fontSize: 13, color: const Color(0xFF1796FF)),
),
),
],
),
),
],
);
}
/// 构建登录按钮行
Widget _buildLoginBtns(ThemeData theme) {
return SizedBox(
height: 24.w,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
GestureDetector(
onTap: () => controller.kr_loginStatus.value =
KRLoginProgressStatus.kr_forgetPsdSendCode,
behavior: HitTestBehavior.opaque,
child: Text(
'login.forgotPassword'.tr,
style: theme.textTheme.bodySmall?.copyWith(
fontSize: 13.sp,
color: const Color(0xFF666666),
fontWeight: FontWeight.w500,
fontFamily: 'AlibabaPuHuiTi-Medium',
),
),
),
GestureDetector(
onTap: () {
controller.kr_loginStatus.value = controller.kr_loginStatus.value ==
KRLoginProgressStatus.kr_loginByPsd
? KRLoginProgressStatus.kr_loginByCode
: KRLoginProgressStatus.kr_loginByPsd;
},
behavior: HitTestBehavior.opaque,
child: Text(
controller.kr_loginStatus.value ==
KRLoginProgressStatus.kr_loginByPsd
? 'login.codeLogin'.tr
: "login.passwordLogin".tr,
style: theme.textTheme.bodySmall?.copyWith(
fontSize: 13.sp,
color: const Color(0xFF666666),
fontWeight: FontWeight.w500,
fontFamily: 'AlibabaPuHuiTi-Medium',
),
),
),
],
),
);
}
/// 构建下一步按钮
Widget _buildNextButton(String text, ThemeData theme) {
return TextButton(
onPressed: () {
switch (controller.kr_loginStatus.value) {
case KRLoginProgressStatus.kr_check:
controller.kr_check();
break;
case KRLoginProgressStatus.kr_loginByCode:
case KRLoginProgressStatus.kr_loginByPsd:
controller.kr_login();
break;
case KRLoginProgressStatus.kr_registerSendCode:
controller.kr_checkCode();
break;
case KRLoginProgressStatus.kr_registerSetPsd:
controller.kr_register();
break;
case KRLoginProgressStatus.kr_forgetPsdSendCode:
controller.kr_checkCode();
break;
case KRLoginProgressStatus.kr_forgetPsdSetPsd:
controller.kr_setNewPsdByForgetPsd();
break;
}
},
style: TextButton.styleFrom(
padding: EdgeInsets.zero,
minimumSize: Size.zero,
tapTargetSize: MaterialTapTargetSize.shrinkWrap,
),
child: Container(
width: double.infinity,
height: 52.w,
decoration: BoxDecoration(
color: const Color(0xFF1797FF),
borderRadius: BorderRadius.circular(12.r),
boxShadow: [
BoxShadow(
color: const Color(0xFF1797FF).withOpacity(0.3),
blurRadius: 8.r,
offset: Offset(0, 4.w),
),
],
),
alignment: Alignment.center,
child: Text(
text,
style: TextStyle(
fontSize: 17.sp,
color: Colors.white,
fontWeight: FontWeight.w600,
letterSpacing: 0.5,
fontFamily: 'AlibabaPuHuiTi-Medium',
),
),
),
);
}
///
Widget _buildIcon(String name) {
return KrLocalImage(
imageName: name,
width: 20.w,
height: 20.w,
);
}
/// 修改区域选择器样式
Widget _buildChoiceCode(ThemeData theme) {
return GestureDetector(
onTap: () {
KRSearchAreaView.show((KRAreaCodeItem selectedArea, int index) {
controller.kr_cutSeleteCodeIndex.value = index;
});
},
child: Container(
padding: EdgeInsets.symmetric(horizontal: 12.w),
child: Row(
mainAxisSize: MainAxisSize.min,
children: [
Obx(() => Text(
controller.kr_areaCodeList[controller.kr_cutSeleteCodeIndex.value].kr_icon,
style: theme.textTheme.bodyMedium?.copyWith(
fontSize: 28.sp,
fontFamily: 'AlibabaPuHuiTi-Regular',
fontWeight: FontWeight.w400,
height: 1.40,
),
)),
SizedBox(width: 8.w),
Obx(() => Text(
'+${controller.kr_areaCodeList[controller.kr_cutSeleteCodeIndex.value].kr_dialCode}',
style: theme.textTheme.bodyMedium?.copyWith(
fontSize: 15.sp,
fontFamily: 'AlibabaPuHuiTi-Regular',
fontWeight: FontWeight.w400,
height: 1.40,
),
)),
SizedBox(width: 4.w),
Icon(
Icons.keyboard_arrow_down,
color: theme.textTheme.bodyMedium?.color,
size: 20.w,
),
],
),
),
);
}
/// 通用文本样式
TextStyle _commonTextStyle({
required double fontSize,
FontWeight fontWeight = FontWeight.w400,
Color? color,
}) {
return KrAppTextStyle(
fontSize: fontSize,
fontWeight: fontWeight,
color: color,
);
}
/// 构建标题文本
Widget _buildHeaderText(String text, ThemeData theme) {
return Text(
text,
style: theme.textTheme.headlineMedium?.copyWith(
fontSize: 24.sp,
fontFamily: 'AlibabaPuHuiTi-Bold',
color: theme.textTheme.bodyMedium?.color,
height: 1.3,
),
);
}
Widget _buildInviteCodeInput(ThemeData theme) {
return Container(
width: double.infinity,
padding: EdgeInsets.symmetric(horizontal: 12.w),
height: 52.w,
decoration: ShapeDecoration(
color: theme.cardColor,
shape: RoundedRectangleBorder(
side: BorderSide(width: 0.5, color: const Color(0xFFD2D2D2)),
borderRadius: BorderRadius.circular(10.r),
),
),
child: Row(
children: [
_buildIcon("login_psd"),
SizedBox(width: 8.w),
Expanded(
child: TextField(
controller: controller.inviteCodeController,
decoration: InputDecoration(
hintText: AppTranslations.kr_login.enterInviteCode,
hintStyle: theme.textTheme.bodySmall?.copyWith(
fontSize: 14.sp,
fontFamily: 'AlibabaPuHuiTi-Regular',
),
border: InputBorder.none,
),
style: theme.textTheme.bodyMedium?.copyWith(
fontSize: 14.sp,
fontFamily: 'AlibabaPuHuiTi-Regular',
),
),
),
Obx(() => Visibility(
visible: controller.kr_inviteCodeHasText.value,
child: GestureDetector(
onTap: () {
controller.inviteCodeController.clear();
},
child: Container(
height: double.infinity,
padding: EdgeInsets.only(left: 5.w, right: 5.w),
child: _buildIcon("login_close"),
),
),
)),
],
),
);
}
Widget _buildBackButton(ThemeData theme) {
return GestureDetector(
onTap: () {
controller.kr_back();
},
child: Padding(
padding: EdgeInsets.fromLTRB(0, 20.w, 0, 0),
child: Row(
children: [
Icon(
size: 16.w,
Icons.arrow_back_ios_sharp,
color: theme.textTheme.bodyMedium?.color,
),
SizedBox(width: 4.w),
Text(
AppTranslations.kr_login.back,
textAlign: TextAlign.center,
style: theme.textTheme.bodySmall?.copyWith(
fontSize: 14.sp,
fontFamily: 'AlibabaPuHuiTi-Medium',
fontWeight: FontWeight.w500,
color: theme.textTheme.bodyMedium?.color,
height: 1.60,
),
),
],
),
),
);
}
Widget _buildPhoneInput(BuildContext context, ThemeData theme) {
return Container(
height: 52.w,
padding: EdgeInsets.symmetric(horizontal: 12.w),
decoration: ShapeDecoration(
color: theme.cardColor,
shape: RoundedRectangleBorder(
side: BorderSide(width: 0.5, color: const Color(0xFFD2D2D2)),
borderRadius: BorderRadius.circular(10.r),
),
),
child: Row(
children: [
_buildIcon("login_account"),
SizedBox(width: 8.w),
Expanded(
child: Focus(
onFocusChange: (hasFocus) {
if (hasFocus) {
controller.kr_accountFocusNode.requestFocus();
}
},
child: TextField(
focusNode: controller.kr_accountFocusNode,
controller: controller.accountController,
keyboardType: TextInputType.phone,
decoration: InputDecoration(
hintText: 'login.enterEmailOrPhone'.tr,
hintStyle: theme.textTheme.bodySmall?.copyWith(
fontSize: 14.sp,
fontFamily: 'AlibabaPuHuiTi-Regular',
),
border: InputBorder.none,
),
style: theme.textTheme.bodyMedium?.copyWith(
fontSize: 14.sp,
fontFamily: 'AlibabaPuHuiTi-Regular',
),
),
),
),
_buildClearButton(),
],
),
);
}
Widget _buildClearButton() {
return Obx(() => Visibility(
visible: controller.kr_accountHasText.value,
child: GestureDetector(
onTap: () {
controller.accountController.clear();
},
child: Container(
height: double.infinity,
padding: EdgeInsets.only(left: 5.w, right: 5.w),
child: _buildIcon("login_close"),
),
),
));
}
Widget _buildAreaSelector(ThemeData theme) {
return GestureDetector(
behavior: HitTestBehavior.opaque,
onTap: () {
KRSearchAreaView.show((KRAreaCodeItem selectedArea, int index) {
controller.kr_cutSeleteCodeIndex.value = index;
});
},
child: Container(
height: 52.w,
decoration: ShapeDecoration(
color: theme.cardColor,
shape: RoundedRectangleBorder(
side: BorderSide(width: 0.5, color: const Color(0xFFD2D2D2)),
borderRadius: BorderRadius.circular(10.r),
),
),
child: _buildChoiceCode(theme),
),
);
}
}