访客功能
一、需求分析
用户在浏览我的主页时,需要记录访客数据,访客在一天内每个用户只记录一次。
首页展示最新5条访客记录
我的模块,分页展示所有的访客记录
二、数据库表
visitors(访客记录表)
{
“_id”: ObjectId(“636334b470603e72be5dbc8d”),
“userId”: NumberLong(“1”),
“visitorUserId”: NumberLong(“1”),
“from”: “首页”,
“date”: NumberLong(“1667445940900”),
“visitDate”: “20221103”,
“score”: 99,
“_class”: “com.tanhua.model.mongo.Visitors”
}
三,保存访客记录
用户在浏览我的主页时,需要记录访客数据
访客在一天内每个用户只记录一次。
思路:1.修改查看佳人详情接口
2.构造访问信息,调用API保存访客数据
代码实现,在查看佳人详情时,保存一条我的访问记录
/**
* 根据id查看佳人详情
* 这个userId是当前用户要查看的用户的id
*/
public TodayBest queryToBestInfo(Long userId) {
//当前用户id
Long currentUserId = ThreadLocalUtils.getUserId();
//1.根据用户id查询用户详情
UserInfo userInfo = userInfoApi.selectUserInfo(userId);
//2.根据当前用户的id,和当前用户要查看的用户id查询推荐人
RecommendUser recommendUser = recommendUserApi.queryRecommendFriend(userId,currentUserId);
//3.在查看用户详情页面的同时,保存一条当前用户的访问记录到visitor数据库表
Visitors visitors = new Visitors();
visitors.setUserId(userId);
//当前用户未访客
visitors.setVisitorUserId(currentUserId);
visitors.setFrom("首页");
visitors.setDate(System.currentTimeMillis());
visitors.setVisitDate(new SimpleDateFormat("yyyyMMdd").format(new Date()));
visitors.setScore(recommendUser.getScore());
visitorsApi.saveVisitors(visitors);
//构造返回值
TodayBest todayBest = TodayBest.init(userInfo, recommendUser);
return todayBest;
}
VisitorApiImpl
@Autowired
private MongoTemplate mongoTemplate;
/**
*
* 保存访客记录,
* 同一个用户一天只能保存一次访客记录
*/
public void saveVisitors(Visitors visitors) {
//1.根据UserId和visitorUserId还有visitDate查询visitors表
Criteria criteria = Criteria.where("userId").is(visitors.getUserId())
.and("visitorUserId").is(visitors.getVisitorUserId())
.and("visitDate").is(visitors.getVisitDate());
Query query = Query.query(criteria);
if(!mongoTemplate.exists(query, Visitors.class)){
mongoTemplate.save(visitors);
}
}
四、访客列表
vo对象
package com.tanhua.model.vo;
import com.tanhua.model.domain.UserInfo;
import com.tanhua.model.mongo.Visitors;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.springframework.beans.BeanUtils;
@Data
@NoArgsConstructor
@AllArgsConstructor
public class VisitorsVo {
private Long id; //用户id
private String avatar;
private String nickname;
private String gender; //性别 man woman
private Integer age;
private String[] tags;
private Long fateValue; //缘分值
/**
* 在vo对象中,补充一个工具方法,封装转化过程
*/
public static VisitorsVo init(UserInfo userInfo, Visitors visitors) {
VisitorsVo vo = new VisitorsVo();
BeanUtils.copyProperties(userInfo,vo);
if(userInfo.getTags() != null) {
vo.setTags(userInfo.getTags().split(","));
}
vo.setFateValue(visitors.getScore().longValue());
return vo;
}
}
UsersController
/**
* 查询全部访客记录
* 请求路径:/users/friends/:type
* 请求方式:get
* 请求参数:路径参数:type;
* page(当前页码),
* pagesize(每页展示数),
* nickname(昵称)
* 响应数据:VisitorsVo
*/
@GetMapping("/friends/{type}")
public ResponseEntity queryVisitors(@PathVariable("type") Integer type,
@RequestParam(defaultValue = "1") Integer page,
@RequestParam(defaultValue = "10") Integer pagesize,
@RequestParam(required = false) String nickname){
PageResult pageResult = service.queryVisitors(page,pagesize,nickname);
return ResponseEntity.ok(pageResult);
}
UsersService
/**
*查看所有访客记录
*/
public PageResult queryVisitors(Integer page, Integer pagesize, String nickname) {
//1调用api查询所有访客
Long currentUserId = ThreadLocalUtils.getUserId();
List<Visitors> visitors = visitorsApi.queryVisitors(currentUserId,page,pagesize);
//2.判断有无访客记录
if(CollUtil.isEmpty(visitors)){
return new PageResult();
}
//3.把查询全部的访客这次时间记录缓存进redis
String key = Constants.VISITORS;
String hashKey =String.valueOf(ThreadLocalUtils.getUserId());
String timeMillis = String.valueOf(System.currentTimeMillis());
redisTemplate.opsForHash().put(key, hashKey, timeMillis);
//4.先获取全部访客的id,再根据id查询他们的用户详情
List<Long> visitorUserIds = CollUtil.getFieldValues(visitors, "visitorUserId", Long.class);
UserInfo info = new UserInfo();
info.setNickname(nickname);
Map<Long, UserInfo> userInfoMap = userInfoApi.batchQueryUserInfo(visitorUserIds, info);
//5.遍历所有访客集合,构造vo对象
List<VisitorsVo> vos = new ArrayList<>();
for (Visitors visitor : visitors) {
Long userId = visitor.getVisitorUserId();
UserInfo userInfo = userInfoMap.get(userId);
if(userInfo != null){
VisitorsVo vo = VisitorsVo.init(userInfo, visitor);
vos.add(vo);
}
}
//6.构造返回值
PageResult pageResult = new PageResult(page,pagesize,0,vos);
return pageResult;
}
VisitorApiImpl
/**
* 查看所有访客记录
* @param currentUserId
* @param page
* @param pagesize
* @return
*/
public List<Visitors> queryVisitors(Long currentUserId, Integer page, Integer pagesize) {
Criteria criteria = Criteria.where("userId").is(currentUserId);
Query query = Query.query(criteria);
query.skip((page - 1 ) * pagesize ).limit(pagesize).with(Sort.by(Sort.Order.desc("date")));
List<Visitors> visitors = mongoTemplate.find(query, Visitors.class);
return visitors;
}
五,查看首页最新访客数据
业务流程
思路
代码实现,MovementController
/**
* 谁看过我
* 请求路径:/movements/visitors
* 请求方式:get
* 响应数据:VisitorsVo
*/
@GetMapping("visitors")
public ResponseEntity queryVisitorsList(){
List<VisitorsVo> list = movementsService.queryVisitorsList();
return ResponseEntity.ok(list);
}
MovementService
/**
* 首页访客列表
* @return
*/
public List<VisitorsVo> queryVisitorsList() {
//1.从redis缓存中获取查看全部访客列表时间
String key = Constants.VISITORS;
String hashKey = String.valueOf(ThreadLocalUtils.getUserId());
String value = (String) redisTemplate.opsForHash().get(key, hashKey);
//三元运算符
Long date = StringUtils.isEmpty(value) ? null:Long.valueOf(value);
//2.调用api查询访客列表
List<Visitors> visitors = visitorsApi.queryLatestVisitors(date,ThreadLocalUtils.getUserId());
//3.判断访客列表是否为空
if(CollUtil.isEmpty(visitors)){
return new ArrayList<>();
}
//4.提取访客的id,根据id查询用户详情
List<Long> visitorUserIds = CollUtil.getFieldValues(visitors, "visitorUserId", Long.class);
Map<Long, UserInfo> userInfoMap = userInfoApi.batchQueryUserInfo(visitorUserIds, null);
//5.遍历访客列表集合,构造vo
List<VisitorsVo> vos = new ArrayList<>();
for (Visitors visitor : visitors) {
Long visitorUserId = visitor.getVisitorUserId();
UserInfo userInfo = userInfoMap.get(visitorUserId);
if(userInfo != null){
VisitorsVo vo = VisitorsVo.init(userInfo, visitor);
vos.add(vo);
}
}
return vos;
}
VisitorApiImpl
/**
* 查看首页的访客
* @param date
* @param userId
* @return
*/
public List<Visitors> queryLatestVisitors(Long date, Long userId) {
//1.构造条件
Criteria criteria = Criteria.where("userId").is(userId);
//2.判断redis中有没有缓存查看全部访客列表的时间,有则添加条件
if(date != null){
criteria.and("date").gt(date);
}
Query query = Query.query(criteria);
query .limit(5).with(Sort.by(Sort.Order.desc("date")));
List<Visitors> visitors = mongoTemplate.find(query, Visitors.class);
return visitors;
}
//2.判断redis中有没有缓存查看全部访客列表的时间,有则添加条件
if(date != null){
criteria.and("date").gt(date);
}
Query query = Query.query(criteria);
query .limit(5).with(Sort.by(Sort.Order.desc("date")));
List<Visitors> visitors = mongoTemplate.find(query, Visitors.class);
return visitors;
}