因为项目业务需要,特此写出此仿QQ空间的评论功能,项目如下图所示,records下的是一级评论
里面的commentList是二级评论,前端根据此数据格式渲染即可
表结构如下,其中father_id与reply_user_id默认为0,由于我是一张表,所以这两个字段用于区分是一级评论还是二级评论
实体类如下,其中有@TableField(exist = false)注解的都是虚拟字段,这里就不贴出用户表的实体类了。
import com.baomidou.mybatisplus.annotation.*;
import java.util.Date;
import com.baomidou.mybatisplus.extension.activerecord.Model;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Data;
import java.io.Serializable;
import java.util.List;
/**
* <p>
* 评论
* </p>
*
* @author Mybatis-plus
* @since 2019-07-26
*/
@Data
@TableName(resultMap = "BaseResultMap")
public class Comment extends Model<Comment> implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 评论ID
*/
@TableId(value = "comment_id",type = IdType.AUTO)
private Long commentId;
/**
* 所属帖子ID
*/
private Long postId;
/**
* 内容
*/
private String content;
/**
* 时间
*/
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone="GMT+8")
@TableField(fill = FieldFill.INSERT)
private Date createTime;
/**
* 评论人ID(当前用户)
*/
private Long activeUserId;
/**
* 所属贴主ID
*/
private Long posterId;
/**
* 已读,未读
*/
private Integer readState;
/**
* 所属父评论ID
*/
private Long fatherId;
/**
* 被回复人ID
*/
private Long replyUserId;
/**
* 当前用户用户名
*/
@TableField(exist = false)
private String userName;
/**
* 被回复人用户名
*/
@TableField(exist = false)
private String replyUserName;
/**
* 当前用户头像
*/
@TableField(exist = false)
private String headPhoto;
/**
* 被回复人用户头像
*/
@TableField(exist = false)
private String replyHeadPhoto;
/**
* 子评论展示状态
*/
@TableField(exist = false)
private boolean commentListState;
/**
* 子评论列表
*/
@TableField(exist = false)
private List<Comment> commentList;
}
mapper.xml如下
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org/DTD Mapper 3.0//EN" "mybatis-3-mapper.dtd">
<mapper namespace="com.jfs1010.mapper.CommentMapper">
<resultMap id="BaseResultMap" type="com.jfs1010.pojo.Comment">
<id property="commentId" column="comment_id"></id>
<id property="postId" column="post_id"></id>
<id property="content" column="content"></id>
<id property="createTime" column="create_time"></id>
<id property="activeUserId" column="active_user_id"></id>
<id property="posterId" column="poster_id"></id>
<id property="readState" column="read_state"></id>
<id property="fatherId" column="father_id"></id>
<id property="replyUserId" column="reply_user_id"></id>
</resultMap>
</mapper>
serviceImpl类如下,这里一级评论和二级评论调用的接口是同一个,传的东西不同
一级评论需要前端传 帖子ID 评论内容 父评论ID 和 被回复人ID 数据库默认是0 无需传
二级评论需要前端传 帖子ID 评论内容 被评论人ID 评论的ID 把 评论的ID set 到 父评论ID里 即 father_id 字段
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.jfs1010.mapper.PostMapper;
import com.jfs1010.mapper.UserMapper;
import com.jfs1010.pojo.Comment;
import com.jfs1010.mapper.CommentMapper;
import com.jfs1010.pojo.Post;
import com.jfs1010.pojo.User;
import com.jfs1010.service.CommentService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
/**
* <p>
* 服务实现类
* </p>
*
* @author Mybatis-plus
* @since 2019-07-26
*/
@Service
public class CommentServiceImpl extends ServiceImpl<CommentMapper, Comment> implements CommentService {
@Autowired(required = false)
private CommentMapper commentMapper;
@Autowired(required = false)
private UserMapper userMapper;
@Autowired(required = false)
private PostMapper postMapper;
/**
* 发布评论(包括一级二级)
*
* @param comment
* @return
*/
@Override
public int createComment(Comment comment) {
//获取当前用户
Post post = new Post();
post.setPostId(comment.getPostId());
//收藏数+1
post.setCommentNum(postMapper.selectById(comment.getPostId()).getCommentNum()+1);
postMapper.updateById(post);
//这里获得当前用户的ID,由于我后台还没写好,故强行获取
comment.setActiveUserId(userMapper.selectOne(new QueryWrapper<User>().eq("user_name", "小兰")).getUserId());
return commentMapper.insert(comment);
}
/**
* 查询出所有的一级评论和二级评论,并且与之对应
* 一级与二级区分
* 一级 post_id father_id = 0 reply_user_id = 0
* 二级 post_id father_id = comment_id
* @param postId
* @param curr
* @param limit
* @return
*/
@Override
public IPage<Comment> findAllComment(Long postId, Integer curr, Integer limit) {
//查出所有的一级评论
QueryWrapper<Comment> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("post_id",postId).eq("father_id",0).eq("reply_user_id",0).orderByDesc("create_time");
Page<Comment> page = new Page<>(curr, limit);
IPage<Comment> listMaps = commentMapper.selectPage(page, queryWrapper);
//根据评论人的ID获取用户名和头像
User user;
for (int i = 0; i < listMaps.getRecords().size(); i++) {
Comment res = listMaps.getRecords().get(i);
user = userMapper.selectById(res.getActiveUserId());
res.setUserName(user.getUserName());
res.setHeadPhoto(user.getHeadPhoto());
//二级评论展示状态,用于前端实现逻辑分页
res.setCommentListState(false);
//存放二级评论
QueryWrapper<Comment> queryWrapperTwo = new QueryWrapper<>();
queryWrapperTwo.eq("post_id",postId).eq("father_id",res.getCommentId()).orderByDesc("create_time");
//修改二级评论里面的用户名和头像
List<Comment> commentList = commentMapper.selectList(queryWrapperTwo);
for (int j = 0;j<commentList.size();j++){
Comment twoRes = commentList.get(j);
user = userMapper.selectById(twoRes.getActiveUserId());
//提问者用户名和头像
twoRes.setUserName(user.getUserName());
twoRes.setHeadPhoto(user.getHeadPhoto());
//回答者用户名和头像
twoRes.setReplyUserName(userMapper.selectById(twoRes.getReplyUserId()).getUserName());
twoRes.setReplyHeadPhoto(userMapper.selectById(twoRes.getReplyUserId()).getHeadPhoto());
}
//把二级评论放到一级评论里面
res.setCommentList(commentList);
}
return listMaps;
}
}
至此完成评论功能,Controller的代码我就不贴出来了。