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

Prestashop 1.7技术问询:如何在product.tpl中获取最低价配送商并展示

在PrestaShop 1.7商品详情页获取最低价配送商方案

嘿,针对你在PrestaShop 1.7的product.tpl里获取最低价配送商的需求,我给你梳理两种可行方案,优先推荐控制器预处理的方式(模板尽量少写业务逻辑是最佳实践哦):

方案一:通过ProductController预处理数据(推荐)

直接修改核心控制器不太友好,建议用override机制来扩展,这样升级PrestaShop时不会丢失你的修改:

  1. 在你的项目根目录下,创建override/controllers/front/ProductController.php文件,写入以下代码:
<?php
class ProductController extends ProductControllerCore
{
    public function initContent()
    {
        parent::initContent();
        
        // 获取当前商品对象
        $product = $this->product;
        
        // 获取计算运费用的地址:已登录用户用默认地址,未登录用系统默认国家临时地址
        if ($this->context->customer->isLogged()) {
            $address = new Address((int)$this->context->customer->id_address_default);
        } else {
            $address = new Address();
            $address->id_country = (int)Configuration::get('PS_COUNTRY_DEFAULT');
            $address->id_state = 0;
            $address->postcode = '';
        }
        
        // 创建临时购物车并添加当前商品(用于计算运费)
        $cart = new Cart();
        $cart->id_customer = (int)$this->context->customer->id;
        $cart->id_address_delivery = (int)$address->id;
        $cart->id_address_invoice = (int)$address->id;
        $cart->id_lang = (int)$this->context->language->id;
        $cart->id_currency = (int)$this->context->currency->id;
        $cart->id_shop = (int)$this->context->shop->id;
        $cart->add();
        $cart->updateQty(1, $product->id);
        
        // 筛选可用配送商并找出最低价
        $carriers = Carrier::getCarriers($this->context->language->id, true, false, false, null, Carrier::ALL_CARRIERS);
        $lowestCarrier = null;
        $lowestPrice = PHP_INT_MAX;
        
        foreach ($carriers as $carrier) {
            $carrierObj = new Carrier((int)$carrier['id_carrier']);
            // 检查配送商是否激活且支持当前地址所在区域
            if ($carrierObj->active && $carrierObj->checkCarrierZone((int)$address->id_country)) {
                $shippingCost = $cart->getPackageShippingCost($carrierObj, $address, true);
                if ($shippingCost < $lowestPrice) {
                    $lowestPrice = $shippingCost;
                    $lowestCarrier = $carrierObj;
                }
            }
        }
        
        // 清理临时购物车,避免产生无效记录
        $cart->delete();
        
        // 将数据传递给模板
        $this->context->smarty->assign([
            'lowest_carrier' => $lowestCarrier,
            'lowest_shipping_price' => $lowestPrice
        ]);
    }
}
  1. 登录后台,进入高级参数 > 性能页面,点击"清除缓存",让override生效。

  2. 在你的主题product.tpl中添加展示代码:

{if $lowest_carrier}
    <div class="product-shipping-info">
        <p>💡 最低价配送:<strong>{$lowest_carrier->name}</strong> - 运费:{$lowest_shipping_price|convertPrice}</p>
    </div>
{else}
    <p>⚠️ 当前商品暂无可用配送方式</p>
{/if}

方案二:直接在模板中编写逻辑(应急可用,不推荐)

如果暂时不想修改控制器,也可以直接在product.tpl中写逻辑,但后期维护会比较麻烦:

{* 获取当前商品 *}
{assign var="current_product" value=$product}

{* 获取地址:已登录用默认地址,未登录用系统默认国家 *}
{assign var="shipping_address" value=""}
{if $customer->isLogged()}
    {assign var="shipping_address" value=new Address($customer->id_address_default)}
{else}
    {assign var="shipping_address" value=new Address()}
    {$shipping_address->id_country = Configuration::get('PS_COUNTRY_DEFAULT')}
    {$shipping_address->id_state = 0}
    {$shipping_address->postcode = ''}
{/if}

{* 创建临时购物车 *}
{assign var="temp_cart" value=new Cart()}
{$temp_cart->id_customer = $customer->id}
{$temp_cart->id_address_delivery = $shipping_address->id}
{$temp_cart->id_address_invoice = $shipping_address->id}
{$temp_cart->id_lang = $language->id}
{$temp_cart->id_currency = $currency->id}
{$temp_cart->id_shop = $shop->id}
{$temp_cart->add()}
{$temp_cart->updateQty(1, $current_product->id)}

{* 遍历配送商找最低价 *}
{assign var="min_shipping_price" value=99999}
{assign var="best_carrier" value=null}

{foreach from=Carrier::getCarriers($language->id, true, false, false, null, Carrier::ALL_CARRIERS) item=carrier_item}
    {assign var="carrier_obj" value=new Carrier($carrier_item.id_carrier)}
    {if $carrier_obj->active && $carrier_obj->checkCarrierZone($shipping_address->id_country)}
        {assign var="cost" value=$temp_cart->getPackageShippingCost($carrier_obj, $shipping_address, true)}
        {if $cost < $min_shipping_price}
            {assign var="min_shipping_price" value=$cost}
            {assign var="best_carrier" value=$carrier_obj}
        {/if}
    {/if}
{/foreach}

{* 清理临时购物车 *}
{$temp_cart->delete()}

{* 展示结果 *}
{if $best_carrier}
    <div class="shipping-notice">
        <p>最低价配送选项:<strong>{$best_carrier->name}</strong>,运费:{$min_shipping_price|convertPrice}</p>
    </div>
{else}
    <p>暂无可用配送方式</p>
{/if}

重要注意事项

  • 地址适配:未登录用户的临时地址可以根据你的业务调整(比如默认热门国家/地区),不然运费计算可能不符合实际场景。
  • 配送商限制:如果你的配送商有重量、体积限制,需要额外添加检查逻辑(比如$carrierObj->checkWeight($product->weight))。
  • 免运费处理:如果有免运费的配送商,代码会自动识别(因为0是最小的价格),符合预期。
  • 缓存问题:修改override后一定要清缓存,否则不会生效。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.20 10:11:48