uniapp雲函式教程② :商品列表增刪改查

JenK發表於2021-10-21

上篇文章uniapp雲函式教程① :登入篇,我們實現了簡單的登入與註冊邏輯。這篇文章我們來實現一個商品列表的增刪改查實戰小專案。原始碼見文末。

掃碼體驗

.png瀏覽器訪問

1.資料庫設計

我們需要2張表:商品分類表(mall_type)以及商品表(mall_shop),商品表通過鍵key來和商品分類表進行關聯

1.1商品分類表(mall_type)

image.png

{
  "bsonType": "object",
  "required": [],
  "permission": {
    "read": false,
    "create": false,
    "update": false,
    "delete": false
  },
  "properties": {
    "_id": {
      "description": "ID,系統自動生成"
    },
    "name": {
      "description": "商品一級分類"
    }
  }
}

1.2商品表(mall_shop)

image.png

{
  "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": "價格"
    }
  }
}

以下僅展示關鍵程式碼,具體程式碼可至原始碼檢視

2.商品列表介面開發

這裡直接使用uviewui垂直分類的程式碼
image.png

3.商品入庫介面開發

3.1商品分類功能開發

image.png

3.1.1商品分類新增功能

新建雲函式addType,上傳部署以及上傳執行,新增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
};

新增表單以及介面

<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商品分類查詢功能

新建雲函式getType,上傳部署以及上傳執行,新增PATH/http/gettype

exports.main = async (event, context) => {
    const db = uniCloud.database(); //程式碼塊為cdb
    const res = await db.collection('mall_type').get()
    return res
};

新增展示當前有多少分類介面,這裡採用tag的形式,也方便做刪除

<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商品分類刪除功能

新建雲函式delType,上傳部署以及上傳執行,新增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
};

新增tag上的方法,以及刪除二次彈窗

<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商品功能開發

image.png

3.2.1商品新增功能

新建雲函式addShop,上傳部署以及上傳執行,新增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
};

這裡圖片直接使用base64進行儲存
新增表單以及介面

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

圖片上傳改為自行上傳,並取到圖片的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商品查詢功能

新建雲函式getShop,上傳部署以及上傳執行,新增PATH/http/getshop
這裡的資料格式按照uview商品模板的資料格式來元件即可

[
  {
    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
    }
};

回到剛才的商城模板頁面,新增獲取商品的程式碼,並將tabbar的模擬資料替換為真實資料

getShop(){
    uni.showLoading({
        title: '獲取商品中'
    });
    uni.request({
        url: 'https://f**.com/http/getShop',
        success: (res) => {
            this.tabbar = res.data.data || []
            uni.hideLoading()
        }
    })
},

3.2.3商品刪除功能

新建雲函式delShop,上傳部署以及上傳執行,新增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
};

在商城列表,我們為商品新增一個長按(longpress)刪除的功能,大約在mallMenu.vue24行。並新增二次確認彈窗

<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()
        }
    })
}

至此,商品的入庫、檢視、刪除功能便開發完成了

結尾

商品圖片素材包下載
原始碼下載
原始碼下載gitee
WX20210922-091703.png

相關文章