|
|
|
|
@ -140,7 +140,7 @@ class OtherController extends CommonController
|
|
|
|
|
$sortName = $all['sort_name'] ?? 'distance';
|
|
|
|
|
$sortType = $all['sort_type'] ?? 'asc';
|
|
|
|
|
|
|
|
|
|
// 先构建基础查询,不使用SQL计算距离
|
|
|
|
|
// 构建基础查询
|
|
|
|
|
$query = Company::select('*')
|
|
|
|
|
->where(function ($query) use ($all) {
|
|
|
|
|
if (isset($all['company_name'])) {
|
|
|
|
|
@ -151,8 +151,6 @@ class OtherController extends CommonController
|
|
|
|
|
->whereNotNull('company_latitude')
|
|
|
|
|
->where('company_longitude', '!=', '')
|
|
|
|
|
->where('company_latitude', '!=', '')
|
|
|
|
|
->whereRaw('company_longitude REGEXP \'^-?[0-9]+\.?[0-9]*$\'')
|
|
|
|
|
->whereRaw('company_latitude REGEXP \'^-?[0-9]+\.?[0-9]*$\'')
|
|
|
|
|
->whereRaw('CAST(company_longitude AS DECIMAL(10,8)) BETWEEN -180 AND 180')
|
|
|
|
|
->whereRaw('CAST(company_latitude AS DECIMAL(10,8)) BETWEEN -90 AND 90')
|
|
|
|
|
->whereHas('users', function ($query) {
|
|
|
|
|
@ -168,19 +166,7 @@ class OtherController extends CommonController
|
|
|
|
|
}
|
|
|
|
|
]);
|
|
|
|
|
|
|
|
|
|
// 添加SQL调试信息
|
|
|
|
|
\Log::info('SQL Query', [
|
|
|
|
|
'sql' => $query->toSql(),
|
|
|
|
|
'bindings' => $query->getBindings()
|
|
|
|
|
]);
|
|
|
|
|
|
|
|
|
|
// 添加参数调试信息
|
|
|
|
|
\Log::info('Distance Parameters', [
|
|
|
|
|
'latitude' => $latitude,
|
|
|
|
|
'longitude' => $longitude,
|
|
|
|
|
'latitude_type' => gettype($latitude),
|
|
|
|
|
'longitude_type' => gettype($longitude)
|
|
|
|
|
]);
|
|
|
|
|
|
|
|
|
|
// 根据排序字段进行排序
|
|
|
|
|
if ($sortName !== 'distance') {
|
|
|
|
|
@ -189,42 +175,53 @@ class OtherController extends CommonController
|
|
|
|
|
|
|
|
|
|
$result = $query->paginate($pageSize, ['*'], 'page', $page);
|
|
|
|
|
|
|
|
|
|
// 在PHP中计算距离
|
|
|
|
|
// 在PHP中计算距离并优化性能
|
|
|
|
|
$latRad = deg2rad($latitude);
|
|
|
|
|
$lonRad = deg2rad($longitude);
|
|
|
|
|
$cosLat = cos($latRad);
|
|
|
|
|
$sinLat = sin($latRad);
|
|
|
|
|
|
|
|
|
|
foreach ($result->items() as $company) {
|
|
|
|
|
$companyLat = floatval($company->company_latitude);
|
|
|
|
|
$companyLon = floatval($company->company_longitude);
|
|
|
|
|
|
|
|
|
|
// 使用Haversine公式计算距离
|
|
|
|
|
$distance = 6371 * acos(
|
|
|
|
|
cos(deg2rad($latitude)) * cos(deg2rad($companyLat)) *
|
|
|
|
|
cos(deg2rad($companyLon) - deg2rad($longitude)) +
|
|
|
|
|
sin(deg2rad($latitude)) * sin(deg2rad($companyLat))
|
|
|
|
|
);
|
|
|
|
|
// 验证经纬度有效性
|
|
|
|
|
if ($companyLat < -90 || $companyLat > 90 || $companyLon < -180 || $companyLon > 180) {
|
|
|
|
|
$company->distance = null;
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 预计算三角函数值以提高性能
|
|
|
|
|
$companyLatRad = deg2rad($companyLat);
|
|
|
|
|
$companyLonRad = deg2rad($companyLon);
|
|
|
|
|
|
|
|
|
|
$acosInput = $cosLat * cos($companyLatRad) * cos($companyLonRad - $lonRad) +
|
|
|
|
|
$sinLat * sin($companyLatRad);
|
|
|
|
|
|
|
|
|
|
$company->distance = $distance;
|
|
|
|
|
// 确保acos输入值在有效范围内
|
|
|
|
|
$acosInput = max(-1, min(1, $acosInput));
|
|
|
|
|
|
|
|
|
|
$distance = 6371 * acos($acosInput);
|
|
|
|
|
$company->distance = round($distance, 2); // 保留两位小数
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 如果按距离排序,在PHP中排序
|
|
|
|
|
if ($sortName === 'distance') {
|
|
|
|
|
$items = $result->items();
|
|
|
|
|
usort($items, function ($a, $b) {
|
|
|
|
|
// 处理无效距离的情况
|
|
|
|
|
if ($a->distance === null && $b->distance === null)
|
|
|
|
|
return 0;
|
|
|
|
|
if ($a->distance === null)
|
|
|
|
|
return 1;
|
|
|
|
|
if ($b->distance === null)
|
|
|
|
|
return -1;
|
|
|
|
|
return $a->distance <=> $b->distance;
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
// 重新设置分页数据
|
|
|
|
|
$result->setCollection(collect($items));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 添加调试信息
|
|
|
|
|
\Log::info('Distance calculation debug', [
|
|
|
|
|
'input_lat' => $latitude,
|
|
|
|
|
'input_lon' => $longitude,
|
|
|
|
|
'target_lat' => '31.326810',
|
|
|
|
|
'target_lon' => '120.421618',
|
|
|
|
|
'expected_distance' => 13.22,
|
|
|
|
|
'actual_distance' => $result->first() ? $result->first()->distance : 'N/A',
|
|
|
|
|
'calculation_method' => 'PHP Haversine'
|
|
|
|
|
]);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return $this->success($result);
|
|
|
|
|
}
|
|
|
|
|
|