跳到主要内容

预约点餐小程序开发

概述#

本文介绍如何用云开发相关能力,快速搭建预约点餐系统。

说明

本实例教程所涉及到的相关源码材料,均已得到相应授权。

准备工作#

  1. 注册腾讯云

  2. 开通了云开发的小程序,详情请参见 小程序端快速入门

  3. 进入云开发控制台 > 设置 > 拓展功能页面,单击开通内容管理内容安全

操作流程#

具体操作流程可分为以下 6 步。更多详情可参见 示例代码

步骤1:搭建轮播图与公告#

本文主要围绕主页的 index 页面、云开发内容管理云开发数据库 进行讲解,更多 index 代码细节可参见 index 页面

步骤 1:开通内容管理#

  1. 首先进入云开发控制台 > 内容管理页面,单击开通,并设置账号密码。内容管理创建需要一定的时间请安心等待。

  1. 在创建成功之后返回内容管理页面,单击访问地址即可访问内容管理平台

  1. 输入登录账号和密码,进入内容管理(CMS)后台,单击创建新项目这里我们起名为预约点餐管理系统。

步骤 2:搭建轮播图#

  1. 进入上述新建的预约点餐管理系统,进入内容模型页面,单击新建模型,这里我们设置展示名称轮播图数据库名banner。设置完成后单击创建

注意事项

更改数据库名会自动重命名原数据库,请谨慎操作。

  1. 单击右侧内容类型 > 图片,进入添加图片字段页面,设置展示名称轮播图数据库字段名photo

单击添加后完成内容模型的创建。

  1. 进入内容集合 > 轮播图页面,单击新建

拖动图片并单击创建后完成轮播图片的上传,这样一个轮播图的内容模型我们就创建完成了。

  1. 通过上面操作后,相应的会在云开发控制台生成 banner 数据库以及上述导入的图片数据。进入云开发控制台 > 数据库 > banner > 数据权限页面,将数据库数据权限改为所有用户可读,仅创建者可读写,这样所有用户就可以看到数据了。

  1. 接下来在 pages/index 中开始编写轮播图。这里我们可以参见 swiper 文档,帮助我们绑定数据,这样我们使用 wx:for 进行列表绑定。

  2. 参数 env 可以在微信开发者工具 > 云开发控制台里获取。

// pages/index/index.jswx.cloud.init({  env: '您的环境ID',  traceUser: true,})const db = wx.cloud.database()Page({  /**   * 页面的初始数据   */  data: {    mgList: ''  },  /**   * 生命周期函数--监听页面加载   */  onLoad: function (options) {    //这里执行的是在页面首次加载时候在banner数据库获取数据,并将他们存在mgList里面    db.collection("banner").get({      success: res => {        console.log(res)        this.setData({          mgList: res.data        })      }    })  }})
  • 在组件上使用 wx:for 控制属性绑定一个数组,即可使用数组中各项的数据重复渲染该组件。
  • 默认数组的当前项的下标变量名默认为 index,数组当前项的变量名默认为 item*
  • 使用 wx:for-item 可以指定数组当前元素的变量名,
  1. 通过以下代码绑定 mgList 数据。
<!--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. 保存运行编译之后,可以看到轮播图。

说明

如果出现运行编译后无法加载轮播图,请在微信开发者工具单击右上角详情,进入本地设置页面,尝试切换调试基础库为较低版本即可。

步骤 3:搭建通知公告#

  1. 参照 步骤 2 创建通知公告内容模型。
  2. 其中通知公告内容模型数据库名设置为 tz。新增的内容类型 > 单行字符串数据库字段名设置为 text

  1. 进入内容集合 > 通知公告单击新建创建公告内容。

  1. 通过以下代码绑定 mgList 数据。
<!-- 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><!--通知栏--><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. 保存运行编译后即可。

步骤2:搭建首页热门栏目#

本文主要围绕主页的 index 页面和配置文件 app.json 进行讲解,更多 index 代码细节可参见 index 页面 和配置文件 app.json

