一、数据库表设计
- 评论表:(如下图)
注:1、comment_type字段针对于程序设计多个不同功能下单评论区分
2、comment_pic字段用于存储评论图片时使用
- 回复表:(如下图)
注:1、reply_type字段与评论中的comment_type字段用法一致
以上为数据库设计, 整体的关键与两表的time字段, 是做评论排序的核心所在
二、代码实现
- 评论实体类
package com.foo.wechat.domain;
import java.util.Date;
import com.foo.common.annotation.Excel;
import com.foo.common.core.domain.BaseEntity;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;
import lombok.Getter;
import lombok.Setter;
/**
* 评论对象 wx_comment
*
* @author foo
* @date 2020-11-10
*/
@Getter
@Setter
public class WxComment extends BaseEntity
{
private static final long serialVersionUID = 1L;
/** 编号 */
private Long commentId;
/** 评论用户 */
private Long commentUid;
/** 对象id */
private Long commentObjectid;
/** 评论内容 */
private String commentTxt;
/** 评论类型 */
private Long commentType;
/** 评论时间 */
private Date commentTime;
/**评论图片*/
private String commentPic;
/**评论者名称*/
private String userName;
/**评论者头像*/
private String userAvatar;
}
- 回复表实体类
package com.foo.wechat.domain;
import java.util.Date;
import com.foo.common.annotation.Excel;
import com.foo.common.core.domain.BaseEntity;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;
import lombok.Getter;
import lombok.Setter;
/**
* 回复对象 wx_reply
*
* @author foo
* @date 2020-11-10
*/
@Getter
@Setter
public class WxReply extends BaseEntity
{
private static final long serialVersionUID = 1L;
/** 编号 */
private Long replyId;
/** 回复用户 */
private Long replyUid;
/** 被回复用户 */
private Long replyUidbe;
/** 回复内容 */
private String replyTxt;
/** 回复时间 */
private Date replyTime;
/** 回复对象 */
private Long replyObjectid;
/** 类型 */
private Long replyType;
/** 类型 */
private String replyPic;
/** 回复用户名 */
private String uname;
/** 回复用户头像 */
private String avatar;
/** 被回复用户名 */
private String ubename;
}
- 评论回复树实体类
package com.foo.wechat.domain;
import lombok.Getter;
import lombok.Setter;
import java.util.Date;
/**
* 评论回复树
*
* @author foo
* @date 2020-11-10
*/
@Getter
@Setter
public class WxCommentTree {
/** 评论实体 */
private WxComment wxComment;
/** 回复实体 */
private WxReply wxReply;
/** 收集时间 */
private Date time;
/** 类似(区分评论/回复) */
private Integer type;
}
- 控制器接口
/**
* 查询评论列表
*/
@GetMapping("/list")
@ResponseBody
@Log(title = "评论", businessType = BusinessType.List, operatorType = OperatorType.MOBILE)
public AjaxResult list(WxComment wxComment,Integer pageNum, Integer pageSize)
{
if(pageNum != null){
Integer size = 10;
if(pageSize != null){
size = pageSize;
}
PageHelper.startPage(pageNum, size);
}
List<WxCommentTree> listTree = new ArrayList<>();
List<WxComment> WxCommentlist = wxCommentService.selectWxCommentList(wxComment);
WxReply wxReply = new WxReply();
wxReply.setReplyType(wxComment.getCommentType());
wxReply.setReplyObjectid(wxComment.getCommentType());
List<WxReply> WxReplylist = wxReplyService.selectWxReplyList(wxReply);
for(int i= 0;i<WxCommentlist.size();i++){
WxComment wxComment1 = WxCommentlist.get(i);
WxCommentTree wxCommentTree = new WxCommentTree();
wxCommentTree.setWxComment(wxComment1);
wxCommentTree.setType(0);
wxCommentTree.setTime(wxComment1.getCommentTime());
listTree.add(wxCommentTree);
}
for(int j= 0;j<WxReplylist.size();j++){
WxReply wxReply1 = WxReplylist.get(j);
WxCommentTree wxCommentTree = new WxCommentTree();
wxCommentTree.setWxReply(wxReply1);
wxCommentTree.setType(1);
wxCommentTree.setTime(wxReply1.getReplyTime());
listTree.add(wxCommentTree);
}
//进行排序
listTree.sort((WxCommentTree m1, WxCommentTree m2) -> m1.getTime().compareTo(m2.getTime()));
return AjaxResult.success(listTree);
}
- html页面
<!DOCTYPE html>
<html lang="zh" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<th:block th:include="include :: header('评价列表')" />
<style>
.user{
display: flex;
}
.user img{
width: 40px;
height: 40px;
margin-top: 3px;
border-radius: 50%;
}
.txt{
/*font-weight: bold;*/
margin-left: 12px;
margin-top: 4px;
}
p{
margin-top: 5px;
}
hr{
margin-top: 6px;
margin-bottom: 10px;
}
</style>
</head>
<body class="white-bg">
<input id="objectId" type="hidden" th:value="*{objectId}">
<input id="type" type="hidden" th:value="*{type}">
<div class="wrapper wrapper-content animated fadeInRight ibox-content">
<!--评论-->
<div id="context">
</div>
</div>
<th:block th:include="include :: footer" />
<script>
$.ajax({
url:ctx+"/wechat/api/comment/list", //请求后台
dataType:"json",
type:"get",
async:true,
data:"commentObjectid="+$("#objectId").val()+"&commentType="+$("#type").val(),
success:function(data){
var data = data.data
for(var i =0;i<data.length;i++){
if(data[i].type==0){
var html ='<div id="z_'+data[i].wxComment.commentId+'" onclick="del(0,'+data[i].wxComment.commentId+')" class="user">'
html +='<img src="'+data[i].wxComment.userAvatar+'">'
html +='<div class="txt">'
html +='<strong>'+data[i].wxComment.userName+'</strong> '
html +='<span>'+data[i].time+'</span>'
html +='<p>'+data[i].wxComment.commentTxt+'</p>'
if(data[i].wxComment.commentPic!=null){
var arr = data[i].wxComment.commentPic.split(',');
html +="<div>"
for(var j in arr){
html +="<img style=\"border-radius: 0;margin-right: 2px\" width='100px' src="+arr[j]+">"
}
html +="</div>"
}
html +='</div>'
html +='</div>'
html +='<hr id="z_h_'+data[i].wxComment.commentId+'">'
$("#context").append(html)
}else {
var html ='<div id="z_'+data[i].wxReply.replyId+'" onclick="del(1,'+data[i].wxReply.replyId+')" class="user">'
html+='<img src="'+data[i].wxReply.avatar+'">'
html+='<div class="txt">'
html+='<strong>'+data[i].wxReply.uname+'</strong><span> 回复 </span><strong>'+data[i].wxReply.ubename+' </strong>'
html+='<span>'+data[i].time+'</span>'
html+='<p>'+data[i].wxReply.replyTxt+'</p>'
if(data[i].wxReply.replyPic!=null){
var arrs = data[i].wxReply.replyPic.split(',');
html +="<div>"
for(var g in arrs){
html +="<img style=\"border-radius: 0;margin-right: 2px\" width='100px' src="+arrs[g]+">"
}
html +="</div>"
}
html+='</div>'
html+='</div>'
html+='<hr id="z_h_'+data[i].wxReply.replyId+'">'
$("#context").append(html)
}
}
}
});
function del(type,object) {
if(type==0){
$.modal.confirm("确认要删除该评论吗?", function() {
$.operate.post(ctx + "/wechat/api/comment/remove", { "id": object});
$.modal.closeLoading();
$("#z_"+object).remove()
$("#z_h_"+object).remove()
})
}else {
$.modal.confirm("确认要删除该回复吗?", function() {
$.operate.post(ctx + "/wechat/api/comment/removeReply", { "id": object});
$.modal.closeLoading();
$("#z_"+object).remove()
$("#z_h_"+object).remove()
})
}
}
</script>
</body>
</html>
- 完成效果如下
至此就实现了类似微信朋友圈的评论回复功能,其中控制器查询比较繁琐,性能不佳但也实现了要求的功能。