|
|
@@ -7,6 +7,7 @@ import 'package:sino_med_cloud/core/constants/app_constants.dart';
|
|
|
import 'package:sino_med_cloud/core/utils/toast_utils.dart'; // 添加 ToastUtils 引用
|
|
|
import '../../../core/utils/logger.dart';
|
|
|
import '../../../core/utils/crypto_utils.dart';
|
|
|
+import '../../../core/storage/local_storage.dart';
|
|
|
import '../../MinePage/data/change_password_provider.dart';
|
|
|
import '../../MinePage/presentation/change_password_page.dart';
|
|
|
import '../domain/login_service.dart';
|
|
|
@@ -47,9 +48,57 @@ class _LoginPageState extends ConsumerState<LoginPage>
|
|
|
void initState() {
|
|
|
super.initState();
|
|
|
_tabController = TabController(length: 2, vsync: this);
|
|
|
+ _loadSavedLoginInfo();
|
|
|
+ }
|
|
|
+
|
|
|
+ /// 加载保存的登录信息
|
|
|
+ void _loadSavedLoginInfo() async {
|
|
|
+ try {
|
|
|
+ // 加载保存的手机号
|
|
|
+ final savedPhone = await LocalStorage.getPhone();
|
|
|
+ if (savedPhone != null && savedPhone.isNotEmpty) {
|
|
|
+ _phoneController.text = savedPhone;
|
|
|
+ _phoneSmsController.text = savedPhone;
|
|
|
+ // 同步到 Provider,避免监听器尚未注册导致 Provider 仍为空
|
|
|
+ if (mounted) {
|
|
|
+ ref.read(passwordLoginPhoneProvider.notifier).state = savedPhone;
|
|
|
+ ref.read(smsLoginPhoneProvider.notifier).state = savedPhone;
|
|
|
+ }
|
|
|
+ AppLogger.d('加载保存的手机号: $savedPhone');
|
|
|
+ }
|
|
|
+
|
|
|
+ // 检查是否记住密码
|
|
|
+ final rememberPassword = await LocalStorage.getRememberPassword();
|
|
|
+ if (mounted) {
|
|
|
+ ref.read(rememberPasswordProvider.notifier).state = rememberPassword;
|
|
|
+ // 回到登录页时,强制隐藏密码(无论前一次是否显示)
|
|
|
+ ref.read(passwordObscureProvider.notifier).state = true;
|
|
|
+ }
|
|
|
+ if (rememberPassword) {
|
|
|
+ // 加载保存的密码(原始密码)
|
|
|
+ final savedPassword = await LocalStorage.getPassword();
|
|
|
+ if (savedPassword != null && savedPassword.isNotEmpty) {
|
|
|
+ // 设置密码(但保持隐藏状态)
|
|
|
+ _passwordController.text = savedPassword;
|
|
|
+ // 同步到 Provider,避免监听器尚未注册导致 Provider 仍为空
|
|
|
+ if (mounted) {
|
|
|
+ ref.read(passwordLoginPasswordProvider.notifier).state = savedPassword;
|
|
|
+ }
|
|
|
+ AppLogger.d('加载保存的密码(原始密码)');
|
|
|
+ }
|
|
|
+ }
|
|
|
+ } catch (e) {
|
|
|
+ AppLogger.e('加载保存的登录信息失败', e);
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
void _setupListeners() {
|
|
|
+ // 先强制同步一次当前 Controller 的值到 Provider(避免 _loadSavedLoginInfo 在 listener 注册前完成)
|
|
|
+ ref.read(passwordLoginPhoneProvider.notifier).state = _phoneController.text;
|
|
|
+ ref.read(passwordLoginPasswordProvider.notifier).state = _passwordController.text;
|
|
|
+ ref.read(smsLoginPhoneProvider.notifier).state = _phoneSmsController.text;
|
|
|
+ ref.read(smsLoginCodeProvider.notifier).state = _smsCodeController.text;
|
|
|
+
|
|
|
// 监听 Tab 切换,同步到 Provider
|
|
|
_tabController.addListener(() {
|
|
|
if (!_tabController.indexIsChanging) {
|
|
|
@@ -169,8 +218,9 @@ class _LoginPageState extends ConsumerState<LoginPage>
|
|
|
// 在异步方法中应使用 ref.read
|
|
|
final phoneNumber = ref.read(passwordLoginPhoneProvider);
|
|
|
final password = ref.read(passwordLoginPasswordProvider);
|
|
|
+ final rememberPassword = ref.read(rememberPasswordProvider);
|
|
|
|
|
|
- // 对密码进行 MD5 加密
|
|
|
+ // 每次登录请求时重新加密(不存 MD5)
|
|
|
final encryptedPassword = CryptoUtils.md5(password);
|
|
|
|
|
|
AppLogger.d('开始密码登录请求: $phoneNumber');
|
|
|
@@ -182,7 +232,24 @@ class _LoginPageState extends ConsumerState<LoginPage>
|
|
|
loginType: _loginType,
|
|
|
);
|
|
|
AppLogger.d('密码登录成功,准备跳转主页');
|
|
|
- // 登录成功,跳转到主页
|
|
|
+
|
|
|
+ // 登录成功后,保存手机号(总是保存)
|
|
|
+ await LocalStorage.savePhone(phoneNumber);
|
|
|
+
|
|
|
+ // 根据"记住密码"选项保存或删除密码
|
|
|
+ if (rememberPassword) {
|
|
|
+ // 保存原始密码(登录时再加密)
|
|
|
+ await LocalStorage.savePassword(password);
|
|
|
+ await LocalStorage.saveRememberPassword(true);
|
|
|
+ AppLogger.d('已保存手机号和密码');
|
|
|
+ } else {
|
|
|
+ // 不记住密码时,删除已保存的密码
|
|
|
+ await LocalStorage.removePassword();
|
|
|
+ await LocalStorage.saveRememberPassword(false);
|
|
|
+ AppLogger.d('已保存手机号,删除密码');
|
|
|
+ }
|
|
|
+
|
|
|
+ // 跳转到主页(使用 go 替换当前路由,销毁登录页)
|
|
|
if (mounted) {
|
|
|
context.go('/mainTab');
|
|
|
}
|
|
|
@@ -235,7 +302,7 @@ class _LoginPageState extends ConsumerState<LoginPage>
|
|
|
ref.read(smsHasReceivedProvider.notifier).state = false;
|
|
|
ref.read(smsCodeFromServerProvider.notifier).state = '';
|
|
|
|
|
|
- // 跳转到主页
|
|
|
+ // 跳转到主页(使用 go 替换当前路由,销毁登录页)
|
|
|
if (mounted) {
|
|
|
context.go('/mainTab');
|
|
|
}
|
|
|
@@ -406,32 +473,67 @@ class _LoginPageState extends ConsumerState<LoginPage>
|
|
|
},
|
|
|
),
|
|
|
const SizedBox(height: 8),
|
|
|
- // 忘记密码
|
|
|
- Align(
|
|
|
- alignment: Alignment.centerRight,
|
|
|
- child: TextButton(
|
|
|
- onPressed: () {
|
|
|
- // 跳转到忘记密码页面
|
|
|
- if (mounted) {
|
|
|
- // 打开对话框前重置所有状态,确保每次打开都是干净的
|
|
|
- ref.read(changePwdPhoneProvider.notifier).state = '';
|
|
|
- ref.read(changePwdServerSmsCodeProvider.notifier).state = '';
|
|
|
- ref.read(changePwdPasswordProvider.notifier).state = '';
|
|
|
- ref.read(changePwdPasswordVisibleProvider.notifier).state = false;
|
|
|
- ref.read(changePwdConfirmPasswordProvider.notifier).state = '';
|
|
|
- ref.read(changePwdConfirmPasswordVisibleProvider.notifier).state = false;
|
|
|
- ref.read(changePwdSmsHasSentProvider.notifier).state = false;
|
|
|
- ref.read(changePwdSmsCountdownProvider.notifier).state = 0;
|
|
|
- ref.read(changePwdShowPasswordErrorProvider.notifier).state = false;
|
|
|
-
|
|
|
- showDialog(
|
|
|
- context: context,
|
|
|
- builder: (context) => const ChangePasswordPage(),
|
|
|
+ // 记住密码 + 忘记密码
|
|
|
+ Row(
|
|
|
+ mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
|
|
+ children: [
|
|
|
+ // 记住密码复选框
|
|
|
+ Consumer(
|
|
|
+ builder: (context, ref, child) {
|
|
|
+ final rememberPassword = ref.watch(rememberPasswordProvider);
|
|
|
+ return Row(
|
|
|
+ mainAxisSize: MainAxisSize.min,
|
|
|
+ children: [
|
|
|
+ Checkbox(
|
|
|
+ value: rememberPassword,
|
|
|
+ onChanged: (value) {
|
|
|
+ ref.read(rememberPasswordProvider.notifier).state = value ?? false;
|
|
|
+ },
|
|
|
+ materialTapTargetSize: MaterialTapTargetSize.shrinkWrap,
|
|
|
+ visualDensity: const VisualDensity(horizontal: -4, vertical: -4),
|
|
|
+ ),
|
|
|
+ const SizedBox(width: 4),
|
|
|
+ GestureDetector(
|
|
|
+ onTap: () {
|
|
|
+ ref.read(rememberPasswordProvider.notifier).state = !rememberPassword;
|
|
|
+ },
|
|
|
+ child: Text(
|
|
|
+ l10n.rememberPassword,
|
|
|
+ style: const TextStyle(
|
|
|
+ fontSize: 14,
|
|
|
+ color: Color(0xFF6B7280),
|
|
|
+ ),
|
|
|
+ ),
|
|
|
+ ),
|
|
|
+ ],
|
|
|
);
|
|
|
- }
|
|
|
- },
|
|
|
- child: Text(l10n.forgotPassword),
|
|
|
- ),
|
|
|
+ },
|
|
|
+ ),
|
|
|
+ // 忘记密码
|
|
|
+ TextButton(
|
|
|
+ onPressed: () {
|
|
|
+ // 跳转到忘记密码页面
|
|
|
+ if (mounted) {
|
|
|
+ // 打开对话框前重置所有状态,确保每次打开都是干净的
|
|
|
+ ref.read(changePwdPhoneProvider.notifier).state = '';
|
|
|
+ ref.read(changePwdServerSmsCodeProvider.notifier).state = '';
|
|
|
+ ref.read(changePwdPasswordProvider.notifier).state = '';
|
|
|
+ ref.read(changePwdPasswordVisibleProvider.notifier).state = false;
|
|
|
+ ref.read(changePwdConfirmPasswordProvider.notifier).state = '';
|
|
|
+ ref.read(changePwdConfirmPasswordVisibleProvider.notifier).state = false;
|
|
|
+ ref.read(changePwdSmsHasSentProvider.notifier).state = false;
|
|
|
+ ref.read(changePwdSmsCountdownProvider.notifier).state = 0;
|
|
|
+ ref.read(changePwdShowPasswordErrorProvider.notifier).state = false;
|
|
|
+
|
|
|
+ showDialog(
|
|
|
+ context: context,
|
|
|
+ builder: (context) => const ChangePasswordPage(),
|
|
|
+ );
|
|
|
+ }
|
|
|
+ },
|
|
|
+ child: Text(l10n.forgotPassword),
|
|
|
+ ),
|
|
|
+ ],
|
|
|
),
|
|
|
const SizedBox(height: 24),
|
|
|
// 登录按钮
|