温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

怎么在微信小程序中实现评论留言功能

发布时间:2021-06-01 17:57:18 来源:亿速云 阅读:4316 作者:Leah 栏目:web开发

怎么在微信小程序中实现评论留言功能?相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。

数据库设计

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

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"  class="list" bindscrolltolower="bindDownLoad" bindscrolltoupper="refresh">  <view class="pro-con">  <block wx:for="{{list}}" wx:key="{{index}}">   <view class="pro-box">   <view class="head">    <image class="img" src="{{item.userPhoto}}" mode="aspectFit"></image>    <view class="box">    <view class="shead clear">     <view class="names fl">{{item.userName}}      <view wx:if="{{!item.replyUserName == \" \"}}">      -> {{item.replyUserName}}     </view>     </view>    </view>    </view>   </view>   <view class="addr-info">    <view class="addr-text">    {{item.comment}}    </view>   </view>   <view class="info">    <view class="text">    <text decode="true">{{item.insertTime}}</text>    </view>    <view class="text">    <button class="sharebtn" data-commentId="{{item.id}}" data-commentUserName="{{item.userName}}" bindtap="bindReply">回复</button>    </view>     <view wx:if="{{item.userId == userId}}" class="status text fr">     <text class="delete" decode="true" bindtap='deleteComment' data-CommentId="{{item.id}}">删除</text>     </view>   </view>   </view>  </block>  </view> </scroll-view> <form bindsubmit="submitForm" report-submit="true">  <view class="release">  <view wx:if="{{reply}}" class="replyinfo1">   回复<text class="text">{{replyUserName}}</text>   <button class="cancel" bindtap="cancleReply">取消回复</button>  </view>  <view class="replyinfo2">   <textarea placeholder-class="input_null" fixed="true" maxlength="-1" show-confirm-bar="false" cursor-spacing="15" auto-height="true" placeholder="请输入回复" name="comment"></textarea>   <button form-type="submit" class="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类中实现即可

package com.melon.haul.web;   import java.sql.Date; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map;   import javax.servlet.http.HttpServletRequest;   import net.sf.json.JSONObject;   import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.test.context.web.WebAppConfiguration; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.ResponseBody; import org.slf4j.Logger; import org.slf4j.LoggerFactory;   import com.melon.haul.dto.DataUtil; import com.melon.haul.dto.GetLocation; import com.melon.haul.dto.Result; import com.melon.haul.entity.Comment; import com.melon.haul.entity.District; import com.melon.haul.entity.Source; import com.melon.haul.service.CommentService; import com.melon.haul.service.DistrictService; import com.melon.haul.service.SourceService;   @Controller @WebAppConfiguration @RequestMapping("/Comment") public class CommentController {  private Logger logger = LoggerFactory.getLogger(this.getClass());    @Autowired  private CommentService commentService;    @RequestMapping(value = "/getComments", method = RequestMethod.POST)  private @ResponseBody List<Comment> getComments(@RequestParam("sourceId") int sourceId,  @RequestParam("limited") int limited,@RequestParam("offset") int offset) {  logger.info("getComments");  List<Comment> list = new ArrayList<Comment>();  try{  list = commentService.getComment(sourceId, limited, offset);  }catch(Exception e){    }  return list;  }    @RequestMapping(value = "/insertComment", method = RequestMethod.POST)  private @ResponseBody  Result<Map<String,String>>insertComment(@RequestParam("sourceId") String sourceId,  @RequestParam("comment") String comment,@RequestParam("userId") int userId,  @RequestParam("userName") String userName,@RequestParam("replyCommentId") String replyCommentId,  @RequestParam("replyUserName") String replyUserName,@RequestParam("userPhoto")String userPhoto) {  logger.info("insertComment");  Map<String, String> resultMap = new HashMap<String, String>();  try{  Integer rCId = -1;  if(!replyCommentId.equals(""))  rCId = Integer.parseInt(replyCommentId);  commentService.insertComment(Integer.parseInt(sourceId), comment, userId,userName,rCId,replyUserName,userPhoto);  resultMap.put("msg", "insertComment success");  }catch(Exception e){  System.out.print(e);  resultMap.put("msg", "insertComment error");  }  return new Result<Map<String, String>>(true, resultMap);  }    @RequestMapping(value = "/deleteComment", method = RequestMethod.POST)  private @ResponseBody  Result<Map<String,String>>deleteComment(@RequestParam("commentId") String commentId) {  logger.info("deleteComment");  Map<String, String> resultMap = new HashMap<String, String>();  try{  commentService.deleteComment(commentId);  resultMap.put("msg", "deleteComment success");  }catch(Exception e){  System.out.print(e);  resultMap.put("msg", "deleteComment error");  }  return new Result<Map<String, String>>(true, resultMap);  } }

公共CSS(app.wxss)

 /**app.wxss**/ .container {  height: 100%;  display: flex;  flex-direction: column;  align-items: center;  justify-content: space-between;  padding: 200rpx 0;  box-sizing: border-box; }  /* large button style */ .large-btn{  background: #f68135;  border-radius: 50rpx;  border: 1px solid #f68135;  color: #fff;  height: 100rpx;  line-height: 100rpx;  margin: 0 auto;  width: 96%;  text-align: center; } .large-btn.empty{  background: transparent;  color: #f68135;  margin-top: 50rpx; } .large-btn.disabled{  border-color: #ccc;  background: #ccc;  color: #fff; } /* public style to clear default styles */ .fl{  float: left; } .fr{  float: right; } .fc{  float:none; } .col-gray{  color: #999!important; }     /* the message of auction about goods & cars */ .pro-con{  padding: 20rpx;  background: #f1f1f1; } .pro-box{  background: #fff;  padding: 20rpx;  box-sizing: border-box;  border-radius: 10rpx;  margin-bottom: 20rpx; } .pro-box .img{  display: inline-block;  vertical-align: top;  width: 80rpx;  height: 80rpx;  border-radius: 50%;  overflow: hidden;  margin-right: 10rpx; } .pro-box .box{  display: inline-block;  vertical-align: top;  width: calc(98% - 80rpx); } .pro-box .shead{  padding-bottom: 20rpx; } .pro-box .shead .name{  font-size: 30rpx;  line-height: 40rpx; } .pro-box .shead .stxt{  font-size: 26rpx;  color: #999; } .pro-box .shead .fr{  padding-top: 10rpx; } .pro-box .shead .fr navigator{  font-size: 0; } .pro-box .shead .fr image{  width: 48rpx;  height: 48rpx; }  .pro-box .sharebtn{  height:48rpx;  background: #f68135;  border-radius: 50rpx;  border: 1px solid #f68135;  color: #fff;  text-align: center;  line-height: 50rpx;  font-size:30rpx; }    .pro-box .addr-info{  align-items: center;  justify-content: space-between;  border-bottom: 1px dashed #ccc;  margin: 0 -20rpx;  margin-bottom: 20rpx;  padding-bottom: 20rpx;  padding-left: 20rpx;  padding-right: 20rpx;  display: inline-block; }   .pro-box .addr-info .addr-text{  font-size: 35rpx;  line-height: 40rpx;  width:100%; }  .pro-box .addr-info .addr-text .color1{  color:lightskyblue;  border-color: #ccc;  border: 1px solid lightskyblue;  border-radius:15px;  margin-right: 5px;  padding: 0rpx,2rpx,0rpx,2rpx; }  .pro-box .addr-info .addr-text .color2{  color: #f68135;  border-color: #ccc;  border: 1px solid #f68135;  border-radius:10px;  margin-right: 5px;  margin-left: 5px;  padding: 0rpx,2rpx,0rpx,2rpx; }    .pro-box .position{  width: 48rpx;  height: 48rpx; }    .pro-box .comment{  width: 55rpx;  height: 48rpx; }    .pro-box .addr{  align-items: center;  justify-content: space-between;  border-bottom: 1px dashed #ccc;  margin: 0 -20rpx;  margin-bottom: 20rpx;  padding-bottom: 20rpx;  padding-left: 20rpx;  padding-right: 20rpx;  display: flex; }   .pro-box .addr .addr-text{  font-size: 34rpx;  line-height: 40rpx;  max-width: 240rpx;  min-width:200rpx;  overflow: hidden;  text-overflow: ellipsis;  white-space: nowrap; } .pro-box .addr .addr-text .color-text{  color: #f68135; } .pro-box .addr .time{  font-size: 26rpx;  line-height: 36rpx;  text-align: center; } .pro-box .addr .line{  background: #ccc;  height: 1px;  margin: 6rpx -20rpx;  position: relative; } .pro-box .info{  display: flex;  align-items: center;  justify-content: space-between; } .pro-box .info .text{  vertical-align:text-top;  font-size: 26rpx; } .pro-box .info .text .delete{  color: #f68135;  border-radius: 50rpx;  border: 1px solid #f68135;  width: 100rpx;  height: 48rpx;  text-align: center; }

看完上述内容,你们掌握怎么在微信小程序中实现评论留言功能的方法了吗?如果还想学到更多技能或想了解更多相关内容,欢迎关注亿速云行业资讯频道,感谢各位的阅读!

向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI