查询附近的人

This commit is contained in:
2026-01-07 16:27:35 +08:00
parent 62d85e29ba
commit 7423618df7
8 changed files with 132 additions and 5 deletions

View File

@@ -5,6 +5,7 @@ import com.bao.dating.common.ResultCode;
import com.bao.dating.context.UserContext; import com.bao.dating.context.UserContext;
import com.bao.dating.pojo.dto.UserInfoUpdateDTO; import com.bao.dating.pojo.dto.UserInfoUpdateDTO;
import com.bao.dating.pojo.dto.UserLoginDTO; import com.bao.dating.pojo.dto.UserLoginDTO;
import com.bao.dating.pojo.entity.User;
import com.bao.dating.pojo.vo.UserInfoVO; import com.bao.dating.pojo.vo.UserInfoVO;
import com.bao.dating.pojo.vo.UserLoginVO; import com.bao.dating.pojo.vo.UserLoginVO;
import com.bao.dating.service.UserService; import com.bao.dating.service.UserService;
@@ -12,6 +13,7 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile; import org.springframework.web.multipart.MultipartFile;
import java.util.List;
import java.util.Map; import java.util.Map;
@RestController @RestController
@@ -109,4 +111,38 @@ public class UserController {
return Result.success(ResultCode.SUCCESS, "登录成功", vo); return Result.success(ResultCode.SUCCESS, "登录成功", vo);
} }
@GetMapping("/nearby")
public Result<List<User>> nearby( @RequestParam(defaultValue = "5") double distance){
// 获取当前线程的用户 ID
Long userId = UserContext.getUserId();
if (userId == null) {
return Result.error(ResultCode.SYSTEM_ERROR, "用户未登录");
}
// 通过 UserID 获取当前用户的经纬度信息
UserInfoVO currentUser = userService.getUserInfo(userId);
if (currentUser == null) {
return Result.error(ResultCode.SYSTEM_ERROR, "用户信息获取失败");
}
// 获取当前用户的经纬度
Double latitude = currentUser.getLatitude();
Double longitude = currentUser.getLongitude();
// 检查经纬度是否为空
if (latitude == null || longitude == null) {
return Result.error(ResultCode.SYSTEM_ERROR, "用户经纬度信息未完善");
}
// 这里可以添加默认值,比如如果 latitude 或 longitude 为 null则设置为某个默认值例如 0
latitude = (latitude != null) ? latitude : 0.0;
longitude = (longitude != null) ? longitude : 0.0;
// 查询附近用户
List<User> nearbyUsers = userService.findNearbyUsers(latitude, longitude, distance);
// 返回成功结果
return Result.success(ResultCode.SUCCESS, "获取附近用户成功", nearbyUsers);
}
} }

View File

@@ -5,6 +5,8 @@ import com.bao.dating.pojo.entity.User;
import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param; import org.apache.ibatis.annotations.Param;
import java.util.List;
/** /**
* 用户Mapper * 用户Mapper
* @author KilLze * @author KilLze
@@ -36,4 +38,13 @@ public interface UserMapper {
User selectByPhone(@Param("phone") String phone); User selectByPhone(@Param("phone") String phone);
/**
* 根据经纬度范围查询用户
* @param minLat 最小纬度
* @param maxLat 最大纬度
* @param minLng 最小经度
* @param maxLng 最大经度
* @return 用户列表
*/
List<User> findByLatLngRange( @Param("minLat") double minLat, @Param("maxLat") double maxLat, @Param("minLng") double minLng, @Param("maxLng") double maxLng);
} }

View File

@@ -43,4 +43,8 @@ public class User implements Serializable {
private String userEmail; private String userEmail;
private String userPhone; private String userPhone;
private Double latitude; // 纬度
private Double longitude; // 经度
} }

View File

@@ -24,4 +24,6 @@ public class UserInfoVO implements Serializable {
private String signature; private String signature;
private LocalDateTime updatedAt; private LocalDateTime updatedAt;
private LocalDateTime createdAt; private LocalDateTime createdAt;
private Double latitude;
private Double longitude;
} }

View File

@@ -2,10 +2,13 @@ package com.bao.dating.service;
import com.bao.dating.pojo.dto.UserInfoUpdateDTO; import com.bao.dating.pojo.dto.UserInfoUpdateDTO;
import com.bao.dating.pojo.dto.UserLoginDTO; import com.bao.dating.pojo.dto.UserLoginDTO;
import com.bao.dating.pojo.entity.User;
import com.bao.dating.pojo.vo.UserInfoVO; import com.bao.dating.pojo.vo.UserInfoVO;
import com.bao.dating.pojo.vo.UserLoginVO; import com.bao.dating.pojo.vo.UserLoginVO;
import org.springframework.web.multipart.MultipartFile; import org.springframework.web.multipart.MultipartFile;
import java.util.List;
/** /**
* 用户服务接口 * 用户服务接口
* @author KilLze * @author KilLze
@@ -51,4 +54,13 @@ public interface UserService {
boolean verifyCode(String phone, String code); boolean verifyCode(String phone, String code);
UserLoginVO loginByPhone(String phone); UserLoginVO loginByPhone(String phone);
/**
* 获取指定经纬度范围内的用户
* @param lat 用户纬度
* @param lng 用户经度
* @param radiusKm 半径 km
* @return 用户列表
*/
List<User> findNearbyUsers(double lat,double lng,double radiusKm);
} }

