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

项目实战-瑞吉外卖day01(B站)

瑞吉外卖-Day01

课程内容


  • 软件开发整体介绍

  • 瑞吉外卖项目介绍

  • 开发环境搭建

  • 后台登录功能开发

  • 后台退出功能开发

1. 软件开发整体介绍


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

1.1 软件开发流程

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

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

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

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

2). 第2阶段: 设计

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

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

3). 第3阶段: 编码

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

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

4). 第4阶段: 测试

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

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

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

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

1.2 角色分工

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

岗位/角色

职责/分工

项目经理

对整个项目负责,任务分配、把控进度

产品经理

进行需求调研,输出需求调研文档、产品原型等

UI设计师

根据产品原型输出界面效果图

架构师

项目整体架构设计、技术选型等

开发工程师

功能代码实现

测试工程师

编写测试用例,输出测试报告

运维工程师

软件环境搭建、项目上线

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

1.3 软件环境

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

1). 开发环境(development)

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

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

2). 测试环境(testing)

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

3). 生产环境(production)

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

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

2 瑞吉外卖项目介绍


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

2.1 项目介绍

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

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

阶段

功能实现

第一期

主要实现基本需求,其中移动端应用通过H5实现,用户可以通过手机浏览器访问

第二期

主要针对移动端应用进行改进,使用微信小程序实现,用户使用起来更加方便

第三期

主要针对系统进行优化升级,提高系统的访问性能

2.2 产品原型

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

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

在课程资料的产品原型文件夹下,提供了两份产品原型。

1). 管理端

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

模块

描述

登录/退出

内部员工必须登录后,才可以访问系统管理后台

员工管理

管理员可以在系统后台对员工信息进行管理,包含查询、新增、编辑、禁用等功能

分类管理

主要对当前餐厅经营的 菜品分类 或 套餐分类 进行管理维护, 包含查询、新增、修改、删除等功能

菜品管理

主要维护各个分类下的菜品信息,包含查询、新增、修改、删除、启售、停售等功能

套餐管理

主要维护当前餐厅中的套餐信息,包含查询、新增、修改、删除、启售、停售等功能

订单明细

主要维护用户在移动端下的订单信息,包含查询、取消、派送、完成,以及订单报表下载等功能

2). 用户端

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

模块

描述

登录/退出

在移动端, 用户也需要登录后使用APP进行点餐

点餐-菜单

在点餐界面需要展示出菜品分类/套餐分类, 并根据当前选择的分类加载其中的菜品信息, 供用户查询选择

点餐-购物车

用户选中的菜品就会加入用户的购物车, 主要包含 查询购物车、加入购物车、删除购物车、清空购物车等功能

订单支付

用户选完菜品/套餐后, 可以对购物车菜品进行结算支付, 这时就需要进行订单的支付

个人信息

在个人中心页面中会展示当前用户的基本信息, 用户可以管理收货地址, 也可以查询历史订单数据

1.3 技术选型

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

1). 用户层

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

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.4 功能架构

1). 移动端前台功能

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

2). 系统管理后台功能

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

1.5 角色

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

角色

权限操作

后台系统管理员

登录后台管理系统,拥有后台系统中的所有操作权限

后台系统普通员工

登录后台管理系统,对菜品、套餐、订单等进行管理 (不包含员工管理)

C端用户

登录移动端应用,可以浏览菜品、添加购物车、设置地址、在线下单等

3. 开发环境搭建


3.1 数据库环境搭建

3.1.1 创建数据库

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

1).图形界面

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

2).命令行

3.1.2 数据库表导入

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

1).图形界面

刷新

2).命令行

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

3.1.3 数据库表介绍

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

序号

表名

说明

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

订单明细表

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

employee 员工表

主要存储员工的个人信息

category 菜品和套餐分类表

dish 菜品表

setmeal 套餐表

dish_flavor 菜品口味关系表

address_book 地址簿表

shopping_cart 购物车表

