diff --git a/src/main/java/com/bao/dating/controller/UserController.java b/src/main/java/com/bao/dating/controller/UserController.java index 7379311..8ef7bd6 100644 --- a/src/main/java/com/bao/dating/controller/UserController.java +++ b/src/main/java/com/bao/dating/controller/UserController.java @@ -6,6 +6,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; @@ -14,6 +15,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 javax.servlet.http.HttpServletRequest; import java.util.Map; @@ -109,4 +111,57 @@ public class UserController { return ok ? Result.success(ResultCode.SUCCESS, "登录成功") : Result.error(ResultCode.SYSTEM_ERROR, "登录失败"); } + /** + * 登录 + * @param body 登录参数 + */ + @PostMapping("/loginPhone") + public Result loginPhone(@RequestBody Map body) { + String phone = body.get("phone"); + String code = body.get("code"); + + //校验验证码 + boolean verify = userService.verifyCode(phone, code); + if (!verify){ + return Result.error(ResultCode.SYSTEM_ERROR, "验证码错误或已过期"); + } + //登录 + UserLoginVO vo = userService.loginByPhone(phone); + 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 a49abc9..0d9b9b2 100644 --- a/src/main/java/com/bao/dating/mapper/UserMapper.java +++ b/src/main/java/com/bao/dating/mapper/UserMapper.java @@ -36,6 +36,8 @@ public interface UserMapper { */ void updateUserInfoByUserId(UserInfoUpdateDTO userInfoUpdateDTO); + User selectByPhone(@Param("phone") String phone); + /** * 根据经纬度范围查询用户 * @param minLat 最小纬度 @@ -44,5 +46,5 @@ public interface UserMapper { * @param maxLng 最大经度 * @return 用户列表 */ - List findByLatLngRange(@Param("minLat") double minLat, @Param("maxLat") double maxLat, @Param("minLng") double minLng, @Param("maxLng") double maxLng); + 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/service/UserService.java b/src/main/java/com/bao/dating/service/UserService.java index a1efe62..bb12eae 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 @@ -56,4 +59,15 @@ public interface UserService { void sendSmsCode(String phone); 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 196c9b5..3f89fb6 100644 --- a/src/main/java/com/bao/dating/service/impl/UserServiceImpl.java +++ b/src/main/java/com/bao/dating/service/impl/UserServiceImpl.java @@ -15,6 +15,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.*; import com.bao.dating.util.CodeUtil; import com.bao.dating.util.FileUtil; import com.bao.dating.util.JwtUtil; @@ -331,6 +332,7 @@ public class UserServiceImpl implements UserService { if (Boolean.TRUE.equals(exists)){ throw new RuntimeException("请勿频繁发送验证码"); } + // 生成验证码 String code = CodeUtil.generateCode(); // 发送短信 @@ -359,4 +361,46 @@ public class UserServiceImpl implements UserService { return true; } + @Override + public UserLoginVO loginByPhone(String phone) { + //根据手机号查询用户 + User user = userMapper.selectByPhone(phone); + //创建token + String token = JwtUtil.generateToken(user.getUserId().toString()); + //封装返回结果 + UserLoginVO VO = new UserLoginVO(); + VO.setUserId(user.getUserId()); + VO.setToken(token); + 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 index 4db45ab..f994f31 100644 --- a/src/main/java/com/bao/dating/util/DistanceUtil.java +++ b/src/main/java/com/bao/dating/util/DistanceUtil.java @@ -1,5 +1,7 @@ package com.bao.dating.util; +//Haversine 公式(标准写法) + public class DistanceUtil { private static final double EARTH_RADIUS = 6371.0; // 地球半径 km diff --git a/src/main/resources/com/bao/dating/mapper/UserMapper.xml b/src/main/resources/com/bao/dating/mapper/UserMapper.xml index fcab72b..f49dfb4 100644 --- a/src/main/resources/com/bao/dating/mapper/UserMapper.xml +++ b/src/main/resources/com/bao/dating/mapper/UserMapper.xml @@ -43,8 +43,10 @@ hobbies, signature, created_at, - updated_at - FROM user WHERE user_id = #{userId} + updated_at, + user_latitude, + user_longitude + FROM dating.user WHERE user_id = #{userId}