做完瑞吉外卖项目的一点笔记和源码

news2024/11/24 12:32:39

源码在 https://gitee.com/pluto8/take-out

一、软件开发整体介绍

1、软件开发流程

  • 需求分析 :产品原型,需求规格说明书(文档形式)
  • 设计:产品文档、UI界面设计、概要设计、详细设计、数据库设计
  • 编码:项目代码,单元测试
  • 测试:测试用例,测试报告
  • 上线运维:软件环境安装,配置

2、角色分工:

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

3、软件环境

  • 开发环境(development):开发人员在开发阶段使用的环境,一般外部用户无法访问
  • 测试环境(testing):专门给测试人员使用的环境,用于测试项目,一般外部用户无法访问
  • 生产环境(production):即线上环境,正式提供对外服务的环境

二、外卖项目介绍

1、项目介绍

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

2、产品原型(产品经理提供)

产品原型,就是一款产品成型之前的一个简单的框架,就是将页面的排版布局展现出来,使产品的初步构思有一个可视化的展示。通过原型展示,可以更加直观的了解项目的需求和提供的功能。产品原型主要用于展示项目的功能,并不是最终的页面效果

3、技术选型

  • 用户层:H5,VUE.JS,ElementUI,微信小程序
  • 网关层:Nginx
  • 应用层:SpringBoot,SpringMVC,Spring Session,Spring,Swagger,lombok
  • 数据层:Mysql,Mybatis,MybatisPlus,Redis
  • 工具:git,maven,junit

4、功能架构

在这里插入图片描述

5、角色

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

三、环境搭建

1、数据库环境搭建

导入sql文件

在这里插入图片描述

2、maven项目搭建

  • 创建maven项目,导入pom.xml和application.yml

  • 直接将前端后端页面复制在resource下,会出现tomcat找不到静态资源页面的情况(报404)

可以通过配置文件来解决。创建一个WebMvcConfig

package com.xqh.reggie.config;

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
     */
    @Override
    protected void addResourceHandlers(ResourceHandlerRegistry registry) {
        log.info("开始进行静态资源映射...");
        registry.addResourceHandler("/backend/**").addResourceLocations("classpath:/backend/");
        registry.addResourceHandler("/front/**").addResourceLocations("classpath:/front/");

    }
}

四、后台登录功能开发

1、需求分析
1)页面原型展示

2)登录页面展示

页面请求—>controller—>service—>Mapper—>DB

3)封装结果类。通用返回结果,服务端响应的数据最终都会封装成此对象

4)controller中创建登录方法

逻辑:页面提交的密码进行md5加密—>根据页面提交的用户名查询数据库,查询不到则返回登录失败,查询到---->密码比对,错误则登录失败,正确---->查看员工状态,已禁用则返回已禁用状态,正常—>登录成功,将员工id存入Session并返回登陆成功结果。

五、后台退出功能

1、处理逻辑:清理Session中的用户id,返回结果

六、员工管理开发

1、完善登录功能

存在一个问题:用户如果不登录,直接访问系统首页面,照样可以正常访问,这是不合理的。

我们希望看到的是,只有登录成功后才可以访问系统中的页面,如果没有登录则跳转到登录页面

如何实现?使用过滤器或者拦截器

2、新增员工

  • 有个问题:当我们在新增员工输入账号,输入之前数据库已经存在的账号,由于表中对这个字段做了唯一约束,所以程序会报错抛出异常
  • 解决:异常捕获。try…catch捕获异常,或者做全局异常捕获

使用异常处理器进行全局异常捕获

总结:

  • 根据产品原型明确业务需求-----实现添加员工,跳转路由、携带参数等都可以在前端页面中找到
  • 通过分析数据的流传过程和数据格式
  • 通过debug断点调试跟踪程序执行过程

3、员工信息分页查询

业务逻辑:

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

4、禁用、启用员工账号

只有admin账户可以使用这个功能。其他用户不显示这个功能(这主要是前端实现,if判断)

出现问题:js对long型数据进行处理时丢失精度,导致提交的id和数据库的id不一致,如何解决?

我们可以在服务端给页面响应json数据时进行处理,将long型数据统一转为String字符串

具体实现步骤:

  • 提供对象转换器JacksonObjectMapper,基于Jackson进行java对象到json数据的转换
  • 在webMvcConfig配置类中扩展SpringMVC的消息转换器,在此消息转换器中使用提供的对象转换器进行java对象到json数据的转换。

5、编辑员工信息

  1. 需求分析:在员工管理列表页面点击编辑按钮,跳转到编辑页面,在编辑页面回显员工信息并进行修改,最后点击保存按钮完成编辑操作
  2. 修改和添加共用一个接口保存到数据库中

