import 'dart:ui'; import 'package:flutter/material.dart'; import 'package:shadcn_ui/shadcn_ui.dart'; import 'package:bot_toast/bot_toast.dart'; import 'package:flutter_localizations/flutter_localizations.dart'; import 'package:provider/provider.dart'; import 'package:provider/single_child_widget.dart'; import 'package:shared_preferences/shared_preferences.dart'; import 'core/network/dio_client.dart'; import 'core/storage/local_storage.dart'; import 'core/theme/app_color_scheme.dart'; import 'core/theme/app_theme.dart'; import 'core/event/app_event_bus.dart'; import 'data/services/user_service.dart'; import 'data/services/market_service.dart'; import 'data/services/trade_service.dart'; import 'data/services/asset_service.dart'; import 'data/services/fund_service.dart'; import 'data/services/bonus_service.dart'; import 'providers/auth_provider.dart'; import 'providers/market_provider.dart'; import 'providers/asset_provider.dart'; import 'providers/theme_provider.dart'; import 'ui/pages/auth/login_page.dart'; import 'ui/pages/main/main_page.dart'; import 'ui/pages/onboarding/onboarding_page.dart'; void main() async { // 确保 Flutter 绑定初始化 WidgetsFlutterBinding.ensureInitialized(); // 全局错误处理 - Flutter 框架错误 FlutterError.onError = (FlutterErrorDetails details) { FlutterError.presentError(details); debugPrint('Flutter Error: ${details.exception}'); debugPrint('Stack trace: ${details.stack}'); }; // 全局错误处理 - 异步未捕获错误 PlatformDispatcher.instance.onError = (error, stack) { debugPrint('Uncaught error: $error'); debugPrint('Stack: $stack'); return true; }; Provider.debugCheckInvalidValueType = null; try { await SharedPreferences.getInstance(); await LocalStorage.init(); debugPrint('App initialized successfully'); } catch (e, stack) { debugPrint('Initialization error: $e'); debugPrint('Stack: $stack'); } runApp(const MyApp()); } class MyApp extends StatelessWidget { const MyApp({super.key}); @override Widget build(BuildContext context) { return MultiProvider( providers: _buildProviders(), child: Consumer( builder: (context, themeProvider, _) { return ShadApp.custom( themeMode: themeProvider.themeMode, theme: ShadThemeData( colorScheme: AppColorScheme.lightShad, brightness: Brightness.light, ), darkTheme: ShadThemeData( colorScheme: AppColorScheme.darkShad, brightness: Brightness.dark, ), appBuilder: _buildMaterialApp, ); }, ), ); } List _buildProviders() { final dioClient = DioClient(); return [ // Theme Provider (必须放在最前面) ChangeNotifierProvider( create: (_) => ThemeProvider()..init(), ), // Services Provider.value(value: dioClient), Provider(create: (_) => AppEventBus()), Provider(create: (_) => UserService(dioClient)), Provider(create: (_) => MarketService(dioClient)), Provider(create: (_) => TradeService(dioClient)), Provider(create: (_) => AssetService(dioClient)), Provider(create: (_) => FundService(dioClient)), Provider(create: (_) => BonusService(dioClient)), // State Management ChangeNotifierProvider( create: (ctx) { final authProvider = AuthProvider(ctx.read()); // token 过期时,DioClient 回调 AuthProvider 强制登出 dioClient.onUnauthorized = authProvider.forceLogout; return authProvider; }, ), ChangeNotifierProvider( create: (ctx) => MarketProvider(ctx.read()), ), ChangeNotifierProvider( create: (ctx) => AssetProvider( ctx.read(), ctx.read(), ctx.read(), ), ), ]; } Widget _buildMaterialApp(BuildContext context) { return MaterialApp( debugShowCheckedModeBanner: false, theme: Theme.of(context), localizationsDelegates: const [ GlobalShadLocalizations.delegate, GlobalMaterialLocalizations.delegate, GlobalCupertinoLocalizations.delegate, GlobalWidgetsLocalizations.delegate, ], builder: (context, child) { child = ShadAppBuilder(child: child!); // 配置 BotToast 确保显示在所有内容之上 final botToastBuilder = BotToastInit(); child = botToastBuilder(context, child); return child; }, navigatorObservers: [BotToastNavigatorObserver()], initialRoute: '/', routes: { '/': (context) => const RootPage(), '/login': (context) => const LoginPage(), '/main': (context) => const MainPage(), }, ); } } /// 根页面 - 决定显示引导页还是主页面 class RootPage extends StatelessWidget { const RootPage({super.key}); @override Widget build(BuildContext context) { // 检查是否需要显示引导页 if (!LocalStorage.isOnboardingCompleted) { return OnboardingPage( onComplete: () { Navigator.of(context).pushReplacementNamed('/login'); }, ); } return Consumer( builder: (context, auth, _) { if (auth.isLoading) { return const Scaffold( body: Center(child: CircularProgressIndicator()), ); } return auth.isLoggedIn ? const MainPage() : const LoginPage(); }, ); } }