Files
DDUp/docs/plans/2025-01-17-vitals-design.md
Rocky b5b2eba6f8 docs: 添加 Vitals 健康管理应用设计文档
- 综合健康管理:运动、饮食、睡眠、体重
- CLI + Web 仪表盘双交互模式
- 支持佳明/咕咚数据导入
- 智能卡路里计算,支持拍照识别食物
- 周报/月报多格式导出(HTML/PDF/PNG)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-17 22:11:13 +08:00

369 lines
13 KiB
Markdown
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.

# Vitals 健康管理应用设计文档
> 生成日期: 2025-01-17
## 概述
Vitals 是一个本地优先的综合健康管理应用,整合运动、饮食、睡眠和体重数据,提供统一的仪表盘和定期报告。
**核心特点:**
- 数据本地存储,隐私有保障
- 支持从佳明手表、咕咚APP导入数据
- 命令行快速记录 + Web 可视化仪表盘
- 智能卡路里计算,支持拍照识别食物
- 周报/月报自动生成
---
## 整体架构
```
┌─────────────────────────────────────────────────────┐
│ 用户交互层 │
├──────────────────────┬──────────────────────────────┤
│ CLI 命令行工具 │ Web 仪表盘 (本地) │
│ - 快速记录数据 │ - 数据可视化 │
│ - 导入外部数据 │ - 趋势图表 │
│ - 生成报告 │ - 健康概览 │
└──────────────────────┴──────────────────────────────┘
┌─────────────────────────────────────────────────────┐
│ 核心服务层 │
│ - 数据标准化处理 │
│ - 报告生成引擎 │
│ - 数据导入适配器 (Garmin / 咕咚 / CSV) │
│ - 食物识别与卡路里计算 │
└─────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────┐
│ 数据存储层 │
│ SQLite 本地数据库 │
│ - 运动记录 - 饮食记录 - 睡眠记录 - 体重记录 │
└─────────────────────────────────────────────────────┘
```
**设计原则:**
- 本地优先:所有数据存储在本地 SQLite不依赖云服务
- 模块解耦CLI、Web、数据处理各自独立
- 可扩展:通过适配器模式支持新的数据源
---
## 数据模型
### 运动记录 (exercise)
| 字段 | 类型 | 说明 |
|-----|------|-----|
| id | INTEGER | 主键 |
| date | DATE | 日期 |
| type | TEXT | 运动类型(跑步/游泳/力量... |
| duration | INTEGER | 时长(分钟) |
| calories | INTEGER | 消耗卡路里 |
| distance | FLOAT | 距离(公里,可选) |
| heart_rate_avg | INTEGER | 平均心率(可选) |
| source | TEXT | 数据来源(手动/garmin/codoon |
| raw_data | JSON | 原始导入数据 |
| notes | TEXT | 备注 |
### 饮食记录 (meal)
| 字段 | 类型 | 说明 |
|-----|------|-----|
| id | INTEGER | 主键 |
| date | DATE | 日期 |
| meal_type | TEXT | 餐次(早/中/晚/加餐) |
| description | TEXT | 食物描述 |
| calories | INTEGER | 总卡路里 |
| protein | FLOAT | 蛋白质(克,可选) |
| carbs | FLOAT | 碳水(克,可选) |
| fat | FLOAT | 脂肪(克,可选) |
| photo_path | TEXT | 照片路径(可选) |
| food_items | JSON | 解析后的食物条目 |
### 睡眠记录 (sleep)
| 字段 | 类型 | 说明 |
|-----|------|-----|
| id | INTEGER | 主键 |
| date | DATE | 日期 |
| bedtime | TIME | 入睡时间 |
| wake_time | TIME | 起床时间 |
| duration | FLOAT | 总时长(小时) |
| quality | INTEGER | 质量评分1-5 |
| deep_sleep_mins | INTEGER | 深睡时长(可选) |
| source | TEXT | 数据来源 |
| notes | TEXT | 备注 |
### 体重记录 (weight)
| 字段 | 类型 | 说明 |
|-----|------|-----|
| id | INTEGER | 主键 |
| date | DATE | 日期 |
| weight_kg | FLOAT | 体重(公斤) |
| body_fat_pct | FLOAT | 体脂率(可选) |
| muscle_mass | FLOAT | 肌肉量(可选) |
| notes | TEXT | 备注 |
### 用户配置 (config)
| 字段 | 类型 | 说明 |
|-----|------|-----|
| age | INTEGER | 年龄 |
| gender | TEXT | 性别 |
| height | FLOAT | 身高(厘米) |
| weight | FLOAT | 当前体重 |
| activity_level | TEXT | 活动水平 |
| goal | TEXT | 目标(减重/维持/增肌) |
| bmr | INTEGER | 基础代谢(自动计算) |
| tdee | INTEGER | 日常总消耗(自动计算) |
---
## CLI 命令设计
```bash
# ===== 数据记录 =====
vitals log weight 72.5 # 记录体重
vitals log weight 72.5 --fat 18.5 # 带体脂率
vitals log meal 早餐 "燕麦+鸡蛋+牛奶" # 记录饮食
vitals log meal 午餐 --photo ~/lunch.jpg # 拍照记录饮食
vitals log sleep 23:30 07:00 --quality 4 # 记录睡眠
vitals log exercise 跑步 30min --distance 5km # 手动记录运动
# ===== 数据导入 =====
vitals import garmin ~/Downloads/export.zip # 导入佳明数据
vitals import codoon ~/Downloads/codoon.json # 导入咕咚数据
vitals import csv ~/data.csv --type weight # 通用CSV导入
# ===== 数据查看 =====
vitals show today # 今日概览
vitals show week # 本周汇总
vitals show weight --days 30 # 最近30天体重趋势
# ===== 报告生成 =====
vitals report week # 生成周报(终端输出)
vitals report week --output report.html # HTML导出
vitals report week --output report.md # Markdown导出
vitals report week --output report.pdf # PDF导出
vitals report week --output report.png # 图片导出
vitals report month # 生成月报
# ===== 个人配置 =====
vitals config set --age 28 --gender male --height 175 --weight 72
vitals config set --activity-level moderate
vitals config set --goal lose
# ===== Web 仪表盘 =====
vitals dashboard # 启动本地Web服务
```
**设计说明:**
- 日期默认今天,可用 `--date 2024-01-15` 覆盖
- 根据文件后缀自动选择导出格式
- 图片导出宽度 1080px适配手机分享
---
## 数据导入适配器
### Garmin 佳明
**导入方式:**
- 从 Garmin Connect 网站导出数据包 (ZIP格式)
- 或通过 Garmin Connect API需授权
**支持数据:**
- 运动记录:跑步、骑行、游泳、力量训练等
- 睡眠数据:入睡/起床时间、深睡/浅睡时长
- 心率数据:静息心率、运动心率
- 体重数据:如使用 Garmin 体重秤
**文件解析:** ZIP 包内含 FIT 文件和 JSON 摘要,优先解析 JSON
### 咕咚 Codoon
**导入方式:** 咕咚APP → 设置 → 数据导出 → 下载 JSON/GPX 文件
**支持数据:**
- 运动记录:跑步、健走、骑行
- 运动轨迹GPX 格式,可选保留
- 运动统计:配速、心率、卡路里
### 去重策略
- 同一天 + 同一运动类型 + 时间差 <5分钟 视为重复
- 保留规则优先保留数据更完整的记录
- 冲突提示发现疑似重复时询问用户处理方式
---
## 卡路里管理
### 食物卡路里推算
**文字输入:**
```bash
vitals log meal 午餐 "一碗米饭+红烧肉+炒青菜"
# 系统自动解析:
# → 米饭(200g): 230卡
# → 红烧肉(100g): 320卡
# → 炒青菜(150g): 45卡
# → 总计: 595卡
```
**图片输入:**
```bash
vitals log meal 午餐 --photo ~/lunch.jpg
# 系统识别:
# → 检测到: 米饭、红烧排骨、西兰花
# → 估算热量: 约 680 卡
```
**技术实现:**
- 内置常见食物数据库 2000+ 种中国常见食物
- 支持自然语言描述智能拆分食物条目
- 图片识别优先使用 Claude Vision API备选本地模型
- 用户修正后记入个人食物库提升准确度
**图片存储:**
- 原图保存至 `~/.vitals/photos/YYYY/MM/DD-meal_type.jpg`
- 可选压缩存储节省空间
### 每日卡路里收支
```
┌─────────────────────────────────────────────────┐
│ 今日卡路里收支 │
├─────────────────────────────────────────────────┤
│ 基础代谢 (BMR) 1,650 卡 │
│ + 日常活动消耗 330 卡 │
│ + 运动消耗 420 卡 │
│ ───────────────────────────────── │
│ = 今日总消耗 2,400 卡 │
│ │
│ - 早餐 470 卡 │
│ - 午餐 595 卡 │
│ - 晚餐 680 卡 │
│ ───────────────────────────────── │
│ = 今日摄入 1,745 卡 │
│ │
│ 差值: -655 卡 (热量缺口,有助于减重) │
└─────────────────────────────────────────────────┘
```
---
## Web 仪表盘
**技术选型:**
- 后端FastAPI
- 前端HTML + Chart.js
- 运行`vitals dashboard` 启动访问 http://localhost:8080
**页面结构:**
- 首页今日概览 + 卡路里收支 + 趋势图表
- 运动页运动历史列表 + 统计图表
- 饮食页饮食记录日历视图 + 图片回顾
- 睡眠页睡眠质量趋势
- 体重页体重变化曲线 + 目标线
- 报告页生成和下载周报/月报
---
## 报告生成
### 输出格式
| 格式 | 说明 |
|-----|------|
| 终端 | 彩色文本直接查看 |
| HTML | 精美排版浏览器打开 |
| Markdown | 方便存档 |
| PDF | 正式文档 |
| PNG | 适合分享到微信/朋友圈宽度 1080px |
### 周报内容
- 本周概览运动次数总时长消耗卡路里
- 睡眠统计平均时长质量评分
- 体重变化起止体重变化量
- 卡路里收支平均每日摄入 vs 消耗
- 运动详情每日运动记录
- 趋势洞察与上周对比进展评估
### 月报额外内容
- 月度目标完成情况
- 与上月同期对比
- 本月最佳/最差记录
- 长期趋势分析
---
## 项目结构
```
vitals/
├── pyproject.toml # 项目配置
├── README.md
├── src/vitals/
│ ├── __init__.py
│ ├── cli.py # CLI 入口
│ │
│ ├── core/
│ │ ├── models.py # 数据模型
│ │ ├── database.py # SQLite 操作
│ │ ├── calories.py # 卡路里计算
│ │ └── report.py # 报告生成
│ │
│ ├── importers/
│ │ ├── base.py # 适配器基类
│ │ ├── garmin.py # 佳明导入
│ │ ├── codoon.py # 咕咚导入
│ │ └── csv.py # CSV导入
│ │
│ ├── vision/
│ │ ├── analyzer.py # 食物识别
│ │ └── providers/
│ │ ├── claude.py # Claude Vision
│ │ └── local.py # 本地模型
│ │
│ ├── web/
│ │ ├── app.py # FastAPI
│ │ ├── static/
│ │ └── templates/
│ │
│ └── data/
│ └── food_database.json # 食物热量库
├── tests/
└── docs/
```
---
## 技术依赖
| | 用途 |
|---|------|
| typer | CLI 框架 |
| sqlite3 | 数据库内置 |
| fastapi | Web 框架 |
| uvicorn | ASGI 服务器 |
| chart.js | 前端图表 |
| weasyprint | PDF 导出 |
| playwright / html2image | 图片导出 |
| anthropic | Claude API食物识别 |
---
## 下一步
1. 初始化项目结构
2. 实现核心数据模型和数据库
3. 实现 CLI 基础命令
4. 实现数据导入适配器
5. 实现卡路里计算和食物识别
6. 实现 Web 仪表盘
7. 实现报告生成