文章目录

  • 软件开发整体介绍
    • 软件开发流程
    • 角色分工
    • 软件环境
  • 瑞吉外卖项目介绍
    • 项目介绍
    • 产品原型
    • 技术选型
    • 功能架构
    • 角色
  • 开发环境搭建
    • 数据库环境搭建
      • 创建数据库
      • 数据库表导入
      • 数据库表介绍
    • Maven项目搭建
      • 创建maven项目
      • 搭建基础环境
      • 前端静态资源导入
  • 后台系统登录功能
    • 需求分析
    • 代码开发
      • 基础准备工作
      • 登录逻辑分析
      • 代码实现
    • 功能测试
  • 后台系统退出功能
    • 需求分析
    • 代码实现
    • 功能测试
  • 思维导图总结

全文主体框架来源于黑马瑞吉外卖的项目资料,我在文中会嵌入如下五个方面的个人内容:

  • 项目中易发生错误的地方
  • 项目中涉及的一些难理解知识点
  • 一些遗忘知识点的回顾
  • 业务的多种实现方法
  • 我在做项目时的思考和一些踩坑

软件开发整体介绍

作为一名软件开发工程师,我们需要了解在软件开发过程中的开发流程, 以及软件开发过程中涉及到的岗位角色,角色的分工、职责, 并了解软件开发中涉及到的三种软件环境。那么这一小节,我们将从以下三个方面,来整体上介绍一下软件开发。

  • 软件开发流程
  • 角色分工
  • 软件环境

软件开发流程

1). 第1阶段: 需求分析

完成产品原型、需求规格说明书的编写。

产品原型,一般是通过网页(html)的形式展示当前的页面展示什么样的数据, 页面的布局是什么样子的,点击某个菜单,打开什么页面,点击某个按钮,出现什么效果,都可以通过产品原型看到。

需求规格说明书, 一般来说就是使用 Word 文档来描述当前项目有哪些功能,每一项功能的需求及业务流程是什么样的,都会在文档中描述。

2). 第2阶段: 设计

设计的内容包含 产品设计、UI界面设计、概要设计、详细设计、数据库设计。

在设计阶段,会出具相关的UI界面、及相关的设计文档。比如数据库设计,需要设计当前项目中涉及到哪些数据库,每一个数据库里面包含哪些表,这些表结构之间的关系是什么样的,表结构中包含哪些字段,字段类型都会在文档中描述清楚。

3). 第3阶段: 编码

编写项目代码、并完成单元测试。

作为软件开发工程师,我们主要的工作就是在该阶段, 对分配给我们的模块功能,进行编码实现。编码实现完毕后,进行单元测试,单元测试通过后再进入到下一阶段。

4). 第4阶段: 测试

在该阶段中主要由测试人员, 对部署在测试环境的项目进行功能测试, 并出具测试报告。

5). 第5阶段: 上线运维

在项目上线之前, 会由运维人员准备服务器上的软件环境安装、配置, 配置完毕后, 再将我们开发好的项目,部署在服务器上运行。

我们作为软件开发工程师, 我们主要的任务是在编码阶段, 但是在一些小的项目组当中, 也会涉及到数据库的设计、测试等方面的工作。

角色分工

学习了软件开发的流程之后, 我们还有必要了解一下在整个软件开发过程中涉及到的岗位角色,以及各个角色的职责分工。

岗位/角色 职责/分工
项目经理 对整个项目负责,任务分配、把控进度
产品经理 进行需求调研,输出需求调研文档、产品原型等
UI设计师 根据产品原型输出界面效果图
架构师 项目整体架构设计、技术选型等
开发工程师 功能代码实现
测试工程师 编写测试用例,输出测试报告
运维工程师 软件环境搭建、项目上线

上述我们讲解的角色分工, 是在一个项目组中比较标准的角色分工, 但是在实际的项目中, 有一些项目组由于人员配置紧张, 可能并没有专门的架构师或测试人员, 这个时候可能需要有项目经理或者程序员兼任。

软件环境

在我们日常的软件开发中,会涉及到软件开发中的三套环境, 那么这三套环境分别是: 开发环境、测试环境、生产环境。 接下来,我们分别介绍一下这三套环境的作用和特点。

1). 开发环境(development)

我们作为软件开发人员,在开发阶段使用的环境,就是开发环境,一般外部用户无法访问。

