news 2026/9/16 22:31:29

Grocy 1.14.0 新特性深度解析:Recipes 菜谱模块如何打通库存与购物清单

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Grocy 1.14.0 新特性深度解析:Recipes 菜谱模块如何打通库存与购物清单

Grocy 1.14.0 新特性深度解析:Recipes 菜谱模块如何打通库存与购物清单

【免费下载链接】grocyERP beyond your fridge - Grocy is a web-based self-hosted groceries & household management solution for your home项目地址: https://gitcode.com/GitHub_Trending/gr/grocy

Grocy 1.14.0(2018-07-15)是本项目发展史上具有里程碑意义的一次发布——它首次引入了Recipes(菜谱)功能,将"库存管理"与"居家做饭"两个场景打通:你可以把一组产品、数量与说明文字组织成一份菜谱,随时查看所需原料是否全部在库,并把缺失的原料一键加入购物清单。本文以 changelog/27_1.14.0_2018-07-15.md 为骨架,结合当前仓库的数据库迁移脚本与 Recipes 相关源码,还原该版本的核心改动,并补充可直接落地的使用与扩展细节。

版本速览:1.14.0 带来了什么

对照变更日志,本次版本的核心内容可归纳为四类:

类别具体改动
核心新功能引入Recipes(菜谱):把产品、数量与说明组织成菜谱;一键查看原料库存匹配情况;一键把缺失原料加入购物清单
本地化新增挪威语(Norwegian)翻译,由社区贡献者 @BlizzWave 提供
UI 改进表格列可拖拽重排;购物清单页内嵌日历;列排序与排序状态被记住;侧边栏折叠状态被记住;修复日期时间选择器边框;激活子菜单时保持父级菜单展开
自定义机制自定义 JS/CSS 文件名发生变更(详见下文第 5 节)

其中Recipes 是整个 Grocy 从"库存工具"走向"家庭管理平台"的关键一步,也是本文展开的重点。

Recipes 功能全景:从菜谱定义到一键补货

数据模型:菜谱与菜谱原料行

从 migrations/0025.sql 可以看到该功能最初落库时的两张核心表:

  • recipes:菜谱主表,字段为idname(菜谱名)、description(说明文字)、row_created_timestamp
  • recipes_pos:菜谱原料行,字段为idrecipe_id(所属菜谱)、product_id(对应产品)、amount(数量)、note(备注)。

也就是说,1.14.0 的菜谱模型就是"菜谱 = 一个名称 + 一段描述 + 若干原料行",原料行通过product_id与产品主数据(stockoverview 中的产品)关联,amount即所需数量。这份结构延续至今,后续版本在此基础上不断加列增强(见第 6 节)。

库存匹配逻辑:recipes_fulfillment 视图

菜谱"原料是否齐备"的判断并非写死在 PHP 里,而是由数据库视图完成。同一迁移文件 migrations/0025.sql 中定义了recipes_fulfillment视图,其核心计算逻辑为:

  • recipe_amount:菜谱要求的数量;
  • stock_amount:当前库存量(来自stock_current视图);
  • need_fulfilledstock_amount >= recipe_amount时为 1,否则为 0(即"该原料是否满足需求");
  • missing_amountstock_amount - recipe_amount为负时的绝对值,即缺口数量;
  • amount_on_shopping_list:该产品当前在购物清单上的数量(含amount_autoadded自动追加部分);
  • need_fulfilled_with_shopping_list:库存加购物清单合计是否满足需求。

配套的recipes_fulfillment_sum视图则对每份菜谱做聚合:只要有一行原料未满足,整份菜谱的need_fulfilled就为 0,并统计missing_products_count(缺失原料种类数)。这就是"一眼看出菜谱是否齐备"的底层来源。

一键补缺:把缺失原料加入购物清单

变更日志承诺的"把缺失的东西一键放到购物清单上"由 RecipesService::AddNotFulfilledProductsToShoppingList 实现,其流程为:

  1. 取该菜谱所有解析后的原料行(recipes_pos_resolved),过滤出属于当前菜谱、且不在excludedProductIds排除列表中的行;
  2. 计算需采购量:missing_amount - amount_on_shopping_list(已在清单上的部分不再重复加);
  3. 对购物清单上已存在的该产品条目执行"累加金额"更新,否则新建条目(记录product_idamountqu_id)。

