Developing and Creating Full-featured Blog Small Programs with Small Programs and Cloud

Keywords: Javascript npm network Database REST

Use Small Program Cloud Development to Get the Common Functions of Blog Small Program "All in One Network"

This paper introduces how to realize the function button of the details page of mini blog applet, including comments, comments, collections and posters. Here, we record the whole implementation process and some pits in the actual coding.

Comments, Comments and Collection Functions

Ideas for Realization

To achieve some of the operational functions of the article, the most important one is the comment, which is the bridge between the author and the reader. The derivation of the comment function is nothing more than to refine the interaction between the author and the reader, or to increase the dissemination of the article. Therefore, when you start developing, you need to think about what functions you expect to achieve and how to carry out the corresponding functions. Refine.

My general experience is to go through the required functions and general processes in my mind, and then draw a little "the most basic prototype, equivalent to the role of the product" in my notes.

Then we begin to build pages directly and simply interact "using false data, completing pages first". In fact, when we construct pages, we can supplement some process defects of the original idea, so that we can make up for them when we design the back-end and database structure, which is basically perfect as a whole.

Looking back at the requirements of my small program, first of all, it must be operation. At the bottom of the article, there is an operation bar for sending comments and other operations. After referring to some similar small programs, I gradually realize my own style. The style screenshots are as follows:

Once functionality is in place, the comment data needs to have a place to display "usually at the bottom of the article" and then a list of comments at the bottom of the article, in the following style:

Since there is a function button of "Praise and Collection", does the user need to look at the list of articles I have Praise and Collection, so there is a corresponding list in "My". The style is as follows:

At this point, the most basic functions are almost the same. Next, we need to see if the back end can support these pages. "The main thing is the preservation and display of data."

For reviews, there must be a collection to save users'comments, and for users' likes and collections, a collection to save.

So we can design mini_comments and mini_posts_related according to the page. The former is used to save comment data, while the latter is used to preserve the association between user actions and articles.

The rest of the work is realized, nothing more than page interaction and data addition, deletion and modification.

Detail point analysis

On the Number of Comments

There is currently a total Comments attribute in the collection of articles, which needs to be added by 1 for every new comment added to the article.

When I first wrote this, I checked it before updating it. The original code is as follows:


let count=post.totalComments+1;

let result =await db.collection('mini_posts').doc(event.commentContent.postId).update({

​    data: {

​      totalComments: count

​    }

  });

Later, looking at the document, we found that we can use the instruction db.command.inc, without looking it up again, we can add 1 to the original field directly, and we can also guarantee atomicity. The code is as follows:


const _ = db.command

let result = db.collection('mini_posts').doc(event.commentContent.postId).update({

​    data: {

​      totalComments: _.inc(1)

​    }

  });

New Subcomments

You need to respond to a comment.

Interactively, clicking on a commenter's nickname or avatar triggers the corresponding click event, records the corresponding comment ID and necessary data in the event, and sets the focus to the comment box:


 /**

  * Click on the comments to reply

  */

  focusComment: function (e) {

​    let that = this;

​    let name = e.currentTarget.dataset.name;

​    let commentId = e.currentTarget.dataset.id;

​    let openId = e.currentTarget.dataset.openid;



​    that.setData({

​      commentId: commentId,

​      placeholder: "Reply" + name + ":",

​      focus: true,

​      toName: name,

​      toOpenId: openId

​    });

  },

db.command.push can be used to develop new sub-comments by using the cloud to "update instructions, add one or more values to the end of an array for a field with an array value", and add new values to the sub-comments collection:


/**

 * New Subcomments

 * @param {} event 

 */

async function addPostChildComment(event) {



  let task = db.collection('mini_posts').doc(event.postId).update({

​    data: {

​      totalComments: _.inc(1)

​    }

  });

  await db.collection('mini_comments').doc(event.id).update({

​    data: {

​      childComment: _.push(event.comments)

​    }

  })

  await task;

}

On Judgment of Collection