order_detail 订单明细表

3.2 Maven项目搭建

3.2.1 创建maven项目

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

2). 检查项目编码

3). 检查maven配置

4). 检查JDK版本

3.2.2 搭建基础环境

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

<?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.4.5</version><relativePath/> <!-- lookup parent from repository --></parent><groupId>com.itheima</groupId><artifactId>reggie_take_out</artifactId><version>1.0-SNAPSHOT</version><properties><java.version>1.8</java.version></properties><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>
</project>

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: 123456
mybatis-plus:configuration:# address_book(表名)  -----> AddressBook(实体类名)# user_name(表名)------> userName(实体类名)#在映射实体或者属性时,将数据库中表名和字段名中的下划线去掉,按照驼峰命名法映射map-underscore-to-camel-case: truelog-impl: org.apache.ibatis.logging.stdout.StdOutImplglobal-config:db-config:id-type: ASSIGN_ID

3). 并编写启动类

@Slf4j
@SpringBootApplication
public class ReggieApplication {public static void main(String[] args) {SpringApplication.run(ReggieApplication.class, args);log.info("项目启动成功...");}
}

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

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

注:这里面我们用公共包的方式创建包

把这里面的com复制过来

3.2.3 前端静态资源导入

我们作为服务端开发工程师, 我们课程学习的重心应该放在后端的业务代码上, 前端的页面我们只需要导入课程资料中的前端资源, 前端页面的代码我们只需要能看懂即可。

1). 导入静态资源

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

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

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

用于在Springboot项目中, 默认静态资源的存放目录为 :

 "classpath:/resources/", "classpath:/static/", "classpath:/public/" ; 

而在我们的项目中静态资源存放在 backend, front 目录中, 那么这个时候要想访问到静态资源, 就需要设置静态资源映射。

@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/");}}

classpath:指的是在resources文件下面

3). 访问测试

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

4. 后台系统登录功能


4.1 需求分析

1). 页面原型展示

2). 登录页面成品展示

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

http://localhost:8080/backend/page/login/login.html

3). 查看登录请求

通过浏览器调试工具(F12),可以发现,点击登录按钮时,页面会发送请求

账号:admin

密码:123456

F12

点击登录按钮时,页面会发送请求 并提交参数 username和password, 请求参数为json格式数据 {"username":"admin","password":"123456"}。

请求地址为http://localhost:8080/employee/login

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

4). 数据模型(employee表)

5). 前端页面分析

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

到达handleLogin()方法之后 先找到表单 然后调用validate()进行表单检验 主要检验我们的用户名和密码是否为空,

如果检验通过后 我们就把loading改成true 【this.loading = true】 当把loading改成true 时 下图就一直属于登录中

这个时候

重点在于如果检验通过之后 就会调用loginApi() 这个方法关联在login.js里面 我们鼠标放在loginApi()上 按住Ctrl+左健 就可以跳转到如下页面

function loginApi(data) {return $axios({'url': '/employee/login','method': 'post',data})
}function logoutApi(){return $axios({'url': '/employee/logout','method': 'post',})
}

通过axios向我们的后端服务来发送请求 请求为'/employee/login' 是一个'post', 并且把数据 data带过来 这个数据就是我们的loginForm loginForm里面话的就是我们的用户名和密码 这个时候我们的请求就发出去了 请求发出去之后 如果我们的服务端接收到请求 就要在服务端进行相对应的处理 处理完之后 在给前端页面 一个响应的结果 而这个就是通过res来进行接收( let res = await loginApi(this.loginForm)) 接收好后 我们在进行判断 如果 String(res.code) === '1' 如果等于1 就表示登录成功 当登录成功之后 将数据转换成JSON 然后保存在浏览器中(存储在客户端的 localStorage 中)(通过k-v的方式转成JSDN)localStorage.setItem('userInfo',JSON.stringify(res.data)) 然后在做页面跳转 跳转的页面为'/backend/index.html'【 window.location.href= '/backend/index.html'】 跳转到如下页面

