project_02_基于SpringBoot的校园外卖系统


本文介绍基于SpringBoot的校园外卖系统。

1. 概述

本项目主要服务于校园外卖,商家只有校园餐厅一家店,相当于某家餐厅专属的服务。由于服务人员主要是学生和后台管理人员,所以前端分为移动端(学生手机)和后台端(餐厅管理员)。

  1. 学生可在线浏览菜品、添加购物车、下单等等。
  2. 管理员可对餐厅的菜品、套餐、订单等进行维护管理。

可了解一下Axure RP原型创建工具。

1.1 软件环境

这里额外介绍一下,软件环境,主要有三种:

  1. 开发环境:开发人员在开发阶段使用的环境,一般外部用户无法访问。
  2. 测试环境:专门给测试人员使用的环境,用于测试项目,一般外部用户无法访问。
  3. 生产环境:即线上环境,正式提供对外服务的环境。

1.2 技术栈

image-20220714200327885

1.3 功能架构

image-20220714200717217

1.4 角色

  1. 后台系统管理员:登录后台管理系统,拥有后台系统中的所有操作权限
  2. 后台系统普通员工:登录有台管理系统,对菜品、套餐、订单等进行管理
  3. 客户端用户:登录移动端应用,可以浏览菜品、添加购物车、设置地址、在线下单等

2. 开发环境搭建

2.1 数据库环境搭建

从上面的需求中,可隐约看出需要的数据表有:员工表、用户表、地址表、菜品表、口味表、套餐表、订单表等。具体来说,有如下所示:

序号 表名 说明
1 employee 员工表
2 category 菜品和套餐分类表【如荤菜、素菜等等】
3 dish 菜品表
4 setmeal 套餐表
5 setmeal_dish 套餐菜品关系表
6 dish_flavor 菜品口味关系表【甜度、辣度等等】
7 user 用户表(C端)
8 address_book 地址簿表
9 shopping_cart 购物车表
10 orders 订单表
11 order_detail 订单明细表

image-20220716104623993

2.2 maven项目搭建

搭建maven项目,加入SpringBoot的相关起步依赖。依赖主要有Springboot相关的起步依赖、测试依赖、web依赖,数据库相关的mysql依赖、MyBatis依赖、druid依赖,还有一些额外的工具类依赖:lombok、fastjson、commons-lang依赖等。

还要注意,resources资源

依赖如下所示pom.xml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
<?xml version="1.0" encoding="UTF-8"?>

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>

<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.6.8</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>

<groupId>org.hianain.campustakeout</groupId>
<artifactId>CampusTakeout</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>war</packaging>

<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
</properties>

<dependencies>

<!-- Springboot起步依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>

<!-- 基于SpringBoot的test依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>

<!-- 基于SpringBoot的web的起步依赖,没有版本,表明采用父项目中规定的版本 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>

<!-- mybatis的起步依赖 -->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.2.2</version>
</dependency>

<!-- mysql的驱动 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>

<!-- druid依赖 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.1.23</version>
</dependency>

<!-- lombok依赖,用于自动构建实体类对象中的方法,get、set、toString -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.20</version>
</dependency>

<!-- fastjson依赖,用于将Java对象序列化为json字符串 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.76</version>
</dependency>

<!-- commons-lang依赖,和Java.lang包类似,提供一些常用的工具类 -->
<dependency>
<groupId>commons-lang</groupId>
<artifactId>commons-lang</artifactId>
<version>2.6</version>
</dependency>

<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
</dependencies>


<build>
</resources>
<resource>
<!-- 告诉指定的目录 -->
<directory>src/main/java</directory>

<!-- 拷贝的资源文件类型 -->
<includes>
<include>**/*.properties</include>
<include>**/*.xml</include>
</includes>
<!-- 设置过滤器,这里不用设置了,上面相当于设置了 -->
<filtering>false</filtering>
</resource>

<!-- 避免上述操作覆盖默认设置,这里将默认设置的目录添加 -->
<resource>
<!-- 告诉指定的目录 -->
<directory>src/main/resources</directory>

