前言:在线教育项目使用的是尚硅谷开源的视频 https://www.bilibili.com/video/BV1dQ4y1A75e?from=search&seid=14479882303889733720,在原的项目上做了细微的修改加上了自己一些细微功能二次开发,笔记方面根据老师开源笔记进行的细微的优化。对缺少的知识点进行了补充,方便日后的复习。

项目地址:

一、项目后台管理功能

1、准备

  1. 启动后接口启动起来
  2. 启动前端项目(前台系统和后台系统)

2、登录和权限管理模块

2.1 登录功能(SpringSecurity框架)

image-20210419161610302

2.1 权限管理模块 (SpringSecurity框架)

页面

image-20210419153215826

后台

image-20210419153516483

  • Config 配置

    • TokenWebSecurityConfig 核心配置类
  • entity 实体类

    • SecurityUser
    • User
  • filter 过滤

    • TokenAuthenticationFilter 授权过滤
    • TokenLoginFilter 认证过滤器
  • security

    • DefaultPasswordEncoder 密码处理
    • TokenLogoutHandler 退出处理器
    • TokenManager Token操作工具类
    • UnauthorizedEntryPoint 未授权统一处理类

(1)菜单管理

  • 列表、添加、修改、删除

image-20210419173451036

(2) 角色管理

  • 列表、添加、修改、删除
  • 为角色分配菜单

image-20210419195705881

image-20210419195720224

(3)用户管理

  • 列表、添加、修改、删除、批量删除

image-20210426170212631

  • 为用户分配角色

image-20210426170431796

(4)权限管理表和关系

  • 使用5张表

image-20210426170532593

3、讲师管理模块

  1. 条件查询分页列表、添加、修改、删除

分页列表

image-20210426170708069

添加

image-20210426170731697

修改

image-20210426170857994

删除

image-20210426170843404

4、课程分类模块

(1) 添加课程分类

​ 读取Excel里面课程分类数据,添加到数据库中

image-20210426171053395

(2) 课程分类列表

使用树形结构显示课程分类列表

image-20210426171149827

5、课程管理模块

(1) 课程列表功能

image-20210426171419518

(2) 添加课程

  • 课程发布流程: 第一步填写课程的基本信息,第二步添加课程大纲(章节和小节),第三步课程信息确认,最终课程发布

image-20210426171552036

注意:

  1. 课程如何判断是否已经被发布了?

    使用status 字段 来进行判断,发布后列表上课程转态会变为已发布

    image-20210426171835154

  2. 课程添加过程中,中途把课程停止添加,重新去添加新的课程,如何找到之前没有发布完成课程,继续进行发布?

    到课程列表中根据课程状态查询未发布的课程,点击课程右边超链接把课程继续发布完成

image-20210426172025595

(3) 添加小节上传课程视频

image-20210426172112656

6、统计分析

(1) 生成统计数据

image-20210426172254115

(2) 统计数据图标显示

image-20210426172338900

二、项目前台用户系统功能

1、首页数据显示

(1) 显示幻灯片功能

image-20210426172907297

(2) 显示热门课程

  • 根据数据库id前8来进行排序

image-20210426173015877

(3)显示名师

image-20210426173048059

2、注册功能

  • 获取手机验证码

image-20210426173136715

3、登录功能

3.1 普通登录

  • SSO(单点登录) 三种常见方式:

    1. session 广播机制实现

      • 登录成功之后,把用户数据放到session里面
      • 判断是否登录,从session获取数据,可以获取到登录
      1
      2
      session.setAttribute("user",user);
      session.setAttribute("user");

      image-20210426174153484

    2. 使用cookie + redis 实现

      • 在项目中任何一个模块登录,登录之后,把数据放到两个地方

        redis: 在key中生成唯一随机值(ip、用户id等等),在value中存放用户数据

        cookie: 把redis里面的生成key值放到cookie里面

      • 访问项目中其他模块,发送请求带着cookie进行发送,获取cookie值,拿着cookie做事情

        把cookie获取值,放到redis进行查询,根据key进行查询,如果查询到数据就是登录

    3. 使用token 实现

      • 在项目某个模块进行登录,登录之后,按照规则生成字符串,把登录之后用户包含到生成字符串里面,把字符串返回

        1. 可以把字符串通过cookie返回

        2. 把字符串通过地址栏返回

      • 再去访问项目其他模块,每次访问在地址带着生成字符串,在访问模块里面获取地址栏字符串,根据字符串获取用户信息。如果可以获取到,就是登录

