硅谷课堂笔记(上)

文章目录

  • 概述
    • 功能架构图
    • 技术架构图
    • MybatisPlus复习
  • 后台开发
    • 搭建工程
      • 数据库设计
      • 数据库设计规则
    • 搭建工程
      • 实体类子模块model
      • 服务子模块service
      • 总结
    • 引入Swagger
      • 遇到的坑
  • 后台开发-讲师管理接口
    • 概述
    • 基础代码自动生成
    • 配置文件和启动类
      • 小改造
      • 测试
    • 引入统一返回结果
    • 引入全局异常处理
      • 示例
      • 自定义异常处理
      • 引入全局异常
      • 测试
    • 教师接口
      • 逻辑删除教师
      • 分页条件查询讲师
        • 分页查询Bug
      • 添加教师
      • 修改教师
      • 批量删除讲师
  • 前台开发
  • 腾讯云存储相关内容
    • 快速起步
      • 开通“对象存储COS”服务
      • 创建存储桶以及测试
      • 创建API秘钥
    • 腾讯云存储后端接口开发
      • 基础环境
      • 上传接口编写
      • 前端上传头像
  • 后台开发-课程分类管理接口
    • 需求分析
        • 1、课程分类管理模块需求
        • 2、课程分类数据库设计
        • 3、功能实现-课程分类列表
    • 后端开发
      • 课程分类前端页面
  • EasyExcel
    • 概述
      • EasyExcel特点
    • 读写操作
      • EasyExcel写操作
      • EasyExcel读操作
  • 功能实现-课程分类导入导出
    • 实体类创建
    • 导出接口编写
    • 整合导出前端
    • 导入接口编写
    • 整合导入前端
  • 后台开发-点播管理模块
    • 涉及数据表
      • 根据相关表生成数据
    • 后端接口编写
      • 课程列表带条件的分页
        • 整合课程列表前端
      • 课程列表接口
        • 整合课程添加前端
      • 课程列表修改课程基本信息
        • 获取课程Form
        • 更新课程
      • 编辑大纲Bug
        • 整合修改课程基本信息前端
    • 课程大纲列表功能
      • 后端接口编写
        • 整合课程大纲前端
      • 小节视频后端接口编写
        • 整合视频小节前端
    • 发布课程-课程最终发布
      • 课程最终发布接口
      • 小Bug
        • 整合课程发布前端
    • 删除课程
        • 课程删除接口
        • 整合前端
  • 后台开发-点播模块
    • 播放统计模块
      • 整合播放统计模块前端
    • 整合腾讯云点播
      • 云点播服务
          • 上传视频
          • 前端集成播放页面
    • 云点播服务端接口
      • 后端上传视频
      • 后端删除视频
      • 点播服务整合前端
    • 腾讯云上传视频其他方式
      • 之前的缺点
      • 客户端上传视频
        • 整合客户端前端页面
      • 完善删除视频功能

概述

资料下载提取码:8op3

功能架构图

硅谷课堂笔记(上)_第1张图片

技术架构图

硅谷课堂笔记(上)_第2张图片

MybatisPlus复习

篇幅有限,我另起了一个笔记进行复习
MybatisPlus快速学习

后台开发

搭建工程

数据库设计

这里的数据库用的是MySQL8.0版本
如果有小伙伴跟着做了,最少也要5.7以上的版本
数据库和表
硅谷课堂笔记(上)_第3张图片

数据库设计规则

以下规则只针对本模块,更全面的文档参考《阿里巴巴Java开发手册》:

1、库名与应用名称尽量一致

2、表名、字段名必须使用小写字母或数字,禁止出现数字开头,

3、表名不使用复数名词

4、表的命名最好是加上“业务名称_表的作用”。如,edu_teacher

5、表必备三字段:id, gmt_create, gmt_modified

说明:

其中 id 必为主键,类型为 bigint unsigned、单表时自增、步长为 1。

(如果使用分库分表集群部署,则id类型为verchar,非自增,业务中使用分布式id生成器)

gmt_create, gmt_modified 的类型均为 datetime 类型,前者现在时表示主动创建,后者过去分词表示被 动更新。

6、单表行数超过 500 万行或者单表容量超过 2GB,才推荐进行分库分表。 说明:如果预计三年后的数据量根本达不到这个级别,请不要在创建表时就分库分表。 

7、表达是与否概念的字段,必须使用 is_xxx 的方式命名,数据类型是 unsigned tinyint (1 表示是,0 表示否)。 

说明:任何字段如果为非负数,必须是 unsigned。 

注意:POJO 类中的任何布尔类型的变量,都不要加 is 前缀。数据库表示是与否的值,使用 tinyint 类型,坚持 is_xxx 的 命名方式是为了明确其取值含义与取值范围。 

正例:表达逻辑删除的字段名 is_deleted,1 表示删除,0 表示未删除。 

8、小数类型为 decimal,禁止使用 floatdouble。 说明:floatdouble 在存储的时候,存在精度损失的问题,很可能在值的比较时,得到不 正确的结果。如果存储的数据范围超过 decimal 的范围,建议将数据拆成整数和小数分开存储。

9、如果存储的字符串长度几乎相等,使用 char 定长字符串类型。 

10、varchar 是可变长字符串,不预先分配存储空间,长度不要超过 5000,如果存储长度大于此值,定义字段类型为 text,独立出来一张表,用主键来对应,避免影响其它字段索 引效率。

11、唯一索引名为 uk_字段名;普通索引名则为 idx_字段名。

说明:uk_ 即 unique key;idx_ 即 index 的简称

12、不得使用外键与级联,一切外键概念必须在应用层解决。外键与级联更新适用于单机低并发,不适合分布式、高并发集群;级联更新是强阻塞,存在数据库更新风暴的风险;外键影响数据库的插入速度。

搭建工程

包结构
硅谷课堂笔记(上)_第4张图片
硅谷课堂笔记(上)_第5张图片

模块说明
ggkt_parent:硅谷课堂根目录(父工程),管理多个子模块:

common:公共模块父节点

common_util:工具类模块,所有模块都可以依赖于它

service_utils:service服务的base包,包含service服务的公共配置类,所有service模块依赖于它

rabbit_utils:rabbitmq封装工具类

model:实体类相关模块

server-gateway:服务网关

service:api接口服务父节点

​ service_acl:权限管理接口服务

​ service_activity:优惠券api接口服务

​ service_live:直播课程api接口服务

​ service_order:订单api接口服务

​ service_user:用户api接口服务

​ service_vod:点播课程 api接口服务

​ service_wechat:公众号api接口服务

service-client:feign服务调用父节点

​ service-activity-client:优惠券api接口

​ service-live-client:直播课程api接口

​ service-order-client:订单api接口

​ service-user-client:用户api接口

​ service-vod-client:点播课程api接口

介绍完毕,开始搭建
硅谷课堂笔记(上)_第6张图片
不用管官方的依赖,我们后面Pom文件自己加
SpringBoot版本统一为2.2.1RELEASE版本
而且作为父工程,是不需要src目录的,因为主要的内容都在他子模块下
所以留个Pom就行
硅谷课堂笔记(上)_第7张图片
依赖我就不粘贴了,太多
需要的小伙伴直接去Gitee找到父工程下的Pom就可以查看

实体类子模块model

先在parent下新建子模块model
以Maven模版生成就可以了
硅谷课堂笔记(上)_第8张图片

直接导入实体类子模块model,当然,MP自动生成也不是不行~

同样子模块也需要引入各种jar包和依赖

 <dependencies>
        <dependency>
            <groupId>org.projectlombokgroupId>
            <artifactId>lombokartifactId>
        dependency>

        
        <dependency>
            <groupId>com.baomidougroupId>
            <artifactId>mybatis-plus-boot-starterartifactId>
            <scope>provided scope>
        dependency>

        <dependency>
            <groupId>com.alibabagroupId>
            <artifactId>easyexcelartifactId>
            <scope>provided scope>
        dependency>
        <dependency>
            <groupId>com.github.xiaoymingroupId>
            <artifactId>knife4j-spring-boot-starterartifactId>
            
            <scope>providedscope>
        dependency>

        <dependency>
            <groupId>org.springframework.bootgroupId>
            <artifactId>spring-boot-starter-data-mongodbartifactId>
            <scope>provided scope>
        dependency>

        <dependency>
            <groupId>com.alibabagroupId>
            <artifactId>fastjsonartifactId>
            <scope>provided scope>
        dependency>

        
        <dependency>
            <groupId>org.springframework.bootgroupId>
            <artifactId>spring-boot-starter-data-elasticsearchartifactId>
            <scope>provided scope>
        dependency>
    dependencies>

服务子模块service

再建一个Service子模块
硅谷课堂笔记(上)_第9张图片
同样需要引入对应的依赖

    <dependencies>
        
        <dependency>
            <groupId>com.ccgroupId>
            <artifactId>modelartifactId>
            <version>0.0.1-SNAPSHOTversion>
        dependency>
        
        <dependency>
            <groupId>org.springframework.bootgroupId>
            <artifactId>spring-boot-starter-webartifactId>
        dependency>

        
        <dependency>
            <groupId>com.baomidougroupId>
            <artifactId>mybatis-plus-boot-starterartifactId>
        dependency>

        
        <dependency>
            <groupId>mysqlgroupId>
            <artifactId>mysql-connector-javaartifactId>
        dependency>

        
        <dependency>
            <groupId>org.springframework.bootgroupId>
            <artifactId>spring-boot-devtoolsartifactId>
            <optional>trueoptional>
        dependency>

        
        
        

        
        

        
        
    dependencies>

因为service包也是对服务进行管理,所以也不留src路径,下面继续还要创建多个服务包
在这里插入图片描述
再建service_vod(视频点播)模块
硅谷课堂笔记(上)_第10张图片

总结

在这里插入图片描述

引入Swagger

对接口信息进行管理,测试一条龙服务
非常快乐
因为Swagger组件是公共的,所以单独拿一个模块做Common-serviceUtils模块
在这里插入图片描述
依赖我就不多说了,具体路径可以看这个onlineClass\common\pom.xml

注意,common包下及其子模块 作为一个单独的子模块,是无法被service模块所看到的。
所以这里也要像之前引入实体类一样,去service模块把这个common模块引入
引入之前一定一定要补全common子模块service-utils的pom信息,缺少信息会找不到
这个是service-utils里的信息
硅谷课堂笔记(上)_第11张图片
这里是service包引入依赖
在这里插入图片描述

到这还不算完,要在在service_vod启动类上加入对于Swagger的扫描

硅谷课堂笔记(上)_第12张图片
在想管理的方法上面加入对应注解就好啦

定义在类上:@Api
定义在方法上:@ApiOperation
定义在参数上:@ApiParam

@Api(tags = "讲师管理接口")
@RestController
@RequestMapping(value="/admin/vod/teacher")
public class TeacherController {
    @Autowired
    private TeacherService teacherService;

    //删除讲师
    @ApiOperation("逻辑删除讲师")
    @DeleteMapping("{id}")
    public boolean removeById(@ApiParam(name = "id", value = "ID", required = true) @PathVariable String id){
        return teacherService.removeById(id);
    }

    //查询所有讲师列表
    @ApiOperation("所有讲师列表")
    @GetMapping("findAll")
    public List<Teacher> findAll(){
        List<Teacher> list = teacherService.list();
        return list;
    }
}

Swagger后台路径:http://localhost:启动端口号/swagger-ui.html

硅谷课堂笔记(上)_第13张图片
后续包括文档的生成,参数注解生成等等都比较好办了,这里不是重点就不过多赘述了

遇到的坑

左找右找,先后加了注解,也不知为什么找不到controller,全都是error
硅谷课堂笔记(上)_第14张图片
通过百度,发现这个问题一般来说都是Swagger配置类没写好。但是刚刚我还写了配置类,显然不太可能是配置类的锅
推测应该是没扫到配置类,之前说过要在启动类上加入配置类扫描
硅谷课堂笔记(上)_第15张图片
仔细一看,好家伙包名没对上!
改了包名就正常了,扫描到配置类自然就都合理起来了
在这里插入图片描述
Swagger后台路径:http://localhost:启动端口号/swagger-ui.html

硅谷课堂笔记(上)_第16张图片
硅谷课堂笔记(上)_第17张图片
硅谷课堂笔记(上)_第18张图片

后台开发-讲师管理接口

概述

添加课程时候,需要选择所属讲师,所以要对讲师进行管理,就是基于讲师的CRUD操作
引入代码生成器,自动生成相关内容

基础代码自动生成

建议这些操作放到test测试包中,避免一起打包了,生成完毕也不需要再删除
(1)引入代码生成器依赖

<dependency>
    <groupId>com.baomidougroupId>
    <artifactId>mybatis-plus-generatorartifactId>
    <version>3.3.1version>
dependency>

<dependency>
    <groupId>org.apache.velocitygroupId>
    <artifactId>velocity-engine-coreartifactId>
    <version>2.0version>
dependency>

(2)复制生成代码工具类

修改代码中路径、数据库、包和表,复制到test目录下

(3)实体类统一替换为model模块的实体类

配置文件和启动类

配置文件

# 服务端口
server.port=8301
# 服务名
spring.application.name=service-vod

# 环境设置:dev、test、prod
spring.profiles.active=dev

