探花交友_第8章_搜附近(新版)

news2024/12/25 12:40:22

探花交友_第8章_搜附近(新版)

文章目录

  • 探花交友_第8章_搜附近(新版)
    • 1.1 需求分析
      • 需求说明
      • 数据库表
    • 1.2 探花推荐列表查询
      • 接口文档
      • tanhua-model
      • tanhua-app-server
        • **TanHuaController**
        • TanHuaService
        • 配置文件
      • tanhua-dubbo-interface
      • tanhua-dubbo-mongo
    • 1.3 左滑右滑
      • 接口文档
      • tanhua-app-server
        • TanHuaController
        • TanHuaService
      • tanhua-dubbo-interface
        • UserLikeApi
      • tanhua-dubbo-mongo
        • UserLikeApi
  • 2. MongoDB地理位置检索
    • 2.1 地理位置索引
      • Point
      • LineString
      • Polygon
    • 2.2 案例
        • 查询附近
        • 查询并获取距离
  • 3. 上报地理位置
    • 3.1 需求分析
      • 数据库表
      • 接口说明
    • 3.2. 代码实现
      • tanhua-model
      • tanhua-app-server
        • BaiduController
        • BaiduService
      • tanhua-dubbo-interface
      • tanhua-dubbo-mongo
      • 运行测试
      • 数据准备
  • 4. 搜附近
    • 4.1 需求分析
      • 需求分析
      • 接口说明
    • 4.2 代码实现
      • tanhua-model
      • tanhua-app-server
        • TanHuaController
        • TanHuaService
      • tanhua-dubbo-interface
      • tanhua-dubbo-mongo
      • 访问测试
      • 访问测试

1.1 需求分析

需求说明

探花功能是将推荐的好友随机的通过卡片的形式展现出来

用户可以选择左滑、右滑操作

  • 左滑:“不喜欢”
  • 右滑:“喜欢”
  • 如果双方互相喜欢,那么就会成为好友
  • 如果已经喜欢或不喜欢的用户在列表中不再显示。

在这里插入图片描述

数据库表

  • 用户的喜欢与不喜欢列表需要保存在redis中

  • 为了防止redis中的数据丢失,同时需要将数据保存到mongodb进行持久化保存。存储结构如下 :

#userLike
{
 "_id": ObjectId("60c05cd88ae133130eb708ab"),
 "userId": NumberLong("106"),
 "likeUserId": NumberLong("2"),
 "isLike": true,
 "created": NumberLong("1623219416873"),
 "updated": NumberLong("1623219416873"),
 "_class": "com.tanhua.model.mongo.UserLike"
}

1.2 探花推荐列表查询

接口文档

接口地址:http://192.168.136.160:3000/project/19/interface/api/115

在这里插入图片描述

tanhua-model

tanhua-model项目中定义实体类UserLike

package com.tanhua.dubbo.server.pojo;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.bson.types.ObjectId;
import org.springframework.data.mongodb.core.index.Indexed;
import org.springframework.data.mongodb.core.mapping.Document;

@Data
@NoArgsConstructor
@AllArgsConstructor
@Document(collection = "user_like")
public class UserLike implements java.io.Serializable {

    private static final long serialVersionUID = 6739966698394686523L;

    private ObjectId id;
    @Indexed
    private Long userId; //用户id,自己
    @Indexed
    private Long likeUserId; //喜欢的用户id,对方
    private Boolean isLike; // 是否喜欢
    private Long created; //创建时间
    private Long updated; // 更新时间

}

tanhua-app-server

TanHuaController

``tanhua-app-server</b></font>项目中的TanHuaController`中定义查询探花列表的方法

/**
* 探花-推荐用户列表
*/
@GetMapping("/cards")
public ResponseEntity queryCardsList() {
    List<TodayBest> list = this.tanhuaService.queryCardsList();
    return ResponseEntity.ok(list);
}

TanHuaService

查询探花推荐好友列表, 如果推荐用户不存在, 则返回默认推荐用户 , 默认推荐用户可以在配置文件中指定

``tanhua-app-server</b></font>项目的TanhuaService`编写业务层代码 , 调用dubbo完成推荐列表查询

//指定默认数据
@Value("${tanhua.default.recommend.users}")
private String recommendUser;