如果登录失败 也就是说String(res.code) != '1' 会提供一个错误信息 this.$message.error(res.msg)

然后把loading 改成 【falseloading = false】 这个时候我们的前端页面又会变成登录按钮 如下图所示

这个时候 我们就可以在重新登录

  methods: {async handleLogin() {this.$refs.loginForm.validate(async (valid) => {if (valid) {this.loading = truelet res = await loginApi(this.loginForm)if (String(res.code) === '1') {localStorage.setItem('userInfo',JSON.stringify(res.data))window.location.href= '/backend/index.html'} else {this.$message.error(res.msg)this.loading = false}}})}}

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

从响应返回结果里面获取到的值 在响应结果中至少包含三个属性: code、data、msg 。

也就是说 要求我们服务端处理完之后 数据里面应该要有code、data、msg 并且是JSON的形式 这样前端页面才能获取到

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

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

4.2 代码开发

4.2.1 基础准备工作

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

这一步 我们通过公共包创建的方式已经完成了

1). 创建实体类Employee

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

所属包: com.itheima.reggie.entity

package 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;}

注意:

实体类和表的名称不同 要开启驼峰命名法

实体类

 private String idNumber;   //驼峰命名法 ---> 映射的字段名为 id_number
private LocalDateTime createTime;
private LocalDateTime updateTime;

数据库中的表

这个时候要开启驼峰命名

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

@Service
public class EmployeeServiceImpl extends ServiceImpl<EmployeeMapper, Employee> implements EmployeeService {}
5). Controller基础代码

所属包: com.itheima.reggie.controller

@Slf4j
@RestController
@RequestMapping("/employee")
public class EmployeeController {@Autowiredprivate EmployeeService employeeService;}

6). 导入通用结果类R

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

后面我们要写很多的controller controller也有很多方法 这些方法全都是响应我们客户端页面发过来的一些请求   然后controller处理完成之后 要给页面一个结果   而这个结果封装的话都统一把所有的返回结果全都封装成一个R对象  

所属包: com.itheima.reggie.common

package 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 方法, 传递错误提示信息即可。

4.2.2 登录逻辑分析

处理逻辑如下:

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

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

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

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

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

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

4.2.3 代码实现

技术点说明:

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

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

   /*员工登录*/public R<Employee> login(HttpServletRequest request, @RequestBody Employee employee){return null;}
package com.itheima.reggie.controller;import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.itheima.reggie.common.R;
import com.itheima.reggie.entity.Employee;
import com.itheima.reggie.service.EmployeeService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.DigestUtils;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;import javax.servlet.http.HttpServletRequest;@Slf4j
@RestController
@RequestMapping("/employee")
public class EmployeeController {@Autowiredprivate EmployeeService employeeService;/*员工登录*/public R<Employee> login(HttpServletRequest request, @RequestBody Employee employee){//1、将页面提交的密码password进行md5加密处理//密码封装到employee里面去了 所以我们直接通过 employee.getPassword() 就可以获取到密码;String password = employee.getPassword();//用工具类进行md5加密  加密完 passwordpassword = 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);}}

4.3 功能测试

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

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

1). 问题说明

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

2). 解决方案

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

4.3 功能测试

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

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

相关文章:

项目实战-瑞吉外卖day01(B站)

瑞吉外卖-Day01课程内容软件开发整体介绍瑞吉外卖项目介绍开发环境搭建后台登录功能开发后台退出功能开发1. 软件开发整体介绍作为一名软件开发工程师,我们需要了解在软件开发过程中的开发流程&#xff0c; 以及软件开发过程中涉及到的岗位角色&#xff0c;角色的分工、职责&am…...

Linux 学习整理(使用 iftop 查看网络带宽使用情况 《端口显示》)

