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; } }