后端: - 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页面完整配色设计+图标底色对照表)
250 lines
11 KiB
Dart
250 lines
11 KiB
Dart
import 'package:flutter/material.dart';
|
||
import '../../core/app_theme.dart';
|
||
import '../../core/navigation_provider.dart';
|
||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||
|
||
/// 服务包数据模型
|
||
class ServicePackage {
|
||
final String id;
|
||
final String title;
|
||
final String subtitle;
|
||
final Color headerColor;
|
||
final List<ServiceItem> services;
|
||
final String targetAudience;
|
||
final List<DetailSection> detailSections;
|
||
|
||
const ServicePackage({
|
||
required this.id,
|
||
required this.title,
|
||
required this.subtitle,
|
||
required this.headerColor,
|
||
required this.services,
|
||
required this.targetAudience,
|
||
required this.detailSections,
|
||
});
|
||
}
|
||
|
||
class ServiceItem {
|
||
final IconData icon;
|
||
final String label;
|
||
|
||
const ServiceItem({required this.icon, required this.label});
|
||
}
|
||
|
||
class DetailSection {
|
||
final String title;
|
||
final String content;
|
||
|
||
const DetailSection({required this.title, required this.content});
|
||
}
|
||
|
||
/// 预定义服务包数据 —— 基于项目实际功能
|
||
final List<ServicePackage> servicePackages = [
|
||
ServicePackage(
|
||
id: 'vip_comprehensive',
|
||
title: '心血管健康管理服务包',
|
||
subtitle: 'VIP 产品权益',
|
||
headerColor: const Color(0xFF4A90D9),
|
||
services: [
|
||
ServiceItem(icon: Icons.phone_in_talk_outlined, label: '电话咨询'),
|
||
ServiceItem(icon: Icons.chat_bubble_outline, label: '在线咨询'),
|
||
ServiceItem(icon: Icons.calendar_month_outlined, label: '个性化随访'),
|
||
ServiceItem(icon: Icons.medication_outlined, label: '调药管理'),
|
||
ServiceItem(icon: Icons.monitor_heart_outlined, label: '风险监测'),
|
||
ServiceItem(icon: Icons.devices_outlined, label: '智能硬件'),
|
||
ServiceItem(icon: Icons.family_restroom_outlined, label: '亲情账号'),
|
||
ServiceItem(icon: Icons.verified_user_outlined, label: '健康保障'),
|
||
],
|
||
targetAudience:
|
||
'心血管疾病患者(如高血压、冠心病、心律失常等)\n'
|
||
'高危人群(如高血脂、糖尿病、肥胖、长期吸烟饮酒者)\n'
|
||
'术后康复人群(如心脏支架/搭桥术后、PCI术后患者)',
|
||
detailSections: [
|
||
DetailSection(
|
||
title: '1、个性化康复管理',
|
||
content:
|
||
'设定动态化的危险因素管理目标,根据患者的住院数据(如基础疾病、高危因素、合并症、当前用药等),确定高危因素(如高脂血症、高血糖等),设定高危因子(如低密度脂蛋白等)的管控目标。基于药物不良反应,制定个性化管理及复查方案。',
|
||
),
|
||
DetailSection(
|
||
title: '2、家庭医生专业团队',
|
||
content:
|
||
'由心内科主诊医生团队联合康复管理团队共同参与患者管理,将疾病康复从院内延伸至院外。团队由专科医生、康复治疗师、健康管理师、营养师等多学科成员组成。',
|
||
),
|
||
DetailSection(
|
||
title: '3、全年不限次数在线咨询',
|
||
content:
|
||
'为患者提供全年不限次数的咨询服务,支持微信(如文字、图文、语音等)、电话咨询等方式。如检查报告解读、用药咨询、病情咨询、饮食咨询、心理咨询等。',
|
||
),
|
||
DetailSection(
|
||
title: '4、主动跟踪随访管理',
|
||
content:
|
||
'动态临床评估:动态评估疾病复发、出血、致死致残等风险,实时优化管理方案。\n'
|
||
'主动症状管理:全年主动跟踪患者临床症状,实现疾病恶化早发现、早处理。\n'
|
||
'精准药物管理:全程用药指导,严密监控药物副作用,及时处理药物不良反应,确保药物治疗效果。\n'
|
||
'生活方式干预:个性化指导患者合理膳食、运动康复、心理调节、戒烟限酒等。',
|
||
),
|
||
DetailSection(
|
||
title: '5、可穿戴智能设备',
|
||
content:
|
||
'配备可穿戴智能监测设备,患者居家测量后实时上传管理中心,医生和家属均可远程实时监测数据(血压和心率),记录数据变化趋势,智能预警,及时干预异常指标,降低不良事件发生率。',
|
||
),
|
||
DetailSection(
|
||
title: '6、亲情账号联动管理',
|
||
content:
|
||
'支持5名家属参与管理,实时多端同步患者病情,医生、患者、家属三方共享,患者安心,家属放心。',
|
||
),
|
||
DetailSection(
|
||
title: '7、健康档案与报告分析',
|
||
content:
|
||
'自动整合血压、心率、血糖、血氧、体重等健康数据,生成可视化健康趋势报告。\n'
|
||
'AI 智能分析健康数据变化,提前预警潜在风险,提供个性化健康建议。',
|
||
),
|
||
],
|
||
),
|
||
ServicePackage(
|
||
id: 'vip_premium',
|
||
title: '心力衰竭专项管理服务包',
|
||
subtitle: 'VIP 产品权益',
|
||
headerColor: const Color(0xFF2BA87E),
|
||
services: [
|
||
ServiceItem(icon: Icons.phone_in_talk_outlined, label: '电话咨询'),
|
||
ServiceItem(icon: Icons.chat_bubble_outline, label: '在线咨询'),
|
||
ServiceItem(icon: Icons.calendar_month_outlined, label: '个性化随访'),
|
||
ServiceItem(icon: Icons.medication_outlined, label: '调药管理'),
|
||
ServiceItem(icon: Icons.monitor_heart_outlined, label: '风险监测'),
|
||
ServiceItem(icon: Icons.devices_outlined, label: '智能硬件'),
|
||
ServiceItem(icon: Icons.family_restroom_outlined, label: '亲情账号'),
|
||
],
|
||
targetAudience:
|
||
'心力衰竭患者\n'
|
||
'心力衰竭高危人群(心肌梗死、瓣膜病、心肌病、高血压、代谢综合征等)',
|
||
detailSections: [
|
||
DetailSection(
|
||
title: '1、个性化康复管理',
|
||
content:
|
||
'设定动态化的危险因素管理目标,根据患者的住院数据(如基础疾病、高危因素、合并症、当前用药等),确定高危因素管控目标。基于药物不良反应,制定个性化管理及复查方案。',
|
||
),
|
||
DetailSection(
|
||
title: '2、家庭医生专业团队',
|
||
content:
|
||
'由心内科主诊医生团队联合哈瑞特医疗院外康复管理团队共同参与患者管理,将疾病康复从院内延伸至院外,哈瑞特医疗康复管理团队由专科医生、康复治疗师、健康管理师、营养师等多学科成员组成。',
|
||
),
|
||
DetailSection(
|
||
title: '3、全年不限次数在线咨询',
|
||
content:
|
||
'为患者提供全年不限次数的咨询服务,支持微信(如文字、图文、语音等)、电话咨询(400-1666199),如检查报告解读、用药咨询、病情咨询、饮食咨询、心理咨询等。',
|
||
),
|
||
DetailSection(
|
||
title: '4、主动跟踪随访管理',
|
||
content:
|
||
'动态临床评估:动态评估疾病复发、出血、致死致残等风险,实时优化管理方案。\n'
|
||
'主动症状管理:全年主动跟踪患者临床症状,实现疾病恶化早发现、早处理。\n'
|
||
'精准药物管理:全程用药指导,严密监控药物副作用,及时处理药物不良反应,确保药物治疗效果。\n'
|
||
'生活方式干预:个性化指导患者合理膳食、运动康复、心理调节、戒烟限酒等。',
|
||
),
|
||
DetailSection(
|
||
title: '5、可穿戴智能设备',
|
||
content:
|
||
'配备可穿戴智能监测设备,患者居家测量后实时上传管理中心,医生和家属均可远程实时监测数据(血压和心率),记录数据变化趋势,智能预警,及时干预异常指标,降低不良事件发生率。',
|
||
),
|
||
DetailSection(
|
||
title: '6、亲情账号联动管理',
|
||
content:
|
||
'支持5名家属参与管理,实时多端同步患者病情,医生、患者、家属三方共享,患者安心,家属放心。',
|
||
),
|
||
],
|
||
),
|
||
];
|
||
|
||
/// 服务包卡片
|
||
class ServicePackageCard extends ConsumerWidget {
|
||
final bool compact;
|
||
const ServicePackageCard({super.key, this.compact = false});
|
||
|
||
@override
|
||
Widget build(BuildContext context, WidgetRef ref) {
|
||
final package = servicePackages.first;
|
||
|
||
// 构建服务图标网格
|
||
final services = package.services.take(8).toList();
|
||
final serviceRows = <Widget>[];
|
||
for (var i = 0; i < services.length; i += 4) {
|
||
final rowItems = services.skip(i).take(4).toList();
|
||
serviceRows.add(Padding(
|
||
padding: EdgeInsets.only(top: i > 0 ? 12 : 0),
|
||
child: Row(
|
||
children: rowItems.map((item) {
|
||
return Expanded(
|
||
child: Column(
|
||
mainAxisSize: MainAxisSize.min,
|
||
children: [
|
||
Container(
|
||
width: 40,
|
||
height: 40,
|
||
decoration: const BoxDecoration(
|
||
color: Color(0xFFFFF8EE),
|
||
shape: BoxShape.circle,
|
||
),
|
||
child: Icon(item.icon, size: 23, color: const Color(0xFFF5A623)),
|
||
),
|
||
const SizedBox(height: 4),
|
||
Text(item.label,
|
||
style: const TextStyle(fontSize: 14, color: AppTheme.textSub),
|
||
textAlign: TextAlign.center,
|
||
),
|
||
],
|
||
),
|
||
);
|
||
}).toList(),
|
||
),
|
||
));
|
||
}
|
||
|
||
Widget card = GestureDetector(
|
||
onTap: () => pushRoute(ref, 'servicePackageDetail', params: {'id': package.id}),
|
||
child: Padding(
|
||
padding: const EdgeInsets.fromLTRB(18, 16, 18, 14),
|
||
child: Column(
|
||
crossAxisAlignment: CrossAxisAlignment.start,
|
||
children: [
|
||
// 标题行 + 详情入口
|
||
Row(children: [
|
||
Text(package.title, style: const TextStyle(fontSize: 19, fontWeight: FontWeight.w600, color: AppTheme.text)),
|
||
const Spacer(),
|
||
GestureDetector(
|
||
onTap: () => pushRoute(ref, 'servicePackageDetail', params: {'id': package.id}),
|
||
child: Row(mainAxisSize: MainAxisSize.min, children: [
|
||
Text('详情', style: TextStyle(fontSize: 16, color: AppTheme.textSub)),
|
||
const SizedBox(width: 2),
|
||
Icon(Icons.chevron_right, size: 21, color: AppTheme.textHint),
|
||
]),
|
||
),
|
||
]),
|
||
const SizedBox(height: 12),
|
||
// 服务图标网格
|
||
...serviceRows,
|
||
],
|
||
),
|
||
),
|
||
);
|
||
|
||
if (compact) return card;
|
||
|
||
return Container(
|
||
margin: const EdgeInsets.symmetric(horizontal: 24),
|
||
decoration: BoxDecoration(
|
||
color: Colors.white,
|
||
borderRadius: BorderRadius.circular(16),
|
||
boxShadow: [
|
||
BoxShadow(
|
||
color: Colors.black.withAlpha(8),
|
||
blurRadius: 12,
|
||
offset: const Offset(0, 4),
|
||
),
|
||
],
|
||
),
|
||
child: card,
|
||
);
|
||
}
|
||
}
|