七、分类管理开发

1、公共字段自动填充

在员工管理功能开发时,新增员工时要设置创建时间、更新时间、创建人、更新人,这些属于公共字段,很多表中都有这些字段,那么能不能对于这些公共字段在某个地方统一处理,来简化开发呢?对于此,MyBatisPlus提供了公共字段自动填充 功能

  • 实现步骤:

    • 在实体类的属性上加入@TableField注解,指定自动填充的策略
    • 按照框架要求编写元数据对象处理器,在此类中统一为公共字段赋值,此类需要实现MetaObjectHandler接口。在这个类中写需要自动填充字段
  • 如何在MyMetaObjectHandler类中获取当前登录用户的id呢?

首先,因为在MyMetaObjectHandler类中是不能获得HttpSession对象的,所以我们不能通过session来获取到登录用户的id。可以使用ThreadLocal来解决此问题,它是jdk中提供的一个类。

需要先确认一个事情,就是客户端每次发送的http请求,对应的在服务端都会分配一个新的线程来处理 。当发送编辑请求时,同时经过下面三个方法,这三个方法对应的线程id是相同的。

:LoginCheckFilter的doFilter方法

:EmployeeController中的update方法

:MyMetaObjectHandler的updateFill方法

一次请求对应的线程id是相同的!

  • 什么是ThreadLocal

ThreadLocal并不是一个Thread,而是Thread的局部变量,当使用ThreadLocal维护变量时,ThreadLocal为每个使用该变量的线程提供独立的变量副本,所以每一个线程都可以独立的改变自己的副本,而不会影响其他线程所对应的副本。ThreadLocal为每个线程提供单独一份存储空间,具有线程隔离的效果,只有在线程内才能获取到对应的值,线程外则不能访问。

  • 我们可以在LoginCheckFilter的doFilter方法中获取当前登录用户id,并调用ThreadLocal的set方法来设置当前线程的线程局部变量的值(用户id),然后在MyMetaObjectHandler的updateFill方法中调用ThreadLocal的get方法来获取当前线程所对应的线程局部变量的值(用户id)

2、新增分类

需求分析:后台系统中可以管理分类信息,分类包括两种类型,分别是菜品分类和套餐分类。可以在后台系统的分类管理页面分别添加菜品分类和套餐分类。新增菜品分类、新增套餐分类。之后的菜品管理和套餐管理,是要关联上这里有的菜品和套餐。

3、分类信息分页查询

构建分页构造器,构造条件构造器,执行分页查询

4、删除分类

  • 需求分析:

在分类管理列表页面,可以对某个分类进行删除操作,需要注意的是,当分类关联了菜品或者套餐时,此分类不允许删除。即菜品和套餐有没有关联上级菜品分类和上级套餐分类,如果有关联,则这个上级菜品分类或上级套餐分类是不允许删除的,没有关联下级的分类才可以被删除。

5、修改分类

八、菜品管理开发

1、文件上传和下载

  • 文件上传

服务端要接收客户端页面上传的文件,通常都会使用Apache的两个组件: commons-fileupload,commons-io

本质都是对流的操作。Spring框架在spring-web包中对文件上传进行了封装,大大简化了服务端代码,我们只需要在Controller的方法中声明一个MultipartFile类型的参数即可接收上传的文件。

  • 文件下载

是指从服务器传输到本地计算机的过程。通过浏览器进行文件下载,通常有两种表现形式:以附件形式下载,弹出保存对话框,将文件保存到指定磁盘目录;直接在浏览器中打开(比如直接显示某个菜品的图片)

通过浏览器进行文件下载,本质上就是服务端将文件以流的形式写回浏览器的过程

2、新增菜品

需求分析:

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

一步是做add业务,一步是要根据type查询分类列表

  • 新增菜品时,菜品信息存到dish表,而口味则要存到dishFlavor表,因此在写controller时,参数不能直接写Dish,因为flavor字段在dish中并没有。对于这种无法概括所有传来参数的情况,需要另外创建一个dto,可以包括传来的数据的所有字段,将这个作为保存业务的参数

在这里插入图片描述

3、更新菜品

同样是对两张表进行操作。

九、套餐管理业务开发

1、新增套餐

  • 通过新增套餐功能来添加一个新的套餐,在添加套餐时需要选择当前套餐所属的套餐分类和包含的菜品,并且需要上传套餐对应的图片,在移动端会按照套餐分类来展示对应的套餐
  • 进入添加套餐页面,前端会回显套餐分类。这是直接请求后后端接口根据type查询分类列表,这个功能之前在开发添加菜品时已经实现。所以这里前端直接调用这个接口,就可以得到已经有的套餐分类