比如,我们在开发中使用的MySQL数据库和其他的一些常用软件,我们可以安装在本地, 也可以安装在一台专门的服务器中, 这些应用软件仅仅在软件开发过程中使用, 项目测试、上线时,我们不会使用这套环境了,这个环境就是开发环境。

2). 测试环境(testing)

当软件开发工程师,将项目的功能模块开发完毕,并且单元测试通过后,就需要将项目部署到测试服务器上,让测试人员对项目进行测试。那这台测试服务器就是专门给测试人员使用的环境, 也就是测试环境,用于项目测试,一般外部用户无法访问。

3). 生产环境(production)

当项目开发完毕,并且由测试人员测试通过之后,就可以上线项目,将项目部署到线上环境,并正式对外提供服务,这个线上环境也称之为生产环境。

拓展知识:

准生产环境: 对于有的公司来说,项目功能开发好, 并测试通过以后,并不是直接就上生产环境。为了保证我们开发的项目在上线之后能够完全满足要求,就需要把项目部署在真实的环境中, 测试一下是否完全符合要求啊,这时候就诞生了准生产环境,你可以把他当做生产环境的克隆体,准生产环境的服务器配置, 安装的应用软件(JDK、Tomcat、数据库、中间件 …) 的版本都一样,这种环境也称为 “仿真环境”。

​ ps.由于项目的性质和类型不同,有的项目可能不需要这个环境

瑞吉外卖项目介绍

在开发瑞吉外卖这个项目之前,我们需要全方位的来介绍一下当前我们学习的这个项目。接下来,我们将从以下的五个方面, 来介绍瑞吉外卖这个项目。

项目介绍

本项目(瑞吉外卖)是专门为餐饮企业(餐厅、饭店)定制的一款软件产品,包括 系统管理后台 和 移动端应用 两部分。其中系统管理后台主要提供给餐饮企业内部员工使用,可以对餐厅的分类、菜品、套餐、订单、员工等进行管理维护。移动端应用主要提供给消费者使用,可以在线浏览菜品、添加购物车、下单等。

本项目共分为3期进行开发:

阶段 功能实现
第一期 主要实现基本需求,其中移动端应用通过H5实现,用户可以通过手机浏览器访问
第二期 主要针对移动端应用进行改进,使用微信小程序实现,用户使用起来更加方便
第三期 主要针对系统进行优化升级,提高系统的访问性能

产品原型

产品原型,就是一款产品成型之前,由产品经理绘制的一个简单的框架,就是将页面的排版布局展现出来,使产品的初步构思有一个可视化的展示。通过原型展示,可以更加直观的了解项目的需求和提供的功能。

注意事项: 产品原型主要用于展示项目的功能,并不是最终的页面效果。

1). 管理端

餐饮企业内部员工使用。 主要功能有:

模块 描述
登录/退出 内部员工必须登录后,才可以访问系统管理后台
员工管理 管理员可以在系统后台对员工信息进行管理,包含查询、新增、编辑、禁用等功能
分类管理 主要对当前餐厅经营的 菜品分类 或 套餐分类 进行管理维护, 包含查询、新增、修改、删除等功能
菜品管理 主要维护各个分类下的菜品信息,包含查询、新增、修改、删除、启售、停售等功能
套餐管理 主要维护当前餐厅中的套餐信息,包含查询、新增、修改、删除、启售、停售等功能
订单明细 主要维护用户在移动端下的订单信息,包含查询、取消、派送、完成,以及订单报表下载等功能

2). 用户端

移动端应用主要提供给消费者使用。主要功能有:

模块 描述
登录/退出 在移动端, 用户也需要登录后使用APP进行点餐
点餐-菜单 在点餐界面需要展示出菜品分类/套餐分类, 并根据当前选择的分类加载其中的菜品信息, 供用户查询选择
点餐-购物车 用户选中的菜品就会加入用户的购物车, 主要包含 查询购物车、加入购物车、删除购物车、清空购物车等功能
订单支付 用户选完菜品/套餐后, 可以对购物车菜品进行结算支付, 这时就需要进行订单的支付
个人信息 在个人中心页面中会展示当前用户的基本信息, 用户可以管理收货地址, 也可以查询历史订单数据

技术选型

关于本项目的技术选型, 我们将会从 用户层、网关层、应用层、数据层 这几个方面进行介绍,而对于我们服务端开发工程师来说,在项目开发过程中,我们主要关注应用层及数据层技术的应用。

