374 行
14 KiB
PHP
可执行文件
374 行
14 KiB
PHP
可执行文件
<?php
|
|
/**
|
|
* Created by PhpStorm.
|
|
* User: dcy
|
|
* Date: 2020/3/23
|
|
* Time: 11:43
|
|
*/
|
|
|
|
namespace Api\Controller;
|
|
|
|
use Common\Model\TemplateAreaModel;
|
|
use think\console\input\Argument;
|
|
use Think\Controller;
|
|
|
|
//[1.4.70]
|
|
|
|
/**
|
|
* 门店商品;配送费计算
|
|
* Class CostCalculationController
|
|
* @package Api\Controller
|
|
*/
|
|
class CostCalculationController extends Controller
|
|
{
|
|
/**
|
|
* 获取配送费
|
|
* @param $goodsData 商品信息 必须包含模板ID(delivery_template_id),商品数量(num)
|
|
* @param $store_id 门店ID
|
|
* @param $province 用户地址的省
|
|
* @param $city 用户地址的市
|
|
* @param $area 用户地址的区
|
|
* @return mixed
|
|
*/
|
|
public function getFreight($goodsData, $store_id, $province, $city, $area)
|
|
{
|
|
//直辖市处理
|
|
$direct = array('北京市', '天津市', '上海市', '重庆市');
|
|
if (in_array($province, $direct)) {
|
|
$province = str_replace('市', '', $province);
|
|
}
|
|
|
|
$goodsData = json_decode($goodsData, true);
|
|
//获取模板id
|
|
$tempIds = $this->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;
|
|
}
|
|
|
|
} |