Java+MyBatisPuls+Mysql实现文章评论回复功能
1、数据库设计
实现这个功能,最初想的是放在一张表里面,后来还是两张表:评论表+回复表!
首先是评论表,评论表里面字段如下图所示,由于我们的业务是B2B的数据量不是很大,用户头像和名称做了冗余字段,如果用户的头像修改了,则关联修改评论表里面的头像,我们的用户名称都是认证企业名称,所以不能修改。
评论表中 bid_id 字段是对应的文章 id 也就是一对多的关系。。。
下面是回复表:
回复表中 comment_id 是对应的评论 id 评论和回复也是一对多的关系,这个回复表里面不需要用户头像
先来看下实现的效果吧。评论和回复是分两个接口查询的。类似于抖音,显示展示出来改作品下所有的评论。如果该评论下有回复信息,可以展开更多回复,没有则不能展开,展开更多回复则是再根据评论ID获取该评论下的回复信息
展开后的效果是如下图所示
2、后端代码实现
2.1 评论代码
2.1.1 发布评论代码
Pojo:
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import java.io.Serializable;
import java.util.Date;
import lombok.Data;
/**
*
*
* @author caiyahui
* @email 1481465736@qq.com
* @date 2020-12-01 17:20:33
*/
@Data
@TableName("bms_bid_comment")
public class BidCommentEntity implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 评论ID
*/
@TableId
private Long id;
/**
* 招标ID
*/
private Long bidId;
/**
* 用户ID
*/
private Long memberId;
/**
* 用户名称
*/
private String memberName;
/**
* 用户头像
*/
private String memberUrl;
/**
* 评论内容
*/
private String content;
/**
* 评论时间
*/
private Date commentTime;
/**
* 是否删除 0 未删除 1已删除
*/
private Integer isDelete;
/**
* 评论回复数
*/
@TableField(exist = false)
private Integer replyCount;
}
Controller层:
/**
* 保存评论
* @param bidCommentEntity
* @return
*/
@RequestMapping("/saveComment")
public R comment(@RequestBody BidCommentEntity bidCommentEntity){
bidCommentService.comment(bidCommentEntity);
return R.ok();
}
Service层:
/**
* 保存评论
* @param bidCommentEntity
*/
@Override
public void comment(BidCommentEntity bidCommentEntity) {
MemberRespVo memberRespVo = LoginUserInterceptor.threadLocal.get();
bidCommentEntity.setMemberId(memberRespVo.getId());
bidCommentEntity.setMemberUrl(memberRespVo.getHeader()==null?"":memberRespVo.getHeader());
bidCommentEntity.setMemberName(memberRespVo.getCompanyName());
bidCommentEntity.setCommentTime(new Date());
bidCommentEntity.setIsDelete(0);
this.save(bidCommentEntity);
}
2.1.2 分页获取当前文章下的评论代码
Controller层:
/**
* 评论列表
* @param params
* @return
*/
@RequestMapping("/commentList")
public R commentList(@RequestParam Map<String,Object> params){
PageUtils page = bidCommentService.commentList(params);
return R.ok().put("data",page);
}
Service层:
@Override
public PageUtils commentList(Map<String,Object> params) {
IPage<BidCommentEntity> page = this.page(
new Query<BidCommentEntity>().getPage(params),
new QueryWrapper<BidCommentEntity>().eq("bid_id",params.get("bidId")).orderByDesc("comment_time")
);
if (page.getRecords()!=null&&page.getRecords().size()>0){
List<BidCommentEntity> replyCount = commentReplyService.getReplyCount(page.getRecords().stream().map(BidCommentEntity::getId).collect(Collectors.toList()));
List<BidCommentEntity> collect = replyCount.stream().filter(item -> item.getIsDelete() == 1 && item.getReplyCount() > 0 || item.getIsDelete() == 0).collect(Collectors.toList());
page.setRecords(collect);
}
return new PageUtils(page);
}
DAO层:
<select id="getReplyCount" resultType="com.zhupinhang.mall.bid.entity.BidCommentEntity">
SELECT
b.id,
b.bid_id,
b.member_id,
b.member_name,
b.member_url,
b.content,
b.comment_time,
b.is_delete,
IFNULL(COUNT(a.`comment_id`), 0) replyCount
FROM
`bms_bid_comment` b
LEFT JOIN `bms_comment_reply` a
ON a.`comment_id` = b.`id`
WHERE b.id IN
<foreach collection="ids" item="id" separator="," open="(" close=")">
#{id}
</foreach>
GROUP BY b.`id`
</select>
2.2 回复代码
2.2.1 新增回复代码
Pojo:
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import java.io.Serializable;
import java.util.Date;
import lombok.Data;
/**
*
*
* @author caiyahui
* @email 1481465736@qq.com
* @date 2020-12-01 17:20:33
*/
@Data
@TableName("bms_comment_reply")
public class CommentReplyEntity implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 自增ID
*/
@TableId
private Long id;
/**
* 评论ID
*/
private Long commentId;
/**
* 用户ID
*/
private Long memberId;
/**
* 用户名称
*/
private String memberName;
/**
* 被回复人ID
*/
private Long replyuserId;
/**
* 被回复人名称
*/
private String replyuserName;
/**
* 被回复内容
*/
private String replyuserContent;
/**
* 回复时间
*/
private Date replyTime;
/**
* 是否删除 0未删除 1已删除
*/
private Integer isDelete;
}
Controller层:
/**
* 新增回复评论
*/
@RequestMapping("/saveCommentReply")
public R commentReply(@RequestBody CommentReplyEntity commentReplyEntity){
commentReplyService.commentReply(commentReplyEntity);
return R.ok();
}
Service层:
/**
* 评论回复
* @param commentReplyEntity
*/
@Override
public void commentReply(CommentReplyEntity commentReplyEntity) {
MemberRespVo memberRespVo = LoginUserInterceptor.threadLocal.get();
commentReplyEntity.setMemberId(memberRespVo.getId());
commentReplyEntity.setMemberName(memberRespVo.getCompanyName());
commentReplyEntity.setReplyTime(new Date());
commentReplyEntity.setIsDelete(0);
this.save(commentReplyEntity);
}
2.2.2 评论下的所有回复信息
Controller层:
/**
* 某一个评论下面的回复信息
* @param params
* @return
*/
@RequestMapping("/commentReplyList")
public R commentReplyList(@RequestParam Map<String,Object> params){
PageUtils page = commentReplyService.commentReplyList(params);
return R.ok().put("data",page);
}
Service层:
@Override
public PageUtils commentReplyList(Map<String, Object> params) {
IPage<CommentReplyEntity> page = this.page(
new Query<CommentReplyEntity>().getPage(params),
new QueryWrapper<CommentReplyEntity>().eq("comment_id",params.get("commentId")).orderByDesc("reply_time")
);
return new PageUtils(page);
}