苍穹外卖学习笔记
苍穹外卖
项目经历
技术架构
SpringBoot+SpringMVC+Mybatis+MySQL+Redis+OSS+AOP+Swagger
项目简介
苍穹外卖是一个在线外卖平台,为用户提供外卖下单、支付、订单跟踪等功能。平台分为管理端和用户端,管理端供商家进行菜品、订单、员工和套餐等基本信息操作,且具有数据统计功能。用户端(微信小程序)供用户进行菜品浏览、添加购物车、下单、支付、催单等操作。
我负责的部分
- 用户认证与权限管理:使用JWT令牌配置自定义拦截器完成用户认证,实现管理人员、用户、卖家的权限管理
- 缓存机制:使用Redis和Spring Cache缓存菜品、套餐等信息
- 文件上传与存储:使用阿里云OSS存储菜品图片等文件
- 定时任务处理:使用Spring Task框架实现定时任务,例如定时处理过期订单等功能
- 实时通讯:使用WebSocket实现来单提醒、用户催单的功能
- 数据导出与可视化:使用EasyExcel导出订单数据、菜品数据等数据
- 公共字段填充:使用AOP切面自定义注解简化数据库表的公共字段的新增和更改
- 异常处理:为集中处理异常系统,自定义统一的错误码,并封装了全局异常处理器,屏蔽了项目冗余的报错细节,便于接口调用方法理解和统一处理
- 自动接口文档:使用Knife4j+Swagger自动生成后端接口文档,并通过编写ApiOperation等注解补充接口注释,避免了人工编写维护文档的麻烦
项目环境
项目角色
产品经理、开发工程师、测试运维工程师
技术选型:展示项目使用到的技术框架和中间件
用户层:node.js/vue.js
网关层:Nginx
应用层:Spring Boot/Spring MVC/Spring Task...
数据库:Mysql/Redis/Mybatis...
工具使用:Maven/Git/Juint/Postman
整体结构
前端:管理端(Web)用户端(小程序)
后端:后端java应用
观察前端发送过来的项目代码
包名:
1. sky-take-out:maven父工程,统一管理依赖版本,聚合其它子模块
2. sky-common:子模块,存放公共类,例如:工具类、常量类(constant)、异常类
3. sky-pojo:子模块,存放实体类,VO、DTO
Entity:实体,和数据库中列表对应
DTO:数据传输对象,通常用于程序中各层之间传递数据
VO:视图对象,为前端展示数据提供的对象
POJO:普通java对象,只有getter和setter
4.sky-server:子模块,后端服务,存放配置文件、Controller、Service、Mapper
配置文件:gitignore:配让git忽略的通配文件
Nginx
好处:
1.提高访问速度
2.进行负载均衡(将大量的请求按照程序员指定的方式分配给不同的服务器)
3.反向代理(避免暴露后端接口,保证后端服务安全)
4.改写请求(控制浏览器【利用请求头设置缓存有效期】、请求重定向、URI重写)
5.日志记录(访问和错误)
6.访问控制和限制(专门限制IP地址)
7.限流
8.开启虚拟主机

数据库密码加密:将明钥改成密钥
前后端开发流程

后端接口测试Swagger技术

