本文主要围绕订单页面进行讲解,更多代码细节可参见 订单 和 订单管理。
操作步骤
步骤1:搭建云函数 look
- 右击当前环境文件夹,单击新建 Node.js 云函数,并将文件命名为 look。
- 在 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
会将连接后的结果输出给下个阶段。lookup({
from: <要连接的集合名>,
localField: <输入记录的要进行相等匹配的字段>,
foreignField: <被连接集合的要进行相等匹配的字段>,
as: <输出的数组字段名>
})参数字段 说明 from 要进行连接的另外一个集合的名字 let 可选。指定在 pipeline
中可以使用的变量,变量的值可以引用输入记录的字段,例如let: { userName: '$name' }
就代表将输入记录的name
字段作为变量userName
的值。在pipeline
中无法直接访问输入记录的字段,必须通过let
定义之后才能访问,访问的方式是在expr
操作符中用$$变量名
的方式访问,例如$$userName
。pipeline 指定要在被连接集合中运行的聚合操作。如果要返回整个集合,则该字段取值空数组 []
。在pipeline
中无法直接访问输入记录的字段,必须通过let
定义之后才能访问,访问的方式是在expr
操作符中用$$变量名
的方式访问,例如$$userName
。as 指定连接匹配出的记录列表要存放的字段名,这个数组包含的是匹配出的来自 from
集合的记录。如果输入记录中本来就已有该字段,则该字段会被覆写SELECT *, <output array field>
FROM collection
WHERE <output array field> IN (SELECT <documents as determined from the pipeline>
FROM <collection to join>
WHERE <pipeline> );
步骤2:搭建云函数 lookup
- 右击当前环境文件夹,单击新建 Node.js 云函数,并将文件命名为 lookup。
- 由于商品里面的 _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()
} - 然后我们在 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:搭建购物车页面
- 接下来我们搭建购物车页面。
<!--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> - 效果如下:
步骤4:搭建取餐功能
- 进入 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('用户点击取消')
}
}
})
}, - 最终效果如下:
至此,该小程序的全部功能已实现完成。更多详情请参见 示例代码。