rwadurian/frontend/mobile-app/lib/app.dart

107 lines
3.2 KiB
Dart
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import 'dart:async';
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:go_router/go_router.dart';
import 'core/di/injection_container.dart';
import 'core/theme/app_theme.dart';
import 'core/services/auth_event_service.dart';
import 'core/providers/maintenance_provider.dart';
import 'routes/app_router.dart';
import 'routes/route_paths.dart';
class App extends ConsumerStatefulWidget {
const App({super.key});
@override
ConsumerState<App> createState() => _AppState();
}
class _AppState extends ConsumerState<App> {
StreamSubscription<AuthEvent>? _authEventSubscription;
@override
void initState() {
super.initState();
_listenToAuthEvents();
_initializeMaintenanceProvider();
}
/// 初始化维护状态提供者
void _initializeMaintenanceProvider() {
// 设置全局导航 Key以便在 App 生命周期事件中显示维护弹窗
ref.read(maintenanceProvider.notifier).setNavigatorKey(rootNavigatorKey);
}
@override
void dispose() {
_authEventSubscription?.cancel();
super.dispose();
}
/// 监听认证事件
void _listenToAuthEvents() {
final authEventService = ref.read(authEventServiceProvider);
_authEventSubscription = authEventService.events.listen((event) {
if (event.type == AuthEventType.tokenExpired) {
_handleTokenExpired(event.message);
}
});
}
/// 处理 token 过期
Future<void> _handleTokenExpired(String? message) async {
debugPrint('[App] Token expired, navigating to login page');
// 清除当前账号状态(但保留账号列表和向导页标识)
final multiAccountService = ref.read(multiAccountServiceProvider);
await multiAccountService.logoutCurrentAccount();
// 使用全局 Navigator Key 跳转到登录页面
final navigatorState = rootNavigatorKey.currentState;
if (navigatorState != null) {
// 显示提示消息
if (message != null) {
ScaffoldMessenger.of(navigatorState.context).showSnackBar(
SnackBar(
content: Text(message),
backgroundColor: Colors.orange,
),
);
}
// 跳转到登录页面
navigatorState.context.go(RoutePaths.phoneLogin);
}
}
@override
Widget build(BuildContext context) {
final router = ref.watch(appRouterProvider);
return ScreenUtilInit(
designSize: const Size(360, 800), // 与 UIPro Figma 设计稿一致
minTextAdapt: true,
splitScreenMode: true,
useInheritedMediaQuery: true,
builder: (context, child) {
return MaterialApp.router(
title: '榴莲皇后',
debugShowCheckedModeBanner: false,
theme: AppTheme.light,
routerConfig: router,
builder: (context, widget) {
// 限制系统字体缩放,保持 UI 一致性
return MediaQuery(
data: MediaQuery.of(context).copyWith(
textScaler: TextScaler.noScaling,
),
child: widget!,
);
},
);
},
);
}
}