grocy 3.1.2 变更日志深度解析:库存、购物清单与 API 过滤器的 8 项修复实践指南

📅 发布时间:2026/9/16 11:11:20
grocy 3.1.2 变更日志深度解析:库存、购物清单与 API 过滤器的 8 项修复实践指南
grocy 3.1.2 变更日志深度解析库存、购物清单与 API 过滤器的 8 项修复实践指南【免费下载链接】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 3.1.22021-09-27 发布这一维护版本的 官方变更日志 展开逐一拆解其中 8 项库存/购物清单/日程/UI 修复与 1 项 API 修复的实现背景与影响。读完本文你将掌握这些 bug 的成因、对应的源码修复点以及在实际使用 grocy 时如何规避与验证这些行为——适合正在维护 grocy 实例或研究其库存核心逻辑的开发者与自托管用户。版本背景一次典型的缺陷修复维护版grocy 3.1.2 属于 3.x 稳定线内的一个补丁版本patch release。从 version.json 可以看出当前仓库主线已演进到 4.6.0而 3.1.2 是介于 3.1.1 与 3.1.3 之间的短期修正版不包含新特性全部条目均为 bug 修复与细微 UI 优化。这类版本非常适合用来观察 grocy 库存引擎StockService在边界条件下的行为约定。整个变更日志共 10 个条目可归纳为四大类库存事务正确性条目 1、3、4、5、6涉及购买、消费、转移、撤销Undo四条核心链路的边界条件本地化与复数规则条目 2数量单位复数字符串在负数场景下的处理日程导出条目 7iCal 导出的健壮性用户体验与 API条目 8、9、10编辑页交互、产品创建流程与查询过滤器字符集。修复一购物清单“将全部条目加入库存”在 6 项以上失效Fixed that the Add all list items to stock shopping list workflow did not work for more than ~6 items (thanks tjhowse)“将清单全部条目加入库存”是 grocy 购物清单页面的一个批量操作用户勾选多个清单项后一键入库。该 bug 表现为当清单项数量超过约 6 个时整个批量入库流程失败。从源码结构看此操作对应 StockService.php 中的AddProduct()services/StockService.php等库存写入入口的批量组合调用以及购物清单视图 shoppinglist.blade.php 中相关的批量处理逻辑。该问题编号 #1500由 tjhowse 报告并协助修复根因是批量处理时单个条目的结果状态如stock_id、transaction_id在超过约 6 项后未正确传播导致后续条目无法完成事务。修复后无论清单项数量多少批量入库都能完整执行。实操验证在购物清单页添加 10 个以上条目勾选全部后点击“将全部条目加入库存”再进入“库存概览”页面确认所有产品均已入库且库存日志stock journal逐条可查。修复二负数场景下数量单位复数形式错误Fixed that plural form handling (e.g. for quantity units) was wrong for negative numbersgrocy 的本地化系统支持带复数规则的翻译gettext 复数形式如英语中1 item与2 items的区别。原实现仅按数值的绝对值或按 1判断单复数导致负数例如消费-1件、盘点差异为-2时选择了错误的词形。修复后复数选择基于数值本身的规则判断多数语言下-1应视为单数形式数量单位名称在消费、库存日志、报告等所有展示位置保持一致。相关路径数量单位名称由 quantityunits.blade.php、quantityunitpluraltesting.blade.php 等视图展示翻译资源位于 localization 目录下各语言的.po文件与 strings.pot。grocy 还内置了“数量单位复数形式测试”页面方便在配置数量单位时即时预览复数结果。实操建议在“数量单位”设置中为某个单位配置复数形式后可利用quantityunitpluraltesting页面输入 -2、-1、0、1、2 等值验证词形选择是否符合预期特别是非英语区域如俄语、捷克语等多复数规则语言。修复三库存量 1 时“消费/转移”菜单项被误禁用Fixed that the context menu entriesConsumeandTransferon the stock overview page were disabled when the amount in stock was 1库存概览页每行产品的右键/三点上下文菜单中Consume消费与Transfer转移项此前按“库存数量 1”即置为禁用状态。这在逻辑上是错误的grocy 允许库存量为小数例如 0.5 千克、0.25 升此时依然应该可以消费或转移部分数量。当前仓库源码中该逻辑已调整见 views/stockoverview.blade.phpConsume项使用if($currentStockEntry-amount_aggregated 0) disabled endif判断amount_aggregated为聚合后的总库存量仅在小于等于 0 时才禁用Transfer项受GROCY_FEATURE_FLAG_STOCK_LOCATION_TRACKING特性开关控制使用if($currentStockEntry-amount 0) disabled endif判断。即修复前 1的误判在 3.1.2 后变为真正的 0无库存才禁用。这也印证了 grocy 的库存模型支持分数数量AddProduct()等方法的float $amount参数services/StockService.php允许任意正小数。实操验证对库存量为 0.5 的产品行打开上下文菜单应看到Consume与Transfer均为可点击状态将库存清空至 0 后二者应变为禁用。修复四非默认位置消费时库存日志记录了错误位置Fixed that on consuming a product from not the products default location, the products default location was recorded in the stock journalgrocy 支持“库存位置跟踪”特性GROCY_FEATURE_FLAG_STOCK_LOCATION_TRACKING产品可分散存放在多个位置。消费时用户可以选择从某个具体位置扣减对应ConsumeProduct()的$locationId参数services/StockService.php。此前的缺陷是当从非产品默认位置消费时stock_log中记录的却是产品的默认位置导致日志与实际的扣减位置不一致。影响面库存日志stock journal是所有统计、撤销操作与审计的基础位置记录错误会进一步影响“位置内容清单”locationcontentsheet等依赖位置的报表。实操验证为产品设置默认位置 A手动入库一部分到位置 B再从位置 B 消费随后查看库存日志该条记录的位置应显示为 B。修复五撤销非默认位置的消费事务时数量错误地加回默认位置Fixed that when undoing a stock consume transaction from not the products default location, the corresponding amount was always added back to the products defaullt location这是修复四在“撤销”链路上的孪生 bug。grocy 的撤销由StockService::UndoBooking()services/StockService.php实现先校验该stock_log记录存在且未被撤销undone 0并检查是否存在后续依赖事务services/StockService.php满足条件后将扣减数量回补。修复前回补操作硬编码写回了产品默认位置未沿用原消费时的位置信息修复后回补位置与原消费位置一致避免库存“在错误位置凭空多出一份”。实操验证按修复四的步骤消费后再点击撤销确认数量回到位置 B 而非默认位置 A。修复六默认购买数量单位存在多个换算时可能选错换算因子Fixed that when having multiple quantity unit conversions for a products default QU purchase, on purchase was potentially a wrong conversion factor pickedgrocy 的数量单位换算体系允许为产品的“购买单位”qu_id_purchase见 services/StockService.php 中入库时对qu_id_purchase的引用与“库存单位”qu_id_stock配置多条换算关系。此前的缺陷是当同一对单位之间存在多条换算记录时购买入库可能选中错误的换算因子导致入库数量与用户输入不符。换算关系的定义与校验位于 quantityunitconversionform.blade.php 与 quantityunitconversionsresolved.blade.php“已解析的换算”页面用于展示实际生效的换算链。修复后购买时的换算因子选择遵循确定性的解析规则优先直接换算、按明确指定的因子不再受多条记录顺序影响。实操建议若某产品同时存在“克→千克”与“克→袋500 克”等多条换算购买时输入数量后留意页面上的换算预览是否正确可在“数量单位换算已解析”页面核对最终生效的换算链。修复七无“下次预计跟踪”时间的日程任务导致 iCal 导出损坏Fixed that when there was any chore with a schedule, but without a next estimated tracking date/time, the iCal export was brokengrocy 的日历页面支持以 iCal 格式导出/订阅该能力自 2.0.0 起提供见 changelog/43_2.0.0_2019-03-06.md。日程类任务chore依赖“下次预计跟踪时间”next estimated tracking date/time生成日历事件。当某个 chore 配置了调度规则、但尚未计算出该时间时旧实现直接引用空值导致 iCal 流整体损坏无法解析或订阅失败。修复后此类 chore 在导出时会被安全跳过或降级处理保证整个 iCal 流始终合法。相关路径日历与导出逻辑位于 CalendarController.php 与 CalendarService.phpchore 调度配置见 choreform.blade.php。实操验证创建一个带调度、但清空“下次预计跟踪”时间的 chore打开日历页执行 iCal 导出或复制订阅地址用任意日历客户端验证流可正常解析。修复八UI 体验——底部粘性保存按钮与创建时即可上传产品图The product and chore edit pages now have bottom-sticky save buttonsA product picture can now be added when creating a product (was currently only possible when editing a product)两项体验优化底部粘性保存按钮产品编辑页与 chore 编辑页的表单较长此前需要滚动到页面底部才能点击保存。3.1.2 起保存按钮固定在视口底部bottom-sticky无论滚动位置都可直接保存减少误操作与滚动成本。对应页面为 productform.blade.php 与 choreform.blade.php。创建产品即可上传图片此前产品图片只能在“编辑产品”时添加现在“新增产品”productform 的创建模式直接提供图片上传字段一次填完表单即可完成产品建档与配图减少一次往返。产品图片由 FilesService.php 统一管理上传的图片会自动缩放以优化加载。API 修复查询过滤器允许国际字符与空格Fixed that international characters and spaces were not allowed in API query filtersgrocy 开放了完整的 REST API见 grocy.openapi.json所有列表接口支持统一的查询过滤器query filters用于按字段值筛选数据。此前的解析实现未正确编码/解码国际字符如中文、德语变音符与空格导致filter参数中包含此类字符时返回空结果或报错。修复后过滤器参数按 URL 编码规范处理任意 Unicode 字符与空格均可安全使用。实操验证以curl为例将产品名称含中文/空格的情况编码后过滤# 过滤名称包含 牛奶 的产品需按 URL 编码传入 curl -G http://your-grocy/api/objects/products \ -H GROCY-API-KEY: your_api_key \ --data-urlencode query[products][name][like]%牛奶% # 过滤名称包含空格的产品 curl -G http://your-grocy/api/objects/products \ -H GROCY-API-KEY: your_api_key \ --data-urlencode query[products][name][like]%olive oil%注意query过滤器参数的具体键名格式以当前版本的 grocy.openapi.json 为准推荐直接用--data-urlencode或编程语言的 URL 编码函数传递整个过滤表达式避免手工拼接。升级与验证清单若你正运行 grocy 3.1.1 或更早的 3.x 版本升级到 3.1.2 属于平滑补丁升级无破坏性变更、无迁移要求grocy 的数据库迁移机制会在访问首页时自动执行见 README.md。升级后建议按以下清单回归验证验证项操作预期结果批量入库购物清单勾选 10 项执行“全部加入库存”全部入库成功日志完整复数形式数量单位复数测试页输入 -2/-1/0/1/2词形选择符合语言规则菜单可用性库存量 0.5 的产品打开上下文菜单Consume/Transfer可点击非默认位置消费从位置 B 消费产品日志记录位置 B撤销消费撤销上一步消费数量回补到位置 BiCal 导出存在无“下次预计跟踪”时间的 chore 时导出日历日历流正常解析API 过滤过滤器参数含中文/空格正常返回匹配结果小结grocy 3.1.2 虽是小型维护版却集中反映了其库存引擎最核心的几条约定库存数量允许小数、位置跟踪必须贯穿消费/撤销全链路、数量单位换算需确定性解析。对于希望深入理解 grocy 内部行为的读者建议进一步阅读 services/StockService.php 中的AddProduct()、ConsumeProduct()、TransferProduct()与UndoBooking()四个核心方法以及 views/stockoverview.blade.php 中基于amount_aggregated/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),仅供参考