The original

From the explosion of wechat xiaocheng in 2018 to the present small programs, cross-platform small program framework. It has been in people’s life for three years, and it has been used more and more deeply. After several years of development, wechat officially provided the mode of cloud development, which made me think that as a developer, I could realize the original goal of full stack engineer. So this article is my first step towards becoming a full stack engineer, and hopefully yours.

Project introduction

My friend opened an eyeglasses shop, and told me that he could get the user information on his mobile phone, and maintain the customer information of his eye shop. I thought it was just the right thing to do. So I find this kind of eyeglass shop design draft on the Internet, after looking for a good, according to his needs, there are small procedures to make an appointment to the shop for business, order maintenance, user information maintenance. With the requirements, the design also has, just use the small program cloud development I can do a project.

The problems encountered during this project are well worth documenting. Therefore, I will realize the process of various, as a share, I hope to help some children.

Project preview

Call interface

User registration

Orders submitted

Order to maintain

Project information

Welcome Fork if you like, please give a Star~

The project content

Project directory

├ ─ ─ the README. Md ├ ─ ─ cloudfunctions// Here is the code for the cloud function│ ├ ─ ─ allOrderInfo │ │ ├ ─ ─ config. The json │ │ ├ ─ ─ index. The js │ │ └ ─ ─ package. The json │ ├ ─ ─ orderInfo │ │ ├ ─ ─ config. The json │ │ ├ ─ ─ Index. Js │ │ └ ─ ─ package. The json │ ├ ─ ─ productInfo │ │ ├ ─ ─ config. The json │ │ ├ ─ ─ index. The js │ │ └ ─ ─ package. The json │ ├ ─ ─ RoleInfo │ │ ├ ─ ─ config. Json │ │ ├ ─ ─ index. The js │ │ └ ─ ─ package. The json │ └ ─ ─ the userInfo │ ├ ─ ─ config. The json │ ├ ─ ─ index. The js │ ├ ─ ─ ├─ ├─ img package-lock. Json │ ├─ ├─ img// Here are some local images, because my project already uses cloud storage to display images│ ├ ─ ─ T1. PNG │ ├ ─ ─ T2. The PNG │ ├ ─ ─ T3. The PNG │ ├ ─ ─ T3_more. PNG │ ├ ─ ─ banner1. Jpeg │ ├ ─ ─ banner2. Jpeg │ └ ─ ─ qrcode. JPG ├ ─ ─ miniprogram// Applet code directory│ ├ ─ ─ app. Js │ ├ ─ ─ app. Json │ ├ ─ ─ app. WXSS │ ├ ─ ─ components │ │ └ ─ ─ cloudTipModal │ ├ ─ ─ envList. Js │ ├ ─ ─ images │ │ ├ ─ ─ BLUE_2. Jpeg │ │ ├ ─ ─ GLASSES. The jpeg │ │ ├ ─ ─ the USER. The PNG │ │ ├ ─ ─ arrow. The PNG │ │ ├ ─ ─ black. The jpeg │ │ ├ ─ ─ blue. The jpeg │ │ ├ ─ ─ Call. The PNG │ │ ├ ─ ─class. Jpeg │ │ ├ ─ ─ detail. Jpeg │ │ ├ ─ ─ glass │ │ ├ ─ ─ jinhangzhong. PNG │ │ ├ ─ ─ pink. The jpeg │ │ ├ ─ ─ quchu. PNG │ │ ├ ─ ─ the submit. PNG │ │ ├ ─ ─ TAB │ │ ├ ─ ─ tea. The jpeg │ │ ├ ─ ─ weifukuan. PNG │ │ ├ ─ ─ white. The jpeg │ │ └ ─ ─ yiwancheng. PNG │ ├ ─ ─ miniprogram_npm │ │ └─ @MiniProgram - Component - Plus │ ├─ Package-Lock. json │ ├─ pages │ ├─ allOrderInfo │ ├─ appointment/ / to make an appointment│ │ ├─ confirmOrder │ ├─ glasses/ / glasses│ ├─ Heavy Metal │ ├─ index/ / home page│ │ ├ ─ ─ the map │ │ ├ ─ ─ orderInfo │ │ ├ ─ ─ orderResult │ │ ├ ─ ─ the updateOrder │ │ ├ ─ ─ the user// Personal center│ │ └ ─ ─ the userInfo │ └ ─ ─ a sitemap. Json ├ ─ ─ project. Config. The json ├ ─ ─ project. Private. Config. The json └ ─ ─ uploadCloudFunction. ShCopy the code

Configuration of the project during cloud development

Cloud development initialization and other configuration in the official document written very clear, what problems can go to the official document query. Let’s get right to the run-time configuration of this project:

  • Create four new collections under the cloud development database directory: order_INFO, product_INFO, ROLE_INFO, and user_INFO.

Order_info stores user order information, product_INFO stores product information, roLE_INFO stores role information, and user_info stores user information

  • Upload and deploy the cloudfunctions in the cloudfunctions directory

User registration

