import 'package:go_router/go_router.dart'; import 'package:im_app/app/di/app_providers.dart'; import 'package:im_app/app/router/app_route_name.dart'; /// 登录守卫 /// /// 在 [GoRouter.redirect] 中调用,返回 null 表示放行,返回路径表示重定向目标。 /// 接收 [AuthNotifier] 而非 [Ref],避免守卫内部依赖 Riverpod,便于单测。 /// /// ## 穷举保护 /// /// 使用 [AppRouteName] 枚举 + switch 分析路由权限,Dart 编译器保证穷举: /// 在 [AppRouteName] 新增枚举值后,此处 switch 未补 case 则编译报错。 /// /// ## 路由权限规则 /// /// | 路由 | 未登录 | 已登录 | /// |------|--------|--------| /// | login | 放行 | 重定向 → chat | /// | 其余 | 重定向 → login | 放行 | /// /// ## storage_sdk 接入后 /// /// 将 [AuthNotifier] 内的 Demo 状态替换为持久化 token,守卫本身无需改动。 String? authGuard(AuthNotifier authNotifier, GoRouterState state) { final isLoggedIn = authNotifier.isLoggedIn; final route = AppRouteName.fromPath(state.matchedLocation); // 路径不在枚举中(理论上不应出现)→ 按受保护处理 if (route == null) return isLoggedIn ? null : AppRouteName.login.path; switch (route) { case AppRouteName.login: // 已登录还在登录页 → 跳聊天页 return isLoggedIn ? AppRouteName.chat.path : null; case AppRouteName.chat: case AppRouteName.chatDetail: case AppRouteName.chatDetailById: case AppRouteName.contact: case AppRouteName.settings: case AppRouteName.settingsTheme: case AppRouteName.settingsEditProfile: case AppRouteName.settingsBlocklist: case AppRouteName.settingsLanguage: case AppRouteName.settingsNetworkDiagnostics: case AppRouteName.settingsAbout: case AppRouteName.chatDBTest: // 受保护路由 → 未登录跳登录页 return isLoggedIn ? null : AppRouteName.login.path; } }