Skip to main content

Reservation and Ordering Mini Program Development

Overview

This article introduces how to use cloud development capabilities to quickly build a reservation and ordering system.

Note

The source code materials involved in this example tutorial have all been properly authorized.

Preparations

  1. Register Tencent Cloud.

  2. Enabled CloudBase for the mini program. For details, see Quick Start for Mini Program Side.

  3. Go to the CloudBase Console > Settings > Extensions page, and click to enable Content Management and Content Security.

Operation Procedure

The specific operation procedure can be divided into the following 6 steps. For more details, refer to the sample code.

This article primarily focuses on the homepage index page, CloudBase Content Management, and CloudBase Database. For more index code details, refer to the index page.

Step 1: Activate Content Management

  1. First, go to the CloudBase console > Content Management page, click Enable, and set up an account and password. The creation of Content Management may take some time, please wait patiently.

  1. After successful creation, return to the Content Management page. Click Access Address to access the Content Management Platform.

  1. Enter your login account and password to access the Content Management (CMS) backend. Click Create New Project - here we name it Reservation and Ordering Management System.

  1. Go to the newly created Reservation and Ordering Management System, navigate to the Content Model page, click New Model. Set the Display Name as Carousel and Database Name as banner. After configuration, click Create.

Note

Changing the database name will automatically rename the original database. Please proceed with caution.

  1. Click Content Type > Image on the right to enter the Add Image Field page, set the Display Name to Carousel Image, and the Database Field Name to photo.

Click Add to complete the creation of the content model.

  1. Go to the Content Collection > Carousel page and click New.

Drag the image and click Create to complete the upload of the carousel image, thus completing the creation of the content model for the carousel.

  1. After the above operations, a banner database and the imported image data will be generated in the CloudBase Console. Go to the CloudBase Console > Database > banner > Data Permissions page, and change the database permission to Readable by all users, writable only by the creator, so that all users can view the data.

  1. Next, start building the carousel in pages/index. Refer to the swiper documentation to help bind data, then use wx:for for list binding.

  2. The env parameter can be obtained in WeChat Developer Tools > Cloud Development Console.

// pages/index/index.js
wx.cloud.init({
env: "Your Environment ID",
traceUser: true,
});
const db = wx.cloud.database();
Page({
/**
* Initial data of the page
*/
data: {
mgList: "",
},
/**
* Lifecycle function--Listening for page load
*/
onLoad: function (options) {
// Here, when the page first loads, it retrieves data from the banner database and stores them in mgList.
db.collection("banner").get({
success: (res) => {
console.log(res);
this.setData({
mgList: res.data,
});
},
});
},
});
  • Use the wx:for control attribute on a component to bind an array, then repeatedly render the component using the data from each item in the array.
  • The default variable name for the index of the current array item is index, and the variable name for the current array item is item*
  • Use wx:for-item to specify the variable name for the current element of the array.
  1. Bind the mgList data using the following code.
<!--pages/index/index.wxml-->
<view class="banner">
<swiper class="swip_main" indicator-dots autoplay interval="6000" circular>
<block wx:for="{{mgList}}">
<swiper-item>
<image src="{{item.photo}}" style="width: 100%;height: 100%;" mode="scaleToFill"></image>
</swiper-item>
</block>
</swiper>
</view>
  1. After saving, running, and compiling, you can see the carousel.

Note

If the carousel fails to load after running the compilation, click Details in the upper right corner of WeChat Developer Tools, navigate to the Local Settings page, and try switching the Debugging Base Library to a lower version.

Step 3: Announcement Setup

  1. Refer to Step 2 to create the Announcement content model.
  2. Set the database name for the Announcement content model to tz. For the newly added Content Type > Single-line string, set the database field name to text.

  1. Go to Content Collection > Announcement and click New to create an announcement.

  1. Bind the mgList data using the following code.
