瑞吉外卖-笔记1

文章目录

一、后台登录功能post

1. 实现登录

  • 将页面提交的密码进行MD5加密处理
  • 根据页面提交的用户名username查询数据库
  • 如果没有查询到则返回登录失败结果
  • 密码比对,如果不一致则返回登录结果
  • 查看员工状态,如果已为禁用状态,则返回员工已禁用结果
  • 登录成功,将员工id存入session并返回登录成功结果

2. 退出功能

3. 完善登录功能(过滤器)

检验是否已经登录,若没有登录,则跳转到登录页面

4. 技术总结

密码加密md5技术
利用mybatis-plus进行数据库查询
HttpServletRequest的session操作
过滤器Filter

二、新增员工信息post

1. 新增员工

2. 处理已存在账号的异常(异常处理器)

3. 技术总结

session操作
mybatis-plus对数据库增加数据,save方法
异常处理:@ControllerAdvice和@ExceptionHandler

三、分页查询

1. mybatis-plus配置类

2. controller类

3. 技术总结

mybatis-plus实现分页查询

四、修改员工状态信息

1. 在controller中创建update方法

2. 编写消息转换器Messager Converter

  • 点击编辑按钮时,页面跳转到add.html,并在url中携带参数[员工id]
  • 在add.html页面获取url中的参数[员工id]
  • 发送ajax请求,请求服务端,同时提交员工id参数
  • 服务端接收请求,根据员工id查询员工信息,将员工信息以json形式响应给页面
  • 页面接收服务端响应的json数据,通过VUE的数据绑定进行员工信息回显
  • 点击保存按钮,发送ajax请求,将页面中的员工信息以json方式提交给服务端
  • 服务端接收员工信息,并进行处理,完成后给页面响应
  • 页面接收到服务端响应信息后进行相应处理
    第五步出现问题
  • 问题描述
    js对long型数据进行处理时丢失精度,导致提交的id和数据库中的id不一致。
    我们可以在服务端给页面响应json数据时进行处理,将long型数据统一转为String字符串

五、编辑员工信息

  • 核心问题
    ----之所以可以修改是因为前面已经写了update方法 点击保存的时候 默认用了update方法
    获取url中的参数id
  • 整体流程
  • 点击编辑按钮时,页面跳转到add.html,并在url中携带参数[员工id]
  • 在add.html页面获取url中的参数[员工id]
  • 发送ajax请求,请求服务端,同时提交员工id参数
  • 服务端接收请求,根据员工id查询员工信息,将员工信息以json形式响应给页面
  • 页面接收服务端响应的json数据,通过VUE的数据绑定进行员工信息回显
  • 点击保存按钮,发送ajax请求,将页面中的员工信息以json方式提交给服务端
  • 服务端接收员工信息,并进行处理,完成后给页面响应
  • 页面接收到服务端响应信息后进行相应处理
    前端做的就是把参数id拿出来交给服务端
    服务端就是id查询数据库,然后把信息以json的方式交给服务端

六、公共字段自动填充

1. 基本操作

employee实体类加上@TableField
注释掉原来代码对公共字段的设置
编写MyMetaObjectHandler类

2.使用threadlocal完善功能

  • 原理
    在学习ThreadLocal之前,我们需要先确认一个事情,就是客户端发送的每次http请求,对应的在服务端都会分配一个新的线程来处理,在处理过程中涉及到下面类中的方法都属于相同的一个线程:
    1.LoginCheckFilter的doFilter方法
    2.EmployeeController的update方法
    3.MyMetaObjectHandler的updateFill方法
  • ThreadLocal常用方法:
    public void set(T value) 设置当前线程的线程局部变量的值
    public T get() 返回当前线程所对应的线程局部变量的值
  • 流程
    我们可以在LoginCheckFilter的doFilter方法中获取当前登录用户id,并调用ThreadLocal的set方法来设置当前线程的线程局部变量的值(用户id),然后在MyMetaObjectHandler的updateFill方法中调用ThreadLocal的get方法来获得当前线程所对应的线程局部变量的值(用户id)。

七、新增菜品分类

- 流程
实体类Category(直接从课程资料中导入即可)
Mapper接口CategoryMapper
业务层接口CategoryService
业务层实现类CategoryServicelmpl
控制层CategoryController

八、分页查询菜品

- 流程
页面发送ajax请求,将分页查询参数(page、pageSize)提交到服务端
服务端Controller接收页面提交的数据并调用Service查询数据
Service调用Mapper操作数据库,查询分页数据
Controler将查询到的分页数据响应给页面
页面接收到分页数据并通过ElementUI的Table组件展示到页面上

九、删除分类

  • 需求分析
    在分类管理列表页面,可以对某个分类进行删除操作
    需要注意的是当分类关联了菜品或者套餐时,此分类不允许删除

1. 基本删除功能

2. 完善删除功能

