3课程管理模块

三课程管理模块

1具体功能

​ 1.1章节增删改查

​ 1.2小节增删改查

​ 1.3视频上传删除

​ 1.4课程增删改查

​ 1.4.1查询课程

  • 条件查询加分页

  • 课程列表(前端主页,基本信息)(封面,课程信息(课程名字,课程分类),讲师,价格,课程状态(已/未发布),发布时间,操作(修该基本信息,编辑大纲,课程统计,删除))

​ 1.4.2课程增加(三步)

  • 填写课程基本信息(标题,讲师,一/二级分类,课程简介,封面)
  • 创建课程大纲(添加章节,添加小节(同时添加课程,包括是否免费))
  • 最终发布(确认信息将未发布改成已发布)

​ 1.4.3课程修改

  • 根据id跳转到课程增加页面
  • 修改基本信息
  • 修改章节和对应小节

​ 1.4.4课程删除

  • 删除所有章节
  • 删除所有小节

​ 1.5课程统计

  • 根据开始时间到结束时间查看观看课程人数统计

2具体知识点

​ 2.1数据库表关系

​ 2.2腾讯云点播

  • 开通云点播服务
  • 前端集成
  • 后端引入相关依赖
  • 第一步:申请上传签名
    • 1创建Signature类(腾讯云有)
    • 2里面的getUploadSignature方法获得签名
  • 第二步:设置腾讯云API秘钥
  • 第三步:SDK上传
    • 直接使用示例demo

​ 2.2(2)阿里云点播

  • 第一步:开通云点播服务
  • 第二步:引入相关依赖
  • 第三步:初始化操作
    • 创建defaultandclient对象(点播服务接入区域,accessKeyId, accessKeySecret)
  • 第四步:实现将文件转成流,然后调用阿里云sdk的方法
  • 第五步:实现根据视频id获取视频播放凭证的方法
  • 第六步:前端实现(需要视频id,播放凭证)

​ 2.3上传视频具体代码(阿里云)

  • controller

  •     //上传视频到阿里云
        @PostMapping("uploadAlyiVideo")
        public R uploadAlyiVideo(MultipartFile file) {
            //返回上传视频id
            String videoId = vodService.uploadVideoAly(file);
            return R.ok().data("videoId",videoId);
        }
    
  • service

  •     @Override
        public String uploadVideoAly(MultipartFile file) {
    
            try {
                //注意,将文件转成流
                //accessKeyId, accessKeySecret
                //fileName:上传文件原始名称   有可能是01.03.09.mp4
                String fileName = file.getOriginalFilename();
                //title:上传之后显示名称 可以和上面一样 但是我们希望还是不带.mp4
                String title = fileName.substring(0, fileName.lastIndexOf("."));
                //inputStream:上传文件输入流
                InputStream inputStream = file.getInputStream();
    
                UploadStreamRequest request = new UploadStreamRequest(ConstantVodUtils.ACCESS_KEY_ID, ConstantVodUtils.ACCESS_KEY_SECRET, title, fileName, inputStream);
    
                UploadVideoImpl uploader = new UploadVideoImpl();
                UploadStreamResponse response = uploader.uploadStream(request);
    
                String videoId = null;
                if (response.isSuccess()) {
                    videoId = response.getVideoId();
                } else { //如果设置回调URL无效,不影响视频上传,可以返回VideoId同时会返回错误码。其他情况上传失败时,VideoId为空,此时需要根据返回错误码分析具体错误原因
                    videoId = response.getVideoId();
                }
                return videoId;
            }catch(Exception e) {
                e.printStackTrace();
                return null;
            }
        }
    
  • 根据视频id获取视频播放凭证(之后前台会用到)

  •     //根据视频id获取视频凭证
        @GetMapping("getPlayAuth/{id}")
        public R getPlayAuth(@PathVariable String id) {
            try {
    
                System.out.println(id);
                //创建初始化对象
                DefaultAcsClient client =
                        InitVodCilent.initVodClient(ConstantVodUtils.ACCESS_KEY_ID, ConstantVodUtils.ACCESS_KEY_SECRET);
                //创建获取凭证request和response对象
                GetVideoPlayAuthRequest request = new GetVideoPlayAuthRequest();
                //向request设置视频id
                request.setVideoId(id);
                //调用方法得到凭证
                GetVideoPlayAuthResponse response = client.getAcsResponse(request);
                String playAuth = response.getPlayAuth();
                return R.ok().data("playAuth",playAuth);
            }catch(Exception e) {
                throw new GuliException(20001,"获取凭证失败");
            }
        }
    