1). 用户层

本项目中在构建系统管理后台的前端页面,我们会用到H5Vue.jsElementUI等技术。而在构建移动端应用时,我们会使用到微信小程序。

2). 网关层

Nginx是一个服务器,主要用来作为Http服务器,部署静态资源,访问性能高。在Nginx中还有两个比较重要的作用: 反向代理和负载均衡, 在进行项目部署时,要实现Tomcat的负载均衡,就可以通过Nginx来实现。

3). 应用层

  • SpringBoot: 快速构建Spring项目, 采用 “约定优于配置” 的思想, 简化Spring项目的配置开发。

  • Spring: 统一管理项目中的各种资源(bean), 在web开发的各层中都会用到。

  • SpringMVC:SpringMVC是spring框架的一个模块,springmvc和spring无需通过中间整合层进行整合,可以无缝集成。

  • SpringSession: 主要解决在集群环境下的Session共享问题。

  • lombok:能以简单的注解形式来简化java代码,提高开发人员的开发效率。例如开发中经常需要写的javabean,都需要花时间去添加相应的getter/setter,也许还要去写构造器、equals等方法。

  • Swagger: 可以自动的帮助开发人员生成接口文档,并对接口进行测试。

4). 数据层

  • MySQL: 关系型数据库, 本项目的核心业务数据都会采用MySQL进行存储。

  • MybatisPlus: 本项目持久层将会使用MybatisPlus来简化开发, 基本的单表增删改查直接调用框架提供的方法即可。

  • Redis: 基于key-value格式存储的内存数据库, 访问速度快, 经常使用它做缓存(降低数据库访问压力, 提供访问效率), 在后面的性能优化中会使用。

5). 工具

  • git: 版本控制工具, 在团队协作中, 使用该工具对项目中的代码进行管理。

  • maven: 项目构建工具。

  • junit:单元测试工具,开发人员功能实现完毕后,需要通过junit对功能进行单元测试。

功能架构

1). 移动端前台功能

手机号登录 , 微信登录 , 收件人地址管理 , 用户历史订单查询 , 菜品规格查询 , 购物车功能 , 下单 , 分类及菜品浏览。

2). 系统管理后台功能

员工登录/退出 , 员工信息管理 , 分类管理 , 菜品管理 , 套餐管理 , 菜品口味管理 , 订单管理 。

角色

在瑞吉外卖这个项目中,存在以下三种用户,这三种用户对应三个角色: 后台系统管理员、后台系统普通员工、C端(移动端)用户。

角色 权限操作
后台系统管理员 登录后台管理系统,拥有后台系统中的所有操作权限
后台系统普通员工 登录后台管理系统,对菜品、套餐、订单等进行管理 (不包含员工管理)
C端用户 登录移动端应用,可以浏览菜品、添加购物车、设置地址、在线下单等

开发环境搭建

数据库环境搭建

创建数据库

可以通过以下两种方式中的任意一种, 来创建项目的数据库:

1).图形界面

注意: 本项目数据库的字符串, 选择 utf8mb4

2).命令行

数据库表导入

项目的数据库创建好了之后, 可以直接将 资料/数据模型/db_reggie.sql 直接导入到数据库中, 也可以通过两种方式实现:

1).图形界面

2).命令行

注意: 通过命令导入表结构时,注意sql文件不要放在中文目录中

数据库表介绍

数据库表导入之后, 接下来介绍一下本项目中所涉及到的表结构:

序号 表名 说明
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 订单明细表

上述的表结构, 我们目前先简单的结合页面原型了解一下, 大概有那些表, 每张表结构中存储什么样的数据, 有一个印象。对于具体的表结构, 以及表结构中的字段, 在讲解具体的功能开发时, 我们再详细介绍。

Maven项目搭建

创建maven项目

1). 在idea中创建maven project, 项目名称 reggie_take_out

2). 检查项目编码

3). 检查maven配置

4). 检查JDK版本

JDK的版本选择1.8;

搭建基础环境

1).在pom.xml中导入依赖

