微信小程序-点餐(美食屋)02开发实践

目录

概要

整体架构流程

(一)用户注册与登录

(二)菜品浏览与点餐

(三)订单管理

(四)后台管理

部分代码展示

1.index.wxml

2.list.wxml

3.checkout.wxml

4.detail.wxml

小结优点

概要

        01篇让我们成功搭建开发环境,现在让我们着手开发 “美食屋” 点餐系统了。下面,我会用 PHP 和 MySQL 实现系统核心功能,像用户注册登录、展示和管理菜品,以及处理订单。

        快一起动手,让 “美食屋” 从概念变成现实吧!

整体架构流程

以下是系统从用户操作到数据处理的完整流程:

(一)用户注册与登录

  1. 用户操作

    • 用户在微信小程序中进行wx账号登录。

  2. 前端处理

    • 小程序通过wx.request发送注册或登录请求到后端API接口。

  3. 后端处理

    • 注册接口

      • 检查用户名是否已存在。

      • 将用户信息存入数据库,密码加密存储。

      • 返回注册成功或失败的提示。

    • 登录接口

      • 验证用户名和密码是否正确。

      • 返回登录成功或失败的提示,登录成功时返回用户ID。

  4. 前端响应

    • 根据后端返回的结果,提示用户注册或登录成功/失败。

    • 登录成功后,存储用户ID到本地存储,用于后续操作。

(二)菜品浏览与点餐

  1. 用户操作

    • 用户在小程序中浏览菜品列表,选择菜品加入购物车,提交订单。

  2. 前端处理

    • 调用后端的菜品列表接口获取菜品数据,并展示在小程序页面上。

    • 用户选择菜品后,将菜品信息存储到本地购物车。

    • 用户提交订单时,将购物车中的菜品信息、用户ID等数据通过wx.request发送到后端订单提交接口。

  3. 后端处理

    • 菜品列表接口

      • 查询数据库中的菜品表,返回菜品信息。

    • 订单提交接口

      • 计算订单总价。

      • 将订单信息存入订单表,将订单详情存入订单详情表。

      • 返回订单提交成功或失败的提示。

  4. 前端响应

    • 根据后端返回的结果,提示用户订单提交成功/失败。

    • 订单提交成功后,清空购物车,跳转到订单详情页面。

(三)订单管理

  1. 用户操作

    • 用户在小程序中查看订单列表、订单详情,进行支付、取消订单等操作。

  2. 前端处理

    • 调用后端的订单列表接口获取订单数据,并展示在小程序页面上。

    • 用户操作订单时,通过wx.request调用后端的订单操作接口(如支付、取消订单)。

  3. 后端处理

    • 订单列表接口

      • 查询数据库中的订单表,根据用户ID返回订单列表。

    • 订单操作接口

      • 根据用户操作更新订单状态(如支付成功后将订单状态改为“已支付”)。

  4. 前端响应

    • 根据后端返回的结果,提示用户操作成功/失败。

    • 更新订单列表页面,显示最新的订单状态。

(四)后台管理

  1. 商家操作

    • 商家通过后台管理系统查看订单、处理订单(如确认订单、完成订单)。

  2. 后端处理

    • 提供后台管理接口,供商家管理系统调用。

    • 商家操作订单时,更新数据库中的订单状态。

  3. 前端响应

    • 商家管理系统根据后端返回的结果,提示操作成功/失败。

    • 更新订单列表页面,显示最新的订单状态。

部分代码展示

1.index.wxml

        这段代码主要实现了首页的轮播图展示、开启点餐之旅的按钮、最新消息展示以及底部菜品分类图标展示的功能。

<!--index.wxml-->
<swiper class="swiper" indicator-dots="true" autoplay="true" interval="5000" duration="1000">
  <block wx:for="{
  
  { swiper }}" wx:key="*this">
    <swiper-item>
      <image src="{
  
  { item }}" />
    </swiper-item>
  </block>
</swiper>
<!-- 开启点餐之旅 -->
<view class="menu-bar">
  <view class="menu-block" bindtap="start">
    <view class="menu-start">开启点餐之旅→</view>
  </view>
</view>
<!-- 最新消息展示 -->
<view class="ad-box">
  <image src="{
  
  { ad }}" class="ad-image" />
</view>
<view class="bottom-box">
  <view class="bottom-pic" wx:for="{
  
  { category }}" wx:key="index">
    <image src="{
  
  { item }}" class="bottom-image" />
  </view>
