feat: 后端架构重构 — Endpoint→Service→Repository分层 + AI确认机制 + 异步任务持久化

- 核心业务拆分为 Endpoint → Application Service → Repository 三层
- AI写入操作必须用户确认后才写库(确认卡片机制)
- 报告/饮食/用药分析改为持久化任务队列(原子领取/重试/重启恢复)
- 运动计划修复: 连续真实日期替代周模板
- 用药提醒去重 + 通知Outbox预留
- 认证收拢到AuthService, 管理员收拢到AdminService
- AI会话加用户归属校验防串号
- 提示词调整为患者视角
- 开发假数据已关闭
- 21/21测试通过, 0警告0错误
This commit is contained in:
MingNian
2026-06-20 20:41:42 +08:00
parent c610417e29
commit 4d213b5a44
132 changed files with 6733 additions and 2856 deletions

View File

@@ -62,37 +62,9 @@ final medicationReminderProvider = FutureProvider<List<Map<String, dynamic>>>((r
/// 医生列表 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;
}
return service.getDoctors().timeout(const Duration(seconds: 8));
});
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);
@@ -102,23 +74,7 @@ final consultationQuotaProvider = FutureProvider<Map<String, dynamic>>((ref) asy
/// 当前运动计划 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,
}),
};
}
return service.getCurrentPlan().timeout(const Duration(seconds: 8));
});
/// 拍照/相册直接触发(无需跳转页面)