//探花-推荐用户列表
public List<TodayBest> queryCardsList() {
    //1、调用推荐API查询数据列表(排除喜欢/不喜欢的用户,数量限制)
    List<RecommendUser> users = recommendUserApi.queryCardsList(UserHolder.getUserId(),10);
    //2、判断数据是否存在,如果不存在,构造默认数据 1,2,3
    if(CollUtil.isEmpty(users)) {
        users = new ArrayList<>();
        String[] userIdS = recommendUser.split(",");
        for (String userId : userIdS) {
            RecommendUser recommendUser = new RecommendUser();
            recommendUser.setUserId(Convert.toLong(userId));
            recommendUser.setToUserId(UserHolder.getUserId());
            recommendUser.setScore(RandomUtil.randomDouble(60, 90));
            users.add(recommendUser);
        }
    }
    //3、构造VO
    List<Long> ids = CollUtil.getFieldValues(users, "userId", Long.class);
    Map<Long, UserInfo> infoMap = userInfoApi.findByIds(ids, null);

    List<TodayBest> vos = new ArrayList<>();
    for (RecommendUser user : users) {
        UserInfo userInfo = infoMap.get(user.getUserId());
        if(userInfo != null) {
            TodayBest vo = TodayBest.init(userInfo, user);
            vos.add(vo);
        }
    }
    return vos;
}

配置文件

``tanhua-app-server`项目的application.yml配置文件中 , 添加默认推荐列表配置

#默认推荐列表
tanhua:
  default:
    recommend:
      users: 2,3,8,10,18,20,24,29,27,32,36,37,56,64,75,88

tanhua-dubbo-interface

tanhua-dubbo-interface项目中定义查询探花列表的接口方法

RecommendUserApi

/**
 * 查询探花列表,查询时需要排除喜欢和不喜欢的用户
 */
List<RecommendUser> queryCardsList(Long userId, int count);

tanhua-dubbo-mongo

``tanhua-dubbo-mongo`项目中实现查询探花列表的接口方法

注意 :

  1. 需要排除掉之前喜欢过的用户
  2. 需要排除掉之前不喜欢过的用户
  3. 随机获取数据返回

RecommendUserApiImpl

    /**
     * 1、排除喜欢,不喜欢的用户
     * 2、随机展示
     * 3、指定数量
     */
public List<RecommendUser> queryCardsList(Long userId, int counts) {
    //1、查询喜欢不喜欢的用户ID
    List<UserLike> likeList = mongoTemplate.find(Query.query(Criteria.where("userId").is(userId)), UserLike.class);
    List<Long> likeUserIdS = CollUtil.getFieldValues(likeList, "likeUserId", Long.class);
    //2、构造查询推荐用户的条件
    Criteria criteria = Criteria.where("toUserId").is(userId).and("userId").nin(likeUserIdS);
    //3、使用统计函数,随机获取推荐的用户列表
    TypedAggregation<RecommendUser> newAggregation = TypedAggregation.newAggregation(RecommendUser.class,
                                                                                     Aggregation.match(criteria),//指定查询条件
                                                                                     Aggregation.sample(counts)
                                                                                    );
    AggregationResults<RecommendUser> results = mongoTemplate.aggregate(newAggregation, RecommendUser.class);
    //4、构造返回
    return results.getMappedResults();
}

1.3 左滑右滑

左滑:“不喜欢”,右滑:“喜欢”,如果双方喜欢,那么就会成为好友。

接口文档

探花喜欢:http://192.168.136.160:3000/project/19/interface/api/112

在这里插入图片描述

探花不喜欢:http://192.168.136.160:3000/project/19/interface/api/109

在这里插入图片描述

tanhua-app-server

