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

Shopware 6:通过编程方式使用规则筛选订单

Shopware 6插件规则筛选订单问题解决思路

问题背景

我正在开发一款Shopware 6插件,核心需求是通过规则构建器选择需要处理的订单:在插件设置中选定规则后,在Symfony控制台命令、消息队列任务及定时任务中加载该规则,按规则筛选系统内所有订单,再传递给后续服务处理。

目前尝试加载规则后将其添加到上下文,但使用仓储搜索订单时未实现过滤效果,代码如下:

$orderRule = $this->helperService->getOrderRule($this->context);

if ($orderRule) {
    $this->context->setRuleIds([$orderRule->getId()]);
}

$criteria = new Criteria();
$result = $this->orderRepository->search($criteria, $this->context)->getEntities();

查看Shopware核心代码后未找到常规规则的直接应用位置,怀疑过滤逻辑是在DAL结果加载后执行。另外,由于Symfony命令默认没有Shopware上下文,我试过使用Context::createDefaultContext(),也考虑过通过SalesChannelContextFactory自行创建SalesChannelContext。


问题根源

Shopware的规则系统默认面向销售渠道场景设计,直接给普通Context设置规则ID不会自动触发订单过滤——规则的匹配逻辑并非直接作用于DAL的查询阶段,需要手动调用规则匹配服务,或转换规则条件为查询筛选器来实现过滤。


正确实现方案

方式一:用RuleMatcher筛选已查询订单

适合订单数量较少的场景,通过规则匹配服务逐个校验订单:

// 注入RuleMatcher和SalesChannelContextFactory服务
private RuleMatcher $ruleMatcher;
private SalesChannelContextFactory $salesChannelContextFactory;

// ...

$orderRule = $this->helperService->getOrderRule($this->context);
if (!$orderRule) {
    return;
}

// 查询目标范围的订单(可添加分页、基础筛选条件)
$criteria = new Criteria();
$orders = $this->orderRepository->search($criteria, $this->context)->getEntities();

// 筛选符合规则的订单
$matchingOrders = [];
foreach ($orders as $order) {
    // 为订单创建对应销售渠道的上下文
    $salesChannelContext = $this->salesChannelContextFactory->create(
        $order->getSalesChannelId(),
        $this->context->getLanguageId(),
        $this->context->getCurrencyId()
    );
    
    if ($this->ruleMatcher->match($orderRule, $salesChannelContext, ['order' => $order])) {
        $matchingOrders[] = $order;
    }
}

方式二:将规则条件转换为DAL查询Criteria

适合订单数量较多的场景,直接在查询阶段过滤,提升效率:

// 注入RuleConditionConverter服务
private RuleConditionConverter $ruleConditionConverter;

// ...

$orderRule = $this->helperService->getOrderRule($this->context);
if (!$orderRule) {
    return;
}

// 将规则条件转换为DAL可识别的过滤条件
$condition = $this->ruleConditionConverter->convertToCriteria($orderRule->getConditions(), $this->context);

$criteria = new Criteria();
$criteria->addFilter($condition);

// 直接查询符合规则的订单
$matchingOrders = $this->orderRepository->search($criteria, $this->context)->getEntities();

注意事项

  • 在控制台/定时任务中创建SalesChannelContext时,必须传入正确的销售渠道ID、语言ID、货币ID,否则规则匹配可能出现错误
  • 若规则包含依赖销售渠道配置的条件,需使用对应销售渠道的上下文进行匹配
  • 大数量订单场景优先使用方式二,避免内存占用过高

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.01 00:47:25