Explorar o código

计算公里 向上取整

shish hai 8 meses
pai
achega
f60b8cf65b
Modificáronse 1 ficheiros con 57 adicións e 51 borrados
  1. 57 51
      common/components/delivery/util/DeliveryQuoteUtil.php

+ 57 - 51
common/components/delivery/util/DeliveryQuoteUtil.php

@@ -1,4 +1,5 @@
 <?php
+
 namespace common\components\delivery\util;
 
 use biz\shop\classes\ShopClass;
@@ -16,7 +17,7 @@ class DeliveryQuoteUtil
 {
     /**
      * 获取配送报价(含免费配送规则计算)
-     * 
+     *
      * @param array $params 参数数组
      *   - productList: 商品列表 [['bigNum' => 数量, 'weight' => 重量], ...]
      *   - deliveryPlatform: 配送平台(shansong/huolala/fengniao等)
@@ -25,37 +26,37 @@ class DeliveryQuoteUtil
      *   - order: 订单基础信息 ['orderSn' => xxx, 'itemTotalAmount' => xxx, 'remark' => xxx]
      *   - mainId: 当前操作者的 mainId
      *   - productCount: 商品总数量(用于免费配送判断)
-     * 
+     *
      * @return array 返回数组
      *   - sendCost: 配送费用(元)
      *   - sendDistance: 配送距离(米)
      *   - deliveryList: 可选配送方式列表
      *   - platformQuotes: 原始平台报价数据
-     * 
+     *
      * @throws \Exception 当报价失败时抛出异常
      */
     public static function getDeliveryQuote($params)
     {
         // 1. 参数验证
         self::validateParams($params);
-        
+
         // 2. 计算商品总重量
         $weight = self::calculateTotalWeight($params['productList']);
-        
+
         // 3. 构建订单数据
         $order = self::buildOrderData($params, $weight);
-        
+
         // 4. 获取供货商店铺信息
         $ghsShop = ShopClass::getById($params['ghsInfo']['shopId']);
         if (empty($ghsShop)) {
             throw new \Exception("供货商店铺信息不存在:shopId={$params['ghsInfo']['shopId']}");
         }
-        
+
         // 5. 调用跑腿平台获取报价
         $orderTime = date('Y-m-d H:i:s');
         $ds = new DispatchService($params['ghsInfo']['mainId'], $params['deliveryPlatform']);
         $platformQuotes = $ds->getAllPlatformPrice($order, $ghsShop, $orderTime);
-        
+
         // 6. 检查报价结果
         if (isset($platformQuotes['error'])) {
             $errorMsg = $platformQuotes['error'];
@@ -63,17 +64,17 @@ class DeliveryQuoteUtil
             noticeUtil::push("{$params['deliveryPlatform']}-跑腿平台估价接口获取费用与距离失败:mainId={$params['mainId']}");
             throw new \Exception($errorMsg);
         }
-        
+
         // 7. 格式化平台报价
         $deliveryList = $ds->formatPlatformQuotesForDisplay($platformQuotes);
-        
+
         // 8. 重试机制(如果第一次失败)
         if (is_array($deliveryList) && empty($deliveryList)) {
             sleep(2);
             $platformQuotes = $ds->getAllPlatformPrice($order, $ghsShop, $orderTime);
             $deliveryList = $ds->formatPlatformQuotesForDisplay($platformQuotes);
         }
-        
+
         // 9. 检查是否有可用的配送方式
         if (is_array($deliveryList) && empty($deliveryList)) {
             $errorMsg = "ghsMainId={$params['ghsInfo']['mainId']}, orderSn={$order['orderSn']} 请求{$params['deliveryPlatform']}平台报价失败。";
@@ -81,33 +82,33 @@ class DeliveryQuoteUtil
             Yii::error($errorMsg);
             throw new \Exception($errorMsg);
         }
-        
+
         // 10. 获取报价结果
         $result = null;
-        if(in_array($params['deliveryPlatform'], ['huolala', 'fengniao'])){
+        if (in_array($params['deliveryPlatform'], ['huolala', 'fengniao'])) {
             $bracketContent = $params['deliveryBracketContent'] ?? '';
             $key = '';
-            foreach($deliveryList as $item){
-                if($params['deliveryPlatform'] == 'huolala'){
+            foreach ($deliveryList as $item) {
+                if ($params['deliveryPlatform'] == 'huolala') {
                     $key = 'vehicle_type';
                 }
-                if($params['deliveryPlatform'] == 'fengniao'){
+                if ($params['deliveryPlatform'] == 'fengniao') {
                     $key = 'base_goods_id';
                 }
-                if($item[$key] == $bracketContent){
+                if ($item[$key] == $bracketContent) {
                     $result = $item;
                 }
             }
-            if($result === null){
+            if ($result === null) {
                 throw new \Exception('没有找到对应的配送方式');
             }
-        }else{
+        } else {
             $result = $deliveryList[0];
         }
 
         $sendCost = ($result['price'] ?? 0) / 100;
         $sendDistance = $result['distance'] ?? 0;
-        
+
         // 11. 应用免费配送规则
         $finalSendCost = self::applyFreeDeliveryRules(
             $sendCost,
@@ -118,7 +119,7 @@ class DeliveryQuoteUtil
             $params['ghsInfo']['mainId'],
             $order['orderSn']
         );
-        
+
         return [
             'sendCost' => $finalSendCost,
             'sendDistance' => $sendDistance,
@@ -126,10 +127,10 @@ class DeliveryQuoteUtil
             'platformQuotes' => $platformQuotes,
         ];
     }
-    
+
     /**
      * 计算商品总重量
-     * 
+     *
      * @param array $productList 商品列表
      * @return float 总重量(公斤)
      */
@@ -147,10 +148,10 @@ class DeliveryQuoteUtil
 
         return $weight;
     }
-    
+
     /**
      * 构建订单数据
-     * 
+     *
      * @param array $params 参数数组
      * @param float $weight 总重量
      * @return array 订单数据
@@ -159,7 +160,7 @@ class DeliveryQuoteUtil
     {
         $custom = $params['custom'];
         $orderInfo = $params['order'];
-        
+
         return [
             'orderSn' => $orderInfo['orderSn'],
             'customName' => $custom->name,
@@ -177,10 +178,10 @@ class DeliveryQuoteUtil
             'actPrice' => $orderInfo['itemTotalAmount'] ?? 0,
         ];
     }
-    
+
     /**
      * 应用免费配送规则
-     * 
+     *
      * @param float $sendCost 原始配送费用
      * @param int $sendDistance 配送距离(米)
      * @param int $shopId 店铺ID
@@ -198,7 +199,8 @@ class DeliveryQuoteUtil
         $itemTotalAmount,
         $ghsMainId,
         $orderSn
-    ) {
+    )
+    {
         // 获取店铺扩展信息(免费配送设置)
         $shopExt = ShopExtClass::getByCondition(['shopId' => $shopId], false, null, 'id,hcFreeKm,hcMap,hsFreeKm,hsAddFee');
         if (empty($shopExt)) {
@@ -206,16 +208,16 @@ class DeliveryQuoteUtil
         }
 
         // XSD_CS-    KD_CS-
-        if(strstr($orderSn, 'XSD_CS') || strstr($orderSn, 'XSD')){//花材
+        if (strstr($orderSn, 'XSD_CS') || strstr($orderSn, 'XSD')) {//花材
             // 获取花材的免费配送设置
             $hcFreeKm = ($shopExt['hcFreeKm'] ?? 0) * 1000; // 转换为米
             $hcMapString = $shopExt['hcMap'] ?? '';
             $hcMap = [];
-            
+
             if (!empty($hcMapString)) {
                 $hcMap = json_decode($hcMapString, true);
             }
-            
+
             // 判断是否免跑腿费
             if ($sendDistance > $hcFreeKm) {
                 // 超过免费距离,检查是否满足其他免费条件
@@ -224,13 +226,13 @@ class DeliveryQuoteUtil
                         $ruleNum = $rule['num'] ?? 0;
                         $rulePrice = $rule['price'] ?? 0;
                         $ruleDistance = ($rule['distance'] ?? 0) * 1000;
-                        
-                        if ($productCount >= $ruleNum 
-                            && $itemTotalAmount >= $rulePrice 
+
+                        if ($productCount >= $ruleNum
+                            && $itemTotalAmount >= $rulePrice
                             && $sendDistance <= $ruleDistance
                         ) {
                             noticeUtil::push(
-                                "ghsMainId={$ghsMainId}, orderSn={$orderSn}, 免跑腿费,满足条件:" 
+                                "ghsMainId={$ghsMainId}, orderSn={$orderSn}, 免跑腿费,满足条件:"
                                 . json_encode($rule)
                             );
                             return 0;
@@ -241,52 +243,56 @@ class DeliveryQuoteUtil
                 // 在免费配送距离内
                 return 0;
             }
-        }else if(strstr($orderSn, 'KD_CS') || strstr($orderSn, 'KD')){//花束
+        } else if (strstr($orderSn, 'KD_CS') || strstr($orderSn, 'KD')) {//花束
             // 获取花材的免费配送设置
             $hsFreeKm = ($shopExt['hsFreeKm'] ?? 0) * 1000; // 转换为米
             $hsAddFee = $shopExt['hsAddFee'] ?? 0;
-            
+
             // 判断是否免跑腿费
             if ($sendDistance > $hsFreeKm) {
-                return ($sendDistance - $hsFreeKm)/1000 * $hsAddFee;
+                $pass = bcsub($sendDistance, $hsFreeKm, 2);
+                $km = bcdiv($pass,1000,2);
+                //向上取整,不足1公里的按1公里算
+                $km = ceil($km);
+                return bcmul($km,$hsAddFee,2);
             } else {
                 // 在免费配送距离内
                 return 0;
             }
-        }else{
+        } else {
             new \Exception('不支持的订单类型');
         }
-        
+
         return $sendCost;
     }
-    
+
     /**
      * 参数验证
-     * 
+     *
      * @param array $params 参数数组
      * @throws \Exception 当参数不合法时抛出异常
      */
     private static function validateParams($params)
     {
         $requiredFields = [
-            'productList', 
-            'deliveryPlatform', 
-            'ghsInfo', 
-            'custom', 
-            'order', 
+            'productList',
+            'deliveryPlatform',
+            'ghsInfo',
+            'custom',
+            'order',
             'mainId'
         ];
-        
+
         foreach ($requiredFields as $field) {
             if (!isset($params[$field])) {
                 throw new \Exception("缺少必要参数:{$field}");
             }
         }
-        
+
         if (empty($params['productList']) || !is_array($params['productList'])) {
             throw new \Exception("商品列表不能为空");
         }
-        
+
         if (empty($params['ghsInfo']['mainId']) || empty($params['ghsInfo']['shopId'])) {
             throw new \Exception("供货商信息不完整");
         }