Przeglądaj źródła

Merge branch 'newsh'

shish 1 dzień temu
rodzic
commit
74a96cad73

+ 5 - 0
app-ghs/controllers/CustomController.php

@@ -1113,6 +1113,11 @@ class CustomController extends BaseController
         if (empty($ghs)) {
             util::fail('没有找到供货商');
         }
+        if (isset($get['home'])) {
+            $home = (int)$get['home'];
+            $custom->home = $home;
+            $ghs->home = $home;
+        }
         $custom->homeAmount = $homeAmount;
         $custom->homeNum = $homeNum;
         $custom->homeUnMeet = $homeUnMeet;

+ 2 - 1
app-ghs/controllers/ShMethodController.php

@@ -62,11 +62,12 @@ class ShMethodController extends BaseController
      * - id: 配置ID(可选)
      * - style: 配送类型 (0: 送货, 1: 自取, 2: 跑腿, 3: 快递, 4: 物流)
      * - name: 名称
+     * - calcType: 算运费方式 (0: 用跑腿, 1: 用自定义)
      * - status: 状态 (0: 禁用, 1: 启用)
      * - sort: 排序
      * - minAmount: 最低消费金额
      * - minNum: 最低消费数量
-     * - unMeet: 不满条件处理方式 (0: 收运费, 1: 不能下单, 2: 收包装费)
+     * - unMeet: 不满条件处理方式 (0: 收运费, 1: 收包装费, 2: 不能下单)
      * - unMeetFee: 运费/包装费金额
      * - startKm: 起步公里数
      * - startPrice: 起步价格

+ 58 - 2
app-hd/controllers/GhsController.php

@@ -8,6 +8,7 @@ use bizGhs\custom\classes\AccountMoneyClass;
 use bizGhs\custom\classes\CustomClass;
 use bizGhs\custom\classes\CustomLevelClass;
 use bizGhs\merchant\classes\WlClass;
+use bizGhs\order\classes\ShMethodClass;
 use bizGhs\shop\classes\GhsNoticeClass;
 use bizHd\purchase\classes\PurchaseClass;
 use bizHd\shop\classes\ShopExtClass;
@@ -26,6 +27,61 @@ class GhsController extends BaseController
 
     public $guestAccess = ['info', 'get-ghs-data', 'detail', 'common-info', 'ghs-notice-detail'];
 
+    //根据自定义价格,计算跑腿费用 ssh 20270730
+    public function actionCalcCustomPtFee()
+    {
+        $get = Yii::$app->request->get();
+        $id = $get['id'] ?? 0;
+        $sendType = $get['sendType'] ?? 2;
+        $ghs = GhsClass::getById($id, true);
+        if (empty($ghs)) {
+            util::fail('没有找到批发店');
+        }
+        if (!isset($ghs->ownShopId) || $ghs->ownShopId != $this->shopId) {
+            util::fail('不是你的批发店');
+        }
+        $customId = $ghs->customId ?? 0;
+        $custom = CustomClass::getById($customId, true);
+        if (empty($custom)) {
+            util::success(['sendCost' => 0, 'sendDistance' => 0]);
+        }
+        $ghsShopId = $ghs->shopId ?? 0;
+        $ghsMainId = $ghs->mainId ?? 0;
+        $shCurrentConfig = shMethodClass::getConfig($ghsShopId, $ghsMainId, $sendType);
+
+        //使用自定义计算费用
+        $startKm = $shCurrentConfig['startKm'] ?? 0;
+        $startPrice = $shCurrentConfig['startPrice'] ?? 0;
+        $perKmPrice = $shCurrentConfig['perKmPrice'] ?? 0;//超出起步,每公里加收金额
+        $changeRate = $shCurrentConfig['changeRate'] ?? 0;//负值时为降价百分比,正值时为涨价百分比
+        if ($startKm <= 0 || $startPrice <= 0 || $perKmPrice <= 0) {
+            util::success(['sendCost' => 0, 'distanceKm' => 0,'distance'=>0]);
+        }
+        //计算客户到店的距离,骑电动车
+        $distanceRespond = mapUtil::calcShopDistanceByEleBike($custom, $ghs, 0);
+        $sendDistance = $distanceRespond['distanceKm'] ?? 0;
+        $distance = $distanceRespond['distance'] ?? 0;
+        $distance = floatval($distance);
+        $sendDistance = floatval($sendDistance);
+        if ($sendDistance <= 0) {
+            util::success(['sendCost' => 0, 'distanceKm' => 0,'distance'=>0]);
+        }
+        // 计算运费逻辑
+        $sendCost = $startPrice;
+        if ($sendDistance > $startKm) {
+            $extraDistance = bcsub($sendDistance, $startKm, 2);
+            $extraCost = bcmul($extraDistance, $perKmPrice, 2);
+            $sendCost = bcadd($sendCost, $extraCost, 2);
+        }
+        if ($changeRate != 0) {
+            // 临时涨价/降价百分比
+            $rate = bcadd(1, bcdiv($changeRate, 100, 4), 4);
+            $sendCost = bcmul($sendCost, $rate, 2);
+        }
+        $sendCost = floatval($sendCost);
+        util::success(['sendCost' => $sendCost, 'distanceKm' => $sendDistance,'distance'=>$distance]);
+    }
+
     //提示花店有多个供货商
     public function actionRemindMoreGhs()
     {
@@ -303,15 +359,14 @@ class GhsController extends BaseController
             }
         }
 