商家管理
新增员工
难点:拿到现在在操作用户的id
解决方式:在校验令牌的下方使用ThreadLocal获取现在的id
ThreadLocal并不是一个线程Thread,而是Thread的局部变量
ThreadLocal为每个线程提供单独一份存储空间,具有线程隔离的效果,只有在线程内才能获取到对应的值,线程外访问不到
注意点:
- Controller层接受前端传过来的数据类型是EmployeeDTO,数据层Mapper接受的数据类型是Employee,中间在Service层要处理一下
2.利用DigestUtils.md5DigestAsHex进行加密处理默认密码
3.一般将经常使用的数据封装成静态变量
分页查询
观察文档接口参数(分页查询有专门接受数据的参数)
思考Mapper语句:select * from employee where name like concat('%',#{name},'%)
Service层:
1.设置分页参数PageHelper.startPage(employeePageQueryDTO.getPage(),employeePageQueryDTO.getPageSize());
2.Mapper层执行查询Page page = employeeMapper.pageQuery(employeePageQueryDTO);
3.封装pageBean PageResult pageResult = new PageResult(page.getTotal(), page.getResult());
禁用启用员工账号
@Builder的作用:
▼text复制代码Employee employee = Employee.builder() .status(status) .id(id) .build();
公共字段自动填充
在update和insert中要添加updateTime和updateUser等,会造成代码冗余的情况
使用Aop面向切面技术
实现思路:
1.自定义注解,用于标识需要自动处理的方法
2.在定义切面类
1.切入点
2.通知
1.获取到当前拦截到的方法对应的数据库类型
2.获取当前拦截到的方法的参数
3.根据不同的操作类型,为对象的属性通过反射来赋值
3.在数据层添加自定义注解进行标识
新增菜品
难点:文件上传
业务逻辑(涉及一次对多个表格进行操作)
解决:1.使用阿里云(在配置文件中的editor去除https:\\ ),阿里云创建的bucket权限是公共读
2. Service层中涉及多条数据执行,记得加事物开启的标识
3.在DishMapper中获取主键id useGeneratedKeys="true" keyProperty="id"
4.在DisFlavorMapper.xml中遍历的时候记得用flavor.name
Redis
Redis存储的是key-value结构的数据
key是字符串数据
value有五种常用的数据类型:
| string(字符串) | hash(哈希) | list(列表) | set(集合) | sorted set / zset (有序集合) |
|---|---|---|---|---|
| 对象(带属性),类型java中的HashMap | 按照插入顺序,可以有重复元素,类似于java中的LinkedList | 无序集合,没有重复元素,类似java里面的HashSet | 集合中每一个元素关联一个分数,根据分数升序排序,没有重复元素 |






在Springboot中操作Spring Data Redis
- 导入Spring Data Redis的maven坐标
- 配置Redis数据源
- 编写配置类,创建RedisTemplate对象
- 通过RedisTemplate对象操作Redis
Spring Cache
具体的实现思路
- 导入Spring Cache和Redis相关maven坐标
- 在启动类上加上@EableCaching注解,开启缓存注解功能
- 在用户端接口SetmealController的list方法上加上@Cacheable注解
- 在管理端接口SetmealController的save、delete、update、startOrStop等方法上加上CacheEvict注解
微信小程序支付流程

内网穿透工具cpolar
获取临时ip网址:cpolar.exe http 8102
Spring Task任务调度
- 导入maven坐标spring-context(已存在)
- 启动类添加注解@EnableScheduling开启任务调度
- 自定义定时任务类
WebSocket
WebSocket是基于TCP的一种新的网络协议。它实现了浏览器与服务器全双工通信——浏览器和服务器只需要完成一次握手,两者之间就可以创建持久性的连接,并进行双向数据传输
Apache ECharts
Apache ECharts是基于一款javascript的数据可视化图标库,提供直观、生动,可交互,可个性化定制的数据可视化表图。
Apache POI
Apache POI是一个处理Miscrosoft Office各种文件格式的开源项目。
应用场景:
- 银行网络系统导出交易明细
- 各种业务系统导出Excel报表
- 批量导入业务数据
代码开发实现步骤:
- 设计Excel模板文件
- 查询最近30天的运营数据
- 将查询到的运营数据写入模板文件
- 通过输出流将Excel文件下载到客户端浏览器
前端vue
基于脚手架创建vue项目
基于vue开发前端项目的环境要求
node.js
npm
Vue CLI
vue项目创建
创建vue项目:进入控制面板,输入指令(注意项目名称)
方式一:vue create 项目名称
方式二:vue ui(包管理器:npm)
项目结构
node_modules:当前项目依赖的js包
assets:静态资源(图片)
components:公共组件
App.vue:项目的主组件,页面的入口文件
main.js:整个项目的入口文件
package.json:配置信息,依赖包管理
vue.config.js:vue-cli配置文件
项目启动
打开vscode的控制面板:输入指令npm run serve
基础
vue组件:template是结构(html),style是样式(css),script是逻辑(js)
文本插值:{{}}
属性绑定v-bind:
事件绑定v-on:
双向绑定v-model
条件渲染v-if、v-else-if、v-else
Axios是一个基于promise的网络请求库,用于浏览器和node.js中【安装命令:npm install axios
导入命令:import axios from ‘axios’
路由Vue-Router
跳转页面主要是跳转路由(路径)
基于Vue CLI 创建带有路由功能的前端项目 【npm install vue-router】
路由配置
- VueRouter:路由器,根据路由请求在路由视图中动态渲染对应的视图组件
- :路由链接组件,浏览器会解析
- :路由视图组件,用来展示与路由路径匹配的视图组件
跳转方式还有js代码: this.$router.push('/about')
嵌套路由
安装 npm i element-ui -S
状态管理vuex
state:状态对象,集中定义各个组件共享的数据
mutations:修改共享数据的方法,要求是同步函数 【 this.$store.commit('setName', 'Vuex'),只能通过store对象的commit方法调用】
actions:类似mutation,可以包含异步操作,通过调用mutation来改变共享数据【只能通过store对象的dispatch方法调用】
TypeScript
包含js
安装:npm install -g typescript
查看版本指令:tsc -v
编译文件:tsc 文件名
运行文件:node 文件名
类型标注的位置:
- 标注变量
- 标注参数
- 标注返回值