2、分页查询

3、删除套餐

删除单个套餐和批量删除套餐,这两种请求的地址和请求方式都是相同的。不同的则是传递的id的个数,所以在服务端可以提供一个方法来统一处理

十、短信服务

1、阿里云短息服务–介绍

阿里云短信服务是广大企业客户快速触达手机用户所优选使用的通信能力,调用API或用群发助手,即可发送验证码、通知类和营销类短信。

应用场景:

  • 验证码
  • 短信通知
  • 推广短信

2、设置短信签名

短信签名是短信发送者的署名,表示发送方的身份

3、设置模板管理

4、需求分析

为了方便用户登录,移动端通常都会提供通过手机验证码登录的功能。手机验证码登录的优点:

  • 方便快捷,无需注册,直接登录
  • 使用短信验证码作为登录凭证,无需记忆密码
  • 安全

十一、菜单列表

十二、购物车

十三、用户下单

十四、后台中订单管理

十五、前后台交互

后台控制订单的状态,例如从已下单到已派送再到已完成,而前台用户端,会显示订单已派送,已完成,当显示已完成,用户端可以直接点击再来一单,可以将订单再次添加到购物车中

十六、

测试

1、添加员工—添加一个测试账号,测试后面的所有功能 test61 123456

2、移动端—注册一个新号码 15083555837 查看数据库是否正常

3、员工管理

  • 新增
  • 编辑
  • 查询

4、分类管理

  • 新增分类—菜品,套餐
  • 修改分类
  • 删除分类

5、菜品管理

  • 批量停售/批量启售
  • 批量删除
  • 修改
  • 新建菜品

6、套餐管理

  • 批量停售/启售
  • 批量删除
  • 修改
  • 新建套餐

7、订单管理

  • 显示用户端传过来的订单
  • 查看订单详情
  • 派送
  • 完成

8、用户端–查看菜品

  • 点击套餐图片可以看到具体的套餐菜品

9、加入购物车

  • 添加
  • 减少
  • 清空

10.下单

11、查看订单,查询订单状态

12、订单已完成,可以再来一单

代码优化

  1. 问题:用户数量多,系统访问量大,频繁访问数据库,系统性能下降,用户体验差
  2. 主要缓存一些需要频繁访问数据库的数据和不会改变的数据:缓存短信验证码、缓存菜品数据、缓存套餐数据

通过redis缓存

缓存短信验证码

  • 将随机生成的验证码缓存到Redis中,并设置有效期为5分钟
  • 从Redis中获取缓存的验证码,如果登录成功则删除redis中的验证码

缓存菜品数据

  • 问题:服务端每次点击分类,后端都要查询数据库,当访问人多或者频繁点击分类时,需要频繁查询数据库,效率低,查询速度慢。高并发情况下,频繁查询数据库会导致系统性能下降,服务端响应时间增长。
  • 先从Redis中获取菜品数据,如果有则直接返回,无需查询数据库;如果没有则查询数据库,并将查询到的菜品数据放入Redis
  • 加入清理缓存的逻辑。在使用缓存过程中,要注意保证数据库中的数据和缓存中的数据一致,如果数据库中的数据发生变化,需要及时清理缓存数据

缓存菜品是通过菜品分类和状态来动态创建一个key

通过Spring cache缓存

  • Spring Cache是一个框架,实现了基于注解的缓存功能,只需要简单地加一个注解,就能实现缓存功能

在SpringBoot项目中使用Spring Cache的操作步骤(使用Redis缓存技术)

  • 导入maven依赖
  • 配置application.yml
  • 启动类上加注解
  • 在controller中方法上加注解

缓存套餐数据

  • 移动端套餐查看功能,对应的服务端方法,此方法会根据前端提交的查询条件进行数据库查询操作,在高并发情况下,频繁查询数据库会导致系统性能下降,服务端响应时间增长,现在需要对此方法进行缓存优化,提高系统的性能。

二、数据库优化

读写分离

面对日益增加的系统访问量,数据库的吞吐量面临着巨大瓶颈,对于同一时刻有大量并发读操作和较少写操作类型的应用系统来说,将数据库拆分为主库和从库,主库负责处理事务性的增删改操作,从库负责处理查询操作,能够有效的避免由数据更新导致的行锁,使得整个系统的查询性能得到极大的改善。

  • 问题:读和写所有压力都由一台数据库承担,压力大,数据库服务器磁盘损坏则数据丢失,单点故障。

