微信小程序仿知乎实现评论留言功能

最近沉迷学习无法自拔,太久没有码字,码一个小程序留言功能实现。先上一波最后效果图:

微信小程序仿知乎实现评论留言功能

微信小程序仿知乎实现评论留言功能

(删除按钮,是用户自己的留言时才会显示该按钮)

实现技术

后台:SSM框架

数据库:MySQL数据库

数据库设计

评论功能的实现主要涉及三个表

comment:存储留言评论信息,表结构如下:

微信小程序仿知乎实现评论留言功能

表中,必须的字段:id,user_id,reply_comment_id,comment,insert_time,source_id

添加了冗余字段username,reply_user_name,userphoto

主要用于存储微信名、回复的微信名、微信头像(这三个字段完全不应该冗余,当小程序用户更换用户名时,该表要跟着更新,可维护性差,不建议存储这些冗余信息,我就是懒得写SQL了)

source:存储你在小程序需要回复的内容。

user:存储小程序使用的用户信息,主要包括用户名、用户头像等微信用户信息。

小程序端

wxml

<scroll-view scroll-top="{{scrollTop}}" scroll-y="true" bindscrolltolower="bindDownLoad" bindscrolltoupper="refresh"> <view> <block wx:for="{{list}}" wx:key="{{index}}"> <view> <view> <image src="https://www.jb51.net/{{item.userPhoto}}" mode="aspectFit"></image> <view> <view> <view>{{item.userName}} <view wx:if="{{!item.replyUserName == \" \"}}"> -> {{item.replyUserName}} </view> </view> </view> </view> </view> <view> <view> {{item.comment}} </view> </view> <view> <view> <text decode="true">{{item.insertTime}}</text> </view> <view> <button data-commentId="{{item.id}}" data-commentUserName="{{item.userName}}" bindtap="bindReply">回复</button> </view> <view wx:if="{{item.userId == userId}}"> <text decode="true" bindtap='deleteComment' data-CommentId="{{item.id}}">删除</text> </view> </view> </view> </block> </view> </scroll-view> <form bindsubmit="submitForm" report-submit="true"> <view> <view wx:if="{{reply}}"> 回复<text>{{replyUserName}}</text> <button bindtap="cancleReply">取消回复</button> </view> <view> <textarea placeholder-class="input_null" fixed="true" maxlength="-1" show-confirm-bar="false" cursor-spacing="15" auto-height="true" placeholder="请输入回复"></textarea> <button form-type="submit">发送</button> </view> </view> </form>

css