<!-- pages/index/index.wxml -->
<!--Carousel-->
<view class="banner">
<swiper class="swip_main" indicator-dots autoplay interval="6000" circular>
<block wx:for="{{mgList}}">
<swiper-item>
<image src="{{item.photo}}" style="width: 100%;height: 100%;" mode="scaleToFill"></image>
</swiper-item>
</block>
</swiper>
</view>
<!--Notice Bar-->
<view class="tz">
<view class="tz_zp">
<image src="../../images/font-ui/zggg.png"></image>
</view>
<swiper class="swiper-news-top" vertical="true" autoplay="ture" circular="ture" interval="3000">
<block wx:for="{{msgList}}">
<navigator url="" open-type="navigate">
<swiper-item>
<view class="swiper_item">{{item.text}}</view>
</swiper-item>
</navigator>
</block>
</swiper>
</view>
  1. Save, run, and compile.

This article primarily focuses on the homepage index page and the configuration file app.json. For more index code details, refer to the index page and the configuration file app.json.

Step 1: Set Up the Bottom Navigation Bar

  1. Configure the corresponding pages in the pages array of app.json.
  2. Then, in the app.json file, configure the bottom navigation bar by setting the tabBar.
"pages": [
"pages/index/index",
"pages/my/my",
"pages/dp/dp",
"pages/gltl/gltl",
"pages/grxx/grxx",
"pages/xgxx/xgxx",
"pages/gywm/gywm",
"pages/buzx/buzx",
"pages/glxq/glxq",
"pages/xpl/xpl",
"pages/fbgl/fbgl",
"pages/xdym/xdym",
"pages/jqqt/jqqd",
"pages/dingdan/dingdan",
"pages/xd/xd",
"pages/gwx/gwx",
"pages/ddgl/ddgl",
"pages/qccg/qccg",
"pages/sjgl/sjgl",
"pages/fbpl/fbpl"
],
3. Save the corresponding UI images for the tarBar in the Mini Program's imges directory and compile.

Step 2: Set Up the Middle Navigation Bar

  1. Enter the home page index directory and develop the front-end home page navigation bar using index.wxml and index.wxss.
<!-- pages/index/ -->
<view class="banner">
<swiper class="swip_main" indicator-dots autoplay interval="6000" circular>
<block wx:for="{{mglist}}">
<swiper-item >
<image style="width: 100%;height: 100%;" mode="scaleToFill" src="{{item.photo}}"></image>
</swiper-item>
</block>
</swiper>
</view>
<view class="tz">
<view class="tz_zp">
<image src="../../images/font-ui/zggg.png"></image>
</view>
<swiper class="swiper-news-top" vertical="true" autoplay="true" circular="true" interval="3000">
<block wx:for="{{msgList}}" >
<navigator url="" open-type="navigate">
<swiper-item>
<view class="swiper_item" >{{item.text}}</view>
</swiper-item>
</navigator>
</block>
</swiper>
</view>
<view class="nav">
<view class="nav-banner" bindtap='showlist'>
<view class="nav-banner-img">
<image src="../../images/font-ui/bigmosque.png"></image>
</view>
<view class="nav-banner-text">East Area Canteen</view>
</view>
<view class="nav-banner" bindtap='showzd'>
<view class="nav-banner-img">
<image src="../../images/font-ui/bigschool.png"></image>
</view>
<view class="nav-banner-text">West Area Canteen</view>
</view>
<view class="nav-banner" bindtap='showwd'>
<view class="nav-banner-img">
<image src="../../images/font-ui/moderncity.png"></image>
</view>
<view class="nav-banner-text">Daily Deals</view>
</view>
<view class="nav-banner" bindtap='showwd'>
<view class="nav-banner-img">
<image src="../../images/font-ui/store.png"></image>
</view>
<view class="nav-banner-text">South Lake Canteen</view>
</view>
<view class="nav-banner" bindtap='showtk'>
<view class="nav-banner-img">
<image src="../../images/font-ui/temple.png"></image>
</view>
<view class="nav-banner-text">Food Sharing</view>
</view>
</view>
  1. Go to the index.js page, use wx.navigateTo(Object object) to navigate to a specific page within the app. Add a click event to the navigation bar so that when the user clicks, it navigates to a "Coming Soon" page.
