五、课程大纲列表 – 前端开发
1、页面模板
<!-- 章节 --> <ul class="chanpterList"> <li v-for="chapter in chapterVideoList" :key="chapter.id"> <p> {{ chapter.title }} <span class="acts"> <el-button style="" type="text" @click="openVideo(chapter.id)">添加小节</el-button> <el-button style="" type="text" @click="openEditChatper(chapter.id)">编辑</el-button> <el-button type="text" @click="removeChapter(chapter.id)">删除</el-button> </span> </p> <!-- 视频 --> <ul class="chanpterList videoList"> <li v-for="video in chapter.children" :key="video.id"> <p>{{ video.title }} <span class="acts"> <el-button style="" type="text" @click="openEditVideo(video.id)">编辑</el-button> <el-button type="text" @click="removeVideo(video.id)">删除</el-button> </span> </p> </li> </ul> </li> </ul> <div> <el-button @click="previous">上一步</el-button> <el-button :disabled="saveBtnDisabled" type="primary" @click="next">下一步</el-button> </div>
2、页面样式
<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、定义api
import request from '@/utils/request' export default { //根据课程id查询章节和小节 getChapterVideo(courseId) { return request({ url: `/eduservice/chapter/getChapterVideo/${courseId}`, method: 'get' }) } }
4、页面调用
在views/edu/course/chapter.vue 中
created() { //获取路由中的id值 if(this.$route.params && this.$route.params.id) { this.courseId = this.$route.params.id //调用 根据课程id查询章节和小节 this.getChapterVideo() } }, methods:{ //根据课程id查询章节和小节 getChapterVideo() { chapter.getChapterVideo(this.courseId) .then(response =>{ this.chapterVideoList = response.data.allChapterVideo }) }, //...... }
5、效果展示
六、修改课程基本信息(从大纲返回到课程基本信息页面)
流程:点击上一步的时候,回到第一步页面,把课程基本信息数据回显。修改数据后点击保存实现更新数据效果。
1、后端Controller类
//根据课程id查询课程信息 @ApiOperation("查询课程信息") @GetMapping("getCourseInfo/{courseId}") public R getCourseInfo(@PathVariable String courseId){//@PathVariable可以省略嘛??? CourseInfoVo courseInfoVo = courseService.getCourseInfo(courseId); return R.ok().data("courseInfoVo",courseInfoVo); } //根据课程id修改课程信息 @ApiOperation("修改课程信息") @PutMapping("updateCourseInfo") public R updateCourseInfo(@RequestBody CourseInfoVo courseInfoVo){ courseService.updateCourseInfo(courseInfoVo); return R.ok(); }
2、后端Service类
//通过id查询课程信息 @Override public CourseInfoVo getCourseInfo(String courseId) { //1.查询课程信息 EduCourse course = this.baseMapper.selectById(courseId); CourseInfoVo courseInfoVo = new CourseInfoVo(); BeanUtils.copyProperties(course,courseInfoVo); //2.查询课程描述信息 EduCourseDescription courseDescription = courseDescriptionService.getById(courseId); courseInfoVo.setDescription(courseDescription.getDescription()); return courseInfoVo; } //修改课程信息 @Override public void updateCourseInfo(CourseInfoVo courseInfoVo) { //1.修改课程表 EduCourse course = new EduCourse(); BeanUtils.copyProperties(courseInfoVo,course); int update1 = this.baseMapper.updateById(course); if(update1==0){ throw new GuLiException(20001, "修改失败!"); } //2.修改课程描述表 EduCourseDescription courseDescription = new EduCourseDescription(); BeanUtils.copyProperties(courseInfoVo,courseDescription); boolean flag = courseDescriptionService.updateById(courseDescription); if(!flag){ throw new GuLiException(20001, "修改失败!"); } }
3、定义前端两个接口
api/edu/course.js
//根据id查询课程信息 getCourseInfo(courseId) { return request({ url: `/eduservice/course/getCourseInfo/${courseId}`, method: 'get' }) }, //根据id修改课程信息 updateCourseInfo(courseInfoVo) { return request({ url: `/eduservice/course/updateCourseInfo`, method: 'put', data: courseInfoVo }) }
4、修改/edu/course/chapter.vue中路径
5、在info.vue页面实现数据回显
created() { //获取路由id值,回显数据 if(this.$route.params && this.$route.params.id) { this.courseId = this.$route.params.id //调用根据id查询课程的方法 this.getCourseInfo() }else{ //初始化courseInfo this.courseInfo = {cover: 'https://guli-photos.oss-cn-hangzhou.aliyuncs.com/course.jpg'}//先清空... //初始化一级分类 this.getOneSubject() } //初始化讲师列表 this.getListTeacher() }, methods:{ //根据课程id查询,回显数据 getCourseInfo(){ course.getCourseInfo(this.courseId) .then(response => { //在courseInfo课程基本信息,包含一级分类id和二级分类id this.courseInfo = response.data.courseInfoVo //需要补充代码的地方... }) } //.... }
注意:这里我们在运行的时候发现二级分类下拉框没有数据,因为subjectTwoList数组为空,所以只显示查询出来的id。
解决办法就是:因为在courseInfo课程基本信息,包含一级分类id和二级分类id,所以先查询所有一级分类,然后遍历所有一级分类,比较当前courseInfo里面一级分类id 和 所有的一级分类id,如果相同则遍历一级分类下面的二级分类。
subject.getAllSubject().then(response=>{ this.subjectOneList = response.data.list for(var i = 0;i < this.subjectOneList.length;i++){ if(this.subjectOneList[i].id==this.courseInfo.subjectParentId){{ this.subjectTwoList = this.subjectOneList[i].children }} } });
此时启动服务测试,页面所以数据都可正常回显。
6、更新数据 js
这里我们对之前写的加以修改,把添加和修改方法单独提出来写
addCourseInfo(){//添加课程基本信息 course.saveCourseInfo(this.courseInfo) .then(response=>{ this.$message({ type:'success', message:'课程添加成功!' }) //跳转到课程大纲页面 this.$router.push({path:'/course/chapter/'+response.data.courseId}) }).catch(response=>{ this.$message({ type:'error', message:'课程添加失败!' }) }) }, updateCourseInfo(){//修改课程基本信息 course.updateCourseInfo(this.courseInfo).then(response=>{ this.$message({ type:'success', message:'课程修改成功!' }) //跳转到课程大纲页面 this.$router.push({path:'/course/chapter/'+this.courseId}) }).catch(response=>{ this.$message({ type:'error', message:'课程修改失败!' }) }) }, //提交课程信息 saveOrUpdate(){ if(!this.courseInfo.id){ // console.log("添加课程"); this.addCourseInfo() }else{ // console.log("修改课程"); this.updateCourseInfo() } },
7、解决从修改页面跳转到添加页面,页面数据保留的问题
添加一个路径监听,路径发生变化就执行一次初始化方法
created() { this.init() }, watch:{//监听 $route(to,from){//当路由路径发生变化时,方法就会被执行 this.init() } }, methods: { init(){//初始化方法封装 if(this.$route.params && this.$route.params.id){//如果是数据回显 this.courseId = this.$route.params.id //查询课程信息 this.getCourseInfo() }else{//如果是课程添加 this.courseInfo = {cover: 'https://guli-photos.oss-cn-hangzhou.aliyuncs.com/course.jpg'}//先清空... this.getOneSubject()//查询所有一级分类 } // this.getAllSubject()//方法二:级联下拉菜单 this.getTeacherList() } }
8、启动服务测试即可