Grocy 2.5.2 版本解读:家务周期调度升级、购物清单功能开关与日期输入快捷键全解析
2026/9/16 19:58:08 网站建设 项目流程

Grocy 2.5.2 版本解读:家务周期调度升级、购物清单功能开关与日期输入快捷键全解析

【免费下载链接】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 2.5.2(2019-10-05 发布)的官方变更记录,深入剖析该版本在库存、菜谱、购物清单、家务(Chores)与日期输入交互五大方向的具体改动。读者将掌握新增的FEATURE_FLAG_SHOPPINGLIST_MULTIPLE_LISTS子功能开关的配置方法、家务"年周期 + 周期间隔"调度体系的底层计算逻辑(含 SQL 视图实现)、以及日期字段的完整键盘快捷键速查表,并了解升级到该版本时数据库迁移的注意事项。

一、版本概览:一次以"家务调度"为重心的修复与增强

Grocy 2.5.2 是 2019 年 10 月 5 日发布的维护版本,紧随 2.5.0 / 2.5.1 之后。从变更记录看,该版本的核心工作集中在三块:

  1. 家务(Chores)模块的功能增强:新增yearly(每年)周期类型,并引入"周期间隔(period interval)"选项,使调度从"固定周期"走向"每 N 天/周/月/年"的灵活组合;
  2. 大量缺陷修复:覆盖库存(Stock)、菜谱(Recipes)两个核心业务模块;
  3. 交互效率优化:为日期字段新增以Shift + 方向键快速增减 1 个月/年的输入快捷键。

下面逐项结合源码剖析其实现与使用方式。

二、库存修复:产品特定数量单位换算覆盖的显示隔离

变更内容:修复了"产品特定数量单位换算(product overrides)在其他具有相同库存数量单位的产品编辑页上也被显示"的问题。

问题背景

在 grocy 中,每个产品可以定义默认数量单位(QU),也可以针对特定产品建立"产品级"的数量单位换算覆盖(即 product overrides)。2.5.2 之前的版本存在一个显示层 bug:当多个产品使用同一个库存数量单位时,某个产品的换算覆盖会被错误地渲染到其他产品的编辑页面上,造成数据混淆——例如给"面粉"配置的500g = 1袋换算,可能错误地出现在同样以克为单位的"砂糖"编辑页上。

修复要点

该问题属于视图(View)层的数据过滤缺陷,修复后每个产品的编辑页(对应views/productform.blade.php所在的表单渲染链路)只展示与自身产品 ID 严格匹配的换算覆盖,不再依据共享的数量单位 ID 做错误关联。从该版本起,涉及数量单位换算配置时,可以确认"一个产品的覆盖配置只会出现在它自己的编辑页"这一行为边界。

三、菜谱修复:总菜谱数超过 100 时成分缺失

变更内容:修复了"当菜谱总数 > 100 时,菜谱显示时缺少成分(ingredients)"的问题。

原因与影响

这是一个典型的分页/查询边界缺陷:当系统中菜谱总量超过 100 条后,菜谱详情页加载成分列表时使用的查询逻辑出现截断,导致成分列表为空或不全。修复后,无论菜谱总量多少,打开单个菜谱都能正确渲染全部成分行。

与菜谱展示相关的完整数据流可参见 controllers/RecipesController.php 与 services/RecipesService.php:前者负责页面路由与渲染参数装配,后者负责从数据库组装菜谱及其recipes_pos(成分明细)数据。2.5.2 的修复即落在这一查询链路的边界条件处理上。

四、购物清单改进:新增FEATURE_FLAG_SHOPPINGLIST_MULTIPLE_LISTS子功能开关

变更内容:新增子功能开关FEATURE_FLAG_SHOPPINGLIST_MULTIPLE_LISTS,用于在"只需要一个购物清单"的场景下禁用多清单功能;默认值为true,即未配置时行为与之前完全一致。

配置方式

该开关属于"子功能开关(Sub feature flags)"层级,在 config-dist.php 中与同组的其他子功能开关并列定义:

// Sub feature flags Setting('FEATURE_FLAG_STOCK_PRICE_TRACKING', true); Setting('FEATURE_FLAG_STOCK_LOCATION_TRACKING', true); Setting('FEATURE_FLAG_STOCK_BEST_BEFORE_DATE_TRACKING', true); Setting('FEATURE_FLAG_STOCK_PRODUCT_OPENED_TRACKING', true); Setting('FEATURE_FLAG_STOCK_PRODUCT_FREEZING', true); Setting('FEATURE_FLAG_STOCK_BEST_BEFORE_DATE_FIELD_NUMBER_PAD', true); Setting('FEATURE_FLAG_SHOPPINGLIST_MULTIPLE_LISTS', true); // ← 2.5.2 新增 Setting('FEATURE_FLAG_RECIPES_MEALPLAN', true); Setting('FEATURE_FLAG_CHORES_ASSIGNMENTS', true); Setting('FEATURE_FLAG_THERMAL_PRINTER', false);