</view>
2.list.wxml

        定义了一个页面,主要用于展示商品列表、购物车功能以及相关的促销信息。页面分为多个部分,包括顶部的折扣信息、商品分类和商品列表区域、购物车界面、满减优惠提示以及底部的操作栏。   

<!--pages/list/list.wxml-->
<view class="discount">
  <text class="discount-txt">减</text>满{
  
  { promotion.k }}元减{
  
  { promotion.v }}元(在线支付专享)
</view>
<view class="content">
  <!-- 左侧菜单栏区域 -->
  <scroll-view class="category" scroll-y>
    <view wx:for="{
  
  { foodList }}" wx:key="id" class="category-item category-{
  
  { activeIndex == index ? 'selected' : 'unselect' }}" data-index="{
  
  { index }}" bindtap="tapCategory">
      <view class="category-name">{
  
  { item.name }}</view>
    </view>
  </scroll-view>
  <!-- 右侧商品列表区域 -->
  <scroll-view class="food" scroll-y scroll-into-view="category_{
  
  { tapIndex }}" scroll-with-animation bindscroll="onFoodScroll">
    <block wx:for="{
  
  { foodList }}" wx:for-item="category" wx:key="id" wx:for-index="category_index">
      <view class="food-category" id="category_{
  
  { category_index }}">{
  
  { category.name }}</view>
      <view class="food-item" wx:for="{
  
  { category.food }}" wx:for-item="food" wx:key="id">
        <view class="food-item-pic">
          <image mode="widthFix" src="{
  
  { food.image_url }}" />
        </view>
        <view class="food-item-info">
          <view>{
  
  { food.name }}</view>
          <view class="food-item-price">{
  
  { priceFormat(food.price) }}</view>
        </view>
        <view class="food-item-opt">
          <i class="iconfont" data-category_index="{
  
  { category_index }}" data-index="{
  
  { index }}" bindtap="addToCart"></i>
        </view>
      </view>
    </block>
  </scroll-view>
</view>
<!-- 购物车界面 -->
<view class="shopcart" wx:if="{
  
  { showCart }}">
  <view class="shopcart-mask" bindtap="showCartList" wx:if="{
  
  { showCart }}"></view>
  <view class="shopcart-wrap">
    <view class="shopcart-head">
      <view class="shopcart-head-title">已选商品</view>
      <view class="shopcart-head-clean" bindtap="cartClear">
        <i class="iconfont"></i>清空购物车
      </view>
    </view>
    <view class="shopcart-list">
      <view class="shopcart-item" wx:for="{
  
  { cartList }}" wx:key="id">
        <view class="shopcart-item-name">{
  
  { item.name }}</view>
        <view class="shopcart-item-price">
          <view>{
  
  { priceFormat(item.price * item.number) }}</view>
        </view>
        <view class="shopcart-item-number">
          <i class="iconfont shopcart-icon-dec" data-id="{
  
  { index }}" bindtap="cartNumberDec"></i>
          <view>{
  
  { item.number }}</view>
          <i class="iconfont shopcart-icon-add" data-id="{
  
  { index }}" bindtap="cartNumberAdd"></i>
        </view>
      </view>
    </view>
  </view>
</view>
<!-- 满减优惠信息 -->
<view class="promotion">
  <label wx:if="{
  
  { promotion.k - cartPrice > 0 }}">满{
  
  { promotion.k }}立减{
  
  { promotion.v }}元,还差{
  
  { promotion.k - cartPrice }}元</label>
  <label wx:else>已满{
  
  { promotion.k }}元可减{
  
  { promotion.v }}元</label>
</view>
<!-- 小球动画 -->
<view class="operate">
  <view class="operate-shopcart-ball" hidden="{
  
  { !cartBall.show }}" style="left: {
  
  { cartBall.x }}px; top: {
  
  { cartBall.y }}px;"></view>
  <view class="operate-shopcart" bindtap="showCartList">
    <i class="iconfont operate-shopcart-icon {
  
  { cartNumber > 0 ? 'operate-shopcart-icon-activity' : '' }}">
      <span wx:if="{
  
  { cartNumber > 0 }}">{
  
  { cartNumber }}</span>
    </i>
    <view class="operate-shopcart-empty" wx:if="{
  
  { cartNumber === 0 }}">购物车是空的</view>
    <view class="operate-shopcart-price" wx:else>
      <block wx:if="{
  
  { cartPrice >= promotion.k }}">
        <view>{
  
  { priceFormat(cartPrice - promotion.v )}}</view>
        <text>{
  
  { priceFormat(cartPrice) }}</text>
      </block>
      <view wx:else>{
  
  { priceFormat(cartPrice) }}</view>
    </view>
  </view>
  <view class="operate-submit {
  
  { cartNumber !== 0 ? 'operate-submit-activity' : '' }}" bindtap="order">选好了</view>
