在线教育开发项目之课程信息业务
课程发布之课程信息
课程目标
1) 课程分类删除实现
2) 编写课程基本信息显示
3) 课程分类二级联动
4) 讲师下拉表显示
1、 课程分类删除
请求路径:
http://localhost:8001/ebs/subject/1263632523339075586
结果:
1. 后端实现
1.1. 添加删除业务逻辑
EbsSubjectController
/** |
EbsSubjectServiceImpl
/** |
1.2. api 接口
/** * 课程分类删除功能 * @param {*} subjectId */ removeById(subjectId) { return request({ url: `${api_name}/${subjectId}`, method: 'delete' }) } |
2. 前端实现
2.1. 准备
安装Chrome插件 Vue.js devtools
参考Element-UI Tree组件
https://element.eleme.cn/#/zh-CN/component/tree
2.2. api
参考Teacher模块
2.3. 组件模板
<el-tree ref="subjectTree" :data="subjectList" :props="defaultProps" :filter-node-method="filterNode" :expand-on-click-node="false" class="filter-tree" default-expand-all node-key="id"> <span slot-scope="{ node, data }" class="custom-tree-node"> <span>{{ node.label }}</span> <span> <!-- 使用Chrome的Vue插件调试 --> <el-button v-if="node.level == 1" type="text" size="mini" @click="() => append(data)">添加</el-button> <el-button v-if="node.level == 2" type="text" size="mini" @click="() => remove(node, data)">删除</el-button> </span> </span> </el-tree> |
2.4. 组件代码
添加remove方法
remove(node, data) { console.log(node) console.log(data) this.$confirm('此操作将永久删除该记录, 是否继续?', '提示', { confirmButtonText: '确定', cancelButtonText: '取消', type: 'warning' }).then(() => { return subject.removeById(data.id) }).then(() => { // this.fetchNodeList()// 刷新列表 this.$refs.subjectTree.remove(node) // 删除节点(效率高) this.$message({ type: 'success', message: '删除成功!' }) }).catch((response) => { // 失败 if (response === 'cancel') { this.$message({ type: 'info', message: '已取消删除' }) } else { this.$message({ type: 'error', message: '删除失败' }) } }) }, |
2、 课程一级分类添加
1. 后端实现
1.1. controller
EbsSubjectController
@ApiOperation(value = "新增一级分类")
|
1.2. service
接口 EbsSubjectService
/** |
辅助方法:判断一级分类是否存在
// 判断数据库表是否存在一级分类 |
2. 前端实现
2.1. api
src/api/subject.js
/** * 新增分类 * @param {*} subject */ saveLevelOne(subject) { return request({ url: `${api_name}/saveLevelOne`, method: 'post', data: subject }) } |
2.2. 组件模板
sec/views/edu/subject/list.vue
添加新增按钮
<el-button type="text" @click="dialogFormVisible = true">添加一级分类</el-button> |
添加新增弹窗表单
<el-dialog :visible.sync="dialogFormVisible" title="添加分类"> <el-form :model="subject" label-width="120px"> <el-form-item label="分类标题"> <el-input v-model="subject.title"/> </el-form-item> </el-form> <div slot="footer" class="dialog-footer"> <el-button @click="dialogFormVisible = false">取 消</el-button> <el-button type="primary" @click="appendLevelOne()">确 定</el-button> </div> </el-dialog> |
2.3. 组件js
sec/views/edu/subject/list.vue
定义表单数据
dialogFormVisible: false, subject: { title: '', parentId: '' } |
保存方法
appendLevelOne() { subject.saveLevelOne(this.subject).then(response => { this.$message({ type: 'success', message: '保存成功!' }) this.dialogFormVisible = false// 如果保存成功则关闭对话框 this.fetchNodeList()// 刷新列表 this.subject.title = ''//置空弹窗内容 }).catch((response) => { // console.log(response) this.$message({ type: 'error', message: '保存失败' }) }) }, |
3、 课程二级分类添加
1. 后端实现
2. 前端实现
2.1. api
src/api/ebs/subject.js
saveLevelTwo(subject) { return request({ url: `${api_name}/saveLeveTwo`, method: 'post', data: subject }) } |
2.2. 组件模板
sec/views/ebs/subject/list.vue
按钮
<el-button v-if="node.level == 1" type="text" size="mini" @click="() => {dialogFormVisible = true; subject.parentId = data.id}">添加二级分类</el-button> |
表单:
修改弹出表单的确定按钮绑定的事件
<el-button type="primary" @click="append()">确 定</el-button> |
2.3. 组件js
sec/views/ebs/subject/list.vue
添加方法 append
append(data) { if (!this.subject.parentId) { this.appendLevelOne() } else { this.appendLevelTwo() } }, |
保存方法
appendLevelTwo() { subject.saveLevelTwo(this.subject).then(response => { this.$message({ type: 'success', message: '保存成功!' }) this.dialogFormVisible = false// 如果保存成功则关闭对话框 this.fetchNodeList()// 刷新列表 this.subject.title = ''// 重置类别标题 this.subject.parentId = '' // 重置表单parentId }).catch((response) => { // console.log(response) this.$message({ type: 'error', message: response.data.message }) }) } |
2.4. controller
EbsSubjectController
@ApiOperation(value = "新增二级分类") |
2.5. service
接口 EbsSubjectService
boolean saveLevelTwo(Subject subject); |
实现 EbsSubjectServiceImpl
/** |
辅助方法:判断二级分类是否存在
//判断数据库表是否存在二级分类 |
4、 课程发布表单-步骤导航
1. 需求
第一步:编辑课程基本信息
第二步:编辑课程大纲
第三步:课程的发布
2. 配置路由
2.1. 添加路由
// 课程管理 { path: '/ebs/course', component: Layout, redirect: '/ebs/course/list', name: 'Course', meta: { title: '课程管理', icon: 'form' }, children: [ { path: 'list', name: 'EbsCourseList', component: () => import('@/views/ebs/course/list'), meta: { title: '课程列表' } }, { path: 'info', name: 'ebsCourseInfo', component: () => import('@/views/ebs/course/info'), meta: { title: '发布课程' } }, { path: 'info/:id', name: 'EbsCourseInfoEdit', component: () => import('@/views/ebs/course/info'), meta: { title: '编辑课程基本信息', noCache: true }, hidden: true }, { path: 'chapter/:id', name: 'ebsCourseChapterEdit', component: () => import('@/views/ebs/course/chapter'), meta: { title: '编辑课程大纲', noCache: true }, hidden: true }, { path: 'publish/:id', name: 'ebsCoursePublishEdit', component: () => import('@/views/ebs/course/publish'), meta: { title: '发布课程', noCache: true }, hidden: true } ] }, |
2.2. 添加vue组件
3. 整合步骤条组件
参考 http://element-cn.eleme.io/#/zh-CN/component/steps
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: '/edu/course/chapter/1' }) } } } </script> |
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: '/edu/course/info/1' }) }, next() { console.log('next') this.$router.push({ path: '/edu/course/publish/1' }) } } } </script> |
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: '/edu/course/chapter/1' }) }, publish() { console.log('publish') this.$router.push({ path: '/edu/course/list' }) } } } </script> |
5、 编辑课程基本信息
1. 后台api
1.1. 定义form表单对象
CourseInfoForm.java
package com.yxzx.ebs.teacher.entity.form; |
1.2. 修改CourseDescription主键生成策略
@ApiModelProperty(value = "课程ID") @TableId(value = "id", type = IdType.INPUT) private String id; |
1.3. 定义常量
实体类Course.Java中定义
package com.yxzx.ebs.teacher.constent; |
1.4. 定义控制层接口
EbsCourseController.java
package com.yxzx.ebs.teacher.controller; |
1.5. 定义业务层方法
接口:EbsCourseService.java
/** * 保存课程和课程详情信息 * */ String saveCourseInfo(CourseInfoForm courseInfoForm); |
实现:CourseServiceImpl.java
注意这里使用了事物
/** |
1.6. Swagger测试
2. 前端实现
2.1. 定义api
import request from '@/utils/request' const api_name = '/ebs/course' export default { saveCourseInfo(courseInfo) { return request({ url: `${api_name}/saveCourseInfo`, method: 'post', data: courseInfo }) } } |
2.2. 组件模板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 --> <!-- 课程封面 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> |
2.3. 组件js
<script> import course from '@/api/ebs/course' const defaultForm = { title: '', subjectId: '', teacherId: '', lessonNum: 0, description: '', cover: '', price: 0 } export default { data() { return { courseInfo: defaultForm, saveBtnDisabled: false // 保存按钮是否禁用 } }, watch: { $route(to, from) { console.log('watch $route') this.init() } }, created() { console.log('info created') this.init() }, methods: { init() { if (this.$route.params && this.$route.params.id) { const id = this.$route.params.id console.log(id) } else { this.courseInfo = { ...defaultForm } } }, next() { console.log('next') this.saveBtnDisabled = true if (!this.courseInfo.id) { this.saveData() } else { this.updateData() } }, // 保存 saveData() { course.saveCourseInfo(this.courseInfo).then(response => { this.$message({ type: 'success', message: '保存成功!' }) return response// 将响应结果传递给then }).then(response => { this.$router.push({ path: '/ebs/course/chapter/' + response.data.courseId }) }).catch((response) => { this.$message({ type: 'error', message: response.message }) }) }, updateData() { this.$router.push({ path: '/ebs/course/chapter/1' }) } } } </script> |
6、 课程分类多级联动的实现
1. 需求
2. 获取一级分类
2.1. 组件数据定义
定义在data中
subjectNestedList: [],//一级分类列表 subSubjectList: []//二级分类列表 |
2.2. 组件模板
<!-- 所属分类:级联下拉列表 --> <!-- 一级分类 --> <el-form-item label="课程类别"> <el-select v-model="courseInfo.subjectParentId" placeholder="请选择"> <el-option v-for="subject in subjectNestedList" :key="subject.id" :label="subject.title" :value="subject.id"/> </el-select> </el-form-item> |
2.3. 组件脚本
表单初始化时获取一级分类嵌套列表,引入subject api
import subject from '@/api/ebs/subject' |
定义方法初始化数据
init() { ...... // 初始化分类列表 this.initSubjectList() }, initSubjectList() { subject.getNestedTreeList().then(response => { this.subjectNestedList = response.data.items }) }, |
3. 级联显示二级分类
3.1. 组件模板
<!-- 二级分类 --> <el-select v-model="courseInfo.subjectId" placeholder="请选择"> <el-option v-for="subject in subSubjectList" :key="subject.value" :label="subject.title" :value="subject.id"/> </el-select> |
3.2. 注册change事件
在一级分类的<el-select>组件中注册change事件
<el-select @change="subjectLevelOneChanged" ...... |
3.3. 定义change事件方法
subjectLevelOneChanged(value) { console.log(value) for (let i = 0; i < this.subjectNestedList.length; i++) { if (this.subjectNestedList[i].id === value) { this.subSubjectList = this.subjectNestedList[i].children this.courseInfo.subjectId = '' } } }, |
7、 讲师下拉列表
1. 前端实现
1.1. 组件模板
<!-- 课程讲师 --> <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> |
1.2. 定义api
api/ebs/teacher.js
getList() { return request({ url: api_name, method: 'get' }) }, |
Info.vue组件中引入teacher api
import teacher from '@/api/ebs/teacher' |
1.3. 组件脚本
定义data
teacherList: [] // 讲师列表 |
表单初始化时获取讲师列表
init() { ...... // 获取讲师列表 this.initTeacherList() }, initTeacherList() { teacher.getList().then(response => { this.teacherList = response.data.items }) }, |
- 点赞
- 收藏
- 关注作者
评论(0)