// index.js
showwd:function(){
wx.navigateTo({
url: '../jqqd/jqqd',
})
},
showtk:function(){
wx.switchTab({
url: '../gltl/gltl'
})
},
Note

Keep the current page and navigate to a page within the app. You can use wx.navigateBack to return to the original page. The page stack in Mini Programs can hold up to ten layers.

  1. Go to the CMS Content Management Console, create a new Food List content model, and set the database name to mslb.
  2. Go to the newly created Food List page and configure the content collection as follows:
Content TypeDisplay NameDatabase Field Name
ImageAttachment Photosrc
Single-line stringNamename
Single-line stringDescriptionjj
Single-line stringAddressdz
Single-line stringbtn1btn1
Single-line stringbtn2btn2
Single-line stringbtn3btn3

For more detailed operations on CMS content management, refer to Building a Carousel.

  1. Go to the index.wxml page and use the list rendering (wx:for) to display the list.
<view class="rmbs">
<view class="rmbs-title">
<view class="rmbs-title-text">Popular Cuisine</view>
<view class="rmbs-title-more" bindtap='showlist'>View More ></view>
</view>
<view class="rmbs-list" wx:for="{{rmbs}}" wx:for-item="item" wx:key="_id" bindtap='showbs' id="{{item._id}}" wx:if="{{index<10}}">
<view class="rmbs-list-photo">
<image src="{{item.src}}"></image>
</view>
<view class="rmbs-list-text">
<view class="rmbs-list-text-tit1">{{item.name}}</view>
<view class="rmbs-list-text-jj">{{item.jj}}</view>
<view class="rmbs-list-text-tit2">Address: {{item.zd}}</view>
<view class="rmbs-list-text-tit3">
<view class="rmbs-list-text-btn" style="background-color: rgb(26, 69, 134);">{{item.btn1}}</view>
<view class="rmbs-list-text-btn" style="background-color: rgb(24, 122, 29);">{{item.btn2}}</view>
<view class="rmbs-list-text-btn" style="background-color: coral;">{{item.btn3}}</view>
<view class="rmbs-list-text-btn">{{item.btn4}}</view>
</view>
</view>
</view>
</view>

Here we find that sometimes the item.btn1 button is displayed even when empty. We can improve this by using wx:if conditional rendering: add a condition to not display the button when it is empty.

<view class="rmbs-list-text-btn" style="background-color: rgb(26, 69, 134);" wx:if="{{item.btn1!=''}}">{{item.btn1}}</view>
<view class="rmbs-list-text-btn" style="background-color: rgb(24, 122, 29);" wx:if="{{item.btn2!=''}}">{{item.btn2}}</view>
<view class="rmbs-list-text-btn" style="background-color: coral;" wx:if="{{item.btn3!=''}}">{{item.btn3}}</view>

The final result is as follows:

Step 3: Set Up My Page

This article primarily focuses on the my page and Cloud Functions. For more code details, refer to the my page.

Step 1: Configure the cloud function

  1. Right-click the current environment folder, click New Node.js Cloud Function, and name the file open.

  1. Under the open cloud function, write code to retrieve the openid in the index.js file.
// Cloud Function entry file
const cloud = require("wx-server-sdk");

cloud.init();

// Cloud function entry function
exports.main = async (event, context) => {
const wxContext = cloud.getWXContext();

return {
event,
openid: wxContext.OPENID,
appid: wxContext.APPID,
unionid: wxContext.UNIONID,
};
};
Note

When invoking cloud functions from the Mini Program side, developers can use the getWXContext method provided by wx-server-sdk to obtain the context of each call (appid, openid, etc.). This allows obtaining inherently trusted user login states (openid) without maintaining complex authentication mechanisms.

  1. Then right-click the open folder and click Upload and Deploy: Cloud-based Dependency Installation to complete the cloud function deployment.

Step 2: Set Up the Login Authorization Function

  1. Open app.js to initialize cloud development.
