Преглед изворни кода

Merge branch 'redesign‌-260706' into dev

ouyang пре 2 недеља
родитељ
комит
8d08eaae9b

+ 3 - 0
app-hd/controllers/DeliveryController.php

@@ -7,6 +7,7 @@ use Yii;
 use biz\ghs\classes\GhsClass;
 use bizGhs\express\classes\DeliveryAuthTokenClass;
 use bizHd\order\classes\OrderClass;
+use bizHd\order\classes\PsMethodClass;
 use bizHd\express\classes\HdDeliveryOrderClass;
 use hd\models\delivery\CancelOrderForm;
 use hd\models\delivery\CreateOrderForm;
@@ -463,6 +464,8 @@ class DeliveryController extends BaseController
 
         $ret = DeliveryAuthTokenClass::deleteByCondition(['mainId' => $this->mainId, 'platform' => $platform]);
         if ($ret > 0) {
+            // 全部取消授权后:无完整自定义则禁用跑腿方式;有自定义则保持启用(主路径/兜底)
+            PsMethodClass::disableRunnerIfNoAuthLeft($this->mainId);
             util::success(['message' => '取消授权成功']);
         } else {
             util::fail('取消授权失败');

+ 110 - 42
app-mall/controllers/OrderController.php

@@ -30,6 +30,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 common\components\stringUtil;
@@ -1268,6 +1269,8 @@ class OrderController extends BaseController
                         'productId' => $saleGoodsId,
                         'unitType' => 0,
                         'property' => 0,
+                        // 花束是否包运费:供跑腿运费分支判断(1=包运费)
+                        'freightType' => (int)($goodsInfo->freightType ?? 0),
                         'unitPrice' => $unitPrice,
                         'num' => $goodsNum,
                         'seckillGoodsId' => $seckillActivityGoodsId,
@@ -1291,12 +1294,19 @@ class OrderController extends BaseController
 
             $sendType = intval($post['sendType'] ?? 0);
             $customInfo = \bizHd\order\classes\PsMethodClass::buildCustomInfo($hd, $custom);
+            // 最低消费数量:花材扎数 + 花束份数(与结算页「还差 N 扎」同源)
+            $unMeetBigNum = $itemBigNum;
+            foreach ($resolvedProduct as $row) {
+                if ((int)($row['property'] ?? 1) === 0) {
+                    $unMeetBigNum = bcadd($unMeetBigNum, $row['num'] ?? 0, 2);
+                }
+            }
             $additionalCosts = \bizHd\order\classes\PsMethodClass::calcFeeForMallContext(
                 $this->shopId,
                 $this->mainId,
                 $sendType,
                 $goodsOnlyPrice,
-                $itemBigNum,
+                $unMeetBigNum,
                 $hdCustomId,
                 $customInfo
             );
@@ -1309,8 +1319,9 @@ class OrderController extends BaseController
             // 含花材(含混合)按花材报价 goodsType=1;纯花束按 0
             $quoteGoodsType = $hasItem ? 1 : 0;
 
-            if (isset($post['sendType']) && $post['sendType'] == 2 && $openIntraCity != 0) {
-                if ($openIntraCity == 2) {
+            // 跑腿 style=2:按包运费花束 / 不包运费花束 / 纯花材满减 + 跑腿或自定义(异常兜底)
+            if (isset($post['sendType']) && (int)$post['sendType'] === 2) {
+                if ((int)$openIntraCity === 2) {
                     util::fail('不能使用跑腿');
                 }
                 if (empty($post['long']) || empty($post['lat'])) {
@@ -1321,48 +1332,105 @@ class OrderController extends BaseController
                 if (empty($shopLat) || empty($shopLong)) {
                     util::fail('商家门店地址定位未设置,编号263');
                 }
-                $distance = 0;
+
+                $psConfig = PsMethodClass::getConfig($this->shopId, $this->mainId, 2);
+                if (empty($psConfig) || (int)($psConfig['status'] ?? 0) !== 1) {
+                    util::fail('跑腿配送方式未启用');
+                }
+                $freightMode = PsMethodClass::resolveMixRunnerFreightMode($resolvedProduct);
+                $calcType = (int)($psConfig['calcType'] ?? 0);
+
+                $quoteCustom = (object)[
+                    'name' => $post['receiveUserName'] ?? '',
+                    'mobile' => $post['receiveMobile'] ?? '',
+                    'fullAddress' => $post['address'] ?? ($post['fullAddress'] ?? ''),
+                    'floor' => $post['floor'] ?? '',
+                    'dist' => $post['dist'] ?? '',
+                    'lat' => $post['lat'],
+                    'long' => $post['long'],
+                    'address' => $post['address'] ?? '',
+                    'city' => $post['city'] ?? '',
+                ];
+                $distanceRespond = mapUtil::calcShopDistanceByEleBike($quoteCustom, $shop, 0);
+                $distanceMeters = (float)($distanceRespond['distance'] ?? 0);
+                $distanceKm = (float)($distanceRespond['distanceKm'] ?? 0);
+                if ($distanceMeters <= 0 && $distanceKm <= 0) {
+                    util::fail('算运费失败,请完善收货地址');
+                }
+                if ($distanceMeters <= 0 && $distanceKm > 0) {
+                    $distanceMeters = $distanceKm * 1000;
+                }
+
                 $sendCost = 0;
-                $prefix = 'PT-MIX-' . $this->mainId . '-';
-                $orderSn = $prefix . round(microtime(true) * 1000);
-                $ghsInfo = ['mainId' => $this->mainId, 'shopId' => $this->shopId];
-                try {
-                    if (empty($post['deliveryPlatform'])) {
-                        util::fail('请选择跑腿');
+                $freightSource = '';
+
+                if ($freightMode === 'bouquetIncluded') {
+                    // A:含包运费花束 → hsFreeKm / hsPerKmPrice
+                    $sendCost = PsMethodClass::calcBouquetFreightByDistance($psConfig, $distanceMeters);
+                    $freightSource = 'bouquetIncluded';
+                } elseif ($freightMode === 'flowerOnly'
+                    && PsMethodClass::matchReduceRuleFree($psConfig, $distanceMeters, $itemBigNum, $goodsOnlyPrice)) {
+                    // C:纯花材命中满减 → 免跑腿
+                    $sendCost = 0;
+                    $freightSource = 'reduceFree';
+                } else {
+                    // B 或不免满减的 C:按 calcType 跑腿或自定义;跑腿异常最终自定义兜底
+                    if ($calcType === 1) {
+                        try {
+                            $sendCost = PsMethodClass::calcCustomFreightByDistance($psConfig, $distanceKm > 0 ? $distanceKm : ($distanceMeters / 1000));
+                            $freightSource = 'custom';
+                        } catch (\Exception $e) {
+                            util::fail($e->getMessage());
+                        }
+                    } else {
+                        $runnerOk = false;
+                        if ((int)$openIntraCity === 1 && !empty($post['deliveryPlatform'])) {
+                            $prefix = 'PT-MIX-' . $this->mainId . '-';
+                            $orderSn = $prefix . round(microtime(true) * 1000);
+                            $ghsInfo = ['mainId' => $this->mainId, 'shopId' => $this->shopId];
+                            try {
+                                $quoteResult = DeliveryQuoteUtil::getDeliveryQuote([
+                                    'productList' => $resolvedProduct,
+                                    'deliveryPlatform' => $post['deliveryPlatform'],
+                                    'deliveryBracketContent' => $post['deliveryBracketContent'] ?? '',
+                                    'ghsInfo' => $ghsInfo,
+                                    'custom' => $quoteCustom,
+                                    'order' => [
+                                        'orderSn' => $orderSn,
+                                        'goodsType' => $quoteGoodsType,
+                                        'itemTotalAmount' => $goodsOnlyPrice,
+                                        'remark' => $post['remark'] ?? '',
+                                    ],
+                                    'mainId' => $this->mainId,
+                                    'productCount' => $totalNum,
+                                    'shConfig' => $psConfig,
+                                ]);
+                                $sendCost = $quoteResult['sendCost'];
+                                $distanceMeters = (float)($quoteResult['sendDistance'] ?? $distanceMeters);
+                                $freightSource = 'platform';
+                                $runnerOk = true;
+                            } catch (\Exception $e) {
+                                $runnerOk = false;
+                                noticeUtil::push('商城混合单跑腿报价异常,改走自定义:' . $e->getMessage());
+                            }
+                        }
+                        if (!$runnerOk) {
+                            try {
+                                $sendCost = PsMethodClass::calcCustomFreightByDistance(
+                                    $psConfig,
+                                    $distanceKm > 0 ? $distanceKm : ($distanceMeters / 1000)
+                                );
+                                $freightSource = 'customFallback';
+                            } catch (\Exception $e) {
+                                util::fail('跑腿计算异常且自定义计费不可用,请更换配送方式');
+                            }
+                        }
                     }
-                    $quoteCustom = (object)[
-                        'name' => $post['receiveUserName'] ?? '',
-                        'mobile' => $post['receiveMobile'] ?? '',
-                        'fullAddress' => $post['address'] ?? '',
-                        'floor' => $post['floor'] ?? '',
-                        'dist' => '',
-                        'lat' => $post['lat'],
-                        'long' => $post['long'],
-                        'address' => $post['address'] ?? '',
-                        'city' => $post['city'] ?? '',
-                    ];
-                    $quoteResult = DeliveryQuoteUtil::getDeliveryQuote([
-                        'productList' => $resolvedProduct,
-                        'deliveryPlatform' => $post['deliveryPlatform'],
-                        'deliveryBracketContent' => $post['deliveryBracketContent'] ?? '',
-                        'ghsInfo' => $ghsInfo,
-                        'custom' => $quoteCustom,
-                        'order' => [
-                            'orderSn' => $orderSn,
-                            'goodsType' => $quoteGoodsType,
-                            'itemTotalAmount' => $modifyPrice,
-                            'remark' => $post['remark'] ?? '',
-                        ],
-                        'mainId' => $this->mainId,
-                        'productCount' => $totalNum,
-                    ]);
-                    $sendCost = $quoteResult['sendCost'];
-                    $distance = $quoteResult['sendDistance'];
-                } catch (\Exception $e) {
-                    util::fail($e->getMessage());
                 }
+
                 $post['sendCost'] = $sendCost;
-                $post['sendDistance'] = $distance;
+                $post['sendDistance'] = $distanceMeters;
+                $post['freightSource'] = $freightSource;
                 $modifyPrice = bcadd($modifyPrice, $sendCost, 2);
             }
 
@@ -1414,7 +1482,7 @@ class OrderController extends BaseController
                 $this->mainId,
                 $sendType,
                 $goodsOnlyPrice,
-                $itemBigNum,
+                $unMeetBigNum,
                 $packingFee,
                 $unMeetSendCost,
                 $hdCustomId,

+ 237 - 3
biz-hd/order/classes/PsMethodClass.php

@@ -7,6 +7,7 @@
 
 namespace bizHd\order\classes;
 
+use bizGhs\express\classes\DeliveryAuthTokenClass;
 use bizHd\base\classes\BaseClass;
 use common\components\dict;
 use Yii;
@@ -187,6 +188,203 @@ class PsMethodClass extends BaseClass
         return $result;
     }
 
+    /**
+     * 自定义计费三项是否均已有效填写(起步公里/起步价/超出每公里价均大于 0)
+     * @param array $config
+     * @return bool
+     */
+    public static function isCustomConfigValid(array $config)
+    {
+        $startKm = (float)($config['startKm'] ?? 0);
+        $startPrice = (float)($config['startPrice'] ?? 0);
+        $perKmPrice = (float)($config['perKmPrice'] ?? 0);
+        return $startKm > 0 && $startPrice > 0 && $perKmPrice > 0;
+    }
+
+    /**
+     * 跑腿 style=2 是否允许启用:已绑定跑腿 或 自定义计费配置完整
+     * @param int $mainId 商户 ID
+     * @param array $config 待保存的 xhPsMethod 配置
+     * @return bool
+     */
+    public static function canEnableRunnerMethod($mainId, array $config)
+    {
+        if (self::isCustomConfigValid($config)) {
+            return true;
+        }
+        $hasAuth = DeliveryAuthTokenClass::getByCondition(['mainId' => (int)$mainId], true);
+        return !empty($hasAuth);
+    }
+
+    /**
+     * 按自定义规则计距算运费(公里)
+     * 超出起步部分:不足 1 公里按 1 公里(向上取整)
+     * @param array $config xhPsMethod
+     * @param float $distanceKm 配送距离(公里)
+     * @return float
+     * @throws \Exception
+     */
+    public static function calcCustomFreightByDistance(array $config, $distanceKm)
+    {
+        $startKm = (float)($config['startKm'] ?? 0);
+        $startPrice = (float)($config['startPrice'] ?? 0);
+        $perKmPrice = (float)($config['perKmPrice'] ?? 0);
+        $changeRate = (float)($config['changeRate'] ?? 0);
+        if ($startKm <= 0 || $startPrice <= 0 || $perKmPrice <= 0) {
+            throw new \Exception('自定义计费规则未配置完整');
+        }
+        // 与前端一致保留两位公里
+        $distanceKm = round((float)$distanceKm, 2);
+        if ($distanceKm <= 0) {
+            throw new \Exception('算运费失败,距离无效');
+        }
+        $sendCost = $startPrice;
+        if ($distanceKm > $startKm) {
+            $extraDistance = (float)bcsub((string)$distanceKm, (string)$startKm, 2);
+            // 不足 1 公里按 1 公里
+            $billableExtra = (int)ceil($extraDistance - 1e-9);
+            if ($billableExtra < 0) {
+                $billableExtra = 0;
+            }
+            $extraCost = bcmul((string)$billableExtra, (string)$perKmPrice, 2);
+            $sendCost = bcadd((string)$sendCost, $extraCost, 2);
+        }
+        if ($changeRate != 0) {
+            $rate = bcadd('1', bcdiv((string)$changeRate, '100', 4), 4);
+            $sendCost = bcmul((string)$sendCost, $rate, 2);
+        }
+        return (float)$sendCost;
+    }
+
+    /**
+     * 花束包运费:hsFreeKm 内免费,超出按 hsPerKmPrice 每公里加收(不足 1 公里按 1 公里)
+     * @param array $config xhPsMethod
+     * @param float $distanceMeters 距离(米)
+     * @return float
+     */
+    public static function calcBouquetFreightByDistance(array $config, $distanceMeters)
+    {
+        $hsFreeKm = (float)($config['hsFreeKm'] ?? 0);
+        $hsPerKmPrice = (float)($config['hsPerKmPrice'] ?? 0);
+        $freeMeters = $hsFreeKm * 1000;
+        $distanceMeters = (float)$distanceMeters;
+        if ($distanceMeters <= $freeMeters) {
+            return 0.0;
+        }
+        $diff = $distanceMeters - $freeMeters;
+        $km = (int)ceil($diff / 1000);
+        if ($km <= 0 || $hsPerKmPrice <= 0) {
+            return 0.0;
+        }
+        return (float)bcmul((string)$km, (string)$hsPerKmPrice, 2);
+    }
+
+    /**
+     * 纯花材是否命中 xhPsReduceRule 免跑腿
+     * @param array $config 含 reduceRules
+     * @param float $distanceMeters
+     * @param float $bigNum 花材扎数
+     * @param float $itemTotalAmount 商品金额
+     * @return bool
+     */
+    public static function matchReduceRuleFree(array $config, $distanceMeters, $bigNum, $itemTotalAmount)
+    {
+        $rules = $config['reduceRules'] ?? [];
+        if (!is_array($rules) || empty($rules)) {
+            return false;
+        }
+        $distanceMeters = (float)$distanceMeters;
+        $bigNum = (float)$bigNum;
+        $itemTotalAmount = (float)$itemTotalAmount;
+        foreach ($rules as $rule) {
+            $meetNum = (float)($rule['meetNum'] ?? 0);
+            $meetAmount = (float)($rule['meetAmount'] ?? 0);
+            $freeKm = (float)($rule['freeKm'] ?? 0);
+            if ($freeKm <= 0) {
+                continue;
+            }
+            $freeMeters = $freeKm * 1000;
+            $numOk = $meetNum <= 0 || $bigNum >= $meetNum;
+            $amountOk = $meetAmount <= 0 || $itemTotalAmount >= $meetAmount;
+            if ($numOk && $amountOk && $distanceMeters <= $freeMeters) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    /**
+     * 混合单跑腿运费模式:bouquetIncluded / bouquetNotIncluded / flowerOnly
+     * @param array $productList [['property'=>0|1,'freightType'=>0|1], ...]
+     * @return string
+     */
+    public static function resolveMixRunnerFreightMode(array $productList)
+    {
+        $hasBouquet = false;
+        $hasIncluded = false;
+        foreach ($productList as $row) {
+            if ((int)($row['property'] ?? 1) !== 0) {
+                continue;
+            }
+            $hasBouquet = true;
+            if ((int)($row['freightType'] ?? 0) === 1) {
+                $hasIncluded = true;
+            }
+        }
+        if ($hasBouquet && $hasIncluded) {
+            return 'bouquetIncluded';
+        }
+        if ($hasBouquet) {
+            return 'bouquetNotIncluded';
+        }
+        return 'flowerOnly';
+    }
+
+    /**
+     * 跑腿保存/启用前校验,不通过时抛异常
+     * @param int $mainId 商户 ID
+     * @param array $data 前端提交的配置
+     * @throws \Exception
+     */
+    public static function validateRunnerSave($mainId, array $data)
+    {
+        $style = (int)($data['style'] ?? 0);
+        if ($style !== 2) {
+            return;
+        }
+        $status = (int)($data['status'] ?? 1);
+        // 无论 calcType=0 用跑腿还是 =1 用自定义,都必须填写自定义计费(跑腿异常时兜底)
+        if (!self::isCustomConfigValid($data)) {
+            throw new \Exception('请完整填写自定义计费规则(起步公里、起步价、超出每公里价)');
+        }
+        if ($status === 1 && !self::canEnableRunnerMethod($mainId, $data)) {
+            throw new \Exception('请先绑定跑腿商户或配置完整的自定义计费后再启用');
+        }
+    }
+
+    /**
+     * 取消全部跑腿授权后:若自定义计费也不完整则禁用 style=2;
+     * 自定义完整则保持启用(calcType=1 主路径,或 calcType=0 跑腿异常时兜底)
+     * @param int $mainId 商户 ID
+     */
+    public static function disableRunnerIfNoAuthLeft($mainId)
+    {
+        $remaining = DeliveryAuthTokenClass::getCount(['mainId' => (int)$mainId]);
+        if ($remaining > 0) {
+            return;
+        }
+        $ps = self::getByCondition(['mainId' => (int)$mainId, 'style' => 2]);
+        if (empty($ps)) {
+            return;
+        }
+        $psArr = is_object($ps) ? $ps->toArray() : $ps;
+        // 仍有完整自定义配置时不禁用,结算可走自定义或兜底
+        if (self::isCustomConfigValid($psArr)) {
+            return;
+        }
+        self::updateByCondition(['id' => (int)$psArr['id']], ['status' => 0]);
+    }
+
     /**
      * 保存指定配送方式配置及关联说明项、满减规则
      * @param int $shopId 门店ID
@@ -200,6 +398,8 @@ class PsMethodClass extends BaseClass
         $id = $data['id'] ?? 0;
         $style = $data['style'] ?? 0;
 
+        self::validateRunnerSave($mainId, $data);
+
         $config = null;
         if ($id > 0) {
             $config = self::getByCondition(['id' => $id, 'mainId' => $mainId], true);
@@ -217,10 +417,13 @@ class PsMethodClass extends BaseClass
             'minNum' => isset($data['minNum']) ? (int)$data['minNum'] : 0,
             'unMeet' => isset($data['unMeet']) ? (int)$data['unMeet'] : 0,
             'unMeetFee' => isset($data['unMeetFee']) ? (float)$data['unMeetFee'] : 0.00,
+            'calcType' => isset($data['calcType']) ? (int)$data['calcType'] : 0,
             'startKm' => isset($data['startKm']) ? (float)$data['startKm'] : 0.00,
             'startPrice' => isset($data['startPrice']) ? (float)$data['startPrice'] : 0.00,
             'perKmPrice' => isset($data['perKmPrice']) ? (float)$data['perKmPrice'] : 0.00,
             'changeRate' => isset($data['changeRate']) ? (float)$data['changeRate'] : 0.00,
+            'hsFreeKm' => isset($data['hsFreeKm']) ? (float)$data['hsFreeKm'] : 0.00,
+            'hsPerKmPrice' => isset($data['hsPerKmPrice']) ? (float)$data['hsPerKmPrice'] : 0.00,
         ];
 
         $transaction = Yii::$app->db->beginTransaction();
@@ -335,6 +538,38 @@ class PsMethodClass extends BaseClass
         return implode('或', $parts);
     }
 
+    /**
+     * 未达门槛时「还差多少可免」提示,如:订单还差20元和3扎可免包装费
+     * @param array $config
+     * @param float $itemTotalAmount
+     * @param float $bigNum
+     * @param string $feeLabel 包装费|运费
+     * @return string
+     */
+    protected static function buildUnMeetShortTip($config, $itemTotalAmount, $bigNum, $feeLabel)
+    {
+        $minAmount = isset($config['minAmount']) ? (float)$config['minAmount'] : 0.00;
+        $minNum = isset($config['minNum']) ? (int)$config['minNum'] : 0;
+        $parts = [];
+        if ($minAmount > 0) {
+            $shortAmount = round(max(0, $minAmount - (float)$itemTotalAmount), 2);
+            if ($shortAmount > 0) {
+                $parts[] = $shortAmount . '元';
+            }
+        }
+        if ($minNum > 0) {
+            $shortNum = max(0, $minNum - (float)$bigNum);
+            // 扎数展示取整友好值
+            if ($shortNum > 0) {
+                $parts[] = (fmod($shortNum, 1) == 0 ? (int)$shortNum : round($shortNum, 2)) . '扎';
+            }
+        }
+        if (empty($parts)) {
+            return '';
+        }
+        return '订单还差' . implode('和', $parts) . '可免' . $feeLabel;
+    }
+
     /**
      * 判断当天是否已收过包装类附加费(xhPsMethod unMeet=2)
      */
@@ -608,9 +843,8 @@ class PsMethodClass extends BaseClass
                     || ($unMeet === 2 && self::hasPackFeeDecisionToday($customId, $style));
                 if (!$locked) {
                     $feeLabel = $unMeet === 2 ? '包装费' : '运费';
-                    if ($conditionText !== '') {
-                        $tip = "订单不满{$conditionText},加{$feeLabel}{$unMeetFee}元";
-                    }
+                    // 展示还差多少可免附加费,便于用户凑单
+                    $tip = self::buildUnMeetShortTip($config, $itemTotalAmount, $bigNum, $feeLabel);
                 }
             }
         }

+ 14 - 9
biz/shop/classes/ShopClass.php

@@ -9,6 +9,7 @@ use bizGhs\custom\classes\CustomClass;
 use bizGhs\express\classes\DeliveryAuthTokenClass;
 use bizGhs\order\classes\OrderClass;
 use bizHd\custom\classes\HdClass;
+use bizHd\order\classes\PsMethodClass;
 use common\components\dict;
 use common\components\httpUtil;
 use common\components\imgUtil;
@@ -37,16 +38,20 @@ class ShopClass extends BaseClass
             //禁用跑腿
             $openIntraCity = 2;
         } else {
-            if ($ext->thirdSendFee == 0) {
-                //商家强制要求客户自理、到付和客户自己叫跑腿
+            $mainId = $shop->mainId ?? 0;
+            $hasAuth = DeliveryAuthTokenClass::getByCondition(['mainId' => $mainId], true);
+            // xhPsMethod style=2 自定义完整时,即使未绑定跑腿也可计费(主路径或异常兜底)
+            $psMethod = PsMethodClass::getByCondition(['mainId' => $mainId, 'style' => 2]);
+            $psArr = !empty($psMethod) ? (is_object($psMethod) ? $psMethod->toArray() : $psMethod) : [];
+            $customOk = !empty($psArr) && PsMethodClass::isCustomConfigValid($psArr);
+            $psEnabled = !empty($psArr) && (int)($psArr['status'] ?? 0) === 1;
+            // 有地图、门店坐标,且(已绑定跑腿 或 跑腿方式启用且自定义完整)则可自动算运费
+            if ($hasMap == 1 && !empty($lat) && !empty($long) && !empty($address)
+                && (!empty($hasAuth) || ($psEnabled && $customOk))) {
+                $openIntraCity = 1;
+            } elseif ((int)$ext->thirdSendFee === 0) {
+                // 未开通自动计费能力时仍为自理/到付
                 $openIntraCity = 0;
-            } else {
-                $mainId = $shop->mainId ?? 0;
-                $hasAuth = DeliveryAuthTokenClass::getByCondition(['mainId' => $mainId], true);
-                //有地图功能,并且有绑定跑腿,并且商家有设置门店的经纬度和地址,则支持通过跑腿接口自动计算跑腿费
-                if ($hasMap == 1 && !empty($hasAuth) && !empty($lat) && !empty($long) && !empty($address)) {
-                    $openIntraCity = 1;
-                }
             }
         }
         return [

+ 6 - 0
sql/20260706_redesign.sql

@@ -432,3 +432,9 @@ CREATE TABLE IF NOT EXISTS `xhMainWalletRecharge` (
     UNIQUE KEY `uk_orderSn` (`orderSn`) USING BTREE,
     KEY `idx_mainId_addTime` (`mainId`, `addTime`) USING BTREE
     ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='中央钱包微信充值订单';
+
+-- 配送方式表 ouyang 2026-8-6 16:55:18
+ALTER TABLE xhPsMethod
+    ADD column calcType       TINYINT NOT NULL DEFAULT 0 COMMENT '算运费方式 0 用跑腿 1用自定义' after `changeRate`,
+    ADD COLUMN hsFreeKm decimal(8, 2) DEFAULT '0.00' COMMENT '花束包邮公里数',
+    ADD COLUMN hsPerKmPrice   decimal(8, 2) DEFAULT '0.00' COMMENT '花束超出包邮每公里价格';