在这里插入图片描述

MySQL主从复制

  • 介绍:

MySQL主从复制是一个异步的复制过程,底层是基于MySQL数据库自带的二进制日志功能。就是一台或多台MySQL数据库(slave,从库)从另一台MySQL数据库(master,主库)进行日志的复制然后再解析日志并应用到自身,最终实现从库的数据和主库的数据保持一致。MySql主从复制是MySQL数据库自带功能,无需借助第三方工具。

  • MySQL复制过程分为三步:

master将改变记录到二进制日志

slave将master的binary log拷贝到它的中继日志(relay log)

slave重做中继日志中的事件,将改变应用到自己数据库中

三、Nginx

  • 静态资源处理
  • 反向代理
  • 负载均衡

四、前后端分离开发

开发流程:

在这里插入图片描述

前端技术栈:

开发工具:

  • VScode
  • hbuilder

技术框架:

  • nodeJS
  • vue
  • elementUI
  • mock
  • webpack

YApi

  • 介绍:

    YApi是高效、易用、功能强大的api管理平台,旨在为开发、产品、测试人员提供更优雅的接口管理服务。可以帮助开发者轻松、发布、维护API,YApi还为用户提供了优秀的交互体验,开发人员只需利用平台接口的接口数据写入工具以及简单的点击操作就可以实现接口的管理。

    YApi让接口开发更简单高效,让接口的管理更具可读性、可维护性,让团队协作更合理。

也可以用api

Swagger

  • 介绍

使用swagger你只需要按照它的规范去定义接口及接口相关的信息,再通过Swagger衍生出来的一系列项目和工具,就可以做到生成各种格式的接口文档,以及在线接口调试页面等等。

  • knife4j

是为java mvc框架集成Swagger生成API文档的增强解决方案。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/616894.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

STM32 实现简单定时任务调度器,支持动态添加临时任务

代码实现和硬件没关系,所以并不限于STM32,Arduino 之类的其他地方也能用,只要有一个能获取时间的函数就行,或者说,只要有一个会随着时间自动增加的变量就行,时间单位无所谓,所以确实想的话&…

菜单权限验证和分页功能

权限验证 1.创建数据库,然后测试菜单权限的联合查询语句; 2.创建项目,导入jar包,配置实体类和工具类 3.完成登录功能,当输入用户名和密码正确后跳转到框架页面 编写导航页(top.jsp)和内容页…

Vscode +Msys2配置C/C++环境

目录 前期准备:Step1: 安装Msys2Step2: 安装编译器Step3: 安装VScodeStep4: 配置VScodec_cpp_properties.jsonlaunch.jsontasks.json Step5: 创建C/C项目 前期准备: 首先,你需要下载并安装以下软件: VsCode:https://c…

软件需求分析-复习指南

