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

Shopware 6插件:如何始终显示销售渠道默认国家运费

解决方案

核心思路

在商品详情页计算运费时,强制使用销售渠道默认国家替代用户收货地址的国家,通过构建修改后的SalesChannelContext重新计算购物车运费,完全忽略用户的默认收货地址。

具体代码修改

在你的CustomsProductDetailRoute类中,注入所需服务并修改load方法:

use Shopware\Core\Checkout\Cart\CartService;
use Shopware\Core\Checkout\Cart\SalesChannel\CartLoaderInterface;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Criteria;
use Shopware\Core\Framework\DataAbstractionLayer\EntityRepository;
use Shopware\Core\System\Country\CountryEntity;
use Shopware\Core\System\SalesChannel\Context\SalesChannelContextFactory;
use Shopware\Core\System\SalesChannel\SalesChannelContext;
use Shopware\Core\Checkout\Customer\Aggregate\CustomerAddress\CustomerAddressEntity;
use Symfony\Component\HttpFoundation\Request;

class CustomsProductDetailRoute extends ProductDetailRoute
{
    private EntityRepository $countryRepository;
    private SalesChannelContextFactory $contextFactory;
    private CartService $cartService;

    public function __construct(
        CartLoaderInterface $cartLoader,
        EntityRepository $productRepository,
        EntityRepository $countryRepository,
        SalesChannelContextFactory $contextFactory,
        CartService $cartService
    ) {
        parent::__construct($cartLoader, $productRepository);
        $this->countryRepository = $countryRepository;
        $this->contextFactory = $contextFactory;
        $this->cartService = $cartService;
    }

    public function load(Request $request, SalesChannelContext $context, Criteria $criteria): ProductDetailRouteResponse
    {
        $response = parent::load($request, $context, $criteria);
        
        // 获取销售渠道默认国家ID
        $salesChannelCountryId = $context->getSalesChannel()->getCountryId();
        if (!$salesChannelCountryId) {
            return $response;
        }

        // 加载销售渠道默认国家实体
        $country = $this->countryRepository->search(new Criteria([$salesChannelCountryId]), $context)->first();
        if (!$country instanceof CountryEntity) {
            return $response;
        }

        // 构建仅包含销售渠道默认国家的运输地址
        $shippingAddress = new CustomerAddressEntity();
        $shippingAddress->setCountryId($salesChannelCountryId);
        $shippingAddress->setCountry($country);

        // 创建修改后的上下文:替换运输地址为销售渠道默认国家地址
        $modifiedContext = $this->contextFactory->create(
            $context->getToken(),
            $context->getLanguageId(),
            $context->getCurrencyId(),
            $context->getPaymentMethodId(),
            $shippingAddress,
            $context->getBillingAddress(), // 保留原账单地址(若需强制统一也可替换)
            $context->getSalesChannelId(),
            $context->getDomainId(),
            $context->getCustomerId(),
            $context->getCustomerGroupId(),
            $context->getPermissions(),
            $context->getRuleIds(),
            $context->getStateMachineStateIds(),
            $context->getVersionId(),
            $context->getCurrencyFactor(),
            $context->getTimeZone(),
            $context->getLocaleId(),
            $context->getTaxState(),
            $context->getShippingMethodId()
        );

        // 用修改后的上下文重新加载并计算购物车运费
        $cart = $this->cartService->load($context->getToken(), $modifiedContext);
        $this->cartService->calculate($cart, $modifiedContext);

        // 将更新后的购物车赋值给响应
        $response->setCart($cart);

        return $response;
    }
}

关键说明

  1. 服务注入:需在插件的services.xml中注册CountryRepository、SalesChannelContextFactory和CartService,确保能正常注入到路由类。
  2. 上下文替换:由于SalesChannelContext是不可变对象,必须通过contextFactory创建新上下文,替换其中的运输地址为销售渠道默认国家地址。
  3. 运费重算:重新加载购物车后必须调用calculate方法,确保系统根据新国家地址重新匹配运费规则。
  4. 容错处理:增加了销售渠道无默认国家、国家实体加载失败的容错逻辑,避免页面报错。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.12 20:32:45