文章目錄
- 1. 項目概述
- 2. 項目思維導圖
- 3. 系統架構特點
- 4. 核心模塊實現代碼
- 1. 登錄注冊
- 2. 首頁模塊實現
- 4. 分類模塊實現
- 5. 購物車模塊實現
- 6. 訂單模塊實現
- 5. 注意事項
- 6. 項目效果截圖
- 7. 關于作者其它項目視頻教程介紹
1. 項目概述
在移動互聯網時代,餐飲行業數字化轉型已成為必然趨勢。今天我想分享一個基于小程序的美食點餐/訂餐系統的設計與實現,該系統包含用戶模塊、首頁模塊、分類模塊、購物車模塊和個人中心等核心功能模塊。
2. 項目思維導圖
3. 系統架構特點
- 純前端實現:不依賴服務器,所有數據存儲在本地
- 基于微信小程序API數據存儲:主要使用wx.setStorageSync/wx.getStorageSync
- 數據持久化:關閉小程序后數據不會丟失
4. 核心模塊實現代碼
1. 登錄注冊
//用戶注冊
onRegisterHandle(){if(this.data.username==='' || this.data.password ===''){wx.showToast({title: '注冊信息不能為空',icon :'error'})return}let users =wx.getStorageSync('users') ||[]if(users.some(item => item.username === this.data.username)){wx.showToast({title: '用戶名已存在',icon: 'error'})return}let user ={username: this.data.username,password: this.data.password}users.push(user)wx.setStorageSync("users",users)wx.showToast({title: '注冊成功',icon :'success'})setTimeout(() => {wx.navigateBack()},500)}//用戶登錄
onLoginHandle(options) {if (this.data.username === '' || this.data.password === '') {wx.showToast({title: '登錄信息不能為空',icon: 'error'})return}let users = wx.getStorageSync('users') || []if (users.some(item => item.username === this.data.username && item.password === this.data.password)) {wx.showToast({title: '登錄成功',icon: 'success'})let user = {username: this.data.username,password: this.data.password}//保存當前用戶登錄信息wx.setStorageSync("user", user)setTimeout(() => {wx.navigateBack()}, 500)} else {wx.showToast({title: '用戶名或密碼錯誤',icon: 'error'})}},
2. 首頁模塊實現
//導入數據
import { bannerList, startList, produtList } from '../../utils/dataservice'Page({data: {bannerList: [],startList: [],produtList: []},onLoad() {this.setData({//加載輪播圖數據bannerList: bannerList,//加載精剛區數據startList: startList,//加載首頁商品列表數據produtList: produtList})},/*** 列表點擊事件*/onItemClickHandle(options) {const item = encodeURIComponent(JSON.stringify(options.currentTarget.dataset.item))wx.navigateTo({url: `/pages/detail/detail?productInfo=${item}`,})},
})
4. 分類模塊實現
// pages/category/category.js//導入數據
import getCategoryList from '../../utils/dataservice';
Page({/*** 頁面的初始數據*/data: {categoryList: [{ "category_id": 0, "category_name": "新品推薦" },{ "category_id": 1, "category_name": "招牌爆款" },{ "category_id": 2, "category_name": "主廚推薦" },{ "category_id": 3, "category_name": "開胃前菜" },{ "category_id": 4, "category_name": "美味主食" },{ "category_id": 5, "category_name": "美味甜品" },{ "category_id": 6, "category_name": "鮮榨果品" },{ "category_id": 7, "category_name": "蔬菜沙拉" },{ "category_id": 8, "category_name": "輕食小吃" },],productList: [],selectedIndex: 0},/*** 生命周期函數--監聽頁面加載*/onLoad(options) {//獲取商品分類列表數據this.getCategoryListData(this.data.selectedIndex)},/*** 商品分類選擇*/onSelectedHandle(options) {this.setData({selectedIndex: options.currentTarget.dataset.item.category_id})//獲取商品分類列表數據this.getCategoryListData(this.data.selectedIndex)},/*** 獲取商品分類列表數據*/getCategoryListData(selectedIndex) {const result = getCategoryList(selectedIndex)this.setData({productList: result})},/*** 列表點擊事件*/onItemClickHandle(options) {const item = encodeURIComponent(JSON.stringify(options.currentTarget.dataset.item))wx.navigateTo({url: `/pages/detail/detail?productInfo=${item}`,})},})
5. 購物車模塊實現
// pages/cart/cart.js
Page({/*** 頁面的初始數據*/data: {carts: [],totalPrice: 0},/*** 生命周期函數--監聽頁面加載*/onShow(options) {this.loadCartData();},/*** 加載購物車數據*/loadCartData() {const user = wx.getStorageSync('user') || {};const allCarts = wx.getStorageSync('carts') || [];// 提取當前用戶的數據const userCart = allCarts.find(cart => cart.username === user.username) || { items: [] };this.setData({carts: userCart.items,totalPrice: this.calculateTotalPrice(userCart.items)});},// 計算總價方法 calculateTotalPrice(cartItems) {// 使用 reduce 方法累加每個商品的總價return cartItems.reduce((total, item) => {return total + (item.price * item.count);}, 0).toFixed(2) * 100; // 保留兩位小數},/*** 加購*/plus(options) {const user = wx.getStorageSync('user') || {};const item = options.currentTarget.dataset.item;// 1. 獲取所有用戶的購物車數據const allCarts = wx.getStorageSync('carts') || [];// 2. 找到當前用戶的購物車(沒有則初始化)let userCart = allCarts.find(cart => cart.username === user.username);if (!userCart) {userCart = { username: user.username, items: [] };allCarts.push(userCart);}// 3. 修改當前用戶的購物車商品數量const updatedItems = userCart.items.map(cartItem => {return cartItem.product_id === item.product_id ? { ...cartItem, count: cartItem.count + 1 } : cartItem;});// 4. 更新數據userCart.items = updatedItems;wx.setStorageSync('carts', allCarts);// 5. 更新頁面顯示(只展示當前用戶的數據)this.setData({carts: updatedItems,totalPrice: this.calculateTotalPrice(updatedItems)});},// 更新購物車數據updateCart(updatedCart) {wx.setStorageSync('carts', updatedCart);this.setData({carts: updatedCart,totalPrice: this.calculateTotalPrice(updatedCart)});},/*** 減購*/minus(options) {// 獲取當前點擊商品數據const product = options.currentTarget.dataset.item;const allCarts = wx.getStorageSync('carts') || [];const user = wx.getStorageSync('user');// 1. 找到當前用戶的購物車const userCart = allCarts.find(cart => cart.username === user.username);if (!userCart) return; // 無購物車則退出// 2. 找到商品在購物車中的索引const itemIndex = userCart.items.findIndex(item => item.product_id === product.product_id);if (itemIndex === -1) return; // 商品不存在則退出// 3. 減少數量userCart.items[itemIndex].count -= 1;// 4. 保存數據并更新 UIwx.setStorageSync('carts', allCarts);this.setData({carts: userCart.items || [], // 確保空購物車時傳空數組totalPrice: this.calculateTotalPrice(userCart.items || [])});},/*** 刪除商品*/removeItemHandle(options) {// 獲取要刪除的商品const product = options.currentTarget.dataset.item;wx.showModal({title: '溫馨提示',content: '確定要從購物車移除該商品嗎?',complete: (res) => {if (res.confirm) {const user = wx.getStorageSync('user');const allCarts = wx.getStorageSync('carts') || [];// 1. 找到當前用戶的購物車const userCartIndex = allCarts.findIndex(cart => cart.username === user.username);if (userCartIndex === -1) return; // 用戶購物車不存在則退出// 2. 從該用戶的 items 中移除目標商品const updatedItems = allCarts[userCartIndex].items.filter(item => item.product_id !== product.product_id);// 3. 更新數據allCarts[userCartIndex].items = updatedItems;// 4. 保存數據并更新 UIwx.setStorageSync('carts', allCarts);this.setData({carts: updatedItems, // 更新當前頁面的購物車列表totalPrice: this.calculateTotalPrice(updatedItems)});}}})},/*** 提交訂單*/onSubmit(options) {const user = wx.getStorageSync('user')if (!user) {wx.showModal({title: '溫馨提示',content: '系統檢測到您未登錄,請先登錄',complete: (res) => {if (res.confirm) {wx.navigateTo({url: '/pages/login/login',})}}})return;}if (this.data.totalPrice === 0) {wx.showToast({title: '購物車空空如也,去看看吧~',icon: 'error',success: () => {setTimeout(() => {wx.switchTab({url: '/pages/category/category',})}, 500)}})return;}wx.showModal({title: '溫馨提示',content: '您確定下單嗎?',complete: (res) => {if (res.confirm) {// 1. 獲取當前用戶的購物車數據const allCarts = wx.getStorageSync('carts') || [];const userCartIndex = allCarts.findIndex(cart => cart.username === user.username);if (userCartIndex === -1 || allCarts[userCartIndex].items.length === 0) {wx.showToast({ title: '購物車為空', icon: 'error' });return;}const userCartItems = allCarts[userCartIndex].items;// 2. 生成訂單(添加訂單時間、狀態等元信息)const newOrder = {order_id: Date.now().toString(), // 簡單生成訂單ID(實際項目建議更嚴謹的方式)username: user.username,items: userCartItems,create_time: new Date().toLocaleString(),status: '支付成功'}// 3. 保存訂單(多用戶訂單隔離)const allOrders = wx.getStorageSync('orders') || [];allOrders.push(newOrder); // 將新訂單追加到訂單列表wx.setStorageSync('orders', allOrders);// 4. 清空當前用戶的購物車(不影響其他用戶)allCarts[userCartIndex].items = []; // 清空items而非刪除用戶條目,保留用戶購物車結構wx.setStorageSync('carts', allCarts);// 5. 更新頁面狀態this.setData({carts: [],totalPrice: 0});wx.showToast({title: '下單成功',})}}})}
})
6. 訂單模塊實現
// pages/order/order.js
Page({/*** 頁面的初始數據*/data: {orderList: []},/*** 生命周期函數--監聽頁面加載*/onLoad(options) {this.loadUserOrders();},/*** 訂單加載方法中預處理數據*/loadUserOrders() {const { username } = wx.getStorageSync('user');// 1. 獲取所有訂單(假設數據結構為訂單數組,每個訂單包含items)const result = wx.getStorageSync('orders') || [];//2. 過濾出當前用戶的訂單,并平鋪itemsconst userOrder = result.filter(item => item.username === username).flatMap(order => {// 為每個商品添加訂單元信息(可選)return order.items.map(item => ({...item,order_id: order.order_id, // 關聯訂單IDorder_status: order.status, // 訂單狀態create_time: order.create_time, // 下單時間unique_id: `${order.order_id}${item.product_id}`}));})// 3. 更新數據this.setData({orderList: userOrder})},/*** 刪除訂單*/removeOrderHandle(options) {const orderInfo = options.currentTarget.dataset.item;const user = wx.getStorageSync('user')wx.showModal({title: '溫馨提示',content: '確定要從訂單中刪除該商品嗎?',complete: (res) => {if (res.confirm) {// 1. 獲取所有訂單數據const allOrders = wx.getStorageSync('orders') || [];// 2. 遍歷查找目標商品const updatedOrders = allOrders.map(order => {// 2.1 檢查訂單歸屬if (order.username !== user.username) {return order;}// 2.2 過濾掉目標商品const updatedItems = order.items.filter(item => `${order.order_id}${item.product_id}` !== orderInfo.unique_id)// 2.3 updatedItems 可能返回空items的訂單,所有加判空處理return updatedItems.length > 0 ? { ...order, items: updatedItems } : null;}).filter(Boolean) // 移除null(即空訂單)console.log(updatedOrders)// 4. 保存數據wx.setStorageSync('orders', updatedOrders);// 5. 重新加載this.loadUserOrders();wx.showToast({title: '刪除成功',})}}})}
})
5. 注意事項
- 存儲限制:wx.setStorageSync有10MB大小限制
- 多設備同步:本地存儲無法實現多設備同步
- 數據持久性:用戶清理緩存會丟失所有數據
這個純前端實現方案適合作為學習項目或個人小店使用,如果要開發商業應用,建議還是使用后端數據庫存儲數據。
6. 項目效果截圖
7. 關于作者其它項目視頻教程介紹
本人在b站錄制的一些視頻教程項目,免費供大家學習
- Android新聞資訊app實戰:https://www.bilibili.com/video/BV1CA1vYoEad/?vd_source=984bb03f768809c7d33f20179343d8c8
- Androidstudio開發購物商城實戰:https://www.bilibili.com/video/BV1PjHfeXE8U/?vd_source=984bb03f768809c7d33f20179343d8c8
- Android開發備忘錄記事本實戰:https://www.bilibili.com/video/BV1FJ4m1u76G?vd_source=984bb03f768809c7d33f20179343d8c8&spm_id_from=333.788.videopod.sections
- Androidstudio底部導航欄實現:https://www.bilibili.com/video/BV1XB4y1d7et/?spm_id_from=333.337.search-card.all.click&vd_source=984bb03f768809c7d33f20179343d8c8
- Android使用TabLayout+ViewPager2實現左右滑動切換:https://www.bilibili.com/video/BV1Mz4y1c7eX/?spm_id_from=333.337.search-card.all.click&vd_source=984bb03f768809c7d33f20179343d8c8