点餐项目实现(一)

简介: 点餐项目实现(一)

目录

项目简介

功能设计

数据库表设计

用户表

订单表

菜品表

订单详情表(关联菜品表和订单表)

配置类

实体类

Dish

OrderDetail

OrderInfo

UserInfo

统一后端返回内容

用户模块

用户注册功能

mapper接口

xml文件

controller层

前端

用户登录功能

验证用户账号和密码(session存储)

session key值

controller层

mapper层

xml

前端

显示所有用户可以点的菜品列表

显示菜品

controller层

mapper层

xml

前端

统计点的菜品个数以及下单总价

刷新页面维持用户登录状态功能

退出登录功能

前端

controller

用户下单菜品功能

controller层

mapper层

xml

用户查看订单详情功能

前端

controller

mapper接口

xml

商家模块

商家登录功能

前端

controller

mapper

xml

保持登录状态

前端

controller

菜品添加功能

前端

controller

mapper

xml

菜品删除功能

前端

controller

mapper

xml

获取订单列表功能

前端

查看所有订单

修改订单状态

查看某个订单详情

controller

查看所有订单

修改订单状态

查看某个订单详情

mapper

查看所有订单

修改订单状态

查看某个订单详情

xml

查看所有订单

修改订单状态

查看某个订单详情

退出登录功能

前端

controller

项目简介

现如今,随着餐饮行业的不断扩大,消费者的年轻化,餐饮行业的点餐逐渐由线下转为线上点单,因此我们这个点餐系统就应运而生。点餐系统为餐厅增添了用户与餐厅的互动性,还可以实现更加多样化的点餐。


本项目运用spingboot + springmvc + mybatis + vue实现了一个具有商家和普通用户的双角色点餐系统。

功能设计

image.png

数据库表设计

用户表

  • 主键id(自增)
  • 用户名
  • 密码
  • 身份标识
+----------+--------------+------+-----+---------+----------------+
| Field    | Type         | Null | Key | Default | Extra          |
+----------+--------------+------+-----+---------+----------------+
| id       | int(11)      | NO   | PRI | NULL    | auto_increment |
| username | varchar(250) | YES  |     | NULL    |                |
| password | varchar(50)  | YES  |     | NULL    |                |
| isadmin  | int(11)      | YES  |     | NULL    |                |
+----------+--------------+------+-----+---------+----------------+

订单表

  • 订单主键ID(自增)
  • 用户ID
  • 订单创建时间
  • 状态(0:未完成; 1:已完成)
+------------+----------+------+-----+-------------------+----------------+
| Field      | Type     | Null | Key | Default           | Extra          |
+------------+----------+------+-----+-------------------+----------------+
| id         | int(11)  | NO   | PRI | NULL              | auto_increment |
| uid        | int(11)  | YES  |     | NULL              |                |
| createtime | datetime | YES  |     | CURRENT_TIMESTAMP |                |
| status     | int(11)  | YES  |     | NULL              |                |
+------------+----------+------+-----+-------------------+----------------+

菜品表

  • 主键ID(自增)
  • 菜品名
  • 价格
+-------+---------------+------+-----+---------+----------------+
| Field | Type          | Null | Key | Default | Extra          |
+-------+---------------+------+-----+---------+----------------+
| id    | int(11)       | NO   | PRI | NULL    | auto_increment |
| name  | varchar(250)  | NO   |     | NULL    |                |
| price | decimal(10,0) | NO   |     | NULL    |                |
+-------+---------------+------+-----+---------+----------------+

订单详情表(关联菜品表和订单表)

  • 订单id
  • 菜品id
+-------+---------+------+-----+---------+-------+
| Field | Type    | Null | Key | Default | Extra |
+-------+---------+------+-----+---------+-------+
| did   | int(11) | NO   |     | NULL    |       |
| oid   | int(11) | NO   |     | NULL    |       |
+-------+---------+------+-----+---------+-------+