</view>
<wxs module="priceFormat">
  module.exports = function (price) {
    return '¥ ' + parseFloat(price)
  }
</wxs>
3.checkout.wxml

        主要实现了订单确认页面的展示,包含订单信息、备注、支付等功能。

<!--pages/order/checkout/checkout.wxml-->
<view class="content">
  <!-- 标题 -->
  <view class="content-title">请确认您的订单</view>
  <!-- 订单信息-->
  <view class="order">
    <view class="order-title">订单详情</view>
    <view class="order-list">
      <!-- 订单商品列表项 -->
      <view class="order-item" wx:for="{
  
  { order_food }}" wx:key="id">
        <view class="order-item-left">
          <image class="order-item-image" mode="widthFix" src="{
  
  { item.image_url }}" />
          <view>
            <view class="order-item-name">{
  
  { item.name }}</view>
            <view class="order-item-number">x {
  
  { item.number }}</view>
          </view>
        </view>
        <view class="order-item-price">{
  
  { priceFormat(item.price * item.number) }}</view>
      </view>
      <!-- 满减信息 -->
      <view class="order-item" wx:if="{
  
  { checkPromotion(promotion) }}">
        <view class="order-item-left">
          <i class="order-promotion-icon">减</i>满减优惠
        </view>
        <view class="order-promotion-price">- {
  
  { priceFormat(promotion) }}</view>
      </view>
      <!-- 小计 -->
      <view class="order-item">
        <view class="order-item-left">小计</view>
        <view class="order-total-price">{
  
  { priceFormat(price) }}</view>
      </view>
    </view>
  </view>
  <!-- 备注功能 -->
  <view class="content-comment">
    <label>备注</label>
    <textarea placeholder="如有其他要求,请输入备注" bindinput="inputComment"></textarea>
  </view>
</view>
<!-- 支付功能 -->
<view class="operate">
  <view class="operate-info">合计:{
  
  { priceFormat(price) }}</view>
  <view class="operate-submit" bindtap="pay">去支付</view>
</view>
<!-- 处理商品价格格式 -->
<wxs module="priceFormat">
  module.exports = function (price) {
    return price ? '¥ ' + parseFloat(price) : ''
  }
</wxs>
<wxs module="checkPromotion">
  module.exports = function (promotion) {
    return parseFloat(promotion) > 0
  }
</wxs>
4.detail.wxml

        此页面主要分为四个部分:顶部取餐号展示区、订单详情区、订单信息列表区、提示信息区。同时,使用了两个 wxs 模块来处理价格格式化和满减优惠判断。

<!--pages/order/detail/detail.wxml-->
<view class="top">
  <view class="card" wx:if="{
  
  { !is_taken }}">
    <view class="card-title">取餐号</view>
    <view class="card-content">
      <view class="card-info">
        <text class="card-code">{
  
  { code }}</text>
        <text class="card-info-r">正在精心制作中…</text>
      </view>
      <view class="card-comment" wx:if="{
  
  { comment }}">备注:{
  
  { comment }}</view>
      <view class="card-tips">美食制作中,尽快为您服务☺</view>
    </view>
  </view>
</view>
<view class="order">
  <view class="order-title">订单详情</view>
  <view class="order-list">
    <!-- 订单商品列表项 -->
    <view class="order-item" wx:for="{
  
  { order_food }}" wx:key="id">
      <view class="order-item-left">
        <image class="order-item-image" mode="widthFix" src="{
  
  { item.image_url }}" />
        <view>
          <view class="order-item-name">{
  
  { item.name }}</view>
          <view class="order-item-number">x {
  
  { item.number }}</view>
        </view>
      </view>
      <view class="order-item-price">{
  
  { priceFormat(item.price * item.number) }}</view>
    </view>
    <!-- 满减信息 -->
    <view class="order-item" wx:if="{
  
  { checkPromotion(promotion) }}">
      <view class="order-item-left">
        <i class="order-promotion-icon">减</i>满减优惠
      </view>
      <view class="order-promotion-price">- {
  
  { priceFormat(promotion) }}</view>
    </view>
    <!-- 小计 -->
    <view class="order-item">
      <view class="order-item-left">小计</view>
      <view class="order-total-price">{
  
  {priceFormat(price)}}</view>
    </view>
  </view>
