1. 程式人生 > >小程式雲開發教程七:貼子的詳情及評論功能

小程式雲開發教程七:貼子的詳情及評論功能

我們先看看介面:
在這裡插入圖片描述

我們如果要實現評論功能, 先看一下總的資料結構:
在這裡插入圖片描述

那麼需要什麼引數呢?
引數如下

       comment: 評論內容
        username: 使用者名稱
        time: 評論時間
        userId: 使用者id
        id: 評論的貼子id
        avatar: 使用者頭像

先上程式碼, wxml:

<!--pages/itemDetail/itemDetail.wxml-->
<view class='flexDownC content'>
  <view class='content flexDownC w100'>
    <view class='userInfo flexRowL w100'>
      <view class='user flexC '>
        <image src='{{data.userImg || defaultImg}}' class='userImg'></image> {{data.username || '糗皮虎'}}</view>
    </view>
    <view class='txt'>{{data.content}}</view>
    <view class='img w100' wx:for="{{data.image}}" wx:for-item='imgItem'>
      <image lazy-load="{{lazy_load}}" mode='widthFix' src='{{(imgItem) || ""}}' class='{{data.image.length ==1 ?"dzImg1": data.image.length == 2 ?"dzimg2": data.image.length == 3 ? "dzImg3" : data.image.length == 4 ? "dzImg4": "" }} dzImg'></image>
    </view>
    <view class='btnsRow flexRowL'>
      <view class='ml20  flexC' bindtap='zan' data-id='{{data.id}}' data-vote='{{data.vote}}'>
        <image src='{{!voteFlag ? shareIconUrl: shareIconUrl1}}' class='btns ml20'></image>
        <text class='ml10'> {{data.vote || 0}}</text>
      </view>
      <view class='ml60  flexC'>
        <image src='../../images/comment.png' class='btns ml40'></image>
        <text class='ml10'> {{data.commentNum || 0}}</text>
      </view>
      <view class='ml60  flexC'>
        <label class='flexC'  data-qiuId='{{data.id}}'>
          <image src='../../images/share.png' class='btns ml40'></image>
           <button open-type='share' hidden='hidden'  data-qiuId='{{data.id}}' data-shareNum='{{data.shareNum}}'></button> 
        </label>
        <text class='ml10'> {{data.shareNum || 0}}</text>
      </view>
    </view>
  </view>
  <view class='garyLine'></view>
  <view class='comments flexDownC'>
    <view wx:if='{{data.comment.length > 0}}' class='com'>
      <view wx:for='{{data.comment}}' wx:key="{{index}}" class='comItem flexDownC'>
        <view class='userInfo flexRowL'>
          <view class='user flexC'>
            <image src='{{item.avatar || defaultImg}}' class='userImg'></image> {{item.username || '糗皮虎'}}</view>
        </view>
        <view class='txt'>{{item.comment}}</view>
        <view class='time textalignRight'>{{item.time}}</view>
      </view>
      
    </view>
    <view wx:else class='noComment'>
      暫無評論...
    </view>
  </view>
</view>

<view class='flexC w100' wx:if='{{isShareTip}}'>
  <button bindtap='navBack' class='navBtn'>回到首頁</button>
</view>

<view class='bottomInput flexC' >
  <input class='inputB' placeholder='友善發言的人運氣不會太差' placeholder-style='color:#ccc' maxlength='120' value='{{commentTxt}}' confirm-type='send' bindinput='inputHandler' bindconfirm='confirm'></input>
</view>

wxss: 引入首頁樣式,減少程式碼量

/* pages/itemDetail/itemDetail.wxss */

@import '../index/index.wxss';
.content{
  align-items: flex-start;
}
.noComment{
  font-size: 28rpx;
  margin-top: 30rpx;
  color: #ccc;
}

.comItem, .comments, .com{
  width: 100%;
}
.userImg{
  margin-right: 10rpx;
}

.comItem{
  padding:10rpx 20rpx;
  margin-top: 30rpx;
  margin-bottom: 20rpx;
  border-bottom: 1px solid #f7f7f7;
}
.navBtn{
  width: 80%;
  height: 80rpx;
  color: #fff;
  background: #ea9518;
  line-height: 80rpx;
  margin-top: 60rpx;
}

