Files
AI-Health/health_app/lib/core/app_router.dart
MingNian ae94ced2d5 feat: 后台管理页全量重构 + backoffice 共享模块 + 启动脚本优化
## 后台管理页重构
- admin 端: add_doctor / doctors / home / patients 四页重构
- doctor 端: consultations / dashboard / followup_edit / followups / home / patient_detail / patients / profile / report_detail / reports / settings 十一页重构
- 新增 backoffice 共享模块: backoffice_refresh_providers + backoffice_formatters + backoffice_ui

## 后端
- AdminService 增强(分页/搜索/统计)
- doctor_endpoints 微调
- appsettings.Development 调整
- 新增 admin_service_tests

## 前端其他
- 今日健康卡片 taskRow 行高 5->7(每行 44->48px)
- 健康仪表盘配色定 #4FACFE 纯色蓝
- admin_drawer / doctor_drawer 微调
- api_client IP 适配

## 启动脚本
- start-dev.bat: 加后端就绪检测(轮询 openapi 端点, 最多等 30s)

## 清理
- 删除旧品牌图(agent_welcome_abstract / login_background_v1)
- 删除 app_status_badge 组件
- 删除旧 HANDOFF 文档, 新增 07-17 版

## 测试
- 新增 backoffice_formatters / backoffice_refresh / backoffice_ui 三个测试
- app_router_test 扩展
2026-07-18 17:48:44 +08:00

148 lines
5.6 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 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'navigation_provider.dart';
import '../pages/auth/login_page.dart';
import '../pages/home/home_page.dart';
import '../pages/chart/trend_page.dart';
import '../pages/medication/medication_list_page.dart';
import '../pages/medication/medication_checkin_page.dart';
import '../pages/medication/medication_edit_page.dart';
import '../pages/report/report_pages.dart';
import '../pages/report/ai_analysis_page.dart';
import '../pages/consultation/consultation_pages.dart';
import '../pages/settings/settings_pages.dart';
import '../pages/settings/notification_prefs_page.dart';
import '../pages/notifications/notification_center_page.dart';
import '../pages/history/conversation_history_page.dart';
import '../pages/profile/profile_page.dart';
import '../pages/profile/profile_edit_page.dart';
import '../pages/diet/diet_capture_page.dart';
import '../pages/exercise/exercise_plan_page.dart';
import '../pages/device/device_scan_page.dart';
import '../pages/device/device_management_page.dart';
import '../pages/remaining_pages.dart';
import '../pages/doctor/doctor_home_page.dart';
import '../pages/doctor/doctor_patient_detail_page.dart';
import '../pages/doctor/doctor_report_detail_page.dart';
import '../pages/doctor/doctor_followup_edit_page.dart';
import '../pages/doctor/doctor_settings_page.dart';
import '../pages/doctor/doctor_profile_page.dart';
import '../pages/admin/admin_home_page.dart';
import '../pages/admin/admin_add_doctor_page.dart';
import '../providers/auth_provider.dart' show userRoleProvider;
import '../widgets/app_error_state.dart';
Widget _missingParamPage() {
return const Scaffold(
body: AppErrorState(title: '页面参数错误', subtitle: '缺少打开页面所需的信息,请返回后重试'),
);
}
String? _requiredParam(Map<String, String> params, String key) {
final value = params[key]?.trim();
return value == null || value.isEmpty ? null : value;
}
/// 根据路由信息返回对应页面
Widget buildPage(RouteInfo route, WidgetRef ref) {
final params = route.params;
switch (route.name) {
case 'login':
return const LoginPage();
case 'home':
final role = ref.watch(userRoleProvider);
return role == 'Doctor' ? const DoctorHomePage() : const HomePage();
case 'doctorHome':
return const DoctorHomePage();
case 'adminHome':
return const AdminHomePage();
case 'adminAddDoctor':
return AdminAddDoctorPage(
id: params['id'],
initialPhone: params['phone'] ?? '',
initialName: params['name'] ?? '',
initialTitle: params['title'] ?? '',
initialDepartment: params['department'] ?? '',
initialDirection: params['direction'] ?? '',
);
case 'trend':
return TrendPage(
metricType: params['type']?.isNotEmpty == true ? params['type'] : null,
);
case 'calendar':
return const HealthCalendarPage();
case 'medications':
return const MedicationListPage();
case 'medCheckIn':
return MedicationCheckInPage(medId: params['id']);
case 'medicationEdit':
return MedicationEditPage(id: params['id']);
case 'reports':
return ReportListPage(openUploadOnEnter: params['openUpload'] == 'true');
case 'aiAnalysis':
final id = _requiredParam(params, 'id');
return id == null ? _missingParamPage() : AiAnalysisPage(id: id);
case 'reportOriginal':
return ReportOriginalPage(
url: params['url'] ?? '',
title: params['title'] ?? '原始报告',
fileType: params['fileType'] ?? 'Image',
);
case 'exercisePlan':
return const EnterpriseExercisePlanPage();
case 'exercisePlanDetail':
return const EnterpriseExercisePlanPage();
case 'exerciseCreate':
return const ExercisePlanCreatePage();
case 'dietRecords':
return const DietRecordListPage();
case 'dietCapture':
return const DietCapturePage();
case 'profile':
return const ProfilePage();
case 'profileEdit':
return const ProfileEditPage();
case 'doctorProfile':
return const DoctorProfileEditPage();
case 'doctorSettings':
return const DoctorSettingsPage();
case 'doctorPatientDetail':
final id = _requiredParam(params, 'id');
return id == null ? _missingParamPage() : DoctorPatientDetailPage(id: id);
case 'doctorChat':
final id = _requiredParam(params, 'id');
return id == null ? _missingParamPage() : DoctorChatPage(id: id);
case 'doctorReportDetail':
final id = _requiredParam(params, 'id');
return id == null ? _missingParamPage() : DoctorReportDetailPage(id: id);
case 'doctorFollowUpEdit':
return DoctorFollowUpEditPage(id: params['id']);
case 'devices':
return const DeviceManagementPage();
case 'deviceScan':
return const DeviceScanPage();
case 'healthArchive':
return const HealthArchivePage();
case 'followups':
return const FollowUpListPage();
case 'settings':
return const SettingsPage();
case 'notificationPrefs':
return const NotificationPrefsPage();
case 'notifications':
return const NotificationCenterPage();
case 'conversationHistory':
return const ConversationHistoryPage();
case 'staticText':
final type = _requiredParam(params, 'type');
return type == null ? _missingParamPage() : StaticTextPage(type: type);
case 'dietDetail':
final id = _requiredParam(params, 'id');
return id == null ? _missingParamPage() : DietRecordDetailPage(id: id);
default:
return const LoginPage();
}
}
// ── 医生端次级页面 Stubs逐步实现──