第6章 圈子功能实现-2
今日内容介绍
学习目标
- 我的动态实现
- 圈子实现点赞、喜欢功能
- 圈子实现评论
- 圈子实现评论的点赞
1. 我的动态
【目标】
我的动态需求介绍
我的动态功能分析
我的动态功能实现
【路径】
1:了解我的动态需求
2:我的动态功能分析
3:我的动态功能实现
【讲解】
1.1. 服务消费者-我的动态
1.1.1. 接口说明
1.1.2. MomentController
/**
* 用户动态(我的动态 首页推荐用户点击进入)
* userId:当前登录用户id
*/
@RequestMapping(value = "/all",method = RequestMethod.GET)
public ResponseEntity findPageAlbum(@RequestParam(defaultValue = "1") int page,
@RequestParam(defaultValue = "10") int pagesize,Long userId) {
PageResult<MomentVo> pageResult = movementsService.findPageAlbum(page,pagesize,userId);
return ResponseEntity.ok(pageResult);
}
1.1.3. MomentService
/**
* 用户动态(我的动态 首页推荐用户点击进入)
* userId:当前登录用户id
*/
public PageResult<MomentVo> findPageAlbum(int page, int pagesize, Long userId) {
//1调用服务 分页查询发布表数据
PageResult<Publish> pagePublish =publishApi.findPageAlbum(userId,page,pagesize);
if(pagePublish == null || CollectionUtils.isEmpty(pagePublish.getItems())){
return new PageResult<>(0l,10l,0l,1l,null);
}
return getMomentVoPageResult(pagePublish);
}
1.2. 服务提供者-我的动态
1.2.1. PublishApi
/**
* 用户动态(我的动态 首页推荐用户点击进入)
* userId:当前登录用户id
*/
PageResult<Publish> findPageAlbum(Long userId, int page, int pagesize);
1.2.2. PublishApiImpl
/**
* 用户动态(我的动态 首页推荐用户点击进入)
* userId:当前登录用户id
*/
@Override
public PageResult<Publish> findPageAlbum(Long userId, int page, int pagesize) {
//1查询相册表(分页查询)
//db.getCollection("recommend_quanzi").find({userId:1}).limit(10).skip(0).sort({"created":-1})
Query query = new Query();
query.limit(pagesize);
query.skip((page-1)*pagesize);
query.with(Sort.by(Sort.Direction.DESC,"created"));
long counts = mongoTemplate.count(query, "quanzi_album_"+userId);
//1.1,查询当前页面数据
List<Album> albumList = mongoTemplate.find(query,Album.class,"quanzi_album_"+userId);
//2再查询发布表动态数据
if(CollectionUtils.isEmpty(albumList)){
return new PageResult<>(counts,(long)pagesize,0l,(long)page,null);
}
//将List<RecommendQuanzi> 转为 List<Publish>
List<Publish> publishList = new ArrayList<>();
for (Album album : albumList) {
//2.1根据发布id 查询 发布表
ObjectId publishId = album.getPublishId();//发布id
Publish publish = mongoTemplate.findById(publishId, Publish.class);
if(publish != null) {
publishList.add(publish);
}
}
//3返回PageResult<Publish>分页数据
long pages = counts/pagesize + (counts%pagesize > 0 ?1:0);
return new PageResult<>(counts,(long)pagesize,pages,(long)page,publishList);
}
1.2.3. 测试
【小结】
掌握我的动态实现
2. 动态点赞、喜欢、评论
【目标】
点赞、喜欢、评论需求介绍
点赞、喜欢、评论功能分析
点赞、喜欢、评论功能实现
【路径】
1:了解我的动态需求
2:点赞、喜欢、评论功能分析
3:点赞、喜欢、评论功能实现
【讲解】
点赞、喜欢、评论等均可理解为用户对动态的评论。
评论数据:
- 读多写少
- 价值低
- 是否点赞,点赞数量等
数据存储
- 点赞数量,评论数量,喜欢数量:
- 在动态表中添加字段
- 当点赞,喜欢,评论:需要修改动态表中的对应字段(+1)
- 是否点赞
- 存入到redis
- mongo的集合(数据库)
2.1. 服务消费者-动态点赞
2.1.1. 接口说明
点赞:
取消点赞:
2.1.2. MomentController
添加点赞与取消点赞方法
@Autowired
private MovementsService movementsService;
/**
* 动态点赞(保存点赞记录到评论表 、 更新发布表点赞数量+1 、查询发布表点赞数量返回 、 将点赞记录写入redis)
* id:动态id
*/
@RequestMapping(value = "/{id}/like",method = RequestMethod.GET)
public ResponseEntity saveComment(@PathVariable("id") String publishId) {
int likeCount = movementsService.saveComment(publishId);
return ResponseEntity.ok(likeCount);
}
/**
* 动态取消点赞(删除点赞记录到评论表 、 更新发布表点赞数量-1 、查询发布表点赞数量返回 、 将点赞记录从redis删除)
* id:动态id
*/
@RequestMapping(value = "/{id}/dislike",method = RequestMethod.GET)
public ResponseEntity deleteComment(@PathVariable("id") String publishId) {
int likeCount = movementsService.deleteComment(publishId);
return ResponseEntity.ok(likeCount);
}
2.1.3. MovementsService
修改queryFriendPublishList、queryRecommendPublishList、queryMyAlbum方法
/**
* 将publish userInfo 转为 MomentVo 动态数据转换公共方法
* @param pagePublish
* @return
*/
private PageResult<MomentVo> getMomentVoPageResult(PageResult<Publish> pagePublish) {
//2根据用户id查询用户信息
//2.1将publish userInfo 转为 MomentVo
List<MomentVo> momentVoList = new ArrayList<>();
for (Publish publish : pagePublish.getItems()) {
MomentVo momentVo = new MomentVo();
Long publishUserId = publish.getUserId();//动态发布者用户id
//用户信息
UserInfo userInfo = userInfoApi.findUserInfoByUserId(publishUserId);
//copy
BeanUtils.copyProperties(publish,momentVo);//userId textContent likeCount commentCount loveCount
BeanUtils.copyProperties(userInfo,momentVo);// nickname avatar gender age
//设置动态id
momentVo.setId(publish.getId().toHexString());//动态id
//设置标签
if(!StringUtils.isEmpty(userInfo.getTags())){
momentVo.setTags(userInfo.getTags().split(","));
}
//图片url地址 将List<String> medias 转为 String[] imageContent
momentVo.setImageContent(publish.getMedias().toArray(new String[]{}));
momentVo.setDistance("1米");//距离
//发布时间
momentVo.setCreateDate(RelativeDateFormat.format(new Date(publish.getCreated())));
//是否点赞 是否喜欢
String key = "likeCount_"+UserHolder.getUserId()+"_"+publish.getId().toHexString();//key规则保证当前用户对此动态点赞
if(StringUtils.isEmpty(redisTemplate.opsForValue().get(key))) {
momentVo.setHasLiked(0);
}else {
momentVo.setHasLiked(1);
}
momentVo.setHasLoved(0);
momentVoList.add(momentVo);
}
//3封装数据返回
PageResult<MomentVo> voPageResult = new PageResult<>();
BeanUtils.copyProperties(pagePublish,voPageResult);
voPageResult.setItems(momentVoList);
return voPageResult;
}
/**
* 动态点赞
* id:动态id
*/
public int saveComment(String publishId) {
Long userId = UserHolder.getUserId();//当前登录用户id
//1.调用服务提供者 点赞 (保存点赞记录到评论表 、 更新发布表点赞数量+1 、查询发布表点赞数量返回)
Comment comment = new Comment();
comment.setPublishId(new ObjectId(publishId));//动态id(针对此动态点赞)
comment.setCommentType(1); //评论类型,1-点赞,2-评论,3-喜欢
comment.setPubType(1);//评论内容类型: 1-对动态操作 2-对视频操作 3-对评论操作
comment.setUserId(userId);
int likeCount = commentApi.saveComment(comment);
//2.将点赞记录写入redis
String key = "likeCount_"+userId+"_"+publishId;//key规则保证当前用户对此动态点赞
redisTemplate.opsForValue().set(key,"1");
//3.返回点赞数量
return likeCount;
}
/**
* 动态取消点赞(删除点赞记录到评论表 、 更新发布表点赞数量-1 、查询发布表点赞数量返回 、 将点赞记录从redis删除)
* id:动态id
*/
public int deleteComment(String publishId) {
Long userId = UserHolder.getUserId();//当前登录用户id
//1.调用服务提供者 点赞 (删除点赞记录到评论表 、 更新发布表点赞数量-1 、查询发布表点赞数量返回 、 将点赞记录从redis删除)
Comment comment = new Comment();
comment.setPublishId(new ObjectId(publishId));//动态id(针对此动态点赞)
comment.setCommentType(1); //评论类型,1-点赞,2-评论,3-喜欢
comment.setPubType(1);//评论内容类型: 1-对动态操作 2-对视频操作 3-对评论操作
comment.setUserId(userId);
int likeCount = commentApi.deleteComment(comment);
//2.将点赞记录从redis删除
String key = "likeCount_"+userId+"_"+publishId;//key规则保证当前用户对此动态点赞
redisTemplate.delete(key);
//3.返回点赞数量
return likeCount;
}
2.2. 服务提供者-动态点赞
2.2.1. 实体类与VO
在tanhua-domain模板mongo包下创建实体对象
package com.tanhua.domain.mongo;
import lombok.Data;
import org.bson.types.ObjectId;
import org.springframework.data.mongodb.core.mapping.Document;
import java.io.Serializable;
@Data
@Document(collection = "quanzi_comment")
public class Comment implements Serializable {
private ObjectId id;
private ObjectId publishId; //发布id
private Integer commentType; //评论类型,1-点赞,2-评论,3-喜欢
private Integer pubType; //评论内容类型: 1-对动态操作 2-对视频操作 3-对评论操作
private String content; //评论内容
private Long userId; //评论人
private Integer likeCount = 0; //点赞数
private Long created; //发表时间
//动态选择更新的字段
public String getCol() {
return this.commentType == 1 ? "likeCount" : commentType==2? "commentCount"
: "loveCount";
}
}
2.2.2. CommentApi
在tanhua-dubbo-interface模板mongo包下创建接口
package com.tanhua.dubbo.api.mongo;
import com.tanhua.domain.mongo.Comment;
/**
* 评论服务接口
*/
public interface CommentApi {
/**
* 动态点赞
* @param comment
* @return
*/
int saveComment(Comment comment);
/**
* 动态取消点赞(删除点赞记录到评论表 、 更新发布表点赞数量-1 、查询发布表点赞数量返回 、 将点赞记录从redis删除)
* id:动态id
*/
int deleteComment(Comment comment);
}
2.2.3. CommentApiImpl
在tanhua-dubbo-service模板mongo包下创建实现类
package com.tanhua.dubbo.api.mongo;
import com.tanhua.domain.mongo.Comment;
import com.tanhua.domain.mongo.Publish;
import org.apache.dubbo.config.annotation.Service;
import org.bson.types.ObjectId;
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;
/**
* 评论服务接口实现类
*/
@Service
public class CommentApiImpl implements CommentApi{
@Autowired
private MongoTemplate mongoTemplate;
/**
* 动态点赞
* @param comment
* @return
*/
@Override
public int saveComment(Comment comment) {
//1保存点赞记录到评论表 、
comment.setId(ObjectId.get());//主键id
comment.setCreated(System.currentTimeMillis());//点赞时间
mongoTemplate.insert(comment);
//2更新发布表点赞数量+1 、
updateCount(comment,1);
//3查询发布表点赞数量返回
return findCount(comment);
}
/**
* 动态取消点赞(删除点赞记录到评论表 、 更新发布表点赞数量-1 、查询发布表点赞数量返回 、 将点赞记录从redis删除)
* id:动态id
*/
@Override
public int deleteComment(Comment comment) {
//1删除点赞记录从评论表
Query query = new Query();
query.addCriteria(
Criteria.where("publishId").is(comment.getPublishId())//发布id
.and("commentType").is(comment.getCommentType())//评论类型,1-点赞,2-评论,3-喜欢
.and("pubType").is(comment.getPubType()) //评论内容类型: 1-对动态操作 2-对视频操作 3-对评论操作
.and("userId").is(comment.getUserId())//评论人
);
mongoTemplate.remove(query,Comment.class);
//2更新发布表点赞数量+1 、
updateCount(comment,-1);
//3查询发布表点赞数量返回
return findCount(comment);
}
/**
* 2更新发布表点赞数量+1
* @param comment
* @param num
*/
private void updateCount(Comment comment, int num) {
//1.构造更新条件 根据发布id更新点赞数量
Query query = new Query();
query.addCriteria(Criteria.where("id").is(comment.getPublishId()));
//2.构造更新数据
Update update = new Update();
update.inc("likeCount",num);
//3.更新
mongoTemplate.updateFirst(query,update, Publish.class);
}
/**
* 3查询发布表点赞数量返回
* @param comment
* @return
*/
private int findCount(Comment comment) {
Publish publish = mongoTemplate.findById(comment.getPublishId(), Publish.class);
return publish.getLikeCount();
}
}
2.2.4. 测试
2.3. 服务消费者-动态喜欢
2.3.1. 接口说明
喜欢:
取消喜欢:
2.3.2. MomentController
修改MomentController代码,添加喜欢与不喜欢的方法
/**
* 动态喜欢(保存喜欢记录到评论表 、 更新发布表喜欢数量+1 、查询发布表喜欢数量返回 、 将喜欢记录写入redis)
* id:动态id
*/
@RequestMapping(value = "/{id}/love",method = RequestMethod.GET)
public ResponseEntity saveLove(@PathVariable("id") String publishId) {
int loveCount = movementsService.saveLove(publishId);
return ResponseEntity.ok(loveCount);
}
/**
* 动态取消喜欢(将喜欢记录从评论表删除 、 更新发布表喜欢数量-1 、查询发布表喜欢数量返回 、 将喜欢记录从redis删除)
* id:动态id
*/
@RequestMapping(value = "/{id}/unlove",method = RequestMethod.GET)
public ResponseEntity deleteLove(@PathVariable("id") String publishId) {
int loveCount = movementsService.deleteLove(publishId);
return ResponseEntity.ok(loveCount);
}
2.3.3. MomentService
修改queryRecommendPublishList方法
/**
* 动态喜欢(保存喜欢记录到评论表 、 更新发布表喜欢数量+1 、查询发布表喜欢数量返回 、 将喜欢记录写入redis)
* id:动态id
*/
public int saveLove(String publishId) {
Long userId = UserHolder.getUserId();//当前登录用户id
//1.调用服务提供者 点赞 (保存喜欢记录到评论表 、 更新发布表喜欢数量+1 、查询发布表喜欢数量返回 、 将喜欢记录写入redis)
Comment comment = new Comment();
comment.setPublishId(new ObjectId(publishId));//动态id(针对此动态点赞)
comment.setCommentType(3); //评论类型,1-点赞,2-评论,3-喜欢
comment.setPubType(1);//评论内容类型: 1-对动态操作 2-对视频操作 3-对评论操作
comment.setUserId(userId);
int loveCount = commentApi.saveComment(comment);
//2.将喜欢记录写入redis
String key = "loveCount_"+userId+"_"+publishId;//key规则保证当前用户对此动态喜欢
redisTemplate.opsForValue().set(key,"1");
//3.返回喜欢数量
return loveCount;
}
/**
* 动态取消喜欢(将喜欢记录从评论表删除 、 更新发布表喜欢数量-1 、查询发布表喜欢数量返回 、 将喜欢记录从redis删除)
* id:动态id
*/
public int deleteLove(String publishId) {
Long userId = UserHolder.getUserId();//当前登录用户id
//1.调用服务提供者 点赞 (将喜欢记录从评论表删除 、 更新发布表喜欢数量-1 、查询发布表喜欢数量返回 、 将喜欢记录从redis删除)
Comment comment = new Comment();
comment.setPublishId(new ObjectId(publishId));//动态id(针对此动态喜欢)
comment.setCommentType(3); //评论类型,1-点赞,2-评论,3-喜欢
comment.setPubType(1);//评论内容类型: 1-对动态操作 2-对视频操作 3-对评论操作
comment.setUserId(userId);
int loveCount = commentApi.deleteComment(comment);
//2.将喜欢记录从redis删除
String key = "loveCount_"+userId+"_"+publishId;//key规则保证当前用户对此动态喜欢
redisTemplate.delete(key);
//3.返回点赞数量
return loveCount;
}
/**
* 将publish userInfo 转为 MomentVo 动态数据转换公共方法
* @param pagePublish
* @return
*/
private PageResult<MomentVo> getMomentVoPageResult(PageResult<Publish> pagePublish) {
//2根据用户id查询用户信息
//2.1将publish userInfo 转为 MomentVo
List<MomentVo> momentVoList = new ArrayList<>();
for (Publish publish : pagePublish.getItems()) {
MomentVo momentVo = new MomentVo();
Long publishUserId = publish.getUserId();//动态发布者用户id
//用户信息
UserInfo userInfo = userInfoApi.findUserInfoByUserId(publishUserId);
//copy
BeanUtils.copyProperties(publish,momentVo);//userId textContent likeCount commentCount loveCount
BeanUtils.copyProperties(userInfo,momentVo);// nickname avatar gender age
//设置动态id
momentVo.setId(publish.getId().toHexString());//动态id
//设置标签
if(!StringUtils.isEmpty(userInfo.getTags())){
momentVo.setTags(userInfo.getTags().split(","));
}
//图片url地址 将List<String> medias 转为 String[] imageContent
momentVo.setImageContent(publish.getMedias().toArray(new String[]{}));
momentVo.setDistance("1米");//距离
//发布时间
momentVo.setCreateDate(RelativeDateFormat.format(new Date(publish.getCreated())));
//是否点赞 是否喜欢
String key = "likeCount_"+UserHolder.getUserId()+"_"+publish.getId().toHexString();//key规则保证当前用户对此动态点赞
if(StringUtils.isEmpty(redisTemplate.opsForValue().get(key))) {
momentVo.setHasLiked(0);
}else {
momentVo.setHasLiked(1);
}
String key2 = "loveCount_"+UserHolder.getUserId()+"_"+publish.getId().toHexString();//key规则保证当前用户对此动态点赞
if(StringUtils.isEmpty(redisTemplate.opsForValue().get(key2))) {
momentVo.setHasLoved(0);
}else {
momentVo.setHasLoved(1);
}
momentVoList.add(momentVo);
}
//3封装数据返回
PageResult<MomentVo> voPageResult = new PageResult<>();
BeanUtils.copyProperties(pagePublish,voPageResult);
voPageResult.setItems(momentVoList);
return voPageResult;
}
2.3.5. CommentApiImpl
/**
* 2更新发布表点赞数量+1
* 2更新发布表喜欢数量+1
* @param comment
* @param num
*/
private void updateCount(Comment comment, int num) {
//1.构造更新条件 根据发布id更新点赞数量
Query query = new Query();
query.addCriteria(Criteria.where("id").is(comment.getPublishId()));
//2.构造更新数据
Update update = new Update();
update.inc(comment.getCol(),num);
//3.更新
mongoTemplate.updateFirst(query,update, Publish.class);
}
/**
* 3查询发布表点赞数量返回
* @param comment
* @return
*/
private int findCount(Comment comment) {
Publish publish = mongoTemplate.findById(comment.getPublishId(), Publish.class);
if(comment.getCommentType() == 1){//评论类型,1-点赞,2-评论,3-喜欢
return publish.getLikeCount();
}
if(comment.getCommentType() == 2){//评论类型,1-点赞,2-评论,3-喜欢
return publish.getCommentCount();
}
if(comment.getCommentType() == 3){//评论类型,1-点赞,2-评论,3-喜欢
return publish.getLoveCount();
}
return 0;
}
2.3.4. 测试
2.4. 服务消费者-查询单条动态
2.4.1. 接口说明
2.4.2. MomentController
/**
* 单条动态
*/
@RequestMapping(value = "/{id}",method = RequestMethod.GET)
public ResponseEntity findPublish(@PathVariable("id") String publishId) {
MomentVo momentVo = movementsService.findPublish(publishId);
return ResponseEntity.ok(momentVo);
}
2.4.3. MomentService
/**
* 单条动态
*/
public MomentVo findPublish(String publishId) {
//1.调用服务提供者:根据发布id查询发布表
Publish publish = publishApi.findPublish(publishId);
//2.封装Vo返回
return getMomentVo(publish);
}
/**
* 将publish userInfo 转为 MomentVo 动态数据转换公共方法
* @param pagePublish
* @return
*/
private PageResult<MomentVo> getMomentVoPageResult(PageResult<Publish> pagePublish) {
//2根据用户id查询用户信息
//2.1将publish userInfo 转为 MomentVo
List<MomentVo> momentVoList = new ArrayList<>();
for (Publish publish : pagePublish.getItems()) {
MomentVo momentVo = getMomentVo(publish);
momentVoList.add(momentVo);
}
//3封装数据返回
PageResult<MomentVo> voPageResult = new PageResult<>();
BeanUtils.copyProperties(pagePublish,voPageResult);
voPageResult.setItems(momentVoList);
return voPageResult;
}
/**
* 将Publish userInfo 转为MomentVo公共方法
* @param publish
* @return
*/
private MomentVo getMomentVo(Publish publish) {
MomentVo momentVo = new MomentVo();
Long publishUserId = publish.getUserId();//动态发布者用户id
//用户信息
UserInfo userInfo = userInfoApi.findUserInfoByUserId(publishUserId);
//copy
BeanUtils.copyProperties(publish,momentVo);//userId textContent likeCount commentCount loveCount
BeanUtils.copyProperties(userInfo,momentVo);// nickname avatar gender age
//设置动态id
momentVo.setId(publish.getId().toHexString());//动态id
//设置标签
if(!StringUtils.isEmpty(userInfo.getTags())){
momentVo.setTags(userInfo.getTags().split(","));
}
//图片url地址 将List<String> medias 转为 String[] imageContent
momentVo.setImageContent(publish.getMedias().toArray(new String[]{}));
momentVo.setDistance("1米");//距离
//发布时间
momentVo.setCreateDate(RelativeDateFormat.format(new Date(publish.getCreated())));
//是否点赞 是否喜欢
String key = "likeCount_"+ UserHolder.getUserId()+"_"+publish.getId().toHexString();//key规则保证当前用户对此动态点赞
if(StringUtils.isEmpty(redisTemplate.opsForValue().get(key))) {
momentVo.setHasLiked(0);
}else {
momentVo.setHasLiked(1);
}
String key2 = "loveCount_"+UserHolder.getUserId()+"_"+publish.getId().toHexString();//key规则保证当前用户对此动态点赞
if(StringUtils.isEmpty(redisTemplate.opsForValue().get(key2))) {
momentVo.setHasLoved(0);
}else {
momentVo.setHasLoved(1);
}
return momentVo;
}
2.4.4. PublishApi
/**
* 单条动态
*/
Publish findPublish(String publishId);
2.4.5 PublishApiImpl
/**
* 单条动态
*/
@Override
public Publish findPublish(String publishId) {
return mongoTemplate.findById(new ObjectId(publishId),Publish.class);
}
2.4.6. 测试
2.5. 服务消费者-评论列表
功能包括:查询评论列表,评论点赞、取消点赞。
2.5.1. 接口说明
2.5.2.CommentVo
在tanhua-domain模板vo包下创建实体对象
package com.tanhua.domain.vo;
import lombok.Data;
@Data
public class CommentVo {
private String id; //评论id
private String avatar; //头像
private String nickname; //昵称
private String content; //评论
private String createDate; //评论时间: 08:27
private Integer likeCount; //点赞数
private Integer hasLiked; //是否点赞(1是,0否)
}
2.5.3. CommentController
package com.tanhua.server.controller;
import com.tanhua.domain.vo.CommentVo;
import com.tanhua.domain.vo.PageResult;
import com.tanhua.server.service.CommentsService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
/**
* 评论管理控制层
*/
@RestController
@RequestMapping("/comments")
public class CommentsController {
@Autowired
private CommentsService commentsService;
/**
* 评论列表分页查询
*/
@RequestMapping(value = "/comments", method = RequestMethod.GET)
public ResponseEntity findPageComments(@RequestParam(defaultValue = "1") int page,
@RequestParam(defaultValue = "10") int pagesize, String movementId) {
PageResult<CommentVo> commentVoPageResult = commentsService.findPageComments(page, pagesize, movementId);
return ResponseEntity.ok(commentVoPageResult);
}
}
2.5.4. CommentService
package com.tanhua.server.service;
import com.tanhua.domain.db.UserInfo;
import com.tanhua.domain.mongo.Comment;
import com.tanhua.domain.vo.CommentVo;
import com.tanhua.domain.vo.PageResult;
import com.tanhua.dubbo.api.db.UserInfoApi;
import com.tanhua.dubbo.api.mongo.CommentApi;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.Reference;
import org.joda.time.DateTime;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import java.util.ArrayList;
import java.util.List;
/**
* 评论管理-业务逻辑处理层
*/
@Service
@Transactional
@Slf4j //日志注解
public class CommentsService {
@Reference
private CommentApi commentApi;
@Reference
private UserInfoApi userInfoApi;
/**
* 评论列表分页查询
*/
public PageResult<CommentVo> findPageComments(int page, int pagesize, String publishId) {
//1. 根据发布id+commentType=2+pubType=1分页查询评论表
PageResult<Comment> pageResult = commentApi.findPageComments(publishId,page,pagesize);
if(pageResult == null || CollectionUtils.isEmpty(pageResult.getItems())){
return new PageResult<>(0l,10l,0l,1l,null);
}
//2. 根据动态发布的用户id 查询tb_user_info
//2.1 将userInfo 评论数据封装
List<CommentVo> voList = new ArrayList<>();
for (Comment comment : pageResult.getItems()) {
CommentVo commentVo = new CommentVo();
Long publishUserId = comment.getUserId();//动态发布用户的id
UserInfo userInfo = userInfoApi.findUserInfoByUserId(publishUserId);
BeanUtils.copyProperties(userInfo,commentVo);//头像 昵称
BeanUtils.copyProperties(comment,commentVo);//评论内容 点赞数量
//评论表主键id设置
commentVo.setId(comment.getId().toHexString());
commentVo.setCreateDate(new DateTime(comment.getCreated()).toString("yyyy年MM月dd日 HH:mm"));
commentVo.setHasLiked(0);//是否点赞(1是,0否)
voList.add(commentVo);
}
//3 返回Vo返回
PageResult<CommentVo> voPageResult = new PageResult<>();
BeanUtils.copyProperties(pageResult,voPageResult); //copy counts pagesize pages page
voPageResult.setItems(voList);//设置返回集合Vo
return voPageResult;
}
}
2.6. 服务提供者-评论列表
2.6.1. CommentApi
在tanhua-dubbo-interface模板mongo包下创建接口
/**
* 评论列表分页查询
*/
PageResult<Comment> findPageComments(String publishId,int page, int pagesize);
2.6.2. CommentApiImpl
/**
* 评论列表分页查询
*/
@Override
public PageResult<Comment> findPageComments(String publishId,int page, int pagesize) {
//1.根据发布id+commentType=2+pubType=1分页查询评论表
Query query = new Query();
query.addCriteria(
Criteria.where("publishId").is(new ObjectId(publishId))
.and("commentType").is(2)
.and("pubType").is(1)
);
query.limit(pagesize);
query.skip((page-1)*pagesize);
long counts = mongoTemplate.count(query, Comment.class);
//2,查询当前页面数据
List<Comment> commentList = mongoTemplate.find(query, Comment.class);
//3.封装PageResult对象返回
//pages //总页数
long pages = counts/pagesize + (counts%pagesize > 0 ?1:0);
return new PageResult<>(counts,(long)pagesize,pages,(long)page,commentList);
}
2.6.3. 测试
2.7. 服务消费者-发表评论
2.7.1. 接口说明
2.7.2. CommentController
/**
* 评论-提交
*/
@RequestMapping(method = RequestMethod.POST)
public ResponseEntity saveComment(@RequestBody Map<String,String> params) {
String publishId = params.get("movementId");//动态发布id
String content = params.get("comment");//评论内容
commentsService.saveComment(publishId, content);
return ResponseEntity.ok(null);
}
2.7.3. CommentService
/**
* 评论-提交
*/
public void saveComment(String publishId, String content) {
//1.发布评论
Long userId = UserHolder.getUserId();//当前登录用户id
//1.调用服务提供者 评论 (保存评论记录到评论表 、 更新发布表评论数量+1 、查询发布表评论数量返回)
Comment comment = new Comment();
comment.setPublishId(new ObjectId(publishId));//动态id(针对此动态评论)
comment.setCommentType(2); //评论类型,1-点赞,2-评论,3-喜欢
comment.setPubType(1);//评论内容类型: 1-对动态操作 2-对视频操作 3-对评论操作
comment.setUserId(userId);
comment.setContent(content);//评论内容
int likeCount = commentApi.saveComment(comment);
//2.返回评论数量
}
2.7.4. 测试
2.8. 评论点赞与取消点赞
评论点赞包含对评论的点赞我与取消点赞
2.8.1. 接口说明
评论点赞:
取消点赞:
2.8.2. CommentController
/**
* 评论点赞(保存评论点赞记录到评论表 、 更新评论表点赞数量+1 、查询评论表点赞数量返回 、 将评论点赞记录写入redis)
* id:评论表主键id
*/
@RequestMapping(value = "/{id}/like",method = RequestMethod.GET)
public ResponseEntity likeComment(@PathVariable("id") String commentId) {
int likeCount = commentsService.likeComment(commentId);
return ResponseEntity.ok(likeCount);
}
/**
* 评论取消点赞(删除评论点赞记录从评论表 、 更新评论表点赞数量-1 、查询评论表点赞数量返回 、 将评论点赞记录从入redis删除)
* id:评论表主键id
*/
@RequestMapping(value = "/{id}/dislike",method = RequestMethod.GET)
public ResponseEntity dislikeComment(@PathVariable("id") String commentId) {
int likeCount = commentsService.dislikeComment(commentId);
return ResponseEntity.ok(likeCount);
}
2.8.3. CommentService
/**
* 评论点赞
* @param commentId
* @return
*/
public Long likeComment(String commentId) {
Long userId = UserHolder.getUserId();
// 创建Comment
Comment comment = new Comment();
// 设置点赞属性
comment.setUserId(userId);
comment.setCommentType(1); // 点赞
comment.setPubType(3); // 对评论操作
comment.setPublishId(new ObjectId(commentId));
// 调用api添加评论信息,且获得最新点赞数
Long total = commentApi.save(comment);
String key = "comment_like_" + userId+"_" + commentId;
// 记录下点了赞了
redisTemplate.opsForValue().set(key,"1");
return total;
}
/**
* 取消对评论的点赞
* @param commentId
* @return
*/
public Long unlikeComment(String commentId) {
Long userId = UserHolder.getUserId();
// 创建Comment对象
Comment comment = new Comment();
// 设置删除条件
comment.setPublishId(new ObjectId(commentId));
comment.setUserId(UserHolder.getUserId());
comment.setCommentType(1);
comment.setPubType(3);
// 调用api删除
long total = commentApi.remove(comment);
String key = "comment_like_" + userId+"_" + commentId;
// 移除redis中记录
redisTemplate.delete(key);
return total;
}
2.8.4. CommentService
修改CommentService中findPage方法
将
commentVo.setHasLiked(0);//是否点赞
改为
String key = "comment_like_" + comment.getUserId()+"_" + comment.getPublishId().toHexString();
// 记录下点了赞了
if(redisTemplate.hasKey(key)){
commentVo.setHasLiked(1);//是否点赞
}
else {
commentVo.setHasLiked(0);//是否点赞
}
2.8.5. 测试
【小结】
掌握动态点赞、喜欢、评论实现
总结
-
我的动态功能实现---重点掌握(将之前好友动态 推荐动态抽取)
-
动态点赞 单个动态查询 查询评论列表 发布评论 ----优先级最高
-
动态喜欢、评论点赞实现
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!