一.需求
二.实现后端开发的接口
1.根据课程id查询课程基本信息接口
EduCourseController
//根据课程查询课程基本信息
@GetMapping("getCourseInfo/{courseId}")
public R getCourseInfo(@PathVariable String courseId){
CourseInfoVo courseInfoVo= courseService.getCourseInfo(courseId);
return R.ok().data("courseInfoVo",courseInfoVo);
}
EduCourseServiceImpl
需要查询两张表
@Override
public CourseInfoVo getCourseInfo(String courseId) {
//1.查询课程表
EduCourse eduCourse = baseMapper.selectById(courseId);
CourseInfoVo courseInfoVo = new CourseInfoVo();
BeanUtils.copyProperties(eduCourse,courseInfoVo);
//2.查询描述表
EduCourseDescription courseDescription = courseDescriptionService.getById(courseId);
courseInfoVo.setDescription(courseDescription.getDescription());
return courseInfoVo;
}
2.修改课程信息接口
EduCourseController
//修改课程信息
@PostMapping("updateCourseInfo")
public R updateCourseInfo(@RequestBody CourseInfoVo courseInfoVo){
courseService.updateCourseInfo(courseInfoVo);
return R.ok();
}
EduCourseServiceImpl
//修改课程信息
@Override
public void updateCourseInfo(CourseInfoVo courseInfoVo) {
//1.修改课程表
EduCourse eduCourse = new EduCourse();
BeanUtils.copyProperties(courseInfoVo,eduCourse);
int update = baseMapper.updateById(eduCourse);
if(update==0){
throw new GuliException(20001,"修改课程信息失败");
}
//2.修改描述信息
EduCourseDescription description = new EduCourseDescription();
description.setId(courseInfoVo.getId());
description.setDescription(courseInfoVo.getDescription());
courseDescriptionService.updateById(description);
}
三.前端开发
一.实现回显
1.在api里面course.js定义接口两个方法
//根据课程id查询课程基本信息
getCourseInfoId(id){
return request({
url:'/eduservice/course/getCourseInfo/'+id,
method:'get'
})
},
//修改课程信息
updateCourseInfo(courseInfo){
return request({
url: '/eduservice/course/updateCourseInfo',
method:'post',
data:courseInfo
})
}
2.修改chapter页面,跳转路径
previous(){
this.$router.push({path:'/course/info/'+this.courseId})
},
next(){
//跳转到第二步
this.$router.push({path:'/course/publish/'+this.courseId})
}
3.在info页面实现数据回显
1.获取路由器中的课程id,调用根据id查询接口,数据显示
created(){ //如果id有值,则是回显,没有则是添加
//获取路由id
if(this.$route.params&&this.$route.params.id){
this.courseId=this.$route.params.id
//调用根据id查询课程的方法
this.getInfo()
}else{
//初始化所有讲师
this.getListTeacher()
//初始化一级分类
this.getOneSubject()
}
}
2.根据路由中的课程id值得到课程信息,赋值给courseInfo,因为courseinfo和v-model绑定,可以数据回显
<tinymce :height="300" v-model="courseInfo.description"/>
methods:{
//根据课程id查询信息
getInfo(){
course.getCourseInfoId(this.courseId)
.then(resp=>{
this.courseInfo=resp.data.courseInfoVo
//1.查询所有分类,包含一级和二级
subject.getSubjectList()
.then(resp=>{
//2.获取所有一级分类
this.subjectOneList= resp.data.list
//3.把所有一级分类数组进行遍历
for(var i=0;i<this.subjectOneList.length;i++){
//获取每个一级分类
var OneSubject=this.subjectOneList[i]
//比较当前courseInfo里面的一级分类id和所有一级分类id
if(this.courseInfo.subjectParentId==oneSubject.id){
//获取一级分类所有的二级分类
this.subjectTwoList=oneSubject.children
}
}
})
//初始化所有讲师
this.getListTeacher()
})
}
解决bug回显之后二级分类显示id
二级分类的数组没有值,只有id
根据存储id和分类所有id比较,如果比较相同,则让相同值进行回显
3.根据有无id值判断添加还是修改
info.vue
//添加课程的方法
addCourse(){
course.addCourseInfo(this.courseInfo)
.then(resp=>{
//提示
this.$message({
type:'success',
message:'添加课程信息成功'
})
//跳转到第二步 获取课程id
this.$router.push({path:'/course/chapter/'+resp.data.courseId})
})
},
//修改课程的方法
updateCourse(){
course. updateCourseInfo(this.courseInfo)
.then(resp=>{
//提示
this.$message({
type:'success',
message:'修改课程信息成功'
})
//跳转到第二步 获取课程id
this.$router.push({path:'/course/chapter/'+this.courseId})
})
},
saveOrUpdate(){
//判断添加还是修改
if(!this.courseInfo.id){
//添加
this.addCourse()
}else{
this.updateCourse()
}
}
最终代码
<template>
<div class="app-container">
<h2 style="text-align: center;">发布新课程</h2>
<el-steps :active="1" process-status="wait" align-center style="margin-bottom: 40px;">
<el-step title="填写课程基本信息"/>
<el-step title="创建课程大纲"/>
<el-step title="最终发布"/>
</el-steps>
<el-form label-width="120px">
<el-form-item label="课程标题">
<el-input v-model="courseInfo.title" placeholder=" 示例:机器学习项目课:从基础到搭建项目视频课程。专业名称注意大小写"/>
</el-form-item>
<!-- 所属分类 TODO -->
<el-form-item label="课程分类">
<el-select
v-model="courseInfo.subjectParentId"
placeholder="一级分类" @change="subjectLevelOneChanged">
<el-option
v-for="subject in subjectOneList"
:key="subject.id"
:label="subject.title"
:value="subject.id"/>
</el-select>
<!-- 二级分类 -->
<el-select v-model="courseInfo.subjectId" placeholder="二级分类">
<el-option
v-for="subject in subjectTwoList"
:key="subject.id"
:label="subject.title"
:value="subject.id"/>
</el-select>
</el-form-item>
<!-- 课程讲师 TODO -->
<!-- 课程讲师 -->
<el-form-item label="课程讲师">
<el-select
v-model="courseInfo.teacherId"
placeholder="请选择">
<el-option
v-for="teacher in teacherList"
:key="teacher.id"
:label="teacher.name"
:value="teacher.id"/>
</el-select>
</el-form-item>
<el-form-item label="总课时">
<el-input-number :min="0" v-model="courseInfo.lessonNum" controls-position="right" placeholder="请填写课程的总课时数"/>
</el-form-item>
<!-- 课程简介-->
<el-form-item label="课程简介">
<tinymce :height="300" v-model="courseInfo.description"/>
</el-form-item>
<!-- 课程封面 TODO -->
<!-- 课程封面-->
<el-form-item label="课程封面">
<el-upload
:show-file-list="false"
:on-success="handleAvatarSuccess"
:before-upload="beforeAvatarUpload"
:action="BASE_API+'/eduoss/fileoss'"
class="avatar-uploader">
<img :src="courseInfo.cover">
</el-upload>
</el-form-item>
<el-form-item label="课程价格">
<el-input-number :min="0" v-model="courseInfo.price" controls-position="right" placeholder="免费课程请设置为0元"/> 元
</el-form-item>
<el-form-item>
<el-button :disabled="saveBtnDisabled" type="primary" @click="saveOrUpdate">保存并下一步</el-button>
</el-form-item>
</el-form>
</div>
</template>
<script>
import course from '@/api/edu/course'
import subject from '@/api/edu/subject'
import Tinymce from '@/components/Tinymce'
export default {
components: { Tinymce },
data(){
return{
saveBtnDisabled:false,
courseInfo:{
title: '',
subjectId: '',//二级分类id
subjectParentId:'',//一级分类id
teacherId: '',
lessonNum: 0,
description: '',
cover: '/static/01.jpg',
price: 0
},
courseId:'',
BASE_API: process.env.BASE_API, // 接口API地址
teacherList:[],//封装所有的讲师
subjectOneList:[],//一级分类
subjectTwoList:[]//二级分类
}
},
created(){ //如果id有值,则是回显,没有则是添加
//获取路由id
if(this.$route.params&&this.$route.params.id){
this.courseId=this.$route.params.id
//调用根据id查询课程的方法
this.getInfo()
}else{
//初始化所有讲师
this.getListTeacher()
//初始化一级分类
this.getOneSubject()
}
},
methods:{
//根据课程id查询信息
getInfo(){
course.getCourseInfoId(this.courseId)
.then(resp=>{
this.courseInfo=resp.data.courseInfoVo
//1.查询所有分类,包含一级和二级
subject.getSubjectList()
.then(resp=>{
//2.获取所有一级分类
this.subjectOneList= resp.data.list
//3.把所有一级分类数组进行遍历
for(var i=0;i<this.subjectOneList.length;i++){
//获取每个一级分类
var OneSubject=this.subjectOneList[i]
//比较当前courseInfo里面的一级分类id和所有一级分类id
if(this.courseInfo.subjectParentId==oneSubject.id){
//获取一级分类所有的二级分类
this.subjectTwoList=oneSubject.children
}
}
})
//初始化所有讲师
this.getListTeacher()
})
},
//上传封面成功
handleAvatarSuccess(res,file){
this.courseInfo.cover=res.data.url
},
//上传之前调用的方法
beforeAvatarUpload(){
const isJPG = file.type === 'image/jpeg'
const isLt2M = file.size / 1024 / 1024 < 2
if (!isJPG) {
this.$message.error('上传头像图片只能是 JPG 格式!')
}
if (!isLt2M) {
this.$message.error('上传头像图片大小不能超过 2MB!')
}
return isJPG && isLt2M
},
//点击某个一级分类,触发change,显示对应的二级分类
subjectLevelOneChanged(value){
//alert(value)
//遍历所有的分类,里面包含一及和二级
for(var i=0;i<this.subjectOneList.length;i++){
//得到每个一级分类
var OneSubject=this.subjectOneList[i]
// 判断,所有一级分类和点击一级分类id是否一样
if(value===OneSubject.id){
//从一级分类里面获取所有的二级分类
this.subjectTwoList= OneSubject.children
//把二级分类的id清空
this.courseInfo.subjectId=''
}
}
},
//查询所有的一级分类
getOneSubject(){
subject.getSubjectList()
.then(resp=>{
this.subjectOneList= resp.data.list
})
},
getListTeacher(){
course.getListTeacher()
.then(resp=>{
this.teacherList = resp.data.items
})
},
//添加课程的方法
addCourse(){
course.addCourseInfo(this.courseInfo)
.then(resp=>{
//提示
this.$message({
type:'success',
message:'添加课程信息成功'
})
//跳转到第二步 获取课程id
this.$router.push({path:'/course/chapter/'+resp.data.courseId})
})
},
//修改课程的方法
updateCourse(){
course. updateCourseInfo(this.courseInfo)
.then(resp=>{
//提示
this.$message({
type:'success',
message:'修改课程信息成功'
})
//跳转到第二步 获取课程id
this.$router.push({path:'/course/chapter/'+this.courseId})
})
},
saveOrUpdate(){
//判断添加还是修改
if(!this.courseInfo.id){
//添加
this.addCourse()
}else{
this.updateCourse()
}
}
}
}
</script>
<style scoped>
.tinymce-container {
line-height: 29px;
}
</style>