app.dart 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  1. import 'package:flutter/material.dart';
  2. import 'package:flutter_riverpod/flutter_riverpod.dart';
  3. import 'package:sino_med_cloud/core/network/network_provider.dart';
  4. import 'package:sino_med_cloud/l10n/app_localizations.dart';
  5. import '../core/constants/app_enum.dart';
  6. import 'router.dart';
  7. import 'theme.dart';
  8. class SinoMedApp extends ConsumerStatefulWidget {
  9. const SinoMedApp({super.key});
  10. @override
  11. ConsumerState<SinoMedApp> createState() => _SinoMedAppState();
  12. }
  13. class _SinoMedAppState extends ConsumerState<SinoMedApp> {
  14. @override
  15. Widget build(BuildContext context) {
  16. // 监听网络状态变化并自动导航
  17. // ref.listen 必须在 build 方法中使用
  18. ref.listen(networkStatusProvider, (previous, next) {
  19. next.whenData((status) {
  20. final router = AppRouter.router;
  21. try {
  22. // 获取当前路由路径
  23. // 注意:如果 router 还没准备好,这里可能会报错,所以加了 try-catch
  24. final matchList = router.routerDelegate.currentConfiguration.matches;
  25. final currentLocation = matchList.isNotEmpty
  26. ? matchList.last.matchedLocation
  27. : router.routerDelegate.currentConfiguration.uri.path;
  28. // 判断网络是否正常(WiFi 和移动网络都视为正常)
  29. final isNetworkAvailable = status == NetworkStatus.wifi || status == NetworkStatus.mobile;
  30. if (isNetworkAvailable) {
  31. // 网络正常:如果当前在无网络页面,则返回到之前保存的页面
  32. if (currentLocation == '/noNetwork') {
  33. final previousPath = ref.read(previousPagePathProvider);
  34. final targetPath = previousPath ?? '/'; // 如果没有保存的页面,则返回登录页
  35. // 使用 addPostFrameCallback 避免在构建过程中导航
  36. WidgetsBinding.instance.addPostFrameCallback((_) {
  37. if (mounted) {
  38. router.go(targetPath);
  39. // 清除保存的页面路径
  40. ref.read(previousPagePathProvider.notifier).state = null;
  41. }
  42. });
  43. }
  44. // 如果网络正常且不在无网络页面,则停留在当前页面
  45. } else {
  46. // 网络不正常(无网络):保存当前页面并导航到无网络页面
  47. if (currentLocation != '/noNetwork') {
  48. // 保存当前页面路径(如果当前不在无网络页面)
  49. ref.read(previousPagePathProvider.notifier).state = currentLocation;
  50. WidgetsBinding.instance.addPostFrameCallback((_) {
  51. if (mounted) {
  52. router.go('/noNetwork');
  53. }
  54. });
  55. }
  56. }
  57. } catch (e) {
  58. // 如果无法获取当前路由,根据网络状态直接处理
  59. final isNetworkAvailable = status == NetworkStatus.wifi || status == NetworkStatus.mobile;
  60. if (!isNetworkAvailable) {
  61. WidgetsBinding.instance.addPostFrameCallback((_) {
  62. if (mounted) {
  63. router.go('/noNetwork');
  64. }
  65. });
  66. }
  67. }
  68. });
  69. });
  70. final networkAsync = ref.watch(networkStatusProvider);
  71. return networkAsync.when(
  72. loading: () {
  73. // Loading 状态显示加载指示器
  74. return const MaterialApp(
  75. debugShowCheckedModeBanner: false,
  76. home: Scaffold(
  77. body: Center(child: CircularProgressIndicator()),
  78. ),
  79. );
  80. },
  81. error: (error, _) {
  82. return _materialApp;
  83. },
  84. data: (_) {
  85. return _materialApp;
  86. },
  87. );
  88. }
  89. MaterialApp get _materialApp => MaterialApp.router(
  90. onGenerateTitle: (context) => AppLocalizations.of(context)?.appSubtitle ?? '中方诊药云',
  91. theme: AppTheme.light,
  92. routerConfig: AppRouter.router,
  93. debugShowCheckedModeBanner: false,
  94. localizationsDelegates: AppLocalizations.localizationsDelegates,
  95. supportedLocales: AppLocalizations.supportedLocales,
  96. locale: const Locale('zh'),
  97. );
  98. }