``tanhua-app-server</b></font>项目中修改TanHuaControllerTanHuaService`

TanHuaController

TanHuaController定义喜欢和不喜欢的方法

/**
 * 喜欢
*/
@GetMapping("{id}/love")
public ResponseEntity<Void> likeUser(@PathVariable("id") Long likeUserId) {
    this.tanhuaService.likeUser(likeUserId);
    return ResponseEntity.ok(null);
}

/**
 * 不喜欢
 */
@GetMapping("{id}/unlove")
public ResponseEntity<Void> notLikeUser(@PathVariable("id") Long likeUserId) {
    this.tanhuaService.notLikeUser(likeUserId);
    return ResponseEntity.ok(null);
}

TanHuaService

TanHuaService中定义方法完成喜欢不喜欢的逻辑代码

喜欢 :

  1. 调用dubbo服务保存数据到MongoDB
  2. 保存喜欢数据到redis , 删除不喜欢数据
  3. 判断是否是双向喜欢, 如果是双向喜欢自动成为好友

不喜欢:

  1. 调用dubbo服务保存数据到MongoDB
  2. 保存不喜欢数据到redis , 删除喜欢数据
  3. 判断是否是双向喜欢, 如果是双向喜欢取消好友关系
    1. 探花系统好友关系
    2. 环信系统好友关系
/**
 * 喜欢
 */
public void likeUser(Long likeUserId) {
    //1、调用API,保存喜欢数据(保存到MongoDB中)
    Boolean save = userLikeApi.saveOrUpdate(UserHolder.getUserId(),likeUserId,true);
    if(!save) {
        //失败
        throw new BusinessException(ErrorResult.error());
    }
    //2、操作redis,写入喜欢的数据,删除不喜欢的数据 (喜欢的集合,不喜欢的集合)
    redisTemplate.opsForSet().remove(Constants.USER_NOT_LIKE_KEY+UserHolder.getUserId(),likeUserId.toString());
    redisTemplate.opsForSet().add(Constants.USER_LIKE_KEY+UserHolder.getUserId(),likeUserId.toString());
    //3、判断是否双向喜欢
    if(isLike(likeUserId,UserHolder.getUserId())) {
        //4、添加好友
        messagesService.contacts(likeUserId);
    }
}

/**
 * 不喜欢
 */
public void notLikeUser(Long likeUserId) {
    //1、调用API,保存喜欢数据(保存到MongoDB中)
    Boolean save = userLikeApi.saveOrUpdate(UserHolder.getUserId(),likeUserId,false);
    if(!save) {
        //失败
        throw new BusinessException(ErrorResult.error());
    }
    //2、操作redis,写入喜欢的数据,删除不喜欢的数据 (喜欢的集合,不喜欢的集合)
    redisTemplate.opsForSet().add(Constants.USER_NOT_LIKE_KEY+UserHolder.getUserId(),likeUserId.toString());
    redisTemplate.opsForSet().remove(Constants.USER_LIKE_KEY+UserHolder.getUserId(),likeUserId.toString());
    //3. 判断是否双向喜欢,删除好友(各位自行实现)
}

//判断是否双向喜欢
public Boolean isLike(Long userId, Long likeUserId) {
    String key = Constants.USER_LIKE_KEY + userId;
    return redisTemplate.opsForSet().isMember(key, likeUserId.toString());
}

tanhua-dubbo-interface

UserLikeApi

tanhua-dubbo-interface项目中创建UserLikeApi接口定义喜欢或者不喜欢的方法

public interface UserLikeApi {

    /**
     * 保存或者更新
     * 左滑右滑(喜欢/不喜欢)
     */
    Boolean saveOrUpdate(Long userId, Long likeUserId, boolean isLike);
}

tanhua-dubbo-mongo

UserLikeApi

tanhua-dubbo-mongo项目中实现喜欢或者不喜欢的方法

package com.tanhua.dubbo.api;

import com.tanhua.dubbo.api.mongo.UserLikeApi;
import com.tanhua.model.mongo.UserLike;
import org.apache.dubbo.config.annotation.DubboService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;

/**
 * @author Administrator
 */
@DubboService
public class UserLikeApiImpl implements UserLikeApi {

    @Autowired
    private MongoTemplate mongoTemplate;

    @Override
    public Boolean saveOrUpdate(Long userId, Long likeUserId, boolean isLike) {
        try {
            //1、查询数据
            Query query = Query.query(Criteria.where("userId").is(userId).and("likeUserId").is(likeUserId));
            UserLike userLike = mongoTemplate.findOne(query, UserLike.class);
            //2、如果不存在,保存
            if(userLike == null) {
                userLike = new UserLike();
                userLike.setUserId(userId);
                userLike.setLikeUserId(likeUserId);
                userLike.setCreated(System.currentTimeMillis());
                userLike.setUpdated(System.currentTimeMillis());
                userLike.setIsLike(isLike);
                mongoTemplate.save(userLike);
            }else {
                //3、更新
                Update update = Update.update("isLike", isLike)
                        .set("updated",System.currentTimeMillis());
                mongoTemplate.updateFirst(query,update,UserLike.class);
            }
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }
}

2. MongoDB地理位置检索

MongoDB 支持对地理空间数据的查询操作。

2.1 地理位置索引

地理位置查询,必须创建索引才可以能查询,目前有两种索引。

2d :

使用2d index 能够将数据作为二维平面上的点存储起来,在MongoDB 2.4以前使用2d。

2dsphere:

2dsphere索引支持查询在一个类地球的球面上进行几何计算,以GeoJSON对象或者普通坐标对的方式存储数据。

MongoDB内部支持多种GeoJson对象类型:

Point

最基础的坐标点,指定纬度和经度坐标,首先列出经度,然后列出 纬度

  • 有效的经度值介于-180和之间180,两者都包括在内。
  • 有效的纬度值介于-90和之间90,两者都包括在内。
{ type: "Point", coordinates: [ 40, 5 ] }

LineString

{ type: "LineString", coordinates: [ [ 40, 5 ], [ 41, 6 ] ] }

Polygon

{
  type: "Polygon",
  coordinates: [ [ [ 0 , 0 ] , [ 3 , 6 ] , [ 6 , 1 ] , [ 0 , 0  ] ] ]
}

2.2 案例

查询附近并按照距离返回

@Data
@AllArgsConstructor
@NoArgsConstructor
@Document("places")
@CompoundIndex(name = "location_index", def = "{'location': '2dsphere'}")
public class Places {

    private ObjectId id;

    private String title;

    private String address;

    private GeoJsonPoint location;
}

插入数据

@Test
public void testAdd() {

    Places places = new Places();
    places.setId(ObjectId.get());
    places.setAddress("湖北省武汉市东西湖区金山大道");
    places.setTitle("金山大道");
    places.setLocation(new GeoJsonPoint(114.226867, 30.636001));
    mongoTemplate.save(places);

    Places places2 = new Places();
    places2.setId(ObjectId.get());
    places2.setAddress("湖北省武汉市东西湖区奥园东路");
    places2.setTitle("奥园东路");
    places2.setLocation(new GeoJsonPoint(114.240592, 30.650171));
    mongoTemplate.save(places2);

    Places places3 = new Places();
    places3.setId(ObjectId.get());
    places3.setAddress("湖北省武汉市黄陂区X003");
    places3.setTitle("黄陂区X003");
    places3.setLocation(new GeoJsonPoint(114.355876, 30.726886));
    mongoTemplate.save(places3);

    Places places4 = new Places();
    places4.setId(ObjectId.get());
    places4.setAddress("湖北省武汉市黄陂区汉口北大道");
    places4.setTitle("汉口北大道");
    places4.setLocation(new GeoJsonPoint(114.364111, 30.722166));
    mongoTemplate.save(places4);
}

查询附近

查询当前坐标附近的目标

@Test
public void testNear() {
    //构造坐标点
    GeoJsonPoint point = new GeoJsonPoint(116.404, 39.915);
    //构造半径
    Distance distanceObj = new Distance(1, Metrics.KILOMETERS);
    //画了一个圆圈
    Circle circle = new Circle(point, distanceObj);
    //构造query对象
    Query query = Query.query(Criteria.where("location").withinSphere(circle));
    //省略其他内容
    List<Places> list = mongoTemplate.find(query, Places.class);
    list.forEach(System.out::println);
}

查询并获取距离

我们假设需要以当前坐标为原点,查询附近指定范围内的餐厅,并直接显示距离

//查询附近且获取间距
@Test
public void testNear1() {
    //1. 构造中心点(圆点)
    GeoJsonPoint point = new GeoJsonPoint(116.404, 39.915);
    //2. 构建NearQuery对象
    NearQuery query = NearQuery.near(point, Metrics.KILOMETERS).maxDistance(1, Metrics.KILOMETERS);
    //3. 调用mongoTemplate的geoNear方法查询
    GeoResults<Places> results = mongoTemplate.geoNear(query, Places.class);
    //4. 解析GeoResult对象,获取距离和数据
    for (GeoResult<Places> result : results) {
        Places places = result.getContent();
        double value = result.getDistance().getValue();
        System.out.println(places+"---距离:"+value + "km");
    }
}

3. 上报地理位置

3.1 需求分析

当客户端检测用户的地理位置,当变化大于500米时或每隔5分钟,向服务端上报地理位置

数据库表

用户的地理位置存储到MongoDB中,如下:
在这里插入图片描述

接口说明

接口地址:http://192.168.136.160:3000/project/19/interface/api/82

在这里插入图片描述

3.2. 代码实现

tanhua-model

tanhua-model中创建UserLocation实体类

@Data
@NoArgsConstructor
@AllArgsConstructor
@Document(collection = "user_location")
@CompoundIndex(name = "location_index", def = "{'location': '2dsphere'}")
public class UserLocation implements java.io.Serializable{

    private static final long serialVersionUID = 4508868382007529970L;

    @Id
    private ObjectId id;
    @Indexed
    private Long userId; //用户id
    private GeoJsonPoint location; //x:经度 y:纬度
    private String address; //位置描述
    private Long created; //创建时间
    private Long updated; //更新时间
    private Long lastUpdated; //上次更新时间
}

tanhua-app-server

``tanhua-app-server</b></font>中定义BaiduControllerBaiduService`实现上报地理位置功能

