赞
踩
重点就放在章节和小节的接口上
看看大纲的数据JSON结构:
数组结构的JSON,明显是返回List集合
实现课程章节的列表、添加、修改和删除功能
@RestController @RequestMapping("/admin/vod/chapter") @CrossOrigin @Api(tags = "章节管理接口") public class ChapterController { @Autowired private ChapterService chapterService; //1大纲列表(章节和小节列表也叫课时)树形结构显示 截图json数据格式(是个数组。对应java中list集合)children是小节的集合 /** * 第一章 * 第一节 * 第二节 * 第二章 * 第一节 * 第二节 **/ @ApiOperation("大纲列表") @GetMapping("getNestedTreeList/{courseId}") public Result getTreeList(@PathVariable Long courseId){ //看看chapterVo有什么属性,他里面还用到了videoVO这是小节(课时)里面的内容 看看course表跟chapter表字段,还有那张图的映射关系 List<ChapterVo> list=chapterService.getTreeList(courseId); return Result.ok(list); } //2添加章节 @ApiOperation("添加章节") @PostMapping("save") public Result save(@RequestBody Chapter chapter){ chapterService.save(chapter); return Result.ok(null); } //3修改-根据id查询 @ApiOperation("根据id查询章节信息") @GetMapping("get/{id}") public Result get(@PathVariable Long id){ Chapter chapter=chapterService.getById(id); return Result.ok(chapter); } //4修改实现(@putMapping也行,resultufl风格推荐用putMapping) @PostMapping("update") public Result update(@RequestBody Chapter chapter){ chapterService.updateById(chapter); return Result.ok(null); } //5删除章节(这里好像只删除了章节没有删除里面的小节,后边腾讯云点播管理模块三完善了该功能) @DeleteMapping("remove/{id}") public Result remove(@PathVariable Long id){ chapterService.removeById(id); return Result.ok(null); } }
@RequestBody主要用来接收前端传递给后端的json字符串中的数据的(请求体中的数据的);而最常用的使用请求体传参的无疑是POST请求了,所以使用@RequestBody接收数据时,一般都用POST方式进行提交。在后端的同一个接收方法里,@RequestBody与@RequestParam()可以同时使用,@RequestBody最多只能有一个,而@RequestParam()可以有多个。
mybatisplus实现逻辑删除:mybatisplus使用
json格式:
ChapterVo(章节对象)
@ApiModel("课程章节对象")
@Data
public class ChapterVo {
@ApiModelProperty(value = "章节ID")
private Long id;
@ApiModelProperty(value = "章节标题")
private String title;
@ApiModelProperty(value = "排序")
private Integer sort;
@ApiModelProperty(value = "章节下的课时列表")
//小节(课时)用VideoVo进行封装
private List<VideoVo> children = new ArrayList<>();
}
VideoVo(小节也是课时对象)
@ApiModel("课时信息")
@Data
public class VideoVo {
@ApiModelProperty(value = "课时ID")
private Long id;
@ApiModelProperty(value = "课时标题")
private String title;
@ApiModelProperty(value = "是否可以试听")
private Integer isFree;
@ApiModelProperty(value = "排序")
private Integer sort;
@ApiModelProperty(value = "腾讯云视频ID")
private String videoSourceId;
}
course表:
chapter表:
表关系:
效果图:
(1)ChapterService
public interface ChapterService extends IService<Chapter> {
1大纲列表(章节和小节列表也叫课时)树形结构显示
List<ChapterVo> getTreeList(Long courseId);
}
(2)ChapterServiceImpl
@Service public class ChapterServiceImpl extends ServiceImpl<ChapterMapper, Chapter> implements ChapterService { @Autowired private VideoService videoService; //章节小结列表封装 @Override public List<ChapterVo> getTreeList(Long courseId) { //定义最终数据List集合 List<ChapterVo>finalChapterList=new ArrayList<>(); //1根据courseId获取课程所有章节 QueryWrapper<Chapter>wrapperChapter=new QueryWrapper<>(); wrapperChapter.eq("course_id",courseId); //如果是自己的实现类就用baseMapper去查询,不是自己的就调用 List<Chapter>chapterList=baseMapper.selectList(wrapperChapter); //2根据courseId获取课程里面所有小节(课时) video是小节内容 // 利用LambdaQueryWrapper写方便复习一下之前的知识 //其实等同于上边获取课程章节的方法,这里使用java8实现 查询一下::的意义 LambdaQueryWrapper<Video> wrapperVideo=new LambdaQueryWrapper<>(); wrapperVideo.eq(Video::getCourseId,courseId); List<Video> videoList=videoService.list(wrapperVideo); //封装章节(记住一个原则遇到集合要么遍历要么return) //遍历所有章节 自己写的话定义一个sql语句也能实现这是一个嵌套循环,多多理解去 for (int i = 0; i <chapterList.size() ; i++) { //得到课程每个章节 Chapter chapter=chapterList.get(i); // (该集合的泛型为ChapterVo而我们得到课程每个章节为chapter所以要它转换为chapervo中) ChapterVo chapterVo=new ChapterVo(); BeanUtils.copyProperties(chapter,chapterVo); //得到每个章节对象放到finalChaperList集合 finalChapterList.add(chapterVo); //封装章节里的小节 //创建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); } } //把章节里面所有小节集合放到每个章节里面 chapterVo.setChildren(videoVoList); } return finalChapterList; } }
知识补充:
java8中可以通过 “::” 关键字来访问类的构造方法,对象方法,静态方法
ChapterVo:
@ApiModel("课程章节对象")
@Data
public class ChapterVo {
@ApiModelProperty(value = "章节ID")
private Long id;
@ApiModelProperty(value = "章节标题")
private String title;
@ApiModelProperty(value = "排序")
private Integer sort;
@ApiModelProperty(value = "章节下的课时列表")
//小节(课时)用VideoVo进行封装
private List<VideoVo> children = new ArrayList<>();
}
@RestController @RequestMapping("/admin/vod/video") @CrossOrigin @Api(tags = "小节管理接口") public class VideoController { @Autowired private VideoService videoService; //根据id查询小节 @ApiOperation(value = "获取") @GetMapping("get/{id}") public Result get(@PathVariable Long id) { Video video = videoService.getById(id); return Result.ok(video); } //小节新增 @ApiOperation(value = "新增") @PostMapping("save") public Result save(@RequestBody Video video) { videoService.save(video); return Result.ok(null); } //小节修改 @ApiOperation(value = "修改") @PutMapping("update") public Result updateById(@RequestBody Video video) { videoService.updateById(video); return Result.ok(null); } //小节删除 @ApiOperation(value = "删除") @DeleteMapping("remove/{id}") public Result remove(@PathVariable Long id) { videoService.removeById(id); return Result.ok(null); } }
(1)chapter.js
import request from '@/utils/request' const api_name = '/admin/vod/chapter' export default { getNestedTreeList(courseId) { return request({ url: `${api_name}/getNestedTreeList/${courseId}`, method: 'get' }) }, removeById(id) { return request({ url: `${api_name}/remove/${id}`, method: 'delete' }) }, save(chapter) { return request({ url: `${api_name}/save`, method: 'post', data: chapter }) }, getById(id) { return request({ url: `${api_name}/get/${id}`, method: 'get' }) }, updateById(chapter) { return request({ url: `${api_name}/update`, method: 'post', data: chapter }) } }
(2)创建video.js
import request from '@/utils/request' const api_name = '/admin/vod/video' export default { save(video) { return request({ url: `${api_name}/save`, method: 'post', data: video }) }, getById(id) { return request({ url: `${api_name}/get/${id}`, method: 'get' }) }, updateById(video) { return request({ url: `${api_name}/update`, method: 'put', data: video }) }, removeById(id) { return request({ url: `${api_name}/remove/${id}`, method: 'delete' }) } }
(1)Chapter -> index.vue
<template> <div class="app-container"> <!-- 添加章节按钮 --> <div> <el-button type="primary" @click="addChapter()">添加章节</el-button> </div> <!-- 章节列表 --> <ul class="chapterList"> <li v-for="chapter in chapterList" :key="chapter.id"> <p> {{ chapter.title }} <span class="acts"> <el-button type="text" @click="addVideo(chapter.id)">添加课时</el-button> <el-button type="text" @click="editChapter(chapter.id)">编辑</el-button> <el-button type="text" @click="removeChapterById(chapter.id)">删除</el-button> </span> </p> <!-- 视频 --> <ul class="chapterList videoList"> <li v-for="video in chapter.children" :key="video.id"> <p> {{ video.title }} <el-tag v-if="!video.videoSourceId" size="mini" type="danger"> {{ '尚未上传视频' }} </el-tag> <span class="acts"> <el-tag v-if="video.isFree" size="mini" type="success">{{ '免费观看' }}</el-tag> <el-button type="text" @click="editVideo(chapter.id, video.id)">编辑</el-button> <el-button type="text" @click="removeVideoById(video.id)">删除</el-button> </span> </p> </li> </ul> </li> </ul> <!-- 章节表单对话框 --> <chapter-form ref="chapterForm" /> <!-- 课时表单对话框 --> <video-form ref="videoForm" /> <div style="text-align:center"> <el-button type="primary" @click="prev()">上一步</el-button> <el-button type="primary" @click="next()">下一步</el-button> </div> </div> </template> <script> import chapterApi from '@/api/vod/chapter' import videoApi from '@/api/vod/video' // 引入组件 import ChapterForm from '@/views/vod/course/components/Chapter/Form' import VideoForm from '@/views/vod/course/components/Video/Form' export default { // 注册组件 components: { ChapterForm, VideoForm }, data() { return { chapterList: [] // 章节嵌套列表 } }, created() { this.fetchNodeList() }, methods: { // 获取章节小节数据 fetchNodeList() { chapterApi.getNestedTreeList(this.$parent.courseId).then(response => { this.chapterList = response.data }) }, //删除章节 removeChapterById(chapterId) { this.$confirm('此操作将永久删除该章节,是否继续?', '提示', { confirmButtonText: '确定', cancelButtonText: '取消', type: 'warning' }).then(() => { return chapterApi.removeById(chapterId) }).then(response => { this.fetchNodeList() this.$message.success(response.message) }).catch((response) => { if (response === 'cancel') { this.$message.info('取消删除') } }) }, // 添加章节 addChapter() { this.$refs.chapterForm.open() }, // 编辑章节 editChapter(chapterId) { this.$refs.chapterForm.open(chapterId) }, // 添加课时 addVideo(chapterId) { this.$refs.videoForm.open(chapterId) }, // 编辑课时 editVideo(chapterId, videoId) { this.$refs.videoForm.open(chapterId, videoId) }, // 删除课时 removeVideoById(videoId) { this.$confirm('此操作将永久删除该课时, 是否继续?', '提示', { confirmButtonText: '确定', cancelButtonText: '取消', type: 'warning' }).then(() => { return videoApi.removeById(videoId) }).then(response => { this.fetchNodeList() this.$message.success(response.message) }).catch((response) => { if (response === 'cancel') { this.$message.info('取消删除') } }) }, // 上一步 prev() { this.$parent.active = 0 }, // 下一步 next() { this.$parent.active = 2 } } } </script> <style scoped> .chapterList{ position: relative; list-style: none; margin: 0; padding: 0; } .chapterList li{ position: relative; } .chapterList p{ float: left; font-size: 20px; margin: 10px 0; padding: 10px; height: 70px; line-height: 50px; width: 100%; border: 1px solid #DDD; } .chapterList .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 dashed #DDD; } </style>
(2)Chapter -> Form.vue
<template> <!-- 添加和修改章节表单 --> <el-dialog :visible="dialogVisible" title="添加章节" @close="close()"> <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"/> </el-form-item> </el-form> <div slot="footer" class="dialog-footer"> <el-button @click="close()">取 消</el-button> <el-button type="primary" @click="saveOrUpdate()">确 定</el-button> </div> </el-dialog> </template> <script> import chapterApi from '@/api/vod/chapter' export default { data() { return { dialogVisible: false, chapter: { sort: 0 } } }, methods: { open(chapterId) { this.dialogVisible = true if (chapterId) { chapterApi.getById(chapterId).then(response => { this.chapter = response.data }) } }, close() { this.dialogVisible = false // 重置表单 this.resetForm() }, resetForm() { this.chapter = { sort: 0 } }, saveOrUpdate() { if (!this.chapter.id) { this.save() } else { this.update() } }, save() { this.chapter.courseId = this.$parent.$parent.courseId chapterApi.save(this.chapter).then(response => { this.$message.success(response.message) // 关闭组件 this.close() // 刷新列表 this.$parent.fetchNodeList() }) }, update() { chapterApi.updateById(this.chapter).then(response => { this.$message.success(response.message) // 关闭组件 this.close() // 刷新列表 this.$parent.fetchNodeList() }) } } } </script>
(1)Video -> Form.vue
<template> <!-- 添加和修改课时表单 --> <el-dialog :visible="dialogVisible" title="添加课时" @close="close()"> <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" /> </el-form-item> <el-form-item label="是否免费"> <el-radio-group v-model="video.isFree"> <el-radio :label="0">免费</el-radio> <el-radio :label="1">默认</el-radio> </el-radio-group> </el-form-item> <!-- 上传视频 --> <el-form-item label="上传视频"> <el-upload ref="upload" :auto-upload="false" :on-success="handleUploadSuccess" :on-error="handleUploadError" :on-exceed="handleUploadExceed" :file-list="fileList" :limit="1" :before-remove="handleBeforeRemove" :on-remove="handleOnRemove" :action="BASE_API+'/admin/vod/upload'"> <el-button slot="trigger" size="small" type="primary">选择视频</el-button> <el-button :disabled="uploadBtnDisabled" style="margin-left: 10px;" size="small" type="success" @click="submitUpload()">上传</el-button> </el-upload> </el-form-item> </el-form> <div slot="footer" class="dialog-footer"> <el-button @click="close()">取 消</el-button> <el-button type="primary" @click="saveOrUpdate()">确 定</el-button> </div> </el-dialog> </template> <script> import videoApi from '@/api/vod/video' //import vodApi from '@/api/vod/vod' export default { data() { return { BASE_API: 'http://localhost:8301', dialogVisible: false, video: { sort: 0, free: false }, fileList: [], // 上传文件列表 uploadBtnDisabled: false } }, methods: { open(chapterId, videoId) { this.dialogVisible = true this.video.chapterId = chapterId if (videoId) { videoApi.getById(videoId).then(response => { this.video = response.data // 回显 if (this.video.videoOriginalName) { this.fileList = [{ 'name': this.video.videoOriginalName }] } }) } }, close() { this.dialogVisible = false // 重置表单 this.resetForm() }, resetForm() { this.video = { sort: 0, free: false } this.fileList = [] // 重置视频上传列表 }, saveOrUpdate() { if (!this.video.id) { this.save() } else { this.update() } }, save() { this.video.courseId = this.$parent.$parent.courseId videoApi.save(this.video).then(response => { this.$message.success(response.message) // 关闭组件 this.close() // 刷新列表 this.$parent.fetchNodeList() }) }, update() { videoApi.updateById(this.video).then(response => { this.$message.success(response.message) // 关闭组件 this.close() // 刷新列表 this.$parent.fetchNodeList() }) }, // 上传多于一个视频 handleUploadExceed(files, fileList) { this.$message.warning('想要重新上传视频,请先删除已上传的视频') }, // 上传 submitUpload() { this.uploadBtnDisabled = true this.$refs.upload.submit() // 提交上传请求 }, // 视频上传成功的回调 handleUploadSuccess(response, file, fileList) { this.uploadBtnDisabled = false this.video.videoSourceId = response.data this.video.videoOriginalName = file.name }, // 失败回调 handleUploadError() { this.uploadBtnDisabled = false this.$message.error('上传失败2') }, // 删除视频文件确认 handleBeforeRemove(file, fileList) { return this.$confirm(`确定移除 ${file.name}?`) }, // 执行视频文件的删除 handleOnRemove(file, fileList) { if (!this.video.videoSourceId) { return } } } } </script>
添加方法
/** * 根据课程id获取课程发布信息 * @param id * @return */ @ApiOperation("根据id获取课程发布信息") @GetMapping("getCoursePublishVo/{id}") public Result getCoursePublishVoById( @ApiParam(value = "课程ID", required = true) @PathVariable Long id){ CoursePublishVo coursePublishVo = courseService.getCoursePublishVo(id); return Result.ok(coursePublishVo); } /** * 根据课程id发布课程 * @param id * @return */ @ApiOperation("课程最终发布") @PutMapping("publishCourseById/{id}") public Result publishCourseById( @ApiParam(value = "课程ID", required = true) @PathVariable Long id){ courseService.publishCourseById(id); return Result.ok(null); }
CoursePublishVo:
@ApiModel("课程发布对象") @Data public class CoursePublishVo { @ApiModelProperty(value = "课程ID") private String id; @ApiModelProperty(value = "课程标题") private String title; @ApiModelProperty(value = "课程封面图片路径") private String cover; @ApiModelProperty(value = "总课时") private Integer lessonNum; @ApiModelProperty(value = "一级分类标题") private String subjectParentTitle; @ApiModelProperty(value = "二级分类标题") private String subjectTitle; @ApiModelProperty(value = "讲师姓名") private String teacherName; @ApiModelProperty(value = "课程销售价格") private String price;//只用于显示 }
//根据id获取课程发布信息
CoursePublishVo getCoursePublishVo(Long id);
//根据id发布课程
void publishCourseById(Long id);
/*** * 根据课程id获取课程发布信息(涉及三张表课程基本信息表,讲师表,分类表所以要自己写一个sql语句) * @param id * @return */ @Override public CoursePublishVo getCoursePublishVo(Long id) { return baseMapper.selectCoursePublishVoById(id); } /** * 课程最终发布(修改发布状态) * @param id * @return */ @Override public void publishCourseById(Long id) { //根据id获取课程信息 Course course=baseMapper.selectById(id); course.setStatus(1);//1为已经发布 course.setPublishTime(new Date()); baseMapper.updateById(course); }
public interface CourseMapper extends BaseMapper<Course> {
/**
* 根据课程id获取课程发布信息
* @param id
* @return
*/
CoursePublishVo selectCoursePublishVoById(Long id);
}
1.5、编写CourseMapper.xml
<?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.atguigu.ggkt.vod.mapper.CourseMapper"> <select id="selectCoursePublishVoById" resultType="com.atguigu.ggkt.vo.vod.CoursePublishVo"> SELECT c.id, c.title, c.cover, c.lesson_num AS lessonNum, c.price, t.name AS teacherName, s1.title AS subjectParentTitle, s2.title AS subjectTitle FROM 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 WHERE c.id=#{id} </select> </mapper>
left outer join简写left join
sql中subject是关键字,表中的字段名是MySql的关键字时,我们可以在表名上面加``
容易混淆的关键字有subject,describe等等
为什么添加配置:
不添加会报这样的错误,因为扫描不到
(1)application.properties添加
mybatis-plus.mapper-locations=classpath:com/atguigu/ggkt/vod/mapper/xml/*.xml
(2)service模块pom.xml添加
<build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> <resources> <resource> <directory>src/main/java</directory> <includes> <include>**/*.yml</include> <include>**/*.properties</include> <include>**/*.xml</include> </includes> <filtering>false</filtering> </resource> <resource> <directory>src/main/resources</directory> <includes> <include>**/*.yml</include> <include>**/*.properties</include> <include>**/*.xml</include> </includes> <filtering>false</filtering> </resource> </resources> </build>
//获取发布课程信息
getCoursePublishById(id) {
return request({
url: `${api_name}/getCoursePublishVo/${id}`,
method: 'get'
})
},
//发布课程
publishCourseById(id) {
return request({
url: `${api_name}/publishCourseById/${id}`,
method: 'put'
})
},
<template> <div class="app-container"> <!--课程预览--> <div class="ccInfo"> <img :src="coursePublish.cover"> <div class="main"> <h2>{{ coursePublish.title }}</h2> <p class="gray"><span>共{{ coursePublish.lessonNum }}课时</span></p> <p><span>所属分类:{{ coursePublish.subjectParentTitle }} — {{ coursePublish.subjectTitle }}</span></p> <p>课程讲师:{{ coursePublish.teacherName }}</p> <h3 class="red">¥{{ coursePublish.price }}</h3> </div> </div> <div style="text-align:center"> <el-button type="primary" @click="prev()">上一步</el-button> <el-button :disabled="publishBtnDisabled" type="primary" @click="publish()">发布课程</el-button> </div> </div> </template> <script> import courseApi from '@/api/vod/course' export default { data() { return { publishBtnDisabled: false, // 按钮是否禁用 coursePublish: {} } }, created() { if (this.$parent.courseId) { this.fetchCoursePublishById(this.$parent.courseId) } }, methods: { // 获取课程发布信息 fetchCoursePublishById(id) { courseApi.getCoursePublishById(id).then(response => { this.coursePublish = response.data }) }, // 上一步 prev() { this.$parent.active = 1 }, // 下一步 publish() { this.publishBtnDisabled = true courseApi.publishCourseById(this.$parent.courseId).then(response => { this.$parent.active = 3 this.$message.success(response.message) this.$router.push({ path: '/vodcourse/course/list' })//路由跳转 }) } } } </script> <style scoped> .ccInfo { background: #f5f5f5; padding: 20px; overflow: hidden; border: 1px dashed #DDD; margin-bottom: 40px; position: relative; } .ccInfo img { background: #d6d6d6; width: 500px; height: 278px; display: block; float: left; border: none; } .ccInfo .main { margin-left: 520px; } .ccInfo .main h2 { font-size: 28px; margin-bottom: 30px; line-height: 1; font-weight: normal; } .ccInfo .main p { margin-bottom: 10px; word-wrap: break-word; line-height: 24px; max-height: 48px; overflow: hidden; } .ccInfo .main p { margin-bottom: 10px; word-wrap: break-word; line-height: 24px; max-height: 48px; overflow: hidden; } .ccInfo .main h3 { left: 540px; bottom: 20px; line-height: 1; font-size: 28px; color: #d32f24; font-weight: normal; position: absolute; } </style>
知识补充:
{{}}作为html模板,用于输出对象属性和函数返回值,其中内容可以是:变量,三元表达式,函数
绑定简单的键值
fetchCoursePublishById(id) 这里通过这个方法获取对象然后得到相应的值
一个课程下包含多个内容
/**
* 删除课程
* @param id
* @return
*/
@ApiOperation(value = "删除课程")
@DeleteMapping("remove/{id}")
public Result remove(@PathVariable Long id) {
courseService.removeCourseById(id);
return Result.ok(null);
}
//根据id删除课程
void removeCourseById(Long id);
/**
* 根据课程id删除课程信息
* @param id
*/
@Override
public void removeCourseById(Long id) {
//根据课程id删除小节
videoService.removeVideoByCourseId(id);
//根据课程id删除章节
chapterService.removeChapterByCourseId(id);
//根据课程id删除描述
courseDescriptionService.removeById(id);
//根据课程id删除课程
baseMapper.deleteById(id);
}
//根据课程id删除小节
void removeVideoByCourseId(Long id);
//根据课程id删除小节
@Override
public void removeVideoByCourseId(Long id) {
QueryWrapper<Video> wrapper = new QueryWrapper<>();
wrapper.eq("course_id",id);
baseMapper.delete(wrapper);
}
//根据课程id删除章节
void removeChapterByCourseId(Long id);
//根据课程id删除章节
@Override
public void removeChapterByCourseId(Long id) {
QueryWrapper<Chapter> wrapper = new QueryWrapper<>();
wrapper.eq("course_id",id);
baseMapper.delete(wrapper);
}
//删除课程
removeById(id) {
return request({
url: `${api_name}/remove/${id}`,
method: 'delete'
})
},
methods: { ...... // 根据id删除数据 removeById(id) { this.$confirm('此操作将永久删除该课程,以及该课程下的章节和视频,是否继续?', '提示', { confirmButtonText: '确定', cancelButtonText: '取消', type: 'warning' }).then(() => { return courseApi.removeById(id) }).then(response => { this.fetchData() this.$message.success(response.message) }).catch((response) => { // 失败 if (response === 'cancel') { this.$message.info('取消删除') } }) }, }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。