refactor: 4层架构重构 + 饮食VLM接入 + 多项修复

- 后端: remaining_endpoints拆分为6个独立文件
- 后端: AI Agent Handler从ai_chat_endpoints抽取为7个独立处理器
- 后端: 食物识别prompt改为输出结构化JSON
- 前端: 饮食识别从Mock替换为真实VLM API调用
- 前端: 首页图片上传URL修复(/api/upload→/api/files/upload)
- 前端: 拍饮食按钮导航到独立DietCapturePage
- 前端: 删除无用agent_bar.dart
- 前端: 修复widget_test.dart过期属性名
- 前端: 恢复ServicePackageCard和详情页
- 新增6份实施文档(情况/问诊/报告/建档/日历/视觉统一)
This commit is contained in:
MingNian
2026-06-03 23:17:37 +08:00
parent 5bd0155e17
commit c2399b952f
33 changed files with 3311 additions and 660 deletions

332
情况.md Normal file
View File

@@ -0,0 +1,332 @@
# 健康管家 — 项目现状与文档差异报告
> 对照文档:《需求规格文档 V2》《技术设计文档 V2》《页面设计文档》《CLAUDE.md 编码规范》
> 检查日期2026-06-03
---
## 一、总体完成度评估
| 层级 | 完成度 | 简评 |
|------|--------|------|
| 后端 Domain | ~85% | 实体/枚举基本齐全,缺少 Interfaces/ 目录 |
| 后端 Application | **~0%** | 项目骨架存在但**空无一物** |
| 后端 Infrastructure | ~55% | AI 客户端就绪,缺 PushService/MinioStorageService/Migrations |
| 后端 WebApi | ~70% | 端点基本覆盖,但多个模块挤在一个文件,缺少 AgentHandler 分离 |
| 前端 Flutter | ~65% | 主流程可跑,但多页用 Mock 数据,问诊对话页是占位符 |
| 测试 | ~10% | 后端正向测试覆盖不全,前端测试属性名已失效 |
---
## 二、后端 vs 技术设计文档 — 逐项比对
### 2.1 Health.Application 层(**完全缺失**
技术文档规定的目录结构与实际情况:
```
文档要求 实际情况
─────────────────────────────────────────────────────
DTOs/ 不存在
Services/AuthService.cs 不存在 — 逻辑散落在 endpoint 里
Services/HealthService.cs 不存在
Services/DietService.cs 不存在
Services/MedicationService.cs 不存在
Services/ReportService.cs 不存在
Services/ConsultationService.cs 不存在
Services/ExerciseService.cs 不存在
Services/UserService.cs 不存在
Interfaces/ 不存在
```
**影响**Endpoint 文件直接操作 DbContext + 内联业务逻辑,没有中间的 Service 抽象。Tool Calling 的执行函数全部写在一个 650 行的 `ai_chat_endpoints.cs` 里。
### 2.2 Health.Domain/Interfaces**缺失**
文档规划了仓储接口目录,实际没有任何接口文件。当前通过 DbContext 直接访问数据,无仓储抽象。
### 2.3 AgentHandlers**缺失**
文档规定 7 个独立 Handler 文件:
```
AgentHandlers/DefaultAgentHandler.cs → 不存在,逻辑在 ai_chat_endpoints.cs
AgentHandlers/ConsultationAgentHandler.cs → 不存在
AgentHandlers/HealthDataAgentHandler.cs → 不存在
AgentHandlers/DietAgentHandler.cs → 不存在
AgentHandlers/MedicationAgentHandler.cs → 不存在
AgentHandlers/ReportAgentHandler.cs → 不存在
AgentHandlers/ExerciseAgentHandler.cs → 不存在
```
当前实现:一个 650 行的 `ai_chat_endpoints.cs` 包含所有 7 个 Agent 的路由 + Tool Calling 循环 + 全部 Tool 执行函数 + SSE 处理 + 图片压缩。
### 2.4 端点文件拆分
| 文档规划 | 实际情况 |
|----------|----------|
| AuthEndpoints.cs | ✅ auth_endpoints.cs |
| HealthEndpoints.cs | ✅ health_endpoints.cs |
| DietEndpoints.cs | ⚠️ 合并在 remaining_endpoints.cs |
| MedicationEndpoints.cs | ⚠️ 合并在 remaining_endpoints.cs |
| ReportEndpoints.cs | ⚠️ 合并在 remaining_endpoints.cs |
| ConsultationEndpoints.cs | ⚠️ 合并在 remaining_endpoints.cs |
| ExerciseEndpoints.cs | ⚠️ 合并在 remaining_endpoints.cs |
| AiChatEndpoints.cs | ✅ ai_chat_endpoints.cs但过重 |
| UserEndpoints.cs | ✅ user_endpoints.cs |
| FileEndpoints.cs | ⚠️ 合并在 remaining_endpoints.cs |
`remaining_endpoints.cs`310 行)把 6 个模块的端点硬塞在一个文件里。
### 2.5 基础设施服务
| 文档规划 | 实际情况 |
|----------|----------|
| JwtProvider.cs | ✅ 已实现 |
| SmsService.cs | ✅ 已实现dev 阶段 Console 输出) |
| PushService.cs极光推送 | ❌ **未实现** — 代码中有 TODO 注释 |
| MinioStorageService.cs文件存储 | ❌ **未实现** — 当前用本地 uploads/ 目录 |
`MedicationReminderService.cs:56` 处有明确 TODO
```csharp
// TODO: 调用极光推送发送用药提醒
```
### 2.6 OpenAiCompatibleClient
文档设计了统一客户端,支持多 BaseUrl 切换、自动重试、JSON Mode。实际实现
- ✅ 流式 Chat CompletionsSSE
- ✅ 非流式 Chat
- ✅ Vision图片理解
- ✅ Tool CallingFunction Calling
- ⚠️ 缺少自动重试逻辑
- ⚠️ 缺少 JSON Mode 支持
- ⚠️ 文档规定的 `OpenAiCompatibleClient` 类虽存在,但实际通过 `DeepSeekClient` + `VisionClient`(继承 IHttpClientFactory 模式)分拆使用,未走统一客户端
### 2.7 Migrations**缺失**
文档规定 `Data/Migrations/` 目录。实际使用 `EnsureCreatedAsync()`(无迁移),生产部署时无法做数据库版本管理。
### 2.8 后台服务
| 文档 | 实际 |
|------|------|
| MedicationReminderService.cs | ✅ 框架存在,但推送为 TODO |
| 文档未提及的CleanupService | ✅ 已实现30天对话清理 + 过期验证码清理) |
---
## 三、后端需求覆盖率
### 3.1 登录与认证
| 需求 | 状态 |
|------|------|
| 手机号+验证码登录 | ✅ |
| 登录即注册 | ✅ |
| 开发阶段任意 6 位数字 | ✅ |
| Service/隐私协议勾选 | ✅ |
| Token 刷新30min access / 30d refresh | ✅ |
| 微信登录(后期) | ❌ 未实现 |
| Apple ID 登录(后期) | ❌ 未实现 |
### 3.2 首页与对话
| 需求 | 状态 |
|------|------|
| 7 个 Agent 路由 | ✅ |
| SSE 流式输出 | ✅ |
| Tool Calling 循环 | ✅max 5 轮) |
| 对话自动创建 | ✅ |
| 对话历史持久化 | ✅ |
| 30 天自动清理 | ✅ |
| AI 首次建档引导 | ❌ **未实现** — 新用户零数据时没有主动引导对话 |
### 3.3 各 Agent 功能
| Agent | 状态 | 缺失 |
|-------|------|------|
| 默认对话 | ✅ | — |
| AI 问诊 | ⚠️ | 转医生流程做了 API但 AI 分身对话未实现 |
| 记数据 | ✅ | — |
| 拍饮食 | ⚠️ | VLM 识别端点存在,但前端 Mock 了识别结果,编辑→重新分析流程不完整 |
| 药管家 | ⚠️ | AI 解析处方图片(拍照上传处方→提取药品信息)未实现 |
| 看报告 | ⚠️ | VLM 报告解读(调用 VisionClient 分析报告图片)未串联完整 |
| 运动计划 | ✅ | — |
### 3.4 医生端
| 需求 | 状态 |
|------|------|
| 医生 Web 后台 | ❌ **完全未开始** — 无任何医生端代码 |
| 医生审阅报告 | ❌ |
| 医生管理患者 | ❌ |
| 医生在线问诊回复 | ❌ |
---
## 四、前端 Flutter — 逐项比对
### 4.1 架构与状态管理
| CLAUDE.md 规范 | 实际 |
|----------------|------|
| Riverpod 管理所有状态 | ✅ 全面使用 |
| SQLite 存 Token不用 shared_preferences | ✅ `LocalDatabase` 用 sqflite |
| 无 shared_preferences 引用 | ✅ 确认无引用 |
### 4.2 各页面完成度
| 页面 | 状态 | 说明 |
|------|------|------|
| 登录页 | ✅ | 完整实现 |
| 首页(对话+胶囊栏) | ✅ | 双份 AgentBarwidgets/agent_bar.dart 和 home_page 内联),功能重复 |
| 侧滑抽屉 | ✅ | 彩色分区卡片,动画入场 |
| 健康趋势图 | ✅ | — |
| 用药列表/编辑 | ✅ | — |
| 报告列表/详情 | ⚠️ | **全部使用 Mock 数据**,未调用后端 API |
| AI 解读页 | ⚠️ | **硬编码 Mock 数据** |
| 饮食拍照页 | ⚠️ | VLM 调用未接通,用 `Future.delayed` 模拟 |
| 医生列表 | ✅ | 调后端 API带 fallback |
| 问诊对话页 | ❌ | **占位符组件**,只显示 "问诊 #id" |
| 运动计划页 | ✅ | 调后端 API带 fallback |
| 饮食记录列表 | ✅ | 调后端 API |
| 个人资料/编辑 | ✅ | 调后端 API |
| 健康档案 | ✅ | 调后端 API |
| 复查随访页 | ⚠️ | **完全 Mock 数据**,添加弹窗不调后端 |
| 健康日历 | ⚠️ | **完全 Mock 数据**`_getEvents` 用固定日期规律) |
| 设置/通知偏好 | ⚠️ | 未查看具体实现 |
| 设备管理 | ❌ | 仅占位 `_empty()` |
| 隐私协议/服务协议 | ✅ | StaticTextPage 硬编码文本 |
### 4.3 页面设计文档一致性
| 设计规范 | 实际情况 |
|----------|----------|
| 颜色"以浅紫色为核心" | ✅ `AppTheme.primary = Color(0xFF8B9CF7)` 淡薰紫 |
| 卡片圆角 24+ | ⚠️ 多处卡片 radius 16部分 20不统一 |
| 按钮圆角 20+ | ⚠️ 多处 radius 12-14 |
| 阴影非常轻 | ✅ |
| 背景浅灰白(非纯白) | ✅ `Color(0xFFF8F9FC)` |
| 不要 M3 默认感 | ✅ 自定义主题 |
| 无传统底部 Tab Bar | ✅ 底部是输入框 |
| 对话优先于表单 | ✅ |
| "AI 健康管家"的第一印象 | ✅ 顶部 "AI 健康管家" 标识 |
### 4.4 UI 细节问题
- 有两套智能体栏实现:`widgets/agent_bar.dart`(未被使用)和 `home_page.dart` 内联版本(正在使用),代码冗余
- 大量卡片硬编码颜色值而非使用 Theme不利于后续主题升级
- `remaining_pages.dart` 文件 700+ 行,包含 6 个不同页面类
---
## 五、测试覆盖率
### 5.1 后端测试
| 文件 | 内容 |
|------|------|
| auth_tests.cs | JWT 生成/验证测试 |
| entity_tests.cs | 实体 CRUD 测试 |
| ai_agent_tests.cs | AI 智能体集成测试(需后端运行) |
| unit_test1.cs | **空测试**(只有 Test1 方法体为空) |
### 5.2 前端测试
| 文件 | 内容 |
|------|------|
| widget_test.dart | **属性名已过期,无法编译通过** |
| RunnerTests.swift | iOS 默认模板,未修改 |
**Flutter 测试问题**`widget_test.dart` 引用了旧版属性名:
```dart
AppTheme.primaryColor // 已改为 AppTheme.primary
AppTheme.background // 已改为 AppTheme.bg
AppTheme.errorRed // 已改为 AppTheme.error
AppTheme.successGreen // 已改为 AppTheme.success
```
---
## 六、CLAUDE.md 编码规范执行情况
### 6.1 C# 后端
| 规范项 | 执行情况 |
|--------|----------|
| 主构造函数 | ✅ 全项目使用 |
| 静态方法标 static | ✅ |
| 集合表达式 `[]` | ✅ |
| TryGetValue 替代 GetValueOrDefault | ✅(实际用 `TryGetProperty` |
| 空 catch 指定异常类型 | ✅ |
| DTO 用 record 类型 | ✅ |
| `private static readonly` 缓存 | ✅tool definitions 等) |
| file-scoped namespace | ✅ 全部文件 |
| global using | ✅ Infrastructure 和 WebApi 独立 GlobalUsings.cs |
| Nullable=enable | ⚠️ 未明确验证 |
| Minimal API 扩展方法 | ✅ `MapXxxEndpoints(this WebApplication app)` |
| AI 用 HttpClient 直连 | ✅ 无第三方 AI SDK |
| 文件命名 snake_case | ✅ |
### 6.2 Dart/Flutter 前端
| 规范项 | 执行情况 |
|--------|----------|
| Riverpod 管理状态+路由 | ✅ |
| SQLite 不用 shared_preferences | ✅ |
---
## 七、优先级排序的问题清单
### 🔴 致命(阻断功能)
1. **问诊对话页是占位符** — 患者无法与医生/医生 AI 分身对话
2. **医生 Web 后台完全未开始** — 医生无法审阅报告、回复患者
3. **推送通知未实现** — 用药提醒、复查提醒无法触达用户
4. **Flutter 测试无法编译** — 属性名过期
### 🟠 严重(架构债务)
5. **Health.Application 层完全空置** — 4 层架构缺中间层,所有逻辑堆在 Endpoints
6. **6 个模块挤在 remaining_endpoints.cs** — 随功能增长不可维护
7. **报告模块全 Mock** — 报告上传/分析/解读均未接真实后端
8. **饮食识别全 Mock** — 未接通 VLM API
9. **MinIO 文件存储未实现** — 图片/报告存本地文件系统,无法扩展
### 🟡 中等(影响体验)
10. **复查随访页全 Mock** — 列表、添加弹窗不调后端
11. **健康日历全 Mock** — 固定日期规律,不反映真实数据
12. **设备管理页为占位** — 不显示任何内容
13. **两套智能体栏代码重复** — 维护混乱
14. **AI 首次建档引导未实现** — 新用户体验缺失
15. **数据库无 Migration** — 生产部署无法管理版本
### 🟢 轻微(改进项)
16. **卡片/按钮圆角不统一** — 与设计文档的 24+/20+ 标准有差距
17. **大量硬编码颜色值** — 应改用 Theme 引用
18. **Agent 工具执行函数无自动重试**
19. **OpenAiCompatibleClient 设计但未被实际使用** — DeepSeekClient/VisionClient 各自实现
20. **空测试文件 unit_test1.cs** — 可删除
---
## 八、已符合规范/设计之处(正向确认)
- 登录流程完整手机号→验证码→JWTaccess+refresh→自动刷新
- 7 个 Agent SSE 端点全部可用Tool Calling 循环正确实现
- 30 天对话自动清理已运行
- 统一 API 响应格式 `{code, data, message}` 全项目一致
- 文件命名 snake_case 贯穿后端
- Minimal API 扩展方法模式统一
- 前端全局使用 Riverpod无 shared_preferences
- 侧滑抽屉有分区卡片+动画入场,设计质量较高
- DevDataSeeder 提供完整的测试数据场景
- 后端测试用 InMemory 数据库,不依赖外部服务
---
*本报告基于 2026-06-03 代码库状态生成。*