BaiduController

package com.tanhua.server.controller;


import com.tanhua.server.service.BaiduService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.Map;

@RestController
@RequestMapping("/baidu")
public class BaiduController {

    @Autowired
    private BaiduService baiduService;

    /**
     * 更新位置
     */
    @PostMapping("/location")
    public ResponseEntity updateLocation(@RequestBody Map param) {
        Double longitude = Double.valueOf(param.get("longitude").toString());
        Double latitude = Double.valueOf(param.get("latitude").toString());
        String address = param.get("addrStr").toString();
        this.baiduService.updateLocation(longitude, latitude,address);
        return ResponseEntity.ok(null);
    }
}

BaiduService

创建BaiduService类 , 调用dubbo服务完成地址位置上报

package com.tanhua.server.service;

import com.tanhua.dubbo.api.UserLocationApi;
import com.tanhua.model.vo.ErrorResult;
import com.tanhua.server.exception.BusinessException;
import com.tanhua.server.interceptor.UserHolder;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.stereotype.Service;

@Service
public class BaiduService {

    @DubboReference
    private UserLocationApi userLocationApi;

    //更新地理位置
    public void updateLocation(Double longitude, Double latitude, String address) {
        Boolean flag = userLocationApi.updateLocation(UserHolder.getUserId(),longitude,latitude,address);
        if(!flag) {
            throw  new BusinessException(ErrorResult.error());
        }
    }
}

