和所有以梦为马的诗人一样,我借此火得度一生的茫茫黑夜
1. 项目介绍及环境配置
2. 短信验证码登录
3. 用户信息
4. MongoDB
5. 推荐好友列表/MongoDB集群/动态发布与查看
6. 圈子动态/圈子互动
7. 即时通讯(基于第三方API)
8. 附近的人(百度地图APi)
9. 小视频
10.网关配置
11.后台管理
新建 tanhua-model/src/main/java/com/tanhua/model/mongo/UserLike.java
文件:
@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/src/main/java/com/tanhua/server/controller/TanhuaController.java
文件:
@RestController
@RequestMapping("/tanhua")
public class TanhuaController {
@Autowired
private TanhuaService tanhuaService;
/**
* 今日佳人
*/
@GetMapping("/todayBest")
public ResponseEntity todayBest() {
TodayBest vo = tanhuaService.todayBest();
return ResponseEntity.ok(vo);
}
/**
* 查询分页推荐好友列表
*/
@GetMapping("recommendation")
public ResponseEntity recommendation(RecommendUserDto dto) {
PageResult pr = tanhuaService.recommendation(dto);
return ResponseEntity.ok(pr);
}
/**
* 查看佳人详情
*/
@GetMapping("/{id}/personalInfo")
public ResponseEntity personalInfo(@PathVariable("id") Long userId) {
TodayBest best = tanhuaService.personalInfo(userId);
return ResponseEntity.ok(best);
}
/**
* 查看陌生人问题
*/
@GetMapping("/strangerQuestions")
public ResponseEntity strangerQuestions(Long userId) {
String questions = tanhuaService.strangerQuestions(userId);
return ResponseEntity.ok(questions);
}
/**
* 回复陌生人问题
*/
@PostMapping("/strangerQuestions")
public ResponseEntity replyQuestions(@RequestBody Map map) {
// 前端传递的userId是 Integer类型
String obj = map.get("userId").toString();
Long userId = Long.valueOf(obj);
String reply = map.get("reply").toString();
tanhuaService.replyQuestions(userId, reply);
return ResponseEntity.ok(null);
}
/**
* 探花 - 推荐用户列表
*/
@GetMapping("cards")
public ResponseEntity queryCardsList() {
List<TodayBest> list = this.tanhuaService.queryCardsList();
return ResponseEntity.ok(list);
}
}
编辑 tanhua-app-server/src/main/resources/application.yml
文件:
#服务端口
server:
port: 18080
spring:
application:
name: tanhua-app-server
redis: #redis配置
port: 6379
host: 192.168.136.160
cloud: #nacos配置
nacos:
discovery:
server-addr: 192.168.136.160:8848
dubbo: #dubbo配置
registry:
address: spring-cloud://localhost
consumer:
check: false
tanhua:
# 默认推荐列表
default:
recommend:
users: 2,3,8,10,18,20,24,29,27,32,36,37,56,64,75,88
sms:
signName: 物流云商
templateCode: SMS_106590012
accessKey: 略
secret: LHLBvXmILRoyw0niRSBuXBZewQ30la
oss:
accessKey: 略
secret: LHLBvXmILRoyw0niRSBuXBZewQ30la
endpoint: oss-cn-beijing.aliyuncs.com
bucketName: tanhua001
url: https://tanhua001.oss-cn-beijing.aliyuncs.com/
aip:
appId: 略
apiKey: 略
secretKey: 略
huanxin:
appkey: 略
clientId: 略
clientSecret: 略
编辑 tanhua-app-server/src/main/java/com/tanhua/server/service/TanhuaService.java
文件:
@Service
public class TanhuaService {
@DubboReference
private RecommendUserApi recommendUserApi;
@DubboReference
private UserInfoApi userInfoApi;
@DubboReference
private QuestionApi questionApi;
@Autowired
private HuanXinTemplate huanXinTemplate;
@Value("${tanhua.default.recommend.users}")
private String recommendUser;
// 查询今日佳人数据
public TodayBest todayBest() {
// 1. 获取用户id
Long userId = UserHolder.getUserId();
// 2. 调用api查询
RecommendUser recommendUser = recommendUserApi.queryWithMaxScore(userId);
// 3. 设置默认值
if(recommendUser == null) {
recommendUser = new RecommendUser();
recommendUser.setUserId(1l);
recommendUser.setScore(99d);
}
// 4. 将recommendUser 转化成 todayBest对象
UserInfo userInfo = userInfoApi.findById(recommendUser.getUserId());
TodayBest vo = TodayBest.init(userInfo, recommendUser);
// 5. 返回
return vo;
}
// 查询分页推荐好友列表
public PageResult recommendation(RecommendUserDto dto) {
// 1. 获取用户id
Long userId = UserHolder.getUserId();
// 2. 调用RecommendUserApi查询数据列表(PageResult -- RecommendUser)
PageResult pr = recommendUserApi.queryRecommendUserList(dto.getPage(), dto.getPagesize(), userId);
// 3. 获取分页中的RecommendUser数据列表
List<RecommendUser> items = (List<RecommendUser>) pr.getItems();
// 4. 判断列表数据是否为空
if (items == null) {
return pr;
}
// // 5. 循环RecommendUser推荐列表,根据推荐的用户id查询用户详情
// List list = new ArrayList<>();
// for (RecommendUser item : items) {
// Long recommendUserId = item.getUserId();
// UserInfo userInfo = userInfoApi.findById(recommendUserId);
// if(userInfo != null) {
// // 条件判断
// if(!StringUtils.isEmpty(dto.getGender()) && !dto.getGender().equals(userInfo.getGender())) {
// continue;
// }
// if (dto.getAge() != null && dto.getAge() < userInfo.getAge()) {
// continue;
// }
// TodayBest vo = TodayBest.init(userInfo, item);
// list.add(vo);
// }
// }
//
// 5. 提取所有推荐的用户id列表
List<Long> ids = CollUtil.getFieldValues(items, "userId", Long.class);
UserInfo userInfo = new UserInfo();
userInfo.setAge(dto.getAge());
userInfo.setGender(dto.getGender());
// 6. 构建查询条件,批量查询所有的用户详情
Map<Long, UserInfo> map = userInfoApi.findByIds(ids, userInfo);
// 7. 循环推荐的数据列表,构建vo对象
List<TodayBest> list = new ArrayList<>();
for (RecommendUser item : items) {
UserInfo info = map.get(item.getUserId());
if(info != null) {
TodayBest vo = TodayBest.init(info, item);
list.add(vo);
}
}
// 6. 构造返回值
pr.setItems(list);
return pr;
}
// 查看佳人详情
public TodayBest personalInfo(Long userId) {
// 1. 根据用户id,查询用户详情
UserInfo userInfo = userInfoApi.findById(userId);
// 2. 根据操作人id, 和查看的用户id,查询两者的推荐数据(缘分值)
RecommendUser user = recommendUserApi.queryByUserId(userId, UserHolder.getUserId());
// 3. 构造返回值
return TodayBest.init(userInfo, user);
}
// 查看陌生人问题
public String strangerQuestions(Long userId) {
Question question = questionApi.findByUserId(userId);
return question == null ? "你喜欢吃青椒吗?" : question.getTxt();
}
// 回复陌生人问题
public void replyQuestions(Long userId, String reply) {
// 1. 构造消息数据
Long currentUserId = UserHolder.getUserId();
UserInfo userInfo = userInfoApi.findById(currentUserId);
Map map = new HashMap<>();
map.put("userId", currentUserId);
map.put("huanXinId", Constants.HX_USER_PREFIX + currentUserId);
map.put("nickname", userInfo.getNickname());
map.put("strangerQuestion", strangerQuestions(userId));
map.put("reply", reply);
String message = JSON.toJSONString(map);
// 2. 调用template对象,发送消息
Boolean aBoolean = huanXinTemplate.sendMsg(Constants.HX_USER_PREFIX + userId, message);
// 3. 异常处理
if (!aBoolean) {
throw new BusinessException(ErrorResult.error());
}
}
// 探花 - 推荐用户列表
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-dubbo/tanhua-dubbo-interface/src/main/java/com/tanhua/dubbo/api/RecommendUserApi.java
文件:
public interface RecommendUserApi {
// 查询今日佳人
RecommendUser queryWithMaxScore(Long toUserId);
// 分页查询推荐好友列表
PageResult queryRecommendUserList(Integer page, Integer pagesize, Long toUserId);
// 根据操作人id, 和查看的用户id,查询两者的推荐数据(缘分值)
RecommendUser queryByUserId(Long userId, Long toUserId);
// 探花 - 查询推荐用户列表
List<RecommendUser> queryCardsList(Long userId, int counts);
}
编辑 tanhua-dubbo/tanhua-dubbo-mongo/src/main/java/com/tanhua/dubbo/api/RecommendUserApiImpl.java
文件:
@DubboService
public class RecommendUserApiImpl implements RecommendUserApi{
@Autowired
private MongoTemplate mongoTemplate;
// 查询今日佳人
public RecommendUser queryWithMaxScore(Long toUserId) {
// 根据toUserId查询,根据评分score排序,获取第一条
// 1. 构建Criteria
Criteria criteria = Criteria.where("toUserId").is(toUserId);
// 2. 构建Query
Query query = Query.query(criteria).with(Sort.by(Sort.Order.desc("score")))
.limit(1); // 查询第一条(第一页第一条)
// 3. 调用mongoTemplate查询
return mongoTemplate.findOne(query, RecommendUser.class);
}
// 分页查询推荐好友列表
public PageResult queryRecommendUserList(Integer page, Integer pagesize, Long toUserId) {
// 1. 构建Criteria对象
Criteria criteria = Criteria.where("toUserId").is(toUserId);
// 2. 构造query对象
Query query = Query.query(criteria);
// 3. 查询总数
long count = mongoTemplate.count(query, RecommendUser.class);
// 4. 查询数据列表
query.with(Sort.by(Sort.Order.desc("score"))).limit(pagesize).skip((page - 1) * pagesize);
List<RecommendUser> list = mongoTemplate.find(query, RecommendUser.class);
// 5. 构造返回值
return new PageResult(page, pagesize, count, list);
}
// 根据操作人id, 和查看的用户id,查询两者的推荐数据(缘分值)
public RecommendUser queryByUserId(Long userId, Long toUserId) {
Criteria criteria = Criteria.where("toUserId").is(toUserId).and("userId").is(userId);
Query query = Query.query(criteria);
RecommendUser user = mongoTemplate.findOne(query, RecommendUser.class);
if(user == null) {
user = new RecommendUser();
user.setUserId(userId);
user.setToUserId(toUserId);
// 构建缘分值
user.setScore(95d);
}
return user;
}
// 探花 - 查询推荐用户列表
@Override
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();
}
}
编辑 tanhua-app-server/src/main/java/com/tanhua/server/controller/TanhuaController.java
文件:
@RestController
@RequestMapping("/tanhua")
public class TanhuaController {
@Autowired
private TanhuaService tanhuaService;
/**
* 今日佳人
*/
@GetMapping("/todayBest")
public ResponseEntity todayBest() {
TodayBest vo = tanhuaService.todayBest();
return ResponseEntity.ok(vo);
}
/**
* 查询分页推荐好友列表
*/
@GetMapping("recommendation")
public ResponseEntity recommendation(RecommendUserDto dto) {
PageResult pr = tanhuaService.recommendation(dto);
return ResponseEntity.ok(pr);
}
/**
* 查看佳人详情
*/
@GetMapping("/{id}/personalInfo")
public ResponseEntity personalInfo(@PathVariable("id") Long userId) {
TodayBest best = tanhuaService.personalInfo(userId);
return ResponseEntity.ok(best);
}
/**
* 查看陌生人问题
*/
@GetMapping("/strangerQuestions")
public ResponseEntity strangerQuestions(Long userId) {
String questions = tanhuaService.strangerQuestions(userId);
return ResponseEntity.ok(questions);
}
/**
* 回复陌生人问题
*/
@PostMapping("/strangerQuestions")
public ResponseEntity replyQuestions(@RequestBody Map map) {
// 前端传递的userId是 Integer类型
String obj = map.get("userId").toString();
Long userId = Long.valueOf(obj);
String reply = map.get("reply").toString();
tanhuaService.replyQuestions(userId, reply);
return ResponseEntity.ok(null);
}
/**
* 探花 - 推荐用户列表
*/
@GetMapping("cards")
public ResponseEntity queryCardsList() {
List<TodayBest> list = this.tanhuaService.queryCardsList();
return ResponseEntity.ok(list);
}
/**
* 探花 - 喜欢
*/
@GetMapping("{id}/love")
public ResponseEntity<Void> likeUser(@PathVariable("id") Long likeUserId) {
this.tanhuaService.likeUser(likeUserId);
return ResponseEntity.ok(null);
}
}
编辑 tanhua-commons/src/main/java/com/tanhua/commons/utils/Constants.java
文件:
//常量定义
public class Constants {
//手机APP短信验证码CHECK_CODE_
public static final String SMS_CODE = "CHECK_CODE_";
//推荐动态
public static final String MOVEMENTS_RECOMMEND = "MOVEMENTS_RECOMMEND_";
//推荐视频
public static final String VIDEOS_RECOMMEND = "VIDEOS_RECOMMEND_";
//圈子互动KEY
public static final String MOVEMENTS_INTERACT_KEY = "MOVEMENTS_INTERACT_";
//动态点赞用户HashKey
public static final String MOVEMENT_LIKE_HASHKEY = "MOVEMENT_LIKE_";
//动态喜欢用户HashKey
public static final String MOVEMENT_LOVE_HASHKEY = "MOVEMENT_LOVE_";
//视频点赞用户HashKey
public static final String VIDEO_LIKE_HASHKEY = "VIDEO_LIKE";
//访问用户
public static final String VISITORS = "VISITORS";
//关注用户
public static final String FOCUS_USER = "FOCUS_USER_{}_{}";
//初始化密码
public static final String INIT_PASSWORD = "123456";
//环信用户前缀
public static final String HX_USER_PREFIX = "hx";
//jwt加密盐
public static final String JWT_SECRET = "itcast";
//jwt超时时间
public static final int JWT_TIME_OUT = 3_600;
//用户喜欢Redis的key
public static final String USER_LIKE_KEY="USER_LIKE_SET_";
//用户不喜欢Redis的key
public static final String USER_NOT_LIKE_KEY="USER_NOT_LIKE_SET_";
}
编辑 tanhua-app-server/src/main/java/com/tanhua/server/service/TanhuaService.java
文件:
@Service
public class TanhuaService {
@DubboReference
private RecommendUserApi recommendUserApi;
@DubboReference
private UserInfoApi userInfoApi;
@DubboReference
private QuestionApi questionApi;
@Autowired
private HuanXinTemplate huanXinTemplate;
@DubboReference
private UserLikeApi userLikeApi;
@Autowired
private RedisTemplate<String, String> redisTemplate;
@Autowired
private MessagesService messagesService;
@Value("${tanhua.default.recommend.users}")
private String recommendUser;
// 查询今日佳人数据
public TodayBest todayBest() {
// 1. 获取用户id
Long userId = UserHolder.getUserId();
// 2. 调用api查询
RecommendUser recommendUser = recommendUserApi.queryWithMaxScore(userId);
// 3. 设置默认值
if(recommendUser == null) {
recommendUser = new RecommendUser();
recommendUser.setUserId(1l);
recommendUser.setScore(99d);
}
// 4. 将recommendUser 转化成 todayBest对象
UserInfo userInfo = userInfoApi.findById(recommendUser.getUserId());
TodayBest vo = TodayBest.init(userInfo, recommendUser);
// 5. 返回
return vo;
}
// 查询分页推荐好友列表
public PageResult recommendation(RecommendUserDto dto) {
// 1. 获取用户id
Long userId = UserHolder.getUserId();
// 2. 调用RecommendUserApi查询数据列表(PageResult -- RecommendUser)
PageResult pr = recommendUserApi.queryRecommendUserList(dto.getPage(), dto.getPagesize(), userId);
// 3. 获取分页中的RecommendUser数据列表
List<RecommendUser> items = (List<RecommendUser>) pr.getItems();
// 4. 判断列表数据是否为空
if (items == null) {
return pr;
}
// // 5. 循环RecommendUser推荐列表,根据推荐的用户id查询用户详情
// List list = new ArrayList<>();
// for (RecommendUser item : items) {
// Long recommendUserId = item.getUserId();
// UserInfo userInfo = userInfoApi.findById(recommendUserId);
// if(userInfo != null) {
// // 条件判断
// if(!StringUtils.isEmpty(dto.getGender()) && !dto.getGender().equals(userInfo.getGender())) {
// continue;
// }
// if (dto.getAge() != null && dto.getAge() < userInfo.getAge()) {
// continue;
// }
// TodayBest vo = TodayBest.init(userInfo, item);
// list.add(vo);
// }
// }
//
// 5. 提取所有推荐的用户id列表
List<Long> ids = CollUtil.getFieldValues(items, "userId", Long.class);
UserInfo userInfo = new UserInfo();
userInfo.setAge(dto.getAge());
userInfo.setGender(dto.getGender());
// 6. 构建查询条件,批量查询所有的用户详情
Map<Long, UserInfo> map = userInfoApi.findByIds(ids, userInfo);
// 7. 循环推荐的数据列表,构建vo对象
List<TodayBest> list = new ArrayList<>();
for (RecommendUser item : items) {
UserInfo info = map.get(item.getUserId());
if(info != null) {
TodayBest vo = TodayBest.init(info, item);
list.add(vo);
}
}
// 6. 构造返回值
pr.setItems(list);
return pr;
}
// 查看佳人详情
public TodayBest personalInfo(Long userId) {
// 1. 根据用户id,查询用户详情
UserInfo userInfo = userInfoApi.findById(userId);
// 2. 根据操作人id, 和查看的用户id,查询两者的推荐数据(缘分值)
RecommendUser user = recommendUserApi.queryByUserId(userId, UserHolder.getUserId());
// 3. 构造返回值
return TodayBest.init(userInfo, user);
}
// 查看陌生人问题
public String strangerQuestions(Long userId) {
Question question = questionApi.findByUserId(userId);
return question == null ? "你喜欢吃青椒吗?" : question.getTxt();
}
// 回复陌生人问题
public void replyQuestions(Long userId, String reply) {
// 1. 构造消息数据
Long currentUserId = UserHolder.getUserId();
UserInfo userInfo = userInfoApi.findById(currentUserId);
Map map = new HashMap<>();
map.put("userId", currentUserId);
map.put("huanXinId", Constants.HX_USER_PREFIX + currentUserId);
map.put("nickname", userInfo.getNickname());
map.put("strangerQuestion", strangerQuestions(userId));
map.put("reply", reply);
String message = JSON.toJSONString(map);
// 2. 调用template对象,发送消息
Boolean aBoolean = huanXinTemplate.sendMsg(Constants.HX_USER_PREFIX + userId, message);
// 3. 异常处理
if (!aBoolean) {
throw new BusinessException(ErrorResult.error());
}
}
// 探花 - 推荐用户列表
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;
}
// 探花 - 喜欢
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);
}
}
// 公共方法 - 判断 id 是否在集合当中
public Boolean isLike(Long userId, Long likeUserId) {
String key = Constants.USER_LIKE_KEY + userId;
return redisTemplate.opsForSet().isMember(key, likeUserId.toString());
}
}
新建 tanhua-dubbo/tanhua-dubbo-interface/src/main/java/com/tanhua/dubbo/api/UserLikeApi.java
文件:
public interface UserLikeApi {
// 保存或者更新
Boolean saveOrUpdate(Long userId, Long likeUserId, boolean isLike);
}
编辑 tanhua-dubbo/tanhua-dubbo-mongo/src/main/java/com/tanhua/dubbo/api/UserLikeApiImpl.java
文件:
@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("update", System.currentTimeMillis());
mongoTemplate.updateFirst(query, update, UserLike.class);
}
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
}
编辑 tanhua-app-server/src/main/java/com/tanhua/server/controller/TanhuaController.java
文件:
@RestController
@RequestMapping("/tanhua")
public class TanhuaController {
@Autowired
private TanhuaService tanhuaService;
/**
* 今日佳人
*/
@GetMapping("/todayBest")
public ResponseEntity todayBest() {
TodayBest vo = tanhuaService.todayBest();
return ResponseEntity.ok(vo);
}
/**
* 查询分页推荐好友列表
*/
@GetMapping("recommendation")
public ResponseEntity recommendation(RecommendUserDto dto) {
PageResult pr = tanhuaService.recommendation(dto);
return ResponseEntity.ok(pr);
}
/**
* 查看佳人详情
*/
@GetMapping("/{id}/personalInfo")
public ResponseEntity personalInfo(@PathVariable("id") Long userId) {
TodayBest best = tanhuaService.personalInfo(userId);
return ResponseEntity.ok(best);
}
/**
* 查看陌生人问题
*/
@GetMapping("/strangerQuestions")
public ResponseEntity strangerQuestions(Long userId) {
String questions = tanhuaService.strangerQuestions(userId);
return ResponseEntity.ok(questions);
}
/**
* 回复陌生人问题
*/
@PostMapping("/strangerQuestions")
public ResponseEntity replyQuestions(@RequestBody Map map) {
// 前端传递的userId是 Integer类型
String obj = map.get("userId").toString();
Long userId = Long.valueOf(obj);
String reply = map.get("reply").toString();
tanhuaService.replyQuestions(userId, reply);
return ResponseEntity.ok(null);
}
/**
* 探花 - 推荐用户列表
*/
@GetMapping("cards")
public ResponseEntity queryCardsList() {
List<TodayBest> list = this.tanhuaService.queryCardsList();
return ResponseEntity.ok(list);
}
/**
* 探花 - 喜欢
*/
@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);
}
}
编辑 tanhua-app-server/src/main/java/com/tanhua/server/service/TanhuaService.java
文件:
@Service
public class TanhuaService {
@DubboReference
private RecommendUserApi recommendUserApi;
@DubboReference
private UserInfoApi userInfoApi;
@DubboReference
private QuestionApi questionApi;
@Autowired
private HuanXinTemplate huanXinTemplate;
@DubboReference
private UserLikeApi userLikeApi;
@Autowired
private RedisTemplate<String, String> redisTemplate;
@Autowired
private MessagesService messagesService;
@Value("${tanhua.default.recommend.users}")
private String recommendUser;
// 查询今日佳人数据
public TodayBest todayBest() {
// 1. 获取用户id
Long userId = UserHolder.getUserId();
// 2. 调用api查询
RecommendUser recommendUser = recommendUserApi.queryWithMaxScore(userId);
// 3. 设置默认值
if(recommendUser == null) {
recommendUser = new RecommendUser();
recommendUser.setUserId(1l);
recommendUser.setScore(99d);
}
// 4. 将recommendUser 转化成 todayBest对象
UserInfo userInfo = userInfoApi.findById(recommendUser.getUserId());
TodayBest vo = TodayBest.init(userInfo, recommendUser);
// 5. 返回
return vo;
}
// 查询分页推荐好友列表
public PageResult recommendation(RecommendUserDto dto) {
// 1. 获取用户id
Long userId = UserHolder.getUserId();
// 2. 调用RecommendUserApi查询数据列表(PageResult -- RecommendUser)
PageResult pr = recommendUserApi.queryRecommendUserList(dto.getPage(), dto.getPagesize(), userId);
// 3. 获取分页中的RecommendUser数据列表
List<RecommendUser> items = (List<RecommendUser>) pr.getItems();
// 4. 判断列表数据是否为空
if (items == null) {
return pr;
}
// // 5. 循环RecommendUser推荐列表,根据推荐的用户id查询用户详情
// List list = new ArrayList<>();
// for (RecommendUser item : items) {
// Long recommendUserId = item.getUserId();
// UserInfo userInfo = userInfoApi.findById(recommendUserId);
// if(userInfo != null) {
// // 条件判断
// if(!StringUtils.isEmpty(dto.getGender()) && !dto.getGender().equals(userInfo.getGender())) {
// continue;
// }
// if (dto.getAge() != null && dto.getAge() < userInfo.getAge()) {
// continue;
// }
// TodayBest vo = TodayBest.init(userInfo, item);
// list.add(vo);
// }
// }
//
// 5. 提取所有推荐的用户id列表
List<Long> ids = CollUtil.getFieldValues(items, "userId", Long.class);
UserInfo userInfo = new UserInfo();
userInfo.setAge(dto.getAge());
userInfo.setGender(dto.getGender());
// 6. 构建查询条件,批量查询所有的用户详情
Map<Long, UserInfo> map = userInfoApi.findByIds(ids, userInfo);
// 7. 循环推荐的数据列表,构建vo对象
List<TodayBest> list = new ArrayList<>();
for (RecommendUser item : items) {
UserInfo info = map.get(item.getUserId());
if(info != null) {
TodayBest vo = TodayBest.init(info, item);
list.add(vo);
}
}
// 6. 构造返回值
pr.setItems(list);
return pr;
}
// 查看佳人详情
public TodayBest personalInfo(Long userId) {
// 1. 根据用户id,查询用户详情
UserInfo userInfo = userInfoApi.findById(userId);
// 2. 根据操作人id, 和查看的用户id,查询两者的推荐数据(缘分值)
RecommendUser user = recommendUserApi.queryByUserId(userId, UserHolder.getUserId());
// 3. 构造返回值
return TodayBest.init(userInfo, user);
}
// 查看陌生人问题
public String strangerQuestions(Long userId) {
Question question = questionApi.findByUserId(userId);
return question == null ? "你喜欢吃青椒吗?" : question.getTxt();
}
// 回复陌生人问题
public void replyQuestions(Long userId, String reply) {
// 1. 构造消息数据
Long currentUserId = UserHolder.getUserId();
UserInfo userInfo = userInfoApi.findById(currentUserId);
Map map = new HashMap<>();
map.put("userId", currentUserId);
map.put("huanXinId", Constants.HX_USER_PREFIX + currentUserId);
map.put("nickname", userInfo.getNickname());
map.put("strangerQuestion", strangerQuestions(userId));
map.put("reply", reply);
String message = JSON.toJSONString(map);
// 2. 调用template对象,发送消息
Boolean aBoolean = huanXinTemplate.sendMsg(Constants.HX_USER_PREFIX + userId, message);
// 3. 异常处理
if (!aBoolean) {
throw new BusinessException(ErrorResult.error());
}
}
// 探花 - 推荐用户列表
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;
}
// 探花 - 喜欢
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);
}
}
// 公共方法 - 判断 id 是否在集合当中
public Boolean isLike(Long userId, Long likeUserId) {
String key = Constants.USER_LIKE_KEY + userId;
return redisTemplate.opsForSet().isMember(key, likeUserId.toString());
}
// 探花 - 不喜欢
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. 判断是否双向不喜欢(删除双向好友)
}
}
随着互联网5G网络的发展, 定位技术越来越精确,地理位置的服务(Location Based Services,LBS)已经渗透到各个软件应用中。如网约车平台,外卖,社交软件,物流等
Gitee仓库地址: https://gitee.com/yuan0_0/tanhua_lbs_demo.git
百度地图开发平台: https://lbsyun.baidu.com/jsdemo.htm#localSearchKeyCircle
新建 tanhua-model/src/main/java/com/tanhua/model/mongo/UserLocation.java
文件:
@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-dubbo/tanhua-dubbo-interface/src/main/java/com/tanhua/dubbo/api/UserLocationApi.java
文件:
public interface UserLocationApi {
}
新建 tanhua-dubbo/tanhua-dubbo-mongo/src/main/java/com/tanhua/dubbo/api/UserLocationApiImpl.java
文件:
@DubboService
public class UserLocationApiImpl implements UserLocationApi{
@Autowired
private MongoTemplate mongoTemplate;
}
新建 tanhua-app-server/src/main/java/com/tanhua/server/controller/BaiduController.java
文件:
@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);
}
}
新建 tanhua-app-server/src/main/java/com/tanhua/server/service/BaiduService.java
文件:
@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/tanhua-dubbo-interface/src/main/java/com/tanhua/dubbo/api/UserLocationApi.java
文件:
public interface UserLocationApi {
// 更新地理位置
Boolean updateLocation(Long userId, Double longitude, Double latitude, String address);
}
编辑 tanhua-dubbo/tanhua-dubbo-mongo/src/main/java/com/tanhua/dubbo/api/UserLocationApiImpl.java
文件:
@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);
// 2. 判断是否存在地址位置信息
if(location == null) {
// 3. 如果不存在, 保存
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 {
// 4. 如果存在, 更新
Update update = Update.update("location", new GeoJsonPoint(longitude, latitude))
.set("update", System.currentTimeMillis())
.set("lastUpdated", location.getUpdated());
mongoTemplate.updateFirst(query, update, UserLocation.class);
}
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
}
新建 tanhua-model/src/main/java/com/tanhua/model/vo/NearUserVo.java
文件:
//附近的人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/src/main/java/com/tanhua/server/controller/TanhuaController.java
文件:
@RestController
@RequestMapping("/tanhua")
public class TanhuaController {
@Autowired
private TanhuaService tanhuaService;
/**
* 今日佳人
*/
@GetMapping("/todayBest")
public ResponseEntity todayBest() {
TodayBest vo = tanhuaService.todayBest();
return ResponseEntity.ok(vo);
}
/**
* 查询分页推荐好友列表
*/
@GetMapping("recommendation")
public ResponseEntity recommendation(RecommendUserDto dto) {
PageResult pr = tanhuaService.recommendation(dto);
return ResponseEntity.ok(pr);
}
/**
* 查看佳人详情
*/
@GetMapping("/{id}/personalInfo")
public ResponseEntity personalInfo(@PathVariable("id") Long userId) {
TodayBest best = tanhuaService.personalInfo(userId);
return ResponseEntity.ok(best);
}
/**
* 查看陌生人问题
*/
@GetMapping("/strangerQuestions")
public ResponseEntity strangerQuestions(Long userId) {
String questions = tanhuaService.strangerQuestions(userId);
return ResponseEntity.ok(questions);
}
/**
* 回复陌生人问题
*/
@PostMapping("/strangerQuestions")
public ResponseEntity replyQuestions(@RequestBody Map map) {
// 前端传递的userId是 Integer类型
String obj = map.get("userId").toString();
Long userId = Long.valueOf(obj);
String reply = map.get("reply").toString();
tanhuaService.replyQuestions(userId, reply);
return ResponseEntity.ok(null);
}
/**
* 探花 - 推荐用户列表
*/
@GetMapping("cards")
public ResponseEntity queryCardsList() {
List<TodayBest> list = this.tanhuaService.queryCardsList();
return ResponseEntity.ok(list);
}
/**
* 探花 - 喜欢
*/
@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);
}
/**
* 搜附近
*/
@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);
}
}
编辑 tanhua-app-server/src/main/java/com/tanhua/server/service/TanhuaService.java
文件:
@Service
public class TanhuaService {
@DubboReference
private RecommendUserApi recommendUserApi;
@DubboReference
private UserInfoApi userInfoApi;
@DubboReference
private QuestionApi questionApi;
@Autowired
private HuanXinTemplate huanXinTemplate;
@DubboReference
private UserLikeApi userLikeApi;
@Autowired
private RedisTemplate<String, String> redisTemplate;
@Autowired
private MessagesService messagesService;
@DubboReference
private UserLocationApi userLocationApi;
@Value("${tanhua.default.recommend.users}")
private String recommendUser;
// 查询今日佳人数据
public TodayBest todayBest() {
// 1. 获取用户id
Long userId = UserHolder.getUserId();
// 2. 调用api查询
RecommendUser recommendUser = recommendUserApi.queryWithMaxScore(userId);
// 3. 设置默认值
if(recommendUser == null) {
recommendUser = new RecommendUser();
recommendUser.setUserId(1l);
recommendUser.setScore(99d);
}
// 4. 将recommendUser 转化成 todayBest对象
UserInfo userInfo = userInfoApi.findById(recommendUser.getUserId());
TodayBest vo = TodayBest.init(userInfo, recommendUser);
// 5. 返回
return vo;
}
// 查询分页推荐好友列表
public PageResult recommendation(RecommendUserDto dto) {
// 1. 获取用户id
Long userId = UserHolder.getUserId();
// 2. 调用RecommendUserApi查询数据列表(PageResult -- RecommendUser)
PageResult pr = recommendUserApi.queryRecommendUserList(dto.getPage(), dto.getPagesize(), userId);
// 3. 获取分页中的RecommendUser数据列表
List<RecommendUser> items = (List<RecommendUser>) pr.getItems();
// 4. 判断列表数据是否为空
if (items == null) {
return pr;
}
// // 5. 循环RecommendUser推荐列表,根据推荐的用户id查询用户详情
// List list = new ArrayList<>();
// for (RecommendUser item : items) {
// Long recommendUserId = item.getUserId();
// UserInfo userInfo = userInfoApi.findById(recommendUserId);
// if(userInfo != null) {
// // 条件判断
// if(!StringUtils.isEmpty(dto.getGender()) && !dto.getGender().equals(userInfo.getGender())) {
// continue;
// }
// if (dto.getAge() != null && dto.getAge() < userInfo.getAge()) {
// continue;
// }
// TodayBest vo = TodayBest.init(userInfo, item);
// list.add(vo);
// }
// }
//
// 5. 提取所有推荐的用户id列表
List<Long> ids = CollUtil.getFieldValues(items, "userId", Long.class);
UserInfo userInfo = new UserInfo();
userInfo.setAge(dto.getAge());
userInfo.setGender(dto.getGender());
// 6. 构建查询条件,批量查询所有的用户详情
Map<Long, UserInfo> map = userInfoApi.findByIds(ids, userInfo);
// 7. 循环推荐的数据列表,构建vo对象
List<TodayBest> list = new ArrayList<>();
for (RecommendUser item : items) {
UserInfo info = map.get(item.getUserId());
if(info != null) {
TodayBest vo = TodayBest.init(info, item);
list.add(vo);
}
}
// 6. 构造返回值
pr.setItems(list);
return pr;
}
// 查看佳人详情
public TodayBest personalInfo(Long userId) {
// 1. 根据用户id,查询用户详情
UserInfo userInfo = userInfoApi.findById(userId);
// 2. 根据操作人id, 和查看的用户id,查询两者的推荐数据(缘分值)
RecommendUser user = recommendUserApi.queryByUserId(userId, UserHolder.getUserId());
// 3. 构造返回值
return TodayBest.init(userInfo, user);
}
// 查看陌生人问题
public String strangerQuestions(Long userId) {
Question question = questionApi.findByUserId(userId);
return question == null ? "你喜欢吃青椒吗?" : question.getTxt();
}
// 回复陌生人问题
public void replyQuestions(Long userId, String reply) {
// 1. 构造消息数据
Long currentUserId = UserHolder.getUserId();
UserInfo userInfo = userInfoApi.findById(currentUserId);
Map map = new HashMap<>();
map.put("userId", currentUserId);
map.put("huanXinId", Constants.HX_USER_PREFIX + currentUserId);
map.put("nickname", userInfo.getNickname());
map.put("strangerQuestion", strangerQuestions(userId));
map.put("reply", reply);
String message = JSON.toJSONString(map);
// 2. 调用template对象,发送消息
Boolean aBoolean = huanXinTemplate.sendMsg(Constants.HX_USER_PREFIX + userId, message);
// 3. 异常处理
if (!aBoolean) {
throw new BusinessException(ErrorResult.error());
}
}
// 探花 - 推荐用户列表
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;
}
// 探花 - 喜欢
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);
}
}
// 公共方法 - 判断 id 是否在集合当中
public Boolean isLike(Long userId, Long likeUserId) {
String key = Constants.USER_LIKE_KEY + userId;
return redisTemplate.opsForSet().isMember(key, likeUserId.toString());
}
// 探花 - 不喜欢
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 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/tanhua-dubbo-interface/src/main/java/com/tanhua/dubbo/api/UserLocationApi.java
文件:
public interface UserLocationApi {
// 更新地理位置
Boolean updateLocation(Long userId, Double longitude, Double latitude, String address);
// 查询附近的人所有的用户id
List<Long> queryNearUser(Long userId, Double metre);
}
编辑 tanhua-dubbo/tanhua-dubbo-mongo/src/main/java/com/tanhua/dubbo/api/UserLocationApiImpl.java
文件:
@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);
// 2. 判断是否存在地址位置信息
if(location == null) {
// 3. 如果不存在, 保存
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 {
// 4. 如果存在, 更新
Update update = Update.update("location", new GeoJsonPoint(longitude, latitude))
.set("update", System.currentTimeMillis())
.set("lastUpdated", location.getUpdated());
mongoTemplate.updateFirst(query, update, UserLocation.class);
}
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
// 查询附近的人所有的用户id
@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);
}
}
新增 tanhua-app-server/src/test/java/com/tanhua/test/TestUserLocationApi.java
文件:
@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, "天津大学(卫津路校区)");
}
}