1500字范文,内容丰富有趣,写作好帮手!
1500字范文 > 课程发布-课程大纲和课程发布

课程发布-课程大纲和课程发布

时间:2021-06-03 12:57:19

相关推荐

课程发布-课程大纲和课程发布

01-课程大纲列表显示

一、后端实现

1、定义vo

ChapterVo

package com.guli.edu.vo;@ApiModel(value = "章节信息")@Datapublic class ChapterVo implements Serializable {private static final long serialVersionUID = 1L;private String id;private String title;private List<VideoVo> children = new ArrayList<>();}

VideoVo

package com.guli.edu.vo;@ApiModel(value = "课时信息")@Datapublic class VideoVo implements Serializable {private static final long serialVersionUID = 1L;private String id;private String title;private Boolean free;}

2、服务层

接口

package com.guli.edu.service;public interface ChapterService extends IService<Chapter> {List<ChapterVo> nestedList(String courseId);}

实现

package com.guli.edu.service.impl;@Servicepublic class ChapterServiceImpl extends ServiceImpl<ChapterMapper, Chapter> implements ChapterService {@Autowiredprivate VideoService videoService;@Overridepublic List<ChapterVo> nestedList(String courseId) {//最终要的到的数据列表ArrayList<ChapterVo> chapterVoArrayList = new ArrayList<>();//获取章节信息QueryWrapper<Chapter> queryWrapper1 = new QueryWrapper<>();queryWrapper1.eq("course_id", courseId);queryWrapper1.orderByAsc("sort", "id");List<Chapter> chapters = baseMapper.selectList(queryWrapper1);//获取课时信息QueryWrapper<Video> queryWrapper2 = new QueryWrapper<>();queryWrapper2.eq("course_id", courseId);queryWrapper2.orderByAsc("sort", "id");List<Video> videos = videoService.list(queryWrapper2);//填充章节vo数据int count1 = chapters.size();for (int i = 0; i < count1; i++) {Chapter chapter = chapters.get(i);//创建章节vo对象ChapterVo chapterVo = new ChapterVo();BeanUtils.copyProperties(chapter, chapterVo);chapterVoArrayList.add(chapterVo);//填充课时vo数据ArrayList<VideoVo> videoVoArrayList = new ArrayList<>();int count2 = videos.size();for (int j = 0; j < count2; j++) {Video video = videos.get(j);if(chapter.getId().equals(video.getChapterId())){//创建课时vo对象VideoVo videoVo = new VideoVo();BeanUtils.copyProperties(video, videoVo);videoVoArrayList.add(videoVo);}}chapterVo.setChildren(videoVoArrayList);}return chapterVoArrayList;}}

3、web层

package com.guli.edu.controller.admin;@Api(description="课程章节管理")@CrossOrigin //跨域@RestController@RequestMapping("/admin/edu/chapter")public class ChapterAdminController {@Autowiredprivate ChapterService chapterService;@ApiOperation(value = "嵌套章节数据列表")@GetMapping("nested-list/{courseId}")public R nestedListByCourseId(@ApiParam(name = "courseId", value = "课程ID", required = true)@PathVariable String courseId){List<ChapterVo> chapterVoList = chapterService.nestedList(courseId);return R.ok().data("items", chapterVoList);}}

4、Swagger测试

二、前端实现

1、定义api

chapter.js

import request from '@/utils/request'const api_name = '/admin/edu/chapter'export default {getNestedTreeList(courseId) {return request({url: `${api_name}/nested-list/${courseId}`,method: 'get'})}}

2、定义组件脚本

定义data

courseId: '', // 所属课程chapterNestedList: [] // 章节嵌套课时列表

created中调用init方法

created() {console.log('chapter created')this.init()},

定义相关methods获取章节和课时列表

init() {if (this.$route.params && this.$route.params.id) {this.courseId = this.$route.params.id// 根据id获取课程基本信息this.fetchChapterNestedListByCourseId()}},fetchChapterNestedListByCourseId() {chapter.getNestedTreeList(this.courseId).then(response => {this.chapterNestedList = response.data.items})},

3、定义组件模板

<el-button type="text">添加章节</el-button><!-- 章节 --><ul class="chanpterList"><liv-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"><liv-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>

02-章节管理后端接口开发

一、新增章节

web层

@ApiOperation(value = "新增章节")@PostMappingpublic R save(@ApiParam(name = "chapterVo", value = "章节对象", required = true)@RequestBody Chapter chapter){chapterService.save(chapter);return R.ok();}

二、根据id查询

web层

@ApiOperation(value = "根据ID查询章节")@GetMapping("{id}")public R getById(@ApiParam(name = "id", value = "章节ID", required = true)@PathVariable String id){Chapter chapter = chapterService.getById(id);return R.ok().data("item", chapter);}

三、更新

web层

@ApiOperation(value = "根据ID修改章节")@PutMapping("{id}")public R updateById(@ApiParam(name = "id", value = "章节ID", required = true)@PathVariable String id,@ApiParam(name = "chapter", value = "章节对象", required = true)@RequestBody Chapter chapter){chapter.setId(id);chapterService.updateById(chapter);return R.ok();}

四、删除

1、web层

@ApiOperation(value = "根据ID删除章节")@DeleteMapping("{id}")public R removeById(@ApiParam(name = "id", value = "章节ID", required = true)@PathVariable String id){boolean result = chapterService.removeChapterById(id);if(result){return R.ok();}else{return R.error().message("删除失败");}}

2、Service

ChapterService层:接口

boolean removeChapterById(String id);

ChapterService层:实现

@Overridepublic boolean removeChapterById(String id) {//根据id查询是否存在视频,如果有则提示用户尚有子节点if(videoService.getCountByChapterId(id)){throw new GuliException(20001,"该分章节下存在视频课程,请先删除视频课程");}Integer result = baseMapper.deleteById(id);return null != result && result > 0;}

VideoService:接口

boolean getCountByChapterId(String chapterId);

VideoService:实现

@Overridepublic boolean getCountByChapterId(String chapterId) {QueryWrapper<Video> queryWrapper = new QueryWrapper<>();queryWrapper.eq("chapter_id", chapterId);Integer count = baseMapper.selectCount(queryWrapper);return null != count && count > 0;}

五、Swagger测试

一、新增章节

web层

@ApiOperation(value = "新增章节")@PostMappingpublic R save(@ApiParam(name = "chapterVo", value = "章节对象", required = true)@RequestBody Chapter chapter){chapterService.save(chapter);return R.ok();}

二、根据id查询

web层

@ApiOperation(value = "根据ID查询章节")@GetMapping("{id}")public R getById(@ApiParam(name = "id", value = "章节ID", required = true)@PathVariable String id){Chapter chapter = chapterService.getById(id);return R.ok().data("item", chapter);}

三、更新

web层

@ApiOperation(value = "根据ID修改章节")@PutMapping("{id}")public R updateById(@ApiParam(name = "id", value = "章节ID", required = true)@PathVariable String id,@ApiParam(name = "chapter", value = "章节对象", required = true)@RequestBody Chapter chapter){chapter.setId(id);chapterService.updateById(chapter);return R.ok();}

四、删除

1、web层

@ApiOperation(value = "根据ID删除章节")@DeleteMapping("{id}")public R removeById(@ApiParam(name = "id", value = "章节ID", required = true)@PathVariable String id){boolean result = chapterService.removeChapterById(id);if(result){return R.ok();}else{return R.error().message("删除失败");}}

2、Service

ChapterService层:接口

boolean removeChapterById(String id);

ChapterService层:实现

@Overridepublic boolean removeChapterById(String id) {//根据id查询是否存在视频,如果有则提示用户尚有子节点if(videoService.getCountByChapterId(id)){throw new GuliException(20001,"该分章节下存在视频课程,请先删除视频课程");}Integer result = baseMapper.deleteById(id);return null != result && result > 0;}

VideoService:接口

boolean getCountByChapterId(String chapterId);

VideoService:实现

@Overridepublic boolean getCountByChapterId(String chapterId) {QueryWrapper<Video> queryWrapper = new QueryWrapper<>();queryWrapper.eq("chapter_id", chapterId);Integer count = baseMapper.selectCount(queryWrapper);return null != count && count > 0;}

五、Swagger测试# 一、新增章节

web层

@ApiOperation(value = "新增章节")@PostMappingpublic R save(@ApiParam(name = "chapterVo", value = "章节对象", required = true)@RequestBody Chapter chapter){chapterService.save(chapter);return R.ok();}

二、根据id查询

web层

@ApiOperation(value = "根据ID查询章节")@GetMapping("{id}")public R getById(@ApiParam(name = "id", value = "章节ID", required = true)@PathVariable String id){Chapter chapter = chapterService.getById(id);return R.ok().data("item", chapter);}

三、更新

web层

@ApiOperation(value = "根据ID修改章节")@PutMapping("{id}")public R updateById(@ApiParam(name = "id", value = "章节ID", required = true)@PathVariable String id,@ApiParam(name = "chapter", value = "章节对象", required = true)@RequestBody Chapter chapter){chapter.setId(id);chapterService.updateById(chapter);return R.ok();}

四、删除

1、web层

@ApiOperation(value = "根据ID删除章节")@DeleteMapping("{id}")public R removeById(@ApiParam(name = "id", value = "章节ID", required = true)@PathVariable String id){boolean result = chapterService.removeChapterById(id);if(result){return R.ok();}else{return R.error().message("删除失败");}}

2、Service

ChapterService层:接口

boolean removeChapterById(String id);

ChapterService层:实现

@Overridepublic boolean removeChapterById(String id) {//根据id查询是否存在视频,如果有则提示用户尚有子节点if(videoService.getCountByChapterId(id)){throw new GuliException(20001,"该分章节下存在视频课程,请先删除视频课程");}Integer result = baseMapper.deleteById(id);return null != result && result > 0;}

VideoService:接口

boolean getCountByChapterId(String chapterId);

VideoService:实现

@Overridepublic boolean getCountByChapterId(String chapterId) {QueryWrapper<Video> queryWrapper = new QueryWrapper<>();queryWrapper.eq("chapter_id", chapterId);Integer count = baseMapper.selectCount(queryWrapper);return null != count && count > 0;}

五、Swagger测试

03-章节管理前端页面实现

一、定义api

removeById(id) {return request({url: `${api_name}/${id}`,method: 'delete'})},save(chapter) {return request({url: api_name,method: 'post',data: chapter})},getById(id) {return request({url: `${api_name}/${id}`,method: 'get'})},updateById(chapter) {return request({url: `${api_name}/${chapter.id}`,method: 'put',data: chapter})}

二、新增章节页面功能

1、定义data数据

dialogChapterFormVisible: false, //是否显示章节表单chapter: {// 章节对象title: '',sort: 0}

2、添加章节按钮

<el-button type="text" @click="dialogChapterFormVisible = true">添加章节</el-button>

3、章节表单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>

4、添加章节methods

saveOrUpdate() {this.saveBtnDisabled = trueif (!this.chapter.id) {this.saveData()} else {this.updateData()}},saveData() {this.chapter.courseId = this.courseIdchapter.save(this.chapter).then(response => {this.$message({type: 'success',message: '保存成功!'})this.helpSave()}).catch((response) => {this.$message({type: 'error',message: response.message})})},updateData() {},helpSave(){this.dialogChapterFormVisible = false// 如果保存成功则关闭对话框this.fetchChapterNestedListByCourseId()// 刷新列表this.chapter.title = ''// 重置章节标题this.chapter.sort = 0// 重置章节标题this.saveBtnDisabled = false},

三、修改章节信息

1、编辑章节按钮

<el-button type="text" @click="editChapter(chapter.id)">编辑</el-button>

2、定义编辑方法

editChapter(chapterId) {this.dialogChapterFormVisible = truechapter.getById(chapterId).then(response => {this.chapter = response.data.item})},

3、定义更新方法

updateData() {chapter.updateById(this.chapter).then(response => {this.$message({type: 'success',message: '修改成功!'})this.helpSave()}).catch((response) => {// console.log(response)this.$message({type: 'error',message: response.message})})},

四、删除章节

1、按钮

<el-button type="text" @click="removeChapter(chapter.id)">删除</el-button>

2、定义删除方法

removeChapter(chapterId) {this.$confirm('此操作将永久删除该记录, 是否继续?', '提示', {confirmButtonText: '确定',cancelButtonText: '取消',type: 'warning'}).then(() => {return chapter.removeById(chapterId)}).then(() => {this.fetchChapterNestedListByCourseId()// 刷新列表this.$message({type: 'success',message: '删除成功!'})}).catch((response) => { // 失败if (response === 'cancel') {this.$message({type: 'info',message: '已取消删除'})} else {this.$message({type: 'error',message: response.message})}})},

04-课时管理后端开发

一、定义Form表单对象

VideoInfoForm.java

package com.guli.edu.form;import io.swagger.annotations.ApiModel;import io.swagger.annotations.ApiModelProperty;import lombok.Data;/*** @author helen* @since /3/5*/@ApiModel(value = "课时基本信息", description = "编辑课时基本信息的表单对象")@Datapublic class VideoInfoForm {@ApiModelProperty(value = "视频ID")private String id;@ApiModelProperty(value = "节点名称")private String title;@ApiModelProperty(value = "课程ID")private String courseId;@ApiModelProperty(value = "章节ID")private String chapterId;@ApiModelProperty(value = "视频资源")private String videoSourceId;@ApiModelProperty(value = "显示排序")private Integer sort;@ApiModelProperty(value = "是否可以试听:0默认 1免费")private Boolean free;}

二、课时保存

1、web层接口的定义

VideoAdminController.java

package com.guli.edu.controller.admin;@Api(description="课时管理")@CrossOrigin //跨域@RestController@RequestMapping("/admin/edu/video")public class VideoAdminController {@Autowiredprivate VideoService videoService;@ApiOperation(value = "新增课时")@PostMapping("save-video-info")public R save(@ApiParam(name = "videoForm", value = "课时对象", required = true)@RequestBody VideoInfoForm videoInfoForm){videoService.saveVideoInfo(videoInfoForm);return R.ok();}}

2、业务层

VideoService.java

void saveVideoInfo(VideoInfoForm videoInfoForm);

VideoServiceImpl.java

@Overridepublic void saveVideoInfo(VideoInfoForm videoInfoForm) {Video video = new Video();BeanUtils.copyProperties(videoInfoForm, video);boolean result = this.save(video);if(!result){throw new GuliException(20001, "课时信息保存失败");}}

三、课时的修改

1、web层接口的定义

VideoAdminController.java

@ApiOperation(value = "根据ID查询课时")@GetMapping("video-info/{id}")public R getVideInfoById(@ApiParam(name = "id", value = "课时ID", required = true)@PathVariable String id){VideoInfoForm videoInfoForm = videoService.getVideoInfoFormById(id);return R.ok().data("item", videoInfoForm);}@ApiOperation(value = "更新课时")@PutMapping("update-video-info/{id}")public R updateCourseInfoById(@ApiParam(name = "VideoInfoForm", value = "课时基本信息", required = true)@RequestBody VideoInfoForm videoInfoForm,@ApiParam(name = "id", value = "课时ID", required = true)@PathVariable String id){videoService.updateVideoInfoById(videoInfoForm);return R.ok();}

2、业务层

VideoService.java

VideoInfoForm getVideoInfoFormById(String id);void updateVideoInfoById(VideoInfoForm videoInfoForm);

VideoServiceImpl.java

@Overridepublic VideoInfoForm getVideoInfoFormById(String id) {//从video表中取数据Video video = this.getById(id);if(video == null){throw new GuliException(20001, "数据不存在");}//创建videoInfoForm对象VideoInfoForm videoInfoForm = new VideoInfoForm();BeanUtils.copyProperties(video, videoInfoForm);return videoInfoForm;}@Overridepublic void updateVideoInfoById(VideoInfoForm videoInfoForm) {//保存课时基本信息Video video = new Video();BeanUtils.copyProperties(videoInfoForm, video);boolean result = this.updateById(video);if(!result){throw new GuliException(20001, "课时信息保存失败");}}

四、课时的删除

1、web层接口的定义

VideoAdminController.java

@ApiOperation(value = "根据ID删除课时")@DeleteMapping("{id}")public R removeById(@ApiParam(name = "id", value = "课时ID", required = true)@PathVariable String id){boolean result = videoService.removeVideoById(id);if(result){return R.ok();}else{return R.error().message("删除失败");}}

2、业务层

VideoService.java

boolean removeVideoById(String id);

VideoServiceImpl.java

@Overridepublic boolean removeVideoById(String id) {//删除视频资源 TODOInteger result = baseMapper.deleteById(id);return null != result && result > 0;}

05-课时管理前端开发

一、定义api

创建video.js

参考course.js

import request from '@/utils/request'const api_name = '/admin/edu/video'export default {saveVideoInfo(videoInfo) {return request({url: `${api_name}/save-video-info`,method: 'post',data: videoInfo})},getVideoInfoById(id) {return request({url: `${api_name}/video-info/${id}`,method: 'get'})},updateVideoInfoById(videoInfo) {return request({url: `${api_name}/update-video-info/${videoInfo.id}`,method: 'put',data: videoInfo})},removeById(id) {return request({url: `${api_name}/${id}`,method: 'delete'})}}

二、新增课时页面功能

1、定义data数据

saveVideoBtnDisabled: false, // 课时按钮是否禁用dialogVideoFormVisible: false, // 是否显示课时表单chapterId: '', // 课时所在的章节idvideo: {// 课时对象title: '',sort: 0,free: 0,videoSourceId: ''},

2、添加课时按钮

<el-button type="text" @click="dialogVideoFormVisible = true; chapterId = chapter.id">添加课时</el-button>

3、课时表单dialog

<!-- 添加和修改课时表单 --><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、添加课时methods

引入video模块

import video from '@/api/edu/video'

方法的定义

saveOrUpdateVideo() {this.saveVideoBtnDisabled = trueif (!this.video.id) {this.saveDataVideo()} else {this.updateDataVideo()}},saveDataVideo() {this.video.courseId = this.courseIdthis.video.chapterId = this.chapterIdvideo.saveVideoInfo(this.video).then(response => {this.$message({type: 'success',message: '保存成功!'})this.helpSaveVideo()})},updateDataVideo() {},helpSaveVideo() {this.dialogVideoFormVisible = false// 如果保存成功则关闭对话框this.fetchChapterNestedListByCourseId()// 刷新列表this.video.title = ''// 重置章节标题this.video.sort = 0// 重置章节标题this.video.videoSourceId = ''// 重置视频资源idthis.saveVideoBtnDisabled = false},

三、修改课时信息

1、编辑课时按钮

<el-button type="text" @click="editVideo(video.id)">编辑</el-button>

2、定义编辑方法

editVideo(videoId) {this.dialogVideoFormVisible = truevideo.getVideoInfoById(videoId).then(response => {this.video = response.data.item})},

3、定义更新方法

updateDataVideo() {video.updateVideoInfoById(this.video).then(response => {this.$message({type: 'success',message: '修改成功!'})this.helpSaveVideo()})},

四、删除课时

1、按钮

<el-button type="text" @click="removeVideo(video.id)">删除</el-button>

2、定义删除方法

removeVideo(videoId) {this.$confirm('此操作将永久删除该记录, 是否继续?', '提示', {confirmButtonText: '确定',cancelButtonText: '取消',type: 'warning'}).then(() => {return video.removeById(videoId)}).then(() => {this.fetchChapterNestedListByCourseId()// 刷新列表this.$message({type: 'success',message: '删除成功!'})}).catch((response) => { // 失败if (response === 'cancel') {this.$message({type: 'info',message: '已取消删除'})}})}

06-课程最终发布前端

一、前端代码

1、定义api

分析这个页面一共有两个远程方法:一个是根基课程id获取课程基本预览信息,第二个是发布课程

getCoursePublishInfoById(id) {return request({url: `${api_name}/course-publish-info/${id}`,method: 'get'})},publishCourse(id) {return request({url: `${api_name}/publish-course/${id}`,method: 'put'})}

2、定义数据模型

data() {return {saveBtnDisabled: false, // 保存按钮是否禁用courseId: '', // 所属课程coursePublish: {}}},

3、完善步骤导航

edu/course/chapter.js

previous() {console.log('previous')this.$router.push({ path: '/edu/course/info/' + this.courseId })},next() {console.log('next')this.$router.push({ path: '/edu/course/publish/' + this.courseId })}

edu/course/pubish.js

<div><el-button @click="previous">返回修改</el-button><el-button :disabled="saveBtnDisabled" type="primary" @click="publish">发布课程</el-button></div>

previous() {console.log('previous')this.$router.push({ path: '/edu/course/chapter/' + this.courseId })},publish() {console.log('publish')course.publishCourse(this.courseId).then(response => {this.$router.push({ path: '/edu/course/list' })})}

4、组件方法定义

import

import course from '@/api/edu/course'

created

created() {console.log('chapter created')this.init()},

获取数据的方法

init() {if (this.$route.params && this.$route.params.id) {this.courseId = this.$route.params.id// 根据id获取课程基本信息this.fetchCoursePublishInfoById()}},fetchCoursePublishInfoById() {course.getCoursePublishInfoById(this.courseId).then(response => {this.coursePublish = response.data.item})},

5、组件模板

<template><div class="app-container"><h2 style="text-align: center;">发布新课程</h2><el-steps :active="3" process-status="wait" align-center style="margin-bottom: 40px;"><el-step title="填写课程基本信息"/><el-step title="创建课程大纲"/><el-step title="发布课程"/></el-steps><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.subjectLevelOne }} — {{ coursePublish.subjectLevelTwo }}</span></p><p>课程讲师:{{ coursePublish.teacherName }}</p><h3 class="red">¥{{ coursePublish.price }}</h3></div></div><div><el-button @click="previous">返回修改</el-button><el-button :disabled="saveBtnDisabled" type="primary" @click="publish">发布课程</el-button></div></div></template>

6、css样式

<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>

07-课程最终发布后端

一、根据id查询课程发布信息

方式一:业务层组装多个表多次的查询结果

方式二:数据访问层进行关联查询

我们使用第二种方式实现

1、定义vo

package com.guli.edu.vo;@ApiModel(value = "课程发布信息")@Datapublic class CoursePublishVo implements Serializable {private static final long serialVersionUID = 1L;private String title;private String cover;private Integer lessonNum;private String subjectLevelOne;private String subjectLevelTwo;private String teacherName;private String price;//只用于显示}

2、数据访问层

接口:CourseMapper.java

package com.guli.edu.mapper;public interface CourseMapper extends BaseMapper<Course> {CoursePublishVo selectCoursePublishVoById(String id);}

实现:CourseMapper.xml

<select id="getCoursePublishVoById" resultType="com.guli.edu.vo.CoursePublishVo">SELECTc.title,c.cover,c.lesson_num AS lessonNum,CONVERT(c.price, DECIMAL(8,2)) AS price,s1.title AS subjectLevelOne,s2.title AS subjectLevelTwo,t.name AS teacherNameFROMedu_course cLEFT JOIN edu_teacher t ON c.teacher_id = t.idLEFT JOIN edu_subject s1 ON c.subject_parent_id = s1.idLEFT JOIN edu_subject s2 ON c.subject_id = s2.idWHEREc.id = #{id}</select>

3、业务层

接口:CourseService.java

CoursePublishVo getCoursePublishVoById(String id);

实现:CourseServiceImpl.java

@Overridepublic CoursePublishVo getCoursePublishVoById(String id) {return baseMapper.getCoursePublishVoById(id);}

4、web层

@ApiOperation(value = "根据ID获取课程发布信息")@GetMapping("course-publish-info/{id}")public R getCoursePublishVoById(@ApiParam(name = "id", value = "课程ID", required = true)@PathVariable String id){CoursePublishVo courseInfoForm = courseService.getCoursePublishVoById(id);return R.ok().data("item", courseInfoForm);}

测试:报告异常

AbstractHandlerExceptionResolver.java:194 |org.springframework.web.servlet.mvc.method.annotation.ExceptionHandlerExceptionResolver |Resolved exception caused by handler execution: org.apache.ibatis.binding.BindingException: Invalid bound statement (not found): com.guli.edu.mapper.CourseMapper.getCoursePublishVoById

问题分析:

dao层编译后只有class文件,没有mapper.xml,因为maven工程在默认情况下src/main/java目录下的所有资源文件是不发布到target目录下的,

解决方案:

1、在guli_edu的pom中配置如下节点

<!-- 项目打包时会将java目录中的*.xml文件也进行打包 --><build><resources><resource><directory>src/main/java</directory><includes><include>**/*.xml</include></includes><filtering>false</filtering></resource></resources></build>

重新打包项目会发现target目录下出现了xml文件夹

2、在Spring Boot配置文件中添加配置

#配置mapper xml文件的路径mybatis-plus.mapper-locations=classpath:com/guli/edu/mapper/xml/*.xml

二、根据id发布课程

1、web层

@ApiOperation(value = "根据id发布课程")@PutMapping("publish-course/{id}")public R publishCourseById(@ApiParam(name = "id", value = "课程ID", required = true)@PathVariable String id){courseService.publishCourseById(id);return R.ok();}

2、service层

接口

void publishCourseById(String id);

实现

@Overridepublic boolean publishCourseById(String id) {Course course = new Course();course.setId(id);course.setStatus(Course.COURSE_NORMAL);Integer count = baseMapper.updateById(course);return null != count && count > 0;}

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。