Shopware 6生产环境Import Export事件仅处理首行问题
Shopware 6 导入事件生产环境仅处理第一行问题
我在Shopware 6插件里订阅了ImportExportBeforeImportRecordEvent事件,用来在CSV导入时计算并设置商品价格。开发环境里onBeforeImport处理器能正常运行,但切到生产环境后,只能处理CSV的第一行,剩下的行都没法修改商品价格,而且导入导出模块没报错。其他事件比如product.written能正常工作,怀疑是生产环境的事件订阅方式导致的问题。
事件订阅代码
ImportExportBeforeImportRecordEvent::class => 'onBeforeImport'
事件处理器代码
public function onBeforeImport(ImportExportBeforeImportRecordEvent $event): void { $context = $event->getContext(); if (empty($event->getRecord())) { return; } $wucPluginRangePrice = $event->getRecord()['wucPluginRangePrice']; if ($this->IsGram($wucPluginRangePrice['rangeUnit']) && $this->IsKilo($wucPluginRangePrice['priceUnit'])) { $criteria = new Criteria(); $criteria->addFilter(new EqualsFilter('id', $event->getRecord()['id'])); $products = $this->productRepository->search($criteria, $context); $product = null; if ($products !== null && !empty($products->getEntities())) { $product = $products->first(); } else { return; } $isUseGross = (bool)$this->systemConfigService->get('WucPluginBasepriceWeightRange.config.wucBasepricePricePerUnitGross'); $toKgValue = ((float)$wucPluginRangePrice['to']) / 1000; $taxRateDivident = $product->getTax() !== null ? ($product->getTax()->getTaxRate() / 100) + 1.00 : (19.00 / 100) + 1.00; if ($isUseGross) { $priceVal = ((float)$wucPluginRangePrice['pricePerUnit']) * $toKgValue; $netVal = ($priceVal / $taxRateDivident); } else { $netVal = ((float)$wucPluginRangePrice['pricePerUnit']) * $toKgValue; $priceVal = ($netVal * $taxRateDivident); } $data = [ 'id' => $product->getId(), 'price' => [ [ 'currencyId' => Defaults::CURRENCY, 'gross' => $priceVal, 'net' => $netVal, 'linked' => false ] ] ]; $this->productRepository->update([$data], $context); } }
问题排查与解决方案
1. 生产环境缓存未更新
生产环境默认开启缓存,事件订阅可能未被正确加载,执行以下命令清理并预热缓存:
bin/console cache:clear --env=prod bin/console cache:warmup --env=prod
2. 直接调用Repository.update干扰导入流程
Shopware导入过程是批量事务处理,你在事件中单独调用productRepository->update会破坏事务上下文,后续导入行的修改会被批量逻辑覆盖,或因状态不一致导致失效。
正确做法:直接修改事件中的Record数据
不需要查询商品再单独更新,直接修改$event->getRecord()里的价格字段,导入流程会自动将修改后的数据写入数据库:
public function onBeforeImport(ImportExportBeforeImportRecordEvent $event): void { $context = $event->getContext(); $record = $event->getRecord(); if (empty($record)) { return; } $wucPluginRangePrice = $record['wucPluginRangePrice']; if ($this->IsGram($wucPluginRangePrice['rangeUnit']) && $this->IsKilo($wucPluginRangePrice['priceUnit'])) { // 从record获取税率信息,避免重复查询商品 $taxRate = 19.00; if (!empty($record['taxId'])) { $criteria = new Criteria([$record['taxId']]); $tax = $this->taxRepository->search($criteria, $context)->first(); if ($tax) { $taxRate = $tax->getTaxRate(); } } $taxRateDivident = ($taxRate / 100) + 1.00; $isUseGross = (bool)$this->systemConfigService->get('WucPluginBasepriceWeightRange.config.wucBasepricePricePerUnitGross'); $toKgValue = ((float)$wucPluginRangePrice['to']) / 1000; if ($isUseGross) { $priceVal = ((float)$wucPluginRangePrice['pricePerUnit']) * $toKgValue; $netVal = ($priceVal / $taxRateDivident); } else { $netVal = ((float)$wucPluginRangePrice['pricePerUnit']) * $toKgValue; $priceVal = ($netVal * $taxRateDivident); } // 直接修改record的price字段,由导入流程统一处理写入 $record['price'] = [ [ 'currencyId' => Defaults::CURRENCY, 'gross' => $priceVal, 'net' => $netVal, 'linked' => false ] ]; $event->setRecord($record); } }
3. 生产环境日志级别过高导致错误被隐藏
临时调整生产环境日志级别,查看导入过程中的错误:
修改config/packages/prod/monolog.yaml:
monolog: handlers: main: level: debug
执行日志查看命令:
tail -n 100 var/log/prod.log
4. 事件订阅优先级被其他插件覆盖
如果有其他插件订阅了同事件,可能优先级更高覆盖了你的修改,可在订阅时指定高优先级:
ImportExportBeforeImportRecordEvent::class => [ ['method' => 'onBeforeImport', 'priority' => 100] ]
数值越高,事件处理器执行越早。
内容的提问来源于stack exchange,提问作者svg87
相关产品推荐
相关产品推荐

