1. 程式人生 > >只用一天就能搭建你的論壇小程式!

只用一天就能搭建你的論壇小程式!

歡迎大家前往騰訊雲+社群,獲取更多騰訊海量技術實踐乾貨哦~

本文由達文西發表

筆者最近涉獵了小程式相關的知識,於是利用週末時間開發了一款類似於同事的小程式,深度體驗了小程式雲開發模式提供的雲函式、資料庫、儲存三大能力。關於雲開發,可參考文件:小程式·雲開發

個人感覺雲開發帶來的最大好處是鑑權流程的簡化和對後端的弱化,所以像筆者這種從未接觸過小程式開發的人也能夠在週末兩天時間內開發出一個功能完備、體驗閉環的勉強能用的產品。

最後,本文並不是搬運官方文件,也不會詳細介紹開發工具和雲開發後臺的使用,所以建議結合上面給出文件連結一起消化本文。

功能分析

img

該小程式功能目前較為簡單(釋出帖子、瀏覽帖子、釋出評論),可用下圖表示,無需贅述:

img

由架構圖可知,雲開發的資料庫(存帖子、存評論)、儲存(圖片)、雲函式(讀、寫、更新資料庫等)都將涉及,很好地達到了練手的目的

釋出帖子

如果帖子不帶圖片,直接寫資料庫即可,如果帶圖片則需要先存入圖片到雲開發提供的儲存中,拿到返回的fileId(可理解為圖片的url)再一併寫入資料庫,核心程式碼:

    for (let i = 0; i < img_url.length; i++) {
      var str = img_url[i];
      var obj = str.lastIndexOf("/");
      var fileName = str.substr(obj + 1)
      console.log(fileName)
      wx.cloud.uploadFile({
        cloudPath: 'post_images/' + fileName,//必須指定檔名,否則返回的檔案id不對
        filePath: img_url[i], // 小程式臨時檔案路徑
        success: res => {
          // get resource ID: 
          console.log(res)
          //把上傳成功的圖片的地址放入陣列中
          img_url_ok.push(res.fileID)
          //如果全部傳完,則可以將圖片路徑儲存到資料庫
          if (img_url_ok.length == img_url.length) {
            console.log(img_url_ok)
            that.publish(img_url_ok)
          }
        },
        fail: err => {
          // handle error
          console.log('fail: ' + err.errMsg)
        }
      })
    }  

通過img_url_ok.length == img_url.length我們確定所有圖片已經上傳完成並返回了對應的id,然後執行寫入資料庫的操作:

  /**
   * 執行釋出時圖片已經上傳完成,寫入資料庫的是圖片的fileId
   */
  publish: function(img_url_ok) {
    wx.cloud.init()
    wx.cloud.callFunction({
      name: 'publish_post',
      data: {
        openid: app.globalData.openId,// 這個雲端其實能直接拿到
        author_name: app.globalData.userInfo.nickName,
        content: this.data.content,
        image_url: img_url_ok,
        publish_time: "",
        update_time: ""//目前讓伺服器自己生成這兩個時間
      },
      success: function (res) {
        // 強制重新整理,這個傳參很粗暴
        var pages = getCurrentPages();             //  獲取頁面棧
        var prevPage = pages[pages.length - 2];    // 上一個頁面
        prevPage.setData({
          update: true
        })
        wx.hideLoading()
        wx.navigateBack({
          delta: 1
        })
      },
      fail: console.error
    })
  },

通過wx.cloud.callFunction我們呼叫了一個雲函式(通過name指定函式名),並將帖子內容content和圖片image_url以及其他資訊(釋出者暱稱、id等)一併傳到雲端。然後再看看這個雲函式:

exports.main = async (event, context) => {
  try {
    return await db.collection('post_collection').add({
      // data 欄位表示需新增的 JSON 資料
      data: {
        // 釋出時小程式傳入
        //author_id: event.openid,不要自己傳,用sdk自帶的
        author_id: event.userInfo.openId,
        author_name: event.author_name,
        content: event.content,
        image_url: event.image_url,
        // 伺服器時間和本地時間會造成什麼影響,需要評估
        publish_time: new Date(),
        // update_time: event.update_time,// 最近一次更新時間,釋出或者評論觸發更新,目前用伺服器端時間
        update_time: new Date(),
        // 預設值,一些目前還沒開發,所以沒設定
        // comment_count: 0,//評論數,直接讀資料庫,避免兩個資料表示同一含義
        watch_count: 3,//瀏覽數
        // star_count: 0,//TODO:收藏人數
      }
    })
  } catch (e) {
    console.error(e)
  }
}