(1)实体类Dish和Setmeal(从课程资料中复制即可)
(2)Mapper接口DishMapper和setmealMapper
(3)Service接口DishService和SetmealService
(4)Service实现类DishServicelmpl和SetmealServicelmpl

  • 在categoryService中自定义remove方法
    逻辑:依次判断是否和菜品、套餐是否关联,采用mybatis-plus构造条件查询器
  • 若关联,自定义异常抛出
    继承runningtime异常,
    在全局异常处理中,对异常处理

十、文件上传与下载

1. 定义

  • 文件上传,也称为upload,是指将本地图片、视频、音频等文件上传到服务器上,可以供其他用户浏览或下载的过程
  • 文件下载,也称为download,是指将文件从服务器传输到本地计算机的过程
  • 通过浏览器进行文件下载,通常有两种表现形式:
    以附件形式下载,弹出保存对话框,将文件保存到指定磁盘目录
    直接在浏览器中打开,本质上就是服务端将文件以流的形式写回浏览器的过程。
  • MultipartFile
    MultipartFile是spring类型,代表HTML中form data方式上传的文件,包含二进制数据+文件名称。
    MultipartFile后面的参数名必须为file,因为需要和前端页面的name保持一致,否则不会生效

2. 文件上传

postmapping
transferTo把原来的文件转存

3. 文件下载

  • FileInputStream流
    被称为文件字节输入流,意思指对文件数据以字节的形式进行读取操作如读取图片视频等
    - ServletOutputStream outputStream = response.getOutputStream();
    通过HttpServletResponse的getOutputStream()创建一个输出流,那么servlet容器就会把response对象交给服务器,服务器将response对象中的内容拆解响应给客户端。
  • response.setContentType
    这个方法设置发送到客户端的响应的内容类型
    InputStream.read(byte[])参数详解
  • fileInputStream.read(bytes)) != -1
    byte数组作为一个缓冲区,每次存入和缓冲区一样大小(byte.length)的数据。当然实际存入的数据是一个个十进制的整数。整个流程是这样子的,文件 -> 输入字节流(二进制整数) -> 十进制整数(通过read(byte[])实现)
    输入字节流in按照byte数组缓冲区每4个字节循环一次进行read操作,直到读到-1这个整数(-1是一个标识,就是文件数据的末尾)。
  • outputStream.write(bytes,0,len);
    java.io.OutputStream.write(byte[] b, int off, int len) 方法从指定的字节数组开始到当前输出流关闭写入len字节。一般的合约write(b, off, len),一些在数组b中的字节写入,以便输出流;元素b[off]是写入的第一个字节和b[off+len-1]是写的这个操作的最后一个字节。

十一、新增菜品

1. 整体需求

后台系统中可以管理菜品信息,通过新增功能来添加一个新的菜品
在添加菜品时需要选择当前菜品所属的菜品分类,并且需要上传菜品图片
在移动端会按照菜品分类来展示对应的菜品信息。

2. 准备工作

实体类DishFlavor(直接从课程资料中导入即可,Dish实体前面课程中已经导入过了)
Mapper接口DishFlavorMapper
业务层接口DishFlavorService
业务层实现类DishFlavorServicelmpl
控制层DishController

3. 启动项目,进入菜品管理,点击菜品分类下拉框,成功获得数据

mybatis-plus查询

4. 接收页面提交的数据

因为Dish实体类不满足接收flavor参数,即需要导入DishDto,用于封装页面提交的数据

5. 保存数据到菜品表和菜品口味表

在保存数据到菜品表和菜品口味表的过程中,我们需要对保存到菜品口味表的数据做相应的处理
取出dishDto的dishId,通过stream流对每一组flavor的dishId赋值
保存菜品口味到菜品数据表
需要重写dishservice的save方法

十二、菜品信息分页查询

与前面的不同在于
在前端页面发现菜品分类对应的prop属性名为categoryName
但我们在响应的数据当中并没有发现categoryName字段
在之前我们创建了DishDto类,发现类中的属性名正好和前端的属性名对应
因此需要把Dish的属性拷贝到DishDto里面 重新写
注意record对象封装的是每一个dish对象 需要改写为dishdto
前端需要的字段 后端的实体类必须满足
多表操作需要加事务管理

十三、修改菜品

  • 页面发送ajax请求,请求服务端获取分类数据,用于菜品分类下拉框中数据展示(已完成)
  • 页面发送ajax请求,请求服务端,根据id查询当前菜品信息,用于菜品信息回显
  • 页面发送请求,请求服务端进行图片下载,用于页图片回显(已完成)
  • 点击保存按钮,页面发送ajax请求,将修改后的菜品相关数据以json形式提交到服务端
    1和3已经完成

十四、新增套餐

  • 页面(backend/page/combo/add.html)发送ajax请求,请求服务端获取套餐分类数据并展示到下拉框中(已完成)
  • 页面发送ajax请求,请求服务端,获取菜品分类数据并展示到添加菜品窗口中
  • 页面发送ajax请求,请求服务端,根据菜品分类查询对应的菜品数据并展示到添加菜品窗口中
  • 页面发送请求进行图片上传,请求服务端将图片保存到服务器(已完成)
  • 页面发送请求进行图片下载,将上传的图片进行回显(已完成)
  • 点击保存按钮,发送ajax请求,将套餐相关数据以json形式提交到服务端

