谷粒学院-第八天-前端功能完善

目录

目录

一、内容介绍

二、添加课程基本信息完善

2.1 整合文本编辑器

2.1.1 复制文本编辑器组件 

2.22 找到guli-admin/build/webpack.dev.conf.js 中添加配置

2.1.3 引入js脚本

2.1.4 页面使用文本编辑器组件(使用标签实现文本编辑组件)

2.1.5 最终效果展示

三、课程大纲管理

3.1 修改课程基本信息功能(编写封装代码)

3.1.1 第一步

3.1.2 第二步

3.1.3 前端整合

3.3 修改课程基本信息

 3.3.1 开发后端接口

 3.3.2 前端接口修改

 3.3.3 在info页面实现数据回显

 3.3.4 修改信息后保存下一步按钮实现

 3.2 章节添加 修改 删除

3.2.1 添加章节的实现(页面)

 3.2.2 章节的实现(后端接口)

  3.2.2 章节的实现(前端接口)

3.3 小节功能实现

3.3.1 接口实现(后端) EduVideoController

 3.3.2 接口实现(前端)

四、 课程信息确认 

 4.1 定义Vo



一、内容介绍

1、添加课程基本信息完善

(1)整合文本编辑器

2、课程大纲管理

(1)课程大纲列表显示

(2)章节添加 修改 删除

(3)小节添加 修改 删除

3、课程信息确认

(1)编写sql语句实现

(2)课程最终发布

二、添加课程基本信息完善

2.1 整合文本编辑器

2.1.1 复制文本编辑器组件 

2.22 找到guli-admin/build/webpack.dev.conf.js 中添加配置

      templateParameters: {
        BASE_URL: config.dev.assetsPublicPath + config.dev.assetsSubDirectory
      }

2.1.3 引入js脚本

在guli-admin/index.html 中引入js脚本

<script src=<%= BASE_URL %>/tinymce4.7.5/tinymce.min.js></script>
<script src=<%= BASE_URL %>/tinymce4.7.5/langs/zh_CN.js></script>

 爆红无影响 框架解析的问题

2.1.4 页面使用文本编辑器组件(使用标签实现文本编辑组件)

 1 在vue.info引入组件 

 2 声明组件

 3 课程组件

      <!-- 课程简介-->
      <el-form-item label="课程简介">
        <tinymce :height="300" v-model="courseInfo.description" />
      </el-form-item>

 4 组件样式

在info.vue文件的最后添加如下代码,调整上传图片按钮的高度

<style scoped>
.tinymce-container {
  line-height: 29px;
}
</style>

scoped 代表只在当前页面有效

2.1.5 最终效果展示

 最终测试 

如果执行了全局异常处理(图片太大换个小的)

存在的问题

一级分类id为空

解决方法

在CouresInfoVo中加上一级分类字段

 

三、课程大纲管理

3.1 修改课程基本信息功能(编写封装代码)

3.1.1 第一步

创建两个实体类,章节和小节,只在章节实体类中使用list表示小节

chapterVo

@Data
public class ChapterVo {

    private String id;

    private String title;

    //表示小节
    private List<VideoVo> children = new ArrayList<>();
}

VideoVo

@Data
public class VideoVo {

    private String id;

    private String title;
}

3.1.2 第二步

1 controller层

@RestController
@RequestMapping("/eduservice/chapter")
@CrossOrigin
public class EduChapterController {

    @Autowired
    private EduChapterService chapterService;

    //课程大纲列表,根据课程id进行查询
    @GetMapping("getChapterVideo/{courseId}")
    public R getChapterVideo(@PathVariable String courseId){
        List<ChapterVo> list = chapterService.getChapterVideoByCourseId(courseId);
        return R.ok().data("allChapterVideo",list);
    }
}

2 service层

public interface EduChapterService extends IService<EduChapter> {

    //课程大纲列表,根据课程id进行查询
    List<ChapterVo> getChapterVideoByCourseId(String courseId);

3 serviceImpl

@Service
public class EduChapterServiceImpl extends ServiceImpl<EduChapterMapper, EduChapter> implements EduChapterService {

    @Autowired
    private EduVideoService videoService;//注入小节的service