# mysql数据库连接
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/glkt_vod?characterEncoding=utf-8&useSSL=false
spring.datasource.username=root
spring.datasource.password=root

#返回json的全局时间格式
spring.jackson.date-format=yyyy-MM-dd HH:mm:ss
spring.jackson.time-zone=GMT+8

#mybatis日志
mybatis-plus.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl

代码生成器

public class CodeGet {

    public static void main(String[] args) {

        // 1、创建代码生成器
        AutoGenerator mpg = new AutoGenerator();

        // 2、全局配置
        // 全局配置
        GlobalConfig gc = new GlobalConfig();
        String projectPath = System.getProperty("user.dir");
        //gc.setOutputDir(projectPath + "/src/main/java");
        //这里是输出生成代码的目录,这里要填电脑的绝对路径(必改)+拼接出来的路径
        gc.setOutputDir("D:\\JavaProject\\onlineClass\\service\\service_vod\\"+"/src/main/java");

        gc.setServiceName("%sService");	//去掉Service接口的首字母I
        gc.setAuthor("cc");
        gc.setOpen(false);
        mpg.setGlobalConfig(gc);

        // 3、数据源配置
        DataSourceConfig dsc = new DataSourceConfig();
        dsc.setUrl("jdbc:mysql://localhost:3307/glkt_vod");
        dsc.setDriverName("com.mysql.jdbc.Driver");
        dsc.setUsername("root");
        dsc.setPassword("123456");
        dsc.setDbType(DbType.MYSQL);
        mpg.setDataSource(dsc);

        // 4、包配置
        PackageConfig pc = new PackageConfig();
        pc.setModuleName("service_vod"); //模块名
        pc.setParent("com");//包名,最后组合成 com.service_vod

        pc.setController("controller");
        pc.setEntity("entity");
        pc.setService("service");
        pc.setMapper("mapper");
        mpg.setPackageInfo(pc);

        // 5、策略配置
        StrategyConfig strategy = new StrategyConfig();

        //具体生成哪些表要具体指定
        //strategy.setInclude("想要生成的表名");
        strategy.setInclude("teacher");

        strategy.setNaming(NamingStrategy.underline_to_camel);//数据库表映射到实体的命名策略

        strategy.setColumnNaming(NamingStrategy.underline_to_camel);//数据库表字段映射到实体的命名策略
        strategy.setEntityLombokModel(true); // lombok 模型 @Accessors(chain = true) setter链式操作

        strategy.setRestControllerStyle(true); //restful api风格控制器
        strategy.setControllerMappingHyphenStyle(true); //url中驼峰转连字符

        mpg.setStrategy(strategy);

        // 6、执行
        mpg.execute();
    }
}

启动类

@SpringBootApplication
public class ServiceVodApplication {
    public static void main(String[] args) {
        SpringApplication.run(ServiceVodApplication.class, args);
    }
}

小改造

修改一下引入的实体类,使用我们创建的实体类工程
在这里插入图片描述
加入MP配置类
硅谷课堂笔记(上)_第19张图片

测试

写一个遍历老师信息的测试
硅谷课堂笔记(上)_第20张图片
在这里插入图片描述

到这里就算搭建成功了,可以开始着手下一步接口的撰写了。

引入统一返回结果

Result结果集,都是老朋友了

项目中我们会将响应封装成json返回,一般我们会将所有接口的数据格式统一, 使前端(iOS Android, Web)对数据的操作更一致、轻松。

一般情况下,统一返回数据格式没有固定的格式,只要能描述清楚返回的数据状态以及要返回的具体数据就可以。但是一般会包含状态码、返回消息、数据这几部分内容

因为这个也算工具的一种,所以把这个结果集写到Common模块的子模块service_utils中

  • 一个结果集 Result
  • 一个结果信息枚举集 ResultCodeEnum
    硅谷课堂笔记(上)_第21张图片
    具体位置:com.cc.result.Result,com.cc.result.ResultCodeEnum
    复习一下Json格式
    硅谷课堂笔记(上)_第22张图片
    使用的话,Result.success.(数据).message(“想填入的信息”)
    Result.success.(数据)

硅谷课堂笔记(上)_第23张图片

引入全局异常处理

有特定异常就先处理特定异常,匹配不到特定异常就走全局异常处理
硅谷课堂笔记(上)_第24张图片

示例

先看看这种代码的try catch
这种try catch来捕获异常固然好,但是,代码量一大起来,超级多的try catch就会很乱
在这里插入图片描述
所以我们要加入全局异常处理
由于这是工具类的属性在Common包的service_utils下,和Result同级,这里只是示例,并不完整
如图是某个特定异常处理
在这里插入图片描述
有了这些异常处理,就可以捕获控制台输出的异常信息,从而对其进行处理

自定义异常处理

硅谷课堂笔记(上)_第25张图片

引入全局异常

把自定义异常引入全局异常处理
硅谷课堂笔记(上)_第26张图片

测试

先测自定义异常,找一个接口人为制造异常
硅谷课堂笔记(上)_第27张图片
测试一下
硅谷课堂笔记(上)_第28张图片
如果我们把try catch去掉,只留下int i=10/0,这个异常算是算数异常,也就是ArithmeticException,因此也会被捕获,此时不出意外就会走特殊异常处理

硅谷课堂笔记(上)_第29张图片
最后,来试试全局异常,一个没有设置对应有任何处理的异常
硅谷课堂笔记(上)_第30张图片
当然,如果想好几种异常都走一种处理方式,也是完全可以的
只需要在异常类型注解上面加入对应类型就好

@ExceptionHandler({异常类型1.class,异常类型2.class})
以上就是全局异常处理类的相关内容

教师接口

硅谷课堂笔记(上)_第31张图片

逻辑删除教师

Delete请求方式+ResultFul请求风格
还是非常简单的,注意,这里是逻辑删除,没有做表的实际删除。
也就是把逻辑字段更新了一下
硅谷课堂笔记(上)_第32张图片
硅谷课堂笔记(上)_第33张图片

分页条件查询讲师

就是简单的按条件分页查询
位置:service模块下的service_vod子模块com.cc.service_vod.controller.TeacherController (findQueryPage)
硅谷课堂笔记(上)_第34张图片
复习一下RequestBody注解
硅谷课堂笔记(上)_第35张图片

分页查询Bug

到了前端测试的时候,发现分页不好使,怎么查都没有Limit
还以为mp出问题了,结果一看,MP的分页配置类没写
硅谷课堂笔记(上)_第36张图片
蚌埠住了,没写配置类
硅谷课堂笔记(上)_第37张图片
加上配置类就好了
硅谷课堂笔记(上)_第38张图片
硅谷课堂笔记(上)_第39张图片

添加教师

位置:service模块下的service_vod子模块com.cc.service_vod.controller.TeacherController (saveTeacher)
硅谷课堂笔记(上)_第40张图片

修改教师

注意,要是想修改的话,肯定是得先获取讲师的信息,才能在获取的基础上对教师信息进行改进
所以要先获取,根据id获取,这里不多赘述,欢迎去Gitee查看~
获取教师位置:service模块下的service_vod子模块com.cc.service_vod.controller.TeacherController (getTeacherById)
更新教师位置:service模块下的service_vod子模块com.cc.service_vod.controller.TeacherController (updateById)

批量删除讲师

根据id集合删讲师位置:service模块下的service_vod子模块com.cc.service_vod.controller.TeacherController (batchRemove)
硅谷课堂笔记(上)_第41张图片

前台开发

前端内容比较多,这里单独再开一篇文章专门写这个
只有教师接口部分是手写的,剩下的内容都是复制粘贴
这部分是基础内容
硅谷课堂前端内容

腾讯云存储相关内容

快速起步

点击就送
硅谷课堂笔记(上)_第42张图片

开通“对象存储COS”服务

进入会送一定额度的免费存储

(1)申请腾讯云账号:https://cloud.tencent.com/

(2)实名认证

(3)开通“对象存储COS”服务

(4)进入管理控制台

硅谷课堂笔记(上)_第43张图片

创建存储桶以及测试

进入管理控制台,找到存储桶列表, 创建存储桶
简单填一下信息就可以了,注意不要选私有读写
后面的配置不用管,无脑跳过就行
硅谷课堂笔记(上)_第44张图片
创建完毕
硅谷课堂笔记(上)_第45张图片
点击 桶名称,进入详情页,可测试上传文件
硅谷课堂笔记(上)_第46张图片

创建API秘钥

硅谷课堂笔记(上)_第47张图片
硅谷课堂笔记(上)_第48张图片
基本操作已经完毕,剩下的交给后端接口

腾讯云存储后端接口开发

基础环境

参考文档:https://cloud.tencent.com/document/product/436/10199
Pom依赖

<dependency>
    
    <dependency>
        <groupId>com.qcloudgroupId>
        <artifactId>cos_apiartifactId>
        <version>5.6.54version>
    dependency>
    
    <dependency>
        <groupId>joda-timegroupId>
        <artifactId>joda-timeartifactId>
    dependency>
dependency>

为后端服务引入依赖
硅谷课堂笔记(上)_第49张图片
配置application.properties

spring.servlet.multipart.max-file-size=1024MB
spring.servlet.multipart.max-request-size=1024MB

#不同的服务器,地址不同
tencent.cos.file.region=ap-beijing
tencent.cos.file.secretid=你的id
tencent.cos.file.secretkey=你的key
#bucket可以在控制台创建,也可以使用java代码创建
tencent.cos.file.bucketname=你的bucketName

在Service模块里新建utils工具包,把配置文件引入

/**
 * 常量类,读取配置文件application.properties中的配置
 */
@Component
public class ConstantPropertiesUtil implements InitializingBean {

    @Value("${tencent.cos.file.region}")
    private String region;

    @Value("${tencent.cos.file.secretid}")
    private String secretId;

    @Value("${tencent.cos.file.secretkey}")
    private String secretKey;

    @Value("${tencent.cos.file.bucketname}")
    private String bucketName;

    public static String END_POINT;
    public static String ACCESS_KEY_ID;
    public static String ACCESS_KEY_SECRET;
    public static String BUCKET_NAME;

    @Override
    public void afterPropertiesSet() throws Exception {
        END_POINT = region;
        ACCESS_KEY_ID = secretId;
        ACCESS_KEY_SECRET = secretKey;
        BUCKET_NAME = bucketName;
    }
}

上传接口编写

创建Interface:FileService.java

public interface FileService {
    //文件上传
    String upload(MultipartFile file);
}

实现:FileServiceImpl.java
硅谷课堂笔记(上)_第50张图片
存储Service实现类
一些数据根据工具类就读取了

@Service
public class FileServiceImpl implements FileService {
    @Override
    public String upload(MultipartFile file) {
        // Endpoint以杭州为例,其它Region请按实际情况填写。
        String endpoint = ConstantPropertiesUtil.END_POINT;

        String bucketName = ConstantPropertiesUtil.BUCKET_NAME;
        // 1 初始化用户身份信息(secretId, secretKey)。
        String secretId = ConstantPropertiesUtil.ACCESS_KEY_ID;
        String secretKey = ConstantPropertiesUtil.ACCESS_KEY_SECRET;
        COSCredentials cred = new BasicCOSCredentials(secretId, secretKey);

        // 2 设置 bucket 的地域
        // clientConfig 中包含了设置 region, https(默认 http),超时, 代理等 set 方法
        Region region = new Region(ConstantPropertiesUtil.END_POINT);
        ClientConfig clientConfig = new ClientConfig(region);
        // 这里建议设置使用 https 协议
        // 从 5.6.54 版本开始,默认使用了 https
        clientConfig.setHttpProtocol(HttpProtocol.https);
        // 3 生成 cos 客户端。
        COSClient cosClient = new COSClient(cred, clientConfig);

        try{
            // 指定要上传的文件
            InputStream inputStream = file.getInputStream();
            // 指定文件将要存放的存储桶
            // 指定文件上传到 COS 上的路径,即对象键。例如对象键为folder/picture.jpg,则表示将文件 picture.jpg 上传到 folder 路径下
            String key = UUID.randomUUID().toString().replaceAll("-","")+
                    file.getOriginalFilename();
            String dateUrl = new DateTime().toString("yyyy/MM/dd");
            key = dateUrl+"/"+key;

            ObjectMetadata objectMetadata = new ObjectMetadata();
            PutObjectRequest putObjectRequest =
                    new PutObjectRequest(bucketName, key, inputStream,objectMetadata);
            PutObjectResult putObjectResult = cosClient.putObject(putObjectRequest);
            System.out.println(JSON.toJSONString(putObjectResult));
            //https://ggkt-atguigu-1310644373.cos.ap-beijing.myqcloud.com/01.jpg
            String url = "https://"+bucketName+"."+"cos"+"."+endpoint+".myqcloud.com"+"/"+key;
            return url;
        } catch (Exception clientException) {
            clientException.printStackTrace();
            return null;
        }
    }
}

编写controller,注入相关接口service就好
硅谷课堂笔记(上)_第51张图片
记得加跨域
在这里插入图片描述
直接打开Swagger进行测试
上传文件
硅谷课堂笔记(上)_第52张图片
回到腾讯云,文件已经上传上来了

前端上传头像

复制粘贴样式和JS,测一下,好用
硅谷课堂笔记(上)_第53张图片
测试一下
硅谷课堂笔记(上)_第54张图片

