OpenCart 3.X获取结账页配送区域信息实现按区域显示配送方式
解决OpenCart 3.x结账页按区域过滤配送方式的问题
我刚好之前处理过OpenCart 3.x里类似的区域配送过滤需求,给你一步步拆解怎么实现:
第一步:在控制器中提前过滤符合区域的配送方式(推荐方案)
OpenCart的结账配送环节逻辑在catalog/controller/checkout/shipping_method.php里,我们可以在控制器层面先过滤掉不符合当前区域的配送方式,再把符合条件的传给模板,这样比在模板里做逻辑更高效安全。
- 打开
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'];
- 接着循环所有可用配送方式,过滤出匹配当前区域的选项:
$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
相关产品推荐
相关产品推荐