// app.js
App({
onLaunch: function () {
if (!wx.cloud) {
console.error(
"Please use base library version 2.2.3 or above to use cloud capabilities"
);
} else {
wx.cloud.init({
// env parameter description:
// The env parameter determines which cloud environment's resources subsequent cloud development calls (wx.cloud.xxx) initiated by the Mini Program will be directed to by default.
// Please enter the environment ID here. The environment ID can be viewed in the cloud console.
// If not filled, the default environment (the first created environment) will be used
env: "Environment ID",
traceUser: true,
});
}

this.globalData = {};
},
globalData: {
userid: "",
},
});
  1. Open my.js to write the page code for the "My" section. Here we create a click event: when the user clicks the button bound to the getUserInfo event, we call to get the user information. getopenid is the method to obtain the user's openid via cloud functions. This value is stored in app.js, allowing direct access from other pages.
const app = getApp();
Page({
/**
* Initial data of the page
*/
data: {
username: "",
openid: "",
},
/**
* Lifecycle function--Listening for page load
*/
onLoad: function (options) {},
getUserInfo(e) {
console.log(e);
this.setData({
username: e.detail.userInfo.nickName,
});
},
getopenid() {
var that = this;
wx.cloud.callFunction({
name: "open",
success: (res) => {
var usid = res.result.openid;
console.log(usid);
this.setData({
openid: res.result.openid,
});
getApp().globalData.userid = res.result.openid;
},
fail(res) {
console.log("Failed to get", res);
},
});
},
});
  1. Open the my.wxml file and add login status checking code. We can determine: if openid is not obtained, prompt the user to log in; if the obtained openid is empty, display the authorization login section.
<view class="topbanner"  wx:if="{{openid!=''}}">
<view class="toplogo">
<open-data type="userAvatarUrl"></open-data>
</view>
<view class="toptext">
<open-data type="userNickName" lang="zh_CN" class="user-name"></open-data>
<view class="user-name2">Patriotism, Dedication, Truth-seeking, Innovation</view>
</view>
</view>
<view class="topbanner" wx:if="{{openid==''}}">
<view class="topban1">You have not authorized login</view>
<view class="topban1">Go to Authorize Login</view>
<button bindtap="getopenid" type="default">Log in</button>
</view>

Step 4: Set up guide page

This article primarily focuses on the guide page. For more code details, refer to the Guide List, Guide Details, Post Comment, and Post Guide.

Step 1: Set up guide display page

  1. Go to the CMS Content Management Console, create a new guide content model, and set the database name to glpj.
  2. Go to the newly created guide page and configure the content collection as follows:
    Content TypeDisplay NameDatabase Field Name
    ImagePhotophoto
    Single-line stringTitletitle
    Date and TimeTimetime
    Single-line stringAuthoruser
    NumberPage Viewslll
    Rich TextDescriptionxq
Note

For more detailed operations on CMS content management, refer to Building a Carousel.

  1. Here we still use wx:for to render the list, bind a click event to it for redirection, and pass the current article ID.
<!--pages/gltl/gltl.wxml-->
<view class="banner">
<image src="https://6363-ccntst-8gsp6zkw250f8e38-1305928500.tcb.qcloud.la/cloudbase-cms/upload/2021-11-25/5hbujycykft9vg9g82xcsw0f6z34v8o5_.jpg"></image>
</view>
<view class="miin_baer">
<view class="title_pl">
<view class="pl_bt">Guide Comments</view>
<view class="qpl" id="{{rmbs._id}}" bindtap='showtl'>Publish</view>
</view>
<view class="mian_box" wx:for="{{rmbs}}" wx:for-item="item" wx:key="_id" bindtap='showbs' id="{{item._id}}">
<view class="min_box_img">
<image src="{{item.phpto}}"></image>
</view>
<view class="mian_text">
<view class="miam_text_title">
{{item.title}}
</view>
<view class="mian_user">
<view class="user_logo">
<image src="../../images/font-ui/nstx.png"></image>
</view>
<view class="user_name">
{{item.user}}
</view>
<view class="taolun">
<image src="../../images/font-ui/pinglun-08.png"></image>
</view>
<view class="liulanl">
<view class="lll_zp">
<image src="../../images/font-ui/liulan.png"></image>
</view>
<view class="lll_sz">
{{item.lll}}+
</view>
</view>
</view>
</view>
</view>
</view>