<properties><java.version>1.8</java.version>
</properties><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.4.5</version><relativePath/> <!-- lookup parent from repository -->
</parent><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId><scope>compile</scope></dependency><dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId><version>3.4.2</version></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><version>1.18.20</version></dependency><dependency><groupId>com.alibaba</groupId><artifactId>fastjson</artifactId><version>1.2.76</version></dependency><dependency><groupId>commons-lang</groupId><artifactId>commons-lang</artifactId><version>2.6</version></dependency><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><scope>runtime</scope></dependency><dependency><groupId>com.alibaba</groupId><artifactId>druid-spring-boot-starter</artifactId><version>1.1.23</version></dependency>
</dependencies><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId><version>2.4.5</version></plugin></plugins>
</build>

我们在这里对每一个依赖进行说明:

  • spring-boot-starter-web:SpringBoot框架Web开发的启动依赖
  • spring-boot-starter-test:SpringBoot框架测试功能的启动依赖
  • mybatis-plus-boot-starter:SpringBoot框架整合MyBatisPlus的启动依赖
  • lombok:代码生成器,简化实体类的开发,同时我们在项目中还会使用到他的日志功能
  • fastjson:帮助我们把json数据转换成对象,把对象转化成json数据
  • commons-lang:跟java.lang这个包的作用类似,Commons Lang这一组API也是提供一些基础的、通用的操作和处理,如自动生成toString()的结果、自动实现hashCode()和equals()方法、数组操作、枚举、日期和时间的处理等等。
  • mysql-connector-java:MySQL提供的JDBC驱动包,用JDBC连接MySQL数据库时必须使用该jar包,它的主要用途有三个:
    • 与数据库建立连接
    • 发送 SQL 语句
    • 处理结果
  • druid-spring-boot-starter:我们使用阿里的Druid数据库连接池就需要此启动依赖

2).在工程的resources目录下创建application.yml文件,并引入配置

server:port: 8080
spring:application:#应用名称 , 可选name: reggie_take_outdatasource:druid:driver-class-name: com.mysql.cj.jdbc.Driverurl: jdbc:mysql://localhost:3306/reggie?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=utf-8&zeroDateTimeBehavior=convertToNull&useSSL=false&allowPublicKeyRetrieval=trueusername: rootpassword: *******************
mybatis-plus:configuration:#在映射实体或者属性时,将数据库中表名和字段名中的下划线去掉,按照驼峰命名法映射 address_book ---> AddressBookmap-underscore-to-camel-case: true#日志输出log-impl: org.apache.ibatis.logging.stdout.StdOutImplglobal-config:db-config:id-type: ASSIGN_ID

3).创建包 com.itheima.reggie , 并编写启动类

import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;@Slf4j
@SpringBootApplication
public class ReggieApplication {public static void main(String[] args) {SpringApplication.run(ReggieApplication.class,args);log.info("项目启动成功...");}
}

@Slf4j :

​ 是lombok中提供的注解, 用来通过slf4j记录日志。

当搭建完上述的基础环境之后, 就可以通过引导类, 启动该项目。

前端静态资源导入

我们这个项目重在后端开发,前端的实现过程不是我们关注的重点,我们直接将前端资源进行导入。

1). 导入静态资源

前端资源存放位置为 资料/前端资源 :

将上述两个目录中的静态资源文件, 导入到项目的resources目录下:

2). 创建配置类WebMvcConfig,设置静态资源映射

在Springboot项目中, 默认静态资源的存放目录为 : “classpath:/resources/”, “classpath:/static/”, “classpath:/public/” ; 而在我们的项目中静态资源存放在 backend, front 目录中, 那么这个时候要想访问到静态资源, 就需要设置静态资源映射。

直接去访问我们的静态资源肯定是访问不到的。客户端发送请求想得到静态资源,我们的Servlet容器拿到请求之后,发现它不会被MVC捕捉,也就是说不需要继续交给SpringMVC的容器去处理,于是自己处理看有没有对应的Servlet页面,发现也没有这个东西,于是报404。所以我们需要将请求静态资源的地址捕捉映射到当前类路径下。

import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport;@Slf4j
@Configuration
public class WebMvcConfig extends WebMvcConfigurationSupport {/*** 设置静态资源映射* @param registry*/@Overrideprotected void addResourceHandlers(ResourceHandlerRegistry registry) {log.info("开始进行静态资源映射...");registry.addResourceHandler("/backend/**").addResourceLocations("classpath:/backend/");registry.addResourceHandler("/front/**").addResourceLocations("classpath:/front/");}
}