步骤 1:搭建底部导航栏#

  1. 在 app.json 的 pages 数组配置好相应页面。
  2. 然后在 app.json 页面。通过设置 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. 将 tarBar 中相应的 UI 图片存到小程序 imges 目录中编译即可。

步骤 2:搭建中部导航栏#

  1. 进入首页 index 目录,通过 index.wxml 和 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" >东区食堂</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">西区食堂</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">每日优惠</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">南湖食堂</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">美食分享</view>  </view></view>
  1. 进入 index.js 页面,我们使用 wx.navigateTo(Object object) 跳转到应用内的某个页面,我们对导航栏给他点击事件,在用户在点击之后跳转到敬请期待页面。
// index.jsshowwd:function(){wx.navigateTo({  url: '../jqqd/jqqd',})},showtk:function(){wx.switchTab({  url: '../gltl/gltl'})},
说明

保留当前页面,跳转到应用内的某个页面。其中可使用 wx.navigateBack 返回到原页面。小程序中页面栈最多十层。

步骤 3:搭建首页热门美食栏目#

  1. 进入 CMS 内容管理控制台,新建美食列表内容模型,数据库名称设置为 mslb
  2. 进入新建的美食列表页面,如下设置内容集合:
内容类型展示名称数据库字段名
图片附件照片src
单行字符串名称name
单行字符串简介jj
单行字符串地址dz
单行字符串btn1btn1
单行字符串btn2btn2
单行字符串btn3btn3

更多 CMS 内容管理详细操作请参见 搭建轮播图

  1. 进入 index.wxml 页面,使用列表渲染 wx:for 进行列表展示。
<view class="rmbs">  <view class="rmbs-title">    <view class="rmbs-title-text">热门美食</view>    <view class="rmbs-title-more" bindtap='showlist'>查看更多 ></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">地址:{{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>

这里我们会发现有的时候 item.btn1 要是为空也会显示出来,我们可以改进一下,使用 wx:if 条件渲染。增加判断之后如果是空置就不显示这个按钮。

<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>

最终效果如下:

步骤3:搭建我的页面#

本文主要围绕我的页面 my 和 云函数 进行讲解,更多代码细节可参见 my 页面

步骤1:配置云函数#

  1. 右击当前环境文件夹,单击新建 Node.js 云函数,并将文件命名为 open

  1. 在 open 云函数下,index.js 文件下编写获取 openid 的代码。
// 云函数入口文件const cloud = require('wx-server-sdk')
cloud.init()
// 云函数入口函数exports.main = async (event, context) => {  const wxContext = cloud.getWXContext()
  return {    event,    openid: wxContext.OPENID,    appid: wxContext.APPID,    unionid: wxContext.UNIONID,  }}
说明

从小程序端调用云函数时,开发者可以在云函数内使用 wx-server-sdk 提供的 getWXContext 方法获取到每次调用的上下文(appidopenid 等),无需维护复杂的鉴权机制,即可获取天然可信任的用户登录态(openid)。

  1. 然后右击 open 文件夹,单击上传并部署:云端安装依赖,即完成了云函数的编写。

步骤2:搭建登录授权功能#

  1. 进入 app.js 初始化云开发。
// app.jsApp({  onLaunch: function () {    if (!wx.cloud) {      console.error('请使用 2.2.3 或以上的基础库以使用云能力');    } else {      wx.cloud.init({        // env 参数说明:        //   env 参数决定接下来小程序发起的云开发调用(wx.cloud.xxx)会默认请求到哪个云环境的资源        //   此处请填入环境 ID, 环境 ID 可打开云控制台查看        //   如不填则使用默认环境(第一个创建的环境)        env: '环境ID',        traceUser: true,      });    }
    this.globalData = {};  },  globalData:{    userid:''   }});
  1. 进入 my.js 在页面编写我的页面代码。在这里我们写一个点击事件,在用户点击我们绑定 getUserInfo 事件的按钮之后,我们调用获取用户信息。getopenid 是通过云函数获取用户 openid 方法。并将这个值存在 app.js 里面这样我们在其他页面可以直接进行调用。