View File

@@ -14,10 +14,7 @@ import com.bao.dating.pojo.entity.User;
import com.bao.dating.pojo.vo.UserInfoVO; import com.bao.dating.pojo.vo.UserInfoVO;
import com.bao.dating.pojo.vo.UserLoginVO; import com.bao.dating.pojo.vo.UserLoginVO;
import com.bao.dating.service.UserService; import com.bao.dating.service.UserService;
import com.bao.dating.util.CodeUtil; import com.bao.dating.util.*;
import com.bao.dating.util.FileUtil;
import com.bao.dating.util.JwtUtil;
import com.bao.dating.util.MD5Util;
import org.springframework.beans.BeanUtils; import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate; import org.springframework.data.redis.core.StringRedisTemplate;
@@ -350,4 +347,33 @@ public class UserServiceImpl implements UserService {
return VO; return VO;
} }
@Override
public List<User> findNearbyUsers(double lat, double lng, double radiusKm) {
//先用经纬度范围筛选(矩形框,提高性能)
double delta = radiusKm / 111.0; // 1° ≈ 111km
double minLat = lat - delta;// 最小纬度
double maxLat = lat + delta;// 最大纬度
double minLng = lng - delta;// 最小经度
double maxLng = lng + delta;// 最大经度
// 打印经纬度范围
System.out.println("Min Latitude: " + minLat + ", Max Latitude: " + maxLat);
System.out.println("Min Longitude: " + minLng + ", Max Longitude: " + maxLng);
List<User> byLatLngRange = userMapper.findByLatLngRange(minLat, maxLat, minLng, maxLng);
//精确计算距离,筛选在半径内的用户
List<User> result = new ArrayList<>();
for (User u:byLatLngRange){
// 检查用户是否有经纬度信息
if (u.getLatitude() != null && u.getLongitude() != null) {
double distance = DistanceUtil.calculate(lat, lng, u.getLatitude(), u.getLongitude());
if (distance <= radiusKm){
result.add(u);
}
}
}
return result;
}
} }

View File

@@ -0,0 +1,29 @@
package com.bao.dating.util;
//Haversine 公式(标准写法)
public class DistanceUtil {
private static final double EARTH_RADIUS = 6371.0; // 地球半径 km
/**
* 计算两点之间距离单位km
*/
public static double calculate(
double lat1, double lon1,
double lat2, double lon2) {
double dLat = Math.toRadians(lat2 - lat1);
double dLon = Math.toRadians(lon2 - lon1);
lat1 = Math.toRadians(lat1);
lat2 = Math.toRadians(lat2);
double a = Math.sin(dLat / 2) * Math.sin(dLat / 2)
+ Math.cos(lat1) * Math.cos(lat2)
* Math.sin(dLon / 2) * Math.sin(dLon / 2);
double c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
return EARTH_RADIUS * c;
}
}

View File

@@ -28,6 +28,8 @@
<result property="signature" column="signature"/> <result property="signature" column="signature"/>
<result property="createdAt" column="created_at"/> <result property="createdAt" column="created_at"/>
<result property="updatedAt" column="updated_at"/> <result property="updatedAt" column="updated_at"/>
<result property="latitude" column="user_latitude"/>
<result property="longitude" column="user_longitude"/>
</resultMap> </resultMap>
<select id="selectByUserId" resultMap="UserResultMap"> <select id="selectByUserId" resultMap="UserResultMap">
SELECT SELECT
@@ -41,7 +43,9 @@
hobbies, hobbies,
signature, signature,
created_at, created_at,
updated_at updated_at,
user_latitude,
user_longitude
FROM dating.user WHERE user_id = #{userId} FROM dating.user WHERE user_id = #{userId}
</select> </select>
@@ -78,4 +82,7 @@
<select id="selectByPhone" resultType="com.bao.dating.pojo.entity.User"> <select id="selectByPhone" resultType="com.bao.dating.pojo.entity.User">
select * from dating.user where user_phone =#{phone} select * from dating.user where user_phone =#{phone}
</select> </select>
<select id="findByLatLngRange" resultType="com.bao.dating.pojo.entity.User">
SELECT * FROM user WHERE user_latitude BETWEEN #{minLat} AND #{maxLat} AND user_longitude BETWEEN #{minLng} AND #{maxLng}
</select>
</mapper> </mapper>