谷粒学院(十)课程管理模块 | 课程大纲列表 | 二级联动 | 富文本编辑器

网友投稿 340 2022-09-23

谷粒学院(十)课程管理模块 | 课程大纲列表 | 二级联动 | 富文本编辑器

一、课程发布分析

1、发布流程图

2、数据表对应

3、课程相关表的关系

二、课程管理–添加课程后端

1、使用代码生成器生成相关课程的代码

2、细节问题

(1)创建vo实体类用户表单数据封装 vo:ViewObject:用于后台向前台显示所创建的实体

(2)把表单提交过来的数据添加到数据库 ==>向两张表添加数据:课程表 和 课程描述表

(3)把讲师和分类使用下拉列表显示 课程分类 做成二级联动

3、创建vo实体类

@ApiModel(value = "课程基本信息", description = "编辑课程基本信息的表单对象")@Datapublic class CourseInfoVo { 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 = "课程专业父级ID") private String subjectParentId; @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;}

4、编写Controller类

@Api(description = "课程管理")@RestController@RequestMapping("/eduservice/course")@CrossOriginpublic class EduCourseController { @Autowired private EduCourseService courseService; @ApiOperation("添加课程基本信息") @PostMapping("saveCourseInfo") public R saveCourseInfo(@ApiParam(name = "CourseInfoForm", value = "课程基本信息", required = true) @RequestBody CourseInfoVo courseInfoVo){ //返回课程id,为了跳转到课程大纲使用 String courseId = courseService.saveCourseInfo(courseInfoVo); return R.ok().data("courseId", courseId); }}

5、编写Service类

@Service@Transactional //开启事务管理public class EduCourseServiceImpl extends ServiceImpl implements EduCourseService { @Autowired private EduCourseDescriptionService courseDescriptionService; //添加课程基本信息 @Override public String saveCourseInfo(CourseInfoVo courseInfoVo) { //1.添加课程基本信息信息到课程表 EduCourse eduCourse = new EduCourse(); BeanUtils.copyProperties(courseInfoVo,eduCourse); int insert = this.baseMapper.insert(eduCourse); if(insert==0){ throw new GuLiException(20001, "添加课程失败!"); } //2.添加课程简介信息到简介表 String id = eduCourse.getId();//获得添加之后的课程id EduCourseDescription eduCourseDescription = new EduCourseDescription(); BeanUtils.copyProperties(courseInfoVo,eduCourseDescription); eduCourseDescription.setId(id);//因为两张表是一对一关系,所以id也应该相同 boolean save = courseDescriptionService.save(eduCourseDescription); if(save==false){ throw new GuLiException(20001, "添加课程失败!"); } return id; }}

注意问题:

(1)课程和描述是一对一关系,添加之后,id应该是相同的。所以描述的id要填入课程的id. EduCourseDescription类中id 属性​​​@TableId(value = "id", type = IdType.INPUT)​​

(2)EduCourse类和EduCourseDescription类中的时间需要自动填充​​@TableField(fill = FieldFill.INSERT)​​

6、启动Swagger测试

三、课程管理–添加课程前端(填写课程基本信息)

1、添加课程管理路由

api/router/index.js

{ path: '/course', component: Layout, //布局 redirect: '/course/table', name: 'CourseAdd', meta: { title: '课程管理', icon: 'form' }, children: [{ path: 'list', name: 'EduCourseList', component: () => import ('@/views/edu/course/list'), meta: { title: '课程列表', icon: 'table' } }, { path: 'info', name: 'EduCourseInfo', component: () => import ('@/views/edu/course/info'), meta: { title: '发布课程', icon: 'tree' } }, { path: 'info/:id', name: 'EduCourseInfoEdit', component: () => import ('@/views/edu/course/info'), meta: { title: '编辑课程基本信息', noCache: true }, hidden: true }, { path: 'chapter/:id', name: 'EduCourseChapterEdit', component: () => import ('@/views/edu/course/chapter'), meta: { title: '编辑课程大纲', noCache: true }, hidden: true }, { path: 'publish/:id', name: 'EduCoursePublishEdit', component: () => import ('@/views/edu/course/publish'), meta: { title: '发布课程', noCache: true }, hidden: true } ] },

**注意:**这里有三个模块添加隐藏域是为了形成 下一步—>下一步—>确认发布 上一步—>上一步—>取消发布 的效果

2、添加Vue组件

3、整合步骤条组件实现页面跳转

参考:info.vue

2、课程大纲页面—chapter.vue

3、课程发布页面—publish.vue

4、定义api

api/edu/course.js

import request from '@/utils/request'export default { //1.添加课程信息 saveCourseInfo(courseInfo) { return request({ url: `/eduservice/course/saveCourseInfo`, method: 'post', data: courseInfo }) }}

5、添加课程表单

src/views/edu/info.vue

保存并下一步

**主意:**TODO是为了后续进行完善,一个项目都是从简单到复杂,功能一步步变繁多的.

7、讲师下拉列表

(1)组件模板

(2)定义api

api/edu/teacher.js

//查询所有讲师getTeacherList() { return request({ url: `/eduservice/teacher/findAll`, method: 'get' })}

组件中引入teacher的api

import teacher from '@/api/edu/teacher'

(3)组件js代码

定义data

teacherList: [] // 讲师列表

表单初始化时获取讲师列表

created() { this.getTeacherList()},methods: { //.... //查询所有讲师 getTeacherList(){ course.getTeacherList().then(response=>{ this.teacherList = response.data.items }) } }

(4)页面效果展示

8、课程分类多级联动

1、两个下拉列表实现

思路分析:使用多个下拉列表来达到多级联动效果,前面的被触发,后面的下拉列表被赋值填充.

(1)组件数据定义—定义data中

subjectOneList:[],//一级分类subjectTwoList:[]//二级分类

(2)组件模板

(3)组件脚本

(1)页面效果

2、使用级联组件

(1)组件模板

(2)模板数据

courseInfo:{ //... subjectId: '',//一级分类id subjectParentId:'',//二级分类id //...},subjectList:[],//课程分类列表subProps:{//模板数据 value:'id', label:'title', children:'children' },subject:[],//存放级联列表的id数组

(3)组件js脚本

handleChange(){//参数为value数据,如果不需要可以不写. console.log(this.subject); this.courseInfo.subjectId = this.subject[1] //将对应的一二级分类id放入到courseInfo中 this.courseInfo.subjectParentId = this.subject[0] }

(4)页面效果

9、课程封面

参考 ​​用户头像上传

1、定义data数据模板

courseInfo:{ //.... cover: ' //....},BASE_API: process.env.BASE_API // 接口API地址

2、组件模板

(3)组件样式

(4)组件效果图

11、课程基本信息页面效果展示

四、课程大纲列表 - 后端开发

1、创建两个实体类,章节和小节

ChapterVo

@ApiModel(value = "章节封装类",description = "章节封装类")@Datapublic class ChapterVo { private String id; private String title; //表示小节 private List children = new ArrayList<>();}

VideoVo

@ApiModel(value = "小节封装类",description = "小节封装类")@Datapublic class VideoVo { private String id; private String title;}

2、编写Controller

@Api(description = "课程大纲")@RestController@RequestMapping("/eduservice/chapter")@CrossOriginpublic class EduChapterController { @Autowired private EduChapterService chapterService; //课程大纲列表,根据课程id进行查询 @ApiOperation("根据课程id查询章节和小节") @GetMapping("getChapterVideo/{courseId}") public R getChapterVideo(@PathVariable String courseId){ List chapterVoList = chapterService.getChapterVideo(courseId); return R.ok().data("list",chapterVoList); }}

3、编写Service

@Servicepublic class EduChapterServiceImpl extends ServiceImpl implements EduChapterService { @Autowired private EduVideoService videoService; //根据课程id查询课程大纲 @Override public List getChapterVideo(String courseId) { //1.查询所有章节 QueryWrapper chapterWrapper = new QueryWrapper <>(); chapterWrapper.eq("course_id",courseId); List chapterList = this.baseMapper.selectList(chapterWrapper); //2.查询所有的小节 QueryWrapper videoWrapper = new QueryWrapper <>(); videoWrapper.eq("course_id",courseId); List videoList = videoService.list(videoWrapper); //定义最终的数据类型 List finalChapterList = new ArrayList (); //3.遍历章节集合,将其封装到List for (EduChapter chapter : chapterList) { ChapterVo chapterVo = new ChapterVo(); BeanUtils.copyProperties(chapter,chapterVo); finalChapterList.add(chapterVo);//将其放入结果集 List children = new ArrayList <>(); //4.遍历小节集合,将其封装到对应的章节中 for (EduVideo video : videoList) { if(video.getChapterId().equals(chapter.getId())){//如果当前小节输入当前章节,则加入该章节 VideoVo videoVo = new VideoVo(); BeanUtils.copyProperties(video,videoVo); children.add(videoVo); } } chapterVo.setChildren(children);//将章节的对应小节设置进去 } return finalChapterList; }}

4、使用Swagger进行测试

五、课程大纲列表 – 前端开发

1、页面模板

  • {{ chapter.title }} 添加小节 编辑 删除

    • {{ video.title }} 编辑 删除

上一步 下一步

2、页面样式