注意:
我们在创建SpringBoot项目的时候会发现resources目录下面还放了两个子目录:

  • static
  • templates

上面代码在进行静态资源导入的时候,是直接把这两个子文件夹给删除了,如果我们没有把他们删除,而是直接把前端的静态资源放在static文件夹下那也是可以的,例如:

不过这个时候我们的静态资源映射就需要更改了:

同时我们来复习一下这段代码:

     registry.addResourceHandler("/backend/**").addResourceLocations("classpath:/static/backend/");

这段代码意思就配置一个拦截器, 如果访问路径是addResourceHandler中的filepath这个路径 那么就 映射到访问本地的addResourceLocations 的参数的这个路径上,这样就可以让别人访问服务器的本地文件了,比如本地图片或者本地音乐视频什么的

说到这我们可以说说这个classpath是什么?

classpath就是我们常说的类路径。

对于SpringBoot项目来说,classpath指的是src.main.java和src.main.resources路径以及第三方jar包的根路径,存放在这两个路径下的文件,都可以通过classpath作为相对路径来引用

说白了,在SpringBoot项目编译之后,我们可以看到一个target文件夹,其中的classes文件夹,对应的就是我们的classpath路径

进入classes:

没有template是因为此时我们的template文件夹中没有放东西,所以打包的时候为了节省空间就自动删除了。

src.main.java和src.main.resources路径下的内容,在执行了Maven的Compile后,都会被放到target.classes目录下,包括.class文件,静态资源文件(图片,CSS,jQuery文件等)

3). 访问测试

http://localhost:8080/backend/index.html

后台系统登录功能

需求分析

1). 页面原型展示

2). 登录页面成品展示

登录页面存放目录 /resources/backend/page/login/login.html

3). 查看登录请求

通过浏览器调试工具(F12),可以发现,点击登录按钮时,页面会发送请求(请求地址为http://localhost:8080/employee/login)并提交参数 username和password, 请求参数为json格式数据 {“username”:“admin”,“password”:“123456”}。

此时报404,是因为我们的后台系统还没有响应此请求的处理器,所以我们需要创建相关类来处理登录请求 ;

4). 数据模型(employee表)

5). 前端页面分析

当点击 “登录” 按钮, 会触发Vue中定义的 handleLogin 方法:

在上述的前端代码中, 大家可以看到, 发送登录的异步请求之后, 获取到响应结果, 在响应结果中至少包含三个属性: code、data、msg 。

由前端代码,我们也可以看到,在用户登录成功之后,服务端会返回用户信息,而前端是将这些用户信息,存储在客户端的 localStorage 中了。

localStorage.setItem('userInfo',JSON.stringify(res.data))

代码开发

基础准备工作

在进行登录功能的代码实现之前, 首先在我们的工程下创建包结构:

1). 创建实体类Employee

该实体类主要用于和员工表 employee 进行映射。 该实体类, 也可以直接从资料( 资料/实体类 )中拷贝工程中。

所属包: com.itheima.reggie.entity

import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.annotation.TableField;
import lombok.Data;
import java.io.Serializable;
import java.time.LocalDateTime;@Data
public class Employee implements Serializable {private static final long serialVersionUID = 1L;private Long id;private String username;private String name;private String password;private String phone;private String sex;private String idNumber; //驼峰命名法 ---> 映射的字段名为 id_numberprivate Integer status;private LocalDateTime createTime;private LocalDateTime updateTime;@TableField(fill = FieldFill.INSERT)private Long createUser;@TableField(fill = FieldFill.INSERT_UPDATE)private Long updateUser;
}

在实体类这一块我们有几个注意点:

  • 在mybatis-plus中,默认开启了下滑线-驼峰转换会把数据库字段中的下划线自动转换成驼峰形式,然后去匹配实体类对象的字段
  • @TableField(fill = FieldFill.INSERT)@TableField(fill = FieldFill.INSERT_UPDATE)是数据库的字段自动填充策略
  • private static final long serialVersionUID = 1L;是用于在序列化和反序列化过程中进行核验的一个版本号。记住:实现Serializable接口,最好规定serialVersionUID,否则JVM会使用相关算法自动帮你生成(当然这是不推荐的)

2). 定义Mapper接口

在MybatisPlus中, 自定义的Mapper接口, 需要继承自 BaseMapper。

所属包: com.itheima.reggie.mapper