+        /*****此区域部分可以考虑删除******/
         $shopExt = ShopExtClass::getByCondition(['shopId' => $ghsShopId], false, false, 'purchaseGuide,purchaseGuideText,hcFreeKm,hcMap');
         $ghsInfo['buyNotice'] = $ghsShop->buyNotice ?? 0;
         $ghsInfo['buyNoticeText'] = $shopExt['purchaseGuideText'] ?? '';
-
         //判断是否开启同城配送功能
         $intraCityRet = ShopClass::hasIntraCity($ghsShop);
         $openIntraCity = $intraCityRet['openIntraCity'];
         $ghsInfo['openIntraCity'] = $openIntraCity;
-
         //花材的免费配送设置
         $hcFreeKm = $shopExt['hcFreeKm'] ?? 0;
         $ghsInfo['hcFreeKm'] = $hcFreeKm;
@@ -321,6 +376,7 @@ class GhsController extends BaseController
             $hcMap = json_decode($hcMapString, true);
         }
         $ghsInfo['hcMap'] = $hcMap;
+        /*****此区域部分可以考虑删除******/
 
         //是否使用新的配送方式,关键词 sh_method_area
         $newShMethod = dict::getNewMethodShop();

+ 8 - 12
app-hd/controllers/NoticeController.php

