diff --git a/src/main/java/com/bao/dating/controller/UserController.java b/src/main/java/com/bao/dating/controller/UserController.java index c4553cb..4cb58e9 100644 --- a/src/main/java/com/bao/dating/controller/UserController.java +++ b/src/main/java/com/bao/dating/controller/UserController.java @@ -5,6 +5,7 @@ import com.bao.dating.common.ResultCode; import com.bao.dating.context.UserContext; import com.bao.dating.pojo.dto.UserInfoUpdateDTO; 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.UserLoginVO; 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.multipart.MultipartFile; +import java.util.List; import java.util.Map; @RestController @@ -109,4 +111,38 @@ public class UserController { return Result.success(ResultCode.SUCCESS, "登录成功", vo); } + @GetMapping("/nearby") + public Result> 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 nearbyUsers = userService.findNearbyUsers(latitude, longitude, distance); + + // 返回成功结果 + return Result.success(ResultCode.SUCCESS, "获取附近用户成功", nearbyUsers); + } + } diff --git a/src/main/java/com/bao/dating/mapper/UserMapper.java b/src/main/java/com/bao/dating/mapper/UserMapper.java index dd43f96..0d9b9b2 100644 --- a/src/main/java/com/bao/dating/mapper/UserMapper.java +++ b/src/main/java/com/bao/dating/mapper/UserMapper.java @@ -5,6 +5,8 @@ import com.bao.dating.pojo.entity.User; import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.Param; +import java.util.List; + /** * 用户Mapper * @author KilLze @@ -36,4 +38,13 @@ public interface UserMapper { User selectByPhone(@Param("phone") String phone); + /** + * 根据经纬度范围查询用户 + * @param minLat 最小纬度 + * @param maxLat 最大纬度 + * @param minLng 最小经度 + * @param maxLng 最大经度 + * @return 用户列表 + */ + List findByLatLngRange( @Param("minLat") double minLat, @Param("maxLat") double maxLat, @Param("minLng") double minLng, @Param("maxLng") double maxLng); } diff --git a/src/main/java/com/bao/dating/pojo/entity/User.java b/src/main/java/com/bao/dating/pojo/entity/User.java index e668af5..9bf9641 100644 --- a/src/main/java/com/bao/dating/pojo/entity/User.java +++ b/src/main/java/com/bao/dating/pojo/entity/User.java @@ -43,4 +43,8 @@ public class User implements Serializable { private String userEmail; private String userPhone; + + private Double latitude; // 纬度 + + private Double longitude; // 经度 } diff --git a/src/main/java/com/bao/dating/pojo/vo/UserInfoVO.java b/src/main/java/com/bao/dating/pojo/vo/UserInfoVO.java index c5a81fa..35c5c90 100644 --- a/src/main/java/com/bao/dating/pojo/vo/UserInfoVO.java +++ b/src/main/java/com/bao/dating/pojo/vo/UserInfoVO.java @@ -24,4 +24,6 @@ public class UserInfoVO implements Serializable { private String signature; private LocalDateTime updatedAt; private LocalDateTime createdAt; + private Double latitude; + private Double longitude; } diff --git a/src/main/java/com/bao/dating/service/UserService.java b/src/main/java/com/bao/dating/service/UserService.java index d8c84e4..45c8ece 100644 --- a/src/main/java/com/bao/dating/service/UserService.java +++ b/src/main/java/com/bao/dating/service/UserService.java @@ -2,10 +2,13 @@ package com.bao.dating.service; import com.bao.dating.pojo.dto.UserInfoUpdateDTO; 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.UserLoginVO; import org.springframework.web.multipart.MultipartFile; +import java.util.List; + /** * 用户服务接口 * @author KilLze @@ -51,4 +54,13 @@ public interface UserService { boolean verifyCode(String phone, String code); UserLoginVO loginByPhone(String phone); + + /** + * 获取指定经纬度范围内的用户 + * @param lat 用户纬度 + * @param lng 用户经度 + * @param radiusKm 半径 km + * @return 用户列表 + */ + List findNearbyUsers(double lat,double lng,double radiusKm); } diff --git a/src/main/java/com/bao/dating/service/impl/UserServiceImpl.java b/src/main/java/com/bao/dating/service/impl/UserServiceImpl.java index 9a6c33a..6c4f0d7 100644 --- a/src/main/java/com/bao/dating/service/impl/UserServiceImpl.java +++ b/src/main/java/com/bao/dating/service/impl/UserServiceImpl.java @@ -14,10 +14,7 @@ import com.bao.dating.pojo.entity.User; import com.bao.dating.pojo.vo.UserInfoVO; import com.bao.dating.pojo.vo.UserLoginVO; import com.bao.dating.service.UserService; -import com.bao.dating.util.CodeUtil; -import com.bao.dating.util.FileUtil; -import com.bao.dating.util.JwtUtil; -import com.bao.dating.util.MD5Util; +import com.bao.dating.util.*; import org.springframework.beans.BeanUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.redis.core.StringRedisTemplate; @@ -350,4 +347,33 @@ public class UserServiceImpl implements UserService { return VO; } + + @Override + public List 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 byLatLngRange = userMapper.findByLatLngRange(minLat, maxLat, minLng, maxLng); + + //精确计算距离,筛选在半径内的用户 + List 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; + } } diff --git a/src/main/java/com/bao/dating/util/DistanceUtil.java b/src/main/java/com/bao/dating/util/DistanceUtil.java new file mode 100644 index 0000000..f994f31 --- /dev/null +++ b/src/main/java/com/bao/dating/util/DistanceUtil.java @@ -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; + } +} diff --git a/src/main/resources/com/bao/dating/mapper/UserMapper.xml b/src/main/resources/com/bao/dating/mapper/UserMapper.xml index 983e37d..f49dfb4 100644 --- a/src/main/resources/com/bao/dating/mapper/UserMapper.xml +++ b/src/main/resources/com/bao/dating/mapper/UserMapper.xml @@ -28,6 +28,8 @@ + + @@ -78,4 +82,7 @@ + \ No newline at end of file