Wechat small program user information authorization is really changed many times, now to obtain the user profile name information to use getUserProfile API, the original use Button component with open-type can also obtain information, but the user information can not be displayed on the real machine.

Pages /user/index WXML: <viewclass="header-icon-box color-fff text-center">
      <block wx:if="{{islogin}}">
        <image class="header-icon block" src="/images/USER.png"></image>
        <! -- <button class="header-icon-btn bg-blue color-fff" open-type="getPhoneNumber" </button> -->
        <button wx:if="{{userParam.errMsg}}" class="header-icon-btn bg-blue color-fff" open-type="getPhoneNumber" bindgetphonenumber="getPhoneNumber">Bind mobile phone number</button>
        <button wx:else class="header-icon-btn bg-blue color-fff" bindtap="handleUserInfo">Please click login</button>
      </block>
      <block wx:else>
        <image class="header-icon block" src="{{userData.avatarUrl}}"></image>
        <view class="color-fff">{{userData.nickName}}</view>
      </block></view>handleUserInfo() {
    wx.getUserProfile({
      desc: 'To improve member information'.// Specify the purpose of obtaining the user's personal information, which will be displayed in the subsequent pop-up window
      success: (res) = > {
        console.log(res)
        if (res.errMsg === 'getUserProfile:ok') {
          this.setData({
            userParam: res
          })
        } else {
          this.setData({
            islogin: true}); }}})},getPhoneNumber(e) {
    wx.showLoading({
      title: 'Loading',
    })
    wx.cloud.callFunction({
        name: 'userInfo'.data: {
          method: 'POST'.param: {
            ...this.data.userParam,
          },
          weRunData: wx.cloud.CloudID(e.detail.cloudID), // Here is the data of the mobile phone number
        },
      })
      .then(res= > {
        wx.hideLoading()
        console.log(res)
        const data = {
          role: res.result.role,
          openid: res.result.openid,
          moblie: res.result.moblie, ... res.result.userInfo }this.setData({
          islogin: false.userData: data
        });
        wx.setStorageSync('UserInfo', data)
      })
  },
Copy the code

Here, because friends are registered companies can be authenticated by wechat, so the dimension of the mobile phone number is added when users register. You can modify the logic as you run the project. The user information interface code is posted below for you to look more convenient.

// Cloud function entry file
const cloud = require('wx-server-sdk')
cloud.init()
const db = cloud.database({
  env: cloud.DYNAMIC_CURRENT_ENV, // This is a variable that uses the default environment ID
})


// Cloud function entry function
exports.main = async (event, context) => {
  const wxContext = cloud.getWXContext()
  switch (event.method) { 
    case "GET": // Here is the logic to get a list of user data
      if (event.param.moblie) {
        return db.collection('user_info')
          .where({
            moblie: event.param.moblie,
          }).skip(event.param.page * event.param.size).limit(event.param.size).get() // skip is the logic for paging
      }
      return db.collection('user_info')
        .skip(event.param.page * event.param.size).limit(event.param.size).get()
      break;
    case "POST":
      const moblie = event.weRunData.data.phoneNumber;
      let role = 'others'
      const userInfo = db.collection('user_info')
      // Configure user roles to distinguish administrators from users
      return db.collection('role_info')
        .get().then((res) = > {
          res.data.map((item, index) = > {
            if (item.openid === wxContext.OPENID) { // Based on the openID of the user after registration
              role = item.role
            }
          })
          const userItem = userInfo.where({
            openid: wxContext.OPENID
          }).get().then(res= > {
          // Check whether the user information exists
            if (res.data.length === 0) {
              console.log('------add')
              userInfo.add({
                data: {
                  ...event.param,
                  openid: wxContext.OPENID,
                  appid: wxContext.APPID,
                  unionid: wxContext.UNIONID,
                  create: new Date(),
                  update: new Date(),
                  role: role,
                  moblie
                }
              })
            } else {
              console.log('------update')
              userInfo.where({
                openid: wxContext.OPENID
              }).update({
                data: {
                  ...event.param,
                  openid: wxContext.OPENID,
                  appid: wxContext.APPID,
                  unionid: wxContext.UNIONID,
                  update: new Date(),
                  role: role,
                  moblie
                }
              })
            }
            console.log('userItem-------', res)
          })
          return {
            ...event.param,
            openid: wxContext.OPENID,
            appid: wxContext.APPID,
            unionid: wxContext.UNIONID,
            role: role,
            moblie
          }
        })
      break;
    default:
      return {
        ...event.param,
          openid: wxContext.OPENID,
          appid: wxContext.APPID,
          unionid: wxContext.UNIONID,
      }
      break; }}Copy the code

Orders submitted