一、命令简介 iftop 是实时流量监控工具&#xff0c;可以用来监控网卡的实时流量&#xff08;可以指定网段&#xff09;、反向解析IP、显示端口信息等。 二、命令安装 yum install -y iftop 三、命令相关参数及说明 3.1、相关参数说明 -i&#xff1a;设定监测的网卡&#…...

Vue3创建项目(四)axios封装及接口配置

项目结构: 目录 &#x1f349;&#x1f349;&#x1f349;index.ts &#x1f349;&#x1f349;&#x1f349; api.ts 看完需要预计花费10分钟。 请求拦截器与响应拦截器 阅读下面代码需先了解以下内容&#xff1a; 请求拦截器&#xff1a; 请求拦截器的作用是在请求发送前进…...

【算法笔记】递归与回溯

递归与回溯 To Iterate is Human, to Recurse, Divine. —L. Peter Deutsch 人理解迭代&#xff0c;神理解递归。 —L. Peter Deutsch 1.什么是递归呢 递归形象描述&#xff1a; 你打开面前这扇门&#xff0c;看到屋里面还有一扇门。 你走过去&#xff0c;发现手中的钥匙还可以…...

蓝桥杯备赛——Echarts学习

文章目录前言学习 ECharts 的方法快速上手基础知识option 配置选项可选配置title 标题组件tooltip 提示框组件axisPointer 坐标轴指示器legend 图例组件toolbox 工具栏坐标轴xAxis和yAxisseries &#xff08;[ ]用数组表示,数组里是一个个数据对象&#xff09;饼状图散点图交互…...

动态规划--最长公共子串

最长公共子串公共子串问题费曼算法动态规划算法思路代码实现公共子串问题 在计算机科学中&#xff0c;最长公共子串问题是寻找两个或多个已知字符串最长的子串。此问题与最长公共子序列问题的区别在于子序列不必是连续的&#xff0c;而子串却必须是。链接: 百度百科 费曼算法…...

【运筹优化】剩余空间法求解带顺序约束的二维矩形装箱问题 + Java代码实现

文章目录一、带顺序约束的二维矩形装箱问题二、剩余空间法三、完整代码实现3.1 Instance 实例类3.2 Item 物品类3.3 PlaceItem 已放置物品类3.4 Solution 结果类3.5 RSPackingWithWeight 剩余空间算法类3.6 Run 运行类3.7 测试案例3.8 ReadDataUtil 数据读取类3.9 运行结果展示…...

第四阶段15-关于权限,处理解析JWT时的异常,跨域请求,关于Spring Security的认证流程

处理解析JWT时的异常 由于解析JWT是在过滤器中执行的&#xff0c;而过滤器是整个服务器端中最早接收到所有请求的组件&#xff0c;此时&#xff0c;控制器等其它组件尚未运行&#xff0c;则不可以使用此前的“全局异常处理器”来处理解析JWT时的异常&#xff08;全局异常处理器…...

毕业设计 基于51单片机的指纹红外密码电子锁

基于51单片机的指纹红外密码电子锁1、项目简介1.1 系统框架1.2 系统功能2、部分电路设计2.1 STC89C52单片机最小系统电路设计2.2 矩阵按键电路电路设计2.3 液晶显示模块电路设计3、部分代码展示3.1 LCD12864显示字符串3.2 串口初始化实物图1、项目简介 选题指导&#xff0c;项…...

【JavaWeb】数据链路层协议——以太网 + 应用层协议——DNS

以太网 以太网不是一个具体的网络&#xff0c;而是一个技术标准&#xff0c;主要应用于数据链路层和物理层。 以太网数据帧结构 以太网的数据帧结构由三部分构成&#xff1a; 帧头 载荷 帧尾 其中的MAC地址是六位&#xff0c;这样就比IPV4所表示的地址大很多&#xff0c;…...

docker 容器安装 python jre

Dockerfile FROM python:2.7.11-alpine RUN mkdir /usr/local/java WORKDIR /usr/local/java # 5.更改 Alpine 的软件源为阿里云&#xff0c;默认从官方源拉取比较慢 RUN echo http://mirrors.aliyun.com/alpine/v3.10/main/ > /etc/apk/repositories && \ echo…...

