# MyMooc **Repository Path**: lkx2000/MyMooc ## Basic Information - **Project Name**: MyMooc - **Description**: 在线学习平台源码第一次提交 - **Primary Language**: Java - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 1 - **Forks**: 0 - **Created**: 2022-05-19 - **Last Updated**: 2024-01-10 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # MyMooc #### 项目描述 分为前台会员系统和后台管理系统,采用微服务技术架构,前后端分离开发。 前台实现课程条件分页查询、详情、评论,讲师分页浏览、详情,课程视频播放、课程支付,会员注册登录等。 后台管理员系统实现了讲师管理、课程分类管理、课程管理、统计分析几大模块。 后端的主要技术架构:SpringBoot+SpringCloud+Mybatis-Plus+Redis+Mysql+Maven+Nginx+EasyExcel 前端只要技术架构:Node.js+Vue.js+element-ui+NUXT+ECharts 涉及第三方中间件:阿里云OSS、阿里云视频点播、QQ邮箱 前台课程多条件分页查询、详情浏览、会员参与评论、课程视频播放、课程购买,讲师详情浏览,会员登录、邮箱验证注册。后台讲师管理、excel文件导入课程分类、课程编辑发布、统计图表可视化等等。 #### 后台管理员系统细讲 前端:基于vueAdmin-template后台管理系统基础模板,进行二次开发 ##### 1、讲师管理模块 实现了条件分页查询列表展示、添加、删除、修改 ![剪影](png%E5%90%8E%E5%8F%B0%E8%AE%B2%E5%B8%88%E5%88%97%E8%A1%A81.png) ##### 2、整合阿里云OSS对上传文件进行云端存储(如头像,课程封面,提供下载的exls示例文件等) ##### 3、整合阿里巴巴EasyExcel 读取exls文件内容 导入课程分类相关信息,有一级和二级两级分类 例如: 一级:后端开发 二级:springboot、mybatisPlus、spring。。 ![剪影](png%E5%90%8E%E5%8F%B0%E5%AF%BC%E5%85%A5%E8%AF%BE%E7%A8%8B%E5%88%86%E7%B1%BB.png) ##### 4、课程分类管理模块 课程分类以树型结构展示在页面,后端为了符合前端框架的数据格式,需要进行数据格式转换 格式如下: ``` OneSubject { private String id; private String title; //一个一级分类有多个二级分类 private List children = new ArrayList<>(); } ``` ##### 5、课程管理模块 (1)课程基本信息条件分页查询展示 (2)课程发布流程:课程基本信息填写—>课程大纲编辑—>课程发布信息确认最终发布 (3)课程详细信息分成两张表存,因为简介一般字节数较大,所有单独一张表存储课程简介,两表一 对一关系。 这就产生了一些课程管理模块中的细节问题: (a)课程实体类不包含课程简介属性,这就需要创建vo实体类用于表单数据的封装 (b)把表单传来的数据添加到数据库,需要向两张表添加 (c)应该把讲师和 课程分类 以下拉列表 给予管理员进行选择 这样的话课程分类 需要做成二级联动 ![剪影](png%E5%90%8E%E5%8F%B0%E8%AF%BE%E7%A8%8B%E5%88%97%E8%A1%A8.png) (4)整合阿里云的视频点播服务,对小节进行教学视频的上传添加删除操作 (5)nacos组件进行服务注册发现,Spring Cloud Feign实现服务调用,实现不同微服务之间的互动。例如: 对service模块下的所有微服务进行了注册,在service_edu模块调用了service_vod模块对存储在阿里云上的视频进行删除操作,实现了在service_edu模块删除小节和课程的同时对视频的删除。 ![图片](png%E5%90%8E%E5%8F%B0%E5%8F%91%E5%B8%83%E8%AF%BE%E7%A8%8B2.png) (6)系统中有很多服务,当某些服务不稳定的时候,使用这些服务的用户线程将会阻塞,如果没有隔离机制,系统随时就有可能会挂掉,从而带来很大的风险。为避免此类风险,引入Hystrix组件,熔断器对每一个Feign调用请求进行拦截。如果出现异常,返回熔断Fallback结果,如果通过,则将调用请求传递给Ribbon组件。 课程最终发布: ![输入图片说明](png%E5%90%8E%E5%8F%B0%E5%8F%91%E5%B8%83%E8%AF%BE%E7%A8%8B3.png) ##### 6、统计分析模块 (1)统计数据的获取 需要远程调用ucenter接口服务,和edu接口服务实现数据的获取,然后封装成统计表实体类对象存入数据库。为后面的图标显示提供数据。 (2)采用ECharts的图表,进行统计数据的展示,编写接口获取表中的统计数据,前端整合ECharts实现数据展示。 ![图片](png%E5%90%8E%E5%8F%B0%E7%BB%9F%E8%AE%A1%E5%88%86%E6%9E%90.png) #### 前台用户系统细讲 ##### 1、前端搭建:采用服务器端渲染技术NUXT。 服务端渲染又称SSR(Server Side Render)是在服务端完成页面的内容,而不是在客户端通过AJAX获取数据。SSR的优势主要在于:更好的 SEO,因为搜索引擎爬虫抓取工具可以直接查看完全渲染的页面。 ##### 2、首页数据展示 (1)轮播图 (2)热门课程(浏览数排序) ![输入图片说明](png%E9%A6%96%E9%A1%B52.png) (3)名师展示(sort字段) ![输入图片说明](png%E5%89%8D%E5%8F%B0%E8%AE%B2%E5%B8%881.png) ##### 3、集成缓存将首页高频率访问的数据存入redis 由于redis缓存是公共应用,所以我将依赖与redis的配置类添加在common模块下。别的模块如果想用缓存功能,需要在配置文件添加redis连接配置,然后用Spring Boot缓存注解调用redis功能,如:@Cacheable、@CachePut。。。 ##### 4、登录注册(SSO) (1)项目有多个模块,现实中通常每个模块部署在不同服务器。因此需要达到只要在一个模块上登录成功,其他模块就不需要再次登录的效果,即单点登录(SSO)。 单点登录三种常见实现方式:session广播机制、cookie+redis实现、token实现。 这里采用 token结合JWT规则实现,使用JWT生成token字符串。 (2)会员注册需要验证码验证环节,这里编写了两种验证码的发送方式:第一种:采用阿里云短信服务向用户手机号发送短信;第二种:通过QQ邮箱发送。验证码的有效时间,通过redis实现。(由于短信服务难申请,我采用了第二种) ![输入图片说明](png%E9%82%AE%E4%BB%B61.png) (3)会员的密码先通过MD5算法加密后再存储到数据库 (4)登录方式:邮箱+密码登录和微信扫码登录。 ##### 5、微信扫码登录实现 准备工作:需要到微信官方进行开发者资质认证给你颁发微信id和密匙,需要营业执照和一定费用。 实现步骤:(1)、访问官方提供的 路径+设置好认证得到的参数发送请求,生成登录二维码 (2)、用户扫码登录后微信方会向项目的服务器发起回调执行我方的业务逻辑代码获取临时票据code。 (3)、用code在请求微信提供的另一个固定地址获得 访问凭证和openid (4)、现根据openid查询数据表,是否已注册过,若注册过不执行第5、6步 (5)、用第3步的两值,访问另一个微信提供的地址,最终获得扫码人的信息,昵称、头像等 (6)、将得到的信息封装存入数据库。完成注册 (7)、得到扫码人信息后,由JWT根据会员id和昵称生成token 加到路径参数中重定向到首页。 之后执行下面 6的2-5步即可。 (有个坑需要注意:区分好this.r o u t e . q u e r y 和 t h i s . route.query 和this.route.query和this.route.params。 前者获取的是以?key=value方式传输的参数后者获取的是/{123}/{5}这种方式) 技术点:a、从上面步骤可知需频繁进行地址访问,采用httpclient实现(不需要浏览器输入地址即可访问) b、用gson对返回的json字符串转换成map ##### 6、实现登录后会员信息回显页头: 第一步:前端调用接口接收token值 (JWT工具自定义规则生成,这里我根据id和昵称生成) 第二步:把token值存在cookie中 第三步:创建前端拦截器,如果cookie中有存入的token,则放到请求头中 第四步:调用接口根据请求头的token值查询到会员信息,将会员信息存在cookie 第五步:跳转首页显示数据 (卡住的地方:Unexpected token o in JSON at position 1; 解决:第四步的时候:this.loginInfo = JSON.stringify(response.data.data.memberInfo 需手动转成json字符串再存入cookie)) 页面跳转两种方式: a、this.$router.push({ path: ‘/order/’+ response.data.data.orderNo }) b、window.location.href = “/”; ##### 7、课程列表条件分页查询 ![输入图片说明](png%E5%89%8D%E5%8F%B0%E8%AF%BE%E7%A8%8B1.png) ##### 8、课程详情页 (1)判断课程是否收费,若免费则免登录免付费即可观看小节视频,否则需要登录购买才可观看。 (2)课程信息显示(包含课程基本信息,分类,讲师,课程大纲) ![输入图片说明](png%E8%AF%BE%E7%A8%8B%E8%AF%A6%E6%83%852.png) ##### 9、完善vod子模块实现课程详情点击小节可观看对应教学视频功能。 编写接口根据视频id获取到播放凭证。mounted生命周期函数在页面渲染完后执行,因此在这里创建视频播放器,因为页面渲染完成时此时js脚本已加载,Aliplayer已定义,可以使用。(如果在created生命周期函数中使用,会出现Aliplayer is not defined错误) ![输入图片说明](png%E5%B0%8F%E8%8A%82%E8%A7%86%E9%A2%91%E8%A7%82%E7%9C%8B.png) ##### 10、整合微信支付课程功能 (1)首先需要编写 根据会员id课程id 生成订单的接口,接口返回订单号,记录订单信息到数据库订单表,订单是另外一个接口服务,所以需要通过nacos和Feign 实现远程调用edu和Ucenter模块实现课程信息和会员信息的获取。在前端课程详情页面整合,点击购买调用。 (2)编写根据订单号获取订单信息接口,课程详情页面,点击购买调用创建订单接口,以动态路由方式跳转到订单页面,渲染前调用查询订单信息接口获取订单信息准备渲染。 (3)编写生成微信支付二维码接口,(同样需要向官方申请),传送数据(商户id商户key等)请求微信方,获取微信那边返回的数据,包含二维码地址等信息,订单页点击支付调用。 (4)编写获取支付状态接口,传输数据请求微信方,根据订单号查询结果,根据SUCCESS或者其他结果,回显会员提示支付状态,前端设置定时器(setInterval)支付页面渲染完后每隔3秒调用一次查询接口。 (5)支付成功后,更新订单信息为已支付,并记录支付信息到支付表中。 (6)edu模块完善查询详情页代码 远程调用order模块根据课程id和会员id查询订单表的接口,得到该课程的支付状态,若已支付或课程免费显示立即观看,反之显示付费观看 ![输入图片说明](%E8%AE%A2%E5%8D%95%E9%A1%B5%E9%9D%A22.png) ##### 11、实现课程评论功能 在详情下分页显示会员对该课程的评论,并限制登陆后才可参与评论。 添加评论: 需要获取 课程id、会员id、讲师id、会员昵称,评论的内容 进行存储,课程id和讲师id在详情页可以直接获取,会员的相关信息登陆时已经存储在cookie中,从中获取即可,通过cookie可以判断是否登录,未登录提示需要登录才能评论。 ![输入图片说明](png%E8%AF%BE%E7%A8%8B%E8%AF%84%E8%AE%BA1.png)