对外暴露的 API 端点为POST /api/recipes/{recipeId}/add-not-fulfilled-products-to-shoppinglist(见 routes.php 与 RecipesApiController.php),该接口要求调用者具备PERMISSION_SHOPPINGLIST_ITEMS_ADD权限,请求体可携带excludedProductIds数组实现"部分排除"。

消耗菜谱与"自产"记账

除了"看缺什么",1.14.0 的 Recipes 还支持按菜谱消耗库存。核心实现位于 RecipesService::ConsumeRecipe:

  • 整个过程包裹在数据库事务中(beginTransaction/commit/rollback),任一原料消耗失败即整体回滚;
  • 遍历每行原料,当stock_amount > 0时调用StockService::ConsumeProduct消耗库存;若库存不足(stock_amount < recipe_amount),则只消耗当前实际库存量;
  • 若菜谱配置了"产出产品"(product_id),随后会通过StockService::AddProductTRANSACTION_TYPE_SELF_PRODUCTION(自产)事务类型把成品加回库存,并写入菜谱名作为来源备注——这为后续"自制果酱""自制面包"等场景奠定了数据基础。

从 routes.php 看,其 API 端点为POST /api/recipes/{recipeId}/consume,并校验PERMISSION_STOCK_CONSUME权限(见 RecipesApiController.php)。

配套页面与路由

1.14.0 同期提供了完整的菜谱 UI,当前仓库中对应页面包括:

  • GET /recipes:菜谱概览页 recipes.blade.php,展示菜谱及其原料匹配状态;
  • GET /recipe/{recipeId}:菜谱编辑页 recipeform.blade.php;
  • GET /recipe/{recipeId}/pos/{recipePosId}:原料行编辑页 recipeposform.blade.php;
  • GET /recipessettings:菜谱设置页 recipessettings.blade.php;
  • GET /recipe/{recipeId}/grocycode:生成菜谱 Grocycode(二维码)图片,实现"扫一个码定位一份菜谱"(见 RecipesController::RecipeGrocycodeImage)。

路由注册集中在 routes.php,页面渲染逻辑见 RecipesController。

本次 UI 改进:可记忆、可重排的表格体验

1.14.0 的 UI 改动集中在交互记忆与表格操作上:

  • 表格列可重排:各列表格的列顺序支持拖拽调整;
  • 排序状态被记住:列排序方向与顺序在页面刷新后依然保留;
  • 侧边栏折叠状态被记住:收起/展开侧边栏后,下次访问保持上次状态;
  • 父级菜单保持展开:当激活页面是某个子菜单项时,其父级菜单项保持展开,避免导航层级跳变;
  • 购物清单页新增日历:变更日志提到作者本人也认为"有用"的内嵌日历,为购物计划提供日期参考;
  • 修复日期时间选择器边框:修正控件外观细节。

这些属于前端交互层的打磨(对应 public/viewjs 下的前端逻辑),核心收益是让高频操作页面(库存、购物清单、菜谱)用起来更顺手

自定义 CSS/JS 注入机制与文件名变更

1.14.0 变更了自定义样式与脚本的文件名。按当前 README.md 的说明,该机制的最终形态为:

  • data/custom_css.html文件存在时,其内容会被注入到每个页面的</head>之前
  • data/custom_js.html文件存在时,其内容会被注入到每个页面的</body>之前

页面布局层 default.blade.php 与 default.blade.php 分别通过file_exists(GROCY_DATAPATH . '/custom_css.html')custom_js.html判断并include注入。这意味着:无需修改应用本体代码,即可在data目录放置自定义 HTML/CSS/JS 片段实现品牌化、埋点或样式覆盖,升级 Grocy 时自定义内容也不会丢失。1.14.0 正是把这些文件的命名约定固定下来的版本。

多语言支持:挪威语加入

