▌ leads

Have been interested in small program development, is ready to do before a belongs to own little program, but also need to purchase a cloud server and deploy the background, a little bit of a problem, since I know that with the development of cloud the server set up and operational of one-stop back-end cloud services “artifact”, is the momentum spent several weekend time to do a blog applet, If you want to build your own blog, you should read this article.

The Introduction of blogging mini program

Main functions:

Including article publishing and browsing, comments, likes, browsing history, classification, leaderboards, sharing, generating posters and so on.

Effect display:

Database Design

The database consists of seven tables, which are: user table, classification table, article table, article content table, comment table, like table and historical browsing table.

Comment on the feature design

Using the article comment function as an example, let’s look at the entire process of code and applet cloud development.

1. Implementation ideas

At the beginning of the implementation of the idea is to prepare two tables, a comment main table, a reply to the comment of the sub-table, later thought that it is not so complicated, in fact, with a table can also achieve the comment and reply function.

2. Code implementation

There are three kinds of comments. The first is to comment on an article, which is a grade 1 comment, the second is to comment on others’ comments, which is a grade 2 comment, and the third is to reply to others’ comments, which is a grade 3 comment.

2.1 How Do I Add a Comment

Combined with the above picture, let’s look at the code again, it is very clear.

/** * Post comments */
submit() {
    var comment = this.data.inputData
    if (comment == ' ') {
      wx.showToast({
        title: 'Please fill out a comment'.icon: 'none'})}else {
      console.log("My comments:" + this.data.inputData)
      var type = this.data.type;
      if (type == 1) { // 1
        this.replyComment(1)}else if (type == 2) {
        this.replyComment(2) // 2 is to reply to others' comments
      } else if (type == 3) { // 3 is a first-class review of the review article
        this.addComment(); }}},/** * Add comments */
  addComment() {
    var _this = this;
    var openid = wx.getStorageSync("openid")
    wx.showLoading({
      title: 'Loading... ',})var create_date = util.formatTime(new Date());
    console.log(The current time is: + create_date);
    var timestamp = Date.parse(new Date());
    timestamp = timestamp / 1000;
    console.log("Current timestamp is:" + timestamp);
    // Call the cloud function
    wx.cloud.callFunction({
      name: 'addComment'.data: {
        //_id: timestamp + _this.data.otherUserInfo._id,
        id: _this.data.articleDetail._id,
        _openid: openid,
        avatarUrl: _this.data.userInfo.avatarUrl,
        nickName: _this.data.userInfo.nickName,
        comment: _this.data.inputData,
        create_date: create_date,
        flag: 0.article_id: _this.data.articleDetail.article_id,
        timestamp: timestamp,
        childComment: []},success: res= > {
        Res.data contains the data for this record
        console.log("Comment added successfully --")
        wx.showToast({
          title: 'Comment submitted successfully',

        })
        wx.navigateBack({
          delta: 1})},fail: err= > {
        console.error('[cloud function] call failed ', err)
      },
      complete: res= > {
        wx.hideLoading()
      }
    })
  },
  /** * Reply to comments */
  replyComment(commentType) {
    var _this = this;
    wx.showLoading({
      title: 'Loading... ',})var create_date = util.formatTime(new Date());
    console.log(The current time is: + create_date);
    var timestamp = Date.parse(new Date());
    timestamp = timestamp / 1000;
    wx.cloud.callFunction({
      name: 'replyComment'.data: {
        id: _this.data.articleDetail._id,
        _id: _this.data.otherUserInfo._id,
        avatarUrl: _this.data.userInfo.avatarUrl,
        nickName: _this.data.userInfo.nickName,
        openId: _this.data.openid,
        comment: _this.data.inputData,
        createDate: create_date,
        flag: commentType,
        opposite_avatarUrl: _this.data.otherUserInfo.avatarUrl,
        opposite_nickName: _this.data.otherUserInfo.nickName,
        opposite_openId: _this.data.otherUserInfo._openid,
        timestamp: timestamp,
      },
      success: res= > {
        Res.data contains the data for this record
        console.log("Comment returned successfully --")
        wx.showToast({
          title: 'Reply submitted successfully',
        })
        wx.navigateBack({
          delta: 1})},fail: err= > {
        console.error('[cloud function] call failed ', err)
      },
      complete: res= > {
        wx.hideLoading()
      }
    })
  },
Copy the code

The following two cloud functions are used to add comments and reply to comments, mainly using the async and await functions. After the async and await functions are finished, update the comment field in the article table by adding 1 to it. The advantage of async and await functions is that they can be done in order.