tanhua-dubbo-interface

tanhua-dubbo-interface工程中创建UserLocationApi接口 , 定义上报地理位置的方法

package com.tanhua.dubbo.api.mongo;

public interface UserLocationApi {

    //更新地理位置
    Boolean updateLocation(Long userId, Double longitude, Double latitude, String address);
}

tanhua-dubbo-mongo

``tanhua-dubbo-mongo`中实现上报地理位置的方法

package com.tanhua.dubbo.api;

import com.tanhua.dubbo.api.mongo.UserLocationApi;
import com.tanhua.model.mongo.UserLocation;
import org.apache.dubbo.config.annotation.DubboService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.geo.GeoJsonPoint;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;

/**
 * @author Administrator
 */
@DubboService
public class UserLocationApiImpl implements UserLocationApi {

    @Autowired
    private MongoTemplate mongoTemplate;

    //更新地理位置
    public Boolean updateLocation(Long userId, Double longitude, Double latitude, String address) {
        try {
            //1、根据用户id查询位置信息
            Query query = Query.query(Criteria.where("userId").is(userId));
            UserLocation location = mongoTemplate.findOne(query, UserLocation.class);
            if(location == null) {
                //2、如果不存在用户位置信息,保存
                location = new UserLocation();
                location.setUserId(userId);
                location.setAddress(address);
                location.setCreated(System.currentTimeMillis());
                location.setUpdated(System.currentTimeMillis());
                location.setLastUpdated(System.currentTimeMillis());
                location.setLocation(new GeoJsonPoint(longitude,latitude));
                mongoTemplate.save(location);
            }else {
                //3、如果存在,更新
                Update update = Update.update("location", new GeoJsonPoint(longitude, latitude))
                        .set("updated", System.currentTimeMillis())
                        .set("lastUpdated", location.getUpdated());
                mongoTemplate.updateFirst(query,update,UserLocation.class);
            }
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }
}

运行测试

在这里插入图片描述

数据准备

后续搜附近,需要一定的数据量。这里准备了单元测试类,方便构造数据

  • 启动tanhua-dubbo-mongo服务
  • tanhua-app-server项目中编写测试类

地理位置坐标拾取:https://lbs.qq.com/getPoint/

@RunWith(SpringRunner.class)
@SpringBootTest(classes = AppServerApplication.class)
public class TestUserLocationApi {

    @DubboReference
    private UserLocationApi userLocationApi;

    @Test
    public void testUpdateUserLocation() {
        this.userLocationApi.updateLocation(1L, 116.353885,40.065911, "育新地铁站");
        this.userLocationApi.updateLocation(2L, 116.352115,40.067441, "北京石油管理干部学院");
        this.userLocationApi.updateLocation(3L, 116.336438,40.072505, "回龙观医院");
        this.userLocationApi.updateLocation(4L, 116.396797,40.025231, "奥林匹克森林公园");
        this.userLocationApi.updateLocation(5L, 116.323849,40.053723, "小米科技园");
        this.userLocationApi.updateLocation(6L, 116.403963,39.915119, "天安门");
        this.userLocationApi.updateLocation(7L, 116.328103,39.900835, "北京西站");
        this.userLocationApi.updateLocation(8L, 116.609564,40.083812, "北京首都国际机场");
        this.userLocationApi.updateLocation(9L, 116.459958,39.937193, "德云社(三里屯店)");
        this.userLocationApi.updateLocation(10L, 116.333374,40.009645, "清华大学");
        this.userLocationApi.updateLocation(41L, 116.316833,39.998877, "北京大学");
        this.userLocationApi.updateLocation(42L, 117.180115,39.116464, "天津大学(卫津路校区)");
    }
}

4. 搜附近

4.1 需求分析

在首页中点击“搜附近”可以搜索附近的好友

需求分析

**加粗样式
**

接口说明

接口地址:http://192.168.136.160:3000/project/19/interface/api/121

在这里插入图片描述

4.2 代码实现

tanhua-model

tanhua-model项目中定义NearUserVo封装返回数据

package com.tanhua.model.vo;

import com.tanhua.model.domain.UserInfo;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

//附近的人vo对象
@Data
@NoArgsConstructor
@AllArgsConstructor
public class NearUserVo {

    private Long userId;
    private String avatar;
    private String nickname;

    public static NearUserVo init(UserInfo userInfo) {
        NearUserVo vo = new NearUserVo();
        vo.setUserId(userInfo.getId());
        vo.setAvatar(userInfo.getAvatar());
        vo.setNickname(userInfo.getNickname());
        return vo;
    }
}

tanhua-app-server

``tanhua-app-server</b></font>中的TanHuaControllerTanHuaService`添加搜附近功能代码