// pages/confirmOrder/index.js
Page({

  /** * initial data for the page */
  data: {
    detail: {},
    userInfo: {}},/** * lifecycle function -- listens for page loading */
  onLoad: function (options) {
    let userInfo = wx.getStorageSync('UserInfo');
    this.setData({
      detail: JSON.parse(options.item),
      userInfo
    })
  },

  /** * Users click on the upper right corner to share */
  onShareAppMessage: function () {},formSubmit(e) {
    console.log(e)

    const formData = e.detail.value;
    let flag = false

    for (const key in formData) {
      if (formData[key]) {
        flag = true
      } else {
        flag = false}}if (flag) {
      wx.showLoading({
        title: 'On appointment',})delete this.data.detail._id
      wx.cloud.callFunction({ // The order cloud function is called here for order submission
        name: 'orderInfo'.data: {
          method: 'POST'.param: {
            orderStatus: "PENDING". formData, ... this.data.userInfo, ... this.data.detail } }, }).then(res= > {
        console.log(res)
        wx.hideLoading()
        wx.navigateTo({
          url: '/pages/orderResult/index',})})}else {
      wx.showToast({
        title: 'Please fill in complete information ~'.icon: 'none'}}}})Copy the code

The code for the OrderInfo cloud function:

// Cloud function entry file
const cloud = require('wx-server-sdk')
cloud.init()
const db = cloud.database({
  env: cloud.DYNAMIC_CURRENT_ENV,
})
exports.main = async (event, context) => {
  const wxContext = cloud.getWXContext()
  const orderInfo = db.collection('order_info')
  switch (event.method) {
    case "GET":
      if (event.param.orderStatus === "ALL") {
        return orderInfo
          .where({
            openid: wxContext.OPENID,
          }).orderBy('create'.'desc').skip(event.param.page * event.param.size).limit(event.param.size).get()
      }
      return orderInfo
        .where({
          openid: wxContext.OPENID,
          orderStatus: event.param.orderStatus
        }).orderBy('create'.'desc').skip(event.param.page * event.param.size).limit(event.param.size).get()
      break;
    case "POST": // Here is the logic to submit the order
      // delete event.method
      console.log(event.param)
      if (event.param._id) {
        return orderInfo
          .where({
            _id: event.param._id
          }).update({
            data: {
              orderStatus: event.param.orderStatus,
            }
          })
      }
      return orderInfo
        .add({
          data: {
            ...event.param,
            create: new Date()}})break;
    default:
      return orderInfo
        .get()
      break; }}Copy the code

The order list

pages/orderInfo/index

getOrderInfo(status = "ALL") { // Get interface data
    wx.showLoading({
      title: 'Loading',
    })
    wx.cloud.callFunction({
      name: 'orderInfo'.data: {
        method: 'GET'.param: {
          orderStatus: status, ... this.data.pageParam// Paging parameters
        }
      },
    }).then(res= > {
      wx.hideLoading()
      const arr = this.data.orderList.concat(res.result.data)
      this.setData({
        orderList: arr,
        onBottom: res.result.data.length === 0 || false})})},handleLower() { // Change paging parameters
    const pageParam = this.data.pageParam;
    const index = this.data.activeTab
    pageParam.page++
    this.setData({
      pageParam
    })
    if (!this.data.onBottom) {
      this.getOrderInfo(this.data.tabs[index].status)
    }
  },
Copy the code

The above two codes are mainly to complete the order query function, the following is the order cloud development of the query and paging code:

// Cloud function entry file
const cloud = require('wx-server-sdk')
cloud.init()
const db = cloud.database({
  env: cloud.DYNAMIC_CURRENT_ENV,
})
exports.main = async (event, context) => {
  const wxContext = cloud.getWXContext()
  const orderInfo = db.collection('order_info')
  switch (event.method) {
    case "GET":
      if (event.param.orderStatus === "ALL") {
        return orderInfo
          .where({
            openid: wxContext.OPENID,
          }).orderBy('create'.'desc').skip(event.param.page * event.param.size).limit(event.param.size).get()
      }
      return orderInfo
        .where({
          openid: wxContext.OPENID,
          orderStatus: event.param.orderStatus
        }).orderBy('create'.'desc').skip(event.param.page * event.param.size).limit(event.param.size).get() // This is mainly the paging logic for cloud development
      break;
    case "POST":
      // delete event.method
      console.log(event.param)
      if (event.param._id) {
        return orderInfo
          .where({
            _id: event.param._id
          }).update({
            data: {
              orderStatus: event.param.orderStatus,
            }
          })
      }
      return orderInfo
        .add({
          data: {
            ...event.param,
            create: new Date()}})break;
    default:
      return orderInfo
        .get()
      break; }}Copy the code

Click here to view cloud development apis

conclusion

Since the project is relatively small, I won’t post a lot of code to lose your valuable time. I strongly recommend that you clone the code and run it yourself, a little bit more, rather than reading the article and not doing it for half a day. This article is mainly to let you try to try the cloud development mode to expand the technology stack, so that they master some knowledge points at the back end. As well as everyone’s encouragement, it is my motivation to update the next. Future update plans: Use RN and Flutter to translate this applet, and also combine cloud development of applet to make APP 🎉🎉🎉

Attached again is the project address (optician shop)

I also wrote a cloud development project, want to do local call recycling, compared to this project a little less you can clone this project to try cloud development: local recycling applets