3.2 JWT

  • 使用 JWT 生成 token 字符串

    token是按照一定的规则生成字符串,包含用户信息

image-20210426175750276

  • JWT 生成字符串包含三部分
    1. 第一部分 jwt头信息
    2. 第二部分 有效载荷 包含主体信息(用户信息)
    3. 第三部分 签名希哈 (防伪标志)

3.3 登录实现流程

​ 登录调用登录接口返回 token 字符串,把返回 token 字符串放到 cookie 里面, 创建前端拦截进行判断,如果 cookie 里面包含 token 字符串,把 token 字符串放到 header 里面。调用接口根据 token 获取用户信息,把用户信息放到 cookie里面,进行显示

02 登录前端整合(实现过程分析)

3.4 微信扫描登录

OAuth2

  • 是针对特定问题解决方案
  • 主要由两个问题: 开放系统间授权,分布式访问
  • OAuth2解决方案:令牌机制,按照一定规则生成字符串,字符串包含用户信息

如何获取扫描人信息过程

​ 扫描之后微信接口返回 Code (临时票据) , 拿着 code 值请求微信固定地址,得到两个值: access_ token(访问凭据)和 openid (微信唯一标识),拿着这两个值再去请求微信固定的地址,得到微信扫描人信息(比如昵称,头像等等)

image-20210426220803854

4、名师列表功能

image-20210426221326429

5、名师详细功能

image-20210426221357129

6、课程列表功能

(1) 条件查询分页查询列表功能

image-20210426222219008

7、课程详情页

(1) 课程信息显示 (包含课程基本信息,分类,讲师,课程大纲)

image-20210426222653498

(2) 判断课程是否需要购买

1
2
3
4
5
6
<section class="c-attr-mt" v-if="isBuy || Number(courseWebVo.price) === 0">
<a href="#" title="立即观看" class="comm-btn c-btn-3">立即观看</a>
</section>
<section class="c-attr-mt" v-else>
<a @click="createOrders()" href="#" title="立即购买" class="comm-btn c-btn-3">立即购买</a>
</section>
1
2
3
//根据课程id和用户id查询订单表中订单状态
@GetMapping("/eduorder/order/isBuyCourse/{courseId}/{memberId}")
public boolean isBuyCourse(@PathVariable("courseId") String courseId, @PathVariable("memberId") String memberId);

查询t_order 字段 status (1 以支付,0未支付)来判断是否需要购买以及视频是否购买过的

image-20210426223245740

8、课程视频在线播放

​ 使用的是阿里云的视频点播 ,具体请参考 阿里视频点播

具体流程

06 整合阿里云播放器

9、课程支付功能(微信支付)

  • 生成课程订单
  • 生成微信支付二维码
  • 微信最终支付

微信支付实现流程

  • 如果课程是收费课程,点击立即购买,生成课程订单

  • 点击订单页面去支付,生成微信支付二维码

  • 使用微信扫描支付二维码实现支付

注意: 如何判断以支付

​ 支付之后,每隔3秒查询支付状态(是否支付成功),如果没有支付成功等待,如果支付成功之后,更新订单状态(已经支付状态),向支付记录表添加支付成功记录。

三、在线教育项目技术点(前端)

架构:在线教育项目采用**前后端分离**开发

1、项目使用前端技术

vue

  • 常见指令 : v-bind v-model v-if v-for v-html

  • 绑定事件: v-on-click @click

  • 生命周期:created() 页面渲染之前 mounted()页面渲染之后

  • ES6 规范