与主功能开关(如FEATURE_FLAG_SHOPPINGLIST)不同,这个子开关不会整体隐藏"购物清单"模块,而是控制多清单能力的 UI 与逻辑分支:

  • true(默认):保留购物清单页面顶部的清单切换下拉框、New shopping list/Edit shopping list等列表操作菜单,支持维护多条清单;
  • false:隐藏清单选择器,购物清单页面退化为"单清单"模式,页面直接使用 id 为 1 的默认清单,界面更简洁。

源码中的实际作用点

该开关在前端三个位置生效,可以直观看到它的控制范围:

  1. 清单切换器渲染:views/shoppinglist.blade.php 中通过@if(GROCY_FEATURE_FLAG_SHOPPINGLIST_MULTIPLE_LISTS)决定是否渲染下拉切换器;为false时则退化为隐藏域selected-shopping-list(固定值为1),页面始终操作默认清单;
  2. 清单项表单:views/shoppinglistitemform.blade.php 中同样用该标志决定"添加到哪条清单"的选择控件是否出现;
  3. 清空清单确认文案:public/viewjs/shoppinglist.js 中,关闭多清单时确认弹窗文案由Are you sure you want to empty shopping list "%s"?简化为Are you sure you want to empty the shopping list?,避免单清单场景下出现无意义的清单名占位。

配置建议

  • 个人/家庭单用户场景:若只使用一条清单,可将该开关设为false以获得更干净的界面;
  • 多场景(如"日常采购"与"周末大采购"分清单)用户:保持默认true即可,无需任何改动。

注意:后续版本曾修复"当该开关为false时,某些操作后清单显示为空"的连带问题(见 changelog/55_2.6.0_2020-01-31.md),若你使用较新版本则无需担心此历史缺陷。

五、家务改进:yearly周期类型与周期间隔(period interval)

变更内容(本版本家务模块的两项核心增强):

  1. 新增周期类型yearly(每年),用于年度性家务安排;
  2. 新增每个家务的"周期间隔(period interval)"选项,适用于 daily / weekly / monthly / yearly 四类周期调度,含义是"每 N 天/周/月/年执行一次",例如可实现**双周(biweekly)**调度。

家务周期类型的完整集合

在服务层 services/ChoresService.php 中,定义了 2.5.2 起全部周期类型的常量:

const CHORE_PERIOD_TYPE_HOURLY = 'hourly'; const CHORE_PERIOD_TYPE_DAILY = 'daily'; const CHORE_PERIOD_TYPE_MANUALLY = 'manually'; const CHORE_PERIOD_TYPE_MONTHLY = 'monthly'; const CHORE_PERIOD_TYPE_WEEKLY = 'weekly'; const CHORE_PERIOD_TYPE_YEARLY = 'yearly'; // ← 2.5.2 新增 const CHORE_PERIOD_TYPE_ADAPTIVE = 'adaptive';

表单中的调度配置项

在 views/choreform.blade.php 的家务编辑表单中,调度相关字段按周期类型联动显示:

  • 周期类型(period_type):下拉选择,required,含上述全部类型;
  • 周期天数(period_days):仅对monthly生效(每月第几天),min = 0
  • 每周星期几复选:仅对weekly生效(周一至周日复选框),选择结果写入隐藏字段period_config
  • 周期间隔(period_interval):2.5.2 新增字段,min = 1,默认1;对hourly / daily / weekly / monthly / yearly五种周期类型均可见,语义为"每隔 N 个基本周期执行一次"(如period_interval = 2+daily即每两天一次,period_interval = 2+weekly即双周一次)。

底层计算逻辑(数据库视图)

家务的下次预计执行时间由数据库视图chores_current统一计算,2.5.2 通过迁移脚本 migrations/0164.sql 重建了该视图,其中period_interval参与各周期类型的推算:

  • dailyDATETIME(MAX(l.tracked_time), '+' || CAST(h.period_interval AS TEXT) || ' day')—— 上次执行时间 + N 天;
  • weekly:在启用的星期中,取"上次执行时间 + N×7 天(基于period_interval - 1计算偏移)后下一个匹配星期"作为下次执行时间;
  • monthlystart of month偏移 N 个月后再加period_days - 1天,即"每月第 N 天";
  • yearlyMAX(l.tracked_time) + N 年后,取其年份拼接start_date的月日部分,即"每年固定在 start_date 设定的月日执行"。