TanHuaController

TanHuaController中定义方法接收请求

/**
* 搜附近
*/
@GetMapping("/search")
public ResponseEntity<List<NearUserVo>> queryNearUser(String gender,
                       @RequestParam(defaultValue = "2000") String distance) {
    List<NearUserVo> list = this.tanhuaService.queryNearUser(gender, distance);
    return ResponseEntity.ok(list);
}

TanHuaService

//搜附近
public List<NearUserVo> queryNearUser(String gender, String distance) {
    //1、调用API查询附近的用户(返回的是附近的人的所有用户id,包含当前用户的id)
    List<Long> userIds = userLocationApi.queryNearUser(UserHolder.getUserId(),Double.valueOf(distance));
    //2、判断集合是否为空
    if(CollUtil.isEmpty(userIds)) {
        return new ArrayList<>();
    }
    //3、调用UserInfoApi根据用户id查询用户详情
    UserInfo userInfo = new UserInfo();
    userInfo.setGender(gender);
    Map<Long, UserInfo> map = userInfoApi.findByIds(userIds, userInfo);
    //4、构造返回值。
    List<NearUserVo> vos = new ArrayList<>();
    for (Long userId : userIds) {
        //排除当前用户
        if(userId == UserHolder.getUserId()) {
            continue;
        }
        UserInfo info = map.get(userId);
        if(info != null) {
            NearUserVo vo = NearUserVo.init(info);
            vos.add(vo);
        }
    }
    return vos;
}

tanhua-dubbo-interface

tanhua-dubbo-interface工程中的UserLocationApi中定义搜索附近的人的方法

/**
 * 根据位置搜索附近人的id集合
 */
List<Long> queryNearUser(Long userId, Double metre);

tanhua-dubbo-mongo

``tanhua-dubbo-mongo</b></font>中的UserLocationApiImpl`中实现搜索附近的人的方法

@Override
public List<Long> queryNearUser(Long userId, Double metre) {
    //1、根据用户id,查询用户的位置信息
    Query query = Query.query(Criteria.where("userId").is(userId));
    UserLocation location = mongoTemplate.findOne(query, UserLocation.class);
    if(location == null) {
        return null;
    }
    //2、已当前用户位置绘制原点
    GeoJsonPoint point = location.getLocation();
    //3、绘制半径
    Distance distance = new Distance(metre / 1000, Metrics.KILOMETERS);
    //4、绘制圆形
    Circle circle = new Circle(point, distance);
    //5、查询
    Query locationQuery = Query.query(Criteria.where("location").withinSphere(circle));
    List<UserLocation> list = mongoTemplate.find(locationQuery, UserLocation.class);
    return CollUtil.getFieldValues(list,"userId",Long.class);
}

访问测试

font color=red>``tanhua-dubbo-mongo</b></font>中的UserLocationApiImpl`中实现搜索附近的人的方法

