Files
AI-Health/health_app/lib/providers/data_providers.dart
MingNian 287eab80a9 fix: 全面修复 - 实时通讯、报告AI流程、健康概览、用药运动提醒
- SignalR Hub消息持久化+防重复+跨端广播
- 报告VLM+LLM真实AI流程(验证→提取→解读)
- 医生审核页重构(严重程度/建议模板/综合评语)
- 健康概览五合一趋势图(fl_chart+指标切换)
- 用药提醒时区修复+跨午夜+过期提醒
- 运动打卡DayOfWeek映射修复+计划覆盖查询
- 体重与其他四指标同级(Abnormal检查/确认卡牌)
- AI Agent支持多种类多时段批量录入
- 删除硬编码假数据(张三/假医生/假AI解读)
- 随访/报告审核数据链路全部打通
2026-06-07 23:04:23 +08:00

127 lines
4.1 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_riverpod/flutter_riverpod.dart';
import 'auth_provider.dart';
import '../services/health_service.dart';
final exerciseServiceProvider = Provider<ExerciseService>((ref) {
return ExerciseService(ref.watch(apiClientProvider));
});
/// 健康数据服务
final healthServiceProvider = Provider<HealthService>((ref) {
return HealthService(ref.watch(apiClientProvider));
});
final userServiceProvider = Provider<UserService>((ref) {
return UserService(ref.watch(apiClientProvider));
});
final medicationServiceProvider = Provider<MedicationService>((ref) {
return MedicationService(ref.watch(apiClientProvider));
});
final dietServiceProvider = Provider<DietService>((ref) {
return DietService(ref.watch(apiClientProvider));
});
final followUpServiceProvider = Provider<FollowUpService>((ref) {
return FollowUpService(ref.watch(apiClientProvider));
});
final consultationServiceProvider = Provider<ConsultationService>((ref) {
return ConsultationService(ref.watch(apiClientProvider));
});
/// 最新健康数据 Provider
final latestHealthProvider = FutureProvider<Map<String, dynamic>>((ref) async {
final service = ref.watch(healthServiceProvider);
return service.getLatest();
});
/// AI 录入数据后调用,刷新侧边栏
void refreshHealthData(WidgetRef ref) {
ref.invalidate(latestHealthProvider);
ref.invalidate(medicationListProvider);
}
/// 用药列表 Provider
final medicationListProvider = FutureProvider<List<Map<String, dynamic>>>((ref) async {
final service = ref.watch(medicationServiceProvider);
return service.getList();
});
final medicationReminderProvider = FutureProvider<List<Map<String, dynamic>>>((ref) async {
final service = ref.watch(medicationServiceProvider);
return service.getReminders();
});
/// 医生列表 Provider
final doctorListProvider = FutureProvider<List<Map<String, dynamic>>>((ref) async {
final service = ref.watch(consultationServiceProvider);
try {
return await service.getDoctors().timeout(const Duration(seconds: 8));
} catch (_) {
return _fallbackDoctors;
}
});
const _fallbackDoctors = [
{
'id': '468b82e2-d95a-4436-bff6-a50eecf99a66',
'name': '张明',
'title': '主任医师',
'department': '心脏康复科',
'introduction': '擅长冠心病、高血压术后管理20年临床经验',
},
{
'id': 'd4148733-b538-4398-af17-0c7592fc0c2d',
'name': '李芳',
'title': '副主任医师',
'department': '营养科',
'introduction': '擅长糖尿病、甲状腺疾病管理15年临床经验',
},
{
'id': 'ef0953c9-eb63-4d03-b6d7-050a1897d4a3',
'name': '王建国',
'title': '主任医师',
'department': '心血管内科',
'introduction': '擅长术后营养指导、饮食方案制定10年临床经验',
},
];
/// 问诊配额 Provider
final consultationQuotaProvider = FutureProvider<Map<String, dynamic>>((ref) async {
final service = ref.watch(consultationServiceProvider);
return service.getQuota();
});
/// 当前运动计划 Provider
final currentExercisePlanProvider = FutureProvider<Map<String, dynamic>?>((ref) async {
final service = ref.watch(exerciseServiceProvider);
try {
return await service.getCurrentPlan().timeout(const Duration(seconds: 8));
} catch (_) {
final today = DateTime.now();
final monday = today.subtract(Duration(days: today.weekday - 1));
return {
'weekStartDate': '${monday.year}-${monday.month.toString().padLeft(2, '0')}-${monday.day.toString().padLeft(2, '0')}',
'items': List.generate(7, (i) => {
'id': 'local_$i',
'dayOfWeek': i, // matches C# DayOfWeek: 0=Sun, 1=Mon, ..., 6=Sat
'exerciseType': i == 1 || i == 6 ? '休息' : '散步',
'durationMinutes': i == 1 || i == 6 ? 0 : 30,
'isRestDay': i == 1 || i == 6,
'isCompleted': false,
}),
};
}
});
/// 拍照/相册直接触发(无需跳转页面)
final cameraActionProvider = NotifierProvider<CameraActionNotifier, String?>(CameraActionNotifier.new);
class CameraActionNotifier extends Notifier<String?> {
@override String? build() => null;
void trigger(String action) => state = action;
void clear() => state = null;
}