When the article is first loaded, we need to determine whether the user has relevant operations on the article. If there are corresponding collection and comment operations, we need to update the corresponding function icon when initializing. The core code is as follows:


  /**

   * Getting the status of collections and favorites

   */

  getPostRelated: async function (blogId) {

​    let where = {

​      postId: blogId,

​      openId: app.globalData.openid

​    }

​    let postRelated = await api.getPostRelated(where, 1);

​    let that = this;

​    for (var item of postRelated.data) {

​      if (config.postRelatedType.COLLECTION === item.type) {

​        that.setData({

​          collection: { status: true, text: "Collected", icon: "favorfill" }

​        })

​        continue;

​      }

​      if (config.postRelatedType.ZAN === item.type) {

​        that.setData({

​          zan: { status: true, text: "Praised", icon: "appreciatefill" }

​        })

​        continue;

​      }

​    }

  },

As for other interaction details and code details, you can read the source code to experience, if you have any questions or better implementation, you can also communicate with me.

Poster function

Give some background

In fact, in the earliest small program has been implemented once, specific reference can be made. Using Cloud to Develop and Optimize Blog Programs (3) - Generating Poster Function The main thing is to use the native cavans to assemble. The original code copy can be changed, but I always feel that the original code is not very good.

So I want to see if there are ready wheels to use, and I found the wxa-plugin-canvas component, which can generate beautiful posters through a very simple configuration.

Small programs use npm

Before summarizing the function of generating posters, it is still necessary to record the use of npm to avoid unnecessary pits.

Considering the size limitation of the applet itself, npm is the best way to use it.

The reason is that according to the official documents, only the build file generation directory in the npm package will be counted as the space occupied by the package, and only the code of the directory will be uploaded when uploading the widget code. This greatly reduces the size of the uploaded code.

Here's a brief introduction to how the small program side uses npm's "Actually, according to the official documents, follow the steps".

Take the path of my current applet as an example, add a folder node_modules to / miniprogram, point to the directory of / miniprogram from the command line:

Installation by command:


npm install wxa-plugin-canvas --production  

After successful installation, it can be built in the widget development tool. Before building, you need to check the use of npm module.

Then click on the menu bar in the developer's tool: Tool - > Build npm.

The miniprogram_npm directory is generated when the build is completed, and the project side is basically tuned up.

wxa-plugin-canvas

After building, you can use wxa-plugin-canvas as a customized component, which is relatively simple to use.

First, introduce the component on the page you need:


{

  "usingComponents": {"poster": "wxa-plugin-canvas/poster"}

}

Then you can use it in wsml:


<poster id="poster" hide-loading="{{false}}" preload="{{false}}" config="{{posterConfig}}" bind:success="onPosterSuccess" bind:fail="onPosterFail"></poster>

Because we need asynchronous access to some data for posters before we generate posters, we use asynchronous generation of posters.

The poster/poster.js file of the component needs to be introduced and then invoked in the code:


import Poster from '../../utils/poster';

Page({

​    /**

​     * Asynchronous generation of posters

​     */

​    onCreatePoster() {

​        // setData configuration data

​        this.setData({ posterConfig: {...} }, () => {

​            Poster.create(); 

​        });

​    }

})

Core Code Parsing

Data needed for posters

Let's first look at the overall structure of the shared poster:

First of all, we need to confirm what data is needed for the composition of the poster, and get the corresponding data before calling the component.

The poster I designed mainly contains three pieces of content, user information (avatar and nickname), article information (first picture, title, introduction) and the most important article's small program code.

User information and article information are actually relatively simple. Both data are available on the details page of the applet, but there are two points to be noted.

The first is the domain name problem. The images used in the canvas need to be configured with domain names, the domain names of the avatar and the domain names of the header of the public document.


https://mmbiz.qpic.cn

https://wx.qlogo.cn

The second is the problem of the public number header. The url of the picture returned from the public number material list is actually http, but the widget stipulates that the bound domain name must be https. At that time, it was rather helpless. Later, it was possible to use HTTPS to access the url of the first picture. Unfortunately, when using the address of the first picture, it was replaced by:


imageUrl = imageUrl.replace('http://', 'https://')

Finally, the article's widget code, need to use the api of the widget getUnlimited, specific reference to official documents, has provided the way of cloud invocation "access_token is not required", call is relatively simple.

Originally, when synchronizing articles, "adminService" was intended to generate small code for the corresponding articles directly. After the code was written, local debugging could be done. However, after uploading to the cloud, the test found that the error had been reported. After visiting the tire, I realized that it was not supported. At the same time, the trigger did not support cloud invocation. So the plan was in vain. I am in the present generation. TODO is typed in the code.