这个表是为了处理订单表和菜品表的多对多关系,也就是中间表

配置类

package com.example.ordersys.config;
/**
 * @author SongBiao
 * @Date 2021/1/18
 */
//此类专门存储session中的key值
public class AppFinal {
    //将session中的key值提取出来,单独放到一个类里面去
    //用户的session key
    public static final String USERINFO_SESSION_KEY = "USERINFO_SESSION_KEY";
}

此类用于统一session存储过程中的key值

实体类

Dish

package com.example.ordersys.model;
import lombok.Data;
import java.math.BigDecimal;
/**
 * @author SongBiao
 * @Date 2021/1/18
 */
@Data
public class Dish {
    private int id;
    private String name;
    private BigDecimal price;
}

OrderDetail

package com.example.ordersys.model;
import lombok.Data;
/**
 * @author SongBiao
 * @Date 2021/1/18
 */
@Data
public class OrderDetail {
    private int oid;
    private int did;
    private Dish dish;
}

OrderInfo

package com.example.ordersys.model;
import lombok.Data;
import java.util.Date;
/**
 * @author SongBiao
 * @Date 2021/1/18
 */
@Data
public class OrderInfo {
    private int id;
    private int uid;
    private Date createtime;
    private int status;
    private String uname;
}

UserInfo

package com.example.ordersys.model;
import lombok.Data;
/**
 * @author SongBiao
 * @Date 2021/1/18
 */
@Data
public class UserInfo {
    private int id;
    private String username;
    private String password;
    private int isadmin;
}

统一后端返回内容

package com.example.ordersys.tools;
import lombok.Data;
/**
 * @author SongBiao
 * 此类用于规范controller类返回的数据类型的统一,我们定义如下类
 * @Date 2021/1/18
 */
@Data
public class ResponseBody<T> {
    //后端返回给前端的状态
    private int status;
    //定义参数的描述信息
    private String msg;
    //后端返回给前端的数据
    private T data;
    public ResponseBody(int status,
                        String msg,
                        T data){
        this.status = status;
        this.msg = msg;
        this.data = data;
    }
}

用户模块

用户注册功能

mapper接口

 //注册方法
    public int register(UserInfo userInfo);

