基于微信小程序的美食點餐訂餐系統

文章目錄

    • 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. 注意事項

  1. 存儲限制:wx.setStorageSync有10MB大小限制
  2. 多設備同步:本地存儲無法實現多設備同步
  3. 數據持久性:用戶清理緩存會丟失所有數據

這個純前端實現方案適合作為學習項目或個人小店使用,如果要開發商業應用,建議還是使用后端數據庫存儲數據。

6. 項目效果截圖

在這里插入圖片描述
在這里插入圖片描述
在這里插入圖片描述

7. 關于作者其它項目視頻教程介紹

本人在b站錄制的一些視頻教程項目,免費供大家學習

  1. Android新聞資訊app實戰:https://www.bilibili.com/video/BV1CA1vYoEad/?vd_source=984bb03f768809c7d33f20179343d8c8
  2. Androidstudio開發購物商城實戰:https://www.bilibili.com/video/BV1PjHfeXE8U/?vd_source=984bb03f768809c7d33f20179343d8c8
  3. Android開發備忘錄記事本實戰:https://www.bilibili.com/video/BV1FJ4m1u76G?vd_source=984bb03f768809c7d33f20179343d8c8&spm_id_from=333.788.videopod.sections
  4. Androidstudio底部導航欄實現:https://www.bilibili.com/video/BV1XB4y1d7et/?spm_id_from=333.337.search-card.all.click&vd_source=984bb03f768809c7d33f20179343d8c8
  5. Android使用TabLayout+ViewPager2實現左右滑動切換:https://www.bilibili.com/video/BV1Mz4y1c7eX/?spm_id_from=333.337.search-card.all.click&vd_source=984bb03f768809c7d33f20179343d8c8

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/84676.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/84676.shtml
英文地址,請注明出處:http://en.pswp.cn/web/84676.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

[neo4j]介紹4個開源的知識圖譜項目

項目主要介紹幾個開源項目: QASystemOnMedicalKG:醫療知識圖譜問答 https://github.com/liuhuanyong/QASystemOnMedicalKG Agriculture_KnowledgeGraph:農業知識圖譜 Financial-Knowledge-Graphs:小型金融知識圖譜 stock-know…

20倍光學鏡頭怎么實現20+20倍數實現

1. 硬件選擇 球機攝像頭 選擇40倍光學變焦的攝像頭 :確保攝像頭具有足夠的變焦能力,同時考慮攝像頭的分辨率、幀率、夜視功能等。 內置云臺 :許多高端攝像頭已經內置了云臺功能,如果是這樣,可以簡化機械設計和電機控制…

Axios 在 Vue3 項目中的使用:從安裝到組件中的使用

🤍 前端開發工程師、技術日更博主、已過CET6 🍨 阿珊和她的貓_CSDN博客專家、23年度博客之星前端領域TOP1 🕠 牛客高級專題作者、打造專欄《前端面試必備》 、《2024面試高頻手撕題》、《前端求職突破計劃》 🍚 藍橋云課簽約作者、…

【Python打卡Day50】預訓練模型與CBAM注意力@浙大疏錦行

現在我們思考下,是否可以對于預訓練模型增加模塊來優化其效果,這里我們會遇到一個問題: 預訓練模型的結構和權重是固定的,如果修改其中的模型結構,是否會大幅影響其性能。其次是訓練的時候如何訓練才可以更好的避免破壞原有的特征…

ONLYOFFICE Jira 集成應用程序 4.0.0 發布,含新的文件格式支持等多個重大更新!

ONLYOFFICE 與 Jira 集成的重大更新現已發布!使用 ONLYOFFICE Docs 在 Jira Software 中處理各種辦公文檔,從 4.0.0 版本開始,ONLYOFFICE 連接器允許您編輯 PDF 文件和表單、直接從編輯器創建新文件、可視化用戶頭像、在 Jira 平臺內處理新文…

安裝區塊鏈相關Geth(基于CentOS7)

注:由于版本沖突問題,請嚴格按如下介紹版本進行安裝 安裝所需資料:通過網盤分享的文件:區塊鏈_CSDN 鏈接: https://pan.baidu.com/s/1dn5xcLtwwFy90xhOWKiWyA?pwdzgzs 提取碼: zgzs --來自百度網盤超級會員v6的分享 一、安裝運…

系統分析師——計算機系統基礎

系統分析師——計算機系統基礎 引言 作為系統分析師學習的第一節課,計算機系統基礎部分構建了整個知識體系的核心框架。本文將圍繞計算機系統的層次結構、硬件組成、軟件分類以及關鍵技術點進行詳細總結,為后續深入學習奠定基礎。 本節學習內容如下圖&…

JS常用設計模式匯總