@Override
public List<Long> queryNearUser(Long userId, Double metre) {
    //1、根据用户id,查询用户的位置信息
    Query query = Query.query(Criteria.where("userId").is(userId));
    UserLocation location = mongoTemplate.findOne(query, UserLocation.class);
    if(location == null) {
        return null;
    }
    //2、已当前用户位置绘制原点
    GeoJsonPoint point = location.getLocation();
    //3、绘制半径
    Distance distance = new Distance(metre / 1000, Metrics.KILOMETERS);
    //4、绘制圆形
    Circle circle = new Circle(point, distance);
    //5、查询
    Query locationQuery = Query.query(Criteria.where("location").withinSphere(circle));
    List<UserLocation> list = mongoTemplate.find(locationQuery, UserLocation.class);
    return CollUtil.getFieldValues(list,"userId",Long.class);
}

访问测试

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/95556.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

2022-前端实现电子签名(web、移动端)通用组件

前端实现电子签名&#xff08;web、移动端&#xff09;通用组件 前言 在现在的时代发展中&#xff0c;从以前的手写签名&#xff0c;逐渐衍生出了电子签名。电子签名和纸质手写签名一样具有法律效应。电子签名目前主要还是在需要个人确认的产品环节和司法类相关的产品上较多。…

可视化大数据分析系统

可视化大数据分析系统有很多&#xff0c;如果系统级都是收费的&#xff0c;如果大家想要了解可视化大数据分析系统&#xff0c;私信我就行。下面聊下5个常用的大数据可视化分析工具。 1、FineReport FineReport是一款纯Java编写的、集数据展示(报表)和数据录入(表单)功能于一…

Linux环境变量配置

在自定义安装软件的时候&#xff0c;经常需要配置环境变量&#xff0c;下面列举出各种对环境变量的配置方法。 下面所有例子的环境说明如下&#xff1a; 系统&#xff1a;Ubuntu 14.0 用户名&#xff1a;uusama 需要配置MySQL环境变量路径&#xff1a;/home/uusama/mysql/bi…

Servlet转发与重定向

✅作者简介&#xff1a;热爱国学的Java后端开发者&#xff0c;修心和技术同步精进。 &#x1f34e;个人主页&#xff1a;Java Fans的博客 &#x1f34a;个人信条&#xff1a;不迁怒&#xff0c;不贰过。小知识&#xff0c;大智慧。 &#x1f49e;当前专栏&#xff1a;JAVA开发者…

【设计模式】代理模式——静态动态代理

【设计模式】代理模式——静态&动态代理 文章目录【设计模式】代理模式——静态&动态代理一&#xff1a;代理模式概述二&#xff1a;代理模式结构三&#xff1a;静态代理四&#xff1a;JDK动态代理1&#xff1a;简介2&#xff1a;步骤五&#xff1a;CGLIB动态代理六&am…

Python -- 元组、字典、集合

目录 1.元组的使用 1.1 访问元组 1.2 修改元组 1.3 count,index 1.4 定义只有一个数据的元组 2.字典的基本使用 2.1 字典的增删改查 2.2 字典的遍历 3.集合的使用 4.通用方法 1.元组的使用 Python的元组与列表类似&#xff0c;不同之处在于元组的元素不能修改。元组使…

测试人必备的Linux常用命令大全...【全网最全面整理】

Linux常用命令大全&#xff08;非常全&#xff01;&#xff01;&#xff01;&#xff09; 最近都在和Linux打交道&#xff0c;感觉还不错。我觉得Linux相比windows比较麻烦的就是很多东西都要用命令来控制&#xff0c;当然&#xff0c;这也是很多人喜欢linux的原因&#xff0c…

基于BP神经网络的数字识别系统仿真,带GUI界面

目录 1.算法描述 2.仿真效果预览 3.MATLAB核心程序 4.完整MATLAB 1.算法描述 OCR&#xff08;Optical Character Recognition&#xff09;即光学字符识别技术&#xff0c;是通过扫描仪把印刷体或手写体文稿扫描成图像&#xff0c;然后识别成相应的计算机可直接处理的字符。…

SoapUI、Jmeter、Postman三种接口测试工具的比较分析

推荐阅读&#xff1a; [内部资源] 想拿年薪30W的软件测试人员&#xff0c;这份资料必须领取~ Python自动化测试全栈性能测试全栈&#xff0c;挑战年薪40W 前段时间忙于接口测试&#xff0c;也看了几款接口测试工具&#xff0c;简单从几个角度做了个比较&#xff0c;拿出来与…

