完善游客模式登录 并且新增设备管理

This commit is contained in:
2025-10-17 21:11:40 +08:00
parent 2333ad52a9
commit de9cf751f3
46 changed files with 4590 additions and 543 deletions
@@ -9,6 +9,7 @@ import 'package:kaer_with_panels/app/model/kr_area_code.dart';
import 'package:kaer_with_panels/app/utils/kr_common_util.dart';
import 'package:kaer_with_panels/app/localization/app_translations.dart';
import 'package:kaer_with_panels/app/utils/kr_event_bus.dart';
import 'package:kaer_with_panels/app/services/kr_site_config_service.dart';
import '../../../localization/kr_language_utils.dart';
@@ -125,9 +126,9 @@ class KRLoginController extends GetxController
String kr_getNextBtnText() {
switch (kr_loginStatus.value) {
case KRLoginProgressStatus.kr_check:
return AppTranslations.kr_login.next;
return AppTranslations.kr_login.passwordLogin; // 显示"登录"
case KRLoginProgressStatus.kr_loginByCode:
return AppTranslations.kr_login.codeLogin;
return AppTranslations.kr_login.passwordLogin; // 已废弃,保留以防兼容性问题
case KRLoginProgressStatus.kr_loginByPsd:
return AppTranslations.kr_login.passwordLogin;
case KRLoginProgressStatus.kr_registerSendCode:
@@ -198,25 +199,17 @@ class KRLoginController extends GetxController
}
});
// 修改 accountController 监听器
// accountController 监听器(仅支持邮箱)
accountController.addListener(() {
String input = accountController.text.trim();
// 延迟执行状态更新,避免在输入过程中频繁切换
// 延迟执行状态更新
Future.microtask(() {
final isNumeric = _isNumeric(input);
if (isNumeric && kr_loginType.value != KRLoginType.kr_telephone) {
kr_loginType.value = KRLoginType.kr_telephone;
kr_emailList.clear();
kr_removeOverlay();
} else if (!isNumeric && kr_loginType.value != KRLoginType.kr_email) {
kr_loginType.value = KRLoginType.kr_email;
}
// 始终保持邮箱类型
kr_loginType.value = KRLoginType.kr_email;
// 只在邮箱模式下更新邮箱列表
if (!isNumeric) {
kr_emailList.value = kr_generateAndSortEmailList(input);
}
// 更新邮箱建议列表
kr_emailList.value = kr_generateAndSortEmailList(input);
kr_accountHasText.value = input.isNotEmpty;
});
@@ -259,40 +252,29 @@ class KRLoginController extends GetxController
return numericRegex.hasMatch(input);
}
/// 检查是否注册
/// 直接登录(不再检查是否注册
void kr_check() async {
if (accountController.text.isEmpty) {
KRCommonUtil.kr_showToast(AppTranslations.kr_login.enterAccount);
return;
}
final either = await KRAuthApi().kr_isRegister(
kr_loginType.value,
accountController.text,
kr_loginType == KRLoginType.kr_telephone
? kr_areaCodeList[kr_cutSeleteCodeIndex.value].kr_dialCode
: null);
either.fold((l) {
KRCommonUtil.kr_showToast(l.msg);
}, (r) async {
kr_isRegistered.value = r;
kr_loginStatus.value = r
? KRLoginProgressStatus.kr_loginByPsd
: KRLoginProgressStatus.kr_registerSendCode;
});
if (psdController.text.isEmpty) {
KRCommonUtil.kr_showToast(AppTranslations.kr_login.enterPassword);
return;
}
// 直接调用登录
kr_login();
}
/// 发送验证码
/// 发送验证码(仅支持邮箱)
void kr_sendCode() async {
final either = await KRAuthApi().kr_sendCode(
kr_loginType.value,
accountController.text,
kr_areaCodeList[kr_cutSeleteCodeIndex.value].kr_dialCode,
kr_loginStatus.value == KRLoginProgressStatus.kr_registerSendCode
? 1
: kr_loginStatus.value == KRLoginProgressStatus.kr_forgetPsdSendCode
? 2
: 2);
? 2 // 注册验证码类型为2
: 3); // 重置密码验证码类型为3
either.fold((l) {
KRCommonUtil.kr_showToast(l.msg);
}, (r) async {
@@ -301,28 +283,15 @@ class KRLoginController extends GetxController
});
}
/// 开始登录
/// 开始登录(仅支持邮箱+密码)
void kr_login() async {
if (kr_loginStatus == KRLoginProgressStatus.kr_loginByCode &&
codeController.text.isEmpty) {
KRCommonUtil.kr_showToast(AppTranslations.kr_login.enterCode);
return;
}
if (kr_loginStatus == KRLoginProgressStatus.kr_loginByPsd &&
psdController.text.isEmpty) {
if (psdController.text.isEmpty) {
KRCommonUtil.kr_showToast(AppTranslations.kr_login.enterPassword);
return;
}
final either = await KRAuthApi().kr_login(
kr_loginType.value,
kr_loginStatus.value == KRLoginProgressStatus.kr_loginByPsd,
accountController.text,
kr_loginType == KRLoginType.kr_telephone
? kr_areaCodeList[kr_cutSeleteCodeIndex.value].kr_dialCode
: null,
codeController.text,
psdController.text);
either.fold((l) {
KRCommonUtil.kr_showToast(l.msg);
@@ -331,8 +300,14 @@ class KRLoginController extends GetxController
});
}
/// 开始注册
/// 开始注册(仅支持邮箱,验证码和邀请码可选)
void kr_register() async {
// 验证邮箱
if (accountController.text.isEmpty) {
KRCommonUtil.kr_showToast(AppTranslations.kr_login.enterAccount);
return;
}
if (psdController.text.isEmpty) {
KRCommonUtil.kr_showToast(AppTranslations.kr_login.enterPassword);
return;
@@ -346,20 +321,26 @@ class KRLoginController extends GetxController
return;
}
// 检查是否需要验证码(基于站点配置)
final siteConfig = KRSiteConfigService();
final needVerification = siteConfig.isEmailVerificationEnabled() ||
siteConfig.isRegisterVerificationEnabled();
if (needVerification && codeController.text.isEmpty) {
KRCommonUtil.kr_showToast(AppTranslations.kr_login.enterCode);
return;
}
final either = await KRAuthApi().kr_register(
kr_loginType.value,
accountController.text,
kr_loginType == KRLoginType.kr_telephone
? kr_areaCodeList[kr_cutSeleteCodeIndex.value].kr_dialCode
: null,
codeController.text,
psdController.text,
inviteCode: inviteCodeController.text);
code: codeController.text.isEmpty ? null : codeController.text,
inviteCode: inviteCodeController.text.isEmpty ? null : inviteCodeController.text);
either.fold((l) {
KRCommonUtil.kr_showToast(l.msg);
}, (r) async {
_saveLoginData(r);
KRCommonUtil.kr_showToast(AppTranslations.kr_login.registerSuccess);
KRCommonUtil.kr_showToast(AppTranslations.kr_login.registerSuccess);
});
}
@@ -390,20 +371,17 @@ class KRLoginController extends GetxController
}
}
/// 验证验证码
/// 验证验证码(仅支持邮箱)
void kr_checkVerificationCode(KRLoginProgressStatus status) async {
final either = await KRAuthApi().kr_checkVerificationCode(
kr_loginType.value,
accountController.text,
kr_areaCodeList[kr_cutSeleteCodeIndex.value].kr_dialCode,
codeController.text,
kr_loginStatus.value == KRLoginProgressStatus.kr_registerSendCode
? 1
: 2);
? 2 // 注册验证码类型为2
: 3); // 重置密码验证码类型为3
either.fold((l) {
KRCommonUtil.kr_showToast(l.msg);
}, (r) async {
if (status == KRLoginProgressStatus.kr_registerSendCode) {
kr_loginStatus.value = KRLoginProgressStatus.kr_registerSetPsd;
} else if (status == KRLoginProgressStatus.kr_forgetPsdSendCode) {
@@ -412,7 +390,7 @@ class KRLoginController extends GetxController
});
}
/// 忘记密码--- 设置新密码
/// 忘记密码-设置新密码(仅支持邮箱)
void kr_setNewPsdByForgetPsd() async {
if (psdController.text.isEmpty) {
KRCommonUtil.kr_showToast(AppTranslations.kr_login.enterPassword);
@@ -428,11 +406,7 @@ class KRLoginController extends GetxController
}
final either = await KRAuthApi().kr_setNewPsdByForgetPsd(
kr_loginType.value,
accountController.text,
kr_loginType == KRLoginType.kr_telephone
? kr_areaCodeList[kr_cutSeleteCodeIndex.value].kr_dialCode
: null,
codeController.text,
psdController.text);
either.fold((l) {
@@ -464,15 +438,13 @@ class KRLoginController extends GetxController
});
}
/// 设置登录数据
/// 设置登录数据(仅支持邮箱)
void _saveLoginData(String token) {
KRAppRunData.getInstance().kr_saveUserInfo(
token,
accountController.text,
kr_loginType.value,
kr_loginType == KRLoginType.kr_telephone
? kr_areaCodeList[kr_cutSeleteCodeIndex.value].kr_dialCode
: null);
KRLoginType.kr_email,
null);
kr_loginStatus.value = KRLoginProgressStatus.kr_check;
// 登录/注册成功后,发送消息触发订阅服务刷新
@@ -480,6 +452,9 @@ class KRLoginController extends GetxController
Future.delayed(Duration(milliseconds: 100), () {
KREventBus().kr_sendMessage(KRMessageType.kr_payment);
});
// 登录成功后返回到上一页
Get.back();
}
/// 根据输入内容匹配邮箱
@@ -611,6 +586,14 @@ class KRLoginController extends GetxController
// }
}
@override
void onReady() {
super.onReady();
// 每次打开登录页面时,重置为登录状态(而不是注册状态)
// 这样确保点击"登录/注册"按钮时始终显示登录页面
kr_loginStatus.value = KRLoginProgressStatus.kr_check;
}
@override
void onClose() {
kr_removeOverlay();
@@ -640,13 +623,9 @@ class KRLoginController extends GetxController
void _updateInputState() {
String input = accountController.text.trim();
if (_isNumeric(input)) {
kr_loginType.value = KRLoginType.kr_telephone;
kr_emailList.clear();
} else {
kr_loginType.value = KRLoginType.kr_email;
kr_emailList.value = kr_generateAndSortEmailList(input);
}
// 始终保持邮箱类型
kr_loginType.value = KRLoginType.kr_email;
kr_emailList.value = kr_generateAndSortEmailList(input);
}
// 添加移除悬浮框的方法
+435 -46
View File
@@ -14,6 +14,7 @@ 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';
import 'package:kaer_with_panels/app/services/kr_site_config_service.dart';
class KRLoginView extends GetView<KRLoginController> {
const KRLoginView({super.key});
@@ -21,15 +22,16 @@ class KRLoginView extends GetView<KRLoginController> {
@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,
return Scaffold(
backgroundColor: theme.scaffoldBackgroundColor,
body: GestureDetector(
behavior: HitTestBehavior.translucent,
onTap: () {
if (!FocusScope.of(context).hasPrimaryFocus) {
FocusScope.of(context).unfocus();
}
_hideDropdown();
},
child: SingleChildScrollView(
padding: EdgeInsets.symmetric(horizontal: 20.w),
child: Obx(() {
@@ -58,16 +60,18 @@ class KRLoginView extends GetView<KRLoginController> {
}
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)),
)),
// 总是显示返回按钮,包括 kr_check 状态
_buildBackButton(Theme.of(context)),
_buildHeaderSection(Theme.of(context)),
// 邮箱输入框
_buildInputSection(context, Theme.of(context)),
SizedBox(height: 8.w),
// 密码输入框
_buildPasswordInput(Theme.of(context)),
_buildDynamicContent(Theme.of(context)),
_buildNextButton(controller.kr_getNextBtnText(), Theme.of(context)),
SizedBox(height: _getBottomPadding()),
@@ -75,6 +79,63 @@ class KRLoginView extends GetView<KRLoginController> {
);
}
/// 构建密码输入框(专用于 kr_check 状态)
Widget _buildPasswordInput(ThemeData theme) {
return 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: _buildIcon("login_psd"),
),
SizedBox(width: 8.w),
Expanded(
child: Obx(() => TextField(
controller: controller.psdController,
obscureText: controller.kr_obscureText.value,
keyboardType: TextInputType.text,
decoration: InputDecoration(
hintText: '请输入密码',
hintStyle: theme.textTheme.bodySmall?.copyWith(
fontSize: 14.sp,
fontFamily: 'AlibabaPuHuiTi-Regular',
),
border: InputBorder.none,
contentPadding: EdgeInsets.symmetric(vertical: 16.w),
suffixIcon: 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',
),
)),
),
],
),
);
}
/// 获取底部间距
double _getBottomPadding() {
switch (controller.kr_loginStatus.value) {
@@ -98,10 +159,7 @@ class KRLoginView extends GetView<KRLoginController> {
return Column(
mainAxisSize: MainAxisSize.min,
children: [
Obx(() => Visibility(
visible: controller.kr_loginStatus.value != KRLoginProgressStatus.kr_check,
child: _buildBackButton(Theme.of(context)),
)),
_buildBackButton(Theme.of(context)),
_buildHeaderSection(Theme.of(context)),
_buildInputSection(context, Theme.of(context)),
_buildDynamicContent(Theme.of(context)),
@@ -116,10 +174,7 @@ class KRLoginView extends GetView<KRLoginController> {
return Column(
mainAxisSize: MainAxisSize.min,
children: [
Obx(() => Visibility(
visible: controller.kr_loginStatus.value != KRLoginProgressStatus.kr_check,
child: _buildBackButton(Theme.of(context)),
)),
_buildBackButton(Theme.of(context)),
_buildHeaderSection(Theme.of(context)),
_buildInputSection(context, Theme.of(context)),
_buildDynamicContent(Theme.of(context)),
@@ -130,18 +185,29 @@ class KRLoginView extends GetView<KRLoginController> {
}
Widget _buildRegisterSendCodeView(BuildContext context) {
// 构建注册发送验证码视图的代码
// 构建单页注册视图 - 所有字段显示在一个页面
final theme = Theme.of(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)),
_buildBackButton(theme),
_buildHeaderSection(theme),
// 邮箱输入框
_buildRegistrationEmailInput(theme),
SizedBox(height: 8.w),
// 验证码输入框(根据站点配置决定是否显示,包括底部间距)
_buildRegistrationCodeInputWithSpacing(theme),
// 密码输入框
_buildRegistrationPasswordInput(theme),
SizedBox(height: 8.w),
// 确认密码输入框
_buildRegistrationConfirmPasswordInput(theme),
SizedBox(height: 8.w),
// 邀请码输入框(可选)
_buildInviteCodeInput(theme),
SizedBox(height: 17.w),
// 注册按钮
_buildNextButton('注册账号', theme),
SizedBox(height: _getBottomPadding()),
],
);
@@ -152,10 +218,7 @@ class KRLoginView extends GetView<KRLoginController> {
return Column(
mainAxisSize: MainAxisSize.min,
children: [
Obx(() => Visibility(
visible: controller.kr_loginStatus.value != KRLoginProgressStatus.kr_check,
child: _buildBackButton(Theme.of(context)),
)),
_buildBackButton(Theme.of(context)),
_buildHeaderSection(Theme.of(context)),
_buildInputSection(context, Theme.of(context)),
Column(
@@ -178,10 +241,7 @@ class KRLoginView extends GetView<KRLoginController> {
return Column(
mainAxisSize: MainAxisSize.min,
children: [
Obx(() => Visibility(
visible: controller.kr_loginStatus.value != KRLoginProgressStatus.kr_check,
child: _buildBackButton(Theme.of(context)),
)),
_buildBackButton(Theme.of(context)),
_buildHeaderSection(Theme.of(context)),
_buildInputSection(context, Theme.of(context)),
_buildDynamicContent(Theme.of(context)),
@@ -196,10 +256,7 @@ class KRLoginView extends GetView<KRLoginController> {
return Column(
mainAxisSize: MainAxisSize.min,
children: [
Obx(() => Visibility(
visible: controller.kr_loginStatus.value != KRLoginProgressStatus.kr_check,
child: _buildBackButton(Theme.of(context)),
)),
_buildBackButton(Theme.of(context)),
_buildHeaderSection(Theme.of(context)),
_buildInputSection(context, Theme.of(context)),
if (controller.kr_loginStatus.value == KRLoginProgressStatus.kr_forgetPsdSetPsd)
@@ -670,7 +727,8 @@ class KRLoginView extends GetView<KRLoginController> {
Widget? content;
switch (controller.kr_loginStatus.value) {
case KRLoginProgressStatus.kr_check:
content = _buildAgreementText(theme);
// 在登录状态显示"忘记密码"和切换按钮
content = _buildLoginBtns(theme);
case KRLoginProgressStatus.kr_loginByCode:
case KRLoginProgressStatus.kr_loginByPsd:
content = _buildLoginBtns(theme);
@@ -744,6 +802,34 @@ class KRLoginView extends GetView<KRLoginController> {
/// 构建登录按钮行
Widget _buildLoginBtns(ThemeData theme) {
// 在 kr_check 状态下显示不同的按钮
if (controller.kr_loginStatus.value == KRLoginProgressStatus.kr_check) {
return SizedBox(
height: 24.w,
child: Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
_buildHoverableTextButton(
text: 'login.forgotPassword'.tr,
onTap: () => controller.kr_loginStatus.value =
KRLoginProgressStatus.kr_forgetPsdSendCode,
theme: theme,
),
SizedBox(width: 16.w),
_buildHoverableTextButton(
text: '点我注册',
onTap: () {
// 跳转到注册页面
controller.kr_loginStatus.value = KRLoginProgressStatus.kr_registerSendCode;
},
theme: theme,
),
],
),
);
}
// 其他状态保持原有逻辑
return SizedBox(
height: 24.w,
child: Row(
@@ -802,7 +888,8 @@ class KRLoginView extends GetView<KRLoginController> {
controller.kr_login();
break;
case KRLoginProgressStatus.kr_registerSendCode:
controller.kr_checkCode();
// 直接调用注册,不再需要多步骤
controller.kr_register();
break;
case KRLoginProgressStatus.kr_registerSetPsd:
controller.kr_register();
@@ -981,8 +1068,21 @@ class KRLoginView extends GetView<KRLoginController> {
Widget _buildBackButton(ThemeData theme) {
return GestureDetector(
behavior: HitTestBehavior.opaque,
onTap: () {
controller.kr_back();
print('👆 返回按钮被点击了!');
print('👆 当前登录状态: ${controller.kr_loginStatus.value}');
// 只有在初始登录状态(kr_check)时,返回按钮才返回主页
// 其他所有状态(包括注册页面)都返回到上一步
if (controller.kr_loginStatus.value == KRLoginProgressStatus.kr_check) {
print('👆 调用 Get.back() 返回主页');
Get.back();
print('👆 Get.back() 调用完成');
} else {
// 其他状态:返回到上一步(例如从注册页返回登录页)
print('👆 调用 controller.kr_back() 返回上一步');
controller.kr_back();
}
},
child: Padding(
padding: EdgeInsets.fromLTRB(0, 20.w, 0, 0),
@@ -1095,4 +1195,293 @@ class KRLoginView extends GetView<KRLoginController> {
),
);
}
/// 构建可悬停的文本按钮
Widget _buildHoverableTextButton({
required String text,
required VoidCallback onTap,
required ThemeData theme,
}) {
return MouseRegion(
cursor: SystemMouseCursors.click,
child: StatefulBuilder(
builder: (context, setState) {
bool isHovering = false;
return MouseRegion(
onEnter: (_) => setState(() => isHovering = true),
onExit: (_) => setState(() => isHovering = false),
child: GestureDetector(
onTap: onTap,
behavior: HitTestBehavior.opaque,
child: Text(
text,
style: theme.textTheme.bodySmall?.copyWith(
fontSize: 13.sp,
color: isHovering ? const Color(0xFF1796FF) : const Color(0xFF666666),
fontWeight: FontWeight.w500,
fontFamily: 'AlibabaPuHuiTi-Medium',
),
),
),
);
},
),
);
}
/// ========== 注册页面相关组件 ==========
/// 构建注册页面的邮箱输入框
Widget _buildRegistrationEmailInput(ThemeData theme) {
return 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: _buildIcon("login_account"),
),
SizedBox(width: 8.w),
Expanded(
child: TextField(
controller: controller.accountController,
keyboardType: TextInputType.emailAddress,
decoration: InputDecoration(
hintText: 'login.enterEmail'.tr,
hintStyle: theme.textTheme.bodySmall?.copyWith(
fontSize: 14.sp,
fontFamily: 'AlibabaPuHuiTi-Regular',
),
border: InputBorder.none,
contentPadding: EdgeInsets.symmetric(vertical: 16.w),
),
style: theme.textTheme.bodyMedium?.copyWith(
fontSize: 14.sp,
fontFamily: 'AlibabaPuHuiTi-Regular',
),
),
),
Obx(() => Visibility(
visible: controller.kr_accountHasText.value,
child: GestureDetector(
onTap: () => controller.accountController.clear(),
child: Container(
height: double.infinity,
padding: EdgeInsets.symmetric(horizontal: 8.w),
child: _buildIcon("login_close"),
),
),
)),
],
),
);
}
/// 构建注册页面的验证码输入框(包含间距)
Widget _buildRegistrationCodeInputWithSpacing(ThemeData theme) {
// 从站点配置服务获取验证配置(站点配置不是响应式的,不需要 Obx)
final siteConfig = KRSiteConfigService();
final needVerification = siteConfig.isEmailVerificationEnabled() ||
siteConfig.isRegisterVerificationEnabled();
// 如果不需要验证码,返回空容器
if (!needVerification) {
return SizedBox.shrink();
}
// 显示验证码输入框和底部间距
return Column(
mainAxisSize: MainAxisSize.min,
children: [
_buildRegistrationCodeInput(theme),
SizedBox(height: 8.w),
],
);
}
/// 构建注册页面的验证码输入框(根据站点配置显示)
Widget _buildRegistrationCodeInput(ThemeData theme) {
// 从站点配置服务获取验证配置
final siteConfig = KRSiteConfigService();
final needVerification = siteConfig.isEmailVerificationEnabled() ||
siteConfig.isRegisterVerificationEnabled();
// 如果不需要验证码,返回空容器
if (!needVerification) {
return SizedBox.shrink();
}
// 显示验证码输入框
return 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: _buildIcon("login_code"),
),
SizedBox(width: 8.w),
Expanded(
child: TextField(
controller: controller.codeController,
keyboardType: TextInputType.number,
decoration: InputDecoration(
hintText: 'login.enterCode'.tr,
hintStyle: theme.textTheme.bodySmall?.copyWith(
fontSize: 14.sp,
fontFamily: 'AlibabaPuHuiTi-Regular',
),
border: InputBorder.none,
contentPadding: EdgeInsets.symmetric(vertical: 16.w),
),
style: theme.textTheme.bodyMedium?.copyWith(
fontSize: 14.sp,
fontFamily: 'AlibabaPuHuiTi-Regular',
),
),
),
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),
],
),
);
}
/// 构建注册页面的密码输入框
Widget _buildRegistrationPasswordInput(ThemeData theme) {
return 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: _buildIcon("login_psd"),
),
SizedBox(width: 8.w),
Expanded(
child: Obx(() => TextField(
controller: controller.psdController,
obscureText: controller.kr_obscureText.value,
keyboardType: TextInputType.text,
decoration: InputDecoration(
hintText: '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_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',
),
)),
),
],
),
);
}
/// 构建注册页面的确认密码输入框
Widget _buildRegistrationConfirmPasswordInput(ThemeData theme) {
return 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: _buildIcon("login_psd"),
),
SizedBox(width: 8.w),
Expanded(
child: Obx(() => TextField(
controller: controller.agPsdController,
obscureText: controller.kr_obscureText.value,
keyboardType: TextInputType.text,
decoration: InputDecoration(
hintText: 'login.reenterPassword'.tr,
hintStyle: theme.textTheme.bodySmall?.copyWith(
fontSize: 14.sp,
fontFamily: 'AlibabaPuHuiTi-Regular',
),
border: InputBorder.none,
contentPadding: EdgeInsets.symmetric(vertical: 16.w),
suffixIcon: controller.kr_agPsdHasText.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',
),
)),
),
],
),
);
}
}