const app = getApp();Page({  /**  * 页面的初始数据  */  data: {    username:"",    openid: '',  },  /**  * 生命周期函数--监听页面加载  */  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("获取失败", res);      }    })  },})
  1. 进入 my.wxml 页面,添加判断登录状态代码,我们可以进行判断如果没有获取到提醒用户登录,如果获取到的 openid 为空我们显示授权登录版块。
<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">爱国、敬业、求实、创新</view>  </view></view><view class="topbanner" wx:if="{{openid==''}}">   <view class="topban1">您还未授权登录</view>  <view class="topban1">去授权登录</view>  <button bindtap="getopenid" type="default">登录</button></view>

步骤4:搭建攻略页面#

本文主要围绕攻略页面进行讲解,更多代码细节可参见 攻略列表攻略详情发布评论发布攻略

步骤1:搭建攻略展示页#

  1. 进入 CMS 内容管理控制台,新建攻略内容模型,数据库名称设置为 glpj
  2. 进入新建的攻略页面,如下设置内容集合:
    内容类型展示名称数据库字段名
    图片照片photo
    单行字符串标题title
    日期与时间时间time
    单行字符串作者user
    数字浏览量lll
    富文本简介xq
说明

更多 CMS 内容管理详细操作请参见 搭建轮播图

  1. 这里我们依然通过 wx:for 渲染出列表,并给他点击跳转事件,并将当前文章 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">攻略评论</view>     <view class="qpl" id="{{rmbs._id}}" bindtap='showtl'>发表</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>

步骤2:搭建攻略详情及发表评论功能#

  1. 进入 CMS 内容管理控制台,新建攻略评论内容模型,数据库名称设置为 glplgl
  2. 进入新建的攻略评论页面,如下设置内容集合:
内容类型展示名称数据库字段名
单行字符串用户user
单行字符串文字text
单行字符串用户名字username
日期与时间datadata
单行字符串plwzplwz
说明

更多 CMS 内容管理详细操作请参见 搭建轮播图

  1. 攻略详情页面的逻辑及前端代码如下:
// pages/glxq/glxq.jswx.cloud.init({  env: '环境 ID',  traceUser: true,})const db=wx.cloud.database()Page({
  /**   * 页面的初始数据   */  data: {    list_id:"",    rmb:""  },
  /**   * 生命周期函数--监听页面加载   */  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      })    })  },
  /**   * 生命周期函数--监听页面初次渲染完成   */  onReady: function () {  },
  /**   * 生命周期函数--监听页面显示   */  onShow: function () {  },  showbs:function(e){    console.log(e.currentTarget.id)    wx.navigateTo({      url:'/pages/xpl/xpl?list_id='+e.currentTarget.id,    })  },})
  1. 在对应的攻略详情页面,单击去评论的时候我们需要获取到用户的 openid 和当前要发布评论的文章 ID。去评论的逻辑及前端代码如下:
// pages/xpl/xpl.jswx.cloud.init({  env: '环境 ID',  traceUser: true,})const db = wx.cloud.database()var myDate = new Date();Page({
  /**   * 页面的初始数据   */  data: {    list_id: "",    userid: '',  },
  /**   * 生命周期函数--监听页面加载   */  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',    })  },  /**   * 生命周期函数--监听页面初次渲染完成   */  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: '成功',          icon: 'success',          duration: 2000        })      })    } else {      wx.showToast({        title: '请填写信息',        icon: 'error',        duration: 2000      })    }  },})
说明

针对内容安全,微信云开发提供内容安全功能,可对云开发数据库中存储的信息进行内容安全的规则设置,自动进行内容审核并对触发违规的内容进行处理。详情请参见 内容安全

  1. 最终效果如下:

步骤3:搭建发表攻略功能#

  1. 进入 app.json 页面,添加 weui 框架。
{  "useExtendedLib": {    "weui": true  }}
  1. 然后进入 fbpl.json 页面再次引入 weui 的框架并在 fbpl.wxml 中调用。相关代码如下:
{  "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. 最终效果如下:

步骤5:搭建店铺页面#

本文主要围绕店铺页面进行讲解,更多代码细节可参见 店铺商家

步骤1:搭建店铺页面#

  1. 进入 CMS 内容管理控制台,新建店铺内容模型,数据库名称设置为 dp
  2. 进入新建的店铺页面,如下设置内容集合:
内容类型展示名称数据库字段名
单行字符串店铺名称name
单行字符串店铺地点dpdd
日期与时间时间time
布尔值是否营业sfyy
图片店铺照片dpzp
单行字符串简介jj
说明

更多 CMS 内容管理详细操作请参见 搭建轮播图

  1. 然后将它在小程序进行展示。
<!--pages/dp/dp.wxml--><view class='search'>  <input type='text' placeholder='请输入您要搜索的内容' 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">地址:{{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}}">营业中</view>        <view class="rmbs-list-text-btn" style="background-color: rgb(26, 69, 134);" wx:else>休息中</view>      </view>    </view>  </view></view>
  1. 效果如下:

步骤2:搭建商品页面#

  1. 进入 CMS 内容管理控制台,新建商品内容模型,数据库名称设置为 sp
  2. 进入新建的商品页面,如下设置内容集合:
    内容类型展示名称数据库字段名
    单行字符串名称name
    数字价格jg
    数字销量xl
    单行字符串配料pl
    图片照片zp
    关联商家sj
    其中,商家关联内容选择店铺展示字段选择店铺名称
说明

更多 CMS 内容管理详细操作请参见 搭建轮播图

  1. 在用户点击商家跳转到商品页面,我们依然需要传递商家的 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">您还未授权登录,请授权登录!</view>    <button size="mini" type="primary" bindtap='showsq' class="btn_sq">去授权</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">配料:{{item.pl}}</view>            <view class="pl">月售:{{item.xl}}</view>            <view class="jg">¥ {{item.jg}}</view>            <button size="mini" type="primary" bindtap="addCart" id="{{item._id}}"  class="btn_9">购买</button>        </view>      </view> </view> 
  1. 效果如下:

步骤3:搭建下单功能#

  1. 进入 CMS 内容管理控制台,新建订单内容模型,数据库名称设置为 dd
  2. 进入新建的订单页面,如下设置内容集合:
    内容类型展示名称数据库字段名
    单行字符串useriduserid
    关联商品sp
    单行字符串时间time
    布尔值下单xd
    布尔值是否取餐qccg
    单行字符串取餐时间qcsj
    其中,商品关联内容选择店铺展示字段选择店铺名
说明

更多 CMS 内容管理详细操作请参见 搭建轮播图

  1. 接下来进入 fbgl.js 页面配置下单事件。
 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: '添加成功',      icon: 'success',      duration: 2000    })  })},
说明

我们思考可以知道,我们用户下单里面需要有用户openid,商品,时间等信息。

我们使用插入数据方法将数据存入数据库,新增记录,如果传入的记录对象没有 _id 字段,则由后台自动生成 _id;若指定了 _id,则不能与已有记录冲突

步骤6:搭建订单页面#

本文主要围绕订单页面进行讲解,更多代码细节可参见 订单订单管理

步骤1:搭建云函数 look#

  1. 右击当前环境文件夹,单击新建 Node.js 云函数,并将文件命名为 look

  1. 在 look 云函数下,index.js 文件下编写聚合阶段联表查询代码。
// 云函数入口文件const cloud = require('wx-server-sdk')
cloud.init({  env: '环境 ID'})const db = cloud.database()// 云函数入口函数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()}
说明

与同个数据库下的一个指定的集合做 left outer join(左外连接)。对该阶段的每一个输入记录,lookup 会在该记录中增加一个数组字段,该数组是被联表中满足匹配条件的记录列表。lookup 会将连接后的结果输出给下个阶段。

