MealPick 是一个零依赖静态网站,用来回答“今天吃什么”。它以 Anduin2017/HowToCook 为核心数据源,在浏览器本地完成菜谱浏览、成员档案管理、整桌搭配推荐和营养估算。
当前本地生成数据来自 HowToCook commit b457738abd37d2621f22d59ff9fb065fcc4528da,收录 364 道菜谱,其中 183 道带有已本地化的真实图片。HowToCook 使用 Unlicense,本项目会在页面中保留来源链接和来源 commit。
注意:开源主仓库默认不提交生成后的 data/recipes.js 和 assets/recipe-images/ 图片文件。它们可以通过脚本从 HowToCook 重新生成,本地预览和部署产物可以包含这些文件。
- 根据用餐场景、用餐成员、时间上限、饮食限制、咸淡、辣度、已有食材和避开食材推荐菜品。
- 支持多个成员档案;年龄、性别、身高、体重、活动量和长期目标保存在浏览器
localStorage,不会作为 cookie 发给服务器。 - 个人档案设置可折叠;每次选菜前可多选本顿用餐成员,推荐会汇总被选成员的热量、蛋白和钠目标。
- 今日搭配会拼出一组菜,并按主动操作时间、可重叠等待时间和菜之间切换开销估算整桌耗时。
- 整桌搭配会额外检查合计热量、蛋白和钠,避免单菜都高分但整桌明显超目标。
- 使用可解释的非深度学习规则打分:时间、目标、营养、咸淡、荤素/主食/汤粥搭配、食材命中和忌口都会进入推荐逻辑。
- 从 HowToCook Markdown 提取原料、用量、操作步骤和附加内容;菜谱详情在本地弹窗中展示,不需要跳转到 GitHub 才能看做法。
- 用本地营养规则表估算热量、蛋白、脂肪、碳水和钠,并展示估算可靠度;明显偏离 HowToCook 原始热量的条目会做 sanity 校准。
- 支持 HowToCook 的 Git LFS 图片本地化;没有配图的菜会显示“无配图”占位。
- 移动端优先展示今日搭配,调整条件放在搭配之后、推荐列表之前。
python3 -m http.server 5173然后打开:
http://localhost:5173/
这是静态网站,不需要后端服务、数据库或 npm 依赖。
先把 HowToCook 克隆到本地:
git clone https://github.com/Anduin2017/HowToCook.git /path/to/HowToCook如果希望图片完整显示,需要先下载 HowToCook 的 Git LFS 图片对象。本机不一定安装了 git-lfs,所以项目内提供了一个直接调用 GitHub LFS API 的脚本:
node scripts/download-howtocook-lfs-images.mjs /path/to/HowToCook只查看需要下载多少图片和体积:
node scripts/download-howtocook-lfs-images.mjs /path/to/HowToCook --dry-run下载完图片后,重新抽取菜谱数据:
node scripts/extract-howtocook.mjs /path/to/HowToCook .生成结果会写入:
data/recipes.js:菜谱、营养估算、完整做法、来源信息。assets/recipe-images/:可用菜谱图片。
抽取后建议运行数据审计:
node scripts/audit-data.mjs审计会检查菜谱数量、完整做法、可解析食材、0 热量异常、极端钠估算,以及被 HowToCook 原始热量校准的条目。
为了让主仓库保持轻量,并避免把 HowToCook 的生成数据和图片直接塞进 Git 历史,本项目的 .gitignore 默认排除了:
data/recipes.jsassets/recipe-images/*
仓库中只保留目录占位文件、前端源码和数据生成脚本。这样做的含义是:
- 开发者 clone 后需要按“数据刷新”步骤生成菜谱数据和图片。
- 本地调试可以保留生成文件,但它们不会被普通
git add .加进主仓库。 - 如果要发布在线 demo,建议在部署流程、单独部署分支、release artifact 或对象存储中放生成后的数据和图片。
- 如果真的要把图片提交到某个仓库,应优先考虑单独的部署仓库或静态托管产物,而不是主源码仓库。
推荐算法在浏览器本地运行,不使用深度学习模型。它会先过滤不可接受的菜,再按规则打分:
- 时间:单菜耗时、整桌耗时、主动操作时间和等待时间。
- 个人目标:热量、蛋白、钠上限、减脂、增肌、控盐、控糖等。
- 菜品结构:蛋白、蔬菜、主食、汤粥是否搭配合理。
- 口味:清淡、偏咸、辣、油香等标签。
- 食材:已有食材会加分,避开食材会排除或降权。
整桌估时不是简单把每道菜相加。炒、煎、拌这类通常算主动操作时间;蒸、炖、烤、汤粥等会拆出等待时间,等待部分可以和其他菜重叠。菜单组合会在时间可行的基础上继续看整桌热量、蛋白和钠,不强行凑满三道菜。
营养值是工程估算,不是医学或营养诊断。估算基于 HowToCook 中的材料和用量,再匹配本地营养规则表。以下情况会带来误差:
- “适量”、可选食材、默认份量。
- 腌制后丢弃、焯洗、弃汤、蒸煮流失。
- 品牌差异和实际烹饪用油量。
- HowToCook 原菜谱未提供完整克数。
应用会展示估算可靠度,方便判断数值是否可靠。
解析脚本会对部分“不会全部吃掉”的材料做折算,例如炸制用油、腌制用盐和弃汤调味。对于材料估算与 HowToCook 原始热量相差过大的菜谱,会保留原始估算并用原始热量做 sanity 校准,同时降低估算可靠度。
前端仍然是零依赖静态网站,但核心逻辑已经拆成几个模块:
src/app.js:状态、渲染和交互入口。src/menu-planner.js:整桌耗时和菜单组合优化。src/image-fallbacks.js:图片加载失败后的本地占位处理。
MealPick 源码使用 MIT License。
核心菜谱数据来自 Anduin2017/HowToCook,当前抽取 commit 为 b457738abd37d2621f22d59ff9fb065fcc4528da。HowToCook 使用 Unlicense。MealPick 只做本地数据抽取、营养估算、推荐排序和前端交互封装,生成后的 data/recipes.js 与 assets/recipe-images/ 默认不提交到源码仓库。