Template
Core 基础设施:Flavor 三包体系、Drift+SQLCipher 加密数据库 7 拦截器 Dio 网络栈、CrashReporter 崩溃日志、Sealed Failure 错误体系 5 色板主题系统、Auth 认证骨架(Clean Architecture)、Dev Panel、Mock Adapter 通过验证:flutter analyze(0 errors)、flutter test(全绿)、staging APK 74.8MB
36 lines
1.1 KiB
Dart
36 lines
1.1 KiB
Dart
import 'package:flutter/widgets.dart';
|
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
|
import 'package:go_router/go_router.dart';
|
|
import 'package:riverpod_annotation/riverpod_annotation.dart';
|
|
import 'package:sunny_mochi/core/observability/talker_setup.dart';
|
|
import 'package:sunny_mochi/features/auth/presentation/notifiers/auth_status_provider.dart';
|
|
|
|
import 'routes.dart';
|
|
|
|
part 'app_router.g.dart';
|
|
|
|
// 不需要登录即可访问的路径
|
|
const _publicPaths = {'/login'};
|
|
|
|
@Riverpod(keepAlive: true)
|
|
GoRouter appRouter(Ref ref) {
|
|
final auth = ref.read(authStatusProvider);
|
|
|
|
return GoRouter(
|
|
debugLogDiagnostics: true,
|
|
initialLocation: '/home',
|
|
refreshListenable: auth.listenable,
|
|
redirect: (BuildContext context, GoRouterState state) {
|
|
final loggedIn = auth.value;
|
|
final path = state.matchedLocation;
|
|
appTalker.verbose('[Router] path=$path loggedIn=$loggedIn');
|
|
|
|
if (loggedIn == null) return null; // bootstrap 未完成,保持当前
|
|
if (!loggedIn && !_publicPaths.contains(path)) return '/login';
|
|
if (loggedIn && path == '/login') return '/home';
|
|
return null;
|
|
},
|
|
routes: $appRoutes,
|
|
);
|
|
}
|