Files
AI-Health/docs/omron_bp_implementation_plan.md
MingNian f01fc9268d feat: UI清爽紫蓝风全面改造 + 对话卡片重构 + 配色体系升级
- 新增 AppColors 统一配色方案(清爽紫蓝,参考蚂蚁阿福风格)
- 新增 common_widgets(GradientBorderButton / CardActionButton / IconBox)
- AgentWelcomeCard 美化:渐变 header + AI标签 + 核心功能区 + 快捷操作区
- DataConfirmCard 统一:三合一(健康/药品/运动),可编辑字段列表
- 删除死代码:medicationConfirm/dietAnalysis/reportAnalysis/quickOptions 卡片
- 删除死路由:doctors/profileEdit/editProfile
- AI 对话去除 Markdown 符号(_stripMd),统一行间距 1.5
- 逐字淡入动画修复:key 改用 stableId 避免重复触发
- 健康概览时间修复:前端发送 UTC 避免时区歧义
- PG 数据目录迁入项目 backend/pgdata/,加入 .gitignore
- 新增欧姆龙血压计实施方案文档
2026-06-09 17:04:11 +08:00

6.8 KiB
Raw Blame History

欧姆龙 J735 蓝牙血压计 — 实施计划


一、当前状态

  • 设备已购:欧姆龙 J735
  • 前端占位:DeviceManagementPage 目前是空壳(显示"暂无绑定设备"),路由 devices 已注册,入口在 ProfilePage → 设备管理
  • 项目风格:淡紫清新风(AppThemeMaterial 3 + shadcn_ui + Riverpod
  • 本地存储SQLiteLocalDatabasekv_store 表)
  • 后端:已有 POST /api/health-records 支持 BloodPressure 类型Source 枚举需加 Device

二、实施范围

2.1 新增依赖

# pubspec.yaml
flutter_blue_plus: ^1.34.0    # BLE 核心
permission_handler: ^11.3.0    # 蓝牙权限

2.2 新增文件6 个)

health_app/lib/
├── services/
│   └── omron_ble_service.dart    # BLE 连接 + SFLOAT 协议解析
├── models/
│   └── bp_reading.dart           # 血压数据模型
├── providers/
│   └── omron_device_provider.dart # 设备绑定状态 + 实时读数
├── pages/
│   └── device/
│       ├── device_scan_page.dart  # 扫描设备页
│       └── device_bind_page.dart  # 已绑定设备管理页(替换空壳)

2.3 修改文件3 个)

文件 改动内容
pages/remaining_pages.dart 替换 DeviceManagementPage 空壳为 DeviceBindPage
core/app_router.dart devices 路由指向新页面
providers/data_providers.dart 新增 omronBleServiceProviderbpReadingsProvider
后端 health_enums.cs HealthRecordSourceDevice

三、分步实施3 天)

Day 1 — BLE 服务层

