修复优化引起的 demo bug
This commit is contained in:
@@ -59,6 +59,10 @@ class LoginViewModel extends _$LoginViewModel {
|
||||
/// 仅用于演示路由守卫行为,正式 UI 就绪后删除此方法,改用 [login]。
|
||||
/// 正式 [login] 成功后同样需要调用 [AuthNotifier.login] 更新守卫状态。
|
||||
Future<void> demoLogin() async {
|
||||
// 防止连点重入:第一次调用未完成前忽略后续调用
|
||||
if (state.isLoading) return;
|
||||
state = state.copyWith(isLoading: true, error: null);
|
||||
|
||||
try {
|
||||
final storageApi = ref.read(storageSdkProvider);
|
||||
final storageLifeCycle = storageApi as StorageSdkLifecycle;
|
||||
@@ -72,11 +76,15 @@ class LoginViewModel extends _$LoginViewModel {
|
||||
// 先完成 DB 操作,再标记登录状态(失败时不会误标为已登录)
|
||||
await storageLifeCycle.openDatabase(user.uid);
|
||||
final userCompanion = UserDto.fromEntity(user).toCompanion();
|
||||
await storageApi.insert(userCompanion);
|
||||
await storageApi.insertOrReplace(userCompanion);
|
||||
|
||||
// 全部成功后再更新登录状态,触发路由守卫重定向
|
||||
// 注意:login() 触发导航后 provider 随即被 dispose,之后不能再写 state
|
||||
if (!ref.mounted) return;
|
||||
ref.read(authNotifierProvider).login();
|
||||
} catch (e) {
|
||||
// 导航已发生时 provider 已被 dispose,静默丢弃,不再写 state
|
||||
if (!ref.mounted) return;
|
||||
state = state.copyWith(error: e.toString(), isLoading: false);
|
||||
}
|
||||
}
|
||||
@@ -94,15 +102,19 @@ class LoginViewModel extends _$LoginViewModel {
|
||||
.read(loginUseCaseProvider)
|
||||
.execute(email: email, password: password);
|
||||
|
||||
if (!ref.mounted) return;
|
||||
state = state.copyWith(user: user, isLoading: false);
|
||||
} on FormatException catch (e) {
|
||||
// 格式校验失败(UseCase 层抛出)
|
||||
if (!ref.mounted) return;
|
||||
state = state.copyWith(error: e.message, isLoading: false);
|
||||
} on ApiError catch (e) {
|
||||
// 网络 / 服务端错误(Repository → SDK 透传)
|
||||
if (!ref.mounted) return;
|
||||
state = state.copyWith(error: e.displayMessage, isLoading: false);
|
||||
} catch (e) {
|
||||
// 兜底:防止未预期的异常导致 isLoading 死锁
|
||||
if (!ref.mounted) return;
|
||||
state = state.copyWith(error: e.toString(), isLoading: false);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,13 +15,12 @@ class LoginPage extends ConsumerWidget {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context, WidgetRef ref) {
|
||||
// ref.watch 保持 loginViewModelProvider 存活(AutoDispose 需要至少一个监听者)
|
||||
final state = ref.watch(loginViewModelProvider);
|
||||
final s = context.styles;
|
||||
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
title: const Text('登录'),
|
||||
automaticallyImplyLeading: false,
|
||||
),
|
||||
appBar: AppBar(title: const Text('登录'), automaticallyImplyLeading: false),
|
||||
body: Center(
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
@@ -34,7 +33,9 @@ class LoginPage extends ConsumerWidget {
|
||||
),
|
||||
const SizedBox(height: 32),
|
||||
FilledButton(
|
||||
onPressed: () => ref.read(loginViewModelProvider.notifier).demoLogin(),
|
||||
onPressed: state.isLoading
|
||||
? null
|
||||
: () => ref.read(loginViewModelProvider.notifier).demoLogin(),
|
||||
child: const Text('登录'),
|
||||
),
|
||||
],
|
||||
|
||||
Reference in New Issue
Block a user