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; } }
关键说明
- 服务注入:需在插件的
services.xml中注册CountryRepository、SalesChannelContextFactory和CartService,确保能正常注入到路由类。 - 上下文替换:由于
SalesChannelContext是不可变对象,必须通过contextFactory创建新上下文,替换其中的运输地址为销售渠道默认国家地址。 - 运费重算:重新加载购物车后必须调用
calculate方法,确保系统根据新国家地址重新匹配运费规则。 - 容错处理:增加了销售渠道无默认国家、国家实体加载失败的容错逻辑,避免页面报错。
内容的提问来源于stack exchange,提问作者mlodhi
相关产品推荐
相关产品推荐