1.根据菜品分类查找数据回显

在这里插入图片描述

2. 保存信息到数据库

十五、 套餐信息分页查询

  • 页面(backend/page/combo/list.html)发送ajax请求,将分页查询参数(page、pageSize、name)提交到服务端,获取分页数据
  • 页面发送请求,请求服务端进行图片下载,用于页面图片展示

十六、删除套餐

1. 需求分析

在套餐管理列表页面点击删除按钮,可以删除对应的套餐信息
也可以通过复选框选择多个套餐,点击批量删除按钮一次删除多个套餐
注意,对于状态为售卖中的套餐不能删除,需要先停售,然后才能删除。

2. 分析

观察删除单个套餐和批量删除套餐的请求信息可以发现,两种请求的地址和请求方式都是相同的
不同的则是传递的id个数,所以在服务端可以提供一个方法来统一处理。
删除SetMeal表
删除SetMealDish表
起售停售功能没有写

十七、移动端登录

在登录页面(front/page/login.html)输入手机号,点击【获取验证码】按钮,页面发送ajax请求,在服务端调用短信服务API给指定手机号发送验证码短信**(不使用短信服务,手动查看验证码,并输入)**
在登录页面输入验证码,点击【登录】按钮,发送ajax请求,在服务端处理登录请求

  1. 导入User类相关
  2. 过滤器放行
  3. 过滤器检测是否登录
  4. 获取验证码
  5. 登录

十八、新增地址簿

常规新增
新增默认地址:先把所有设置0 再改指定位1

十九、菜品展示

根据分类展示菜品和套餐 如果有口味点击规格能修改

菜品部分

  • 页面(front/index.html)发送ajax请求,获取分类数据(菜品分类和套餐分类)
    改前端代码 前端写死了 需要同时 购物车和菜品分类成功 才能渲染 为了方便可以先注释掉购物车部分
    后端的再categorycontroller里面已经写了list方法

  • 页面发送ajax请求,获取第一个分类下的菜品或者套餐

后端的再dishcontroller里面已经写了list方法,但是没有实现规格 可选口味功能 需要改写

套餐部分

setmeal 写一个 list方法

二十、添加购物车

1. 需求

  • 移动端用户可以将菜品或者套餐添加到购物车
  • 对于菜品来说,如果设置了口味信息,则需要选择规格后才能加入购物车
  • 对于套餐来说,可以直接点击将当前套餐加入购物车
  • 在购物车中可以修改菜品和套餐的数量,也可以清空购物车。

2. 代码

设置用户id
判断是菜品还是套餐
判断菜品或套餐是否已存在

二十一、查看购物车和清空购物车

把前端代码改好
注意登录用户要保持一致
根据用户id查表

考虑问题 有没有 点减号 删除信息 减少数量

二十二、用户下单

在购物车中点击去结算按钮,页面跳转到订单确认页面
在订单确认页面,发送ajax请求,请求服务端获取当前登录用户的默认地址
在订单确认页面,发送ajax请求,请求服务端获取当前登录用户的购物车数据
在订单确认页面点击去支付按钮,发送ajax请求,请求服务端完成下单操作…未完成
//获取当前用户id
//查询当前用户的购物车数据
//查询用户数据
//查询地址数据
//向订单表插入数据,一条数据
//向订单明细表插入数据,多条数据
//清空购物车数据

二十三、优化部分:前后端分离

在这里插入图片描述

1. YApi

前面的定制接口部分,定义了接口规范,给前后端人员看,同时可以实现模拟作用

2. Swagger

配置好相关的东西 可以导出你项目中所有的接口信息

3. 项目部署 ****

在这里插入图片描述

192.168.138.100(服务器A)
Nginx:部署前端项目、配置反向代理
MySql:主从复制结构中的主库
192.168.138.101(服务器B)
jdk:运行java项目
git:版本控制工具
maven:项目构建工具
jar:Spring Boot 项目打成jar包基于内置Tomcat运行
MySql:主从复制结构中的从库
172.17.2.94(服务器C)
Redis:缓存中间件

4.反向代理

在这里插入图片描述
在这里插入图片描述
上面第一张图 为访问的地址,对应的是代理服务器
通过反向代理配置,对url进行重写后,跳转到另外一个服务器

优化部分:Mysql主从复制、读写分离(对移动端)

0. 原因分析

在这里插入图片描述

1. 主从复制

  • 介绍
    在这里插入图片描述
    主从复制是读写分离的基础

https://blog.csdn.net/qq_40492693/article/details/124793705

  • 配置过程
    提前准备两台服务器
  • 主库
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
  • 从库
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    这里的bin 和 los两个参数必须严格对照前面master的
    在这里插入图片描述

2. 读写分离

java怎么知道主库执行写操作,从库执行读操作
在这里插入图片描述
配置文件修改
在这里插入图片描述
在这里插入图片描述

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值