|
|
@@ -1,22 +1,108 @@
|
|
|
import 'package:flutter/material.dart';
|
|
|
+import 'package:flutter_riverpod/flutter_riverpod.dart';
|
|
|
+import 'package:sino_med_cloud/core/network/network_provider.dart';
|
|
|
import 'package:sino_med_cloud/l10n/app_localizations.dart';
|
|
|
+import '../core/constants/app_enum.dart';
|
|
|
import 'router.dart';
|
|
|
import 'theme.dart';
|
|
|
|
|
|
-class SinoMedApp extends StatelessWidget {
|
|
|
+class SinoMedApp extends ConsumerStatefulWidget {
|
|
|
const SinoMedApp({super.key});
|
|
|
|
|
|
@override
|
|
|
+ ConsumerState<SinoMedApp> createState() => _SinoMedAppState();
|
|
|
+}
|
|
|
+
|
|
|
+class _SinoMedAppState extends ConsumerState<SinoMedApp> {
|
|
|
+ @override
|
|
|
Widget build(BuildContext context) {
|
|
|
- return MaterialApp.router(
|
|
|
- title: '中方诊药云',
|
|
|
- theme: AppTheme.light,
|
|
|
- routerConfig: AppRouter.router,
|
|
|
- debugShowCheckedModeBanner: false,
|
|
|
- // 本地化配置
|
|
|
- localizationsDelegates: AppLocalizations.localizationsDelegates,
|
|
|
- supportedLocales: AppLocalizations.supportedLocales,
|
|
|
- locale: const Locale('zh'), // 默认中文
|
|
|
+ // 监听网络状态变化并自动导航
|
|
|
+ // ref.listen 必须在 build 方法中使用
|
|
|
+ ref.listen(networkStatusProvider, (previous, next) {
|
|
|
+ next.whenData((status) {
|
|
|
+ final router = AppRouter.router;
|
|
|
+ try {
|
|
|
+ // 获取当前路由路径
|
|
|
+ // 注意:如果 router 还没准备好,这里可能会报错,所以加了 try-catch
|
|
|
+ final matchList = router.routerDelegate.currentConfiguration.matches;
|
|
|
+ final currentLocation = matchList.isNotEmpty
|
|
|
+ ? matchList.last.matchedLocation
|
|
|
+ : router.routerDelegate.currentConfiguration.uri.path;
|
|
|
+
|
|
|
+ // 判断网络是否正常(WiFi 和移动网络都视为正常)
|
|
|
+ final isNetworkAvailable = status == NetworkStatus.wifi || status == NetworkStatus.mobile;
|
|
|
+
|
|
|
+ if (isNetworkAvailable) {
|
|
|
+ // 网络正常:如果当前在无网络页面,则返回到之前保存的页面
|
|
|
+ if (currentLocation == '/noNetwork') {
|
|
|
+ final previousPath = ref.read(previousPagePathProvider);
|
|
|
+ final targetPath = previousPath ?? '/'; // 如果没有保存的页面,则返回登录页
|
|
|
+
|
|
|
+ // 使用 addPostFrameCallback 避免在构建过程中导航
|
|
|
+ WidgetsBinding.instance.addPostFrameCallback((_) {
|
|
|
+ if (mounted) {
|
|
|
+ router.go(targetPath);
|
|
|
+ // 清除保存的页面路径
|
|
|
+ ref.read(previousPagePathProvider.notifier).state = null;
|
|
|
+ }
|
|
|
+ });
|
|
|
+ }
|
|
|
+ // 如果网络正常且不在无网络页面,则停留在当前页面
|
|
|
+ } else {
|
|
|
+ // 网络不正常(无网络):保存当前页面并导航到无网络页面
|
|
|
+ if (currentLocation != '/noNetwork') {
|
|
|
+ // 保存当前页面路径(如果当前不在无网络页面)
|
|
|
+ ref.read(previousPagePathProvider.notifier).state = currentLocation;
|
|
|
+
|
|
|
+ WidgetsBinding.instance.addPostFrameCallback((_) {
|
|
|
+ if (mounted) {
|
|
|
+ router.go('/noNetwork');
|
|
|
+ }
|
|
|
+ });
|
|
|
+ }
|
|
|
+ }
|
|
|
+ } catch (e) {
|
|
|
+ // 如果无法获取当前路由,根据网络状态直接处理
|
|
|
+ final isNetworkAvailable = status == NetworkStatus.wifi || status == NetworkStatus.mobile;
|
|
|
+ if (!isNetworkAvailable) {
|
|
|
+ WidgetsBinding.instance.addPostFrameCallback((_) {
|
|
|
+ if (mounted) {
|
|
|
+ router.go('/noNetwork');
|
|
|
+ }
|
|
|
+ });
|
|
|
+ }
|
|
|
+ }
|
|
|
+ });
|
|
|
+ });
|
|
|
+
|
|
|
+ final networkAsync = ref.watch(networkStatusProvider);
|
|
|
+
|
|
|
+ return networkAsync.when(
|
|
|
+ loading: () {
|
|
|
+ // Loading 状态显示加载指示器
|
|
|
+ return const MaterialApp(
|
|
|
+ debugShowCheckedModeBanner: false,
|
|
|
+ home: Scaffold(
|
|
|
+ body: Center(child: CircularProgressIndicator()),
|
|
|
+ ),
|
|
|
+ );
|
|
|
+ },
|
|
|
+ error: (error, _) {
|
|
|
+ return _materialApp;
|
|
|
+ },
|
|
|
+ data: (_) {
|
|
|
+ return _materialApp;
|
|
|
+ },
|
|
|
);
|
|
|
}
|
|
|
+
|
|
|
+ MaterialApp get _materialApp => MaterialApp.router(
|
|
|
+ onGenerateTitle: (context) => AppLocalizations.of(context)?.appSubtitle ?? '中方诊药云',
|
|
|
+ theme: AppTheme.light,
|
|
|
+ routerConfig: AppRouter.router,
|
|
|
+ debugShowCheckedModeBanner: false,
|
|
|
+ localizationsDelegates: AppLocalizations.localizationsDelegates,
|
|
|
+ supportedLocales: AppLocalizations.supportedLocales,
|
|
|
+ locale: const Locale('zh'),
|
|
|
+ );
|
|
|
}
|