    //课程大纲列表,根据课程id进行查询
    @Override
    public List<ChapterVo> getChapterVideoByCourseId(String courseId) {

        //1 根据课程id查询课程里面所有的章节
        QueryWrapper<EduChapter> wrapperChapter = new QueryWrapper<>();
        wrapperChapter.eq("course_id",courseId);
        List<EduChapter> eduChapterList = baseMapper.selectList(wrapperChapter);

        //2 查询小节
        QueryWrapper<EduVideo> wrapperVideo = new QueryWrapper<>();
        wrapperVideo.eq("course_id",courseId);
        List<EduVideo> eduVideoList = videoService.list(wrapperVideo);

        //创建list集合,用于最终封装数据
        List<ChapterVo> finalList = new ArrayList<>();

        //3 遍历查询章节list集合进行封装
        //遍历查询章节list集合
        for (int i = 0; i < eduChapterList.size(); i++) {
            //每个章节
            EduChapter eduChapter = eduChapterList.get(i);
            //eduChapter对象值复制到ChapterVo里面
            ChapterVo chapterVo = new ChapterVo();
            BeanUtils.copyProperties(eduChapter,chapterVo);
            //把chapterVo放到最终list集合里面
            finalList.add(chapterVo);

            //创建集合,用于封装章节的小节
            List<VideoVo> videoList = new ArrayList<>();
            //4 遍历查询小节list集合,进行封装
            for (int m = 0; m < eduVideoList.size(); m++) {
                //得到每个小节
                EduVideo eduVideo = eduVideoList.get(m);
                //判断:小节里面chapterid和章节里面id是否一样
                if(eduVideo.getChapterId().equals(eduChapter.getId())){
                    //进行封装
                    VideoVo videoVo = new VideoVo();
                    BeanUtils.copyProperties(eduVideo,videoVo);
                    //放到小节封装集合
                    videoList.add(videoVo);
                }
            }
            //把封装之后小节list集合,放到章节对象里面
            chapterVo.setChildren(videoList);
        }

        return finalList;
    }
}

3.1.3 前端整合

1 创建 chapter.js

import request from '@/utils/request'
export default {

  // 1 根据课程id获取章节集合小节数据列表
  getAllChapterVideo(courseId) {
    return request({
      url: '/eduservice/chapter/getChapterVideo/'+courseId,
      method: 'get'
    })
  }
}

2 在chapter.vue引入chapter

 3 定义方法

 

4 定义变量进行赋值

5 调用方法

 6 获取路由id值

7 页面数据显示 

7.1 章节

(1)代码如下

(2)效果展示 (ctrl+f5 强制刷新浏览器)可能因为缓存问题没有显示

7.2 小节

(1)代码

 (2)效果展示

 7.3 用模板

    <!-- 章节 -->
    <ul class="chanpterList">
      <li v-for="chapter in chapterVideoList" :key="chapter.id">
        <p>
          {{ chapter.title }}
         
        </p>
        <!-- 视频 -->
        <ul class="chanpterList videoList">
          <li v-for="video in chapter.children" :key="video.id">
            <p>
              {{ video.title }}
              
            </p>
          </li>
        </ul>
      </li>
    </ul>
    <div>
      <el-button @click="previous">上一步</el-button>
      <el-button :disabled="saveBtnDisabled" type="primary" @click="next"
        >下一步</el-button
      >
    </div>

添加个css样式

</script>
<style scoped>
.chanpterList {
  position: relative;
  list-style: none;
  margin: 0;
  padding: 0;
}
.chanpterList li {
  position: relative;
}
.chanpterList p {
  float: left;
  font-size: 20px;
  margin: 10px 0;
  padding: 10px;
  height: 70px;
  line-height: 50px;
  width: 100%;
  border: 1px solid #ddd;
}
.chanpterList .acts {
  float: right;
  font-size: 14px;
}
.videoList {
  padding-left: 50px;
}
.videoList p {
  float: left;
  font-size: 14px;
  margin: 10px 0;
  padding: 10px;
  height: 50px;
  line-height: 30px;
  width: 100%;
  border: 1px dotted #ddd;
}
</style>

效果展示

3.3 修改课程基本信息

 3.3.1 开发后端接口

1、根据课程id查询课程基本信息接口

(1)cotroller层(EduCourseController)

 (2)service层(EduCourseService)

(3)serviceImpl层(EduCourseServiceImpl)

2、修改课程信息接口

(1)cotroller层(EduCourseController)

 (2)service层(EduCourseService)

(3)serviceImpl层(EduCourseServiceImpl)

 3.3.2 前端接口修改

 1 修改course.js

 2 修改chapter.vue中的方法

 3.3.3 在info页面实现数据回显

1 定义方法

2 变量赋值

 3 方法调用

 4 测试出错

403 出现的可能清空 跨域 或者路径写错

修改后的course.js

 5 存在的问题(二级分类没有回显)

 下拉列表数据回显

根据存储id和分类所有id进行比较,如果比较相同,让相同值进行数据回显

<select>
    <option selected="selected">前端开发</option>
<select/>
<input type="checkbox" checked/>
<input type="radio" checked/>

5.1 先修改create的方法

 5.2 在method创建方法

 5.3 测试 