xml文件

 <insert id="register">
      insert into userinfo(username,password,isadmin)
      values(#{username},#{password},0)
    </insert>

controller层

 /**
     * 用户注册功能,这里指的是顾客
     */
    @RequestMapping("/reg")
    public ResponseBody<Integer> register(UserInfo userInfo) {
        int data = userMapper.register(userInfo);
        return new ResponseBody<>(0, "", data);
    }

前端

<!-- 注册窗口 -->
            <v-row justify="center">
                <v-dialog v-model="reg.showRegister" persistent max-width="400px">
                    <v-card>
                        <v-card-title>
                            <span class="headline">注册</span>
                        </v-card-title>
                        <v-card-text>
                            <v-container>
                                <v-row>
                                    <v-col cols="12" sm="12">
                                        <v-text-field label="用户名*" v-model="reg.name" required></v-text-field>
                                    </v-col>
                                </v-row>
                                <v-row>
                                    <v-col cols="12" sm="12">
                                        <v-text-field label="密码*" v-model="reg.password" required></v-text-field>
                                    </v-col>
                                </v-row>
                                <v-row>
                                    <v-col cols="12" sm="12">
                                        <v-text-field label="确认密码*" v-model="reg.password2" required></v-text-field>
                                    </v-col>
                                </v-row>
                                <v-row>
                                    <v-col cols="12" sm="6">
                                        <v-btn color="primary" block v-on:click="doRegister">注册</v-btn>
                                    </v-col>
                                    <v-col cols="12" sm="6">
                                        <v-btn color="primary" block v-on:click="reg.showRegister = false">取消
                                        </v-btn>
                                    </v-col>
                                </v-row>
                            </v-container>
                        </v-card-text>
                    </v-card>
                </v-dialog>
            </v-row>
// 注册方法
            doRegister() {
                //获取用户输入的值,通过v-model来确定如何获取值
                let username = app.reg.name;
                let password = app.reg.password;
                let password2 = app.reg.password2;
                //非空校验
                if (username == "") {
                    alert("请先输入用户名");
                    return false;
                }
                if (password == "") {
                    alert("请先输入密码");
                    return false;
                }
                if (password2 == "") {
                    alert("请先输入确认密码");
                    return false;
                }
                if (password != password2) {
                    alert("两次输入的密码不一致,请核对");
                    return false;
                }
                //请求后端接口实现注册功能
                jQuery.getJSON("/user/reg", {
                    "username": username,
                    "password": password
                }, function (result) {
                    if (result != null && result.data != null && result.data > 0) {
                        alert("恭喜添加成功");
                        //每次一个用户注册信息后将信息置空
                        app.reg.name = "";
                        app.reg.password = "";
                        app.reg.password2 = "";
                        //隐藏注册窗体
                        app.reg.showRegister = false;
                    } else {
                        alert("抱歉,添加失败,请重试");
                    }
                });
            },

用户登录功能

(1)验证用户的账号和密码

(2)存储session信息

(3)显示欢迎信息

image.png

(4)显示所有用户可以点的菜品列表

image.png

(5)刷新页面维持页面登录状态

(6)退出登录

验证用户账号和密码(session存储)

session key值

package com.example.ordersys.config;
/**
 * @author SongBiao
 * @Date 2021/1/18
 */
//此类专门存储session中的key值
public class AppFinal {
    //将session中的key值提取出来,单独放到一个类里面去
    //用户的session key
    public static final String USERINFO_SESSION_KEY = "USERINFO_SESSION_KEY";
}

controller层

//登录功能
    @RequestMapping("/login")
    public ResponseBody<UserInfo> login(UserInfo userInfo, HttpServletRequest request) {
        UserInfo user = userMapper.login(userInfo);
        //登录后将信息存入session当中
        if (user != null && user.getId() > 0) {
            HttpSession session = request.getSession();
            session.setAttribute(AppFinal.USERINFO_SESSION_KEY,
                    user);
        }
        return new ResponseBody<>(0, "", user);
    }

mapper层

//登录方法
    public UserInfo login(UserInfo userInfo);

xml

<select id="login" resultType="com.example.ordersys.model.UserInfo">
    select * from userinfo where
    username=#{username} and password=#{password}
</select>

前端

// 登录方法
doLogin() {
    //获取用户输入的用户名和密码,还是看v-model
    let username = app.login.inputUsername;
    let password = app.login.inputPassword;
    //非空校验
    if (username == "") {
        alert("请输入用户名");
        return false;
    }
    if (password == "") {
        alert("请输入密码");
        return false;
    }
    //访问后端接口,验证用户信息
    jQuery.getJSON("/user/login", {
        "username": username,
        "password": password
    }, function (result) {
        if (result != null && result.data != null && result.data.id > 0) {
            //登录成功
            alert("登录成功!");
            //登录成功后,隐藏左侧未登录之前的导航,并显示欢迎信息
            //因为两者的v-show是一样的
            app.login.isLogin = true;
            //去掉登录时的窗口,还是查看v-model
            app.login.showLoginDialog = false;
            //请求后端得到菜品列表
            jQuery.getJSON("/dish/list", {}, function (result) {
                if (result != null && result.data != null) {
                    app.dishes = result.data;
                }
            });
        } else {
            //用户名或密码错误,请重新输入
            alert("用户名或密码错误,请重新输入");
        }
    });
},

显示所有用户可以点的菜品列表

显示菜品

controller层
@RequestMapping("/list")
public ResponseBody<List<Dish>> getList() {
    List<Dish> data = dishMapper.getDishList();
    return new ResponseBody<>(0, "", data);
}
mapper层
//查询菜单列表
public List<Dish> getDishList();
xml
<select id="getDishList" resultType="com.example.ordersys.model.Dish">
   select * from dish
</select>
前端
<v-simple-table v-show="status == 'dishesPage' && login.isLogin">
    <template v-slot:default>
        <thead>
        <tr>
            <th class="text-left">菜名</th>
            <th class="text-left">价格</th>
            <th class="text-left">选择</th>
        </tr>
        </thead>
        <tbody>
        <tr v-for="dish in dishes">
            <td>
                <v-icon>mdi-food</v-icon>
                {{dish.name}}
            </td>
            <td>
                <v-icon>mdi-cash</v-icon>
                {{dish.price}}
            </td>
            <!--   选择窗体-->
            <td>
                <v-switch v-model="dish.isSelected"></v-switch>
            </td>
        </tr>
        </tbody>
    </template>
</v-simple-table>
jQuery.getJSON("/dish/list", {}, function (result) {
                if (result != null && result.data != null) {
                    app.dishes = result.data;
                }
            });

统计点的菜品个数以及下单总价

<v-row v-show="status == 'dishesPage' && login.isLogin">
    <v-col :col="11">
        <div class="pa-2">已点 {{selectedDishCount}} 道菜, 总计 {{selectedDishPrice}} 元</div>
    </v-col>
</v-row>
computed: {
    // 点餐的个数
    selectedDishCount() {
        let count = 0;
        this.dishes.forEach(dish => {
            if (dish.isSelected) {
                count++;
            }
        });
        return count;
    },
    // 计算下单的菜品总价
    selectedDishPrice() {
        let price = 0;
        this.dishes.forEach(dish => {
            if (dish.isSelected) {
                price += dish.price;
            }
        })
        return price;
    }
},


相关文章
|
5月前
|
小程序 安全
【实训项目】“优品果园”-线上水果商城小程序
【实训项目】“优品果园”-线上水果商城小程序
|
7月前
|
Python
项目商场储物柜
用python语言编写项目商场储物柜。
53 0
|
SQL 安全 JavaScript
基于JavaWeb的电影院在线选座订票管理系统
基于JavaWeb的电影院在线选座订票管理系统
548 0
基于JavaWeb的电影院在线选座订票管理系统
|
11天前
|
SQL Java Go
java项目超市购物管理系统
java项目超市购物管理系统
|
1月前
|
小程序 算法 数据可视化
点餐小程序实战教程07-点餐功能开发
点餐小程序实战教程07-点餐功能开发
|
8月前
|
小程序
【带源码】基于微信小程序的旅游订票旅游预订小程序酒店预订项目
重要的事情说三遍,可白嫖,可白嫖,可白嫖!!! 源码下载链接:docs.qq.com/doc/DYm5DSlBWZEplalBP 随着移动互联网的迅速发展,人们对于旅游信息获取和旅行订票的需求也逐渐增加。传统的旅游指南和订票方式往往不够便捷和灵活,而微信作为一种广泛使用的社交媒体平台,拥有巨大的用户群体和强大的社交属性,成为了传递信息和服务的重要渠道。
拍卖软件开发方式,直播竞拍商城定制开发成品源码选择
为了开发一个成功的拍卖软件平台,选择适合的开发方式至关重要。在定制开发和购买“东莞梦幻网络科技”拍卖直播成品源码之间做出选择时,需要考虑以下多个关键因素,以确保最终的选择符合您的自身需求和目标。
|
9月前
|
存储 JavaScript 前端开发
基于SpringBoot和微信小程序的餐馆点餐系统的设计和实现(一)
基于SpringBoot和微信小程序的餐馆点餐系统的设计和实现
296 0
|
9月前
|
小程序 前端开发 安全
基于SpringBoot和微信小程序的餐馆点餐系统的设计和实现(二)
基于SpringBoot和微信小程序的餐馆点餐系统的设计和实现
265 0
|
XML 前端开发 数据格式
点餐项目实现(三)
点餐项目实现(三)
174 0