宝体数据调用接口
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

186 lines
5.6 KiB

<?php
namespace app\common\service\delivery;
use app\common\model\Setting as SettingModel;
use app\common\enum\OrderType as OrderTypeEnum;
/**
* 快递配送服务类
* Class Delivery
* @package app\common\service
*/
class Express
{
private $wxappId; // 小程序商城id
private $cityId; // 用户收货城市id
private $goodsList; // 订单商品列表
private $orderType; // 订单类型 (主商城、拼团)
/**
* 配送服务类构造方法
* Delivery constructor.
* @param int $wxappId 小程序商城id
* @param int $cityId 用户收货城市id
* @param array $goodsList 订单商品列表
* @param int $orderType 订单商品列表
*/
public function __construct(
$wxappId,
$cityId,
&$goodsList,
$orderType = OrderTypeEnum::MASTER
)
{
$this->wxappId = $wxappId;
$this->cityId = $cityId;
$this->goodsList = $goodsList;
$this->orderType = $orderType;
}
/**
* 根据用户收货城市id 验证是否在商品配送规则中
* 如果不存在则返回该商品,如果存在返回false
* @return bool
*/
public function getNotInRuleGoods()
{
if ($this->cityId) {
foreach ($this->goodsList as &$goods) {
$cityIds = [];
foreach ($goods['delivery']['rule'] as $item)
$cityIds = array_merge($cityIds, $item['region_data']);
if (!in_array($this->cityId, $cityIds))
return $goods;
}
}
return false;
}
/**
* 设置订单商品的运费
* @return bool
*/
public function setExpressPrice()
{
// 订单商品总金额
$orderTotalPrice = array_sum(array_column($this->goodsList, 'total_price'));
foreach ($this->goodsList as &$goods) {
$goods['express_price'] = $this->onCalcGoodsfreight($goods, $orderTotalPrice);
}
return true;
}
/**
* 获取订单最终运费
* @return double
*/
public function getTotalFreight()
{
if (empty($this->goodsList)) {
return 0.00;
}
// 所有商品的运费金额
$expressPriceArr = array_column($this->goodsList, 'express_price');
return $this->freightRule($expressPriceArr);
}
/**
* 计算商品的配送费用
* @param int $goods 商品id
* @param double $orderTotalPrice 订单总金额
* @return double
*/
private function onCalcGoodsfreight(&$goods, $orderTotalPrice)
{
// 判断是否满足满额包邮条件
if ($this->isFullFree($goods['goods_id'], $orderTotalPrice)) {
return 0.00;
}
// 当前收货城市配送规则
$rule = $this->getCityDeliveryRule($goods);
// 商品总重量
$totalWeight = bcmul($goods['goods_sku']['goods_weight'], $goods['total_num'], 2);
// 商品总数量or总重量
$total = $goods['delivery']['method']['value'] == 10 ? $goods['total_num'] : $totalWeight;
if ($total <= $rule['first']) {
return number_format($rule['first_fee'], 2);
}
// 续件or续重 数量
$additional = $total - $rule['first'];
if ($additional <= $rule['additional']) {
return number_format($rule['first_fee'] + $rule['additional_fee'], 2);
}
// 计算续重/件金额
if ($rule['additional'] < 1) {
// 配送规则中续件为0
$additionalFee = 0.00;
} else {
$additionalFee = bcdiv($rule['additional_fee'], $rule['additional'], 2) * $additional;
}
return number_format($rule['first_fee'] + $additionalFee, 2);
}
/**
* 判断是否满足满额包邮条件
* @param int $goodsId 商品id
* @param double $orderTotalPrice 订单总金额
* @return bool
*/
private function isFullFree($goodsId, $orderTotalPrice)
{
// 非商城主订单不参与满额包邮
if ($this->orderType !== OrderTypeEnum::MASTER) {
return false;
}
// 获取满额包邮设置
$options = SettingModel::getItem('full_free', $this->wxappId);
if (
$options['is_open'] == false
|| $orderTotalPrice < $options['money']
|| in_array($goodsId, $options['notin_goods'])
|| in_array($this->cityId, $options['notin_region']['citys'])
) {
return false;
}
return true;
}
/**
* 根据城市id获取规则信息
* @param
* @return array|false
*/
private function getCityDeliveryRule(&$goods)
{
foreach ($goods['delivery']['rule'] as $item) {
if (in_array($this->cityId, $item['region_data'])) {
return $item;
}
}
return false;
}
/**
* 根据运费组合策略 计算最终运费
* @param array $expressPriceArr 全部商品运费
* @return double
*/
private function freightRule($expressPriceArr)
{
$expressPrice = 0.00;
switch (SettingModel::getItem('trade', $this->wxappId)['freight_rule']) {
case '10': // 策略1: 叠加
$expressPrice = array_sum($expressPriceArr);
break;
case '20': // 策略2: 以最低运费结算
$expressPrice = min($expressPriceArr);
break;
case '30': // 策略3: 以最高运费结算
$expressPrice = max($expressPriceArr);
break;
}
return $expressPrice;
}
}