3.1、dubbo服务
3.1.1、定义pojo
在my-tanhua-dubbo-interface中创建:
1. @Data 2. @NoArgsConstructor 3. @AllArgsConstructor 4. @Document(collection = "user_location") 5. @CompoundIndex(name = "location_index", def = "{'location': '2dsphere'}") 6. public class UserLocation implements java.io.Serializable{ 7. 8. private static final long serialVersionUID = 4508868382007529970L; 9. 10. @Id 11. private ObjectId id; 12. @Indexed 13. private Long userId; //用户id 14. private GeoJsonPoint location; //x:经度 y:纬度 15. private String address; //位置描述 16. private Long created; //创建时间 17. private Long updated; //更新时间 18. private Long lastUpdated; //上次更新时间 19. }
3.1.2、定义dubbo接口
在my-tanhua-dubbo-interface工程中。
1. package com.tanhua.dubbo.server.api; 2. 3. public interface UserLocationApi { 4. 5. //更新地理位置 6. Boolean updateLocation(Long userId, Double longitude, Double latitude, String address); 7. }
3.1.3、编写实现
1. @DubboService 2. public class UserLocationApiImpl implements UserLocationApi{ 3. 4. @Autowired 5. private MongoTemplate mongoTemplate; 6. 7. //更新地理位置 8. public Boolean updateLocation(Long userId, Double longitude, Double latitude, String address) { 9. try { 10. //1、根据用户id查询位置信息 11. Query query = Query.query(Criteria.where("userId").is(userId)); 12. UserLocation location = mongoTemplate.findOne(query, UserLocation.class); 13. if(location == null) { 14. //2、如果不存在用户位置信息,保存 15. location = new UserLocation(); 16. location.setUserId(userId); 17. location.setAddress(address); 18. location.setCreated(System.currentTimeMillis()); 19. location.setUpdated(System.currentTimeMillis()); 20. location.setLastUpdated(System.currentTimeMillis()); 21. location.setLocation(new GeoJsonPoint(longitude,latitude)); 22. mongoTemplate.save(location); 23. }else { 24. //3、如果存在,更新 25. Update update = Update.update("location", new GeoJsonPoint(longitude, latitude)) 26. .set("updated", System.currentTimeMillis()) 27. .set("lastUpdated", location.getUpdated()); 28. mongoTemplate.updateFirst(query,update,UserLocation.class); 29. } 30. return true; 31. } catch (Exception e) { 32. e.printStackTrace(); 33. return false; 34. } 35. } 36. }
3.1.4、单元测试
地理位置坐标拾取:拾取坐标系统
1. @RunWith(SpringRunner.class) 2. @SpringBootTest(classes = AppServerApplication.class) 3. public class TestUserLocationApi { 4. 5. @DubboReference 6. private UserLocationApi userLocationApi; 7. 8. @Test 9. public void testUpdateUserLocation() { 10. this.userLocationApi.updateLocation(1L, 116.353885,40.065911, "育新地铁站"); 11. this.userLocationApi.updateLocation(2L, 116.352115,40.067441, "北京石油管理干部学院"); 12. this.userLocationApi.updateLocation(3L, 116.336438,40.072505, "回龙观医院"); 13. this.userLocationApi.updateLocation(4L, 116.396797,40.025231, "奥林匹克森林公园"); 14. this.userLocationApi.updateLocation(5L, 116.323849,40.053723, "小米科技园"); 15. this.userLocationApi.updateLocation(6L, 116.403963,39.915119, "天安门"); 16. this.userLocationApi.updateLocation(7L, 116.328103,39.900835, "北京西站"); 17. this.userLocationApi.updateLocation(8L, 116.609564,40.083812, "北京首都国际机场"); 18. this.userLocationApi.updateLocation(9L, 116.459958,39.937193, "德云社(三里屯店)"); 19. this.userLocationApi.updateLocation(10L, 116.333374,40.009645, "清华大学"); 20. this.userLocationApi.updateLocation(41L, 116.316833,39.998877, "北京大学"); 21. this.userLocationApi.updateLocation(42L, 117.180115,39.116464, "天津大学(卫津路校区)"); 22. } 23. }
3.2、APP接口
接口文档:https://mock-java.itheima.net/project/35/interface/api/557
3.2.1、BaiduController
1. @RestController 2. @RequestMapping("/baidu") 3. public class BaiduController { 4. 5. @Autowired 6. private BaiduService baiduService; 7. 8. /** 9. * 更新位置 10. */ 11. @PostMapping("/location") 12. public ResponseEntity updateLocation(@RequestBody Map param) { 13. Double longitude = Double.valueOf(param.get("longitude").toString()); 14. Double latitude = Double.valueOf(param.get("latitude").toString()); 15. String address = param.get("addrStr").toString(); 16. this.baiduService.updateLocation(longitude, latitude,address); 17. return ResponseEntity.ok(null); 18. } 19. }
3.2.2、BaiduService
1. @Service 2. public class BaiduService { 3. 4. @DubboReference 5. private UserLocationApi userLocationApi; 6. 7. //更新地理位置 8. public void updateLocation(Double longitude, Double latitude, String address) { 9. Boolean flag = userLocationApi.updateLocation(UserHolder.getUserId(),longitude,latitude,address); 10. if(!flag) { 11. throw new BusinessException(ErrorResult.error()); 12. } 13. } 14. }
3.3、测试
4、搜附近
在首页中点击“搜附近”可以搜索附近的好友,效果如下:
实现思路:根据当前用户的位置,查询附近范围内的用户。范围是可以设置的。
4.1、dubbo服务
4.1.1、定义接口方法
UserLocationApi
1. /** 2. * 根据位置搜索附近人的所有ID 3. */ 4. List<Long> queryNearUser(Long userId, Double metre);
4.1.2、编写实现
UserLocationApiImpl
1. @Override 2. public List<Long> queryNearUser(Long userId, Double metre) { 3. //1、根据用户id,查询用户的位置信息 4. Query query = Query.query(Criteria.where("userId").is(userId)); 5. UserLocation location = mongoTemplate.findOne(query, UserLocation.class); 6. if(location == null) { 7. return null; 8. } 9. //2、已当前用户位置绘制原点 10. GeoJsonPoint point = location.getLocation(); 11. //3、绘制半径 12. Distance distance = new Distance(metre / 1000, Metrics.KILOMETERS); 13. //4、绘制圆形 14. Circle circle = new Circle(point, distance); 15. //5、查询 16. Query locationQuery = Query.query(Criteria.where("location").withinSphere(circle)); 17. List<UserLocation> list = mongoTemplate.find(locationQuery, UserLocation.class); 18. return CollUtil.getFieldValues(list,"userId",Long.class); 19. }
4.2、APP接口服务
4.2.1、NearUserVo
1. //附近的人vo对象 2. @Data 3. @NoArgsConstructor 4. @AllArgsConstructor 5. public class NearUserVo { 6. 7. private Long userId; 8. private String avatar; 9. private String nickname; 10. 11. public static NearUserVo init(UserInfo userInfo) { 12. NearUserVo vo = new NearUserVo(); 13. vo.setUserId(userInfo.getId()); 14. vo.setAvatar(userInfo.getAvatar()); 15. vo.setNickname(userInfo.getNickname()); 16. return vo; 17. } 18. }
4.2.2、TanHuaController
1. /** 2. * 搜附近 3. */ 4. @GetMapping("/search") 5. public ResponseEntity<List<NearUserVo>> queryNearUser(String gender, 6. @RequestParam(defaultValue = "2000") String distance) { 7. List<NearUserVo> list = this.tanhuaService.queryNearUser(gender, distance); 8. return ResponseEntity.ok(list); 9. }
4.2.3、TanHuaService
1. //搜附近 2. public List<NearUserVo> queryNearUser(String gender, String distance) { 3. //1、调用API查询附近的用户(返回的是附近的人的所有用户id,包含当前用户的id) 4. List<Long> userIds = userLocationApi.queryNearUser(UserHolder.getUserId(),Double.valueOf(distance)); 5. //2、判断集合是否为空 6. if(CollUtil.isEmpty(userIds)) { 7. return new ArrayList<>(); 8. } 9. //3、调用UserInfoApi根据用户id查询用户详情 10. UserInfo userInfo = new UserInfo(); 11. userInfo.setGender(gender); 12. Map<Long, UserInfo> map = userInfoApi.findByIds(userIds, userInfo); 13. //4、构造返回值。 14. List<NearUserVo> vos = new ArrayList<>(); 15. for (Long userId : userIds) { 16. //排除当前用户 17. if(userId == UserHolder.getUserId()) { 18. continue; 19. } 20. UserInfo info = map.get(userId); 21. if(info != null) { 22. NearUserVo vo = NearUserVo.init(info); 23. vos.add(vo); 24. } 25. } 26. return vos; 27. }
4.2.4、测试