完善游客模式登录 并且新增设备管理
This commit is contained in:
@@ -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);
|
||||
}
|
||||
|
||||
// 添加移除悬浮框的方法
|
||||
|
||||
@@ -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',
|
||||
),
|
||||
)),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user