Linux下将C++程序打包成动态库静态库方法

之前在这篇文章里介绍过动态库和静态库的理论部分,这篇文章主要介绍下实际的操作步骤&#xff1a; 静态链接库生成 gcc -c main.cpp -o main.o ar -rc libmain.a main.o sudo cp libmain.a /usr/local/lib 调用即可解释一下上面的命令&#xff1a;前两步生成了libmain.a sudo…...

Centos7 服务器基线检查处理汇总

1、服务器超时设置 问题描叙 TMOUT的值大于key2且小于等于{key2}且小于等于key2且小于等于{key1}视为合规 查看命令&#xff1a;export检测结果 超时时间:0处理方式 备份/etc/profile文件 cp /etc/profile /etc/profile_bak编辑profile文件 vim /etc/profile修改/新增 TMO…...

PaddleOCR遇到 lanms-neo问题处理

在window环境中安装PaddleOCR依赖是真的蛋疼&#xff0c;关键官方论坛里也都没有具体的解决方案。吐槽。。。吐槽。。。 我在 “windows安装lanms-neo问题处理”文章中看到lanms-neo问题全过程解决。个人觉得文档说明不是很细致&#xff0c;导致我按步骤执行&#xff0c;还是安…...

coreldraw2023安装包下载及新功能介绍

对于广告标识业来说 coreldraw这个软件&#xff0c;对我们来说绝对不陌生&#xff0c;我从2008年开始接触到广告制作&#xff0c;到现在已经13多年了&#xff0c;从一开始的coreldraw 9红色的热气球开始。就被这个强大的软件所吸引&#xff0c;他有强大的排榜功能已经对位图的处…...

Nginx 负载均衡服务失败场景

nginx可以配置负载均衡&#xff0c;我们可以通过配置实现nginx负载均衡。这里部署了两个服务producter-one和producter-one2。 upstream proxyproducter-one {server producter-one:8080 weight1;server producter-one2:8080 weight1;}# 访问其他服务server {listen 9090…...

开学季哪个电容笔好?2023口碑最好电容笔推荐

虽说苹果原装的电容笔非常好用&#xff0c;性能也非常不错&#xff0c;但由于价格昂贵&#xff0c;普通的学生是没办法购买的&#xff0c;再加上重量比较大&#xff0c;使用时间长了&#xff0c;难免会让人感觉到疲劳。如果仅仅是为了学习记笔记&#xff0c;那就没必要再去购买…...

经验分享-如何使用http调用chatGPT-3.5-turbo模型API

今天上午&#xff0c;就在工作群里收到了关于openAI发布chatGPT官方模型的消息分享。openAI这次的动作真的很快啊&#xff0c;没想到这么快就直接发布了chatGPT目前所使用的模型api。据Open AI在官方消息&#xff0c;本次开放了ChatGPT和Whisper的模型API&#xff0c;可以供用户…...

【C#】yyyy-MM-dd HH:mm:ss 时间格式 时间戳 全面解读超详细

C# 日期转字符串 实例化一个时间字符串 DateTimeFormatInfo dfInfonew DateTimeFormatInfo(); dfInfo.ShortDatePattern "yyyy/MM/dd hh:mm:ss:ffff"; DateTime dt Convert.ToDateTime("2019/07/01 18:18:18:1818", dfInfo);日期转字符串 string dat…...

基于神经网络的滑模鲁棒控制

目录 前言 1.双关节机械手臂模型 2.神经网络自适应律设计 3. 滑模控制律设计 4. 仿真分析 4.1 仿真模型 4.2 仿真结果 4.3 小结 5 学习问题 前言 上一篇文章我介绍了神经网络补偿的机理&#xff0c;只不过控制律不同&#xff0c;本章我们结合滑模理论设计控制律&#…...