后台开发-课程分类管理接口

需求分析

硅谷课堂笔记(上)_第55张图片

1、课程分类管理模块需求

(1)课程分类列表功能
这个也叫懒加载,不点就不加载
点了就展现二级内容
硅谷课堂笔记(上)_第56张图片
(2)课程分类导入功能

在这里插入图片描述
(3)课程分类导出功能
硅谷课堂笔记(上)_第57张图片

2、课程分类数据库设计

(1)创建课程分类表subject
硅谷课堂笔记(上)_第58张图片

3、功能实现-课程分类列表

接口实现分析

课程分类采用树形展示,我们使用“树形数据与懒加载”的方式展现数据列表,因此需要提供的接口如下:根据上级id获取下级数据,参考element-ui文档:https://element.eleme.cn/#/zh-CN/component/table,页面搜索:树形数据与懒加载
硅谷课堂笔记(上)_第59张图片
硅谷课堂笔记(上)_第60张图片

后端开发

因为没有生成相关的实体类,所以要用代码生成器生成一下,简单修改一下就可以生成
硅谷课堂笔记(上)_第61张图片
生成完毕后就可以写接口了
根据刚刚的分析,要对当前课程是否有parentId做出相关判断
硅谷课堂笔记(上)_第62张图片
controller位置:com.cc.service_vod.controller.SubjectController
serviceImpl位置:com.cc.service_vod.service.impl.FileServiceImpl (selectList、isChild)

这里有个小问题,就是Service层去调用MP的扩展方法怎么办
答案就是用BaseMapper去调用,因为已经扩展好了
硅谷课堂笔记(上)_第63张图片

课程分类前端页面

硅谷课堂笔记(上)_第64张图片
引入JS 创建文件 src/api/vod/subject.js
硅谷课堂笔记(上)_第65张图片
复制粘贴样式 编写subject/list.vue src\views\vod\subject\list.vue

测试一下,包括懒加载都没有问题了
在这里插入图片描述

EasyExcel

概述

EasyExcel是阿里巴巴开源的一个excel处理框架,以使用简单、节省内存著称。EasyExcel能大大减少占用内存的主要原因是在解析Excel时没有将文件数据一次性全部加载到内存中,而是从磁盘上一行行读取数据,逐个解析。

EasyExcel特点

  • Java领域解析、生成Excel比较有名的框架有Apache poi、jxl等。但他们都存在一个严重的问题就是非常的耗内存。如果你的系统并发量不大的话可能还行,但是一旦并发上来后一定会OOM或者JVM频繁的full gc。
  • EasyExcel采用一行一行的解析模式,并将一行的解析结果以观察者的模式通知处理(AnalysisEventListener)
  • EasyExcel是一个基于Java的简单、省内存的读写Excel的开源项目。在尽可能节约内存的情况下支持读写百M的Excel。
    比较一下二者的区别
    在这里插入图片描述

硅谷课堂笔记(上)_第66张图片

读写操作

EasyExcel写操作

硅谷课堂笔记(上)_第67张图片

(1)pom中引入xml相关依赖

<dependencies>
    
    <dependency>
        <groupId>com.alibabagroupId>
        <artifactId>easyexcelartifactId>
        <version>2.1.1version>
    dependency>
dependencies>

(2)创建实体类
Excel作为一种表,和数据库一样,也应该有实体类与之对应

设置表头和添加的数据字段

@Data
public class Stu {
    //设置表头名称
    @ExcelProperty("学生编号")
    private int sno;
    //设置表头名称
    @ExcelProperty("学生姓名")
    private String sname;
}

(3)实现写操作

创建方法循环设置要添加到Excel的数据

//循环设置要添加的数据,最终封装到list集合中
private static List<Stu> data() {
    List<Stu> list = new ArrayList<Stu>();
    for (int i = 0; i < 10; i++) {
        Stu data = new Stu();
        data.setSno(i);
        data.setSname("张三"+i);
        list.add(data);
    }
    return list;
}

实现最终的添加操作

public static void main(String[] args) throws Exception {
    // 写法1
    String fileName = "F:\\11.xlsx";
    // 这里 需要指定写用哪个class去写,然后写到第一个sheet,名字为模板 然后文件流会自动关闭
    // 如果这里想使用03 则 传入excelType参数即可
    EasyExcel.write(fileName, 对应实体类.class).sheet("sheet表名").doWrite(data());
}

硅谷课堂笔记(上)_第68张图片
这个时候,在D盘中已经生成了一个对应的Excel文件
在这里插入图片描述
硅谷课堂笔记(上)_第69张图片

EasyExcel读操作

硅谷课堂笔记(上)_第70张图片

(1)创建实体类

@Data
public class Stu {
    //设置表头名称
    //设置列对应的属性 index代表表头下标,从0开始
    @ExcelProperty(value = "学生编号",index = 0)
    private int sno;
    //设置表头名称
    //设置列对应的属性
    @ExcelProperty(value = "学生姓名",index = 1)
    private String sname;
}

(2)创建读取操作的监听器

public class ExcelListener extends AnalysisEventListener<Stu> {
    //创建list集合封装最终的数据
    List<Stu> list = new ArrayList<Stu>();
    //一行一行去读取excle内容
    //默认从第二行开始读,第一行默认表头,表头在下面的invokeHeadMap中读
    @Override
    public void invoke(Stu user, AnalysisContext analysisContext) {
        System.out.println("***"+user);
        list.add(user);
    }
    //读取excel表头信息(第一行)
    @Override
    public void invokeHeadMap(Map<Integer, String> headMap, AnalysisContext context) {
        System.out.println("表头信息:"+headMap);
    }
    //读取完成后执行
    @Override
    public void doAfterAllAnalysed(AnalysisContext analysisContext) {
    }
}

(3)调用实现最终的读取

   public static void main(String[] args) throws Exception {
   //指定读取路径
        String fileName = "D:\\11.xlsx";
        // 这里 需要指定读用哪个class去读,然后读取第一个sheet 文件流会自动关闭
        EasyExcel.read(fileName, 实体类.class, new ExcelListener()).sheet().doRead();
}

测试一下,已经读取到内存了
硅谷课堂笔记(上)_第71张图片

功能实现-课程分类导入导出

思路
硅谷课堂笔记(上)_第72张图片

实体类创建

在model模块下,创建课程表对应实体类,Excel版Subject专用
和普通的Subject分隔开
硅谷课堂笔记(上)_第73张图片

导出接口编写

硅谷课堂笔记(上)_第74张图片
硅谷课堂笔记(上)_第75张图片

整合导出前端

硅谷课堂笔记(上)_第76张图片
加入这俩按钮