.comItem:last-child{
  border: none
}
.time{
  width: 100%;
  font-size: 24rpx;
  color: #ccc;
  margin-right: 50rpx;
}

.bottomInput{
  width: 100%;
  height: 100rpx;
}


.inputB{
  width: 95%;
  height: 80rpx;
  line-height: 80rpx;
  border: 1px solid #f4f4f4;
  border-radius: 10rpx;
  background: #f9f9f9;
}

js:

// pages/itemDetail/itemDetail.js
const db = wx.cloud.database()
const _ = db.command
var app = getApp()
const util = require('../../util/util.js');

Page({

  /**
   * 頁面的初始資料
   */
  data: {
    defaultImg: '../../images/tx.png',
    data: {},
    shareIconUrl: '../../images/zan.png',
    shareIconUrl1: '../../images/zan1.png',
    commentTxt: '',
    itemId: '',
    comments: [],
    isShareTip: false,
    voteFlag: false
  },

  /**
   * 生命週期函式--監聽頁面載入
   */
  onLoad: function (options) {

    if (options.isShareTip){
      this.setData({
        isShareTip: true
      })
    }
    if (options.id){
      this.setData({
        itemId: options.id
      })
      console.log(options.id)
      this.search(options.id)
    }

  },
  search: function(id){
    let idNum = 0;
    if (Number(id) || Number(id) == 0)
      idNum = Number(id)
    else
      idNum = this.data.itemId;
    db.collection('funnys').where({
      id: _.eq(idNum)
    }).get({
      success: res => {
        console.log(res)
        let D = res.data;

        this.setData({
          data: D[0]
        })
      },
      fail: function (e) {
        console.log(e)
      }
    })
  },
  inputHandler: function(e){
    console.log(e)
    this.setData({
      commentTxt: e.detail.value
    })
  },
  confirm: function(){
    const db = wx.cloud.database()
    const _ = db.command

    let userOpenId = wx.getStorageSync('openId')
 
    //傳送評論
    let d = new Date(),data = {};
    let arr = util.typeC(this.data.data.comment) == 'array' ? this.data.data.comment : new Array(this.data.data.comment);
    if (this.data.commentTxt){
      data = {
        comment: this.data.commentTxt,
        username: wx.getStorageSync('username'),
        time: d.getFullYear() + '-' + (d.getMonth() + 1) + '-' + d.getDate(),
        userId: wx.getStorageSync('userId'),
        id: this.data.itemId,
        avatar: wx.getStorageSync('avatar')
      }
      arr.push(data)
     
    }else
      wx.showToast({
        title: '請填寫內容',
        icon:'none'
      })

   
    if (!userOpenId){
     
      wx.showToast({
        title: '您還未登入,請先登入',
        icon: 'none'
      })
      setTimeout(()=>{
        wx.switchTab({
          url: '../me/me',
        })
      }, 1000)
    }else{
      var cn = this.data.data.comment.length + 1;
      db.collection('comments').add({
        data: {
          id: data.userId,
          userId: data.userId,
          text: data.comment,
          _openid: userOpenId
        },
        success: res=>{
          console.log('comment新增成功')
        },
        fail: e=>{
          console.log('comment新增失敗')
        }
      })
      wx.cloud.callFunction({
        name: 'comment',
        data: {
          comment: arr,
          id: this.data.itemId,
          commentNum: cn
        },        
        success: res => {
          wx.showToast({
            title: '評論成功',
          })  
          this.search()      
        },
        fail: err => {
          wx.showToast({
            icon: 'none',
            title: '評論失敗',
          })
          console.error('[雲函式] [comment] 呼叫失敗:', err)
        }
      })
    }
    console.log(data)
  },


  navBack: function(){
    wx.switchTab({
      url: '../index/index',
    })
  },

  /**
   * 使用者點選右上角分享
   */
  onShareAppMessage: function (res) {
    console.log(res)
    var that = this;
    if (res.from === "button") {
      wx.cloud.callFunction({
        name: 'shareHandler',
        data: {
          id: res.target.dataset.qiuid,
          shareNum: Number(res.target.dataset.sharenum) + 1
        },
        success: e => {
          wx.showToast({
            title: '分享成功',
          })
          that.search(that.data.pageId)
          console.log(e)
        },
        fail: e => {
          console.log(e)
        }
      })
      return {
        title: "我發現了一個好笑的東西,分享給你 --糗皮虎",
        path: '/pages/itemDetail/itemDetail?id=' + res.target.dataset.qiuid + '&isShareTip=1',
        imageUrl: ''
      }
    }
  },
  zan: function (e) {
    if (!this.data.voteFlag){
      var id = Number(e.currentTarget.dataset.id),
        vote = Number(e.currentTarget.dataset.vote)
        ;

      var that = this,
        D = this.data.data;
      D.vote = vote + 1

      wx.cloud.callFunction({
        name: 'zan',
        data: {
          data: {
            vote: vote + 1,
            id: id,
          }
        },
        success: res => {
          wx.showToast({
            title: '點贊成功',
          })
          that.setData({
            data: D,
            voteFlag: true
          })

        },
        fail: err => {
          wx.showToast({
            icon: 'none',
            title: '點贊失敗',
          })
          console.error('[雲函式] [zan] 呼叫失敗:', err)
        }
      })  
    }else{
      wx.showToast({
        title: '你已經投過票了',
        icon: 'none'
      })
    }
     

  },
})

