Grocy 4.5.0 版本更新详解:条码查询优化、库存概览增强与扫码引擎升级
【免费下载链接】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 4.5.0(2025-03-28 发布)聚焦于日常库存管理链路的三处关键打磨:内置 Open Food Facts 条码查询插件的健壮性优化、库存概览页新增"默认商店"列,以及前端相机扫码引擎由 Quagga2 全面切换为 ZXing(支持 2D 码)。同时,标签打印机 Webhook 增加了details与stock_entry字段,为外部打印服务提供了完整的数据上下文。阅读本文后,你将掌握这些更新的行为变化、底层实现依据以及升级后的使用方式。
本文以官方变更日志 changelog/80_4.5.0_2025-03-28.md 为主体骨架,并结合仓库源码、数据库迁移与前端实现进行纵深讲解。
Stock 模块更新
1. Open Food Facts 条码查询插件容错性优化
4.5.0 对内置的 Open Food Facts 外部条码查询插件(plugins/OpenFoodFactsBarcodeLookupPlugin.php)做了两处细节修复:
- 空的本土化产品名不再被采用:插件在请求 Open Food Facts API 时,会同时请求通用
product_name与基于当前语言环境的本地化字段product_name_<locale>(见源码第 17 行$productNameFieldLocalized的构造逻辑)。此前若本地化字段存在但内容为空,会覆盖掉正常的通用产品名;现在仅在本地化字段存在且非空时(第 55 行isset(...) && !empty(...)判断)才使用本地化名称,否则回退到通用product_name。 - 产品名中的非 ASCII 字符被忽略:部分条码数据源返回的产品名会夹杂换行符等控制字符,导致后续入库时生成异常的产品名称。4.5.0 之后此类字符不再影响产品创建流程。
该插件通过BaseBarcodeLookupPlugin基类接入,在 config-dist.php 中通过如下配置启用:
Setting('STOCK_BARCODE_LOOKUP_PLUGIN', 'OpenFoodFactsBarcodeLookupPlugin');启用后,扫码录入或手动输入条码时,插件会向https://world.openfoodfacts.org/api/v2/product/<条码>?fields=product_name,image_url,product_name_xx发起请求,并将返回结果映射为name、location_id、qu_id_purchase、qu_id_stock、__barcode、__image_url等字段(见插件第 60-68 行的返回结构)。其中仓库位置与采购/库存计量单位会优先采用用户在用户设置中预设的product_presets_location_id与product_presets_qu_id,未设置时则回退到第一个已存在的仓库位置与计量单位(第 40-51 行)。
2. 修复:带查询参数的图片 URL 不再生成非法文件名
此前,当外部条码查询插件返回的图片 URL 携带查询参数(如https://example.com/img.jpg?width=200)时,创建产品时会将该 URL 的尾部直接作为图片文件名写入,从而得到一个非法/无效的图片文件。4.5.0 修复了这一问题,确保只有有效的图片文件名才会被附加到新创建的产品记录上。这保证了后续在 views/productform.blade.php 等页面中展示产品图片时不会出现损坏的引用。
3. 库存概览页新增"默认商店"列(默认隐藏)
库存概览页(views/stockoverview.blade.php)新增了Default store(默认商店)列,该列展示每个产品配置的默认购物地点。出于界面整洁考虑,该列默认隐藏,用户可通过表格列设置手动开启。
该列的底层数据来自迁移脚本 migrations/0252.sql 重建的uihelper_stock_current_overview视图:视图通过LEFT JOIN shopping_locations sl ON p.shopping_location_id = sl.id关联产品默认购物地点,并输出sl.name AS default_store_name字段(第 16、82-83 行)。因此,该列展示的是产品上配置的默认购物地点名称,与购物清单页中的商店归属保持一致。同一次迁移还清理了两个旧的 DataTables 用户设置键(datatables_state_stock-overview-tablee等),用于重置旧版表格状态,避免列变更后出现显示异常。
General 模块更新
4. 非拉丁字符使用前端默认字体
此前 Web 前端指定的默认字体只覆盖拉丁字符集,导致中文、日文、韩文、西里尔文等非拉丁文字在界面中回退到系统字体,观感不一致。4.5.0 优化了字体栈,使非拉丁字符同样使用前端默认字体,统一了多语言界面(如保加利亚语)下的文字渲染效果。
5. 标签打印机 Webhook 新增details与stock_entry字段
标签打印机通过 Webhook 与外部打印服务通信,此前负载中仅包含product(产品名)、grocycode(Grocy 二维码)以及用户在 config-dist.php 中配置的GROCY_LABEL_PRINTER_PARAMS自定义参数。4.5.0 起,Webhook 负载新增:
details:完整的对象(产品 / 家务 / 电池等)详情;stock_entry:仅在打印库存条目标签时包含,携带完整的库存条目对象。
在 services/StockService.php 中可以看到实际组装逻辑(第 227-232 行与第 280-285 行):
$webhookData = array_merge([ 'product' => $productDetails->product->name, 'grocycode' => (string)(new Grocycode(Grocycode::PRODUCT, $productId, [$stockId])), 'details' => $productDetails, 'stock_entry' => $stockRow, ], GROCY_LABEL_PRINTER_PARAMS);其中details对应uihelper_product_details视图聚合出的完整产品信息(含last_purchased、last_used、stock_amount、stock_value、location、default_shopping_location_id等字段,见 services/StockService.php 第 776-820 行的返回结构);stock_entry为stock表中的整行记录。
Webhook 的发送由 helpers/WebhookRunner.php 执行:以 2 秒超时的 POST 请求发送,默认以form_params表单形式提交;若配置GROCY_LABEL_PRINTER_HOOK_JSON则切换为json格式(第 16-26 行)。这意味着外部打印服务现在可以直接读取details/stock_entry中的结构化数据来定制标签内容(如打印有效期、采购日期、当前库存),无需再依赖额外的二次查询。
该功能需满足GROCY_FEATURE_FLAG_LABEL_PRINTER与GROCY_LABEL_PRINTER_RUN_SERVER两个特性开关同时开启才生效(第 225、278 行)。
6. 相机扫码引擎:Quagga2 → ZXing
这是 4.5.0 中影响面最大的前端升级:驱动相机扫码的组件从 Quagga2 替换为 ZXing(感谢社区贡献者 @gergof)。替换后带来的变化:
- 整体识别性能更好:ZXing 的解码效率与稳定性优于此前的 Quagga2 实现;
- 支持 2D 条码:除 EAN-8、EAN-13、CODE_39、CODE_128 等传统一维码外,新增对QRCode 与 DataMatrix的解码支持。
实现证据位于 public/viewjs/components/camerabarcodescanner.js 第 202-209 行:
Grocy.Components.CameraBarcodeScanner.Scanner = new ZXing.BrowserMultiFormatReader(new Map().set(ZXing.DecodeHintType.POSSIBLE_FORMATS, [ ZXing.BarcodeFormat.EAN_8, ZXing.BarcodeFormat.EAN_13, ZXing.BarcodeFormat.CODE_39, ZXing.BarcodeFormat.CODE_128, ZXing.BarcodeFormat.DATA_MATRIX, ZXing.BarcodeFormat.QR_CODE, ]));扫码流程(第 75-78 行)通过decodeFromVideoDevice从摄像头实时视频流中解码,扫描出的条码结果会填充到各页面的扫码输入框中。由于扫码组件被consume、purchase、transfer、mealplan、productpicker、barcodescannertesting等多个页面复用,此升级一次性惠及所有条码录入场景。如果你想验证相机扫码是否可用,可以在"条码扫描器测试"页面(views/barcodescannertesting.blade.php)中直接体验。
7. 新增保加利亚语翻译
4.5.0 新增了保加利亚语(Bulgarian)翻译,相关词条位于 localization/bg_BG(strings、permissions、demo_data 等 9 个 .po 文件均有对应翻译)。官方同时提供了保加利亚语演示站点(bg.demo.grocy.info)。结合第 4 点的字体优化,非拉丁字符的保加利亚语界面现在也能以一致的默认字体呈现。
升级与验证建议
- 备份数据库后执行迁移:4.5.0 包含迁移 migrations/0252.sql,会重建
uihelper_stock_current_overview视图并清理旧表格状态设置。请确保迁移正常执行完成。 - 验证条码查询:在启用
OpenFoodFactsBarcodeLookupPlugin的环境下,扫描带非 ASCII 字符或本地化字段为空的商品,确认产品名与图片文件正常生成。 - 验证标签打印:若使用标签打印机,检查外部 Webhook 接收端能否正确解析新增的
details与stock_entry字段(注意GROCY_LABEL_PRINTER_HOOK_JSON决定表单或 JSON 格式)。 - 体验新扫码引擎:刷新前端静态资源后,使用相机扫描一维码与二维码(QRCode/DataMatrix),确认识别正常;扫描 2D 码需要新版浏览器支持摄像头视频流解码。
- 开启默认商店列:在库存概览页的表格列设置中勾选"Default store",确认各产品显示其默认购物地点名称。
小结
Grocy 4.5.0 是一次偏"体验与稳定性"的迭代:条码查询插件的容错修复提升了自动化建品成功率,details/stock_entry字段让标签打印服务获得完整对象上下文,ZXing 引擎则为扫码场景带来了更快的识别速度与 2D 码支持。对于自托管家庭库存管理用户而言,升级成本低、收益直观,值得尽快跟进。
【免费下载链接】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),仅供参考