<div class="el-toolbar">
    <div class="el-toolbar-body" style="justify-content: flex-start;">
      <el-button type="text" @click="exportData"><i class="fa fa-plus"/> 导出</el-button>
    </div>
</div>

JS逻辑
硅谷课堂笔记(上)_第77张图片

导入接口编写

controller接口
硅谷课堂笔记(上)_第78张图片
因为读操作要用监听器,所以创建一个

@Component
public class SubjectListener extends AnalysisEventListener<SubjectEeVo> {

    @Autowired
    private SubjectMapper subjectMapper;

    //一行一行读取
    @Override
    public void invoke(SubjectEeVo subjectEeVo, AnalysisContext analysisContext) {
        //调用方法添加数据库
        Subject subject = new Subject();
        BeanUtils.copyProperties(subjectEeVo,subject);
        subjectMapper.insert(subject);
    }
    @Override
    public void doAfterAllAnalysed(AnalysisContext analysisContext) {
    }
}

硅谷课堂笔记(上)_第79张图片

ServiceImpl层
硅谷课堂笔记(上)_第80张图片

整合导入前端

(1)在list.vue页面添加导入按钮

<el-button type="text" @click="importData"><i class="fa fa-plus"/> 导入</el-button>

(2)添加导入弹出层

<el-dialog title="导入" :visible.sync="dialogImportVisible" width="480px">
    <el-form label-position="right" label-width="170px">
        <el-form-item label="文件">
            <el-upload
                       :multiple="false"
                       :on-success="onUploadSuccess"
                       :action="'http://localhost:8301/admin/vod/subject/importData'"
                       class="upload-demo">
                <el-button size="small" type="primary">点击上传</el-button>
                <div slot="tip" class="el-upload__tip">只能上传xls文件,且不超过500kb</div>
            </el-upload>
        </el-form-item>
    </el-form>
    <div slot="footer" class="dialog-footer">
        <el-button @click="dialogImportVisible = false">取消</el-button>
    </div>
</el-dialog>

(3)添加导入弹出层属性

data() {
    return {
        dialogImportVisible: false,
        list:[] //数据字典列表数组
    }
},

(4)添加导入方法

importData() {
    this.dialogImportVisible = true
},
onUploadSuccess(response, file) {
    this.$message.info('上传成功')
    this.dialogImportVisible = false
    this.getSubList(0)
},

测试一下,导入成功

硅谷课堂笔记(上)_第81张图片

后台开发-点播管理模块

硅谷课堂笔记(上)_第82张图片

涉及数据表

硅谷课堂笔记(上)_第83张图片
课程基本信息表course
硅谷课堂笔记(上)_第84张图片
课程描述表course_description
硅谷课堂笔记(上)_第85张图片

章节表chapter
硅谷课堂笔记(上)_第86张图片
小节和视频表video
硅谷课堂笔记(上)_第87张图片
课程分类表subject
硅谷课堂笔记(上)_第88张图片

根据相关表生成数据

硅谷课堂笔记(上)_第89张图片

硅谷课堂笔记(上)_第90张图片

后端接口编写

课程列表带条件的分页

硅谷课堂笔记(上)_第91张图片

controller代码位置硅谷课堂笔记(上)_第92张图片
service代码位置
硅谷课堂笔记(上)_第93张图片

整合课程列表前端

先引入路由
硅谷课堂笔记(上)_第94张图片
这样新的列表就出来了
硅谷课堂笔记(上)_第95张图片
创建对应的页面
硅谷课堂笔记(上)_第96张图片

在api目录创建course.js文件
硅谷课堂笔记(上)_第97张图片
在api目录teacher.js文件定义接口
硅谷课堂笔记(上)_第98张图片
编写list.vue页面,直接CV了
硅谷课堂笔记(上)_第99张图片

课程列表接口

发布新课程
硅谷课堂笔记(上)_第100张图片
要操作两个表
在这里插入图片描述
无非就是把前端传来的CourseVo拆分成Course和CourseDescription这两个对象,分别传入对应的表
还是比较好做的
controller位置
硅谷课堂笔记(上)_第101张图片
service位置:
硅谷课堂笔记(上)_第102张图片

整合课程添加前端

课程列表list.vue添加方法
硅谷课堂笔记(上)_第103张图片
course.js定义接口
硅谷课堂笔记(上)_第104张图片
添加课程按钮标签在这里添加
硅谷课堂笔记(上)_第105张图片
硅谷课堂笔记(上)_第106张图片

点击添加后课程具体信息列表
硅谷课堂笔记(上)_第107张图片

硅谷课堂笔记(上)_第108张图片

课程列表修改课程基本信息

一看就是个更新信息,按ID查询回显+update操作
按ID查询的URL
注意,这个getById返回的是Vo,因为要带着课程描述一起更改,所以返回的是CourseFormVo

获取课程Form

硅谷课堂笔记(上)_第109张图片

Controller位置
硅谷课堂笔记(上)_第110张图片
ServiceImpl位置
硅谷课堂笔记(上)_第111张图片

更新课程

硅谷课堂笔记(上)_第112张图片

Controller位置
硅谷课堂笔记(上)_第113张图片
ServiceImpl位置
硅谷课堂笔记(上)_第114张图片

编辑大纲Bug

点击修改之后编辑信息进入下一步
硅谷课堂笔记(上)_第115张图片
硅谷课堂笔记(上)_第116张图片
发出的RestFul请求的id是null,这个明显是不对的
硅谷课堂笔记(上)_第117张图片
这里少了两个id,一个是课程表单ID,另一个是课程的描述id

一个是课程表单ID
看看前端的方法,明显是需要一个course的返回值的

硅谷课堂笔记(上)_第118张图片

在CourseController里的update方法
原来这里是没有返回值的

硅谷课堂笔记(上)_第119张图片
课程描述ID
硅谷课堂笔记(上)_第120张图片
这个BUG折磨了我一晚上,淦
希望能帮到诸位小伙伴

整合修改课程基本信息前端

course.js定义方法
硅谷课堂笔记(上)_第121张图片
修改Info.vue页面,引入样式信息
硅谷课堂笔记(上)_第122张图片
创建Chapter-index.vue页面
CV了样式,就那样了~

硅谷课堂笔记(上)_第123张图片

硅谷课堂笔记(上)_第124张图片

硅谷课堂笔记(上)_第125张图片

课程大纲列表功能

后端接口编写

表关系
硅谷课堂笔记(上)_第126张图片

硅谷课堂笔记(上)_第127张图片

重点就放在章节和小节的接口上
看看大纲的数据JSON结构:
数组结构的JSON,明显是返回List集合
在这里插入图片描述
Controller位置
硅谷课堂笔记(上)_第128张图片
业务比较复杂,在Service单独分离出来的业务
在这个路径下,欢迎去Gitee查看~
硅谷课堂笔记(上)_第129张图片