<!-- 拷贝的资源文件类型 -->
<includes>
<include>**/*.*</include>
</includes>
<!-- 设置过滤器,这里不用设置了,上面相当于设置了 -->
<filtering>false</filtering>
</resource>
</resources>

<plugins>
<!-- SpringBoot项目用到的maven插件 -->
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>

之后,配置SpringBoot配置文件application.yml,设置端口号等初始化信息:

1
2
3
4
5
6
7
8
9
server:
port: 8080
servlet:
context-path: /campusTakeout

spring:
application:
# 设置项目名称,可选
name: campus_takeout

将一些前端静态资源放到resources/static目录下,这样静态资源可直接通过路径访问【SpringBoot默认该文件下的资源可通过路径访问】。设置启动类,测试项目正常运行:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// Slf4j是lombok提供的日志注解
@Slf4j
@SpringBootApplication
public class Application {

public static void main(String[] args) {

SpringApplication.run(Application.class, args);

// log是Slf4j中的日志变量
log.info("项目启动成功");

// System.out.println("项目启动成功");
}
}

整体项目结构如下所示:

image-20220716151957044

3. 功能开发

这里有一个注意点:

  1. 本项目的id采用的是bigint,而前端JS支持的最长位数【注意,其实前端可以接收到,但是在显示的时候会损失精度,最终需要将id传给后端的时候,只能是损失精度后的值】,只能支持16位。因此,要么直接在数据库字段中id为字符串,要么就是在Java对象转换为json对象时进行格式转换为String。

    由于数据库字段为id,所以这里引入消息转换器JacksonObjectMapper【基于jackson】,将Java对象转换为JSON对象时进行设置数据格式转换。

3.1 员工模块

3.1.1 员工登录功能

注意,员工的密码在数据库中是采用MD5加密的。

登录功能处理逻辑如下所示:

  1. 将页面提交的密码password进行md5加密处理
  2. 根据页面提交的用户名username查询数据库
  3. 如果没有查询到则返回登录失败结果
  4. 查询到之后进行密码比对,如果不一致则返回登录失败结果
  5. 查询员工状态,如果为已禁用状态,则返回员工已禁用
  6. 登良成功,将员工id存入Session并返回登录成功结果

image-20220716165339648

注意,不要忘记设置拦截器,进行登录验证。

3.1.2 新增员工

3.1.3 分页查询

注意,分页查询,需要显示总条数,即需要查询两次数据库,一次是依据条件查询总条数,一次是依据条件以及分页查询指定页码上的数据。

3.1.4 启用禁用用户

注意,只有admin用户可对普通用户进行启动、禁用操作。【前端直接判断账号,来确定是否显示按钮即可】

其实前面的新增按钮和后面的修改按钮,也应该只能admin用户进行操作。

3.1.5 修改员工信息

3.2 分类模块

这里的分类有两类:

  1. 菜品分类:指的是菜品的种类,比如热菜、荤菜、湘菜等菜的种类。
  2. 套餐分类:指的是套餐的种类,如超值午餐、极品晚餐等。

这里的分类其实就是相当于一个选择,类似于下拉框,方便后续新增菜的时候,选择对应的菜品分类。之后,用户进行选择的时候,可根据这些种类,进行筛选。

3.2.1 新增分类

3.2.2 删除分类

注意,在删除分类的时候,一定要保证该菜品、套餐分类下,没有菜、套餐了。否则就不能删除。

3.3 菜品模块

3.3.1 新增菜品

注意,需要上传图片【上传文件,后台员工新增菜品需要上传实物图】、下载图片【下载文件,用户登录外卖系统,实物图片需要从服务端传输到浏览器端,直接显示,不是以附件形式下载】等。

注意,在新增菜品上传图片,其实图片会保存到服务器本地,而数据库中存储的图片字段则是图片在服务器本地的地址。注意,新增菜品,需要选择菜品分类。还要选择菜品口味。此时需要分类表【字段为菜品的分类,即1】、菜品口味表。注意,菜品口味是前端以字符串形式展示。

点击保存,除了保存菜品表之外,还需要需要将菜品口味一起存入菜品口味表,这一步是为了后续用户下单的时候,选择口味。

这里因为前端传过来两张表的数据,因为单凭一个表的实体类是无法接收参数的,可新建一个实体类,继承两张表的实体类,这种在层和层之间传递数据的对象称为DTO(Data Transfer Object),即数据传输对象。

注意,因为这里是操作多张表,所以需要添加事务注解。

还要注意一定,事务已经捕获异常了,此时应该根据异常来产生失败的响应。

3.3.2 菜品分页查询

分页查询展示的效果,除了菜品记录之外,还需要有图片、菜品种类。所以除了查询该菜品表之外,还需要图片文件传输以及菜品表查询。

3.3.3 修改菜品

注意,先查询数据库回显指定菜品的信息。菜品页面除了包含菜品信息外,还包含了菜品口味。所以依然涉及到两张表。

3.4 套餐

套餐其实就是各个菜品的组合。

3.4.1 新增套餐

注意,套餐包括了套餐名、套餐价格、套餐类别等基础字段,还包含具体的菜品、以及份数等其他字段。因此前面的基础字段可形成套餐表,后面的其他字段可结合套餐表的id形成一个联合表,即套餐-菜品表。这样就是一对多的关系。

3.4.2 套餐分页查询

3.4.3 删除套餐

注意,只能删除停售的套餐。【这里的删除指的是逻辑删除,即is_deleted】。而且还有批量删除和单个删除。此时,可统一传参,如果是批量删除,那么就以逗号形式拼接字符串传入后台,后台则切割字符串获取要删除的列表即可。

另外,因为在新增套餐时,将套餐中的菜品放到了套餐菜品关联表中了,所以将套餐菜品关联表中套餐id为本套餐的记录删除掉。

3.5 用户短信验证码登录

目前市面上有很多第三方提供的短信服务,这些第三方短信服务会和各个运营商(移动、联通、电信)对接,我们只需要注册成为会员并且按照提供的开发文档进行调用就可以发送短信。需要说明的是,这些短信服务一般都是收费服务。

常用的短信服务有:阿里云、华为云、腾讯云、京东、梦网、乐信等。

阿里云短信服务(Short Meaasge Service,SMS)是广大企业客户快速触达手机用户所优先使用的通信能力。调用API或用群发助手,即可发送验证码、通知类和营销类短信;国内验证短信秒级触达,到达率最高可达99%;国际/港澳台短信覆盖200多个国家和地区,安全稳定,广受出海企业选用。

应用场景:

  1. 验证码
  2. 短信通知
  3. 推广短信

可在对应的阿里云官网以及其他云官网搜索“短信服务”。

采用手机验证码登录:

  1. 方便快捷,无需注册,直接登录
  2. 无需记忆密码
  3. 安全

登录流程:输入手机号——>获取验证码【后台短信服务】——>输入验证码——>点击登录——>登录成功。注意,通过手机验证码登录,手机号是区分不同用户的标识。

这时候,在登录的时候就会完成注册。首先判断要登录的用户是否在user表中【如果在,则说明已经注册过了】,如果不在,则将其存入到user表中,即进行注册。

3.6 用户端菜品展示

读取菜品、套餐表并展示。除了上述出售的物品,还要展示用户的购物车信息。

3.7 添加菜品/套餐到购物车

这里,是将一个菜品/一个套餐作为一条记录插入到购物车表中。其实就是一件商品作为一条记录,该记录中包含了商品的可选属性,比如口味,数量,金额等等。所以,添加菜品或套餐调用的后台API是相同的。

3.8 用户地址

增删改查、设置默认地址【注意,默认地址只能有一个,所以在设置默认地址时,要将该用户的所有地址都设置非默认的,然后再将本地址设置为默认的status=1】。

3.9 用户下单

3.10 查询订单

4. 总结

4.x 待解决

  1. session和token,将登录id存入token,保存登录状态。token存入redis?
  2. MD5加密不安全,了解一下SpringSecurity和Shiro框架

5. 备注


文章作者: 浮云
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 浮云 !
  目录