The last article uniapp cloud function tutorial ①: Login article , we have implemented simple login and registration logic. In this article, let's implement a small project of adding, deleting, modifying and verifying a product list. See the end of the text for the source code.
Scan code experience
1. Database design
We need 2 tables: commodity classification table ( mall_type
) and commodity table ( mall_shop
). The commodity table is associated with the commodity classification table key
1.1 Product classification table ( mall_type
)
{
"bsonType": "object",
"required": [],
"permission": {
"read": false,
"create": false,
"update": false,
"delete": false
},
"properties": {
"_id": {
"description": "ID,系统自动生成"
},
"name": {
"description": "商品一级分类"
}
}
}
1.2 Product list ( mall_shop
)
{
"bsonType": "object",
"required": [],
"permission": {
"read": false,
"create": false,
"update": false,
"delete": false
},
"properties": {
"_id": {
"description": "ID,系统自动生成"
},
"name": {
"description": "商品名称"
},
"key": {
"description": "对应的一级分类Id"
},
"icon": {
"description": "商品图片"
},
"price": {
"description": "价格"
}
}
}
only the key code is shown, the specific code can be viewed in the source code
2. Product list interface development
Here directly use the code of uviewui vertical classification
3. Development of commodity warehousing interface
3.1 Commodity classification function development
3.1.1 Product classification added function
Create a new cloud function addType
, upload deployment and upload operation, add PATH /http/addtype
'use strict';
exports.main = async (event, context) => {
const db = uniCloud.database(); //代码块为cdb
const dbCmd = db.command
const collection = db.collection('mall_type');
let queryStringParameters = event.queryStringParameters
let name = queryStringParameters['name']
let callback = {}
let isHasRes = await collection.where({
name: dbCmd.eq(name)
})
.get()
//简单做一下重复校验
if (isHasRes.data.length) {
callback = {
mesg: '商品分类重复',
code: 500
}
} else {
let res = await collection.add({
name: queryStringParameters['name']
})
callback = {
mesg: '添加成功',
code: 200,
id: res.id
}
}
return callback
};
Add form and interface
<u-form :model="form" ref="uForm">
<u-form-item label="商品分类" prop="name" label-width='150'>
<u-input v-model="form.name" placeholder="衣服、酒水等等" />
</u-form-item>
</u-form>
<u-button @click="submit" type="primary" >提交</u-button>
addType() {
uni.showLoading({
title: '添加中'
});
uni.request({
url: 'https://**.com/http/addtype',
data: {
name: this.form.name
},
success: (res) => {
if (res.data.code == 200) {
uni.showToast({
icon: 'success',
title: '添加成功'
});
this.$refs.uForm.resetFields()
} else {
uni.showToast({
icon: 'error',
title: res.data.mesg || '添加失败'
});
}
},
complete: () => {
uni.hideLoading();
this.getType()
}
})
},
3.1.2 Product classification query function
Create a new cloud function getType
, upload deployment and upload operation, add PATH /http/gettype
exports.main = async (event, context) => {
const db = uniCloud.database(); //代码块为cdb
const res = await db.collection('mall_type').get()
return res
};
Add to show how many classification interfaces there are currently, here in tag
, it is also convenient to delete
<u-tag :text="item.name" v-for="(item,index) in typeList" :key="index" />
getType() {
uni.showLoading({
title: '获取分类中'
});
uni.request({
url: 'https://**.com/http/gettype',
success: (res) => {
this.typeList = res.data.data || []
uni.hideLoading()
}
})
}
3.1.2 Commodity category deletion function
Create a new cloud function delType
, upload deployment and upload operation, add PATH /http/deltype
'use strict';
exports.main = async (event, context) => {
const db = uniCloud.database();
const dbCmd = db.command
let id = event.queryStringParameters['id']
const collection = db.collection('mall_type');
let res = await collection.where({
_id: dbCmd.eq(id)
}).remove()
return res
};
Add tag
, and delete the secondary pop-up window
<u-tag :text="item.name" v-for="(item,index) in typeList" :key="index" closeable @close="tagClick(item,index)" />
<u-modal v-model="show" content="是否删除商品类型?" @confirm='confirm' show-cancel-button></u-modal>
tagClick(item, index) {
this.show = true;
this.selectItem = item
},
confirm() {
uni.request({
url: 'https://**.com/http/deltype',
data: {
id: this.selectItem._id
},
success: (res) => {
uni.showToast({
icon: 'success',
title: '删除成功'
});
this.getType()
}
})
}
3.2 Product function development
3.2.1 Product addition function
Create a new cloud function addShop
, upload deployment and upload operation, add PATH /http/addshop
'use strict';
exports.main = async (event, context) => {
const db = uniCloud.database(); //代码块为cdb
const dbCmd = db.command
const collection = db.collection('mall_shop');
//因为数据有base64图片,所以改为body获取
let body = JSON.parse(event.body)
let name = body['name']
let key = body['key']
let icon = body['icon']
let price = body['price']
let callback = {}
let isHasRes = await collection.where({
name: dbCmd.eq(name)
})
.get()
if (isHasRes.data.length) {
callback = {
mesg: '商品重复',
code: 500
}
} else {
let res = await collection.add({
name: name,
key: key,
icon: icon,
price: price,
})
callback = {
mesg: '添加成功',
code: 200,
id: res.id
}
}
//返回数据给客户端
return callback
};
The picture here is directly saved base64
Add form and interface
<u-form :model="form" ref="uForm" label-width='150'>
<u-form-item label="商品名称" prop="name">
<u-input v-model="form.name" placeholder="请输入商品名称" />
</u-form-item>
<u-form-item label="商品价格" prop="price">
<u-input v-model="form.price" placeholder="请输入商品价格" type='number' />
</u-form-item>
<u-form-item label="商品类型" label-width="150" prop="keyLabel">
<u-input type="select" :select-open="selectShow" v-model="form.keyLabel" placeholder="请选择商品类型"
@click="selectShow = true"></u-input>
</u-form-item>
<u-form-item label="商品图片(<1MB)" prop="icon" label-width="150">
<u-upload :max-size="1 * 1024 * 1024" ref="uUpload" width="160" height="160" @on-choose-complete='changeImg' :auto-upload="false" max-count="1"></u-upload>
</u-form-item>
</u-form>
<u-button @click="submit" type="primary">提交</u-button>
<u-select mode="single-column" :list="typeList" v-model="selectShow" @confirm="selectConfirm"></u-select>
The picture upload is changed to upload by base64
changeImg(){
let file = this.$refs.uUpload.lists[0]
var fr = new FileReader();
fr.onloadend = function(e) {
this.form.icon = e.target.result;
}.bind(this);
fr.readAsDataURL(file.file);
},
addShop() {
uni.showLoading({
title: '添加中'
});
uni.request({
url: 'https://f**.com/http/addshop',
method: 'POST',
data: {
key: this.form.key,
price: this.form.price,
name: this.form.name,
icon: this.form.icon,
},
success: (res) => {
if (res.data.code == 200) {
uni.showToast({
icon: 'success',
title: '添加成功'
});
// this.$refs.uForm.resetFields()
} else {
uni.showToast({
icon: 'error',
title: res.data.mesg || '添加失败'
});
}
},
complete: () => {
uni.hideLoading();
}
})
},
3.2.2 Product query function
Create a new cloud function getShop
, upload deployment and upload operation, add PATH /http/getshop
The data format here can be uview
according to the data format of the 0616fcc935dba0 product template
[
{
name: "xxx",
foods: [
{
name: "xx",
key: "xx",
icon: "xx",
price: "xx"
}
]
}
];
'use strict';
exports.main = async (event, context) => {
const db = uniCloud.database(); //代码块为cdb
const dbCmd = db.command
//查询商品分类
const typeRes = await db.collection('mall_type').get()
const collection = db.collection('mall_shop');
let shopList = []
let typeList = typeRes.data || []
for (var i = 0; i < typeList.length; i++) {
//查询商品分类下的所属商品
let list = await collection.where({
key: dbCmd.eq(typeList[i]._id)
})
.get()
let obj = {
name: typeList[i].name,
foods: list.data || []
}
shopList.push(obj)
}
return {
data: shopList
}
};
Go back to the mall template page just now, add the code to get the product, and tabbar
the simulated data of 0616fcc935dbf7 with real data
getShop(){
uni.showLoading({
title: '获取商品中'
});
uni.request({
url: 'https://f**.com/http/getShop',
success: (res) => {
this.tabbar = res.data.data || []
uni.hideLoading()
}
})
},
3.2.3 Commodity deletion function
Create a new cloud function delShop
, upload deployment and upload operation, add PATH /http/delshop
'use strict';
exports.main = async (event, context) => {
const db = uniCloud.database(); //代码块为cdb
const dbCmd = db.command
let id = event.queryStringParameters['id']
const collection = db.collection('mall_shop');
let res = await collection.where({
_id: dbCmd.eq(id)
}).remove()
//返回数据给客户端
return res
};
In the mall list, we add a long press ( longpress
) delete function for the product, which is about line 24 of mallMenu.vue
And add a second confirmation popup
<view class="thumb-box" v-for="(item1, index1) in item.foods" :key="index1" @longpress='del(item1)'>
<image class="item-menu-image" :src="item1.icon" mode=""></image>
<view class="item-menu-name">{{item1.name}}</view>
</view>
、、、
、、、
<u-modal v-model="show" content="是否删除商品?" @confirm='confirm' show-cancel-button></u-modal>
del(item){
this.delItem = item
this.show = true
},
confirm(){
uni.request({
url: 'https://**.com/http/delshop',
data: {
id: this.delItem._id
},
success: (res) => {
uni.showToast({
icon: 'success',
title: '删除成功'
});
this.getShop()
}
})
}
At this point, the product storage, viewing, and deletion functions have been developed
end
product picture material package download
source download
source download gitee
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。