可以看到,雲函式寫入了一條資料庫記錄,我們的引數通過event這個變數帶了進來。

獲取帖子列表

所謂獲取帖子列表其實就是讀上一節寫入的資料庫,但是我們並不需要全部資訊(例如圖片url),並且要求按照時間排序,如果熟悉資料庫的話,會發現這又是一條查詢語句罷了:

exports.main = async (event, context) => {
  return {
    postlist: await db.collection('post_collection').field({// 指定需要返回的欄位
      _id: true,
      author_name: true,
      content: true,
      title: true,
      watch_count: true
    }).orderBy('update_time', 'desc').get(),//指定排序依據

  }
}

瀏覽帖子內容

瀏覽帖子內容及給定一個帖子的id,由帖子列表點選時帶入:

  onItemClick: function (e) {
    console.log(e.currentTarget.dataset.postid)
    wx.navigateTo({
      url: '../postdetail/postdetail?postid=' + e.currentTarget.dataset.postid,
    })
  },

然後在雲函式中根據這個id拿到全部資料:

exports.main = async (event, context) => {
  
  return {
    postdetail: await db.collection('post_collection').where({
      _id: event.postid
    }).get(),
  }
}

拿到全部資料後,再根據圖片id去載入貼子的圖片:

    // 獲取內容
    wx.cloud.callFunction({
      // 雲函式名稱 
      name: 'get_post_detail',
      data: {
        postid: options.postid
      },
      success: function (res) {
        var postdetail = res.result.postdetail.data[0];
        that.setData({
          detail: postdetail,
          contentLoaded: true
        })
        that.downloadImages(postdetail.image_url)
      },
      fail: console.error
    })

這裡that.downloadImages(postdetail.image_url)即載入圖片:

  /**
   * 從資料庫獲取圖片的fileId,然後去雲端儲存下載,最後加載出來
   */
  downloadImages: function(image_urls){
    var that = this
    if(image_urls.length == 0){
      return
    } else {
      var urls = []
      for(let i = 0; i < image_urls.length; i++) {
        wx.cloud.downloadFile({
          fileID: image_urls[i],
          success: res => {
            // get temp file path
            console.log(res.tempFilePath)
            urls.push(res.tempFilePath)
            if (urls.length == image_urls.length) {
              console.log(urls)
              that.setData({
                imageUrls: urls,
                imagesLoaded: true
              })
            }
          },
          fail: err => {
            // handle error
          }
        })
      }
    }
  },

發表評論

發表評論和釋出帖子邏輯類似,只是寫入的資料不同,不做贅述。

總結

前面說過,雲開發弱化了後端(簡化鑑權本質也是弱化後端),這樣帶來的好處就是提高了開發效率,因為前後端聯調向來都是一件耗時間的事情,而且小程式本身主打的就是小型應用,實在沒有必要引入過多的開發人員。但云開發也不是萬能的,例如我一開始想做RSS閱讀器,那麼後端就需要聚合資訊,目前雲開發還做不了。個人感覺只要是資訊類的小程式,如新聞類、視訊類,雲開發目前都很乏力,因為資料庫的支援還過於簡陋(也可能是我太菜,沒發現很好的解決辦法,歡迎拍磚)。但如果是本文提及的這種使用者自己也會產生資訊的小程式,那麼雲開發則會有開發效率上的優勢。最後就是雲開發目前提供的2G資料庫和5G儲存,對於一些使用者量較多的小程式是否足夠也是個問題,目前也沒見有付費版。

此文已由作者授權騰訊雲+社群釋出,更多原文請點選

搜尋關注公眾號「雲加社群」,第一時間獲取技術乾貨,關注後回覆1024 送你一份技術課程大禮包!