后端: - User表加Role字段 + DoctorProfile表 + 废弃旧Doctor数据 - JWT加Role claim + 注册/登录拆分(/api/auth/register + /api/auth/login) - 医生端点全量加JWT鉴权+Role校验(15个端点) - 日历端点改造(用药/运动/随访按日期+星期匹配) - 饮食记录PUT端点 + 健康记录DELETE端点 - 用户Profile端点返回Role 前端: - 登录页重做(角色选择卡片 用户紫/医生蓝 + 审核码6666 + 注册返登录) - App路由分流(userRole→患者端/医生端) - 医生端: 工作台Dashboard + 患者管理(搜索分页) + 问诊/报告/随访CRUD - 报告审核: AI预分析+指标表格+严重程度4级+模板多选+评语 - 随访编辑: 患者选择器+日期时间+打通患者端 - 健康日历: 可点击日历+当日安排列表+用药/运动/随访颜色标记 - 饮食记录: 热量趋势7/30天+日历(一周)+当日胶囊详情+侧滑编辑删除 - 健康档案: 日期选择器+手术可添加多条+白底渐变保存按钮 - 配色系统: 清理25个未使用色+新增doctorBlue/drawerGradient/pageGrey - 患者端侧边栏: 新渐变+白底按钮+紫色汉堡图标 - AI对话: 用户气泡白底黑字+药管家改蓝色 - App启动闪屏: 防登录页闪烁 文档: color_design_system.md(20页面完整配色设计+图标底色对照表)
81 lines
2.5 KiB
Dart
81 lines
2.5 KiB
Dart
import 'package:flutter/material.dart';
|
||
import 'package:flutter_localizations/flutter_localizations.dart';
|
||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||
import 'package:shadcn_ui/shadcn_ui.dart';
|
||
import 'core/app_colors.dart';
|
||
import 'core/app_router.dart';
|
||
import 'core/app_theme.dart';
|
||
import 'core/navigation_provider.dart';
|
||
import 'providers/auth_provider.dart';
|
||
|
||
/// 健康管家 App 根组件
|
||
class HealthApp extends ConsumerWidget {
|
||
const HealthApp({super.key});
|
||
|
||
@override
|
||
Widget build(BuildContext context, WidgetRef ref) {
|
||
return MaterialApp(
|
||
title: '健康管家',
|
||
debugShowCheckedModeBanner: false,
|
||
theme: AppTheme.lightTheme,
|
||
localizationsDelegates: const [
|
||
GlobalMaterialLocalizations.delegate,
|
||
GlobalWidgetsLocalizations.delegate,
|
||
GlobalCupertinoLocalizations.delegate,
|
||
],
|
||
supportedLocales: const [
|
||
Locale('zh', 'CN'),
|
||
Locale('zh'),
|
||
],
|
||
locale: const Locale('zh'),
|
||
home: const _RootNavigator(),
|
||
// 注入 ShadTheme,让所有页面都能用 shadcn 组件
|
||
builder: (context, child) => ShadTheme(
|
||
data: AppTheme.shadTheme,
|
||
child: child!,
|
||
),
|
||
);
|
||
}
|
||
}
|
||
|
||
/// 根导航——根据 Riverpod 路由状态切换页面
|
||
class _RootNavigator extends ConsumerWidget {
|
||
const _RootNavigator();
|
||
|
||
@override
|
||
Widget build(BuildContext context, WidgetRef ref) {
|
||
final stack = ref.watch(routeStackProvider);
|
||
final current = stack.last;
|
||
final authState = ref.watch(authProvider);
|
||
|
||
// 启动时正在检查登录状态 → 显示闪屏
|
||
if (authState.isLoading && current.name == 'login') {
|
||
return Scaffold(
|
||
backgroundColor: Colors.white,
|
||
body: Center(
|
||
child: Column(mainAxisSize: MainAxisSize.min, children: [
|
||
Icon(Icons.favorite, size: 48, color: AppColors.primary),
|
||
const SizedBox(height: 16),
|
||
Text('健康管家', style: TextStyle(fontSize: 22, fontWeight: FontWeight.w700, color: AppColors.textPrimary)),
|
||
]),
|
||
),
|
||
);
|
||
}
|
||
|
||
// 登录后根据角色分流
|
||
if (authState.isLoggedIn && current.name == 'login') {
|
||
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||
goRoute(ref, authState.user?.role == 'Doctor' ? 'doctorHome' : 'home');
|
||
});
|
||
}
|
||
|
||
return PopScope(
|
||
canPop: stack.length <= 1,
|
||
onPopInvokedWithResult: (didPop, result) {
|
||
if (!didPop) popRoute(ref);
|
||
},
|
||
child: buildPage(current, ref),
|
||
);
|
||
}
|
||
}
|