Element-ui

nodejs

 是JavaScript运行环境,不需要浏览器直接运行js代码,模拟服务器效果

NPM

  • 包管理工具,类似于Maven

  • npm命令: npm init npm install 依赖名称

Babel

​ 转码器,可以把ES6代码转换成ES5代码

前端模块化

  • 通过一个页面或者一个js文件,调用另外一个js文件里面的方法

  • 问题:ES6的模块化无法在Node.js中执行,需要用Babel编辑成ES5后再执行

    后台系统使用vue-admin-template

  • 基于vue+Element-ui

    前台系统使用Nuxt

  • 基于vue

  • 服务器渲染技术

Echarts

  • 图表工具

四、在线教育项目技术点

1、技术点一

项目采用微服务架构: SpringBoot + SpringCloud

SpringBoot

  1. SpringBoot本质上就是Spring, 只是快速构建Spring工程脚手架

  2. 细节

    • 启动类包扫描机制

    • 设置扫描规则 @ComponentScan(“包路径”)

    1
    2
    3
    @SpringBootApplication
    @ComponentScan(basePackages = {"com.oy.guli"})
    @MapperScan("com.oy.guli.eduorder.mapper")
    • 配置类

    image-20210427002055962

SpringCloud

  • 是很多框架总称,使用这些框架实现微服务架构,基于SpringBoot实现
  1. 组成框架有哪些?

image-20210427002421711

  1. 项目中,使用阿里巴巴Nacos,替代SpringCloud一些组件

  2. Nacos

  • 使用Nacos作为注册中心

  • 使用Nacos作为配置中心

  1. Feign
  • 服务调用,一个微服务调用另外一个微服务,实现远程调用
  1. 熔断器(Hystrix)
  • 当其中有一层服务故障了,可能会导致一层服务或者多层服务故障,会导致整个系统故障。这种现象被称为服务雪崩效应,这个需要配置熔断器来进行熔断保护。使用SpringCloud 中的 Hystrix 组件来解决,保护的方法就是使用 Fallback,当调用的服务出现故障时,就可以使用 Fallback 方法的。返回值;Hystrix 间隔时间会再次检查故障的服务,如果故障服务恢复,将继续使用服务。
  1. Gateway网关
  • SpringCloud之前zuul网关,目前Gateway网关
  1. SpringCloud 版本选择

    image-20210427002947030

MyBatisPlus

  • MyBatisPlus就是对MyBatis做增强

  • 自动填充

  • 乐观锁

image-20210427003134144

  • 逻辑删除
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
@Component
public class DataMetaObjectHandler implements MetaObjectHandler {
@Override
public void insertFill(MetaObject metaObject) {
// 自动补充teacher对象属性中的数据, isDeleted: Boolean 所以我们应该放入true, false
this.setFieldValByName("isDeleted",false,metaObject);
this.setFieldValByName("gmtCreate",new Date(),metaObject);
this.setFieldValByName("gmtModified",new Date(),metaObject);
}

@Override
public void updateFill(MetaObject metaObject) {
this.setFieldValByName("gmtModified", new Date(),metaObject);
}
}

image-20210427003240505

image-20210427003308054

  • 代码生成器

EasyExcel

(1)阿里巴巴提供操作excel工具,代码简洁,效率很高

(2)EasyExcel对poi进行封装,采用SAX方式解析

(3)项目应用在添加课程分类,读取excel数据

2、技术点二

(1) Spring Security

  1. 项目中整合框架实现权限管理功能
  2. SpringSecurity框架组成: 认证和授权
  3. SpringSescurity 登录认证过程

image-20210427125838517

​ 输入用户名和密码后,根据用户名查询用户的权限列表,把查询后的结果用redis存储 key 用来存储登录成功的用户名 value 来存储用户权限列表,同时生成 token 令牌 ,token 放到cookie 中,也在header 中存放token值。