这里我们使用连表查询,使用 Aggregate.lookup(object: Object): Aggregate 方法。

lookup({  from: <要连接的集合名>,  localField: <输入记录的要进行相等匹配的字段>,  foreignField: <被连接集合的要进行相等匹配的字段>,  as: <输出的数组字段名>})
参数字段说明
from要进行连接的另外一个集合的名字
let可选。指定在 pipeline 中可以使用的变量,变量的值可以引用输入记录的字段,例如 let: userName: '$name' 就代表将输入记录的 name 字段作为变量 userName 的值。在 pipeline 中无法直接访问输入记录的字段,必须通过 let 定义之后才能访问,访问的方式是在 expr 操作符中用 $$变量名 的方式访问,例如 $$userName
pipeline指定要在被连接集合中运行的聚合操作。如果要返回整个集合,则该字段取值空数组 []。在 pipeline 中无法直接访问输入记录的字段,必须通过 let 定义之后才能访问,访问的方式是在 expr 操作符中用 $$变量名 的方式访问,例如 $$userName
as指定连接匹配出的记录列表要存放的字段名,这个数组包含的是匹配出的来自 from 集合的记录。如果输入记录中本来就已有该字段,则该字段会被覆写

该操作等价于以下伪 SQL 语句:

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

步骤2:搭建云函数 lookup#

  1. 右击当前环境文件夹,单击新建 Node.js 云函数,并将文件命名为 lookup

  1. 由于商品里面的 _id 与订单里面 sp 相同,在 lookup 云函数下,index.js 文件编写以下代码,实现两个表的关联。
// 云函数入口文件const cloud = require('wx-server-sdk')
cloud.init({  env: '环境 ID'})const db = cloud.database()// 云函数入口函数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. 然后我们在 dingdan.js 页面传 openid 到云函数 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      })    }  })},

步骤3:搭建购物车页面#

  1. 接下来我们搭建购物车页面。
<!--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">暂未有订单,快去下单吧!</view></view><view class="qsy" wx:if="{{openid==''}}">    <view class="wdl">        <image src="../../images/font-ui/wdl.png"></image>    </view>    <view class="text_main">您还未授权登录,请授权登录!</view>    <button bindtap="getopenid" size="default" class="btn_sq" type="primary">登录</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">下单</button>            <button size="mini" type="warn" class="sp_btn" id="{{item._id}}" bindtap="binqc">清除商品</button>        </view>        <view class="zp_sp">            <image src='{{item.bookList[0].zp}}'></image>        </view>        <view class="zp_nrl">            <view class="title_zpnrl">                配料:{{item.bookList[0].pl}}            </view>            <view class="title_zpnrl1">                价格:{{item.bookList[0].jg}}            </view>            <view class="title_zpnrl">                加入时间:{{item.time}}            </view>        </view>    </view></view>  
  1. 效果如下:

步骤4:搭建取餐功能#

  1. 进入 ddgl.js 页面,增加以下方法实现取餐取消商品功能。
binqc: function (e) {    wx.showModal({      title: '提示',      content: '是否确认取消订单,会影响您的诚信度哦!',      success(res) {        if (res.confirm) {          console.log('确定')          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('取消')        }      }    })
  },  binxd: function (e) {    wx.showModal({      title: '取餐',      content: '取餐号为' + e.currentTarget.id,      success(res) {        if (res.confirm) {          db.collection('dd').doc(e.currentTarget.id).update({            // data 传入需要局部更新的数据            data: {              // 表示将 done 字段置为 true              qccg: 1,              qcsj: myDate.toLocaleString(),            },            success: res => {              wx.showToast({                title: '取餐成功',                icon: 'success',                duration: 2000              })            }
          })        } else if (res.cancel) {          console.log('用户点击取消')        }      }    })  },
  1. 最终效果如下:

至此,该小程序的全部功能已实现完成。更多详情请参见 示例代码