查询附近的人
This commit is contained in:
@@ -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);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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; // 经度
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
29
src/main/java/com/bao/dating/util/DistanceUtil.java
Normal file
29
src/main/java/com/bao/dating/util/DistanceUtil.java
Normal 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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>
|
||||||
Reference in New Issue
Block a user