一、課程章節列表顯示後端實現
1、創建章節和小節vo類
/**
* 章節和小節的vo類
*/
@Data
@ApiModel("章節和小節的vo類")
public class ChapterVo {
private String id;
private String title;
//如果是章節用於存放其包含小節
//如果是小節則爲空
private List<ChapterVo> children = null;
}
2、服務層
接口
public interface EduChapterService extends IService<EduChapter> {
List<ChapterVo> getChapterByCourseId(String courseId);
}
實現
@Service
public class EduChapterServiceImpl extends ServiceImpl<EduChapterMapper, EduChapter> implements EduChapterService {
@Autowired
private EduVideoMapper videoMapper;
/**
* 根據課程id獲取課程包含的章節和小節信息
* 並以ChapterVo的形式作爲結果集返回
* @param courseId
* @return
*/
@Override
public List<ChapterVo> getChapterByCourseId(String courseId) {
//用於存放章節和小節列表(樹狀)
List<ChapterVo> res = new ArrayList<>();
//根據課程id插入課程所有的章節
QueryWrapper<EduChapter> chapterWrapper = new QueryWrapper<>();
chapterWrapper.eq("course_id", courseId);
List<EduChapter> chapters = baseMapper.selectList(chapterWrapper);
//根絕課程id查詢出該課程所有小節
QueryWrapper<EduVideo> videoWrapper = new QueryWrapper<>();
chapterWrapper.eq("course_id", courseId);
List<EduVideo> videos = videoMapper.selectList(videoWrapper);
for (EduChapter chapter : chapters) {
ChapterVo chapterVo = new ChapterVo();
BeanUtils.copyProperties(chapter, chapterVo);
//爲章節創建children列表
chapterVo.setChildren(new ArrayList<>());
String chapterId = chapterVo.getId();
//遍歷所有小節,將與chapterVo對應的小節存入children列表中
for (EduVideo video : videos) {
if (chapterId != null && chapterId.equals(video.getChapterId())){
ChapterVo videoVo = new ChapterVo();
BeanUtils.copyProperties(video, videoVo);
chapterVo.getChildren().add(videoVo);
}
}
//將章節存入結果集中
res.add(chapterVo);
}
return res;
}
}
3、controller層
@RestController
@RequestMapping("/eduservice/chapter")
@CrossOrigin
@Api("課程章節管理")
public class EduChapterController {
@Autowired
private EduChapterService chapterService;
@ApiOperation("根絕課程id獲取其對應的章節和小節")
@GetMapping("list/{courseId}")
public R getCourseChapter(
@PathVariable("courseId") String courseId) {
List<ChapterVo> list = chapterService.getChapterByCourseId(courseId);
return R.ok().data("list", list);
}
}
4、測試
打開swagger,找到接口輸入課程id,點擊執行
二、課程章節列表顯示前端實現
1、定義api
在scr/api/edu
下創建chapter.js,內容如下:
import request from '@/utils/request'
//表示導出,別的文件可以使用
export default {
/**
* 添加課程信息
*/
getCourseChapter(courseId){
return request({
url: `/eduservice/chapter/list/${courseId}`,
method: 'get',
})
},
}
2、定義組件腳本
定義data
courseId: '', // 所屬課程
chapterNestedList: [] // 章節嵌套課時列表
methods中添加方法
methods: {
//根據課程id獲取章節和小節信息
getCourseChapter(){
chapterApi.getCourseChapter(this.courseId)
.then(response => {
this.chapterNestedList = response.data.list
})
},
...//其他方法
}
created中調用上述方法
created() {
//根據路由獲取url中的id值
if(this.$route.params && this.$route.params.id){
this.courseId = this.$route.params.id
//根據課程id獲取章節和小節信息
this.getCourseChapter()
}
},
3、定義組件模板
<el-button type="text">添加章節</el-button>
<!-- 章節 -->
<ul class="chanpterList">
<li
v-for="chapter in chapterNestedList"
:key="chapter.id">
<p>
{{ chapter.title }}
<span class="acts">
<el-button type="text">添加課時</el-button>
<el-button style="" type="text">編輯</el-button>
<el-button type="text">刪除</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 type="text">編輯</el-button>
<el-button type="text">刪除</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>
4、定義樣式
將樣式的定義放在頁面的最後
scope表示這裏定義的樣式只在當前頁面範圍內生效,不會污染到其他的頁面
<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>
5、效果
三、課程信息回顯實現
1、業務層
接口:CourseService.java
CourseInfoVo getCourseInfoById(String id);
實現:CourseServiceImpl.java
/**
* 根據課程id獲取課程基本信息和課程描述信息
* 並封裝到CourseInfoVo中
* @param id
* @return
*/
@Override
public CourseInfoVo getCourseInfoById(String id) {
CourseInfoVo courseInfo = new CourseInfoVo();
//從數據庫獲取課程基本信息
EduCourse eduCourse = baseMapper.selectById(id);
//將基本信息賦值給courseInfo
BeanUtils.copyProperties(eduCourse, courseInfo);
//從數據庫獲取課程描述信息,描述信息id和課程信息一致
EduCourseDescription description = descriptionService.getById(id);
courseInfo.setDescription(description.getDescription());
return courseInfo;
}
2、controller層
@ApiOperation(value = "根據id獲取課程基本信息")
@GetMapping("{id}")
public R getCourseById(@PathVariable String id) {
//根據id獲取課程基本信息,包括課程描述信息
CourseInfoVo course = courseService.getCourseInfoById(id);
return R.ok().data("course", course);
}
後端實現之後,接下來實現前端的內容
3、定義api
在api/edu/course.js
中添加如下內容
/**
* 根據課程id獲取課程基本信息和課程描述信息
*/
getCourseInfoById(id){
return request({
url: `/eduservice/course/${id}`,
method: 'get',
})
},
4、修改chapter.vue中的跳轉路徑
previous() {
console.log('previous')
this.$router.push({ path: '/course/info/'+this.courseId })
},
next() {
console.log('next')
this.$router.push({ path: '/course/publish/'+this.courseId })
}
5、定義data
在course.vue中
data() {
return {
...
courseId: '', //修改時路徑中傳來的課程id
...
}
}
6、編寫方法
在course.vue中
methods: {
//根據課程id獲取課程信息
getCourseInfo(id){
courseApi.getCourseInfoById(id)
.then(response => {
this.courseInfo = response.data.course
})
},
...
}
7、初始化時調用方法
在course.vue中
created() {
//根據路由獲取url中的id值
if(this.$route.params && this.$route.params.id){
this.courseId = this.$route.params.id
this.getCourseInfo(this.courseId)
}
this.getAllTeacherList()
this.getAllSubjectrList()
},
8、測試
四、解決級聯下拉菜單回顯問題
可以看到上面的測試中課程的二級類編顯示是id而不是名稱,所以我們需要進行解決
1、修改init方法
將 this.initSubjectList()移至else
created() {
//根據路由獲取url中的id值
if(this.$route.params && this.$route.params.id){ //修改
this.courseId = this.$route.params.id
this.getCourseInfo(this.courseId)
} else{ //添加
this.getAllSubjectrList()
}
//獲取講師列表
this.getAllTeacherList()
},
2、修改getCourseInfo方法
//根據課程id獲取課程信息
getCourseInfo(id){
courseApi.getCourseInfoById(id)
.then(response => {
this.courseInfo = response.data.course
//調用接口獲取所有的課程分類信息
subjectApi.getAllSubject()
.then(response => {
debugger
this.subjectParentList = response.data.list
//對一級分類進行遍歷找到其中courseId與this.courseId相等的一級分類
//並將其中包含的二級分類信息賦值爲this.subSubjidectList
for (let i = 0; i < this.subjectParentList.length; i++) {
if (this.subjectParentList[i].id === this.courseInfo.subjectParentId) {
this.subSubjectList = this.subjectParentList[i].children
}
}
})
})
},
3、效果
五、課程信息的更新實現
1、業務層
接口:CourseService.java
void updateCourseInfo(CourseInfoVo course);
實現:CourseServiceImpl.java
/**
* 更新課程基本信息和描述信息
* @param courseInfo
*/
@Override
public void updateCourseInfo(CourseInfoVo courseInfo) {
//創建並賦值EduCourse對象
EduCourse course = new EduCourse();
BeanUtils.copyProperties(courseInfo, course);
//更新數據庫
int update1 = baseMapper.updateById(course);
if (update1 == 0) {
throw new CustomException(20001, "修改課程基本信息失敗");
}
//創建並賦值EduCourseDescription對象
EduCourseDescription description = new EduCourseDescription();
description.setId(courseInfo.getId());
description.setDescription(courseInfo.getDescription());
description.setGmtModified(new Date());
//更新數據庫
boolean update2 = descriptionService.updateById(description);
if (!update2) {
throw new CustomException(20001, "修改課程描述信息失敗");
}
}
2、controller層
@ApiOperation(value = "根據課程基本信息,包括課程描述信息")
@PostMapping("update")
public R updateCourse(@RequestBody CourseInfoVo course) {
courseService.updateCourseInfo(course);
return R.ok();
}
後端實現之後,接下來實現前端的內容
3、定義api
在api/edu/course.js
中添加如下內容
/**
* 更新課程基本信息和描述信息
*/
updateCourseInfo(courseInfo){
return request({
url: `/eduservice/course/update`,
method: 'post',
data:courseInfo
})
},
4、組件js
將之前的next方法修改爲下面的內容
//添加或者修改課程信息
next() {
//更新時會從接口查詢出courseInfo,其中會包括id
if(this.courseInfo.id){ //修改
this.updateCourse()
} else {
this.addCourse()
}
},
//修改課程信息
updateCourse(){
courseApi.updateCourseInfo(this.courseInfo)
.then(response => {
this.$message({
type: 'success',
message: '修改課程信息成功'
})
this.$router.push({ path: '/course/chapter/'+this.courseId })
})
.catch(error => {
this.saveBtnDisabled = false
console.log(error)
}) //請求失敗
},
//添加課程信息
addCourse(){
console.log('next')
this.saveBtnDisabled = true
courseApi.addCourseInfo(this.courseInfo)
.then(response=>{
this.$message({
type: 'success',
message: '添加課程信息成功'
})
this.$router.push({ path: '/course/chapter/'+response.data.id })
})
.catch(error => {
this.saveBtnDisabled = false
console.log(error)
}) //請求失敗
}
5、測試
首先在表單中輸入信息並點擊保存下一步
之後點擊上一步,再次修改表單內容表單
點擊保存並下一步,提示修改課程信息成功
查看數據庫中已經修改成功