网站开发 · 2025年4月26日

Zen-cart自定义运费模块-China Post

中国邮政小包有挂号和平邮,这里说的是挂号国家邮政小包。这个运输方式把国家分成10个区,每个区对应不同的费率(每公斤多少钱)。
Zen-cart自定义运费模块-China Post插图

由于针对不同国家可能对应了不同费率,所有实现这个插件并没有那么简单,以上图片展示的只是一些基本参数,实际的国家分区费率表需要导入到数据库中,而这些Zen-cart并没有实现。

这些工作量是有点大的,比如为了能使用国家对应的中文名称包国家导入到分区表,我们首先需要扩展countries表,把每个国家的中文名对应上去。这个步骤可以写一段程序批量导入,这里跳过了。

接下来是建立分区,这里重复利用Zen-cart默认的geo_zone

要导入的表:
Zen-cart自定义运费模块-China Post插图1

不过为了让每个geo_zone对应费率,需要对geo_zone进行扩展(添加cost字段)

1 ALTER TABLE `geo_zones` ADD `cost` VARCHAR( 64 ) NULL DEFAULT ‘0’

这样分区对应的国家的对应关系就建立起来了,每个分区用cost字段记录了这个分区的费率。

那么China Post运费模块的quote方法:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 // class methods function quote($method = ”) {     global $order,$shipping_weight,$shipping_num_boxes,$db,$currencies;        $total_weight = $shipping_weight * $shipping_num_boxes;       if($total_weight > (int)MODULE_SHIPPING_CHINA_POST_MAX_WEIGHT){         return false;       }     //package weight     $total_weight += (int)MODULE_SHIPPING_CHINA_POST_PACKAGE_WEIGHT;        $cost = $db->Execute(“select gz.geo_zone_name, gz.cost, ztgz.zone_id from geo_zones gz, zones_to_geo_zones ztgz where gz.geo_zone_id = ztgz.geo_zone_id and ztgz.zone_country_id = “.(int)$order->delivery[‘country’][‘id’].” and ztgz.zone_id = 0 and gz.geo_zone_name like ‘ChinaPost_%'”);       if($cost->RecordCount() > 0){         $first = round((float)MODULE_SHIPPING_CHINA_POST_COST,2);         $continue = round($cost->fields[‘cost’],2);           $rate = (float)$currencies->currencies[‘CNY’][‘value’];         if($rate <= 0){             $rate = 1;         }                $disc = (float)MODULE_SHIPPING_CHINA_POST_RATE;         if($disc <= 0){             $disc = 1;         }                $ttl = round($disc*($first+$continue*ceil($total_weight/10)/100)/$rate,2);         $this->quotes = array(‘id’ => $this->code,                             ‘module’ => MODULE_SHIPPING_CHINA_POST_TEXT_TITLE,                             ‘methods’ => array(array(‘id’ => $this->code,                                                      ‘title’ => MODULE_SHIPPING_CHINA_POST_TEXT_WAY,                                                      ‘cost’ => $ttl)));     }else{         return false;       }       if ($this->tax_class > 0) {         $this->quotes[‘tax’] = zen_get_tax_rate($this->tax_class, $order->delivery[‘country’][‘id’], $order->delivery[‘zone_id’]);     }       if (zen_not_null($this->icon)) $this->quotes[‘icon’] = zen_image($this->icon, $this->title);       return $this->quotes; }

主要是根据国家代码把费率给找出来,如果还有其它运输方式也采用类似的方法,那么某个国家可能对应多个geo_zone,这个时候需要过滤出符合当前运输方式的geo_zone,在导入分区表时,每个分区都采用ChinaPost_前缀,所以这里添加了like ‘ChinaPost_%’条件就可以过滤出当前的运输方式的分区,当然务必要避免同一个国家装入同一种运输方式的不同分区中(国家分区导入时需要考虑这个逻辑),否则将得到多个费率,这里总是使用返回排在第一的那条记录。