docs: 添加 Vitals 健康管理应用设计文档

- 综合健康管理:运动、饮食、睡眠、体重
- CLI + Web 仪表盘双交互模式
- 支持佳明/咕咚数据导入
- 智能卡路里计算,支持拍照识别食物
- 周报/月报多格式导出(HTML/PDF/PNG)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
Rocky
2026-01-17 22:11:13 +08:00
commit b5b2eba6f8

View File

@@ -0,0 +1,368 @@
# 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. 实现报告生成