app_router.dart 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105
  1. import 'package:flutter/material.dart';
  2. import 'package:flutter/services.dart';
  3. import 'package:go_router/go_router.dart';
  4. import '../../shared/widgets/app_scaffold.dart';
  5. import '../../shared/widgets/nav_bar_config.dart';
  6. import 'route_observer.dart';
  7. import '../../features/home/home_page.dart';
  8. import '../../features/messages/message_list_page.dart';
  9. import '../../features/profile/profile_page.dart';
  10. import '../../features/expense/expense_list_page.dart';
  11. import '../../features/expense/expense_create_page.dart';
  12. import '../../features/expense/expense_detail_page.dart';
  13. import '../../features/expense/expense_apply_import_page.dart';
  14. import '../../features/overtime/overtime_list_page.dart';
  15. import '../../features/overtime/overtime_create_page.dart';
  16. import '../../features/overtime/overtime_detail_page.dart';
  17. import '../../features/vehicle/vehicle_list_page.dart';
  18. import '../../features/vehicle/vehicle_create_page.dart';
  19. import '../../features/vehicle/vehicle_detail_page.dart';
  20. import '../../features/outing_log/outing_log_list_page.dart';
  21. import '../../features/outing_log/outing_log_create_page.dart';
  22. import '../../features/outing_log/outing_log_detail_page.dart';
  23. import '../../features/announcement/announcement_list_page.dart';
  24. import '../../features/announcement/announcement_detail_page.dart';
  25. import '../../features/announcement/announcement_create_page.dart';
  26. import '../../features/expense_apply/expense_apply_list_page.dart';
  27. import '../../features/expense_apply/expense_apply_detail_page.dart';
  28. import '../../features/expense_apply/expense_apply_create_page.dart';
  29. import '../../features/expense_apply/expense_apply_edit_page.dart';
  30. import '../../features/expense/expense_edit_page.dart';
  31. import '../../features/report/expense_detail_report_page.dart';
  32. import '../../features/report/overtime_detail_report_page.dart';
  33. import '../../features/report/vehicle_detail_report_page.dart';
  34. import '../../features/report/expense_apply_detail_report_page.dart';
  35. import '../../features/report/outing_log_detail_report_page.dart';
  36. import '../../features/admin/admin_permissions_page.dart';
  37. Widget _addButton(BuildContext context, String route) => GestureDetector(
  38. onTap: () => context.push(route),
  39. child: const Icon(Icons.add, color: Color(0xFF333333), size: 22),
  40. );
  41. void _popToNative() {
  42. FocusManager.instance.primaryFocus?.unfocus();
  43. SystemNavigator.pop();
  44. }
  45. void _smartBack(BuildContext context) {
  46. final r = GoRouter.of(context);
  47. if (r.canPop()) { r.pop(); } else { SystemNavigator.pop(); }
  48. }
  49. GoRouter createAppRouter() => GoRouter(
  50. observers: [routeObserver],
  51. initialLocation: '/',
  52. routes: [
  53. // ── 根 Tab ──
  54. GoRoute(path: '/', pageBuilder: (_, _) => const MaterialPage(child: AppScaffold(showTabBar: true, body: HomePage()))),
  55. GoRoute(path: '/messages', pageBuilder: (_, _) => const MaterialPage(child: AppScaffold(showTabBar: true, body: MessageListPage()))),
  56. GoRoute(path: '/profile', pageBuilder: (_, _) => const MaterialPage(child: AppScaffold(showTabBar: true, body: ProfilePage()))),
  57. // ── 费用报销 ──
  58. 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()))),
  59. GoRoute(path: '/expense/import-apply', pageBuilder: (context, _) => MaterialPage(child: AppScaffold(navConfig: NavBarConfig(showBack: true, onBack: () => _smartBack(context)), body: const ExpenseApplyImportPage(), resizeToAvoidBottomInset: false))),
  60. GoRoute(path: '/expense/create', pageBuilder: (context, state) => MaterialPage(key: ValueKey(state.uri.toString()), child: AppScaffold(navConfig: NavBarConfig(showBack: true), body: ExpenseCreatePage(editId: state.uri.queryParameters['id']), resizeToAvoidBottomInset: false))),
  61. 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)))),
  62. 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))),
  63. // ── 加班 ──
  64. GoRoute(path: '/overtime/list', pageBuilder: (context, state) => MaterialPage(key: ValueKey(state.uri.toString()), child: AppScaffold(navConfig: NavBarConfig(showBack: true, showRight: true, rightWidget: _addButton(context, '/overtime/create'), onBack: _popToNative), body: const OvertimeListPage()))),
  65. GoRoute(path: '/overtime/create', pageBuilder: (context, state) => MaterialPage(child: AppScaffold(navConfig: NavBarConfig(showBack: true), body: OvertimeCreatePage(editId: state.uri.queryParameters['id'])))),
  66. GoRoute(path: '/overtime/detail/:id', pageBuilder: (context, state) => MaterialPage(child: AppScaffold(navConfig: NavBarConfig(showBack: true, onBack: () => _smartBack(context)), body: OvertimeDetailPage(id: state.pathParameters['id']!)))),
  67. // ── 用车 ──
  68. GoRoute(path: '/vehicle/list', pageBuilder: (context, state) => MaterialPage(key: ValueKey(state.uri.toString()), child: AppScaffold(navConfig: NavBarConfig(showBack: true, showRight: true, rightWidget: _addButton(context, '/vehicle/create'), onBack: _popToNative), body: const VehicleListPage()))),
  69. GoRoute(path: '/vehicle/create', pageBuilder: (context, state) => MaterialPage(child: AppScaffold(navConfig: NavBarConfig(showBack: true), body: VehicleCreatePage(editId: state.uri.queryParameters['id'])))),
  70. GoRoute(path: '/vehicle/detail/:id', pageBuilder: (context, state) => MaterialPage(child: AppScaffold(navConfig: NavBarConfig(showBack: true, onBack: () => _smartBack(context)), body: VehicleDetailPage(id: state.pathParameters['id']!)))),
  71. // ── 外勤日志 ──
  72. 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()))),
  73. GoRoute(path: '/outing-log/create', pageBuilder: (context, _) => MaterialPage(child: AppScaffold(navConfig: NavBarConfig(showBack: true), body: const OutingLogCreatePage()))),
  74. 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']!)))),
  75. // ── 公告 ──
  76. 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()))),
  77. GoRoute(path: '/announcement/detail/:id', pageBuilder: (context, state) => MaterialPage(child: AppScaffold(navConfig: NavBarConfig(showBack: true, onBack: () => _smartBack(context)), body: AnnouncementDetailPage(id: state.pathParameters['id']!)))),
  78. GoRoute(path: '/announcement/create', pageBuilder: (context, _) => MaterialPage(child: AppScaffold(navConfig: NavBarConfig(showBack: true), body: const AnnouncementCreatePage()))),
  79. // ── 费用申请 ──
  80. 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()))),
  81. 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)))),
  82. GoRoute(path: '/expense-apply/create', pageBuilder: (context, state) => MaterialPage(key: ValueKey(state.uri.toString()), child: AppScaffold(navConfig: NavBarConfig(showBack: true), body: ExpenseApplyCreatePage(id: state.uri.queryParameters['id']), resizeToAvoidBottomInset: false))),
  83. 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))),
  84. // ── 报表 ──
  85. GoRoute(path: '/report/expense-detail', pageBuilder: (context, _) => MaterialPage(child: AppScaffold(navConfig: NavBarConfig(showBack: true, onBack: () => _smartBack(context)), body: const ExpenseDetailReportPage()))),
  86. GoRoute(path: '/report/expense-apply-detail', pageBuilder: (context, _) => MaterialPage(child: AppScaffold(navConfig: NavBarConfig(showBack: true, onBack: () => _smartBack(context)), body: const ExpenseApplyDetailReportPage()))),
  87. GoRoute(path: '/report/overtime-detail', pageBuilder: (context, _) => MaterialPage(child: AppScaffold(navConfig: NavBarConfig(showBack: true, onBack: () => _smartBack(context)), body: const OvertimeDetailReportPage()))),
  88. GoRoute(path: '/report/vehicle-detail', pageBuilder: (context, _) => MaterialPage(child: AppScaffold(navConfig: NavBarConfig(showBack: true, onBack: () => _smartBack(context)), body: const VehicleDetailReportPage()))),
  89. GoRoute(path: '/report/outing-log-detail', pageBuilder: (context, _) => MaterialPage(child: AppScaffold(navConfig: NavBarConfig(showBack: true, onBack: () => _smartBack(context)), body: const OutingLogDetailReportPage()))),
  90. // ── 管理 ──
  91. GoRoute(path: '/admin/permissions', pageBuilder: (context, _) => MaterialPage(child: AppScaffold(navConfig: NavBarConfig(showBack: true, onBack: () => _smartBack(context)), body: const AdminPermissionsPage()))),
  92. ],
  93. );