这里写自定义目录标题 下面是一段用例的描述,针对一个汽车保险系统中“将一辆新车加入一个已有保单中”的用例。请你为其设计: (1) 领域模型(要求给出建立过程)(20分); (2) 活动图 (14分); (3) 顺序图 (14分…

linux内核open文件流程

打开文件流程 本文基本Linux5.15 当应用层通过open api打开一个文件,内核中究竟如何处理? 本身用来描述内核中对应open 系统调用的处理流程。 数据结构 fdtable 一个进程可以打开很多文件, 内核用fdtable来管理这些文件。 include/linu…

为项目添加 HibernateValidator

HibernateValidatorhttps://hibernate.org/validator/ 引入依赖项 首先&#xff0c;确保已将Hibernate Validator添加到Maven或Gradle依赖项中&#xff1a; <!-- Maven 依赖 --> <dependency><groupId>org.hibernate.validator</groupId><artifa…

三年功能测试经验,投了几百份简历,为什么没有收到offer?

软件测试行业3年多经验&#xff0c;学历大专自考本科&#xff0c;主要测试方向web&#xff0c;PC端&#xff0c;wap站&#xff0c;小程序公众号都测试过&#xff0c;app也测过一些&#xff0c;C端B端都有&#xff0c;除功能外&#xff0c;接口性能也有涉猎&#xff0c;但是不能…

kafka--多易杰哥讲解

Kafka是一种分布式的流式数据平台&#xff0c;广泛应用于实时流数据处理和消息系统。它可以让处理数据的应用程序能够处理高流量的数据流&#xff0c;同时提供可靠性和可扩展性。 【多易教育】-Kafka文档 1.基本概念 1.1什么是kafka Kafka 最初是由 LinkedIn 即领英公司…

教你如何用fiddler抓取https(详细教程)

对于想抓取HTTPS的测试初学者来说&#xff0c;常用的工具就是fiddler&#xff0c;可是在初学时&#xff0c;大家对于fiddler如何抓取HTTPS真是伤了脑筋&#xff0c;可能你一步步按着网上的帖子成功了&#xff0c;那当然是极好的&#xff0c;有可能没有成功&#xff0c;这时候你…

前端基础(JavaScript)——基础语法(变量,分支...) Json对象【重要】 函数定义 事件(未完待续)

目录 引出JS是啥&#xff0c;能干啥基础语法1.变量----let2.怎么打印---console3.if条件分支--啥都可以是条件例子&#xff1a;输入框&#xff0c;打印输入和未输入4.数组push 和 splice&#xff08;2&#xff09;splice&#xff0c;3个参数&#xff0c;索引开始、删除几个&…

广域网技术

广域网互连一般采用在网络层进行协议转换的方法实现。时延网关&#xff0c;更确切的说是路由器。 无连接的网际互连&#xff1a; 在网际层提供路由信息的是路由表&#xff0c;每个站或者路由器中都有一个网际路由表&#xff0c;表的每一行说明一个目标站对应的路由器地址。 路…

如何在Ubuntu20.04中配置 libarchive 库

libarchive 是什么&#xff1f; libarchive是一个开源的压缩和归档库。 它支持实时访问多种压缩文件格式&#xff0c;比如7z、zip、cpio、pax、rar、cab、uuencode等&#xff0c;因此应用十分广泛。 举个例子&#xff0c;我写了一段代码&#xff0c;想要解压一个压缩包&#…

HARVEST基音检测算法

Harvest: A high-performance fundamental frequency estimator from speech signals一种基于语音信号的高性能基频估计算法 Harvest的独特之处在于可以获得可靠的F0轮廓&#xff0c;减少了将浊音部分错误地识别为清音部分的错误。 它包括两个步骤:估计F0候选点和在这些候选点…

17JS08——函数

函数 一、函数的概念二、函数的使用2.1 声明函数2.2 调用函数2.3 函数的封装 三、函数的参数3.1 形参和实参3.2 形参和实参个数不匹配问题3.3 小结 四、函数的返回值4.1 return语句4.2 return终止函数4.3 break、continue、return的区别4.4 案例 五、arguments的使用案例1&…

案例30:基于Springboot酒店管理系统开题报告设计

博主介绍&#xff1a;✌全网粉丝30W,csdn特邀作者、博客专家、CSDN新星计划导师、java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精彩专…

Java-多线程解析1

一、线程的描述&#xff1a; 1、线程是一个应用程序进程中不同的执行路径比例如&#xff1a;一个WEB服务器&#xff0c;能够为多个用户同时提供请求服务&#xff1b;而 -> 进程是操作系统中正在执行的不同的应用程序,比如&#xff1a;我们可以同时打开系统的word和游戏 2、多…

Tomcat优化及Nginx、tomcat动静分离配置

Tomcat优化及Nginx、tomcat动静分离配置 一、Tomcat优化1、操作系统优化&#xff08;内核参数优化&#xff09;2、Tomacat配置文件优化3、Java虚拟机&#xff08;JVM&#xff09;调优 二、Nginx、tomcat动静分离配置(七层代理)三、四层代理 一、Tomcat优化 Tomcat默认安装下的…

八、进程等待

文章目录 一、进程创建&#xff08;一&#xff09;fork函数概念1.概念2.父子进程共享fork之前和fork之后的所有代码&#xff0c;只不过子进程只能执行fork之后的&#xff01; &#xff08;二&#xff09;fork之后&#xff0c;操作系统做了什么?1.进程具有独立性&#xff0c;代…

(二)CSharp-字段-属性-常量

一、字段 什么是字段 字段&#xff08;filed&#xff09;是一种表示与对象或类型&#xff08;类或结构体&#xff09;关联的变量字段是类型的成员&#xff0c;旧称“成员变量”与对象关联的字段亦称“实例字段”与类型关联的字段称为“静态字段”&#xff0c;由 static 修饰 …

java SSM 学生家长联系系统myeclipse开发mysql数据库springMVC模式java编程计算机网页设计

一、源码特点 java SSM学生家长联系系统是一套完善的web设计系统&#xff08;系统采用SSM框架进行设计开发&#xff0c;springspringMVCmybatis&#xff09;&#xff0c;对理解JSP java编程开发语言有帮助&#xff0c;系统具有完整的源代码和数据库&#xff0c;系统主要采用…