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

OpenCart 3.X获取结账页配送区域信息实现按区域显示配送方式

解决OpenCart 3.x结账页按区域过滤配送方式的问题

我刚好之前处理过OpenCart 3.x里类似的区域配送过滤需求,给你一步步拆解怎么实现:

第一步:在控制器中提前过滤符合区域的配送方式(推荐方案)

OpenCart的结账配送环节逻辑在catalog/controller/checkout/shipping_method.php里,我们可以在控制器层面先过滤掉不符合当前区域的配送方式,再把符合条件的传给模板,这样比在模板里做逻辑更高效安全。

  1. 打开shipping_method.php,找到if ($json['shipping_methods']) {这段代码(大概在文件后半部分),在这段之前先获取用户选中的配送地址信息:
// 获取用户选中的配送地址的国家/区域ID
$country_id = $this->session->data['shipping_address']['country_id'];
$zone_id = $this->session->data['shipping_address']['zone_id'];
// 如果你的场景是用账单地址判断,就替换成下面两行
// $country_id = $this->session->data['payment_address']['country_id'];
// $zone_id = $this->session->data['payment_address']['zone_id'];
  1. 接着循环所有可用配送方式,过滤出匹配当前区域的选项:
$filtered_shipping = [];
foreach ($json['shipping_methods'] as $code => $method) {
    // 针对基于重量的配送方式(weight)做区域匹配
    if ($code == 'weight') {
        $this->load->model('extension/shipping/weight');
        foreach ($method['quote'] as $quote_code => $quote) {
            // 获取该重量配送规则的适用区域设置
            $weight_rule = $this->model_extension_shipping_weight->getMethod($this->session->data['shipping_address'], $quote_code);
            
            // 匹配规则:国家ID一致,且区域ID匹配(0代表全区域适用)
            if ($weight_rule && ($weight_rule['country_id'] == $country_id && ($weight_rule['zone_id'] == 0 || $weight_rule['zone_id'] == $zone_id))) {
                $filtered_shipping[$code]['quote'][$quote_code] = $quote;
            }
        }
        // 保留该配送方式的基础信息(如果有符合的规则)
        if (!empty($filtered_shipping[$code]['quote'])) {
            $filtered_shipping[$code]['title'] = $method['title'];
            $filtered_shipping[$code]['code'] = $method['code'];
        }
    } else {
        // 其他配送方式可按需处理,这里直接保留(也可以参照上面的逻辑添加过滤)
        $filtered_shipping[$code] = $method;
    }
}
// 替换原配送方式数组为过滤后的结果
$json['shipping_methods'] = $filtered_shipping;

第二步:(可选)在Twig模板中直接获取国家/区域值做判断

如果你需要在模板里做简单的显示逻辑,可以先在控制器把国家/区域数据传给模板:

在shipping_method.php的$data['continue'] = $this->url->link('checkout/payment_method');附近,添加:

// 传递区域ID和名称到模板
$data['shipping_country_id'] = $this->session->data['shipping_address']['country_id'];
$data['shipping_zone_id'] = $this->session->data['shipping_address']['zone_id'];

$this->load->model('localisation/country');
$this->load->model('localisation/zone');
$data['shipping_country'] = $this->model_localisation_country->getCountry($data['shipping_country_id']);
$data['shipping_zone'] = $this->model_localisation_zone->getZone($data['shipping_zone_id']);

然后在catalog/view/theme/你的主题/template/checkout/shipping_method.twig里,就可以直接使用这些变量做判断了:

{# 显示当前选中的区域 #}
{% if shipping_country and shipping_zone %}
    <p>当前配送区域:{{ shipping_country.name }} - {{ shipping_zone.name }}</p>
{% endif %}

{# 循环配送方式时过滤显示 #}
{% for shipping_method in shipping_methods %}
    {% for quote in shipping_method.quote %}
        {% if quote.zone_id == shipping_zone_id or quote.zone_id == 0 %}
            <div class="radio">
                <label>
                    <input type="radio" name="shipping_method" value="{{ shipping_method.code }}.{{ quote.code }}" />
                    {{ quote.title }} - {{ quote.text }}
                </label>
            </div>
        {% endif %}
    {% endfor %}
{% endfor %}

注意事项

  • 记得把代码中的你的主题替换成你实际使用的主题文件夹名称
  • 测试时要确保用户已经选择了配送地址,否则session里的shipping_address可能不存在,建议加个判断避免报错
  • 基于重量的配送规则存储在extension_shipping_weight表中,getMethod方法可以准确获取对应规则的区域配置

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.26 09:16:29