Step 2: Set up guide details and comment publishing feature

  1. Go to the CMS Content Management Console, create a new guide comment content model, and set the database name to glplgl.
  2. Go to the newly created Guide Comments page and configure the content collection as follows:
Content TypeDisplay NameDatabase Field Name
Single-line stringUseruser
Single-line stringTexttext
Single-line stringUser Nameusername
Date and Timedatadata
Single-line stringplwzplwz
Note

For more detailed operations on CMS content management, refer to Building a Carousel.

  1. Guide Details The page logic and frontend code are as follows:
// pages/glxq/glxq.js
wx.cloud.init({
env: "Environment ID",
traceUser: true,
});
const db = wx.cloud.database();
Page({
/**
* Initial data of the page
*/
data: {
list_id: "",
rmb: "",
},

/**
* Lifecycle function--Listening for page load
*/
onLoad: function (options) {
this.setData({
list_id: options.list_id,
});
console.log(this.data.list_id),
/**/
db
.collection("glpj")
.doc(this.data.list_id)
.get()
.then((res) => {
console.log(res);
this.setData({
rmbs: res.data,
});
});
const _ = db.command;
db.collection("glpj")
.doc(this.data.list_id)
.update({
data: {
lll: _.inc(1),
},
});
db.collection("glplgl")
.where({ plwz: this.data.list_id })
.get()
.then((res) => {
console.log(res);
this.setData({
rmb: res.data,
});
});
},

/**
* Lifecycle function--Listening for initial page rendering completion
*/
onReady: function () {},

/**
* Lifecycle function--Listening for page display
*/
onShow: function () {},
showbs: function (e) {
console.log(e.currentTarget.id);
wx.navigateTo({
url: "/pages/xpl/xpl?list_id=" + e.currentTarget.id,
});
},
});
  1. On the corresponding Guide Details page, when clicking Go to comments, we need to obtain the user's openid and the article ID for the current comment to be published. The logic and frontend code for Go to comments are as follows:
// pages/xpl/xpl.js
wx.cloud.init({
env: "Environment ID",
traceUser: true,
});
const db = wx.cloud.database();
var myDate = new Date();
Page({
/**
* Initial data of the page
*/
data: {
list_id: "",
userid: "",
},

/**
* Lifecycle function--Listening for page load
*/
onLoad: function (options) {
this.setData({
list_id: options.list_id,
});
console.log(this.data.list_id);
const app = getApp();
var userid = app.globalData.userid;
this.setData({
userid: userid,
});
},
showsq: function () {
wx.switchTab({
url: "../my/my",
});
},
/**
* Lifecycle function--Listening for initial page rendering completion
*/
onReady: function () {},
btnSub(res) {
if (res.detail.value.text != "" && res.detail.value.username != "") {
var { text, username } = res.detail.value;
db.collection("glplgl")
.add({
data: {
user: this.data.userid,
text: text,
plwz: this.data.list_id,
username: username,
data: myDate.toLocaleString(),
_createTime: Date.parse(new Date()),
},
})
.then((res) => {
wx.showToast({
title: "Success",
icon: "success",
duration: 2000,
});
});
} else {
wx.showToast({
title: "Please fill in the information",
icon: "error",
duration: 2000,
});
}
},
});
Note

For content security, WeChat Cloud Development provides content security capabilities that allow setting content security rules for information stored in Cloud Development databases, automatically performing content moderation, and handling violating content. For details, see Content Security.

  1. The final result is as follows:

Step 3: Set up guide publishing feature

  1. Go to the app.json page and add the weui framework.
{
"useExtendedLib": {
"weui": true
}
}
  1. Then go to the fbpl.json page to import the weui framework again and call it in fbpl.wxml. Relevant code is as follows:
{
"usingComponents": {
"mp-uploader": "weui-miniprogram/uploader/uploader",
"mp-cells": "weui-miniprogram/cells/cells",
"mp-cell": "weui-miniprogram/cell/cell",
"mp-form-page": "weui-miniprogram/form-page/form-page",
"mp-form": "weui-miniprogram/form/form",
"mp-toptips": "weui-miniprogram/toptips/toptips",
"mp-checkbox-group": "weui-miniprogram/checkbox-group/checkbox-group",
"mp-half-screen-dialog": "weui-miniprogram/half-screen-dialog/half-screen-dialog"
}
}
  1. The final result is as follows:

Step 5: Set up store page

This article primarily focuses on the store page. For more code details, refer to the Store and Merchant.

Step 1: Set up store page

  1. Go to the CMS Content Management Console, create a new store content model, and set the database name to dp.
  2. Go to the newly created store page and configure the content collection as follows:
Content TypeDisplay NameDatabase Field Name
Single-line stringStore Namename
Single-line stringStore Locationdpdd
Date and TimeTimetime
BooleanOpensfyy
ImageStore Photodpzp
Single-line stringDescriptionjj
Note

For more detailed operations on CMS content management, refer to Building a Carousel.

  1. Then display it in the mini program.
<!--pages/dp/dp.wxml-->
<view class='search'>
<input type='text' placeholder='Enter search content' bindinput='input' bindconfirm='confirm' />
<icon type='search' class='icons'></icon>
</view>
<view class="rmbs">
<view class="rmbs-list" wx:for="{{list}}" wx:for-item="item" wx:key="_id" bindtap='showbs' id="{{item._id}}" wx:if="{{item.show}}">
<view class="rmbs-list-photo">
<image src="{{item.dpzp}}"></image>
</view>
<view class="rmbs-list-text">
<view class="rmbs-list-text-tit1">{{item.name}}</view>
<view class="rmbs-list-text-jj">{{item.jj}}</view>
<view class="rmbs-list-text-tit2">Address: {{item.dpdd}}</view>
<view class="rmbs-list-text-tit3">
<view class="rmbs-list-text-btn" style="background-color: rgb(24, 122, 29);" wx:if="{{item.sfyy!=false}}">Open</view>
<view class="rmbs-list-text-btn" style="background-color: rgb(26, 69, 134);" wx:else>Closed</view>
</view>
</view>
</view>
</view>
  1. The effect is as follows:

Step 2: Build Product Page

  1. Go to the CMS Content Management Console, create a new product content model, and set the database name to sp.
  2. Go to the newly created product page and configure the content collection as follows:
    Content TypeDisplay NameDatabase Field Name
    Single-line stringNamename
    NumberPricejg
    NumberSales Volumexl
    Single-line stringIngredientspl
    ImagePhotozp
    AssociationMerchantsj
    Among them, for the merchant's associated content, select store, and for the display field, select store name.
Note

For more detailed operations on CMS content management, refer to Building a Carousel.

  1. When a user clicks on a merchant and navigates to the product page, we still need to pass the merchant ID.
<!--pages/fbgl/fbgl.wxml-->
<view class="wdl_ban" wx:if="{{userid==''}}">
<view class="wdl">
<image src="../../images/font-ui/wdl.png"></image>
</view>
<view class="text_main">You have not authorized login, please authorize login!</view>
<button size="mini" type="primary" bindtap='showsq' class="btn_sq">Go to Authorization</button>
</view>
<view class="contmian" wx:if="{{userid!=''}}">
<view class="mian_box" wx:for="{{rmb}}" wx:for-item="item" wx:key="_id" bindtap='showbs' >
<view class="main_box_left">
<image src="{{item.zp}}" class="zszp"></image>
</view>
<view class="main_box_right">
<view class="tit_zs">{{item.name}}</view>
<view class="pl">Ingredients:{{item.pl}}</view>
<view class="pl">Monthly Sales:{{item.xl}}</view>
<view class="jg">¥ {{item.jg}}</view>
<button size="mini" type="primary" bindtap="addCart" id="{{item._id}}" class="btn_9">Buy</button>
</view>
</view>
</view>
  1. The effect is as follows:

Step 3: Build Order Placement Function

  1. Go to the CMS Content Management Console, create a new order content model, and set the database name to dd.
  2. Go to the newly created order page and configure the content collection as follows:
    Content TypeDisplay NameDatabase Field Name
    Single-line stringuseriduserid
    AssociationProductsp
    Single-line stringTimetime
    BooleanPlace Orderxd
    BooleanPickupqccg
    Single-line stringPickup Timeqcsj
    Among them, for the product's associated content, select store, and for the display field, select store name.
Note

For more detailed operations on CMS content management, refer to Building a Carousel.

  1. Next, go to the fbgl.js page to configure the order placement event.
 addCart(res) {
console.log(res)
const _=db.command
db.collection('sp').doc(res.currentTarget.id).update({
data:{
xl:_.inc(1)
}
})
db.collection("sp").get().then(res=>{
console.log(res)
this.setData({
rmb:res.data
})
})
db.collection("dd").add({
data: {
userid: this.data.userid,
sp: res.currentTarget.id,
_createTime: Date.parse(new Date()),
time: myDate.toLocaleString(),
xd:0,
qccg:0,
}
}).then(res => {
wx.showToast({
title: 'Added Successfully',
icon: 'success',
duration: 2000
})
})
},
Note

We can understand that user orders need to include information such as user openid, products, time, etc.

We use the add method to insert data into the database and create new records. If the passed record object lacks an _id field, the backend automatically generates an _id. If an _id is specified, it must not conflict with existing records.

Step 6: Set Up Order Page

This article primarily focuses on the order page. For more code details, refer to the Order and Order Management.

Step 1: Set Up the Cloud Function look

  1. Right-click the current environment folder, click New Node.js Cloud Function, and name the file look.

  1. In the look cloud function, write the aggregation pipeline join query code in the index.js file.
// Cloud Function entry file
const cloud = require("wx-server-sdk");

cloud.init({
env: "Environment ID",
});
const db = cloud.database();
// Cloud function entry function
exports.main = async (event, context) => {
var text = event.userid;
return await db
.collection("dd")
.aggregate()
.lookup({
from: "sp",
localField: "sp",
foreignField: "_id",
as: "bookList",
})
.end();
};
Note

Performs a left outer join with a specified collection in the same database. For each input record in this stage, lookup adds an array field containing matching records from the joined collection. lookup then outputs the joined results to the next stage.

Here we use a join table query with the Aggregate.lookup(object: Object): Aggregate method.

lookup({
from: <name of the collection to join>,
localField: <The field in the input record for equality matching>,
foreignField: <The field in the joined collection for equality matching>,
as: <output array field name>
})
Parameter FieldDescription
fromThe name of another collection to join
letOptional. Specifies variables that can be used in the pipeline. The value of variables can reference fields from input records, e.g., let: userName: '$name' means using the input record's name field as the userName variable value. Input record fields cannot be accessed directly in the pipeline; they must be defined via let before access. Access is achieved in the expr operator using $$variable_name syntax, e.g., $$userName.
pipelineOptional. Specifies variables that can be used in the pipeline. The value of variables can reference fields from input records, e.g., let: userName: '$name' means using the input record's name field as the userName variable value. Input record fields cannot be accessed directly in the pipeline; they must be defined via let before access. Access is achieved in the expr operator using $$variable_name syntax, e.g., $$userName.
asSpecifies the field name to store the list of matched records from the join. This array contains matched records from the from collection. If the input record already has this field, it will be overwritten.

The operation is equivalent to the following pseudo-SQL statement:

SELECT *, <output array field>
FROM collection
WHERE <output array field> IN (SELECT <documents as determined from the pipeline>
FROM <collection to join>
WHERE <pipeline> );

Step 2: Set Up the Cloud Function lookup

  1. Right-click the current environment folder, click New Node.js Cloud Function, and name the file lookup.

  1. Since the _id in the products matches the sp in the orders, write the following code in the index.js file under the lookup cloud function to associate the two tables.