 3.3.4 修改信息后保存下一步按钮实现

1 在method中写方法

//添加课程
    addCourse(){
       course.addCourseInfo(this.courseInfo).then((response) => {
        //提示消息
        this.$message({
          type: "success",
          message: "添加课程信息成功!",
        });
        //跳转到第二步
        this.$router.push({
          path: "/course/chapter/" + response.data.courseId})
        });
    },
    //修改课程
    updateCourse() {
      course.updateCourseInfo(this.courseInfo)
        .then(response => {
          //提示
          this.$message({
            type:'success',
            message:'修改课程信息成功!',
          });
          //跳转到第二步
        this.$router.push({
          path: "/course/chapter/" + thus.courseId})
        })
    },
    saveOrUpdate() {
      //判断试试添加还是修改
      if(!this.courseInfo.id){
        //添加
        this.addCourse()
      }else{
        this.updateCourse()
      }
    }

 测试效果

 3.2 章节添加 修改 删除

3.2.1 添加章节的实现(页面)

1、 添加按钮 添加章节

(1)先添加按钮 chapter.vue

 (2)章节表单dialog

    <!-- 添加和修改章节表单 -->
    <el-dialog :visible.sync="dialogChapterFormVisible" title="添加章节">
      <el-form :model="chapter" label-width="120px">
        <el-form-item label="章节标题">
          <el-input v-model="chapter.title" />
        </el-form-item>
        <el-form-item label="章节排序">
          <el-input-number
            v-model="chapter.sort"
            :min="0"
            controls-position="right"
          />
        </el-form-item>
      </el-form>
      <div slot="footer" class="dialog-footer">
        <el-button @click="dialogChapterFormVisible = false">取 消</el-button>
        <el-button type="primary" @click="saveOrUpdate">确 定</el-button>
      </div>
    </el-dialog>

 (3)初始化数据

 (4)给按钮绑定事件

 (5)效果

 2、点击添加章节按钮,弹出添加框,输入章节信息,点击保存添加

 3.2.2 章节的实现(后端接口)

删除章节

如果章节里面没有小节,直接删除

如果章节里面有小节,如何删除?

第一种 删除章节的时候,把章节里面所有的小节都删除

第二种 如果删除的章节下面有小节,不让进行删除

1、controller EduChapterController

@RestController
@RequestMapping("/eduservice/chapter")
@CrossOrigin
public class EduChapterController {

    @Autowired
    private EduChapterService chapterService;

    //课程大纲列表,根据课程id进行查询
    @GetMapping("getChapterVideo/{courseId}")
    public R getChapterVideo(@PathVariable String courseId) {
        List<ChapterVo> list = chapterService.getChapterVideoByCourseId(courseId);
        return R.ok().data("allChapterVideo", list);
    }

    //添加章节
    @PostMapping("addChapter")
    public R addChapter(@RequestBody EduChapter eduChapter) {
        chapterService.save(eduChapter);
        return R.ok();
    }

    //根据章节id查询
    @GetMapping("getChapterInfo/{chapterId}")
    public R getChapterInfo(@PathVariable String chapterId) {
        EduChapter eduChapter = chapterService.getById(chapterId);
        return R.ok().data("chapter", eduChapter);
    }

    //修改章节
    @PostMapping("updateChapter")
    public R updateChapter(@RequestBody EduChapter eduChapter) {
        chapterService.updateById(eduChapter);
        return R.ok();
    }

    //删除的方法
    @DeleteMapping("{chapterId}")
    public R deleteChapter(@PathVariable String chapterId) {
        boolean flag = chapterService.deleteChapter(chapterId);
        if (flag) {
            return R.ok();
        } else {
            return R.error();

        }
    }
}

2、service EduChapterService

public interface EduChapterService extends IService<EduChapter> {

    //课程大纲列表,根据课程id进行查询
    List<ChapterVo> getChapterVideoByCourseId(String courseId);

    //删除章节的方法
    boolean deleteChapter(String chapterId);
}

3、 serviceImpl EduChapterServiceImpl

  3.2.2 章节的实现(前端接口)

1、在api下的chapter.js创建接口

import request from '@/utils/request'
export default {

  // 1 根据课程id获取章节集合小节数据列表
  getAllChapterVideo(courseId) {
    return request({
      url: '/eduservice/chapter/getChapterVideo/'+courseId,
      method: 'get'
    })
  },
  //添加章节
  addChapter(chapter) {
    return request({
      url: '/eduservice/chapter/addChapter',
      method: 'post',
      data: chapter
    })
  },
  //根据id查询章节
  getChapter(chapterId){
    return request({
      url: '/eduservice/chapter/getChapterInfo/'+chapterId,
      method: 'get'
    })
  },
  //修改章节
  updateChapter(chapter){
    return request({
      url: '/eduservice/chapter/updateChapter/',
      method: 'post',
      data: chapter
    })
  },
   //删除章节
   deleteChapter(chapterId){
    return request({
      url: '/eduservice/chapter/'+chapterId,
      method: 'delete'
    })
  }
}

2 添加章节

(1)定义data数据