.names { display: flex; font-size: 30rpx; line-height: 40rpx; } .input_null { color: #c9c9c9; } .replyAll { position:absolute; } .release { align-items: flex-end; /*底部对齐*/ box-sizing: border-box; position: fixed; left: 0; bottom: 0; width: 100%; padding: 18rpx 0 18rpx 30rpx; background-color: #f7f8f7; font-size: 28rpx; z-index: 999; } .replyinfo1{ display: flex; justify-content: space-between; /*两端对齐*/ font-size: 35rpx; } .replyinfo2{ display: flex; justify-content: space-between; /*两端对齐*/ } .release textarea { width: 550rpx; min-height: 34rpx; max-height: 102rpx; /*最多显示三行*/ border-width: 15rpx 20rpx; /*使用padding与预期留白不一致,故使用border*/ border-style: solid; border-color: #fff; line-height: 34rpx; font-size: 28rpx; background-color: #fff; border-radius: 4rpx; } .release .text { font-size: 40rpx; color: #c9c9c9; } .cancel { width: 240rpx; height: 64rpx; line-height: 64rpx; text-align: center; color: #6c0; margin: 0 3px; padding: 0; } .release .submit { width: 120rpx; height: 64rpx; line-height: 64rpx; text-align: center; color: #6c0; margin: 0 3px; padding: 0; } .pro-box .info .text .delete { color: #f68135; border-radius: 50rpx; border: 1px solid #f68135; font-size: 28 rpx; width: 150rpx; height: 48rpx; text-align: center; }

js

// pages/comment/comment.js const model = require('../cityChoose/cityChoose.js') const config = require('../../utils/config.js') const util = require('../../utils/util.js') const app = getApp() var mydata = { end: 0, replyUserName: "" } Page({ /** * 页面的初始数据 */ data: { list: [], }, /** * 生命周期函数--监听页面加载 */ onLoad: function(options) { var that = this; mydata.sourceId = options.sourceId mydata.commentId = ""; mydata.replyUserName = ""; //设置scroll的高度 wx.getSystemInfo({ success: function(res) { that.setData({ scrollHeight: res.windowHeight, userId:app.globalData.haulUserInfo.id }); } }); mydata.page = 1; that.getPageInfo(mydata.page); }, /** * 页面下拉刷新事件的处理函数 */ refresh: function() { console.log('refresh'); mydata.page = 1 this.getPageInfo(mydata.page, function() { this.setData({ list: [] }) }); mydata.end = 0; }, /** * 页面上拉触底事件的处理函数 */ bindDownLoad: function() { console.log("onReachBottom"); var that = this; if (mydata.end == 0) { mydata.page++; that.getPageInfo(mydata.page); } }, bindReply: function(e) { console.log(e); mydata.commentId = e.target.dataset.commentid; mydata.replyUserName = e.target.dataset.commentusername; this.setData({ replyUserName: mydata.replyUserName, reply: true }) }, // 合并数组 addArr(arr1, arr2) { for (var i = 0; i < arr2.length; i++) { arr1.push(arr2[i]); } return arr1; }, deleteComment:function(e){ console.log(e); var that = this; var commentId = e.target.dataset.commentid; wx.showModal({ title: '删除评论', content: '请确认是否删除该评论?', success: function (res) { if (res.confirm) { wx.request({ url: config.deleteComment, method: "POST", data: { commentId: commentId }, header: { "content-type": "application/x-www-form-urlencoded;charset=utf-8", }, success: res => { that.refresh(); wx.showToast({ title: "删除成功" }) } }) } else if (res.cancel) { console.log('用户点击取消') } } }) }, cancleReply: function(e) { mydata.commentId = ""; mydata.replyUserName = ""; this.setData({ replyUserName: mydata.replyUserName, reply: false }) }, // 更新页面信息 // 此处的回调函数在 传入新值之前执行 主要用来清除页面信息 getPageInfo(page, callback) { var that = this; util.showLoading(); console.log("getPageInfo"); console.log("page" + page); var limited = 6; var offset = (page - 1) * 6; wx.request({ url: config.getComments, method: "POST", data: { sourceId: mydata.sourceId, limited: limited, offset: offset }, header: { "content-type": "application/x-www-form-urlencoded;charset=utf-8", }, success: res => { console.log(res); if (page == 1) { that.data.list = res.data; that.setData({ list: that.data.list }) mydata.end = 0; } else { // 当前页为其他页 var list = that.data.list; if (res.data.length != 0) { list = that.addArr(list, res.data); that.setData({ list: list }) mydata.end = 0; } else { mydata.end = 1; } } wx.hideLoading(); } }) }, submitForm(e) { var form = e.detail.value; var that = this; console.log(app.globalData.haulUserInfo); if(form.comment == ""){ util.showLog('请输入评论'); return; } // 提交评论 wx.request({ url: config.insertComment, method: "POST", data: { sourceId: mydata.sourceId, comment: form.comment, userId: app.globalData.haulUserInfo.id, userName: app.globalData.haulUserInfo.userName, replyCommentId: mydata.commentId, replyUserName: mydata.replyUserName, userPhoto: app.globalData.haulUserInfo.userPhoto }, header: { "content-type": "application/x-www-form-urlencoded;charset=utf-8", //token: app.globalData.token }, success: res => { console.log(res) if (res.data.success) { wx.showToast({ title: "回复成功" }) that.refresh(); mydata.commentId = ""; mydata.replyUserName = ""; this.setData({ replyUserName: mydata.replyUserName, reply: false }) } else { wx.showToast({ title: '回复失败,请检查您的网络', }) } } }) } })

后台

后台功能:获取评论、删除评论、插入评论,都是简单的数据库操作,放在一个controller类中实现即可

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:http://www.heiqu.com/fdc58d5f1a882ba55c2f8cf50a964bcb.html