1.14.0 新增了挪威语翻译(由 @BlizzWave 贡献)。Grocy 的本地化采用 gettext 体系,翻译文件以.po形式存放于 localization 目录(当前仓库已包含no/语言包,内含strings.polocales.popermissions.po等),后续版本也持续沿用了"社区贡献翻译 + 独立 demo 站点"的协作模式。

从 1.14.0 到当前版本:Recipes 模块的持续演进

需要说明的是:本文所引用的迁移脚本与源码来自当前仓库,属于该功能历经多个版本演进后的形态。从源码结构看,1.14.0 之后 Recipes 模块至少经历了以下增强,可作为你阅读 services/RecipesService.php 与 migrations 目录时的参考线索:

  • 原料行支持独立计量单位与换算(migrations/0045.sql 为recipes_pos加入qu_idonly_check_single_unit_in_stock(仅检查是否有任意数量在库)、ingredient_group(原料分组)、not_check_stock_fulfillment(不参与库存匹配检查),并通过触发器在新增原料行时自动回填产品的qu_id_stock);
  • 菜谱嵌套(recipes_nestings,一份菜谱包含另一份菜谱)与"产出产品/按份数"(recipes.product_idbase_servings/desired_servings)能力,从 RecipesService::CopyRecipe 的复制逻辑可窥一斑;
  • 用餐计划(Meal Plan)模块:RecipesService中定义了RECIPE_TYPE_MEALPLAN_DAYRECIPE_TYPE_MEALPLAN_WEEKRECIPE_TYPE_MEALPLAN_SHADOW等内部菜谱类型(services/RecipesService.php),对应的日历视图见 mealplan.blade.php;
  • 其他 API 能力:菜谱复制POST /api/recipes/{recipeId}/copy、匹配状态查询GET /api/recipes/{recipeId}/fulfillment、标签打印GET /api/recipes/{recipeId}/printlabel(路由见 routes.php)。

小结

Grocy 1.14.0 用一套简洁的"菜谱 + 原料行"数据模型,撬动了库存查询、缺料补单、消耗记账三个核心流程,其设计骨架(视图计算匹配、事务化消耗、API 化补单)在此后多个版本中持续复用与扩展。对于希望深入理解 Grocy 的读者,建议按以下路径继续探索:

  1. 先读 migrations/0025.sql 与 migrations/0045.sql,掌握菜谱相关表与视图的演进;
  2. 再读 services/RecipesService.php 与 controllers/Api/RecipesApiController.php,理解补单、消耗、复制等操作的服务层实现;
  3. 最后对照 routes.php 与 RecipesController.php 把"页面 → 路由 → 服务 → 数据库"这条调用链串起来。

若想在自建实例上体验,只需将 Grocy 部署后访问/recipes创建菜谱并添加原料行,再回到库存页补足库存,即可直观看到recipes_fulfillment视图中need_fulfilledmissing_amount字段的实时变化。

【免费下载链接】grocyERP beyond your fridge - Grocy is a web-based self-hosted groceries & household management solution for your home项目地址: https://gitcode.com/GitHub_Trending/gr/grocy

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/16 22:26:49

智能体技能工程体系:TypeScript + Nx + 语义化发布实战

1. 项目概述&#xff1a;这不是一个“技能库”&#xff0c;而是一套可复用、可验证、可演进的智能体能力工程体系你搜“agent-skills”时&#xff0c;看到的多半是零散的 GitHub 仓库、某篇博客里几行代码示例&#xff0c;或是面试题里一句“请手写一个工具调用函数”。但真正做…

作者头像 李华
网站建设 2026/9/16 22:23:13

微信小程序点餐系统毕设源码(Spring Boot+MySQL)

简介&#xff1a;这是一套面向计算机专业本科生的微信点餐系统毕业设计/课程设计完整源码&#xff0c;适用于小程序开发入门到进阶实践&#xff0c;解决从菜单展示、用户下单、订单管理到后台数据交互的一站式学习需求。资源共1285个文件&#xff0c;涵盖138个Vue页面组件&…

作者头像 李华