@Mapper
public interface EmployeeMapper extends BaseMapper<Employee>{}

3).Service接口

本项目的Service接口, 在定义时需要继承自MybatisPlus提供的Service层接口 IService, 这样就可以直接调用 父接口的方法直接执行业务操作, 简化业务层代码实现。

所属包: com.itheima.reggie.service

public interface EmployeeService extends IService<Employee> {}

4). Service实现类

所属包: com.itheima.reggie.service.impl

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.itheima.reggie.entity.Employee;
import com.itheima.reggie.mapper.EmployeeMapper;
import com.itheima.reggie.service.EmployeeService;
import org.springframework.stereotype.Service;@Service
public class EmployeeServiceImpl extends ServiceImpl<EmployeeMapper,Employee> implements EmployeeService{}

5). Controller基础代码

所属包: com.itheima.reggie.controller

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;@Slf4j
@RestController
@RequestMapping("/employee")
public class EmployeeController {@Autowiredprivate EmployeeService employeeService;}

6). 导入通用结果类R

此类是一个通用结果类,服务端响应的所有结果最终都会包装成此种类型返回给前端页面。

所属包: com.itheima.reggie.common

import lombok.Data;
import java.util.HashMap;
import java.util.Map;/*** 通用返回结果,服务端响应的数据最终都会封装成此对象* @param <T>*/
@Data
public class R<T> {private Integer code; //编码:1成功,0和其它数字为失败private String msg; //错误信息private T data; //数据private Map map = new HashMap(); //动态数据public static <T> R<T> success(T object) {R<T> r = new R<T>();r.data = object;r.code = 1;return r;}public static <T> R<T> error(String msg) {R r = new R();r.msg = msg;r.code = 0;return r;}public R<T> add(String key, Object value) {this.map.put(key, value);return this;}
}

A. 如果业务执行结果为成功, 构建R对象时, 只需要调用 success 方法; 如果需要返回数据传递 object 参数, 如果无需返回, 可以直接传递null。

B. 如果业务执行结果为失败, 构建R对象时, 只需要调用error 方法, 传递错误提示信息即可。

登录逻辑分析

处理逻辑如下:

①. 将页面提交的密码password进行md5加密处理, 得到加密后的字符串

②. 根据页面提交的用户名username查询数据库中员工数据信息

③. 如果没有查询到, 则返回登录失败结果

④. 密码比对,如果不一致, 则返回登录失败结果

⑤. 查看员工状态,如果为已禁用状态,则返回员工已禁用结果

⑥. 登录成功,将员工id存入Session, 并返回登录成功结果

代码实现

技术点说明:

A. 由于需求分析时, 我们看到前端发起的请求为post请求, 所以服务端需要使用注解 @PostMapping

B. 由于前端传递的请求参数为json格式的数据, 这里使用Employee对象接收, 但是将json格式数据封装到实体类中, 在形参前需要加注解@RequestBody

文档内提供的实现代码:

/*** 员工登录* @param request* @param employee* @return*/
@PostMapping("/login")
public R<Employee> login(HttpServletRequest request,@RequestBody Employee employee){//1、将页面提交的密码password进行md5加密处理String password = employee.getPassword();password = DigestUtils.md5DigestAsHex(password.getBytes());//2、根据页面提交的用户名username查询数据库LambdaQueryWrapper<Employee> queryWrapper = new LambdaQueryWrapper<>();queryWrapper.eq(Employee::getUsername,employee.getUsername());Employee emp = employeeService.getOne(queryWrapper);//3、如果没有查询到则返回登录失败结果if(emp == null){return R.error("登录失败");}//4、密码比对,如果不一致则返回登录失败结果if(!emp.getPassword().equals(password)){return R.error("登录失败");}//5、查看员工状态,如果为已禁用状态,则返回员工已禁用结果if(emp.getStatus() == 0){return R.error("账号已禁用");}//6、登录成功,将员工id存入Session并返回登录成功结果request.getSession().setAttribute("employee",emp.getId());return R.success(emp);
}

个人实现:

/*** @author 十八岁讨厌编程* @date 2023/3/13 11:24* @PROJECT_NAME reggie_project* @description*/
@RestController
@RequestMapping("employee")
public class EmployeeController {@Resourceprivate EmployeeService employeeService;@PostMapping("login")public R<Employee> login(@RequestBody Employee employee, HttpServletRequest request){String password = employee.getPassword();//首先对密码进行md5加密String md5DigestAsHex= DigestUtils.md5DigestAsHex(password.getBytes());//在数据库查询是否有这个用户,如果有则进行密码比对Employee queryEmployee = employeeService.getOne(new LambdaQueryWrapper<Employee>().eq(Employee::getUsername,employee.getUsername()));if (queryEmployee == null){return R.error("没有此用户");}if (!queryEmployee.getPassword().equals(md5DigestAsHex)){return R.error("密码错误");}//查看该用户是否被禁用if (queryEmployee.getStatus() == 0) {return R.error("该用户已被禁用");}//进行到此时表示用户登陆正常,将用户信息存储到session中request.getSession().setAttribute("employee",queryEmployee.getId());return R.success(queryEmployee);}}

这一段代码有几个注意点、复习点:

  • DigestUtils是一个加密算法工具类,这个类来自于org.springframework.util包下,我们可以凭其进行常用的md2 md5 sha sha1 sha256 sha384 sha512 加密算法。
  • MyBatisPlus中条件构造器的使用
  • HttpServletRequest
  • Session工作原理
  • lambda表达式,特别是其中的方法引用部分

queryWrapper.eq(Employee::getUsername,employee.getUsername());中的Employee::getUsername传入的其实是SFunction对象,通过AbstractLambdaWrapper.columnsToString方法将SFunction转为column名称。
我们可以看到:columnsToString方法源码:

我们再进去看看LambdaUtils.resolve(column)是个什么东西

可以肯定的是用到了反射机制拿到的表的字段名。

功能测试

代码实现完毕后, 启动项目, 访问url: http://localhost:8080/backend/page/login/login.html , 进行登录测试。

在测试过程中, 可以通过debug断点调试的方式来跟踪程序的执行过程,并且可以查看程序运行时各个对象的具体赋值情况。而且需要注意, 在测试过程中,需要将所有的情况都覆盖到。

1). 问题说明

当我们在进行debug端点调试时, 前端可能会出现如下问题: 前端页面的控制台报出错误-超时;

2). 解决方案

前端进行异步请求时, 默认超时10000ms , 可以将该值调大一些。

由于修改了JS文件,需要手动清理一下浏览器缓存,避免缓存影响,JS不能及时生效。

后台系统退出功能

需求分析

在后台管理系统中,管理员或者员工,登录进入系统之后,页面跳转到后台系统首页面(backend/index.html),此时会在系统的右上角显示当前登录用户的姓名。

如果员工需要退出系统,直接点击右侧的退出按钮即可退出系统,退出系统后页面应跳转回登录页面。

1). 退出页面展示

2).前端页面分析

点击将会调用一个js方法logout, 在logout的方法中执行如下逻辑:

A. 发起post请求, 调用服务端接口 /employee/logout 执行退出操作 ;

B. 删除客户端 localStorage 中存储的用户登录信息, 跳转至登录页面 ;

代码实现

需要在Controller中创建对应的处理方法, 接收页面发送的POST请求 /employee/logout ,具体的处理逻辑:

A. 清理Session中的用户id

B. 返回结果

/**
* 员工退出
* @param request
* @return
*/
@PostMapping("/logout")
public R<String> logout(HttpServletRequest request){//清理Session中保存的当前登录员工的idrequest.getSession().removeAttribute("employee");return R.success("退出成功");
}

功能测试

1). 代码实现完毕后, 重启服务, 访问登录界面 http://localhost:8080/backend/page/login/login.html ;

2). 登录完成之后, 进入到系统首页 backend/index.html,点击右上角 按钮 执行退出操作, 完成后看看是否可以跳转到登录页面 , 并检查localStorage。

思维导图总结

