项目介绍
功能架构
技术选型
MD5
1.修改数据库中明文密码,改为MD5加密后的密文
2.修改Java代码,前端提交的密码进行MD5加密后再跟数据库中密码比对
Swagger
使用Swagger你只需要按照它的规范去定义接口及接口相关的信息,就可以做到生成接口文档,以及在线接口调试页面。
员工管理
面试问题
- nginx反向代理好处
1 | 提高访问速度 |
- DTO
1 | 当前端提交的数据和实体类中对应的属性差别比较大时,建议使用DTO来封装数据 |
- JWT
- 日期处理
在WebMvcConfiguration中扩展SpringMVC的消息转换器,统一对日期类型进行格式处理
- 公共字段自动填充
使用AOP切面编程,实现功能增强,来完成公共字段自动填充功能。
实现步骤:
1). 自定义注解 AutoFill,用于标识需要进行公共字段自动填充的方法
2). 自定义切面类 AutoFillAspect,统一拦截加入了 AutoFill 注解的方法,通过反射为公共字段赋值
3). 在 Mapper 的方法上加入 AutoFill 注解
技术点:枚举、注解、AOP、反射
- 新增菜品,包括图片文件
使用第三方的存储服务,选用了阿里云的OSS服务进行文件存储。
- 删除菜品的性能优化
在DishServiceImpl中,删除菜品是一条一条传送执行的,大大降低了执行效率,为了提高性能,进行修改,使用动态sql执行删除操作
- redis
基于键值对的非关系数据库。
常用数据类型
1 | 字符串 string |
- 微信登录
业务规则:
基于微信登录实现小程序的登录功能
如果是新用户需要自动完成注册
要完成微信登录的话,最终就要获得微信用户的openid。在小程序端获取授权码后,向后端服务发送请求,并携带授权码,这样后端服务在收到授权码后,就可以去请求微信接口服务。最终,后端向小程序返回openid和token等数据。
- 应用层
SpringBoot: 快速构建Spring项目, 采用 “约定优于配置” 的思想, 简化Spring项目的配置开发。
SpringMVC:SpringMVC是spring框架的一个模块,springmvc和spring无需通过中间整合层进行整合,可以无缝集成。
Spring Task: 由Spring提供的定时任务框架。
httpclient: 主要实现了对http请求的发送。
Spring Cache: 由Spring提供的数据缓存框架
JWT: 用于对应用程序上的用户进行身份验证的标记。
阿里云OSS: 对象存储服务,在项目中主要存储文件,如图片等。
Swagger: 可以自动的帮助开发人员生成接口文档,并对接口进行测试。
POI: 封装了对Excel表格的常用操作。
WebSocket: 一种通信网络协议,使客户端和服务器之间的数据交换更加简单,用于项目的来单、催单功能实现。
- 数据层
MySQL: 关系型数据库, 本项目的核心业务数据都会采用MySQL进行存储。
Redis: 基于key-value格式存储的内存数据库, 访问速度快, 经常使用它做缓存。
Mybatis: 本项目持久层将会使用Mybatis开发。
- Swagger
- 使得前后端分离开发更加方便,有利于团队协作
- 接口的文档在线自动生成,降低后端开发人员编写接口文档的负担
- 功能测试
- 解析出登录员工id后,如何传递给Service的save方法
通过ThreadLocal进行传递。
- 分页
使用 mybatis 的分页插件 PageHelper 来简化分页代码的开发。
1 | PageHelper是MyBatis的一个插件,内部实现了一个PageInterceptor拦截器。Mybatis会加载这个拦截器到拦截器链中。在我们使用过程中先使用PageHelper.startPage这样的语句在当前线程上下文中设置一个ThreadLocal变量,再利用PageInterceptor这个分页拦截器拦截,从ThreadLocal中拿到分页的信息,如果有分页信息拼装分页SQL(limit语句等)进行分页查询,最后再把ThreadLocal中的东西清除掉。 |
- 前端小程序的微信登录流程
1 | 微信登录的核心是通过微信小程序提供的临时凭证code换取永久凭证openid的过程 |
- redis应用
1 | 我们项目中有两处地方用到了Redis,分别是:店铺营业状态标识和小程序端的套餐、菜品列表数据 |
- SpringCache在项目中的应用
1 | SpringCache是Spring提供的一个缓存框架,它可以通过简单的注解实现缓存的操作,我们常用的注解有下面几个: |
- SpringTask在项目中的应用
1 | SpringTask是Spring框架提供的一种任务调度工具,用来按照定义的时间格式执行某段代码。 |
cron表达式其实就是一个字符串,通过cron表达式可以定义任务的触发时间
- WebSocket对比HTTP
1 | HTTP的通信是单向的,要先请求后响应,类似于对讲机 |
- 核心功能
菜品新增:对菜品表和口味表进行新增操作
首先将前端传过来的菜品信息保存到菜品表并主键返回,然后遍历前端传过来的口味集合,
为每个口味设置刚才返回来的主键并保存到口味表
菜品修改:对菜品表进行更新,对菜品详情表进行增删操作
首先根据前端传过来的菜品信息对菜品表进行修改
然后根据菜品id删除对应的口味列表集合
最后再把前端传过来的口味集合重新加入到口味表中
菜品删除:对菜品表和口味表进行删除操作
遍历前端传过来的菜品id集合得到每个菜品的信息
如果当前菜品是启售状态或者被套餐关联那么就不能被删除
否则就可以通过菜品id对菜品表和口味表中的数据进行删除
套餐新增:对套餐表和套餐菜品关系表进行新增操作
首先将前端传过来的套餐基本信息保存到套餐表中,并返回主键的id
然后为前端传过来的套餐菜品设置套餐id
最后将套餐包含的菜品添加到套餐菜品关系表中
套餐修改:对套餐表进行修改,在对套餐菜品关系表进行增删操作
首先根据前端传过来的套餐基本信息更新到套餐表中
然后根据套餐的id删除所有套餐菜品关系表中包含的菜品信息
最后遍历前端传过来的菜品的列表,设置好套餐的id后重新保存到套餐菜品关系表中
套餐删除:对套餐表和套餐菜品关系表进行删除操作
首先遍历前端传过来套餐id的集合得到每一个套餐的信息
然后根据id查询套餐,判断套餐的状态是否为启售状态,如果是启售状态,则不能删除
如果是在禁售状态,就可以通过套餐的id进行套餐菜品关系表的删除操作
分类删除
分类删除的核心逻辑就是根据前端传过来的分类id去分类表进行一个删除操作
但是要对这个分类里面是否有菜品和套餐做一个判断,拿着这个id去菜品表和套餐表做一个统计查询
如果查出来数量大于0,就不能删除,如果为0,直接删除
添加购物车:将用户选择的商品基本数据信息添加到数据库表中进行保存
利用到的数据库表(本次项目):购物车表,菜品表、套餐表,保存的信息就是从表中查到的
首先根据id查询购物车中是否有相同商品
有:则不用添加,只修改查询到的商品number属性+1并重新赋值即可,执行mapper更新。
无:则判断是菜品还是套餐,查询对应商品的数据库得到基本信息,补全购物车需要的参数执行保存。
- websocket
- threadlocal