整合课程大纲前端

定义对应JS的API,都是CRUD的内容
硅谷课堂笔记(上)_第130张图片
画前端的页面,直接CV样式了
硅谷课堂笔记(上)_第131张图片

小节视频后端接口编写

这个模块都是单表的CRUD,在Controller层直接用MybatisPlus就可以实现
所以只有Controller层
硅谷课堂笔记(上)_第132张图片

整合视频小节前端

硅谷课堂笔记(上)_第133张图片

发布课程-课程最终发布

硅谷课堂笔记(上)_第134张图片

课程最终发布接口

一共有两个接口,一个是回显的根据id查询课程信息,另一个是根据ID发布课程(更新一下是否发布的字段)

根据id查询课程信息
Controller位置:
硅谷课堂笔记(上)_第135张图片
service层
硅谷课堂笔记(上)_第136张图片
Mapper接口对应
硅谷课堂笔记(上)_第137张图片
这次是多表联查,不用MP了,用Mybatis去编写XML文件直接查多表
硅谷课堂笔记(上)_第138张图片
根据ID发布课程
发布课程,相当于把字段更新了
controller位置:和上面一样,Service也一样

小Bug

Mybatis的绑定问题
这种问题无外乎两种
硅谷课堂笔记(上)_第139张图片
第一种:Mapper接口名称和XML文件的id对不上,没绑定上自然就报错了。这个要仔细检查
第二种:Maven没有加载这个文件
硅谷课堂笔记(上)_第140张图片
修改POM文件(就在当前模块下):
在POM最末尾(也就是 之前)

<build>
    <plugins>
        <plugin>
            <groupId>org.springframework.bootgroupId>
            <artifactId>spring-boot-maven-pluginartifactId>
        plugin>
    plugins>
    <resources>
        <resource>
            <directory>src/main/javadirectory>
            <includes>
                <include>**/*.ymlinclude>
                <include>**/*.propertiesinclude>
                <include>**/*.xmlinclude>
            includes>
            <filtering>falsefiltering>
        resource>
        <resource>
            <directory>src/main/resourcesdirectory>
            <includes> <include>**/*.ymlinclude>
                <include>**/*.propertiesinclude>
                <include>**/*.xmlinclude>
            includes>
            <filtering>falsefiltering>
        resource>
    resources>
build>

修改properties文件