@@ -192,14 +192,13 @@ class NoticeController extends PublicController
                         Yii::$app->redis->executeCommand('SETEX', [$key, 86400, '1']);
                     }
                 } else {
-                    //标记当配送方式已收一次包装费/运费,岭南批发市场用的功能,关键词 sh_method_area,只要有成功单就标记,不再要求金额必须>0
+                    //标记当配送方式已成功下过单,后续不再要求门槛或加收费用
                     $customId = $cg->customId ?? 0;
                     $current = date("Y_m_d");
-                    if (isset($cg->sendType) && in_array($cg->sendType, [0, 4])) {
+                    if (isset($cg->sendType)) {
                         $key = 'ghs_custom_today_has_get_pack_cost_' . $cg->sendType . '_' . $current . '_' . $customId;
                         Yii::$app->redis->executeCommand('SETEX', [$key, 86400, '1']);
 
-                        // 兼容快递收运费的情况
                         $sendKey = 'ghs_custom_today_has_get_send_cost_' . $cg->sendType . '_' . $current . '_' . $customId;
                         Yii::$app->redis->executeCommand('SETEX', [$sendKey, 86400, '1']);
                     }
@@ -411,14 +410,13 @@ class NoticeController extends PublicController
                         Yii::$app->redis->executeCommand('SETEX', [$key, 86400, '1']);
                     }
                 } else {
-                    //标记当配送方式已收一次包装费/运费,岭南批发市场用的功能,关键词 sh_method_area,只要有成功单就标记,不再要求金额必须>0
+                    //标记当配送方式已成功下过单,后续不再要求门槛或加收费用
                     $customId = $cg->customId ?? 0;
                     $current = date("Y_m_d");
-                    if (isset($cg->sendType) && in_array($cg->sendType, [0, 4])) {
+                    if (isset($cg->sendType)) {
                         $key = 'ghs_custom_today_has_get_pack_cost_' . $cg->sendType . '_' . $current . '_' . $customId;
                         Yii::$app->redis->executeCommand('SETEX', [$key, 86400, '1']);
 
-                        // 兼容快递收运费的情况
                         $sendKey = 'ghs_custom_today_has_get_send_cost_' . $cg->sendType . '_' . $current . '_' . $customId;
                         Yii::$app->redis->executeCommand('SETEX', [$sendKey, 86400, '1']);
                     }
@@ -579,14 +577,13 @@ class NoticeController extends PublicController
                     }
                 } else {
 
-                    //标记当配送方式已收一次包装费/运费,岭南批发市场用的功能,关键词 sh_method_area,只要有成功单就标记,不再要求金额必须>0
+                    //标记当配送方式已成功下过单,后续不再要求门槛或加收费用
                     $customId = $cg->customId ?? 0;
                     $current = date("Y_m_d");
-                    if (isset($cg->sendType) && in_array($cg->sendType, [0, 4])) {
+                    if (isset($cg->sendType)) {
                         $key = 'ghs_custom_today_has_get_pack_cost_' . $cg->sendType . '_' . $current . '_' . $customId;
                         Yii::$app->redis->executeCommand('SETEX', [$key, 86400, '1']);
 
-                        // 兼容快递收运费的情况
                         $sendKey = 'ghs_custom_today_has_get_send_cost_' . $cg->sendType . '_' . $current . '_' . $customId;
                         Yii::$app->redis->executeCommand('SETEX', [$sendKey, 86400, '1']);
                     }
@@ -836,14 +833,13 @@ class NoticeController extends PublicController
                                 Yii::$app->redis->executeCommand('SETEX', [$key, 86400, '1']);
                             }
                         } else {
-                                //标记当配送方式已收一次包装费/运费,岭南批发市场用的功能,关键词 sh_method_area,只要有成功单就标记,不再要求金额必须>0
+                                //标记当配送方式已成功下过单,后续不再要求门槛或加收费用
                                 $customId = $cg->customId ?? 0;
                                 $current = date("Y_m_d");
-                                if (isset($cg->sendType) && in_array($cg->sendType, [0, 4])) {
+                                if (isset($cg->sendType)) {
                                     $key = 'ghs_custom_today_has_get_pack_cost_' . $cg->sendType . '_' . $current . '_' . $customId;
                                     Yii::$app->redis->executeCommand('SETEX', [$key, 86400, '1']);
 
-                                    // 兼容快递收运费的情况
                                     $sendKey = 'ghs_custom_today_has_get_send_cost_' . $cg->sendType . '_' . $current . '_' . $customId;
                                     Yii::$app->redis->executeCommand('SETEX', [$sendKey, 86400, '1']);
                                 }

+ 113 - 27
app-hd/controllers/PurchaseController.php

@@ -22,6 +22,7 @@ use common\components\dateUtil;
 use common\components\delivery\util\DeliveryQuoteUtil;
 use common\components\dict;
 use common\components\imgUtil;
+use common\components\mapUtil;
 use common\components\noticeUtil;
 use common\components\orderSn;
 use Yii;
@@ -622,30 +623,114 @@ class PurchaseController extends BaseController
                 // xhShMethod 门店:下单前按配置写入不满最低消费时的附加包装费/运费,关键词 sh_method_area
                 $newShMethod = dict::getNewMethodShop();
                 if (in_array($ghsShopId, $newShMethod)) {
-                    $shMethodBigNum = 0;
-                    foreach ($productList as $itemData) {
-                        $shMethodBigNum += floatval($itemData['bigNum'] ?? 0);
-                    }
-                    $additionalCosts = ShMethodClass::calcFee(
-                        $ghsShopId,
-                        $ghsMainId,
-                        $sendType,
-                        $shMethodItemAmount,
-                        $shMethodBigNum,
-                        $customId,
-                        $ghsInfo
-                    );
-
-                    // 如果产生了附加运费,与前面可能产生的 sendCost 进行累加或覆盖
-                    if ($additionalCosts['sendCost'] > 0) {
-                        $post['sendCost'] = bcadd($post['sendCost'] ?? 0, $additionalCosts['sendCost'], 2);
+
+                    $shCurrentConfig = shMethodClass::getConfig($ghsShopId, $ghsMainId, $sendType);
+                    $shCurrentName = $shCurrentConfig['name'] ?? '';
+                    if (isset($shCurrentConfig['status']) && $shCurrentConfig['status'] == 0) {
+                        util::fail($shCurrentName . '已停用');
                     }
 
-                    // 如果产生了附加包装费,覆盖前面赋值的 packCost
-                    if ($additionalCosts['packCost'] > 0) {
-                        $post['packCost'] = $additionalCosts['packCost'];
+                    if ($sendType == dict::getDict('sendType', 'thirdSend')) {
+                        //如果是发跑腿
+
+                        // 生成随机订单号,不要跟原来的订单号混起来,跑腿-销售单-
+                        $prefix = 'PT-XSD-' . $this->mainId . '-';
+                        $orderSn = $prefix . round(microtime(true) * 1000);
+
+                        $calcType = $shCurrentConfig['calcType'] ?? 0;
+                        if ($calcType == 1) {
+                            //使用自定义计算费用
+                            $startKm = $shCurrentConfig['startKm'] ?? 0;
+                            $startPrice = $shCurrentConfig['startPrice'] ?? 0;
+                            $perKmPrice = $shCurrentConfig['perKmPrice'] ?? 0;//超出起步,每公里加收金额
+                            $changeRate = $shCurrentConfig['changeRate'] ?? 0;//负值时为降价百分比,正值时为涨价百分比
+                            if ($startKm <= 0 || $startPrice <= 0 || $perKmPrice <= 0) {
+                                util::fail('算运费失败,请更换配送方式');
+                            }
+                            //计算客户到店的距离,骑电动车
+                            $distanceRespond = mapUtil::calcShopDistanceByEleBike($custom, $ghsShopInfo);
+                            $sendDistance = $distanceRespond['distanceKm'] ?? 0;
+                            if ($sendDistance <= 0) {
+                                util::fail('算运费失败,距离是0,请选到店自取');
+                            }
+                            // 计算运费逻辑
+                            $sendCost = $startPrice;
+                            if ($sendDistance > $startKm) {
+                                $extraDistance = bcsub($sendDistance, $startKm, 2);
+                                $extraCost = bcmul($extraDistance, $perKmPrice, 2);
+                                $sendCost = bcadd($sendCost, $extraCost, 2);
+                            }
+                            if ($changeRate != 0) {
+                                // 临时涨价/降价百分比
+                                $rate = bcadd(1, bcdiv($changeRate, 100, 4), 4);
+                                $sendCost = bcmul($sendCost, $rate, 2);
+                            }
+
+                            $post['sendCost'] = bcadd($post['sendCost'] ?? 0, $sendCost, 2);
+                            $post['sendDistance'] = $sendDistance;
+
+                        } else {
+                            // 使用 DeliveryQuoteUtil 获取配送报价
+                            try {
+                                $quoteResult = DeliveryQuoteUtil::getDeliveryQuote([
+                                    'productList' => $productList,
+                                    'deliveryPlatform' => $post['deliveryPlatform'],
+                                    'deliveryBracketContent' => $post['deliveryBracketContent'], // 平台多报价识别id
+                                    'ghsInfo' => $ghsInfo,
+                                    'custom' => $custom,
+                                    'order' => [
+                                        'orderSn' => $orderSn,
+                                        'goodsType' => 1, //商品类型:0 花束 1 花材
+                                        'itemTotalAmount' => $post['itemTotalAmount'] ?? 0,
+                                        'remark' => $post['remark'] ?? '',
+                                    ],
+                                    'mainId' => $this->mainId,
+                                    'productCount' => $productCount,
+                                    //当前配送方式
+                                    'shConfig' => $shCurrentConfig,
+                                ]);
+
+                                $sendCost = $quoteResult['sendCost'];
+                                $sendDistance = $quoteResult['sendDistance'];
+
+                                $post['sendCost'] = bcadd($post['sendCost'] ?? 0, $sendCost, 2);
+                                $post['sendDistance'] = $sendDistance;
+
+                            } catch (\Exception $e) {
+                                noticeUtil::push("计算跑腿费用出错了:" . $e->getMessage(), '15280215347');
+                                util::fail('下单失败,请选其他配送方式');
+                            }
+                        }
+
+                    } else {
+                        //如果是不是发跑腿,比如送货上门和发快递,则可能要收运费或打包费任一
+
+                        $shMethodBigNum = 0;
+                        foreach ($productList as $itemData) {
+                            $shMethodBigNum += floatval($itemData['bigNum'] ?? 0);
+                        }
+
+                        $additionalCosts = ShMethodClass::calcFee(
+                            $shCurrentConfig,
+                            $sendType,
+                            $shMethodItemAmount,
+                            $shMethodBigNum,
+                            $customId,
+                            $ghsInfo
+                        );
+
+                        // 如果产生了附加运费,与前面可能产生的 sendCost 进行累加或覆盖
+                        if ($additionalCosts['sendCost'] > 0) {
+                            $post['sendCost'] = bcadd($post['sendCost'] ?? 0, $additionalCosts['sendCost'], 2);
+                        }
+                        // 如果产生了附加包装费,覆盖前面赋值的 packCost。
+                        if ($additionalCosts['packCost'] > 0) {
+                            $post['packCost'] = $additionalCosts['packCost'];
+                        }
+
                     }
-                }else{
+
+                } else {
 
                     //同城发货包装费和运费的计算
                     $sendCost = 0;
@@ -658,7 +743,7 @@ class PurchaseController extends BaseController
                             util::fail('不能使用跑腿');
                         }
                         if ($openIntraCity == 1) {
-                            // 生成随机订单号,不要跟原来的混起来,跑腿-销售单-
+                            // 生成随机订单号,不要跟原来的单号混起来,跑腿-销售单-
                             $prefix = 'PT-XSD-' . $this->mainId . '-';
                             $orderSn = $prefix . round(microtime(true) * 1000);
 
@@ -688,7 +773,8 @@ class PurchaseController extends BaseController
                                 $sendCost = $quoteResult['sendCost'];
                                 $sendDistance = $quoteResult['sendDistance'];
                             } catch (\Exception $e) {
-                                util::fail($e->getMessage());
+                                noticeUtil::push("计算跑腿费用出错了:" . $e->getMessage(), '15280215347');
+                                util::fail('下单失败,请选其他配送方式');
                             }
                         }
                     }
@@ -770,7 +856,7 @@ class PurchaseController extends BaseController
 
                         //情意花卉,必选品
                         if ($ghsShopId == 100883) {
-                            $hasMust = array_intersect($ids, [5017957,5036067,5036089,5036099,5017958,5036063,5017948,5035980,5036073,5036075,5036076,5036117,5036118,5017949,5035979,5035976,5035928,5035930,5036061,5035879]);
+                            $hasMust = array_intersect($ids, [5017957, 5036067, 5036089, 5036099, 5017958, 5036063, 5017948, 5035980, 5036073, 5036075, 5036076, 5036117, 5036118, 5017949, 5035979, 5035976, 5035928, 5035930, 5036061, 5035879]);
                             if (empty($hasMust)) {
                                 util::fail('请返回选择 必选商品');
                             }
@@ -950,13 +1036,13 @@ class PurchaseController extends BaseController
                     Yii::$app->redis->executeCommand('SETEX', [$key, 86400, '1']);
                 }
             } else {
-                //标记当配送方式已收一次包装费/运费,岭南批发市场用的功能,关键词 sh_method_area,只要有成功单就标记,不再要求金额必须>0
+                //标记当配送方式已收一次包装费/运费,只要有成功单就标记,后续不再重复要求门槛或加收费用
                 $current = date("Y_m_d");
-                if (isset($info->sendType) && in_array($info->sendType, [0, 4])) {
+                if (isset($info->sendType)) {
                     $key = 'ghs_custom_today_has_get_pack_cost_' . $info->sendType . '_' . $current . '_' . $customId;
                     Yii::$app->redis->executeCommand('SETEX', [$key, 86400, '1']);
 
-                    // 兼容快递收运费的情况
+                    // 兼容快递/送货/跑腿收运费或限制下单的情况
                     $sendKey = 'ghs_custom_today_has_get_send_cost_' . $info->sendType . '_' . $current . '_' . $customId;
                     Yii::$app->redis->executeCommand('SETEX', [$sendKey, 86400, '1']);
                 }

+ 3 - 7
app-hd/controllers/ShMethodController.php

@@ -56,13 +56,9 @@ class ShMethodController extends BaseController
                     $hasPaidSendCost = ShMethodClass::isSendCostPaidToday($customId, $style);
                     $hasPaidPackCost = ShMethodClass::isPackPaidToday($customId, $style);
 
-                    // 如果是加收运费或加收包装费,并且今天已经收过对应的费用
-                    // 则将前端展示的条件清空(设为0),从而不再显示要收附加费的提示
-                    if ($unMeet === 0 && $hasPaidSendCost) {
-                        $config['minAmount'] = 0;
-                        $config['minNum'] = 0;
-                        $config['unMeetFee'] = 0;
-                    } elseif ($unMeet === 2 && $hasPaidPackCost) {
+                    // 如果是加收运费、加收包装费或不能下单,并且今天已经成功下单/收取过费用
+                    // 则将前端展示的条件清空(设为0),从而不再显示要收附加费或限制下单的提示
+                    if (($unMeet === 0 && $hasPaidSendCost) || ($unMeet === 1 && $hasPaidPackCost) || ($unMeet === 2 && ($hasPaidSendCost || $hasPaidPackCost))) {
                         $config['minAmount'] = 0;
                         $config['minNum'] = 0;
                         $config['unMeetFee'] = 0;

+ 14 - 11
biz-ghs/order/classes/ShMethodClass.php

@@ -254,7 +254,11 @@ class ShMethodClass extends BaseClass
         $unMeetFee = isset($config['unMeetFee']) ? (float)$config['unMeetFee'] : 0;
 
         // 不满最低消费且不允许下单
-        if ($unMeet === 1) {
+        if ($unMeet === 2) {
+            // 如果当天该配送方式已成功下过单,不再限制,直接放行
+            if (self::isPackPaidToday($customId, $style) || self::isSendCostPaidToday($customId, $style)) {
+                return '';
+            }
             if ($minAmount > 0 && (float)$actPrice < $minAmount) {
                 return "满{$minAmount}元 可{$methodName}";
             }
@@ -265,12 +269,12 @@ class ShMethodClass extends BaseClass
         }
 
         // 不满最低消费但允许加收费用时,校验包装费/运费是否已写入采购单,防止前端绕过
-        if (($unMeet === 0 || $unMeet === 2) && $unMeetFee > 0) {
-            // unMeet === 0 加收运费, unMeet === 2 加收包装费
-            $feeToCheck = $unMeet === 2 ? $packCost : $sendCost;
+        if (($unMeet === 0 || $unMeet === 1) && $unMeetFee > 0) {
+            // unMeet === 0 加收运费, unMeet === 1 加收包装费
+            $feeToCheck = $unMeet === 1 ? $packCost : $sendCost;
             
             // 如果今天已经收过对应的附加费用,则直接通过校验
-            if ($unMeet === 2 && self::isPackPaidToday($customId, $style)) {
+            if ($unMeet === 1 && self::isPackPaidToday($customId, $style)) {
                 return '';
             }
             if ($unMeet === 0 && self::isSendCostPaidToday($customId, $style)) {
@@ -278,7 +282,7 @@ class ShMethodClass extends BaseClass
             }
             
             if (bccomp((string)$feeToCheck, (string)$unMeetFee, 2) < 0) {
-                $feeLabel = $unMeet === 2 ? '包装费' : '运费';
+                $feeLabel = $unMeet === 1 ? '包装费' : '运费';
                 return "未达最低消费,需加收{$feeLabel}{$unMeetFee}元";
             }
         }
@@ -334,7 +338,7 @@ class ShMethodClass extends BaseClass
      * @param array|object $ghsInfo 客户与该供货商的关系信息(xhGhs)
      * @return array ['sendCost' => 运费, 'packCost' => 包装费]
      */
-    public static function calcFee($shopId, $mainId, $sendType, $itemTotalAmount, $bigNum, $customId = 0, $ghsInfo = [])
+    public static function calcFee($config, $sendType, $itemTotalAmount, $bigNum, $customId = 0, $ghsInfo = [])
     {
         $costs = ['sendCost' => 0, 'packCost' => 0];
         
@@ -343,8 +347,6 @@ class ShMethodClass extends BaseClass
             return $costs;
         }
 
-        $config = self::getConfig($shopId, $mainId, $style);
-
         if (empty($config)) {
             return $costs;
         }
@@ -380,12 +382,12 @@ class ShMethodClass extends BaseClass
         $unMeetFee = isset($config['unMeetFee']) ? (float)$config['unMeetFee'] : 0;
         
         if ($unMeetFee > 0) {
-            // unMeet: 0 加收运费(默认),2 加收包装费
+            // unMeet: 0 加收运费(默认),1 加收包装费,2 不能下单
             if ($unMeet === 0) {
                 if (!self::isSendCostPaidToday($customId, $style)) {
                     $costs['sendCost'] = $unMeetFee;
                 }
-            } elseif ($unMeet === 2) {
+            } elseif ($unMeet === 1) {
                 if (!self::isPackPaidToday($customId, $style)) {
                     $costs['packCost'] = $unMeetFee;
                 }
@@ -421,6 +423,7 @@ class ShMethodClass extends BaseClass
 
         $saveData = [
             'name' => $data['name'] ?? '',
+            'calcType' => isset($data['calcType']) ? (int)$data['calcType'] : 0, // 算运费方式 (0: 用跑腿, 1: 用自定义)
             'status' => isset($data['status']) ? (int)$data['status'] : 1,
             'sort' => isset($data['sort']) ? (int)$data['sort'] : 0,
             'minAmount' => isset($data['minAmount']) ? (float)$data['minAmount'] : 0.00,

+ 71 - 14
common/components/delivery/util/DeliveryQuoteUtil.php

@@ -115,20 +115,42 @@ class DeliveryQuoteUtil
         $sendCost = ($result['price'] ?? 0) / 100;
         $sendDistance = $result['distance'] ?? 0;
 
-        // 11. 应用免费配送规则
-        if(isset($params['order']['freightType']) && $params['order']['freightType'] == 0) { //用于处理及区分花束订单是否部分免跑腿费,还是完全收取跑腿费
-            $finalSendCost= $sendCost;
-        }else{
-            $finalSendCost = self::applyFreeDeliveryRules(
-                $sendCost,
-                $sendDistance,
-                $params['ghsInfo']['shopId'],
-                $params['productCount'],
-                $params['order']['itemTotalAmount'],
-                $params['ghsInfo']['mainId'],
-                $order['orderSn'],
-                $order['goodsType']
-            );
+        if (empty($params['shConfig'])) {
+            //旧的规则走这个
+
+            // 11. 应用免费配送规则
+            if (isset($params['order']['freightType']) && $params['order']['freightType'] == 0) { //用于处理及区分花束订单是否部分免跑腿费,还是完全收取跑腿费
+                $finalSendCost = $sendCost;
+            } else {
+                $finalSendCost = self::applyFreeDeliveryRules(
+                    $sendCost,
+                    $sendDistance,
+                    $params['ghsInfo']['shopId'],
+                    $params['productCount'],
+                    $params['order']['itemTotalAmount'],
+                    $params['ghsInfo']['mainId'],
+                    $order['orderSn'],
+                    $order['goodsType']
+                );
+            }
+        } else {
+            //新免费规则走这里,欧阳写到这里有问题沟通 ssh 20260730
+
+            $freightType = $params['order']['freightType'] ?? 0; //运费计算方式,0 按距离计算 1 免运费,包运费
+            $property = $order['goodsType'] ?? 1;//订单是什么类型订单 0 花束订单 1 花材订单,多种商品,只要含一把花束,就是花束订单
+            $totalPrice = $params['order']['itemTotalAmount'] ?? 0;
+            $totalNum = $params['productCount'] ?? 0;
+            $element = [
+                'shConfig' => $params['shConfig'],
+                'sendCost' => $sendCost,
+                'sendDistance' => $sendDistance,
+                'freightType' => $freightType,
+                'property' => $property,
+                'totalPrice' => $totalPrice,
+                'totalNum' => $totalNum,
+            ];
+            $discountRespond = self::discountSearch($element);
+            $finalSendCost = $discountRespond['sendCost'] ?? 0;
         }
 
         return [
@@ -139,6 +161,41 @@ class DeliveryQuoteUtil
         ];
     }
 
+    //查询是否符合跑腿的满减规则
+    private static function discountSearch($params)
+    {
+        $shConfig = $params['shConfig'] ?? [];
+        $sendCost = $params['sendCost'] ?? 0;
+        $sendDistance = $params['sendDistance'] ?? 0;
+        $sendDistanceKm = bcdiv($sendDistance, 1000, 2);
+        $freightType = $params['freightType'] ?? 0;
+        //0 花束 1 花材
+        $property = $params['property'] ?? 1;
+        $totalPrice = $params['totalPrice'] ?? 0;
+        $totalNum = $params['totalNum'] ?? 0;
+
+        //免运费的情况 (配置本身设为包邮)
+        if ($freightType == 1) {
+            return ['sendCost' => 0];
+        }
+
+        // 遍历满减规则,判断是否符合免邮条件
+        if (!empty($shConfig['reduceRules']) && is_array($shConfig['reduceRules'])) {
+            foreach ($shConfig['reduceRules'] as $rule) {
+                $meetNum = (float)($rule['meetNum'] ?? 0);
+                $meetAmount = (float)($rule['meetAmount'] ?? 0);
+                $freeKm = (float)($rule['freeKm'] ?? 0);
+
+                // 校验规则:金额满 meetAmount 且 数量满 meetNum 且 距离在 freeKm 以内
+                if ($totalPrice >= $meetAmount && $totalNum >= $meetNum && $sendDistanceKm <= $freeKm) {
+                    return ['sendCost' => 0];
+                }
+            }
+        }
+
+        return ['sendCost' => $sendCost];
+    }
+
     /**
      * 计算商品总重量
      *

+ 5 - 0
common/components/dict.php

@@ -13,6 +13,7 @@ class dict
             0 => [
                 'name' => '送货',
                 'originName' => '送货',
+                'calcType' => 0,
                 'status' => 1,
                 'sort' => 1,
                 'minAmount' => 0.00,
@@ -27,6 +28,7 @@ class dict
             1 => [
                 'name' => '自取',
                 'originName' => '自取',
+                'calcType' => 0,
                 'status' => 1,
                 'sort' => 2,
                 'minAmount' => 0.00,
@@ -41,6 +43,7 @@ class dict
             2 => [
                 'name' => '跑腿',
                 'originName' => '跑腿',
+                'calcType' => 0,
                 'status' => 1,
                 'sort' => 3,
                 'minAmount' => 0.00,
@@ -55,6 +58,7 @@ class dict
             4 => [
                 'name' => '快递',
                 'originName' => '快递',
+                'calcType' => 0,
                 'status' => 1,
                 'sort' => 4,
                 'minAmount' => 0.00,
@@ -69,6 +73,7 @@ class dict
             3 => [
                 'name' => '物流',
                 'originName' => '物流',
+                'calcType' => 0,
                 'status' => 1,
                 'sort' => 5,
                 'minAmount' => 0.00,

+ 43 - 5
common/components/mapUtil.php

@@ -47,6 +47,44 @@ class mapUtil
         return $distance;
     }
 
+    //计算客户到店距离,骑电动车 ssh 2026.7.30
+    public static function calcShopDistanceByEleBike($beginPlace, $toPlace, $report = 1)
+    {
+        $beginLnt = $beginPlace->long ?? '';
+        $beginLat = $beginPlace->lat ?? '';
+        $toLnt = $toPlace->long ?? '';
+        $toLat = $toPlace->lat ?? '';
+
+        // 校验经纬度参数格式
+        if (empty($beginLnt) || empty($beginLat)) {
+            if ($report == 1) {
+                util::fail('计算距离失败,请完善地址');
+            }
+            return ['distance' => 0, 'distanceKm' => 0];
+        }
+        if (!is_numeric($beginLnt) || !is_numeric($beginLat)) {
+            if ($report == 1) {
+                util::fail('计算距离失败,请完善地址');
+            }
+            return ['distance' => 0, 'distanceKm' => 0];
+        }
+        if (empty($toLnt) || empty($toLat)) {
+            if ($report == 1) {
+                util::fail('计算距离失败,商家地址没有完善');
+            }
+            return ['distance' => 0, 'distanceKm' => 0];
+        }
+        if (!is_numeric($toLnt) || !is_numeric($toLat)) {
+            if ($report == 1) {
+                util::fail('计算距离失败,商家地址没有完善');
+            }
+            return ['distance' => 0, 'distanceKm' => 0];
+        }
+        $distance = self::calculateDistance($beginLnt, $beginLat, $toLnt, $toLat);
+        $distanceKm = bcdiv($distance, 1000, 2);
+        return ['distance' => $distance, 'distanceKm' => $distanceKm];
+    }
+
     /**
      * 批量计算多个起点到一个终点的距离 (高德 V3 距离测量接口)
      * @param array $origins 起点坐标数组,例如:[['lng' => '116.481028', 'lat' => '39.989643'], ...]
@@ -79,12 +117,12 @@ class mapUtil
         if (!empty($result['status']) && $result['status'] == 1 && !empty($result['results'])) {
             foreach ($result['results'] as $index => $res) {
                 // 返回的结果顺序与传入的 origins 顺序一致
-                $distances[$index] = $res['distance'] ?? 0; 
+                $distances[$index] = $res['distance'] ?? 0;
             }
-        }else{
-            noticeUtil::push("高德批量测距接口返回失败:".json_encode($result)." url:".$url);
+        } else {
+            noticeUtil::push("高德批量测距接口返回失败:" . json_encode($result) . " url:" . $url);
         }
-        
+
         return $distances;
     }
 
@@ -316,4 +354,4 @@ class mapUtil
         }
         return false;
     }
-}
+}