Files
AI-Health/docs/HANDOFF-2026-07-17.md
MingNian ae94ced2d5 feat: 后台管理页全量重构 + backoffice 共享模块 + 启动脚本优化
## 后台管理页重构
- admin 端: add_doctor / doctors / home / patients 四页重构
- doctor 端: consultations / dashboard / followup_edit / followups / home / patient_detail / patients / profile / report_detail / reports / settings 十一页重构
- 新增 backoffice 共享模块: backoffice_refresh_providers + backoffice_formatters + backoffice_ui

## 后端
- AdminService 增强(分页/搜索/统计)
- doctor_endpoints 微调
- appsettings.Development 调整
- 新增 admin_service_tests

## 前端其他
- 今日健康卡片 taskRow 行高 5->7(每行 44->48px)
- 健康仪表盘配色定 #4FACFE 纯色蓝
- admin_drawer / doctor_drawer 微调
- api_client IP 适配

## 启动脚本
- start-dev.bat: 加后端就绪检测(轮询 openapi 端点, 最多等 30s)

## 清理
- 删除旧品牌图(agent_welcome_abstract / login_background_v1)
- 删除 app_status_badge 组件
- 删除旧 HANDOFF 文档, 新增 07-17 版

## 测试
- 新增 backoffice_formatters / backoffice_refresh / backoffice_ui 三个测试
- app_router_test 扩展
2026-07-18 17:48:44 +08:00

220 lines
9.2 KiB
Markdown
Raw Permalink 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.