YSYX学习记录(八)

C语言&#xff0c;练习0&#xff1a; 先创建一个文件夹&#xff0c;我用的是物理机&#xff1a; 安装build-essential 练习1&#xff1a; 我注释掉了 #include <stdio.h> 出现下面错误 在你的文本编辑器中打开ex1文件&#xff0c;随机修改或删除一部分&#xff0c;之后…...

什么是库存周转?如何用进销存系统提高库存周转率?

你可能听说过这样一句话&#xff1a; “利润不是赚出来的&#xff0c;是管出来的。” 尤其是在制造业、批发零售、电商这类“货堆成山”的行业&#xff0c;很多企业看着销售不错&#xff0c;账上却没钱、利润也不见了&#xff0c;一翻库存才发现&#xff1a; 一堆卖不动的旧货…...

macOS多出来了:Google云端硬盘、YouTube、表格、幻灯片、Gmail、Google文档等应用

文章目录 问题现象问题原因解决办法 问题现象 macOS启动台&#xff08;Launchpad&#xff09;多出来了&#xff1a;Google云端硬盘、YouTube、表格、幻灯片、Gmail、Google文档等应用。 问题原因 很明显&#xff0c;都是Google家的办公全家桶。这些应用并不是通过独立安装的…...

[10-3]软件I2C读写MPU6050 江协科技学习笔记(16个知识点)

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16...

ServerTrust 并非唯一

NSURLAuthenticationMethodServerTrust 只是 authenticationMethod 的冰山一角 要理解 NSURLAuthenticationMethodServerTrust, 首先要明白它只是 authenticationMethod 的选项之一, 并非唯一 1 先厘清概念 点说明authenticationMethodURLAuthenticationChallenge.protectionS…...

EtherNet/IP转DeviceNet协议网关详解

一&#xff0c;设备主要功能 疆鸿智能JH-DVN-EIP本产品是自主研发的一款EtherNet/IP从站功能的通讯网关。该产品主要功能是连接DeviceNet总线和EtherNet/IP网络&#xff0c;本网关连接到EtherNet/IP总线中做为从站使用&#xff0c;连接到DeviceNet总线中做为从站使用。 在自动…...

Mobile ALOHA全身模仿学习

一、题目 Mobile ALOHA&#xff1a;通过低成本全身远程操作学习双手移动操作 传统模仿学习&#xff08;Imitation Learning&#xff09;缺点&#xff1a;聚焦与桌面操作&#xff0c;缺乏通用任务所需的移动性和灵活性 本论文优点&#xff1a;&#xff08;1&#xff09;在ALOHA…...

Java线上CPU飙高问题排查全指南

一、引言 在Java应用的线上运行环境中&#xff0c;CPU飙高是一个常见且棘手的性能问题。当系统出现CPU飙高时&#xff0c;通常会导致应用响应缓慢&#xff0c;甚至服务不可用&#xff0c;严重影响用户体验和业务运行。因此&#xff0c;掌握一套科学有效的CPU飙高问题排查方法&…...

Redis的发布订阅模式与专业的 MQ(如 Kafka, RabbitMQ)相比,优缺点是什么?适用于哪些场景?

Redis 的发布订阅&#xff08;Pub/Sub&#xff09;模式与专业的 MQ&#xff08;Message Queue&#xff09;如 Kafka、RabbitMQ 进行比较&#xff0c;核心的权衡点在于&#xff1a;简单与速度 vs. 可靠与功能。 下面我们详细展开对比。 Redis Pub/Sub 的核心特点 它是一个发后…...

【Android】Android 开发 ADB 常用指令

查看当前连接的设备 adb devices 连接设备 adb connect 设备IP 断开已连接的设备 adb disconnect 设备IP 安装应用 adb install 安装包的路径 卸载应用 adb uninstall 应用包名 查看已安装的应用包名 adb shell pm list packages 查看已安装的第三方应用包名 adb shell pm list…...