// Add comment cloud function
const cloud = require('wx-server-sdk')
var env = 'hsf-blog-product-xxxxx'; // Formal environment
// var env = 'xxxxxxxxxxxxx'; // Test environment
cloud.init({
  env: env
})
const db = cloud.database()
const _ = db.command
exports.main = async(event, context) => {
  try {
    let res = await db.collection('comment').add({
      data: {
        _openid: event._openid,
        avatarUrl: event.avatarUrl,
        nickName: event.nickName,
        comment: event.comment,
        create_date: event.create_date,
        flag: event.flag,
        article_id: event.article_id,
        timestamp: event.timestamp,
        childComment: [],
      }
    }).then(res= > {
      return res;
    })
    await db.collection('article').doc(event.id).update({
      data: {
        comment_count: _.inc(1)}})return res;
  } catch (e) {
    console.error(e)
  }
}
Copy the code
// Reply to comment cloud function
const cloud = require('wx-server-sdk')
var env = 'hsf-blog-product-xxxxx';  // Formal environment
// var env = 'xxxxxxxxxxxxxx'; // Test environment
cloud.init({
  env: env
})
const db = cloud.database()
const _ = db.command
exports.main = async(event, context) => {
  try {
    let res = await db.collection('comment').doc(event._id).update({
      data: {
        childComment: _.push({
          avatarUrl: event.avatarUrl,
          nickName: event.nickName,
          openId: event.openId,
          comment: event.comment,
          createDate: event.createDate,
          flag: event.flag,
          opposite_avatarUrl: event.opposite_avatarUrl,
          opposite_nickName: event.opposite_nickName,
          opposite_openId: event.opposite_openId,
          timestamp: event.timestamp,
        })
      }
    }).then(res= > {
      return res;
    })
    await db.collection('article').doc(event.id).update({
      data: {
        comment_count: _.inc(1)}})return res;
  } catch (e) {
    console.error(e)
  }
}
Copy the code

2.2 How Do I Display Each Comment

Retrieve the comment data from the database and loop through each parent comment, and if there are any children, loop through the comments. The unique identifier of each comment here is the user’s openId, so we can use this to do some things, such as: we can judge that if the comment is their own, they cannot reply.

<view class="comment" wx:if="{{commentList.length>0}}"> <view class="comment-line"> <text Class ="comment-text"> </text> < class="comment-text"> </text> < class="comment-text"> </view> </view> <block wx:for='{{commentList}}' wx:key='*this' wx:for-item="itemfather"> <view class='commentList'> <view class="top-info"> <view class='img-name'> <image src="{{itemfather.avatarUrl}}"></image> <label>{{itemfather.nickName}}</label> </view> </view> <view class="father-content"> <text class="text">{{itemfather.comment}}</text> <view class="father-reply-time"> <text class="create-time">{{itemfather.create_date}}</text> <text class="reply" data-item="{{itemfather}}" bindtap='clickFatherConter' wx:if="{{openid ! = itemFather._openID}}"> </text> </view> </view> <view class="children-content"> <block wx:for='{{itemfather.childComment}}' wx:key='*this'> <view class='childComment'> <view class="child-img-name"> <view class="avatar-name"> <image src="{{item.avatarUrl}}"></image> <text class='nickName'>{{item.nickName}}</text> </view> </view> <view class="child-comment" wx:if="{{item.flag==2}}"> <text class='huifu'> </text> <text class='opposite-nickName'>{{item.opposite_nickName}}</text> <text class='comment-text'>{{item.comment}}</text> </view> <view class="child-comment" wx:if="{{item.flag==1}}"> <text class='comment-text'>{{item.comment}}</text> </view> <view class="child-reply-time"> <text class="child-create-time">{{item.createDate}}</text> <text class="reply" data-item="{{item}}" data-id="{{itemfather._id}}" bindtap='clickChildrenConter' wx:if="{{openid ! Reply = item. OpenId}} "> < / text > < view > < view > < block > < view > < view > < / block > < / view >Copy the code

Project Running

1. Download source code

Download the code locally on Github:

https://github.com/husanfeng/hsf_blog.git

** 2. Environment preparation **

(1) Download small program development tools;

(2) Register appID;

(3) Use small program development tools to import downloaded code, fill in their registered AppID.

3. Prepare for cloud development

(1) Enable the cloud development function.

(2) Create test environment and production environment.

4. Change the environment ID

(1) Change the environment ID in app.js to your own environment ID.

(2) Change the environment ID in all cloud functions to its own environment ID.

5. Cloud function deployment

(1) Right-click the cloud function directory, click open in the terminal, and execute NPM install.

(2) Right click upload and deploy: All files.

6. Build the NPM

(1) Select the NPM module.

(2) Click the top function bar to build NPM.

7. Compile

Publishing Precautions

Small procedures now audit is more and more rigorous, in order not to let you in the audit road detours, I will share some of my experience with you.

  1. On the wechat public platform, select the right and appropriate service categories for small programs, such as blog small programs can choose educational information services.

  2. If your mini program requires an account and password to log in, you need to submit an account and password when submitting for approval, and this account cannot be a test account, and test data cannot appear.

  3. The submitted version should have a data presentation on the front page, such as a blog widget where you need to publish one or more articles.

  4. The content of the article must not contain sensitive content.

  5. Review function audit is more strict, once there are sensitive words in the comments, the audit will not pass, the official proposal to call small program content security API, or use other technology, manual audit means, filtering pornography, illegal and other harmful information, to ensure the safety of the published content.

The source address

Github.com/TencentClou…


If you want to know more about cloud development CloudBase related technical stories/technical practical experience, please scan the code to pay attention to [Tencent Cloud development] public account ~

About Cloud Development

CloudBase is a cloud-integrated product solution. It adopts the Serverless architecture, avoids operation and maintenance affairs such as environment construction, supports one cloud and multiple terminals, and facilitates the rapid construction of small programs, Web applications, and mobile applications.

  • Technical documentation: www.cloudbase.net/
  • Wechat search: Tencent Cloud development, get the latest progress of the project