当前位置: 首页 > news >正文

基于微信小程序的美食点餐订餐系统

文章目录

    • 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.lryc.cn/news/572711.html

相关文章:

  • OPENGLPG第九版学习 - 纹理与帧缓存 part1
  • .docx 和 .doc 都是 Word 文档格式的区别
  • el-table复杂表头(多级表头行或列的合并)
  • Mac电脑 窗口分屏管理 Magnet Pro
  • 4、做中学 | 二年级下期 Golang整型和浮点型
  • react扩展
  • Excel批量计算时间差
  • 【笔记】解决部署国产AI Agent 开源项目 MiniMax-M1时 Hugging Face 模型下载缓存占满 C 盘问题:更改缓存位置全流程
  • ElSelect 多选远程搜索选项丢失问题
  • 甘肃安全员A证考试备考题库含答案2025年
  • WIFI原因造成ESP8266不断重启的解决办法
  • 【同声传译】RealtimeSTT:超低延迟语音转文字,支持唤醒词与中译英
  • npm 更新包名,本地导入
  • vue2通过leaflet实现图片点位回显功能
  • Fiddler抓包工具使用技巧:如何结合Charles和Wireshark提升开发调试效率
  • OpenCV C++ 边缘检测与图像分割
  • NY339NY341美光固态闪存NW841NW843
  • 【VUE】某时间某空间占用情况效果展示,vue2+element ui实现。场景:会议室占用、教室占用等。
  • PVE使用ubuntu-cloud-24.img创建虚拟机并制作模板
  • NVIDIA开源Fast-dLLM!解析分块KV缓存与置信度感知并行解码技术
  • 旋转图像C++
  • json.Unmarshal精度丢失问题分析
  • vue3组件式开发示例
  • 大模型与搜索引擎的技术博弈及未来智能范式演进
  • MySQL查询语句的通配符*
  • 组态王工程运行时间显示
  • 【案例拆解】米客方德 SD NAND 在车联网中(有方模块)的应用:破解传统 TF 卡振动脱落与寿命短板
  • 在VTK中捕捉体绘制图像进阶(同步操作)
  • 零基础入门PCB设计 一实践项目篇 第三章(STM32开发板原理图设计)
  • 云计算处理器选哪款?性能与能效的平衡艺术