 (2)创建方法

 (3)测试

 修改前端方法(chapter.vue)

后端(EduChapter加上时间自动填充)

 (4)再次测试

(4)存在小bug 重新添加数据 表单没有清空

 绑定方法

 创建修改方法

 测试

 3、修改章节

(1)先增加修改按钮 chapter.vue 

 

(2)实现编辑

先绑定事件(编辑需要查询然后修改 传入id进行查询)

 创建方法

 效果显示 成功回显数据

 修改功能实现

 测试

 4 删除实现

(1)给删除绑定事件

 (2)定义方法

3.3 小节功能实现

3.3.1 接口实现(后端) EduVideoController

 3.3.2 接口实现(前端)

1 先添加按钮

 2 定义方法

3 添加小节弹框

 <!-- 添加和修改课时表单 -->
    <el-dialog :visible.sync="dialogVideoFormVisible" title="添加课时">
      <el-form :model="video" label-width="120px">
        <el-form-item label="课时标题">
          <el-input v-model="video.title" />
        </el-form-item>
        <el-form-item label="课时排序">
          <el-input-number
            v-model="video.sort"
            :min="0"
            controls-position="right"
          />
        </el-form-item>
        <el-form-item label="是否免费">
          <el-radio-group v-model="video.free">
            <el-radio :label="true">免费</el-radio>
            <el-radio :label="false">默认</el-radio>
          </el-radio-group>
        </el-form-item>
        <el-form-item label="上传视频">
          <!-- TODO -->
        </el-form-item>
      </el-form>
      <div slot="footer" class="dialog-footer">
        <el-button @click="dialogVideoFormVisible = false">取 消</el-button>
        <el-button
          :disabled="saveVideoBtnDisabled"
          type="primary"
          @click="saveOrUpdateVideo"
          >确 定</el-button
        >
      </div>
    </el-dialog>

4 给初始值 dialogVideoFormVisible

 5 效果显示

 6 创建video.js

import request from '@/utils/request'
export default {

  //添加小节
  addVideo(video) {
    return request({
      url: '/eduservice/video/addVideo',
      method: 'post',
      data: video
    })
  },
   //删除小节
   deleteVideo(id){
    return request({
      url: '/eduservice/video/'+id,
      method: 'delete'
    })
  }
}

7 去页面调用 chapter.vue 

8 设置章节id和课程id

 9 效果显示

 10 创建按钮

 11 定义方法

12 效果

四、 课程信息确认 

 sql代码

SELECT ec.`id`,ec.`title`,ec.`lesson_num`,
	ecd.`description`,
	et.`name`,
	es1.title AS oneSubject,
	es2.title AS twoSubject
FROM edu_course ec LEFT JOIN edu_course_description ecd ON ec.`id`=ecd.`id`
			    LEFT JOIN edu_teacher et ON ec.`teacher_id` = et.`id`
			    LEFT JOIN edu_subject es1 ON ec.`subject_parent_id`=es1.`id`
			    LEFT JOIN edu_subject es2 ON ec.`subject_id`=es2.`id`
			    WHERE ec.`id`='1441326613974253570'

 4.1 定义Vo

1 定义Vo

@Data
public class CoursePublishVo {
    private String id;
    private String title;
    private String cover;
    private Integer lessonNum;
    private String subjectLevelOne;
    private String subjectLevelTwo;
    private String teacherName;
    private String price;//只用于显示
}

2、数据访问层

3实现:CourseMapper.xml

<!-- sql语句:根据课程id查询课程确认信息 -->
    <select id="getPublishCourseInfo" resultType="com.atguigu.eduservice.entity.vo.CoursePublishVo">
        SELECT ec.`id`,ec.`title`,ec.`price`,ec.`lesson_num` AS lesson_num,ec.`cover`,
               et.`name` AS teacherName,
               es1.`title` AS subjectLevelOne,
               es2.`title` AS subjectLevelTwo
        FROM edu_course ec LEFT JOIN edu_course_description ecd ON ec.`id`=ecd.`id`
                           LEFT JOIN edu_teacher et ON ec.`teacher_id` = et.`id`
                           LEFT JOIN edu_subject es1 ON ec.`subject_parent_id`=es1.`id`
                           LEFT JOIN edu_subject es2 ON ec.`subject_id`=es2.`id`
        WHERE ec.`id`=#{courseId}
    </select>

4 业务层 

EduCourseService

 实现:CourseServiceImpl

5、 测试(报错)

 由maven默认加载机制造成的问题

maven加载时候,把java文件夹里面,java类型文件进行编译,如果换其他类型文件,不会加载

解决方式:

1、赋值xml到tagrget目录中

2、把xml放到resource目录下

3、推荐使用:通过配置实现

(1)pom.xml

(2)项目application.properties

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值