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

如何在Shopware中实现商品列表按参考价格排序?

Shopware商品列表页按实时计算的参考价格排序方案

核心思路

因为参考价格是实时计算的(含税价格 / 销售单位),无法直接使用数据库字段排序,需要通过自定义DQL表达式或者扩展商品查询构建器注入计算逻辑来实现。

具体实现步骤

1. 创建自定义排序选项

先按照官方流程注册自定义排序,setFields留空,后续通过事件替换排序逻辑:

// 在插件的Migration或排序注册类中
$sorting = new ProductSortingEntity();
$sorting->setKey('reference_price_asc');
$sorting->setLabel('按参考价格升序');
$sorting->setActive(true);
$sorting->setFields(''); // 留空,后续通过事件处理

$this->productSortingRepository->create([$sorting], Context::createDefaultContext());

// 同时注册降序排序
$sortingDesc = new ProductSortingEntity();
$sortingDesc->setKey('reference_price_desc');
$sortingDesc->setLabel('按参考价格降序');
$sortingDesc->setActive(true);
$sortingDesc->setFields('');

$this->productSortingRepository->create([$sortingDesc], Context::createDefaultContext());

2. 监听商品列表查询事件

通过ProductListingCriteriaEvent事件修改查询的排序逻辑,注入实时计算表达式:

// 事件订阅类
use Shopware\Core\Content\Product\Events\ProductListingCriteriaEvent;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Shopware\Core\Framework\DataAbstractionLayer\Sorting\FieldSorting;

class ReferencePriceSortingSubscriber implements EventSubscriberInterface
{
    public static function getSubscribedEvents(): array
    {
        return [
            ProductListingCriteriaEvent::class => 'onProductListingCriteria'
        ];
    }

    public function onProductListingCriteria(ProductListingCriteriaEvent $event): void
    {
        $criteria = $event->getCriteria();
        $sorting = $criteria->getSorting()[0] ?? null;

        // 判断当前是否使用自定义的参考价格排序
        if (!$sorting || !in_array($sorting->getField(), ['reference_price_asc', 'reference_price_desc'])) {
            return;
        }

        // 移除默认排序规则,添加自定义计算排序
        $criteria->resetSorting();
        
        // 构建参考价格计算表达式,用IFNULL处理除数为0的异常
        $direction = $sorting->getField() === 'reference_price_asc' ? 'ASC' : 'DESC';
        $criteria->addSorting(new FieldSorting(
            'IFNULL(product.price / product.packUnit, 0)',
            $direction,
            true // 标记为DQL表达式,避免被解析为数据库字段
        ));
    }
}

3. 注册事件订阅者

在插件的services.xml中注册订阅类,让Shopware识别这个事件处理器:

<service id="YourPluginNamespace\Subscriber\ReferencePriceSortingSubscriber">
    <tag name="kernel.event_subscriber"/>
</service>

注意事项

  • 若含税价格存储在关联表(如product_price),需调整表达式为关联字段,例如product_price.gross / product.packUnit
  • 必须处理销售单位为0的情况,否则会触发SQL除法错误,示例中用IFNULL将异常值设为0

内容的提问来源于stack exchange,提问作者lubart

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.18 05:04:50