先看實現的效果圖



評論及評論回復實現
- 分析
評論和評論回復可以設計成1張表也可以設計成2張表,根據使用場景的不同選擇,這里我將評論和回復表設計成一張表,表結構如下
CREATE TABLE `tb_post_newcomment` (
`post_comment_id` int(11) NOT NULL AUTO_INCREMENT COMMENT '說說評論表id',
`group_post_id` int(11) DEFAULT NULL COMMENT '說說id',
`uid` int(11) DEFAULT NULL COMMENT '用戶id',
`nickname` varchar(50) DEFAULT NULL COMMENT '用戶昵稱',
`avatar_url` varchar(255) DEFAULT NULL COMMENT '用戶頭像地址',
`content` varchar(255) DEFAULT NULL COMMENT '評論內容',
`createtime` datetime DEFAULT NULL COMMENT '創建時間',
`status` varchar(2) DEFAULT NULL COMMENT '狀態 -1已刪除 0正常',
`to_uid` int(11) DEFAULT NULL COMMENT '目標用戶id ',
`to_user_nickname` varchar(50) DEFAULT NULL COMMENT '目標用戶昵稱 沉余字段',
`to_user_avatar` varchar(255) DEFAULT NULL COMMENT '目標用戶頭像 沉余字段',
PRIMARY KEY (`post_comment_id`)
) ENGINE=InnoDB AUTO_INCREMENT=67 DEFAULT CHARSET=utf8mb4 COMMENT='動態評論';
其中最主要的是字段需要包含用戶id和目標用戶id,當然還有評論內容content字段,用戶id和目標用戶id這里可以理解成是誰評論了誰或誰回復了誰
- 設計完表結構之后,再來看代碼實現
在小程序頁面里
doNewComment(){
let content = this.commentContent;
if(!content){
return;
}
api.postNewComment({
uid:this.userid,
postid:this.curPostItem.group_post_id,
post_user_id:this.curPostItem.uid,//當前這條動態所屬人 用於消息通知
content:this.commentContent,
nickname:this.xuserInfo.nickname,
avatar_url:this.xuserInfo.head_url,
to_uid:this.curCommentItem?this.curCommentItem.uid:0,//默認值0 ,為空時傳0
to_user_nickname:this.curCommentItem?this.curCommentItem.nickname:'',
to_user_avatar:this.curCommentItem?this.curCommentItem.avatar_url:'',
}).then(res=>{
if(res.code==0){
this.curPostItem.comments.push(res.data);
this.commentContent = '';
this.isShowComment = false;
}
})
},
這里需要注意的是,如果是評論的話,我們將目標用戶id設置為空,回復的話則將要回復的目標id傳過去。
在小程序后端,通過接受前端傳過來的數據,將其保存到數據庫表中,保存成功后更新評論表的count字段,最后返回當前評論對象到前端進行頁面顯示
if (result.affectedRows === 1) {
// 更新說說表評論數量
let postResult = await this.app.mysql.select('tb_group_posts', {
where: { group_post_id: group_post_id }
})
let comment_count = postResult[0].comment_count;
comment_count += 1;
await this.app.mysql.update('tb_group_posts', { comment_count: comment_count }, {
where: {
group_post_id: group_post_id
}
});
// 返回當前評論記錄
let commentResult = await this.app.mysql.select('tb_post_newcomment', {
where: { post_comment_id: result.insertId }
})
return commentResult[0];
}
前端評論及回復頁面展示
<ul class="comment-list" v-if="item.comments.length>0">
<li class="comment-item" v-for="(comment,commentIndex) in item.comments" :key="commentIndex" @click="replyShow(comment);getCurPostItem(item)">
<div v-if="comment.to_uid!=0"><span class="nickname">{{comment.nickname}}</span>回復<span class="nickname">{{comment.to_user_nickname}}</span>:{{comment.content}}</div>
<div v-else><span class="nickname">{{comment.nickname}}</span>:{{comment.content}}</div>
</li>
</ul>
消息通知實現
我們創建一個消息通知表,當我們點贊和評論的時候,創建一條消息通知記錄,表結構設計如下
CREATE TABLE `tb_notify` (
`notify_id` int(11) NOT NULL AUTO_INCREMENT COMMENT '通知id',
`content` varchar(1000) DEFAULT NULL COMMENT '消息內容 公告和私信類型的消息使用',
`type` varchar(2) DEFAULT NULL COMMENT '通知類型 1、公告 2、提醒 3、私信',
`target_id` int(11) DEFAULT NULL COMMENT '目標id(如post的id)',
`action` varchar(2) DEFAULT NULL COMMENT '1、點贊 2、評論 3、回復 4、關注',
`sender_id` int(11) DEFAULT NULL COMMENT '發送者id',
`sender_type` varchar(2) DEFAULT NULL COMMENT '發送者類型 1普通用戶 2管理員',
`user_id` int(11) DEFAULT NULL COMMENT '消息所屬者,如post動態發布者',
`is_read` varchar(2) DEFAULT NULL COMMENT '消息是否已讀 0未讀 1已讀',
`created_at` datetime DEFAULT NULL COMMENT '創建時間',
`nickname` varchar(50) DEFAULT NULL COMMENT '發送者昵稱',
`avatar_url` varchar(255) DEFAULT NULL COMMENT '發送者頭像',
`comment_id` int(11) DEFAULT NULL COMMENT '評論id 評論的時候存儲',
PRIMARY KEY (`notify_id`)
) ENGINE=InnoDB AUTO_INCREMENT=120 DEFAULT CHARSET=utf8mb4 COMMENT='通知消息';
- 一般消息通知分為公告、提醒和私信三個類別的通知消息 ,type字段用於存儲消息通知類型
- action用來保存動作,例如,點贊、評論、回復或關注
- user_id用來存儲該條消息的接收者 ,如評論回復的目標用戶id,如沒有目標用戶id,則消息所屬人為該條動態的發布者
- is_read表示的是消息讀取狀態 ,已讀和未讀
- sender_id就是消息發送者id了 ,誰觸發的這個動作 ,評論人、點贊的人
后端邏輯代碼如下
try {
let result = await this.GroupService.postNewComment(params);
if (result) {
// 消息通知目標人 根據to_uid判斷 0的話說明是評論 則消息通知目標人為動態發布者,否則的話消息通知目標人為to_uid
let notify_user_id = params.to_uid ? params.to_uid : params.post_user_id;
let notifyObj = {
comment_id: result.post_comment_id,//評論id
content: params.content,//評論內容
type: '2',//1、公告 2、提醒 3、私信
target_id: params.postid,
//action 1點贊 2評論 3回復 4關注
action: params.to_uid?'3':'2',
sender_id: params.uid,//發送者id
nickname: params.nickname,
avatar_url: params.avatar_url,
is_read: '0',
user_id: notify_user_id,//消息所屬人
}
// 添加消息通知 如果是自己則不創建通知消息
if (params.uid != notify_user_id) {
await this.NotifyService.add(notifyObj);
}
// 返回當前評論記錄
response = this.ResultResponse.createBySuccessData(result);
} else {
response = this.ResultResponse.createByErrorMsg('評論失敗');
}
對於消息創建,如果是我們自己評論了自己,則此時不用去創建消息通知,只有在別人評論或者回復的時候去創建
前端頁面展示及邏輯
<div class="action" v-if="list.length>0">
<span v-text="lastUnreadNotify.nickname"></span>
<span v-text="lastUnreadNotify.action==1?'贊了你的動態':lastUnreadNotify.action==2?'評論了你的動態':lastUnreadNotify.action==3?'回復了你的評論':'關注了你'"></span>
</div>
我們在小程序首頁mounted方法里面創建一個定時器,每5秒或者10去請求一次未讀消息接口,如果有未讀消息則設置底部消息欄小紅點提醒
// 輪詢 每15秒請求一次
this.setNotifyRemind();
setInterval(() => {
this.setNotifyRemind();
}, 15000);
loadData(){
api.unReadNotifyList({
uid:this.uid
}).then(res=>{
if(res.code==0){
this.list = res.data
if(this.list.length>0){
this.lastUnreadNotify = this.list[0];
// 設置tab小紅點
wx.setTabBarBadge({index: 3,text: `${this.list.length}`})
}else{
wx.removeTabBarBadge({index: 3})
}
}
wx.stopPullDownRefresh();
})
},
當點擊消息列表的時候再將用戶通知消息全部設置為已讀狀態就可以了
最后
以上就實現了小程序的評論、評論回復及消息通知的功能,這在小程序里面都是很常見的功能,特別是在社交小程序當中,當然,從表結構的設計到頁面的展示還有很多不完善考慮不周的情況,也只有在以后的使用過程中發現問題再去優化了 。
參考閱讀
https://www.cnblogs.com/Renyi-Fan/p/9057170.html
https://www.codercto.com/a/24135.html