You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.24 06:35:43