In this case, when generating posters, they are generated and uploaded directly to cloud storage. FileID is saved to the collection of articles, so that they can be used all the time with only one generation. The specific code is as follows:


/**

 * Two-Dimensional Code for New Articles

 * @param {} event 

 */

async function addPostQrCode(event)

{

  let scene = 'timestamp=' + event.timestamp;

  let result = await cloud.openapi.wxacode.getUnlimited({

​    scene: scene,

​    page: 'pages/detail/detail'

  })



  if (result.errCode === 0) {

​    let upload = await cloud.uploadFile({

​      cloudPath: event.postId + '.png',

​      fileContent: result.buffer,

​    })



​    await db.collection("mini_posts").doc(event.postId).update({

​      data: {

​        qrCode: upload.fileID

​      }

​    });



​    let fileList = [upload.fileID]

​    let resultUrl = await cloud.getTempFileURL({

​      fileList,

​    })

​    return resultUrl.fileList

  }



  return []



}

But here's an awkward place: the maximum length of scene parameter in the api that generates the small code is 32, and the length of the article ID is 32. It's impossible to splice and jump pages according to the article id, so the timestamp field in the mini_posts set is temporarily used here as "theoretically unique".

So you also need to be compatible with the timestamp field in the details page.

Poster Picture Display

Poster picture display is relatively simple, using a bullet window, the generated poster picture can be displayed:


  /**

   * Poster Generation Success - Callback

   * @param {} e 

   */

  onPosterSuccess(e) {

​    const { detail } = e;

​    this.setData({

​      posterImageUrl: detail,

​      isShowPosterModal: true

​    })

​    console.info(detail)

  },

Preserve poster pictures

The user album is invoked by wx.saveImageToPhotosAlbum to save the picture. Here, we need to be compatible with some column operations that users refuse the album authorization. The specific code is as follows:


  /**

  * Preserve poster pictures

  */

  savePosterImage: function () {

​    let that = this

​    wx.saveImageToPhotosAlbum({

​      filePath: that.data.posterImageUrl,

​      success(result) {

​        console.log(result)

​        wx.showModal({

​          title: 'Tips',

​          content: 'Two-dimensional code posters have been saved in mobile photo albums. Share them with friends circle as soon as possible.',

​          showCancel: false,

​          success: function (res) {

​            that.setData({

​              isShowPosterModal: false,

​              isShow: false

​            })

​          }

​        })

​      },

​      fail: function (err) {

​        console.log(err);

​        if (err.errMsg === "saveImageToPhotosAlbum:fail auth deny") {

​          console.log("Re-authorization");

​          wx.showModal({

​            title: 'User unauthorized',

​            content: 'Authorization is required if poster pictures are to be saved to the album..Whether to select "Save to Album" in Authorization Management?',

​            showCancel: true,

​            success: function (res) {

​              if (res.confirm) {

​                console.log('User Click OK')

​                wx.openSetting({

​                  success: function success(res) {

​                    console.log('Open Settings', res.authSetting);

​                    wx.openSetting({

​                      success(settingdata) {

​                        console.log(settingdata)

​                        if (settingdata.authSetting['scope.writePhotosAlbum']) {

​                          console.log('Successful access to save to album');

​                        } else {

​                          console.log('Failed to get permission to save to album');

​                        }

​                      }

​                    })



​                  }

​                });

​              }

​            }

​          })

​        }

​      }

​    });

  },

Experience summary

  • Good open source components can be fully utilized to avoid duplication of wheels, and have the opportunity to learn how others implement them.
  • Look at the documentation more, in fact, the documentation of the applet is really very detailed.
  • Here I want to share the process of realizing a function and how to achieve it step by step when I have an idea.
  • The small program itself is not difficult, and the corresponding documents are very detailed, but the process of assembly and the realization of logic need to think and experience. Look at the documentation more, in fact, the documentation of the applet is really very detailed.
  • If your ideas and processes are very clear, but you still can't achieve your expected functions, then I suggest that you put them in first, first familiar with html,css,javascript, and then look at the documentation of small programs several times, maybe the problem you faced at that time is no longer a problem.

Source Link

https://github.com/TencentCloudBase/Good-practice-tutorial-recommended

If you want to share your technical stories / experiences in developing CloudBase using the cloud, please leave a message to contact us.

Posted by dt192 on Sun, 25 Aug 2019 20:13:19 -0700