Kaynağa Gözat

优化 buildNearbyGhsRelations(),并过滤非法坐标系

shizhongqi 4 ay önce
ebeveyn
işleme
ad160579bf
1 değiştirilmiş dosya ile 72 ekleme ve 23 silme
  1. 72 23
      biz/ghs/classes/GhsClass.php

+ 72 - 23
biz/ghs/classes/GhsClass.php

@@ -333,6 +333,11 @@ class GhsClass extends BaseClass
     public static function buildNearbyGhsRelations($shopId, $pfShopId, $toLat, $toLnt)
     {
         if (empty($toLat) || empty($toLnt)) {
+            noticeUtil::push("批发关系建立失败:目标门店坐标为空,shopId={$shopId}");
+            return false;
+        }
+        if (!self::isValidAmapCoordinate($toLat, $toLnt)) {
+            noticeUtil::push("批发关系建立失败:目标门店坐标非法,shopId={$shopId},lat={$toLat},lng={$toLnt}");
             return false;
         }
 
@@ -350,50 +355,71 @@ class GhsClass extends BaseClass
             }
         }
 
-        $origins = [];
-        $validNearbyShops = [];
+        $nearbyShopOriginPairs = [];
         foreach ($nearbyShops as $nearbyShop) {
             if ($nearbyShop['id'] == $pfShopId) {
                 continue;
             }
-            if (!empty($nearbyShop['lat']) && !empty($nearbyShop['long'])) {
-                $origins[] = [
-                    'lat' => $nearbyShop['lat'],
-                    'lng' => $nearbyShop['long'],
+            if (!empty($nearbyShop['lat']) && !empty($nearbyShop['long']) && self::isValidAmapCoordinate($nearbyShop['lat'], $nearbyShop['long'])) {
+                $nearbyShopOriginPairs[] = [
+                    'shop' => $nearbyShop,
+                    'origin' => [
+                        'lat' => $nearbyShop['lat'],
+                        'lng' => $nearbyShop['long'],
+                    ],
                 ];
-                $validNearbyShops[] = $nearbyShop;
             } else {
                 // 发送钉钉通知
-                noticeUtil::push('批发商:' . $nearbyShop['merchantName'] . '(' . $nearbyShop['id'] . ')未设置经纬度');
+                noticeUtil::push('批发商:' . $nearbyShop['merchantName'] . '(' . $nearbyShop['id'] . ')经纬度无效,lat=' . ($nearbyShop['lat'] ?? '') . ',lng=' . ($nearbyShop['long'] ?? ''));
             }
         }
 
-        if (empty($origins)) {
+        if (empty($nearbyShopOriginPairs)) {
             return false;
         }
 
         // 高德批量测距接口最多支持 100 个起点,需分批处理
-        $chunkOrigins = array_chunk($origins, 100);
-        $allDistances = [];
+        $chunkPairs = array_chunk($nearbyShopOriginPairs, 100);
+        $distanceShopPairs = [];
+
+        foreach ($chunkPairs as $chunk) {
+            $chunkOrigins = array_column($chunk, 'origin');
+            $distances = \common\components\mapUtil::calculateBatchDistance($chunkOrigins, $toLnt, $toLat);
+
+            if (empty($distances)) {
+                noticeUtil::push("批发关系建立失败:高德批量测距返回空结果,shopId={$shopId}");
+                continue;
+            }
 
-        foreach ($chunkOrigins as $chunk) {
-            $distances = \common\components\mapUtil::calculateBatchDistance($chunk, $toLnt, $toLat);
-            $allDistances = array_merge($allDistances, $distances);
+            foreach ($chunk as $index => $pair) {
+                if (!isset($distances[$index]) || !is_numeric($distances[$index])) {
+                    continue;
+                }
+                $distanceShopPairs[] = [
+                    'distance' => (float)$distances[$index],
+                    'shop' => $pair['shop'],
+                ];
+            }
+        }
+
+        if (empty($distanceShopPairs)) {
+            noticeUtil::push("批发关系建立失败:没有可用距离数据,shopId={$shopId}");
+            return false;
         }
-        noticeUtil::push("执行到这里。。。。1");
-        // 建立关系前要先执照距离从小到大排序
-        // 注意:array_multisort($allDistances, SORT_ASC, $validNearbyShops) 能保证 $allDistances 与 $validNearbyShops 保持索引同步,
-        // 即排序后 $validNearbyShops[$i] 就是排序后第 $i 小距离的门店信息,$allDistances[$i] 为其对应距离。
-        array_multisort($allDistances, SORT_ASC, $validNearbyShops);
+
+        // 建立关系前距离从小到大排序
+        usort($distanceShopPairs, function ($a, $b) {
+            return $a['distance'] <=> $b['distance'];
+        });
 
         // 取前6个
-        $allDistances = array_slice($allDistances, 0, 6);
-        $validNearbyShops = array_slice($validNearbyShops, 0, 6);
+        $distanceShopPairs = array_slice($distanceShopPairs, 0, 6);
 
         // 建立关系并保存距离
-        foreach ($validNearbyShops as $index => $nearbyShop) {
+        foreach ($distanceShopPairs as $pair) {
+            $nearbyShop = $pair['shop'];
             $ghsShopId = $nearbyShop['id'];
-            $distance = $allDistances[$index] ?? 0;
+            $distance = $pair['distance'] ?? 0;
             // 距离大于60公里不建立关系
             if ($distance > 60 * 1000) {
                 noticeUtil::push("执行到这里,没有建立关系。。。。" . $distance . ' ' . $ghsShopId . ' ' . $shopId);
@@ -411,4 +437,27 @@ class GhsClass extends BaseClass
         noticeUtil::push("执行到这里。。。。2");
         return true;
     }
+
+    /**
+     * 高德坐标有效性校验(仅保留中国大陆范围坐标)
+     * @param mixed $lat
+     * @param mixed $lng
+     * @return bool
+     */
+    private static function isValidAmapCoordinate($lat, $lng)
+    {
+        if (!is_numeric($lat) || !is_numeric($lng)) {
+            return false;
+        }
+        $lat = (float)$lat;
+        $lng = (float)$lng;
+
+        if ($lng < 72.004 || $lng > 137.8347) {
+            return false;
+        }
+        if ($lat < 0.8293 || $lat > 55.8271) {
+            return false;
+        }
+        return true;
+    }
 }