水库信息化监测系统有哪些?水库信息化监测解决方案

一、背景分析 全国现有水库9.8万余座&#xff0c;小型水库占95.3%。小型水库数量最多&#xff0c; 主要分布山东、安徽、江西、广东、湖南、湖北、四川和云南&#xff0c;每个省小型水库数量超过5000座 全国中小型水库9万余座&#xff0c;其中4万余座存在病险&#xff0c;195…

图解设计模式:动动手玩转适配器模式

前言 &#x1f4e3; &#x1f4e3; &#x1f4e3; &#x1f4e2;&#x1f4e2;&#x1f4e2; ☀️☀️点开就是缘分认识一下&#xff0c;我是小冷。是一个兴趣驱动自学练习两年半的的Java工程师。 &#x1f4d2; 一位十分喜欢将知识分享出来的Java博主⭐️⭐️⭐️&#xff0c;…

C++进阶 继承

作者&#xff1a;小萌新 专栏&#xff1a;C进阶 作者简介&#xff1a;大二学生 希望能和大家一起进步&#xff01; 本篇博客简介&#xff1a;简单介绍C中继承的概念 继承的概念及定义 继承的概念 继承是一种面向对象编程的概念&#xff0c;它指的是一个类&#xff08;称为子类…

Win10关闭安全中心的病毒和威胁实时保护

一、遇到问题 想必大家在下载软件时&#xff0c;经常会遇到这样的问题&#xff1a;当我们下载好一个软件安装包时&#xff0c;当双击进行安装时&#xff0c;电脑却报出“无法成功完成操作&#xff0c;因为文件包含病毒或潜在的垃圾软件”。这是Win10的安全中心误以为此为问题软…

ShardingJDBC读写分离

ShardingJDBC是什么 看一看ChatGPT对他的解释&#xff1a; ShardingJDBC是一个数据库连接池&#xff0c;它为数据库的分片和读/写拆分提供支持。它允许您跨多个物理数据库和服务器分发数据&#xff0c;并根据设置的配置将读写操作路由到适当的数据库。 以下是它的工作原理&…

基于java+springmvc+mybatis+vue+mysql的校园拼车系统

项目介绍 本系统采用java语言开发&#xff0c;后端采用ssm框架&#xff0c;前端采用vue技术&#xff0c;数据库采用mysql进行数据存储。 管理员后台页面&#xff1a; 功能&#xff1a;首页、个人中心、学生管理、司机管理、订单信息管理、接单信息管理、留言信息管理 学生后…

小米(Android)刷NetHunter安装指南,无需ssh执行kali命令

一、安装NetHunter 前提&#xff1a;确保手机已经root&#xff0c;已装上magisk。如果没有root&#xff0c;可用尝试magisk root 后执行此文 1、下载Nethunter&#xff1a;Get Kali | Kali Linux 然后push 到sdcard 里&#xff0c; 2、打开magisk&#xff0c;选择刚刚下好的…

【问答篇】Java 基础篇面试题(一)

每天进步一点~ 01、问&#xff1a;空字符串的作用 package com.neuedu.nineteen;public class Test {public static void main(String[] args) {String s"";for (char i a; i < d; i) {ssi;//输出abcsis;//输出cba}System.out.println(s);} } 答&#xff1a;如…

[附源码]Node.js计算机毕业设计高校迎新管理系统Express

项目运行 环境配置&#xff1a; Node.js最新版 Vscode Mysql5.7 HBuilderXNavicat11Vue。 项目技术&#xff1a; Express框架 Node.js Vue 等等组成&#xff0c;B/S模式 Vscode管理前后端分离等等。 环境需要 1.运行环境&#xff1a;最好是Nodejs最新版&#xff0c;我…

(五)springcloud之Nacos注册中心-2

最近因口罩事件&#xff0c;也被“阳"了。自己在宿舍&#xff0c;闲来无事。整理下Nacos的注册中心的知识点。 模块&#xff1a; 1.父工程&#xff08;管理版本&#xff09; 2.公共模块&#xff1a;Common-API 3.测试模块&#xff1a;NacosClientConfigConsumer80 版本&am…

Vue3基础语法(⼀)

文章目录02——Vue3基础语法&#xff08;⼀&#xff09;VSCode代码片段模板语法Mustachev-once指令v-textv-htmlv-prev-bind绑定class对象语法数组语法绑定style动态绑定属性绑定一个对象v-on基本使用参数传递修饰符02——Vue3基础语法&#xff08;⼀&#xff09; 上一节中的问…