该视图同时处理manually(固定返回2999-12-31表示永不自动到期)、rollover(过期未做则顺延)等分支逻辑,并只聚合active = 1且未撤销(undone = 0)的跟踪记录,具体可查看 migrations/0164.sql。

迁移脚本对旧数据的兼容处理

migrations/0164.sql 不仅新建了period_intervalstart_date字段,还做了三项历史数据适配:

  1. chores表新增start_date(开始日期),并将已有家务的开始日期回填为最早一次跟踪时间;从未执行过的家务则回填为当天;
  2. 通过INSERT/UPDATE触发器保证新家务未显式填写开始日期时自动取当前时间;
  3. 将历史遗留的yearly周期数据转换为daily + period_interval = 365的等价表达(period_interval = IFNULL(period_interval, 1) * 365),确保旧数据迁移后调度语义不变。

配置示例:双周保洁

在"家务"页面新建/编辑家务时:

配置项说明
周期类型weekly按周调度
周期间隔2每 2 周执行一次
星期周六每周期的具体执行日
开始日期选择首次执行日期作为周期锚点

保存后,家务总览页会基于上述配置自动推算下一次预计执行时间。

六、通用改进:日期字段的键盘输入快捷键

变更内容:日期字段新增输入快捷键——通过Shift + 方向键可将日期增减 1 个月/年。

完整快捷键速查表

该能力实现在 public/viewjs/components/datetimepicker.js(前端日期时间选择器组件),综合普通方向键与 Shift 组合键,完整的按键行为如下:

按键效果
日期 -1 天
日期 +1 天
日期 -1 周
日期 +1 周
Shift + ↑日期 -1 个月
Shift + ↓日期 +1 个月
Shift + ←日期 -1 年
Shift + →日期 +1 年
空输入框 + 任意方向键自动填入今天

上述行为对仓库内所有使用日期/日期时间选择器组件的页面(如采购、消费、库存盘点、家务跟踪、任务等)统一生效,无需逐页面配置。

同期的其他日期输入技巧

在 2.5.2 前后,日期输入组件还支持若干文本快捷输入(同样位于 public/viewjs/components/datetimepicker.js):

  • 输入xX:快捷设为"永不过期"(内部表示为2999-12-31 23:59:59);
  • 输入+3d/-2m/+1y:相对今天增减 N 天/月/年;
  • 输入 4 位数字(如1015):解析为MMDD,若早于今天则自动顺延到下一年;
  • 输入 8 位数字(如20191005):解析为YYYY-MM-DD

这些快捷键与方向键组合共同构成了 grocy 高效的日期录入体系,尤其适合在购买页批量录入保质期等场景。

七、升级到 2.5.2 的注意事项

从变更记录与迁移脚本可以总结出以下升级要点:

  1. 数据库会自动迁移:本次升级包含迁移脚本 migrations/0164.sql,会自动为chores表新增start_dateperiod_interval字段并重建chores_current视图,无需手工操作,但升级前仍建议备份数据库;
  2. 旧数据兼容:存量家务的开始日期会被自动回填为最早跟踪时间;历史yearly类型数据会被自动转换为等价的daily + 365表达,调度不会错乱;
  3. 新功能默认开启FEATURE_FLAG_SHOPPINGLIST_MULTIPLE_LISTS默认true,不修改配置则升级前后行为一致;需要精简界面再将其改为false
  4. 升级方式:标准 grocy 升级流程为备份数据目录后,以新版本文件覆盖部署并执行一次页面访问以触发数据库迁移(update.sh与版本文件 version.json 记录了发布版本信息)。

八、小结

Grocy 2.5.2 通过"家务年度周期 + 周期间隔"的组合,将家务调度从"固定每天/每周"扩展为"每 N 天/周/月/年"的灵活模式,配合yearly类型在数据库视图层完成推算;同时以新增子功能开关的方式,让单清单用户能够按需精简购物清单界面;库存与菜谱的两个显示缺陷修复则提升了数据展示的准确性。日期字段的 Shift 快捷键则从交互层面提升了采购、盘点等高频录入场景的效率。该版本是 2.5.x 系列中家务调度能力成型的关键节点,其调度模型与开关设计在此后的版本中持续沿用。

【免费下载链接】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),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询