【SpringBoot项目实战+思维导图】瑞吉外卖①(项目介绍、开发环境搭建、后台登陆/退出功能开发)相关推荐

  1. 【SpringBoot项目实战+思维导图】瑞吉外卖⑥(用户地址簿功能、菜品展示、购物车、下单)

    文章目录 用户地址簿功能 需求分析 数据模型 导入功能代码 功能测试 思维导图总结 菜品展示 需求分析 前端页面分析 代码开发 查询菜品方法修改 根据分类ID查询套餐 功能测试 思维导图总结 购物车 ...

  2. 医学计算机应用基础项目五思维导图,【羊五小•项目学习】“一千零一夜+思维导图”学习成果发布会(五年级)...

    原标题:[羊五小•项目学习]"一千零一夜+思维导图"学习成果发布会(五年级) 在"思维导图"的世界里遇到最美好的自己 题记 学校借助美国项目学习理念,围绕&qu ...

  3. 瑞吉外卖(1)环境搭建

    导入sql /* Navicat MySQL Data TransferSource Server : localhost Source Server Version : 50728 Source H ...

  4. 云服务器部署SpringBoot工程-瑞吉外卖项目

    Linux部署SpringBoot工程-瑞吉外卖项目 云平台:阿里云 终端软件:Tabby Terminal 部署项目项目: SpringBoot-瑞吉外卖 自己第一次从本地web项目搭建到云端部署发 ...

  5. XX项目测试策略思维导图

    曾经参加过的一个项目测试环节的思维导图. 下载地址XX项目测试策略思维导图 转载于:https://www.cnblogs.com/Sayiod/archive/2007/06/27/797837.h ...

  6. 瑞吉外卖项目详细分析笔记及所有功能补充代码

    目录 项目刨析简介 技术栈 项目介绍 项目源码 一.架构搭建 1.初始化项目结构 2.数据库表结构设计 3.项目基本配置信息添加 公共字段的自动填充 全局异常处理类 返回结果封装的实体类 二.管理端业 ...

  7. 瑞吉外卖项目(一)软件开发流程设计及环境搭建

    第一章 软件开发整体介绍 软件开发流程 软件开发流程 需求分析:产品原型.需求规格说明书 设计:产品文档,ui界面设计,概要设计,详细设计,数据库设计 编码:项目代码,单元测试 测试:测试用例,测试报 ...

  8. 瑞吉外卖项目剩余功能补充

    目录 菜品启售和停售 菜品批量启售和批量停售 菜品的批量删除 菜品删除逻辑优化 套餐管理的启售,停售 套餐管理的修改 后台按条件查看和展示客户订单 手机端减少购物车中的菜品或者套餐数量(前端展示有一点 ...

  9. 黑马瑞吉外卖项目开发笔记

    目录 软件开发整体介绍 开发流程 角色分工 软件环境 瑞吉外卖项目介绍 项目介绍 产品原型展示 技术选型 功能架构 角色 开发环境搭建 数据库环境搭建 Maven环境搭建 1.直接创建maven项目( ...

最新文章

  1. 网路摄像头技术参数介绍
  2. oracle to_char函数的使用
  3. 在Exchange Server 2007中使用多主机名称证书
  4. Service随系统启动运行
  5. AttributeError: module ‘tensorflow‘ has no attribute ‘app‘
  6. vmstat使用简介各种linux命令使用
  7. LNMP+HAProxy+Keepalived负载均衡(五)- 通过rsyncd实现文件的相互同步
  8. 第一阶段冲刺(第十天)
  9. linux网络子系统分析(五)——netfilter
  10. 最小二乘支持向量机(LS-SVM)使用说明
  11. aruba交换机配置命令_Aruba 无线交换机基本操作命令
  12. 笹山希 java,C#版数据结构与算法高级教程(深入探讨)--附各种算法实例-升级版
  13. 临床公共数据库挖掘系列1---seer数据库注册
  14. lol服务器维护8月7,LOL8月7日维护到几点 具体更新了什么
  15. coreapi自动生成API接口文档
  16. 法国蓬皮杜中心天猫官方旗舰店开业;洲际集团旗下高端品牌voco全球开业及签约酒店数突破100家 | 美通企业日报...
  17. 使用total commander打开当前目录
  18. 安卓蓝牙实现即时通讯功能
  19. 新任学校领导的国家简报
  20. Ubuntu下将rm命令替换为trash命令

热门文章

  1. [Oracle] 自定义数据类型Type
  2. 祈福医疗冲刺港股:年营收12亿 经营利润2.27亿
  3. 基于vue的分享插件
  4. Games101-课程16笔记
  5. 夜深人静写算法(三十二)- 费马小定理
  6. 编译器与Debug的传奇:Grace Murray Hopper小传
  7. 一文读懂 Apache Pulsar详细解析和实战运用
  8. 中专初级计算机专业学什么知识,中专计算机主要学什么内容
  9. LeetCode(力扣)_接雨水
  10. AlphaZero如何学习国际象棋的?