</view>
<view class="list">
  <view>
    <text>订单号码</text>
    <view>{
  
  { sn }}</view>
  </view>
  <view>
    <text>下单时间</text>
    <view>{
  
  { create_time }}</view>
  </view>
  <view>
    <text>付款时间</text>
    <view>{
  
  { pay_time }}</view>
  </view>
  <view wx:if="{
  
  { is_taken }}">
    <text>取餐时间</text>
    <view>{
  
  { taken_time }}</view>
  </view>
</view>
<view class="tips" wx:if="{
  
  { is_taken }}">取餐号{
  
  { code }} 您已取餐</view>
<view class="tips" wx:else>请凭此页面至取餐柜台领取美食</view>
<wxs module="priceFormat">
  module.exports = function (price) {
    return price ? '¥ ' + parseFloat(price) : ''
  }
</wxs>
<wxs module="checkPromotion">
  module.exports = function (promotion) {
    return parseFloat(promotion) > 0
  }
</wxs>

小结优点

  1. 前后端分离

    • 前端专注于用户体验,后端专注于数据处理,提高开发效率和系统可维护性。

  2. 数据交互标准化

    • 使用JSON格式进行数据交互,便于前后端解析和处理。

  3. 扩展性强

    • 后端接口可独立扩展,支持多端接入(如小程序、Web端等)。

  4. 安全性高

    • 数据通过HTTPS传输,后端对用户密码加密存储,保障用户信息安全。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/959746.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

计算机工程:解锁未来科技之门!

计算机工程与应用是一个充满无限可能性的领域。随着科技的迅猛发展&#xff0c;计算机技术已经深深渗透到我们生活的方方面面&#xff0c;从医疗、金融到教育&#xff0c;无一不在彰显着计算机工程的巨大魅力和潜力。 在医疗行业&#xff0c;计算机技术的应用尤为突出。比如&a…

OS Copilot功能测评:智能助手的炫彩魔法

简介&#xff1a; OS Copilot 是一款融合了人工智能技术的智能助手&#xff0c;专为Linux系统设计&#xff0c;旨在提升系统管理和运维效率。本文详细介绍了在阿里云ECS实例上安装和体验OS Copilot的过程&#xff0c;重点评测了其三个核心参数&#xff1a;-t&#xff08;模式…

随机变量的变量替换——归一化流和直方图规定化的数学基础

变量替换是一种在统计学和数学中广泛应用的技术&#xff0c;它通过定义新的变量来简化问题&#xff0c;使得原本复杂的随机变量变得更加容易分析。 变量替换的公式&#xff0c;用于将一个随机变量 X X X 的概率密度函数 f X f_X fX​ 转换为其经过函数 g g g 变换后的随机变…

新电脑安装系统找不到硬盘原因和解决方法来了

有不少网友反馈新电脑采用官方u盘方式装win10或win100出现找不到硬盘是怎么回事&#xff1f;后来研究半天发现是bios中开启了rst(vmd)模式。如果关闭rst模式肯定是可以安装的&#xff0c;但这会影响硬盘性能&#xff0c;有没有办法解决开启rst模式的情况安装win10或win11呢&…

Maui学习笔记-SignalR简单介绍

SignalR是ASP.NET Core中的一个库,支持服务器与其连接的客服端之间的双象通信,它允许服务器立即将更新的消息推送到客服端,而不是要求客户端轮询服务器来获取更新 创建项目 使用SignalR在服务器实时发送消息给客服端,客服端拿到消息后在UI页面更新 首先创建一个Web API项目 …

接口(完)

大家好&#xff0c;今天我们着重来总结一下接口的知识&#xff0c;并且将接口和抽象类的区别罗列一下&#xff0c;帮助我们更好的认识抽象类和接口。 2.7 抽象类和接口的区别. 抽类和接口都是Java中多态的常见使用方式,都需要重点掌握,同时又要认清两者的区别(重要!!&#xf…

机器学习-线性回归(参数估计之经验风险最小化)

给定一组包含 &#x1d441; 个训练样本的训练集 我们希望能够 学习一个最优的线性回归的模型参数 &#x1d498; 现在我们来介绍线性回归的一种模型参数估计方法&#xff1a;经验风险最小化。 我们前面说过&#xff0c;对于标签 &#x1d466; 和模型输出都为连续的实数值&…

77,【1】.[CISCN2019 华东南赛区]Web4

有句英文&#xff0c;看看什么意思 好像也可以不看 进入靶场 点击蓝色字体 我勒个豆&#xff0c;百度哇 所以重点应该在url上&#xff0c;属于任意文件读取类型 接下来该判断框架了 常见的web框架如下 一&#xff0c;Python 框架 1.Flask URL 示例 1&#xff1a;http://…

