|
@@ -5,6 +5,7 @@ namespace App\Services\Client;
|
|
|
use App\Models\CoachUser;
|
|
|
use Illuminate\Support\Facades\Auth;
|
|
|
use Illuminate\Support\Facades\Redis;
|
|
|
+use Illuminate\Support\Facades\Log;
|
|
|
|
|
|
class CoachService
|
|
|
{
|
|
@@ -18,7 +19,17 @@ class CoachService
|
|
|
// 获取当前用户
|
|
|
$user = Auth::user();
|
|
|
|
|
|
+ Log::info('Current user and coordinates:', [
|
|
|
+ 'user' => $user ? $user->id : null,
|
|
|
+ 'latitude' => $latitude,
|
|
|
+ 'longitude' => $longitude,
|
|
|
+ ]);
|
|
|
+
|
|
|
// 检查用户状态
|
|
|
+ if (!$user) {
|
|
|
+ throw new \Exception('用户未登录');
|
|
|
+ }
|
|
|
+
|
|
|
if ($user->state !== 'enable') {
|
|
|
throw new \Exception('用户状态异常');
|
|
|
}
|
|
@@ -68,10 +79,34 @@ class CoachService
|
|
|
*/
|
|
|
public function getCoachDetail($coachId, $latitude, $longitude)
|
|
|
{
|
|
|
+ // 检查Redis连接
|
|
|
+ try {
|
|
|
+ $pingResult = Redis::connection()->ping();
|
|
|
+ Log::info('Redis connection test:', ['ping_result' => $pingResult]);
|
|
|
+ } catch (\Exception $e) {
|
|
|
+ Log::error('Redis connection error:', ['error' => $e->getMessage()]);
|
|
|
+ throw new \Exception('Redis连接失败:' . $e->getMessage());
|
|
|
+ }
|
|
|
+
|
|
|
+ // 检查Redis中的所有位置数据
|
|
|
+ $allLocations = Redis::zrange('coach_locations', 0, -1, 'WITHSCORES');
|
|
|
+ Log::info('All locations in Redis:', ['locations' => $allLocations]);
|
|
|
+
|
|
|
// 获取当前用户
|
|
|
$user = Auth::user();
|
|
|
|
|
|
+ Log::info('Current user and coordinates:', [
|
|
|
+ 'user' => $user ? $user->id : null,
|
|
|
+ 'latitude' => $latitude,
|
|
|
+ 'longitude' => $longitude,
|
|
|
+ 'coach_id' => $coachId
|
|
|
+ ]);
|
|
|
+
|
|
|
// 检查用户状态
|
|
|
+ if (!$user) {
|
|
|
+ throw new \Exception('用户未登录');
|
|
|
+ }
|
|
|
+
|
|
|
if ($user->state !== 'enable') {
|
|
|
throw new \Exception('用户状态异常');
|
|
|
}
|
|
@@ -97,32 +132,116 @@ class CoachService
|
|
|
$homeLocation = Redis::geopos('coach_locations', $coachId.'_home');
|
|
|
$workLocation = Redis::geopos('coach_locations', $coachId.'_work');
|
|
|
|
|
|
- // 计算距离
|
|
|
- $distanceHome = $homeLocation && ! empty($homeLocation[0]) ? $this->calculateDistance($latitude, $longitude, $homeLocation[0][1], $homeLocation[0][0]) : null;
|
|
|
+ Log::info('Coach locations from Redis:', [
|
|
|
+ 'coach_id' => $coachId,
|
|
|
+ 'home_location' => $homeLocation,
|
|
|
+ 'work_location' => $workLocation,
|
|
|
+ 'home_key' => $coachId.'_home',
|
|
|
+ 'work_key' => $coachId.'_work'
|
|
|
+ ]);
|
|
|
+
|
|
|
+ // 检查输入的经纬度是否有效
|
|
|
+ if (!is_numeric($latitude) || !is_numeric($longitude)) {
|
|
|
+ Log::error('Invalid coordinates:', ['latitude' => $latitude, 'longitude' => $longitude]);
|
|
|
+ throw new \Exception('无效的经纬度坐标');
|
|
|
+ }
|
|
|
|
|
|
- $distanceWork = $workLocation && ! empty($workLocation[0]) ? $this->calculateDistance($latitude, $longitude, $workLocation[0][1], $workLocation[0][0]) : null;
|
|
|
+ // 临时存储用户当前位置用于计算距离
|
|
|
+ $tempKey = 'user_temp_'.$user->id;
|
|
|
+ $addResult = Redis::geoadd('coach_locations', $longitude, $latitude, $tempKey);
|
|
|
+
|
|
|
+ Log::info('User location added to Redis:', [
|
|
|
+ 'temp_key' => $tempKey,
|
|
|
+ 'latitude' => $latitude,
|
|
|
+ 'longitude' => $longitude,
|
|
|
+ 'add_result' => $addResult
|
|
|
+ ]);
|
|
|
+
|
|
|
+ // 计算距离(单位:km)
|
|
|
+ $distanceHome = null;
|
|
|
+ $distanceWork = null;
|
|
|
+
|
|
|
+ if ($homeLocation && !empty($homeLocation[0])) {
|
|
|
+ $distanceHome = Redis::geodist('coach_locations', $tempKey, $coachId.'_home', 'km');
|
|
|
+ Log::info('Home distance calculation:', [
|
|
|
+ 'from' => $tempKey,
|
|
|
+ 'to' => $coachId.'_home',
|
|
|
+ 'distance' => $distanceHome,
|
|
|
+ 'home_location' => $homeLocation[0]
|
|
|
+ ]);
|
|
|
+ }
|
|
|
+
|
|
|
+ if ($workLocation && !empty($workLocation[0])) {
|
|
|
+ $distanceWork = Redis::geodist('coach_locations', $tempKey, $coachId.'_work', 'km');
|
|
|
+ Log::info('Work distance calculation:', [
|
|
|
+ 'from' => $tempKey,
|
|
|
+ 'to' => $coachId.'_work',
|
|
|
+ 'distance' => $distanceWork,
|
|
|
+ 'work_location' => $workLocation[0]
|
|
|
+ ]);
|
|
|
+ }
|
|
|
+
|
|
|
+ Log::info('Distance calculation results:', [
|
|
|
+ 'distance_home' => $distanceHome,
|
|
|
+ 'distance_work' => $distanceWork,
|
|
|
+ 'temp_key' => $tempKey,
|
|
|
+ 'coach_id' => $coachId
|
|
|
+ ]);
|
|
|
+
|
|
|
+ // 删除临时位置点
|
|
|
+ Redis::zrem('coach_locations', $tempKey);
|
|
|
|
|
|
// 选择最近的距离
|
|
|
- $coach->distance = round(min(array_filter([$distanceHome, $distanceWork])), 2);
|
|
|
+ $distances = array_filter([$distanceHome, $distanceWork]);
|
|
|
+ $coach->distance = !empty($distances) ? round(min($distances), 2) : null;
|
|
|
|
|
|
return $coach;
|
|
|
}
|
|
|
|
|
|
- // 添加一个计算距离的方法
|
|
|
- private function calculateDistance($lat1, $lon1, $lat2, $lon2)
|
|
|
+ /**
|
|
|
+ * 设置技师位置信息
|
|
|
+ *
|
|
|
+ * @param int $coachId 技师ID
|
|
|
+ * @param float $latitude 纬度
|
|
|
+ * @param float $longitude 经度
|
|
|
+ * @param string $type 位置类型 (home|work)
|
|
|
+ * @return bool
|
|
|
+ * @throws \Exception
|
|
|
+ */
|
|
|
+ public function setCoachLocation($coachId, $latitude, $longitude, $type = 'home')
|
|
|
{
|
|
|
- // 实现距离计算逻辑
|
|
|
- $earthRadius = 6371; // 地球半径,单位为公里
|
|
|
-
|
|
|
- $dLat = deg2rad($lat2 - $lat1);
|
|
|
- $dLon = deg2rad($lon2 - $lon1);
|
|
|
-
|
|
|
- $a = sin($dLat / 2) * sin($dLat / 2) +
|
|
|
- cos(deg2rad($lat1)) * cos(deg2rad($lat2)) *
|
|
|
- sin($dLon / 2) * sin($dLon / 2);
|
|
|
+ if (!is_numeric($latitude) || !is_numeric($longitude)) {
|
|
|
+ Log::error('Invalid coordinates in setCoachLocation:', [
|
|
|
+ 'coach_id' => $coachId,
|
|
|
+ 'latitude' => $latitude,
|
|
|
+ 'longitude' => $longitude
|
|
|
+ ]);
|
|
|
+ throw new \Exception('无效的经纬度坐标');
|
|
|
+ }
|
|
|
|
|
|
- $c = 2 * atan2(sqrt($a), sqrt(1 - $a));
|
|
|
+ if (!in_array($type, ['home', 'work'])) {
|
|
|
+ throw new \Exception('无效的位置类型,必须是 home 或 work');
|
|
|
+ }
|
|
|
|
|
|
- return $earthRadius * $c;
|
|
|
+ $key = $coachId . '_' . $type;
|
|
|
+ $result = Redis::geoadd('coach_locations', $longitude, $latitude, $key);
|
|
|
+
|
|
|
+ Log::info('Coach location set:', [
|
|
|
+ 'coach_id' => $coachId,
|
|
|
+ 'type' => $type,
|
|
|
+ 'key' => $key,
|
|
|
+ 'latitude' => $latitude,
|
|
|
+ 'longitude' => $longitude,
|
|
|
+ 'result' => $result
|
|
|
+ ]);
|
|
|
+
|
|
|
+ // 验证数据是否成功写入
|
|
|
+ $location = Redis::geopos('coach_locations', $key);
|
|
|
+ Log::info('Verify location after set:', [
|
|
|
+ 'key' => $key,
|
|
|
+ 'location' => $location
|
|
|
+ ]);
|
|
|
+
|
|
|
+ return $result;
|
|
|
}
|
|
|
}
|