// Cloud Function entry file
const cloud = require("wx-server-sdk");

cloud.init({
env: "Environment ID",
});
const db = cloud.database();
// Cloud function entry function
exports.main = async (event, context) => {
var text = event.userid;
return await db
.collection("dd")
.aggregate()
.lookup({
from: "sp",
localField: "sp",
foreignField: "_id",
as: "bookList",
})
.end();
};
  1. Then, on the dingdan.js page, we pass the openid to the cloud function look.
onLoad: function (options) {
const app = getApp()
var userid = app.globalData.userid
this.setData({
userid: userid,
})
wx.cloud.callFunction({
name: 'lookup',
data: {
userid: app.globalData.userid
},
complete: res => {
console.log(res.result.list)
this.setData({
rmb: res.result.list
})
}
})
},

Step 3: Set Up the Shopping Cart Page

  1. Next, we will set up the shopping cart page.
<!--pages/dingdan/dingdan.wxml-->
<view class="qsy" wx:if="{{openid!=''&&rmb==''}}">
<view class="mydd">
<image src="../../images/font-ui/zwjl.png"></image>
</view>
<view class="text_wydd">No orders yet, go place an order now!</view>
</view>
<view class="qsy" wx:if="{{openid==''}}">
<view class="wdl">
<image src="../../images/font-ui/wdl.png"></image>
</view>
<view class="text_main">You have not authorized login, please authorize login!</view>
<button bindtap="getopenid" size="default" class="btn_sq" type="primary">Log in</button>
</view>
<view wx:if="{{openid!=''&&rmb!=''}}" class="text_main1" wx:for="{{rmb}}" wx:for-item="item" wx:key="_id" bindtap='showbs' id="{{item._id}}" wx:if="{{openid==item.userid&&item.xd==0}}">
<view class="main_gwc">
<view class="title">
<view class="sjmc_1">
{{item.bookList[0].name}}
</view>
<button size="mini" type="primary" class="sp_btn" id="{{item._id}}" bindtap="binxd">Place Order</button>
<button size="mini" type="warn" class="sp_btn" id="{{item._id}}" bindtap="binqc">Clear Items</button>
</view>
<view class="zp_sp">
<image src='{{item.bookList[0].zp}}'></image>
</view>
<view class="zp_nrl">
<view class="title_zpnrl">
Ingredients:{{item.bookList[0].pl}}
</view>
<view class="title_zpnrl1">
Price:{{item.bookList[0].jg}}
</view>
<view class="title_zpnrl">
Added: {{item.time}}
</view>
</view>
</view>
</view>
  1. The following figure shows the effect:

Step 4: Build Meal Pickup Function

  1. Go to the ddgl.js page and add the following methods to implement the meal pickup and cancel item functionality.
binqc: function (e) {
wx.showModal({
title: 'Prompt',
content: 'Are you sure you want to cancel the order? This will affect your credibility.',
success(res) {
if (res.confirm) {
console.log('Confirm')
console.log(e.currentTarget.id)
db.collection('dd').doc(e.currentTarget.id).remove({
success: function (res) {
wx.navigateTo({
url: '/pages/index/index',
})
}
})
} else if (res.cancel) {
console.log('Cancel')
}
}
})

},
binxd: function (e) {
wx.showModal({
title: 'Meal Pickup',
content: 'Meal Pickup Number: ' + e.currentTarget.id,
success(res) {
if (res.confirm) {
db.collection('dd').doc(e.currentTarget.id).update({
// Pass in the data that requires partial updating
data: {
// Indicates setting the done field to true
qccg: 1,
qcsj: myDate.toLocaleString(),
},
success: res => {
wx.showToast({
title: 'Meal Pickup Successful',
icon: 'success',
duration: 2000
})
}

})
} else if (res.cancel) {
console.log('User clicked cancel')
}
}
})
},
  1. The final result is as follows:

At this point, all features of the mini program have been implemented. For more details, refer to the sample code.