c语言中的数组(上)

数组的概念 数组是⼀组相同类型元素的集合&#xff1b; 数组中存放的是1个或者多个数据&#xff0c;但是数组元素个数不能为0。 数组中存放的多个数据&#xff0c;类型是相同的。 数组分为⼀维数组和多维数组&#xff0c;多维数组⼀般⽐较多⻅的是⼆维数组。 数组创建 在C语言…

景联文科技加入AIIA联盟数据标注分委会

2025年1月16日&#xff0c;中国人工智能产业发展联盟&#xff08;简称AIIA&#xff09;数据委员会数据标注分委会&#xff08;以下简称“分委会”&#xff09;正式成立。景联文科技成为第一批AIIA联盟数据标注分委会委员单位。 数据标注分委会的成立旨在搭建数据标注领域产学研…

[笔记] 极狐GitLab实例 : 手动备份步骤总结

官方备份文档 : 备份和恢复极狐GitLab 一. 要求 为了能够进行备份和恢复&#xff0c;请确保您系统已安装 Rsync。 如果您安装了极狐GitLab&#xff1a; 如果您使用 Omnibus 软件包&#xff0c;则无需额外操作。如果您使用源代码安装&#xff0c;您需要确定是否安装了 rsync。…

消息队列篇--通信协议篇--AMOP(交换机,队列绑定,消息确认,AMOP实现实例,AMOP报文,帧,AMOP消息传递模式等)

AMQP&#xff08;Advanced Message Queuing Protocol&#xff0c;高级消息队列协议&#xff09;是一种开放的、跨平台的消息传递协议&#xff0c;旨在提供一种标准化的方式在不同的消息代理和客户端之间进行消息传递。AMQP不仅定义了消息格式和路由机制&#xff0c;还规定了如何…

小利特惠源码/生活缴费/电话费/油卡燃气/等充值业务类源码附带承兑系统

全新首发小利特惠/生活缴费/电话费/油卡燃气/等充值业务类源码附带U商承兑系统 安装教程如下 图片:

HTML<hgroup>标签

例子&#xff1a; 使用hgroup元素标记标题和段落是相关的&#xff1a; <hgroup> <h2>Norway</h2> <p>The land with the midnight sun.</p> </hgroup> 定义和用法&#xff1a; 标签<hgroup>用于包围标题和一个或多个<p&g…

14-6-3C++STL的list

&#xff08;一&#xff09;list的插入 1.list.insert(pos,elem);//在pos位置插入一个elem元素的拷贝&#xff0c;返回新数据的位置 #include <iostream> #include <list> using namespace std; int main() { list<int> lst; lst.push_back(10); l…

【2024年终总结】深圳工作生活评测

距离上次写年终总结已经过了一年半了&#xff0c;这一年半中哪怕经历了很多的事情&#xff0c;但是感觉又没发生什么。想写一些骚话&#xff0c;却总觉得自己无法完全表达&#xff0c;便也就这样&#xff0c;静静地记录下这一段时光。 现在是2025年&#xff0c;春节前的时光&am…

前端jquery 实现文本框输入出现自动补全提示功能

git仓库&#xff1a;web_study/some-demos/inputAutoFit at main Cong0925/web_study (github.com) 压缩包&#xff1a;已绑定到指定资源 示例图&#xff1a; 实现说明: 1.首先&#xff0c;html部分设置好相关的定位标签如图&#xff1a; 2.主要函数 3.默认数据

(5)STM32 USB设备开发-USB键盘

讲解视频&#xff1a;2、USB键盘-下_哔哩哔哩_bilibili 例程&#xff1a;STM32USBdevice: 基于STM32的USB设备例子程序 - Gitee.com 本篇为使用使用STM32模拟USB键盘的例程&#xff0c;没有知识&#xff0c;全是实操&#xff0c;按照步骤就能获得一个STM32的USB键盘。本例子是…

java后端之登录认证

基础登录功能&#xff1a;根据提供的用户名和密码判断是否存在于数据库 LoginController.java RestController Slf4j public class LoginController {Autowiredprivate UserService userService;PostMapping("/login")public Result login(RequestBody User user) {…

Spring--Bean的生命周期和循环依赖

Bean的生命周期和循环依赖 Bean 的生命周期了解么?Spring中的循环引用什么是循环引用&#xff1f;三级缓存解决循环依赖总结构造方法出现了循环依赖怎么解决&#xff1f; Bean 的生命周期了解么? 整体上可以简单分为四步&#xff1a;实例化 —> 属性赋值 —> 初始化 —…