Loading... ## 课程说明 - 圈子动态查询 - 圈子实现评论 - 圈子实现点赞、喜欢功能 - 圈子实现评论 ## 1、动态查询 我的动态:查询个人发布的动态列表(分页查询),和之前实现的好友动态,推荐动态实现逻辑是一致。 ### 1.1、查询好友动态 查询好友动态与查询推荐动态显示的结构是一样的,只是其查询数据源不同 #### 1.1.1、接口文档 API接口文档:http://192.168.136.160:3000/project/19/interface/api/142 #### 1.1.2、代码步骤 * Controller层接受请求参数 * Service数据封装 * 调用API查询好友动态详情数据 * 调用API查询动态发布人详情 * 构造VO对象 * API层根据用户ID查询好友发布动态详情 * 查询好友时间线表 * 查询动态详情 #### 1.1.3、代码实现 ##### MovementController ```java /** * 查询好友动态 */ @GetMapping public ResponseEntity movements(@RequestParam(defaultValue = "1") Integer page, @RequestParam(defaultValue = "10") Integer pagesize) { PageResult pr = movementService.findFriendMovements(page,pagesize); return ResponseEntity.ok(pr); } ``` ##### MovementService ```java //好友动态 public PageResult findFriendMovements(Integer page, Integer pagesize) { //1、获取当前用户id Long userId = UserHolder.getUserId(); //2、查询数据列表 List<Movement> items = movementApi.findFriendMovements(userId,page,pagesize); //3、非空判断 if(CollUtil.isEmpty(items)) { return new PageResult(); } //4、获取好友用户id List<Long> userIds = CollUtil.getFieldValues(items, "userId", Long.class); //5、循环数据列表 Map<Long, UserInfo> userMaps = userInfoApi.findByIds(userIds, null); List<MovementsVo> vos = new ArrayList<>(); for (Movement item : items) { //5、一个Movement构建一个Vo对象 UserInfo userInfo = userMaps.get(item.getUserId()); MovementsVo vo = MovementsVo.init(userInfo, item); vos.add(vo); } //6、构建返回值 return new PageResult(page,pagesize,0L,vos); } ``` ##### movementApi ```java @Override public List<Movement> findFriendMovements(Long friendId, Integer page, Integer pagesize) { //1、查询好友时间线表 Query query = Query.query(Criteria.where("friendId").in(friendId)) .skip((page - 1)*pagesize).limit(pagesize) .with(Sort.by(Sort.Order.desc("created"))); List<MovementTimeLine> lines = mongoTemplate.find(query, MovementTimeLine.class); //2、提取动态id集合 List<ObjectId> movementIds = CollUtil.getFieldValues(lines, "movementId", ObjectId.class); //3、根据动态id查询动态详情 Query movementQuery = Query.query(Criteria.where("id").in(movementIds)); return mongoTemplate.find(movementQuery, Movement.class); } ``` ### 1.2、查询推荐动态 推荐动态是通过推荐系统计算出的结果,现在我们只需要实现查询即可,推荐系统在后面的课程中完成。 推荐系统计算完成后,会将结果数据写入到Redis中,数据如下: ~~~shell 192.168.31.81:6379> get MOVEMENTS_RECOMMEND_1 "2562,3639,2063,3448,2128,2597,2893,2333,3330,2642,2541,3002,3561,3649,2384,2504,3397,2843,2341,2249" ~~~ 可以看到,在Redis中的数据是有多个发布id组成(pid)由逗号分隔。所以实现中需要自己对这些数据做分页处理。 #### 1.2.1、接口文档 API接口文档:http://192.168.136.160:3000/project/19/interface/api/145 #### 1.2.2、代码步骤 * Controller层接受请求参数 * Service数据封装 * 从redis获取当前用户的推荐PID列表 * 如果不存在,调用API随机获取10条动态数据 * 如果存在,调用API根据PID列表查询动态数据 * 构造VO对象 * API层编写方法 * 随机获取 * 根据pid列表查询 #### 1.2.3、代码实现 ##### Constants ```java package com.tanhua.commons.utils; //常量定义 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; } ``` ##### MovementController ```java /** * 推荐动态 */ @GetMapping("/recommend") public ResponseEntity recommend(@RequestParam(defaultValue = "1") Integer page, @RequestParam(defaultValue = "10") Integer pagesize) { PageResult pr = movementService.findRecommendMovements(page,pagesize); return ResponseEntity.ok(pr); } ``` ##### MovementService ```java //推荐动态 public PageResult findRecommendMovements(Integer page, Integer pagesize) { String redisKey = "MOVEMENTS_RECOMMEND_" + UserHolder.getUserId(); String redisData = this.redisTemplate.opsForValue().get(redisKey); List<Movement> list = Collections.EMPTY_LIST; if(StringUtils.isEmpty(redisData)){ list = movementApi.randomMovements(pagesize); }else { String[] split = redisData.split(","); if ((page-1) * pagesize > split.length) { return new PageResult(); } List<Long> pids = Arrays.stream(split) .skip((page - 1) * pagesize) .limit(pagesize) .map(e -> Convert.toLong(e)) .collect(Collectors.toList()); list = movementApi.findByPids(pids); } List<Long> userIds = CollUtil.getFieldValues(list, "userId", Long.class); //5、循环数据列表 Map<Long, UserInfo> userMaps = userInfoApi.findByIds(userIds, null); List<MovementsVo> vos = new ArrayList<>(); for (Movement item : list) { //5、一个Movement构建一个Vo对象 UserInfo userInfo = userMaps.get(item.getUserId()); MovementsVo vo = MovementsVo.init(userInfo, item); vos.add(vo); } //6、构建返回值 return new PageResult(page,pagesize,0L,vos); } ``` ##### movementApi ```java //随机获取 public List<Movement> randomMovements(Integer counts) { TypedAggregation aggregation = Aggregation.newAggregation(Movement.class, Aggregation.sample(counts)); AggregationResults<Movement> movements = mongoTemplate.aggregate(aggregation,Movement.class); return movements.getMappedResults(); } //根据PID查询 public List<Movement> findByPids(List<Long> pids) { Query query = Query.query(Criteria.where("pId").in(pids)); return mongoTemplate.find(query, Movement.class); } ``` ### 1.3、根据id查询动态 根据id查询动态:当手机端查看评论内容时(需要根据动态id,查询动态详情),后续再去查询评论列表 #### 1.3.1、接口文档 API接口文档:http://192.168.136.160:3000/project/19/interface/api/151 #### 1.3.2、代码实现 ##### MovementController ```java /** * 根据id查询动态 */ @GetMapping("/{id}") public ResponseEntity findById(@PathVariable("id") String movementId) { MovementsVo vo = movementService.findMovementById(movementId); return ResponseEntity.ok(vo); } ``` ##### MovementService ```java public MovementsVo findMovementById(String movementId) { Movement movements = movementApi.findById(movementId); if(movements == null) { return null; }else { UserInfo userInfo = userInfoApi.findById(movements.getUserId()); return MovementsVo.init(userInfo,movements); } } ``` ##### movementApi ```java @Override public Movement findById(String movementId) { return mongoTemplate.findById(movementId,Movement.class); } ``` ## 2、圈子互动 点赞、喜欢、评论等均可理解为用户对动态的互动。 数据库表:`quanzi_comment` ```shell 将数据记录到表中:保存到MongoDB中 互动表需要几张:需要一张表即可(quanzi_comment) 里面的数据需要分类:通过字段commentType 1-点赞,2-评论,3-喜欢 { "_id" : ObjectId("5fe7f9263c851428107cd4e8"), "publishId" : ObjectId("5fae53947e52992e78a3afa5"), "commentType" : 1, "userId" : NumberLong(1), "publishUserId" : NumberLong(1), "created" : NumberLong(1609038118275), "likeCount" : 0, "_class" : "com.tanhua.domain.mongo.Comment" } ``` 数据存储位置:**redis**,**mongodb** **mongodb中的数据** * **在动态详情Movement表中,加入喜欢,点赞,评论数量:检查数据库访问压力** * 互动操作的时候,不要忘记对上面的字段进行维护 * **圈子互动的表 comment** * 互动完成(点赞,喜欢):不仅要将数据保存到mongo中,需要记录到redis中 * 页面查询圈子列表时,可以从redis中判断是否有点赞,和喜欢历史 ### 2.1、环境搭建 #### 2.1.1 创建API接口 ```java public interface CommentApi { } ``` #### 2.1.2 创建API实现类 ```java @DubboService public class CommentApiImpl implements CommentApi { @Autowired private MongoTemplate mongoTemplate; } ``` #### 2.1.3 Movement对象 ```java @Data @NoArgsConstructor @AllArgsConstructor @Document(collection = "movement") public class Movement implements java.io.Serializable { private ObjectId id; //主键id //redis实现,使用Mongodb实现 private Long pid; //Long类型,用于推荐系统的模型(自动增长) private Long created; //发布时间 private Long userId; private String textContent; //文字 private List<String> medias; //媒体数据,图片或小视频 url private String longitude; //经度 private String latitude; //纬度 private String locationName; //位置名称 private Integer state = 0;//状态 0:未审(默认),1:通过,2:驳回 //补充字段 private Integer likeCount = 0; //点赞数 private Integer commentCount = 0; //评论数 private Integer loveCount = 0; //喜欢数 //根据评论类型,获取对应的互动数量 public Integer statisCount(Integer commentType) { if (commentType == CommentType.LIKE.getType()) { return this.likeCount; } else if (commentType == CommentType.COMMENT.getType()) { return this.commentCount; } else { return loveCount; } } } ``` #### 2.1.4 实体类对象 ```java package com.tanhua.domain.mongo; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; import org.bson.types.ObjectId; import org.springframework.data.mongodb.core.mapping.Document; /** * 圈子互动表(点赞,评论,喜欢) */ @Data @NoArgsConstructor @AllArgsConstructor @Document(collection = "comment") public class Comment implements java.io.Serializable{ private ObjectId id; private ObjectId publishId; //发布id private Integer commentType; //评论类型,1-点赞,2-评论,3-喜欢 private String content; //评论内容 private Long userId; //评论人 private Long publishUserId; //被评论人ID private Long created; //发表时间 private Integer likeCount = 0; //当前评论的点赞数 } ``` #### 2.1.5 VO对象 ```java @Data @NoArgsConstructor @AllArgsConstructor public class CommentVo implements Serializable { private String id; //评论id private String avatar; //头像 private String nickname; //昵称 private String content; //评论 private String createDate; //评论时间 private Integer likeCount; //点赞数 private Integer hasLiked; //是否点赞(1是,0否) public static CommentVo init(UserInfo userInfo, Comment item) { CommentVo vo = new CommentVo(); BeanUtils.copyProperties(userInfo, vo); BeanUtils.copyProperties(item, vo); vo.setHasLiked(0); Date date = new Date(item.getCreated()); vo.setCreateDate(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(date)); vo.setId(item.getId().toHexString()); return vo; } } ``` #### 2.1.6 CommentType枚举 ```java /** * 评论类型:1-点赞,2-评论,3-喜欢 */ public enum CommentType { LIKE(1), COMMENT(2), LOVE(3); int type; CommentType(int type) { this.type = type; } public int getType() { return type; } } ``` ### 2.2、动态评论 功能包括:查询评论列表,发布评论,对评论点赞和取消点赞。 #### 2.2.1 分页列表查询 ##### CommentController ```java //分页查询评理列表 @GetMapping public ResponseEntity findComments(@RequestParam(defaultValue = "1") Integer page, @RequestParam(defaultValue = "10") Integer pagesize, String movementId) { PageResult pr = commentsService.findComments(movementId,page,pagesize); return ResponseEntity.ok(pr); } ``` ##### CommentService ```java //分页查询评理列表 public PageResult findComments(String movementId, Integer page, Integer pagesize) { //1、调用API查询评论列表 List<Comment> list = commentApi.findComments(movementId,CommentType.COMMENT,page,pagesize); //2、判断list集合是否存在 if(CollUtil.isEmpty(list)) { return new PageResult(); } //3、提取所有的用户id,调用UserInfoAPI查询用户详情 List<Long> userIds = CollUtil.getFieldValues(list, "userId", Long.class); Map<Long, UserInfo> map = userInfoApi.findByIds(userIds, null); //4、构造vo对象 List<CommentVo> vos = new ArrayList<>(); for (Comment comment : list) { UserInfo userInfo = map.get(comment.getUserId()); if(userInfo != null) { CommentVo vo = CommentVo.init(userInfo, comment); vos.add(vo); } } //5、构造返回值 return new PageResult(page,pagesize,0l,vos); } ``` ##### CommentAPI ```java //分页查询 public List<Comment> findComments(String movementId, CommentType commentType, Integer page, Integer pagesize) { //1、构造查询条件 Query query = Query.query(Criteria.where("publishId").is(new ObjectId(movementId)).and("commentType") .is(commentType.getType())) .skip((page -1) * pagesize) .limit(pagesize) .with(Sort.by(Sort.Order.desc("created"))); //2、查询并返回 return mongoTemplate.find(query,Comment.class); } ``` #### 2.2.2 发布评论 ##### CommentController ```java @RestController @RequestMapping("/comments") public class CommentsController { @Autowired private CommentsService commentsService; /** * 发布评论 */ @PostMapping public ResponseEntity saveComments(@RequestBody Map map) { String movementId = (String )map.get("movementId"); String comment = (String)map.get("comment"); commentsService.saveComments(movementId,comment); return ResponseEntity.ok(null); } } ``` ##### CommentService ```java @Service @Slf4j public class CommentsService { @DubboReference private CommentApi commentApi; //发布评论 public void saveComments(String movementId, String comment) { //1、获取操作用户id Long userId = UserHolder.getUserId(); //2、构造Comment Comment comment1 = new Comment(); comment1.setPublishId(new ObjectId(movementId)); comment1.setCommentType(CommentType.COMMENT.getType()); comment1.setContent(comment); comment1.setUserId(userId); comment1.setCreated(System.currentTimeMillis()); //3、调用API保存评论 Integer commentCount = commentApi.save(comment1); log.info("commentCount = " + commentCount); } } ``` ##### CommentAPI ```java //发布评论,并获取评论数量 public Integer save(Comment comment) { //1、查询动态 Movement movement = mongoTemplate.findById(comment.getPublishId(), Movement.class); //2、向comment对象设置被评论人属性 if(movement != null) { comment.setPublishUserId(movement.getUserId()); } //3、保存到数据库 mongoTemplate.save(comment); //4、更新动态表中的对应字段 Query query = Query.query(Criteria.where("id").is(comment.getPublishId())); Update update = new Update(); if(comment.getCommentType() == CommentType.LIKE.getType()) { update.inc("likeCount",1); }else if (comment.getCommentType() == CommentType.COMMENT.getType()){ update.inc("commentCount",1); }else { update.inc("loveCount",1); } //设置更新参数 FindAndModifyOptions options = new FindAndModifyOptions(); options.returnNew(true) ;//获取更新后的最新数据 Movement modify = mongoTemplate.findAndModify(query, update, options, Movement.class); //5、获取最新的评论数量,并返回 return modify.statisCount(comment.getCommentType() ); } ``` ##### 测试API代码 ```java @RunWith(SpringRunner.class) @SpringBootTest(classes = AppServerApplication.class) public class CommentApiTest { @DubboReference private CommentApi commentApi; @Test public void testSave() { Comment comment = new Comment(); comment.setCommentType(CommentType.COMMENT.getType()); comment.setUserId(106l); comment.setCreated(System.currentTimeMillis()); comment.setContent("测试评论"); comment.setPublishId(); commentApi.save(comment); } } ``` ### 2.3、点赞 #### 2.3.1、编写Controller 修改`MovementsController`代码,添加点赞与取消点赞方法 ```java /** * 点赞 */ @GetMapping("/{id}/like") public ResponseEntity like(@PathVariable("id") String movementId) { Integer likeCount = commentsService.likeComment(movementId); return ResponseEntity.ok(likeCount); } /** * 取消点赞 */ @GetMapping("/{id}/dislike") public ResponseEntity dislike(@PathVariable("id") String movementId) { Integer likeCount = commentsService.dislikeComment(movementId); return ResponseEntity.ok(likeCount); } ``` #### 2.3.2、编写Service 创建`CommentService`,添加点赞与取消点赞方法 ```java //动态点赞 public Integer likeComment(String movementId) { //1、调用API查询用户是否已点赞 Boolean hasComment = commentApi.hasComment(movementId,UserHolder.getUserId(),CommentType.LIKE); //2、如果已经点赞,抛出异常 if(hasComment) { throw new BusinessException(ErrorResult.likeError()); } //3、调用API保存数据到Mongodb Comment comment = new Comment(); comment.setPublishId(new ObjectId(movementId)); comment.setCommentType(CommentType.LIKE.getType()); comment.setUserId(UserHolder.getUserId()); comment.setCreated(System.currentTimeMillis()); Integer count = commentApi.save(comment); //4、拼接redis的key,将用户的点赞状态存入redis String key = Constants.MOVEMENTS_INTERACT_KEY + movementId; String hashKey = Constants.MOVEMENT_LIKE_HASHKEY + UserHolder.getUserId(); redisTemplate.opsForHash().put(key,hashKey,"1"); return count; } //取消点赞 public Integer dislikeComment(String movementId) { //1、调用API查询用户是否已点赞 Boolean hasComment = commentApi.hasComment(movementId,UserHolder.getUserId(),CommentType.LIKE); //2、如果未点赞,抛出异常 if(!hasComment) { throw new BusinessException(ErrorResult.disLikeError()); } //3、调用API,删除数据,返回点赞数量 Comment comment = new Comment(); comment.setPublishId(new ObjectId(movementId)); comment.setCommentType(CommentType.LIKE.getType()); comment.setUserId(UserHolder.getUserId()); Integer count = commentApi.delete(comment); //4、拼接redis的key,删除点赞状态 String key = Constants.MOVEMENTS_INTERACT_KEY + movementId; String hashKey = Constants.MOVEMENT_LIKE_HASHKEY + UserHolder.getUserId(); redisTemplate.opsForHash().delete(key,hashKey); return count; } ``` #### 2.3.3、修改API服务 ##### 判断Comment数据是否存在 ```java //判断comment数据是否存在 public Boolean hasComment(String movementId, Long userId, CommentType commentType) { Criteria criteria = Criteria.where("userId").is(userId) .and("publishId").is(new ObjectId(movementId)) .and("commentType").is(commentType.getType()); Query query = Query.query(criteria); return mongoTemplate.exists(query,Comment.class); //判断数据是否存在 } ``` ##### 删除互动数据 ```java //删除 public Integer delete(Comment comment) { //1、删除Comment表数据 Criteria criteria = Criteria.where("userId").is(comment.getUserId()) .and("publishId").is(comment.getPublishId()) .and("commentType").is(comment.getCommentType()); Query query = Query.query(criteria); mongoTemplate.remove(query,Comment.class); //2、修改动态表中的总数量 Query movementQuery = Query.query(Criteria.where("id").is(comment.getPublishId())); Update update = new Update(); if(comment.getCommentType() == CommentType.LIKE.getType()) { update.inc("likeCount",-1); }else if (comment.getCommentType() == CommentType.COMMENT.getType()){ update.inc("commentCount",-1); }else { update.inc("loveCount",-1); } //设置更新参数 FindAndModifyOptions options = new FindAndModifyOptions(); options.returnNew(true) ;//获取更新后的最新数据 Movement modify = mongoTemplate.findAndModify(movementQuery, update, options, Movement.class); //5、获取最新的评论数量,并返回 return modify.statisCount(comment.getCommentType() ); } ``` #### 2.3.4、修改查询动态点赞数 修改之前的查询圈子列表代码,从redis查询是否具有操作记录 ### 2.4、喜欢 喜欢和取消喜欢:和刚才的点赞与取消点赞基本上市一模一样的!操作的类型comment_type=3,操作的字段loveCount #### MovementsController 修改`MovementsController`代码,添加喜欢与取消喜欢方法 ```java /** * 喜欢 */ @GetMapping("/{id}/love") public ResponseEntity love(@PathVariable("id") String movementId) { Integer likeCount = commentsService.loveComment(movementId); return ResponseEntity.ok(likeCount); } /** * 取消喜欢 */ @GetMapping("/{id}/unlove") public ResponseEntity unlove(@PathVariable("id") String movementId) { Integer likeCount = commentsService.disloveComment(movementId); return ResponseEntity.ok(likeCount); } ``` #### CommentService 修改`CommentService`,添加点赞与取消点赞方法 ```java //喜欢 public Integer loveComment(String movementId) { //1、调用API查询用户是否已点赞 Boolean hasComment = commentApi.hasComment(movementId,UserHolder.getUserId(),CommentType.LOVE); //2、如果已经喜欢,抛出异常 if(hasComment) { throw new BusinessException(ErrorResult.loveError()); } //3、调用API保存数据到Mongodb Comment comment = new Comment(); comment.setPublishId(new ObjectId(movementId)); comment.setCommentType(CommentType.LOVE.getType()); comment.setUserId(UserHolder.getUserId()); comment.setCreated(System.currentTimeMillis()); Integer count = commentApi.save(comment); //4、拼接redis的key,将用户的点赞状态存入redis String key = Constants.MOVEMENTS_INTERACT_KEY + movementId; String hashKey = Constants.MOVEMENT_LOVE_HASHKEY + UserHolder.getUserId(); redisTemplate.opsForHash().put(key,hashKey,"1"); return count; } //取消喜欢 public Integer disloveComment(String movementId) { //1、调用API查询用户是否已点赞 Boolean hasComment = commentApi.hasComment(movementId,UserHolder.getUserId(),CommentType.LOVE); //2、如果未点赞,抛出异常 if(!hasComment) { throw new BusinessException(ErrorResult.disloveError()); } //3、调用API,删除数据,返回点赞数量 Comment comment = new Comment(); comment.setPublishId(new ObjectId(movementId)); comment.setCommentType(CommentType.LOVE.getType()); comment.setUserId(UserHolder.getUserId()); Integer count = commentApi.delete(comment); //4、拼接redis的key,删除点赞状态 String key = Constants.MOVEMENTS_INTERACT_KEY + movementId; String hashKey = Constants.MOVEMENT_LOVE_HASHKEY + UserHolder.getUserId(); redisTemplate.opsForHash().delete(key,hashKey); return count; } ``` ### 2.5 修复前端点赞和喜欢显示效果Bug 显示效果和`MovementsVo`中的`hasLiked`与`hasLoved`绑定了,所以我们在分页查询动态数据构造`vo`对象时,需要判断是否点赞和喜欢了,对应修改`hasLiked`与`hasLoved`即可。 ```java private PageResult getPageResult(Integer page, Integer pagesize, List<Movement> movementList) { if (movementList == null || movementList.isEmpty()) { return new PageResult(); } // 4. 提取动态发布人的id列表 List<Long> userIds = CollUtil.getFieldValues(movementList, "userId", Long.class); // 5. 根据用户的id列表获取用户信息 Map<Long, UserInfo> map = userInfoApi.findByIds(userIds, null); // 6. 一个Movement构造一个vo对象 List<MovementsVo> vos = new ArrayList<>(); for (Movement movement : movementList) { UserInfo userInfo = map.get(movement.getUserId()); if (userInfo != null) { MovementsVo vo = MovementsVo.init(userInfo, movement); // 修复点赞和喜欢的bug String key = Constants.MOVEMENTS_INTERACT_KEY + movement.getId().toHexString(); String likeHashKey = Constants.MOVEMENT_LIKE_HASHKEY + UserHolder.getUserId(); if (redisTemplate.opsForHash().hasKey(key, likeHashKey)) { vo.setHasLiked(1); } String loveHashKey = Constants.MOVEMENT_LOVE_HASHKEY + UserHolder.getUserId(); if (redisTemplate.opsForHash().hasKey(key, loveHashKey)) { vo.setHasLoved(1); } vos.add(vo); } } // 7. 构造PageResult并返回 return new PageResult(page, pagesize, 0, vos); } ``` 最后修改:2023 年 01 月 20 日 © 允许规范转载 打赏 赞赏作者 支付宝微信 赞 1 如果觉得我的文章对你有用,请随意赞赏