# 小脉健康项目交接报告2026-07-17
## 1. 本轮工作范围
本轮工作集中在以下三项:
1. 对医生端和管理员端进行患者端风格的轻量统一。
2. 检查并修复医生、登录账号、医生资料之间的同步逻辑。
3. 进行源码级逻辑检查和小范围自动化验证。
本轮没有生成 APK、没有进行真机或截图测试、没有启动 Web API、没有部署、没有推送远程代码也没有修改真实数据库数据。
## 2. 医生端与管理员端 UI 改造
### 2.1 共用视觉层
新增后台共用展示组件:
- `health_app/lib/widgets/backoffice_ui.dart`
- `health_app/lib/utils/backoffice_formatters.dart`
- `health_app/lib/providers/backoffice_refresh_providers.dart`
统一内容包括:
- 使用患者端现有的紫蓝渐变和浅色页面背景。
- 使用白色圆角卡片、轻边框和统一阴影。
- 统一加载、空数据、加载失败和重试状态。
- 统一管理员端、医生端侧边栏的选中态。
- 对空姓名头像和不完整时间字符串进行安全展示。
### 2.2 医生端
已覆盖的主要页面:
- 工作台
- 患者列表与患者详情
- 问诊列表
- 报告列表与报告详情
- 随访列表与新增/编辑随访
- 医生资料
- 医生设置
- 医生侧边栏
已修复的页面问题:
- “新建随访”以前会被路由器当成缺少 ID 的详情页,现在可以正常进入新建模式。
- 新增或编辑随访后,返回列表会自动刷新。
- 随访和报告日期不再直接强制截取 16 个字符,避免空值或短字符串导致 `RangeError`
- 空患者姓名不再因为直接读取第一个字符而导致崩溃。
- 患者列表加载失败后不再反复自动请求。
- 医生资料页面重建时不再反复覆盖用户正在编辑的输入内容。
- 停用医生登录后,工作台显示“账号已停用,新患者暂时无法选择您”的提示。
### 2.3 管理员端
已覆盖的主要页面:
- 医生管理
- 患者管理
- 新增医生
- 编辑医生
- 管理员侧边栏
已修复的页面问题:
- 管理员接口失败时不再无限显示加载状态。
- 医生列表增加“编辑”入口,复用新增医生表单。
- 新增或编辑医生后,返回列表会自动刷新。
- 停用和删除失败时显示后端返回的具体原因,不再静默失败。
- 删除确认文案改为安全规则:有绑定患者或问诊记录时只能停用,不能删除。
- 停用医生在管理员列表中继续显示“已停用”状态。
## 3. 医生账号三层数据同步
医生相关数据由以下三部分组成:
- `Doctor`:患者选择、医生展示和业务归属。
- `User(Role=Doctor)`:医生登录账号。
- `DoctorProfile`:医生端资料和医生实体关联。
本轮修改了 `backend/src/Health.Infrastructure/Admin/AdminService.cs`,规则如下。
### 3.1 新增医生
- 一次性创建 `Doctor`、医生登录 `User``DoctorProfile`
- 三者使用相同的手机号和姓名,并建立正确 ID 关联。
- 手机号已被患者、医生或其他账号使用时拒绝新增。
### 3.2 编辑医生
- 手机号同步更新 `Doctor` 和登录 `User`
- 姓名同步更新 `Doctor`、登录 `User``DoctorProfile`
- 职称、科室同步更新 `Doctor``DoctorProfile`
- 专业方向更新到 `Doctor`
- 修改手机号前检查其他账号和医生是否已经占用。
- 医生登录资料缺失时拒绝局部修改,避免继续扩大不一致数据。
### 3.3 停用医生
- 同步更新 `Doctor.IsActive``DoctorProfile.IsActive`
- 医生登录账号保持 `Role=Doctor`,仍可正常登录并服务已绑定患者。
- 患者与医生的原有绑定关系保持不变。
- 公开医生列表原本已经只查询 `Doctor.IsActive == true`,因此新患者注册时不会再看到已停用医生。
- 注册接口原本已经再次校验医生必须有效且启用。
### 3.4 删除医生
- 医生仍有绑定患者时拒绝删除。
- 医生已有问诊记录时拒绝删除。
- 无绑定患者和问诊记录时,删除 `Doctor`、对应登录 `User``DoctorProfile` 和刷新令牌。
- 有历史数据的医生应使用“停用”,不应通过物理删除清理。
## 4. 自动化验证
本轮最终验证结果:
- `flutter analyze`:通过,零问题。
- 后端 `Health.Tests`56 项通过0 项失败0 项跳过。
- 医生/管理员 UI、路由和刷新相关测试通过。
新增或更新的测试包括:
- `backend/tests/Health.Tests/admin_service_tests.cs`
- `health_app/test/backoffice_ui_test.dart`
- `health_app/test/backoffice_formatters_test.dart`
- `health_app/test/backoffice_refresh_test.dart`
- `health_app/test/app_router_test.dart`
说明:`dotnet test` 会自动编译测试程序集,但本轮没有执行发布构建,没有生成 Android APK/AAB也没有执行 iOS 构建。
## 5. 数据库核对结果
本轮只进行了只读连接检查,没有修改数据库。
- 项目本地配置指向 `localhost:5432 / health_manager`
- 本机 PostgreSQL 没有运行,因此无法读取本地实际数据。
- 开发 API `http://10.4.237.12:5000` 当前无法连接。
- 正式 API `https://erpapi.datalumina.cn/xiaomai/api/doctors` 可以访问,但公开接口返回的启用医生数量为 0。
- 交接资料显示正式数据库和备份方案尚未最终配置。
因此目前无法确认数据库中是否已经存在以下旧数据问题:
- `Doctor` 存在但没有医生登录 `User`
- `DoctorProfile` 缺失或关联错误。
- 三层手机号、姓名或启用状态不一致。
- 重复医生手机号。
- 患者 `DoctorId` 指向不存在的医生。
新代码可以防止以后继续产生这些不一致,但不会自动修改已有数据。获得生产 PostgreSQL 只读连接或实际数据库备份后,应单独执行数据核对。
## 6. 仍未解决的高优先级问题
### P0固定管理员验证码
`backend/src/Health.Infrastructure/Auth/AuthService.cs` 仍保留固定管理员手机号和固定验证码 `000000`。上线前必须移除,管理员需要使用受控的创建和认证方式。
### P0短信服务仍是开发实现
`backend/src/Health.Infrastructure/Services/sms_service.cs` 只向服务端控制台输出验证码,没有接入真实短信服务。生产环境不会把验证码返回 App因此普通用户无法正常接收验证码。
### P0问诊 SignalR Hub 未鉴权
`backend/src/Health.WebApi/Hubs/ConsultationHub.cs` 没有强制 JWT 身份验证,也没有校验用户或医生是否属于指定问诊。调用者可以传入 `senderType``senderName`,存在加入其他问诊、伪造医生消息和写入数据库的风险。
### P1医生聊天错误复用患者聊天流程
医生问诊列表进入的 `DoctorChatPage` 复用了患者端 `consultationChatProvider`
- 把问诊 ID 当成医生 ID。
- 调用患者配额接口。
- 尝试创建新问诊。
- 发送消息时使用患者身份。
- 医生需要回复的 `WaitingDoctor` 状态反而不能发送。
医生实时问诊目前不能视为可用功能。需要拆分独立医生聊天 Provider 和页面,并与 Hub 鉴权一起处理。
### P1AI SSE 鉴权和上传文件隐私
此前检查发现:
- AI SSE 接口允许从 query token 中直接读取 JWT claims没有完整验证签名、签发者、受众和有效期。
- 上传的医疗图片和报告通过 `/uploads` 静态公开访问。
- 附件本地路径解析缺少完整的目录边界和文件归属校验。
- CORS 当前允许任意来源并携带凭据。
这些问题应在正式上线前统一修复。
### P1iOS 蓝牙流程仍需修复和真机验证
此前检查发现 iOS 页面仍请求 Android 风格蓝牙权限,并调用仅 Android 支持的 `FlutterBluePlus.turnOn()`。iOS Pods 也需要在 macOS 上重新安装并验证。当前 Windows 环境不能证明 iOS 构建和真机蓝牙可用。
## 7. Apple 医疗硬件审核准备
如果首版明确只支持欧姆龙 J735建议准备
- J735 当前有效的医疗器械注册或批准材料。
- 小脉健康 App 与 J735 的联调测试报告。
- 真实 iPhone、J735 和当前版本 App 的完整配对及测量演示视频。
- App、审核说明、兼容设备清单和宣传文案全部明确首版支持范围。
注册证只能证明血压计本身合规,不能替代 App 与硬件联调测试报告和演示视频。
## 8. 建议后续顺序
1. 修复固定管理员验证码并接入正式短信服务。
2. 拆分医生聊天流程并为 SignalR Hub 增加 JWT、角色和问诊归属校验。
3. 修复 AI SSE 鉴权、上传文件访问控制、路径边界和 CORS。
4. 获得真实数据库只读连接,核对并修复旧医生账号数据。
5. 在 macOS 和真实 iPhone 上修复并验证 iOS 蓝牙流程。
6. 准备 J735 监管材料、联调报告和真实设备演示视频。
7. 完成正式服务器、数据库、短信、对象存储、域名和 HTTPS 配置后,再进入发布构建和应用商店提交。
## 9. 当前操作边界
- 本轮代码修改和本交接报告均未进行新的 Git 提交或远程推送。
- 没有执行数据库迁移。
- 没有写入、更新或删除真实数据库数据。
- 没有生成或上传发布安装包。
- 没有启动需要额外关闭的前端或后端常驻服务。