目标:手机能搜到 J735、连接上、收到蓝牙数据并正确解析

  1. 添加 flutter_blue_plus + permission_handler 依赖
  2. 配置 Android 蓝牙权限(AndroidManifest.xml+ iOS 权限(Info.plist
  3. 实现 BpReading 数据模型systolic/diastolic/pulse/timestamp/status
  4. 实现 OmronBleService
    • scan() — 过滤蓝牙名含 OMRON/HEM/BLEsmart 且有 0x1810 服务的设备
    • connect() — 连接 → discoverServices → 订阅 0x2A35 Indicate
    • _parseReading() — SFLOAT 解码 + Flags 解析kPa 转换、体动、心律等)
    • _syncTime() — 写入 0x2A08 同步时间
    • disconnect() / dispose()
  5. 用 nRF Connect 抓包验证原始 HEX → SFLOAT 解码结果与屏幕一致

产出OmronBleService 可独立运行,单元测试验证 SFLOAT 解码

Day 2 — UI 页面

目标:实现扫描绑定页 + 已绑定管理页,风格对齐项目淡紫主题

扫描绑定页 (DeviceScanPage)

  • AppBar 标题"添加血压计",返回按钮
  • 顶部:扫描状态指示(转圈 + "正在扫描..." / "扫描完成,发现 N 台设备"
  • 空状态:未发现设备时显示使用说明卡片(装电池 → 长按蓝牙键 → 手机靠近 → 检查权限)
  • 设备列表:每行显示 BLE 设备名 + 信号强度 + MAC + "连接"按钮
  • 连接中:按钮变 loading
  • 连接成功SnackBar "已连接 OMRON xxx",返回上一页并传递设备信息
  • 底部:重新扫描按钮

已绑定管理页 (DeviceBindPage,替换空壳)

  • 未绑定状态:大蓝牙图标 + "未绑定设备" + 说明文字 + "添加设备"按钮,点击跳扫描页
  • 已绑定状态:白底圆角卡片
    • 设备图标(紫色渐变圆)+ 设备名
    • MAC 地址(灰色小字)
    • 上次同步时间
    • "解绑设备"按钮(红色文字)

风格要点(保证不出现"全黑"

  • 背景色:AppTheme.bg(淡紫白 #FAF9FF
  • 卡片:白色 Colors.white,圆角 AppTheme.rLg20AppTheme.shadowCard 阴影
  • 按钮:紫色实心(AppTheme.primary+ 圆角 AppTheme.rPill
  • 空状态图标:Colors.grey[300],文字 AppTheme.textHint
  • 使用 shadcn_ui 图标(LucideIcons
  • 与 SettingsPage、ProfilePage 保持一致的 AppBar 风格

产出:两个 UI 页面,风格与项目统一,从 ProfilePage → 设备管理可进入

Day 3 — 数据同步 + 联调

  1. Provider 层omronDeviceProvider 管理绑定状态MAC/name/lastSync 存入 SQLite
  2. 自动同步:收到 BLE 读数后自动 POST /api/health-records
    {
      'type': 'BloodPressure',
      'systolic': reading.systolic,
      'diastolic': reading.diastolic,
      'source': 'Device',
      'unit': 'mmHg',
      'recordedAt': reading.timestamp.toUtc().toIso8601String(),
    }
    
  3. 去重逻辑:同一时间戳(精确到秒)+ 同一值 → 跳过
  4. 健康概览刷新:同步后 ref.invalidate(latestHealthProvider)
  5. 真机 + J735 联调
    • 扫描 → 连接 → 测量 → 数据上传 → 健康概览显示新数据
    • 断连 → 重新打开 App → 再次连接
    • iOS 和 Android 双平台测试

四、交互流程

用户操作                        App 行为
────────                      ────────
设置 → 蓝牙血压计             打开 DeviceBindPage已绑定/未绑定)
  │
  ├─ 未绑定
  │   └─ 点"添加设备"          打开 DeviceScanPage
  │       └─ 扫到 J735         点击"连接"
  │           └─ 连接成功      返回 DeviceBindPage已绑定状态
  │
  └─ 已绑定
      └─ 血压计测量            血压计按开始键 → 测量完成
          │                    BLE Indicate 推送数据
          │                    App 收到 120/80
          │                    SnackBar: "已同步: 120/80 mmHg"
          │                    自动写入 HealthRecords
          │                    健康概览刷新
          └─ 查看              点"健康概览"可看到新数据

五、预期效果

  • 从 ProfilePage → 设备管理,不再是全黑空壳,而是漂亮的设备管理页面
  • 点击"添加设备"打开扫描页15 秒内搜索到 J735
  • 点击"连接" 2 秒内完成绑定
  • J735 测量完毕后App 自动收到数据(无需手动操作)
  • 数据自动写入健康记录,健康概览实时刷新
  • 同一数据不重复录入
  • 重新打开 App 后已绑定设备状态保留
  • iOS + Android 双平台均可使用

六、风险点

风险 应对
J735 蓝牙名称与预期不符 不硬编码名称,用 0x1810 服务 UUID 过滤;首次连接后打印实际名称
Android 12+ 蓝牙权限弹窗被拒 permission_handler 检测权限状态,引导用户去设置开启
设备已被系统蓝牙占用 扫描页提示"如搜不到请先取消系统蓝牙配对"
SFLOAT 解码与屏幕值有偏差 用 nRF Connect 抓 HEX 对比,误差 > 1 则调整解码
iOS BLE 后台断连 前台连接同步,完成后断开;不做后台持久连接