​ 进入spring security模块,从header获取token获取用户名,拿着用户名从redis中获取权限列表,再由springsecurity 给当前用户赋予权限,可以进行相应的操作

  1. SpringSecurity代码执行过程

    详细代码请查看 guli-acl 模块

02 Spring Security代码执行过程

(2) Redis

  1. 首页数据通过 Redis 进行缓存
  2. Redis 数据类型
  3. 使用Redis 作为缓存,不太重要或者不经常改变数据适合放到Redis作为缓存

(3) Nginx

  1. 反向代理服务器
  2. 请求转发,负载均衡,动静分离

(4) OAuth2 + JWT

  1. OAuth2 针对特定问题解决方案 (开放系统间授权分布式访问
  2. JWT 包含三部分 (jwt头信息有效载荷 包含主体信息 (用户信息)签名希哈(防伪标志)

(5) HttpClien

  1. 发送请求返回响应的工具,不需要要浏览器完成请求和响应的过程
  2. 应用场景: 微信登录获取扫描人信息,微信支付查询支付状态

(6) Cookie

特点:

1. 客户端技术
 2. 每次发送请求带着cookie值进行发送
 3. cookie有默认会话级别,关闭浏览器 cookie 默认不存在,但是可以设置 cookie 有效时长 setMaxAge

(7) 微信登录、微信支付

(8) 阿里技术服务

  • 阿里云OSS
    1. 文件存储服务
    2. 添加讲师时候上传讲师头像
  • 阿里云视频点播
    1. 视频上传、删除、播放
    2. 整合阿里云视频播放器进行视频播放 (使用视频播放凭证)
  • 阿里云短信服务
    1. 注册时候,发送手机验证码

(9)Git

​ 代码提交到远程Git仓库

(10) Docker+Jenkins

 详细请参考这篇博客:[https://oy6090.top/posts/91ec6c75/](https://oy6090.top/posts/91ec6c75/)
  1. 手动打包运行
  2. idea 打包
  3. jenkins 自动化部署过程

五、在线教育项目问题

1、前端问题-路由切换问题

  1. 多次路由跳转到同一个vue页面,页面中created方法只会执行一次

  2. 解决方案:使用vue监听

    image-20210427140541810

2、前端问题-ES6模块化运行问题

  1. Nodejs不能直接运行ES6模块化代码,需要使用Babel把ES6模块化代码转换ES5代码 执行

3、mp生成19位id值

  1. mp生成id值是19位,JavaScript处理数字类型值时候,只会处理到16位

4、跨域问题

  1. 访问协议,ip地址,端口号,这三个如果有任何一个不一样,产生跨域

  2. 跨域解决:

  • 在Controller添加注解 @CrossOrigin

    image-20210427140725728

  • 通过网关解决

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
@Configuration
public class CorsConfig {
@Bean
public CorsWebFilter corsFilter() {
CorsConfiguration config = new CorsConfiguration();
config.addAllowedMethod("*");
config.addAllowedOrigin("*");
config.addAllowedHeader("*");

UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(new PathPatternParser());
source.registerCorsConfiguration("/**", config);

return new CorsWebFilter(source);
}
}

image-20210427140811089

5、413问题

  1. 上传视频时候,因为Nginx有上传文件大小限制,如果超过Nginx大小,出现413

  2. 413错误:请求体过大

  3. 在Nginx配置客户端大小

  4. 响应状态码:413 403 302

解决方式

1
2
3
include       mime.types;
default_type application/octet-stream;
client_max_body_size 1024m;

image-20210427140928563

6、Maven加载问题

(1)maven加载项目时候,默认不会加载src-java文件夹里面xml类型文件的

(2)解决方案:

  • 直接复制xml文件到target目录

  • 通过配置实现

1
2
3
4
5
6
7
8
9
10
11
<build>
<resources>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.xml</include>
</includes>
<filtering>false</filtering>
</resource>
</resources>
</build>

7、其他问题

请查看这篇博客:在线教育项目Bug整理总结:https://oy6090.top/posts/de6b4930/