mybatis-plus.mapper-locations=classpath:com/atguigu/ggkt/vod/mapper/xml/*.xml

整合课程发布前端

先是引入相关JS,在API目录下的course.js定义接口
再去复制样式 编写Publish.vue
硅谷课堂笔记(上)_第141张图片

删除课程

一个课程下包含多个内容
硅谷课堂笔记(上)_第142张图片

课程删除接口

(1)编写课程Controller

@ApiOperation(value = "删除课程")
@DeleteMapping("remove/{id}")
public Result remove(@PathVariable Long id) {
    courseService.removeCourseById(id);
    return Result.ok();
}

(2)编写课程Service

    //删除课程
    @Override
    public void removeCourseById(Long id) {
        //根据课程id删除小节
        videoService.removeVideoByCourseId(id);
        //根据课程id删除章节
        chapterService.removeChapterByCourseId(id);
        //根据课程id删除描述
        descriptionService.removeById(id);
        //根据课程id删除课程
        baseMapper.deleteById(id);
    }

(3)编写VideoService

@Service
public class VideoServiceImpl extends ServiceImpl<VideoMapper, Video> implements VideoService {

    //根据课程id删除小节
    @Override
    public void removeVideoByCourseId(Long id) {
        QueryWrapper<Video> wrapper = new QueryWrapper<>();
        wrapper.eq("course_id",id);
        baseMapper.delete(wrapper);
    }
}

(4)编写ChapterService

   //根据课程id删除章节
    @Override
    public void removeChapterByCourseId(Long id) {
        QueryWrapper<Chapter> wrapper = new QueryWrapper<>();
        wrapper.eq("course_id",id);
        baseMapper.delete(wrapper);
    }

整合前端

API下course.js定义接口
course -> list.vue添加方法
都是老生常谈,欢迎到Gitee查看

后台开发-点播模块

播放统计模块

课程统计需求
在这里插入图片描述
用折线图来显示观看人数数据
还可以通过时间区间对数据进行约束
硅谷课堂笔记(上)_第143张图片

所以涉及的表就是video_visitor

硅谷课堂笔记(上)_第144张图片
折线图对应的就是Echars
分析一下返回数据,一个要放x轴的日期,一个要放y轴的数量
硅谷课堂笔记(上)_第145张图片
所以,对应的就是两个集合,来存放不同的数据
因为是K-V的形式拿到最后的数据,所以这里用Key-集合Value的形式
Controller位置:硅谷课堂笔记(上)_第146张图片

这里放出Mapper和Service的内容
硅谷课堂笔记(上)_第147张图片
硅谷课堂笔记(上)_第148张图片
最终查出来的效果,对播放数量进行了统计
硅谷课堂笔记(上)_第149张图片

整合播放统计模块前端

Echars肯定不用想,必用
安装ECharts组件
ECharts是百度的一个项目,后来百度把Echart捐给apache,用于图表展示,提供了常规的折线图、柱状图、散点图、饼图、K线图,用于统计的盒形图,用于地理数据可视化的地图、热力图、线图,用于关系数据可视化的关系图、treemap、旭日图,多维数据可视化的平行坐标,还有用于 BI 的漏斗图,仪表盘,并且支持图与图之间的混搭。

官方网站:https://echarts.apache.org/zh/index.html

npm install --save [email protected]

编写页面

创建chart.vue页面直接CV了~
硅谷课堂笔记(上)_第150张图片

整合腾讯云点播

上传视频
在发布课程时候,需要添加课时并且上传课程视频,这个时候需要使用到腾讯云点播服务进行上传视频管理
硅谷课堂笔记(上)_第151张图片

需求分析
硅谷课堂笔记(上)_第152张图片

云点播服务

这个功能要去腾讯云开一个点播服务的,大概几块钱的流量就可以了
腾讯云点播服务:https://console.cloud.tencent.com/vod/register

硅谷课堂笔记(上)_第153张图片
开通好了进来就自带体验流量
硅谷课堂笔记(上)_第154张图片

上传视频

上传视频可将视频上传到云点播的存储中,以进行后续的处理和分发等。

  • 单击左侧菜单栏【媒资管理 > 视频管理】,默认展示【已上传】标签页;
  • 点击【上传视频】按钮;
  • 单击【选择视频】,选择本地视频文件;
  • 单击【开始上传】;
  • 页面将自动跳转至【正在上传】标签页, 本地文件所在行【状态】栏为“上传成功”时,单击【已上传】标签页,可见完成上传的视频;
    硅谷课堂笔记(上)_第155张图片
    到这里就上传完毕了,单击【管理】,可以查看视频详情;
    硅谷课堂笔记(上)_第156张图片
前端集成播放页面

前端集成有两种方式,使用“超级播放器预览”与“web播放器预览”,或者代码已经不更新,推荐使用前者,因此“web播放器预览”仅做了解。

1、查看“web播放器预览”;
硅谷课堂笔记(上)_第157张图片
说明:需要将视频进行转码,才能支持超级播放器播放,转码为:自适应码流

2、查看“任务流设置”

硅谷课堂笔记(上)_第158张图片
3、点击查看详情
硅谷课堂笔记(上)_第159张图片
当前任务流就是系统默认的“自适应码流”任务流

4、在【音视频管理】重新上传视频

5、查看详情,下面有HTML代码,复制粘贴到浏览器就可以使用
硅谷课堂笔记(上)_第160张图片

云点播服务端接口

因为是视频点播接口,相关类需要创建Vod相关的播放接口
因为服务在腾讯云上,所以这里就不需要有Mapper相关接口了
硅谷课堂笔记(上)_第161张图片

引入点播相关POM依赖
< exclusion>是避免日志和SpringBoot的日志有冲突

<dependency>
    <groupId>com.qcloudgroupId>
    <artifactId>vod_apiartifactId>
    <version>2.1.4version>
    <exclusions>
        <exclusion>
            <groupId>org.slf4jgroupId>
            <artifactId>slf4j-log4j12artifactId>
        exclusion>
    exclusions>
dependency>

腾讯云点播Java文档:https://cloud.tencent.com/document/product/266/10276

后端上传视频

硅谷课堂笔记(上)_第162张图片
Controller位置:Service_Vod下的com.cc.service_vod.controller.VodController
硅谷课堂笔记(上)_第163张图片
ServiceImpl 这里要引入腾讯云官方的SDK

ConstantPropertiesUtil是读取properties的工具类,通过这个工具类读取出相关配置内容,都是静态变量

    //上传视频
    @Override
    public String uploadVideo(InputStream inputStream, String originalFilename) {
        try {
            VodUploadClient client =
                    new VodUploadClient(ConstantPropertiesUtil.ACCESS_KEY_ID,
                            ConstantPropertiesUtil.ACCESS_KEY_SECRET);
            VodUploadRequest request = new VodUploadRequest();
            //视频本地地址
            request.setMediaFilePath("D:\\测试视频.mp4");
            //指定任务流,就是之前你上传时设置的那个
            request.setProcedure("任务流");
            //调用上传方法,传入接入点地域及上传请求。
            VodUploadResponse response = client.upload("对应的AP节点", request);
            //返回文件id保存到业务表,用于控制视频播放
            String fileId = response.getFileId();
            System.out.println("Upload FileId = {}"+response.getFileId());
            return fileId;
        } catch (Exception e) {
            System.out.println(e.toString());
        }
        return null;
    }

后端删除视频

Controller和上面一样,重点Service不太一样
还是腾讯云SDK的内容可在线生成相关删除代码:
地址:https://console.cloud.tencent.com/api/explorer?Product=vod&Version=2018-07-17&Action=DescribeMediaInfos&SignVersion=
硅谷课堂笔记(上)_第164张图片

生成出来的Service代码

    //删除视频
    @Override
    public void removeVideo(String videoSourceId) {
       try{
            // 实例化一个认证对象,入参需要传入腾讯云账户secretId,secretKey,此处还需注意密钥对的保密
            Credential cred = 
                    new Credential(ConstantPropertiesUtil.ACCESS_KEY_ID, 
                            ConstantPropertiesUtil.ACCESS_KEY_SECRET);
            // 实例化要请求产品的client对象,clientProfile是可选的
            VodClient client = new VodClient(cred, "");
            // 实例化一个请求对象,每个接口都会对应一个request对象
            DeleteMediaRequest req = new DeleteMediaRequest();
            //设置删除视频ID
            req.setFileId(videoSourceId);
            // 返回的resp是一个DeleteMediaResponse的实例,与请求对象对应
            DeleteMediaResponse resp = client.DeleteMedia(req);
            // 输出json格式的字符串回包
            System.out.println(DeleteMediaResponse.toJsonString(resp));
        } catch (TencentCloudSDKException e) {
            System.out.println(e.toString());
        }
    }

点播服务整合前端

定义vod.js
硅谷课堂笔记(上)_第165张图片
CV页面样式 修改Video -> Form.vue页面
硅谷课堂笔记(上)_第166张图片
硅谷课堂笔记(上)_第167张图片

腾讯云上传视频其他方式

在这里插入图片描述

之前的缺点

上传代码的部分有Bug,上传路径写固化了,而且没有官方解决办法
硅谷课堂笔记(上)_第168张图片
所以这里有了新的办法就是下面的客户端上传视频
更改是服务端Server上传

客户端上传视频

https://cloud.tencent.com/document/product/266/9219
在这里插入图片描述
操作步骤一(申请上传签名)
找到Java签名示例
硅谷课堂笔记(上)_第169张图片
硅谷课堂笔记(上)_第170张图片
复制一下,编写签名工具类
Signature类 在Util包下
在这里插入图片描述
在编写Controller来获取生成的签名,还是在那个包的Controller

整合客户端前端页面

因为上传也是一个页面嘛,所以也要对应的有页面进行处理
复制粘贴腾讯云给的示例代码

https://tencentyun.github.io/vod-js-sdk-v6/

请 单击此处 查看 script 方式引入的 Demo,请 单击此处 查看 Demo 源码。
创建之后把 Demo 源码CV进去
在这里插入图片描述
在页面上右键,跑起来,就可以对客户端上传进行测试
硅谷课堂笔记(上)_第171张图片

硅谷课堂笔记(上)_第172张图片

完善删除视频功能

将课程中对应的视频全部删除
VideoController 删除小节时带着这个小节下的视频全删掉

@ApiOperation(value = "删除")
@DeleteMapping("remove/{id}")
public Result remove(@PathVariable Long id) {
    videoService.removeVideoById(id);
    return Result.ok();
}

提前注入,一会要调用服务删视频
硅谷课堂笔记(上)_第173张图片
一共两个接口,一个是根据课程id删除小节,另一个是根据小节id删除小节删除视频
硅谷课堂笔记(上)_第174张图片

从这里开始就算是硅谷课堂的上半部分了,因为开始了分布式的内容
硅谷课堂中间部分笔记
具体链接可以看看博客主页~

你可能感兴趣的:(在线课堂内容,笔记,数据库,java,开发语言)