getTempIds($goodsData); //获取模板对应的区域信息 $TemplateAreaModel = new TemplateAreaModel(); $areaData = $TemplateAreaModel->getTemplateAreas($tempIds); //获取用户地址省市区对应的区域信息 $userAreaData = D('Citys')->getCityDataByCityName($province, $city, $area); if (empty($userAreaData)) { return array( 'status' => 0, 'msg' => '您的收货地址有误', ); } //判断出包含用户地址的模板区域信息 $areaDetails = $this->getUserRespeRegion($areaData, $userAreaData); //组合商品和商品的配送模板信息 $goodAndTemData = $this->comGoodsAndArea($areaDetails, $goodsData); foreach ($goodAndTemData as $item) { if (empty($item['areaData'])) { return array( 'status' => 0, 'msg' => '您的收货地址暂时不在购买的商品支持发货地区范围内', ); } } $comGoodsAndTemData = $this->comGoodsAndTemData($goodAndTemData);//组合运费模板相同的商品 $distributionFee = $this->getDistributionFee($comGoodsAndTemData, $store_id);//获取最终配送费 if ($distributionFee == -1) { return array( 'status' => 0, 'msg' => '商家未开启快递发货,请退出重试', 'delivery_fee' => $distributionFee, ); } else { return array( 'status' => 1, 'msg' => '配送费获取成功', 'delivery_fee' => $distributionFee, ); } } /** * 获取商品模板id * @param $goodsData * @return array */ private function getTempIds(&$goodsData) { $tempIds = array(); foreach ($goodsData as &$value) { $tempIds[] = $value['delivery_template_id']; if (!empty($value['weight_value'])) { $value['num'] = round($value['num'] * $value['weight_value'], 3); } } return $tempIds; } /** * 返回当前用户地址所属的区域信息 * @param $areaData * @param $userAreaData * @return array */ private function getUserRespeRegion($areaData, $userAreaData) { $areaDetails = array(); foreach ($areaData as $item) { if (strpos($item['area_id'], $userAreaData[2]['cityid'])) { $areaDetails[] = $item; continue; } elseif (strpos($item['area_id'], $userAreaData[1]['cityid'])) { $areaDetails[] = $item; continue; } elseif (strpos($item['area_id'], $userAreaData[0]['cityid'])) { $areaDetails[] = $item; continue; } } return $areaDetails; } /** * 组合商品和配送区域费用问题 * @param $areaDetails * @param $goodsData * @return mixed */ private function comGoodsAndArea($areaDetails, $goodsData) { foreach ($goodsData as &$goods) { foreach ($areaDetails as $item) { if ($goods['delivery_template_id'] == $item['template_id']) { $goods['areaData'] = $item; break; } } } return $goodsData; } /** * 获取配送费 * @param $goodsAndTemData * @param $store_id * @return int */ private function getDistributionFee($goodsAndTemData, $store_id) { $storeConfigData = D('StoreConfig')->getStoreTemConfiguration($store_id); if ($storeConfigData['delivery_template_status'] == 2) { if ($storeConfigData['template_charging_type'] == 1) { //累加运费 $distributionFee = $this->cumulativeFreightCalculation($goodsAndTemData); } else { //组合运费 $distributionFee = $this->combinedFreightCalculation($goodsAndTemData); } return $distributionFee; } else { return -1; } } /** * 累加运费计算 * @param $goodsAndTemData * @return int */ private function cumulativeFreightCalculation($goodsAndTemData) { $count = array_count_values(array_column($goodsAndTemData, "delivery_template_id")); $arrSize = sizeof($goodsAndTemData); if ($count[$goodsAndTemData[0]['delivery_template_id']] == $arrSize) {//判断商品使用的模板是否相同 foreach ($goodsAndTemData as $item) { if ($item['areaData']['type'] == 1) { //免运费 $distributionFee = 0; break; } elseif ($item['areaData']['type'] == 2 || $item['areaData']['type'] == 3) { //按件数 || 按重量 $totalQuantity = 0; //商品总数量totalQuantity foreach ($goodsAndTemData as $items) { $totalQuantity += $items['num']; } $firstNum = $item['areaData']['first_num']; //首重 $appendNum = $item['areaData']['append_num']; //续重 $check = ($totalQuantity > $firstNum) ? 1 : 0; if ($check) { $merchant = ceil(($totalQuantity - $firstNum) / $appendNum); $distributionFee = $item['areaData']['first_fee'] + $merchant * $item['areaData']['append_fee']; break; } else { $distributionFee = $item['areaData']['first_fee']; break; } } elseif ($item['areaData']['type'] == 4) {//统一运费 $distributionFee = $item['areaData']['unified_fee']; break; } } } else { $freeArr = [];//免运费数组 $numArr = [];//按件数 $weightArr = [];//按重量 $unifiedArr = [];//统一运费 $freeFee = 0;//免运费 $numFee = 0; //按件收费 $weightFee = 0; //按重收费 $maxUnifiedFee = 0; //最大统一运费 foreach ($goodsAndTemData as $goods) { if ($goods['areaData']['type'] == 1) { array_push($freeArr, $goods); } elseif ($goods['areaData']['type'] == 2) { array_push($numArr, $goods); } elseif ($goods['areaData']['type'] == 3) { array_push($weightArr, $goods); } elseif ($goods['areaData']['type'] == 4) { array_push($unifiedArr, $goods); } } if (!empty($freeArr)) { $freeFee = 0; } if (!empty($numArr)) {//按件数 foreach ($numArr as $num) { $merchant = ceil(($num['num'] - $num['areaData']['first_num']) / $num['areaData']['append_num']); $count = ($num['num'] > $num['areaData']['first_num']) ? 1 : 0; if ($count) { $numFee += $num['areaData']['first_fee'] + $merchant * $num['areaData']['append_fee']; } else { $numFee += $num['areaData']['first_fee']; } } } if (!empty($weightArr)) {//按重量 foreach ($weightArr as $weight) { $merchant = ceil(($weight['num'] - $weight['areaData']['first_num']) / $weight['areaData']['append_num']); $count = ($weight['num'] > $weight['areaData']['first_num']) ? 1 : 0; if ($count) { $weightFee += $weight['areaData']['first_fee'] + $merchant * $weight['areaData']['append_fee']; } else { $weightFee += $weight['areaData']['first_fee']; } } } if (!empty($unifiedArr)) {//统一运费 foreach ($unifiedArr as $unified) { $maxUnifiedFee = ($maxUnifiedFee > $unified['areaData']['unified_fee']) ? $maxUnifiedFee : $unified['areaData']['unified_fee']; } } $distributionFee = round($freeFee + $numFee + $weightFee + $maxUnifiedFee, 2); } return $distributionFee; } /** * 组合运费计算 * @param $goodsAndTemData * @return int */ private function combinedFreightCalculation($goodsAndTemData) { $distributionFee = 0; if (count($goodsAndTemData) == 1) { //商品使用相同的模板 switch ($goodsAndTemData[0]['areaData']['type']) { case '1': //免运费 $distributionFee = 0; break; case '2': case '3': //2按件数 3按重量 $totalQuantity = $goodsAndTemData[0]['num'];//商品总数量 $firstNum = $goodsAndTemData[0]['areaData']['first_num']; //首重 $appendNum = $goodsAndTemData[0]['areaData']['append_num']; //续重 $append_num = ceil(($totalQuantity - $firstNum) / $appendNum); $append_num = $append_num > 0 ? $append_num : 0; $distributionFee = round($goodsAndTemData[0]['areaData']['first_fee'] + $append_num * $goodsAndTemData[0]['areaData']['append_fee'], 2); break; case '4': //统一运费 $distributionFee = $goodsAndTemData[0]['areaData']['unified_fee']; break; } return $distributionFee; } else { //多种模板组合 $freeArr = [];//免运费数组 $numArr = [];//按件数 | 按重量 $unifiedArr = [];//统一运费 $comFee = 0; //组合运费 $maxUnifiedFee = 0; //最大统一运费 foreach ($goodsAndTemData as $goods) { switch ($goods['areaData']['type']) { case '1': array_push($freeArr, $goods); break; case '2': case '3': array_push($numArr, $goods); break; case '4': array_push($unifiedArr, $goods); break; } } //按件数 | 按重量 if (!empty($numArr)) { $maxFirstFee = 0;//最大首运费 foreach ($numArr as $num) { $maxFirstFee = ($maxFirstFee > $num['areaData']['first_fee']) ? $maxFirstFee : $num['areaData']['first_fee']; } //根据最大续费获取最大续费当前模板的首件|首重 以及 续件|续重 $maxIdent = 0;//最大的标识 foreach ($numArr as $nums) { if ($maxFirstFee == $nums['areaData']['first_fee'] && $maxIdent == 0) { if ($nums['num'] > $nums['areaData']['first_num']) { $append_num = ceil(($nums['num'] - $nums['areaData']['first_num']) / $nums['areaData']['append_num']); $append_num = $append_num > 0 ? $append_num : 0; $comFee += $nums['areaData']['first_fee'] + $append_num * $nums['areaData']['append_fee']; } else { $comFee += $nums['areaData']['first_fee']; } $maxIdent = 1; } else { $append_num = ceil($nums['num'] / $nums['areaData']['append_num']); $comFee += $append_num * $nums['areaData']['append_fee']; } } $comFee = round($comFee, 2); } //统一运费 if (!empty($unifiedArr)) { foreach ($unifiedArr as $unified) { $maxUnifiedFee = ($maxUnifiedFee > $unified['areaData']['unified_fee']) ? $maxUnifiedFee : $unified['areaData']['unified_fee']; } $maxUnifiedFee = round($maxUnifiedFee, 2); } $distributionFee = ($comFee > $maxUnifiedFee) ? $comFee : $maxUnifiedFee; } return $distributionFee; } /** * 把配送模板ID相同的数据融合一起 * @param $goodsAndTemData * @return mixed */ private function comGoodsAndTemData($goodsAndTemData) { $tempData = array(); $count = count($goodsAndTemData); for ($i = 0; $i < $count; $i++) { if (!$goodsAndTemData[$i]['del']) { for ($j = $i + 1; $j <= $count; $j++) { if ($goodsAndTemData[$i]['delivery_template_id'] == $goodsAndTemData[$j]['delivery_template_id']) { $goodsAndTemData[$i]['num'] += $goodsAndTemData[$j]['num']; $goodsAndTemData[$j]['del'] = 1; } } $tempData[] = $goodsAndTemData[$i]; } } return $tempData; } }