我們仔細看看onload函式:
我們判斷路徑中是否有引數isShareTip, 有代表是通過分享出去的連結點選進來的, 那麼我們就必須給他一個回到首頁的按鈕;
然後判斷是否有id, 如果有,就進行資料庫搜尋,展示該條貼子;
沒有就不搜尋。

我們把search封裝成一個函式,適合呼叫。
我們看看評論功能:

  confirm: function(){
    const db = wx.cloud.database()
    const _ = db.command

    let userOpenId = wx.getStorageSync('openId')
 
    //傳送評論
    let d = new Date(),data = {};
    let arr = util.typeC(this.data.data.comment) == 'array' ? this.data.data.comment : new Array(this.data.data.comment);
    if (this.data.commentTxt){
      data = {
        comment: this.data.commentTxt,
        username: wx.getStorageSync('username'),
        time: d.getFullYear() + '-' + (d.getMonth() + 1) + '-' + d.getDate(),
        userId: wx.getStorageSync('userId'),
        id: this.data.itemId,
        avatar: wx.getStorageSync('avatar')
      }
      //把評論的資訊組成一個數組,通過雲函式的update函式更新
      arr.push(data)
     
    }else
      wx.showToast({
        title: '請填寫內容',
        icon:'none'
      })

   
    if (!userOpenId){
     
      wx.showToast({
        title: '您還未登入,請先登入',
        icon: 'none'
      })
      setTimeout(()=>{
        wx.switchTab({
          url: '../me/me',
        })
      }, 1000)
    }else{
      var cn = this.data.data.comment.length + 1;
      db.collection('comments').add({
        data: {
          id: data.userId,
          userId: data.userId,
          text: data.comment,
          _openid: userOpenId
        },
        success: res=>{
          console.log('comment新增成功')
        },
        fail: e=>{
          console.log('comment新增失敗')
        }
      })
      wx.cloud.callFunction({
        name: 'comment',
        data: {
          comment: arr,
          id: this.data.itemId,
          commentNum: cn
        },        
        success: res => {
          wx.showToast({
            title: '評論成功',
          })  
          this.search()      
        },
        fail: err => {
          wx.showToast({
            icon: 'none',
            title: '評論失敗',
          })
          console.error('[雲函式] [comment] 呼叫失敗:', err)
        }
      })
    }
    console.log(data)
  },

雲函式:

// 雲函式入口檔案
const cloud = require('wx-server-sdk')
cloud.init()
const db = cloud.database()



// 雲函式入口函式
exports.main = async (event, context) => {

  var comment = event.comment, id = event.id,
    commentNum = event.commentNum;
  console.log('雲函式comment成功', comment, id)

  // console.warn(data)

  try {
    return await db.collection('funnys').where({
      id: Number(id)
    }).update({
      data: {
        comment: comment,
        commentNum: commentNum
      },
      success: res => {
        console.log('雲函式comment成功', comment, id)

      },
      fail: e => {
        console.error(e)
      }
    })
  } catch (e) {
    console.error(e)
  }

}



現在, 稽核功能就完成了。

大家看在我碼字那麼辛苦的份上,順手給github點一個小星星唄