​ 2.4根据课程id查询章节和小节(大纲列表)

  • @Override
       public List<ChapterVo> getTreeList(Long courseId) {
           //1定义最终数据list集合
           List<ChapterVo> finalChapterList = new ArrayList<>();
      
           //2根据courseId获取课程里面所有章节
           QueryWrapper<Chapter> wrapperChapter = new QueryWrapper<>();
           wrapperChapter.eq("course_id",courseId);
           List<Chapter> chapterList = baseMapper.selectList(wrapperChapter);
      
           //3根据courseId获取课程里面所有小节
           //换一种方式,Lambda表达方式
           LambdaQueryWrapper<Video> wrapperVideo = new LambdaQueryWrapper<>();
           wrapperVideo.eq(Video::getCourseId,courseId);
           List<Video> videoList = videoService.list(wrapperVideo);
      
           //4封装章节
           //遍历所有章节
           for (int i = 0; i < chapterList.size(); i++) {
               //得到课程每个章节
               Chapter chapter = chapterList.get(i);
               // chapter -- ChapterVo
               ChapterVo chapterVo = new ChapterVo();
               BeanUtils.copyProperties(chapter,chapterVo);
               //得到每个章节对象放到finalChapterList集合
               finalChapterList.add(chapterVo);
      
               //5封装章节里面小节
               //创建list集合用户封装章节所有小节
               List<VideoVo> videoVoList = new ArrayList<>();
               //遍历小节list
               for (Video video:videoList) {
                   //判断小节是哪个章节下面
                   //章节id  和 小节chapter_id
                   if(chapter.getId().equals(video.getChapterId())) {
                       // video  -- VideoVo
                       VideoVo videoVo = new VideoVo();
                       BeanUtils.copyProperties(video,videoVo);
                       //放到videoVoList
                       videoVoList.add(videoVo);
                   }
               }
               //6把章节里面所有小节集合放到每个章节里面
               chapterVo.setChildren(videoVoList);
           }
           //7返回最终章节集合
           return finalChapterList;
       }
    

2.5根据课程id查询课程详情

  • 因为有讲师,还有课程分类,涉及多表,所以要自己写xml

  • <!--//根据课程id查询课程详情-->
       <select id="selectCourseVoById" resultType="com.fao.ggkt.vo.vod.CourseVo">
           SELECT
           c.id,
           c.title,
           c.lesson_num AS lessonNum,
           c.price,
           c.cover,
           c.buy_count AS buyCount,
           c.view_count AS viewCount,
           c.status,
           c.publish_time AS publishTime,
           c.teacher_id AS teacherId,
           t.name AS teacherName,
           s1.title AS subjectParentTitle,
           s2.title AS subjectTitle
           FROM
           <include refid="tables"></include>
           WHERE c.id=#{id}
       </select>
      
       <sql id="tables">
           course c
          LEFT OUTER JOIN teacher t ON c.teacher_id=t.id
          LEFT OUTER JOIN `subject` s1 ON c.subject_parent_id=s1.id
          LEFT OUTER JOIN `subject` s2 ON c.subject_id=s2.id
       </sql>
    

2.6删除课程(一起删)

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

2.7课程统计

  • 后端三个参数:courseId, startDate, endDate

  • 返回两个list,一个代表所有日期,一个代表日期对应数量

  • //课程统计的接口
      @Override
      public Map<String, Object> findCount(Long courseId, String startDate, String endDate) {
          //调用mapper的方法
          List<VideoVisitorCountVo> videoVisitorVoList =
                  baseMapper.findCount(courseId,startDate,endDate);
          //创建map集合
          Map<String, Object> map = new HashMap<>();
          //创建两个list集合,一个代表所有日期,一个代表日期对应数量
          //封装数据  代表所有日期
          List<String> dateList =
                  videoVisitorVoList.stream().map(VideoVisitorCountVo::getJoinTime).
                          collect(Collectors.toList());
          //代表日期对应数量
          List<Integer> countList = videoVisitorVoList.stream().map(VideoVisitorCountVo::getUserCount)
                  .collect(Collectors.toList());
          //放到map集合
          map.put("xData", dateList);
          map.put("yData", countList);
          return map;
      }
    
  • xml

  • public interface VideoVisitorMapper extends BaseMapper<VideoVisitor> {
        //课程统计的接口
        List<VideoVisitorCountVo> findCount(@Param("courseId") Long courseId,
                                            @Param("startDate")String startDate,
                                            @Param("endDate")String endDate);
    }
    
  • <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
    <mapper namespace="com.fao.ggkt.vod.mapper.VideoVisitorMapper">
    
        <select id="findCount" resultType="com.fao.ggkt.vo.vod.VideoVisitorCountVo">
            SELECT
            DATE(join_time) AS joinTime,
            COUNT(*) AS userCount
            FROM video_visitor
            <where>
                <if test="startDate != null and startDate != ''">
                    AND DATE(join_time) >= #{startDate}
                </if>
                <if test="endDate != null and endDate != ''">
                    AND DATE(join_time) &lt;= #{endDate}
                </if>
                and course_id=#{courseId}
            </where>
            GROUP BY DATE(join_time)
            ORDER BY DATE(join_time)
        </select>
    </mapper>
    
  • 转成具体sql

  • SELECT
          DATE(join_time) AS joinTime,
          COUNT(*) AS userCount
          FROM video_visitor
          where
                  DATE(join_time) >= '2001-11-22'
                  AND DATE(join_time) <= '2031-11-22 13:39:27'
                  and course_id=1
          GROUP BY DATE(join_time)
          ORDER BY DATE(join_time)
    
  • 前端安装ECharts组件

posted @ 2022-07-14 15:45  fao99  阅读(419)  评论(0)    收藏  举报