1、基于類的單例模式 // PageManager.js class PageManager {constructor(config) {if (!PageManager.instance) {this.config config;this.initialized false;PageManager.instance this;this.init();}return PageManager.instance;}init() {if (this.initialized) return…

邁向軟件開發 T 型人才之路:構建多元能力體系

在軟件開發的廣袤天地里,T 型人才備受矚目。這類人才猶如具備強大能量的 “多面手”,既有深入專精的技術能力,又有廣泛多元的知識與技能儲備,能夠從容應對復雜多變的項目需求,引領行業創新發展。于當今社會而言&#x…

SALMONN-omni論文閱讀

論文鏈接 項目鏈接 名詞理解: backchanneling: 指的是聽話人在不打斷說話人的情況下,用簡短的語氣詞或動作表示“我在聽”“我理解了”的反饋。 常見示例包括: “嗯哼”(“uh-huh”) “對的”&#xff08…

區塊鏈:什么是DeFi?

DeFi(去中心化金融,Decentralized Finance) 是一種基于區塊鏈技術的金融生態系統,旨在通過去中心化的方式提供傳統金融服務(如借貸、交易、儲蓄等),無需依賴銀行、經紀商等中介機構。DeFi主要構…

idea編譯器使用git拉取、提交非常慢的原因和解決方案

前言 最近在公司換了一個電腦,但是發現這個電腦用idea編譯器使用git拉取、提交各種操作非常慢,有時候需要等10分鐘左右,這明顯是不對勁的,說明電腦的某些環境影響到git和idea之間的整合了。 目錄 在idea拉取代碼非常慢的原因 解決方案 在idea拉取代碼非常慢的原因 經過排查…

C語言變量的奇妙世界:探秘作用域

資料合集下載鏈接: ??https://pan.quark.cn/s/472bbdfcd014?? 在C語言的編程世界里,變量是我們存儲和操作數據的基礎。然而,僅僅知道如何定義和使用變量是遠遠不夠的。一個更深層次的理解,在于掌握變量的“作用域”——也就是變量在程序中可以被訪問和使用的范圍。這就…

恒流源和直流穩壓電源 電路

目錄 前言一、恒流源電路1.低端反饋2.低端反饋注意事項注意1:電阻Rx注意2:三極管和運放的限制 3.高端反饋注意:自激振蕩方案二 二、直流穩壓電源電流1.帶反饋2.不帶反饋3.區別 前言 基礎知識可以看個人筆記:個人筆記 一、恒流源…

那些年,曾經輝煌過的數據庫

滾滾長江東逝水,浪花淘盡英雄! 數據庫的演進史,正是這樣一部“英雄迭代”的壯闊史詩。從早期數據模型的拓荒者,到關系型數據庫的商業巨頭;從桌面應用的普及者,再到開源與大數據時代的弄潮兒;每…

2D曲線點云平滑去噪

2D曲線點云,含許多噪聲,采用類似移動最小二乘的方法(MLS)分段擬合拋物線并投影至拋物線,進行點云平滑去噪。 更通俗的說法是讓有一定寬度的曲線點云,變成一條細曲線上的點。 分兩種情況進行討論: 1&#…

【平面波導外腔激光器專題系列】用于精密測量的平面波導外腔激光器特性

----翻譯自Kenji Numata等人的文章 摘要 1542 nm平面波導外腔激光器PW-ECL具有足夠低的噪聲非常適合精密測量應用。與 0.1mHz至100kHz 之間,其頻率和強度噪聲與非平面環形振蕩器 NPRO和光纖激光器相當或更好。通過將 PW-ECL 的頻率穩定在乙炔(13C2H2&a…

文件時間修改器

文件時間修改器是一款幫助用戶修改文件創建時間的軟件,支持毫秒級時間的修改,包括文件的創建時間、修改時間、訪問時間等時間都支持修改,可以批量處理文件。 飛貓云下載 | 備用下載1 |備用下載2 基本簡介 本軟件主要為批量修改文件的創建時…

倉頡語言實戰:MQTT物聯網開發

目錄 引言 mqtt4cj庫的使用 申請倉頡編程語言內測 下載STDX 測試程序 結束語 引言 最近一直在學習倉頡語言,由于我對物聯網比較感興趣,自然想到寫一個MQTT的程序,好在找到了mqtt4cj庫,今天分享一下學習心得。 mqtt4cj庫的…

OpenCV CUDA模塊設備層-----用于在 CUDA 核函數中訪問紋理數據的一個封裝類TexturePtr()

操作系統&#xff1a;ubuntu22.04 OpenCV版本&#xff1a;OpenCV4.9 IDE:Visual Studio Code 編程語言&#xff1a;C11 算法描述 TexturePtr<T, R> 是 OpenCV 的 opencv_cudev 模塊中用于在 CUDA 核函數中訪問紋理數據的一個封裝類。它主要用于將一個已創建好的 cudaTe…