在线教育_Day07-项目课程发布-添加课程信息
Posted 编程指南针
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了在线教育_Day07-项目课程发布-添加课程信息相关的知识,希望对你有一定的参考价值。
一、课程发布表单-步骤导航
1.1 需求分析
1.2 课程相关表关系
二、添加课程基本信息后台
2.1 生成课程相关代码
使用代码生成器生成课程相关的代码。
2.2 定义form表单对象
我们添加基本课程信息时,需要涉及到两张表edu_course和edu_course_description,同时我们在添加课时还需要指定课程的老师和课程的分类。添加的内容比较多,所以我们将前台提交的数据,进行封装为一个CourseInfoFormVo对象。
在entity/vo下创建CourseInfoForm类
@ApiModel(value = "课程基本信息", description = "编辑课程基本信息的表单对象") @Data public class CourseInfoFormVo implements Serializable private static final long serialVersionUID = 1L; @ApiModelProperty(value = "课程ID") private String id; @ApiModelProperty(value = "课程讲师ID") private String teacherId; @ApiModelProperty(value = "课程专业ID") private String subjectId; @ApiModelProperty(value = "课程标题") private String title; @ApiModelProperty(value = "课程销售价格,设置为0则可免费观看") private BigDecimal price; @ApiModelProperty(value = "总课时") private Integer lessonNum; @ApiModelProperty(value = "课程封面图片路径") private String cover; @ApiModelProperty(value = "课程简介") private String description;
2.3 定义控制层EduCourseController
前面我们已经使用代码生成工具,将代码生成完毕,我们只需要在EduCourseController.java编写代码即可。
@Api(description="课程管理") @CrossOrigin //跨域 @RestController @RequestMapping("/eduservice/course") public class EduCourseController @Autowired private CourseService courseService; @ApiOperation(value = "新增课程") @PostMapping("/addCourseInfo") public R addCourseInfo(@RequestBody CourseInfoFormVo courseInfoFormVo) String courseId = eduCourseService.saveCourseInfo(courseInfoFormVo); return R.ok().data("courseId",courseId);
2.4 定义业务层方法CourseService
接口:CourseService.java
/** * 保存课程和课程详情信息 * @param courseInfoForm * @return 新生成的课程id */ void saveCourseInfo(CourseInfoFormVo courseInfoFormVo);
实现:CourseServiceImpl.java
/** * <p> * 课程 服务实现类 * </p> * * @author zjl */ @Service public class EduCourseServiceImpl extends ServiceImpl<EduCourseMapper, EduCourse> implements EduCourseService @Autowired EduCourseDescriptionService eduCourseDescriptionService; // 添加课程信息 @Override public void saveCourseInfo(CourseInfoFormVo courseInfoFormVo) // 向课程表添加课程基本信息 EduCourse eduCourse = new EduCourse(); BeanUtils.copyProperties(courseInfoFormVo, eduCourse); int insert = this.baseMapper.insert(eduCourse); // 判断添加课程基本信息是否成功 if (insert==0) throw new EduException(20001, "添加课程基本信息失败!"); // 向课程简介表添加课程简介 EduCourseDescription eduCourseDescription = new EduCourseDescription(); eduCourseDescription.setDescription(courseInfoFormVo.getDescription()); eduCourseDescriptionService.save(eduCourseDescription);
2.5 Swagger测试
查看数据库信息
在数据库分析中,课程表和课程简介表是一对一的关系,但是添加数据时,却发现不是一对一的关系。
在edu_course表中的id是1548334513809661953
, 在edu_course_description表中的id是1548334513809661954
通过两个id值发现它们两个表是没有关系的。想要一对一关系,在edu_course_description表的id值应该是edu_course表中的id值 。
2.6 修改CourseServiceImpl
在添加完课程信息之后,获取课程的Id,再将课程的id设置到课程描述信息中即可。
同时修改EduCourseDescription类中的id主键策略,这个表中的id不需要生动生成。需要我们手动插入。
三、添加基本课程信息前端
3.1 添加课程管理路由
// 课程管理 path: '/course', component: Layout, redirect: '/course/list', name: '课程管理', meta: title: '课程管理', icon: 'form' , children: [ path: 'list', name: '课程列表', component: () => import('@/views/edu/course/list'), meta: title: '课程列表' , path: 'info', name: '添加课程', component: () => import('@/views/edu/course/info'), meta: title: '添加课程' , path: 'info/:id', name: '编辑课程基本信息', component: () => import('@/views/edu/course/info'), meta: title: '编辑课程基本信息', noCache: true , hidden: true , path: 'chapter/:id', name: '编辑课程大纲', component: () => import('@/views/edu/course/chapter'), meta: title: '编辑课程大纲', noCache: true , hidden: true , path: 'publish/:id', name: '发布课程', component: () => import('@/views/edu/course/publish'), meta: title: '发布课程', noCache: true , hidden: true ]
3.2 添加vue组件
3.3 整合步骤条组件
参考 http://element-cn.eleme.io/#/zh-CN/component/steps
3.3.1 课程信息页面
在info.vue中添加以下内容:
<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> <el-button :disabled="saveBtnDisabled" type="primary" @click="next">保存并下一步</el-button> </el-form-item> </el-form> </div> </template> <script> export default data() return saveBtnDisabled: false // 保存按钮是否禁用 , created() console.log('info created') , methods: next() console.log('next') this.$router.push( path: '/course/chapter/1' ) </script>
3.3.2 课程大纲页面
在chapter.vue添加以下内容
<template> <div class="app-container"> <h2 style="text-align: center;">发布新课程</h2> <el-steps :active="2" 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> <el-button @click="previous">上一步</el-button> <el-button :disabled="saveBtnDisabled" type="primary" @click="next">下一步</el-button> </el-form-item> </el-form> </div> </template> <script> export default data() return saveBtnDisabled: false // 保存按钮是否禁用 , created() console.log('chapter created') , methods: previous() console.log('previous') this.$router.push( path: '/course/info/1' ) , next() console.log('next') this.$router.push( path: '/course/publish/1' ) </script>
3.3.3 课程发布页面
在publish.vue文件中添加以下内容
<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> <el-form label-width="120px"> <el-form-item> <el-button @click="previous">返回修改</el-button> <el-button :disabled="saveBtnDisabled" type="primary" @click="publish">发布课程</el-button> </el-form-item> </el-form> </div> </template> <script> export default data() return saveBtnDisabled: false // 保存按钮是否禁用 , created() console.log('publish created') , methods: previous() console.log('previous') this.$router.push( path: '/course/chapter/1' ) , publish() console.log('publish') this.$router.push( path: '/course/list' ) </script>
3.4 添加课程页面实现
3.4.1 定义api
在src/api/edu下创建course.js文件,添加以下内容
import request from '@/utils/request' export default addCourseInfo(courseInfo) return request( url: `/eduservice/course/addCourseInfo`, method: 'post', data: courseInfo )
3.4.2 组件模板
在edu/course/info.vue中添加以下页面信息:
<el-form label-width="120px"> <el-form-item label="课程标题"> <el-input v-model="courseInfo.title" placeholder=" 示例:机器学习项目课:从基础到搭建项目视频课程。专业名称注意大小写"/> </el-form-item> <!-- 所属分类 TODO --> <!-- 课程讲师 TODO --> <el-form-item label="总课时"> <el-input-number :min="0" v-model="courseInfo.lessonNum" controls-position="right" placeholder="请填写课程的总课时数"/> </el-form-item> <!-- 课程简介 TODO --> <el-form-item label="课程简介"> <el-input v-model="courseInfo.description" placeholder="填写课程描述信息"/> </el-form-item> <!-- 课程封面 TODO --> <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="next">保存并下一步</el-button> </el-form-item> </el-form>
3.4.3 添加js
<script> import course from '@/api/edu/course.js' export default data() return saveBtnDisabled: false ,// 保存按钮是否禁用 courseInfo: title: '', subjectId: '', teacherId: '', lessonNum: 0, description: '', cover: '', price: 0 , created() console.log('info created') , methods: saveOrUpdate() console.log('next') course.addCourseInfo(this.courseInfo).then(response => this.$message( type: 'success', message: '保存成功!' ) this.$router.push( path: '/course/chapter/1' ) ) </script>
3.4.4 添加之后,返回课程id
添加课程信息之后,后面在添加小节时,还是需要课程的id,所以我们要如下改造:
修改EduCourseController
在EduCourseController中的addCourseInfo方法,添加返回值
@PostMapping("/addCourseInfo") public R addCourseInfo(@RequestBody CourseInfoFormVo courseInfoFormVo) String courseId = eduCourseService.saveCourseInfo(courseInfoFormVo); return R.ok().data("courseId",courseId);
修改EduCourseService
添加返回值String
public interface EduCourseService extends IService<EduCourse> String saveCourseInfo(CourseInfoFormVo courseInfoFormVo);
// 添加课程信息 @Override public String saveCourseInfo(CourseInfoFormVo courseInfoFormVo) // 向课程表添加课程基本信息 EduCourse eduCourse = new EduCourse(); BeanUtils.copyProperties(courseInfoFormVo, eduCourse); int insert = this.baseMapper.insert(eduCourse); // 判断添加课程基本信息是否成功 if (insert==0) throw new EduException(20001, "添加课程基本信息失败!"); // 获取添加课程之后的id String cid = eduCourse.getId(); // 向课程简介表添加课程简介 EduCourseDescription eduCourseDescription = new EduCourseDescription(); eduCourseDescription.setId(cid); eduCourseDescription.setDescription(courseInfoFormVo.getDescription()); eduCourseDescriptionService.save(eduCourseDescription); return cid;
修改info.vue
修改edu/course/info.vue中的saveOrUpdate方法
saveOrUpdate() console.log('next') course.addCourseInfo(this.courseInfo).then(response => this.$message( type: 'success', message: '保存成功!' ) this.$router.push( path: '/course/chapter/'+response.data.courseId ) )
3.5 讲师下拉列表
3.5.1 组件模板
将以下代码添加到views/edu/course/info.vue中
<!-- 课程讲师 --> <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>
3.5.2 定义获取讲师列表接口
直接调用EduTeacherController中的findAll接口即可。之前我们都已经写过。
3.5.3 定义api
在api/edu/course.js中定义查询所有讲师
getListTeacher() return request( url: `/eduservice/edu-teacher/findAll`, method: 'get' ) ,
3.5.4 组件脚本
定义data,不要定义在courseInfo中
teacherList: [] // 讲师列表
表单初始化时获取讲师列表
created() console.log('info created') // 初始化讲师列表 this.getListTeacher() , methods: // 查询所有讲师 getListTeacher() course.getListTeacher().then(response => this.teacherList = response.data.items ) ,
3.5.5 效果展示
3.6 课程分类多级联动的实现
需求
3.6.1 获取一级分类
组件数据定义
在views/edu/course/info.vue的data中定义一级分类和二级分类集合.最后在courseInfo中添加subjectParentId
subjectOneList: [],//一级分类列表 subjectTwoList: []//二级分类列表
组件模板
在course/info.vue中定义一级分类下拉框
<!-- 一级分类 --> <el-form-item label="课程类别"> <el-select v-model="courseInfo.subjectParentId" placeholder="请选择"> <el-option v-for="subject in subjectOneList" :key="subject.id" :label="subject.title" :value="subject.id"/> </el-select> </el-form-item>
组件脚本
在course/info.vue中引入subject.js
import subject from '@/api/edu/subject.js'
定义方法,查询所有的一级分类
created() console.log('info created') // 初始化讲师列表 this.getListTeacher() // 初始化一级分类列表 this.getOneSubjectList() , methods: // 查询所有的一级分类 getOneSubjectList() subject.getSubjectList().then(response => this.subjectOneList = response.data.list ) ,
3.6.2 级联显示二级分类
组件模板
<!-- 二级分类 --> <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>
注册change事件
在一级分类的<el-select>组件中注册change事件
<el-select @change="subjectLevelOneChanged" ......
定义change事件方法
subjectLevelOneChanged(value) console.log(value); // 遍历所有的分类,包含一级分类和二级分类 for (let i = 0; i < this.subjectOneList.length; i++) if (this.subjectOneList[i].id === value) this.subjectTwoList = this.subjectOneList[i].children; // 清空二级分类 this.courseInfo.subjectId = ""; ,
3.7 课程封面
3.7.1 整合上传组件
参考 http://element-cn.eleme.io/#/zh-CN/component/upload 用户头像上传
3.7.2 上传默认封面
创建文件夹cover,上传默认的课程封面
3.7.3 定义data数据
BASE_API: process.env.BASE_API // 接口API地址
3.7.4 组件模板
在info.vue中添加上传组件模板
<!-- 课程封面--> <el-form-item label="课程封面"> <el-upload :show-file-list="false" :on-success="handleAvatarSuccess" :before-upload="beforeAvatarUpload" :action="BASE_API+'/eduoss/file/upload'" class="avatar-uploader"> <img :src="courseInfo.cover" width="250px" height="150px" /> </el-upload> </el-form-item>
3.7.5 定义默认封面
cover: "https://zjledu.oss-cn-beijing.aliyuncs.com/cover/%E9%BB%98%E8%AE%A4%E8%AF%BE%E7%A8%8B%E5%B0%81%E9%9D%A2.jpg",
3.7.6 结果回调
handleAvatarSuccess(res, file) console.log(res)// 上传响应 console.log(URL.createObjectURL(file.raw))// base64编码 this.courseInfo.cover = res.data.url , beforeAvatarUpload(file) 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
3.7.8 综合测试
四、富文本编辑器Tinymce
在课程基本信息添加页面中,集成富文本编辑器
4.1 组件初始化
Tinymce是一个传统javascript插件,默认不能用于Vue.js因此需要做一些特殊的整合步骤
4.1.1 复制脚本库
将资料中的components/Tinymce复制到前端工程中components目录下
将资料中的\\static\\tinymce4.7.5得到到static目录下
4.1.2 配置html变量
在 /build/webpack.dev.conf.js 中添加配置 使在html页面中可是使用这里定义的BASE_URL变量
new HtmlWebpackPlugin( ...... templateParameters: BASE_URL: config.dev.assetsPublicPath + config.dev.assetsSubDirectory )
注意:配置完成之后,最好重启一下前端服务器
4.1.3 引入js脚本
在/index.html 中引入js脚本
<script src=<%= BASE_URL %>/tinymce4.7.5/tinymce.min.js></script> <script src=<%= BASE_URL %>/tinymce4.7.5/langs/zh_CN.js></script>
4.2 使用文本编辑器
为了让Tinymce能用于Vue.js项目,vue-element-admin-master对Tinymce进行了封装,下面我们将它引入到我们的课程信息页面
4.2.1 引入组件
在课程信息info.vue中引入 Tinymce
import Tinymce from '@/components/Tinymce' export default components: Tinymce , ......
4.2.2 引用组件模板
<!-- 课程简介--> <el-form-item label="课程简介"> <tinymce :height="300" v-model="courseInfo.description"/> </el-form-item>
4.2.3 组件样式
在info.vue文件的最后添加如下代码,调整上传图片按钮的高度
<style scoped> .tinymce-container line-height: 29px; </style>
4.2.5 图片的base64编码
Tinymce中的图片上传功能直接存储的是图片的base64编码,因此无需图片服务器
4.2.6 测试
测试会出现添加课程二级分类时,会没有数据。是因为,在CourseInfoFormVo中,没有subjectParentId这个字段。在CourseInfoFormVo类中添加该字段即可。
@ApiModelProperty(value = "一级分类ID") private String subjectParentId;
以上是关于在线教育_Day07-项目课程发布-添加课程信息的主要内容,如果未能解决你的问题,请参考以下文章