import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:go_router/go_router.dart'; import '../../shared/widgets/app_scaffold.dart'; import '../../shared/widgets/nav_bar_config.dart'; import 'route_observer.dart'; import '../../features/home/home_page.dart'; import '../../features/messages/message_list_page.dart'; import '../../features/profile/profile_page.dart'; import '../../features/expense/expense_list_page.dart'; import '../../features/expense/expense_create_page.dart'; import '../../features/expense/expense_detail_page.dart'; import '../../features/expense/expense_apply_import_page.dart'; import '../../features/overtime/overtime_apply_list_page.dart'; import '../../features/overtime/overtime_apply_create_page.dart'; import '../../features/overtime/overtime_apply_detail_page.dart'; import '../../features/overtime/overtime_apply_edit_page.dart'; import '../../features/vehicle/vehicle_apply_list_page.dart'; import '../../features/vehicle/vehicle_apply_create_page.dart'; import '../../features/vehicle/vehicle_apply_detail_page.dart'; import '../../features/vehicle/vehicle_apply_edit_page.dart'; import '../../features/outing_log/outing_log_list_page.dart'; import '../../features/outing_log/outing_log_create_page.dart'; import '../../features/outing_log/outing_log_detail_page.dart'; import '../../features/announcement/announcement_list_page.dart'; import '../../features/announcement/announcement_detail_page.dart'; import '../../features/announcement/announcement_create_page.dart'; import '../../features/expense_apply/expense_apply_list_page.dart'; import '../../features/expense_apply/expense_apply_detail_page.dart'; import '../../features/expense_apply/expense_apply_create_page.dart'; import '../../features/expense_apply/expense_apply_edit_page.dart'; import '../../features/expense/expense_edit_page.dart'; import '../../features/report/expense_detail_report_page.dart'; import '../../features/report/overtime_detail_report_page.dart'; import '../../features/report/vehicle_detail_report_page.dart'; import '../../features/report/expense_apply_detail_report_page.dart'; import '../../features/report/outing_log_detail_report_page.dart'; import '../../features/admin/admin_permissions_page.dart'; Widget _addButton(BuildContext context, String route) => GestureDetector( onTap: () => context.push(route), child: const Icon(Icons.add, color: Color(0xFF333333), size: 22), ); void _popToNative() { FocusManager.instance.primaryFocus?.unfocus(); SystemNavigator.pop(); } void _smartBack(BuildContext context) { final r = GoRouter.of(context); if (r.canPop()) { r.pop(); } else { SystemNavigator.pop(); } } GoRouter createAppRouter() => GoRouter( observers: [routeObserver], initialLocation: '/', routes: [ // ── 根 Tab ── GoRoute( path: '/', pageBuilder: (_, _) => const MaterialPage( child: AppScaffold(showTabBar: true, body: HomePage()), ), ), GoRoute( path: '/messages', pageBuilder: (_, _) => const MaterialPage( child: AppScaffold(showTabBar: true, body: MessageListPage()), ), ), GoRoute( path: '/profile', pageBuilder: (_, _) => const MaterialPage( child: AppScaffold(showTabBar: true, body: ProfilePage()), ), ), // ── 费用报销 ── GoRoute( path: '/expense/list', pageBuilder: (context, state) => MaterialPage( key: ValueKey(state.uri.toString()), child: AppScaffold( navConfig: NavBarConfig( showBack: true, showRight: true, rightWidget: _addButton(context, '/expense/create'), onBack: _popToNative, ), body: const ExpenseListPage(), ), ), ), GoRoute( path: '/expense/import-apply', pageBuilder: (context, _) => MaterialPage( child: AppScaffold( navConfig: NavBarConfig( showBack: true, onBack: () => _smartBack(context), ), body: const ExpenseApplyImportPage(), resizeToAvoidBottomInset: false, ), ), ), GoRoute( path: '/expense/create', pageBuilder: (context, state) => MaterialPage( key: ValueKey(state.uri.toString()), canPop: false, child: AppScaffold( navConfig: NavBarConfig(showBack: true), body: ExpenseCreatePage(editId: state.uri.queryParameters['id']), resizeToAvoidBottomInset: false, ), ), ), GoRoute( path: '/expense/detail/:billNo', pageBuilder: (context, state) => MaterialPage( key: ValueKey(state.uri.toString()), child: AppScaffold( navConfig: NavBarConfig( showBack: true, onBack: () => _smartBack(context), ), body: ExpenseDetailPage( billNo: state.pathParameters['billNo']!, queryId: int.tryParse(state.uri.queryParameters['queryId'] ?? '0') ?? 0, ), ), ), ), GoRoute( path: '/expense/edit/:billNo', pageBuilder: (context, state) => MaterialPage( key: ValueKey(state.uri.toString()), child: AppScaffold( navConfig: NavBarConfig( showBack: true, onBack: () => _smartBack(context), ), body: ExpenseEditPage(billNo: state.pathParameters['billNo']!), resizeToAvoidBottomInset: false, ), ), ), // ── 加班 ── GoRoute( path: '/overtime-apply/list', pageBuilder: (context, state) => MaterialPage( key: ValueKey(state.uri.toString()), child: AppScaffold( navConfig: NavBarConfig( showBack: true, showRight: true, rightWidget: _addButton(context, '/overtime-apply/create'), onBack: _popToNative, ), body: const OvertimeApplyListPage(), ), ), ), GoRoute( path: '/overtime-apply/create', pageBuilder: (context, state) => MaterialPage( child: AppScaffold( navConfig: NavBarConfig(showBack: true), body: const OvertimeApplyCreatePage(), ), ), ), GoRoute( path: '/overtime-apply/detail/:billNo', pageBuilder: (context, state) => MaterialPage( child: AppScaffold( navConfig: NavBarConfig( showBack: true, onBack: () => _smartBack(context), ), body: OvertimeApplyDetailPage( billNo: state.pathParameters['billNo']!, ), ), ), ), GoRoute( path: '/overtime-apply/edit/:billNo', pageBuilder: (context, state) => MaterialPage( key: ValueKey(state.uri.toString()), child: AppScaffold( navConfig: NavBarConfig( showBack: true, onBack: () => _smartBack(context), ), body: OvertimeApplyEditPage(billNo: state.pathParameters['billNo']!), resizeToAvoidBottomInset: false, ), ), ), // ── 用车 ── GoRoute( path: '/vehicle-apply/list', pageBuilder: (context, state) => MaterialPage( key: ValueKey(state.uri.toString()), child: AppScaffold( navConfig: NavBarConfig( showBack: true, showRight: true, rightWidget: _addButton(context, '/vehicle-apply/create'), onBack: _popToNative, ), body: const VehicleApplyListPage(), ), ), ), GoRoute( path: '/vehicle-apply/create', pageBuilder: (context, state) => MaterialPage( child: AppScaffold( navConfig: NavBarConfig(showBack: true), body: const VehicleApplyCreatePage(), ), ), ), GoRoute( path: '/vehicle-apply/detail/:billNo', pageBuilder: (context, state) => MaterialPage( child: AppScaffold( navConfig: NavBarConfig( showBack: true, onBack: () => _smartBack(context), ), body: VehicleApplyDetailPage(billNo: state.pathParameters['billNo']!), ), ), ), GoRoute( path: '/vehicle-apply/edit/:billNo', pageBuilder: (context, state) => MaterialPage( child: AppScaffold( navConfig: NavBarConfig(showBack: true), body: VehicleApplyEditPage(billNo: state.pathParameters['billNo']!), ), ), ), GoRoute( path: '/vehicle-apply/edit/:billNo', pageBuilder: (context, state) => MaterialPage( key: ValueKey(state.uri.toString()), child: AppScaffold( navConfig: NavBarConfig( showBack: true, onBack: () => _smartBack(context), ), body: VehicleApplyEditPage(billNo: state.pathParameters['billNo']!), resizeToAvoidBottomInset: false, ), ), ), // ── 外勤日志 ── GoRoute( path: '/outing-log/list', pageBuilder: (context, state) => MaterialPage( key: ValueKey(state.uri.toString()), child: AppScaffold( navConfig: NavBarConfig( showBack: true, showRight: true, rightWidget: _addButton(context, '/outing-log/create'), onBack: _popToNative, ), body: const OutingLogListPage(), ), ), ), GoRoute( path: '/outing-log/create', pageBuilder: (context, _) => MaterialPage( child: AppScaffold( navConfig: NavBarConfig(showBack: true), body: const OutingLogCreatePage(), ), ), ), GoRoute( path: '/outing-log/detail/:id', pageBuilder: (context, state) => MaterialPage( child: AppScaffold( navConfig: NavBarConfig( showBack: true, onBack: () => _smartBack(context), ), body: OutingLogDetailPage(id: state.pathParameters['id']!), ), ), ), // ── 公告 ── GoRoute( path: '/announcement/list', pageBuilder: (context, state) => MaterialPage( key: ValueKey(state.uri.toString()), child: AppScaffold( navConfig: NavBarConfig( showBack: true, showRight: true, rightWidget: _addButton(context, '/announcement/create'), onBack: _popToNative, ), body: const AnnouncementListPage(), ), ), ), GoRoute( path: '/announcement/detail/:id', pageBuilder: (context, state) => MaterialPage( child: AppScaffold( navConfig: NavBarConfig( showBack: true, onBack: () => _smartBack(context), ), body: AnnouncementDetailPage(id: state.pathParameters['id']!), ), ), ), GoRoute( path: '/announcement/create', pageBuilder: (context, _) => MaterialPage( child: AppScaffold( navConfig: NavBarConfig(showBack: true), body: const AnnouncementCreatePage(), ), ), ), // ── 费用申请 ── GoRoute( path: '/expense-apply/list', pageBuilder: (context, state) => MaterialPage( key: ValueKey(state.uri.toString()), child: AppScaffold( navConfig: NavBarConfig( showBack: true, showRight: true, rightWidget: _addButton(context, '/expense-apply/create'), onBack: _popToNative, ), body: const ExpenseApplyListPage(), ), ), ), GoRoute( path: '/expense-apply/detail/:billNo', pageBuilder: (context, state) => MaterialPage( key: ValueKey(state.uri.toString()), child: AppScaffold( navConfig: NavBarConfig( showBack: true, onBack: () => _smartBack(context), ), body: ExpenseApplyDetailPage( billNo: state.pathParameters['billNo']!, queryId: int.tryParse(state.uri.queryParameters['queryId'] ?? '0') ?? 0, ), ), ), ), GoRoute( path: '/expense-apply/create', pageBuilder: (context, state) => MaterialPage( key: ValueKey(state.uri.toString()), canPop: false, child: AppScaffold( navConfig: NavBarConfig(showBack: true), body: ExpenseApplyCreatePage(id: state.uri.queryParameters['id']), resizeToAvoidBottomInset: false, ), ), ), GoRoute( path: '/expense-apply/edit/:billNo', pageBuilder: (context, state) => MaterialPage( key: ValueKey(state.uri.toString()), child: AppScaffold( navConfig: NavBarConfig( showBack: true, onBack: () => _smartBack(context), ), body: ExpenseApplyEditPage(billNo: state.pathParameters['billNo']!), resizeToAvoidBottomInset: false, ), ), ), // ── 报表 ── GoRoute( path: '/report/expense-detail', pageBuilder: (context, _) => MaterialPage( child: AppScaffold( navConfig: NavBarConfig( showBack: true, onBack: () => _smartBack(context), ), body: const ExpenseDetailReportPage(), ), ), ), GoRoute( path: '/report/expense-apply-detail', pageBuilder: (context, _) => MaterialPage( child: AppScaffold( navConfig: NavBarConfig( showBack: true, onBack: () => _smartBack(context), ), body: const ExpenseApplyDetailReportPage(), ), ), ), GoRoute( path: '/report/overtime-apply-detail', pageBuilder: (context, _) => MaterialPage( child: AppScaffold( navConfig: NavBarConfig( showBack: true, onBack: () => _smartBack(context), ), body: const OvertimeDetailReportPage(), ), ), ), GoRoute( path: '/report/vehicle-apply-detail', pageBuilder: (context, _) => MaterialPage( child: AppScaffold( navConfig: NavBarConfig( showBack: true, onBack: () => _smartBack(context), ), body: const VehicleDetailReportPage(), ), ), ), GoRoute( path: '/report/outing-log-detail', pageBuilder: (context, _) => MaterialPage( child: AppScaffold( navConfig: NavBarConfig( showBack: true, onBack: () => _smartBack(context), ), body: const OutingLogDetailReportPage(), ), ), ), // ── 管理 ── GoRoute( path: '/admin/permissions', pageBuilder: (context, _) => MaterialPage( child: AppScaffold( navConfig: NavBarConfig( showBack: true, onBack: () => _smartBack(context), ), body: const AdminPermissionsPage(), ), ), ), ], );