课程管理-章节后端接口开发 | 学习笔记

简介: 简介:快速学习课程管理-章节后端接口开发

开发者学堂课程【微服务+全栈在线教育实战项目演练(SpringCloud Alibaba+SpringBoot):课程管理-章节后端接口开发】学习笔记,与课程紧密联系,让用户快速学习知识。

课程地址:https://developer.aliyun.com/learning/course/667/detail/11383


课程管理-章节后端接口开发

 

内容介绍

一、本章介绍

二、章节添加页面部分

三、章节添加,删除和修改接口部分

 

一、本章介绍

首先做的第一个功能,将课程大纲列表中章节做操作,因为之前仅仅做了一个列表功能。章节有它的添加,删除和修改功能。接下来我们对章节的添加,删除和修改功能做实现。同时小节中也有添加,删除和修改功能,但仅仅对小节的删除和修改进行讲解,其他按照章节留给同学自行完成。接下来要完成的第一部分就是章节添加,删除和修改功能;

image.png

第二部分为即第三步最终发布。

image.png

也是课程信息的确认,即该图的效果,还有课程最终发布。将之前填写的课程信息做个显示,做个确认目录,最后点最终发布,课程就真正进行发布。

所以之后主要完成,第一部分章节小节的增加、修改和删除功能,第二部分课程信息确认和最终发布。


二、章节添加页面部分

首先做第一个功能,课程章节的添加,删除和修改功能。

1. 分析

为了效果明显,添加一条数据:标题为测试下午内容,一级分类为前端开发,二级分类为 vue,课程讲师为李四,总课时为10,课程简介为111,课程封面默认,课程价格为10。

image.png

点击保存并下一步,课程信息就添加进去。

到达第二步:创建课程大纲。

同时注意,当填写课程基本信息后,课程中还没有章节小节,因为还没有添加,上午显示内容是为了巩固创建课程大纲部分的内容,按照正确顺序,填写填写课程基本信息后,课程中没有章节小节。

而在第二步:创建课程大纲中要添加章节,首先应该有添加章节的按钮。我们将添加章节的按钮加在如图位置,这就是要做的第一部分内容。

image.png

接下来第二部分,当点击添加章节后要对应添加章节信息,需要在表单中进行添加,可以做成和之前添加讲师的效果,但在此采取使用弹框的方式,使得点击按钮后能够弹出一个页面,在弹出界面中输入章节的名称包括章节数据,最后点击保存作添加。这就是第二步,添加一个弹框,在弹框中输入课程信息最后保存。

image.png

2. 添加按钮

按照分析过程,对其做实现,首先添加一个添加章节的按钮或超链接。在此添加按钮,只需要赋值01-课程大纲列表中的按钮代码放在 chapter.vue 课程大纲页面代码12行即可。

l 代码如下:

<el-button type="text">添加章节</el-button>

添加代码后,刷新页面,就可以看见页面中显示了添加章节按钮。

3. 添加弹框

① 分析

之后再使得点击按钮能够弹出一个弹框,再在弹框中输入章节名称。打开 Element网站查找弹框如何实现。找到 MUI,进入页面点击组件部分的查看详情,查看其中关于弹框的组件 MessageBox 弹框,在其中查看是否为对应的弹框形式。

消息提示显然不是,因为我们需要能够输入的地方。

提交内容,显示的效果接近,打开源代码后发现它是直接写了一段JavaScript代码实现,该方法可实现,但一般更倾向于使用标签来实现。

l 代码如下:

<tesplate>

<el-button type="text " @click="open">点击打开Hessage Box</el-button>

</templat e>

<script>

export default {

methods : {

open( ) i

this.$prompt ('请输入邮箱''提示',iconfirmButtonText :‘确定',

cancelButtonText :'取消',

inputPattern:/[w!#$88'*+/m?^_`K/)--]+(? \.[ \w I#$88'*+/日?_`{/--]+)*[P(?:[\w](?:[ \w-]*[\w])?入.)+[\w](?:[\....

inputErrorHessage:'邮箱格式不正确‘

}).then((i value }) => {

this.$message({

type: 'success ',

message: ‘你的邮箱是:' + value

});

).catch(() =>ithis.$message(itype: 'info ',

message:‘取消输入′

});

});

}

}

}

<f s cript>

② 表单代码

所以再向下翻找到,Dialog 对话框,将其点开其中有各种内容,找到其中的自定义内容,点击效果展示,发现与所期望的一致,点击查看源码。

image.png

该部分代码为表格,并不需要所以删除即可。

<!-- Table -->

<el-button type="text" @click="dialogTableVisible = true">打开嵌套表格的 Dialog</el-button>

<el-dialog title="收货地址" :visible.sync="dialogTablevisible">

<el-table :data="gridData">

<el-table-column property="date" label="日期"width=*150"></el-table-column>

<el-table-column property="name" label="姓名" width="200"></el-table-column>

<el-table-column property="address" label="地址"></el-table-column>

</el-table>

</el-dialog>

查看表单部分如何实现即可。表单部分表示,当点击页面中的打开嵌套表单的Dialog 后会弹出弹框,就是我们需要在添加章节中做的内容。

image.png

l 代码如下:

<!-- Form -->

//在打开开嵌套表单的Dialog按钮button中有个@click事件,在事件中有个dialogFormVisible值为true

<el-button type="text" @click="dialogFormVisible = true">打开嵌套表单的 Dialog</el-button>

//el-dialog表示对话框,visible属性表示是否显示,显示的值为dialogFormVisible,所以当我们要显示弹框的代码结构和其一致。

<el-dialog title="收货地址” :visible.sync="dialogFormVisible">

//表示dialogFormVisible为true就弹出页面,为false就隐藏

//之后再添加el-form表单部分即可。

<el-form :model="form">

<el-form-item label="活动名称" :label-width="formLabelwidth">

<el-input v-model="form.name " autocomplete="off"></el-input>

</ el-form-item>

<el-form-item label="活动区域” :label-width="formLabelwidth">

<el-select v-model="form.region" placeholder="请选择活动区域

<el-option label="区域一" value="shanghai"></ el-option>

<el-option label="区域二" value="beijing"></el-option>

</el-select>

</el-form-item></el-form>

<div slot="footer" class="dialog-footer">

<el-button @click="dialogFormvisible = false">取消</el-button>

<el-button type="primary" @click="dialogFormvisible = false">确定</el-button>

</ div>

</el-dialog>

根据以上 Dialog 对话框的写法,直接在课件03-章节管理器阿奴单页面实现中的章节表单 diglog 复制表单代码到 chapter.vue 页面代码即可,不必自行编写。弹框代码位置任意,只要放在</div></div>标签中即可

l 代码如下:

<! --添加和修改章节表单-->

<el-dillog :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="o" 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>

③ 赋初始值

表单代码中的 dialogChapterFormVisible 为其在 data()中赋初值,默认为 false 表示章节弹框值。同时其中还有一个 v-model=chapter.title,将其中的 chapter 也定义,方便之后操作。

export default {

data() {

return {

saveBtnDisabled:false,

courseId: ' ',//课程

idchaptervideoList:[],

chapter:{//封装章节数据,其中的属性之后再完善

},

dialogChapterFormvisible:false//章节弹框

}

},

④ 显示弹框

之后让 dialogChapterFormVisible 为 ture 使得弹框出现。首先将 chaoter.vue13行代码,绑定弹框出现事件为 dialogChapterFormVisible为ture,在此也可以编写一个方法实现。

l 代码如下:

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

保存并运行代码后,此时的效果则为点击添加章节按钮时,dialogChapterFormVisible 值就会为 ture,弹框就会显示

⑤ 效果展示

运行代码之后,刷新页面,当点击添加章节时,就会出现添加章节的弹框。同时还能输入章节标题和设置排序。

假设此时输入章节标题为第一章,章节排序为1。点击确定之后数据就应该加在数据库中。

image.png

⑥ 小问题

在复制课程大纲页面代码时,要全部复制来覆盖原来页面包括最后代码的上一步下一步实现完整替换,否则页面样式会出现问题。

l 完整代码如下:

<el-button type="text”>添加章节</el-button>

<! --章节-->

//class为设置的样式

<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 classmchanpterList videoList">

<li

v-form" 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>

到此页面效果就全部完成。最后编写接口部分,通过接口来实现功能。

 

三、开发章节添加,删除和修改接口部分

最后来写章节添加的接口,最终通过页面调用将功能实现出来。因为是章节所以先来到 EduChapterController 中,在课程大纲列表,根据课程 id 进行查询的代码下继续添加。再写个添加章节

1. 添加章节

l 代码如下:

//添加章节

//使用post提交方式,叫做addChapter

@PostMapping(" addChapter")

//编写方法addChapter(),章节中有许多数据,最后使用对象chapter进行提交,所以用@RequestBody通过路径获取eduChapter

public R addChapter(@RequestBody EduChapter eduChapter){

//调用chapterService中的save添加方法,传入参数eduChapter,完成添加操作。

chapterService. save(eduChapter) ;

//最后return

return R. ok() ;

}

以上就是添加的所有操作。

2. 根据章节 id 查询

l 代码如下:

//根据章节id查询

//get提交方式,重命名为getChapterInfo,传入章节id

@GetMapping("getChapterInfo/ {chapterId}")

//编写方法getChapterInfo的具体内容,同时使用@PathVariable注解,通过路径将章节id值在方法中取到

public R getChapterInfo(@PathVariable String chapterId){

//调chapterService中的方法-getById根据id查询,将chapterId传入,返回一个章节对象eduChapter

EduChapter eduChapter = chapterService. getById(chapterId);

//最后return,命名为chapter值为eduChapter。

return R. ok() .data("chapter" , eduChapter);

}

这是第二个根据 id 查询。

3.修改章节

是根据回显,再进行修改。修改与添加代码差不多,复制添加章节代码进行修改即可。

l 代码如下:

//修改章节

//使用post提交方式,叫做updateChapter

@PostMapping ("updateChapter")

//编写方法updateChapter(),用@RequestBody通过路径获取eduChapter

public R updateChapter(@RequestBody EduChapter eduChapter){

/调用chapterService中的updateById根据id查询方法

chapterService. updateById(eduChapter) ;

//返回一个值

return R.ok() ;

}

到此就快速将添加,修改和根据 id 查询给完成了。最后还有一个删除接口。

4.删除章节

在方法中调用chapterService中的删除方法时,有一些问题。来到页面,ctrl+f5 刷新。

假设此时要将第七章:I/O 流删除,因为章节之中有小节,所以直接删章节,小节的存在就毫无意义。所以,如果章节之中没有小节,可以直接删除;但如果章节中有小节时,该如果删除?

章节中有小节或一级分类下有二级分类,在开发时通常有两种实现方式。

第一种,在删除章节时,将其中所有的小节都删掉。

第二种,如果删除的章节中有小节,不让进行删除。

即当删除第七章:I/O 流时,其中有小节,则不让其进行删除。我们在此选用第二种方式,当有小节时选择不删。

当做到课程删除时,再采用第一种方式。当课程中有章节、小节、描述视频就都删掉。

l 代码如下:

//删除的方法

//使用delete提交,传入参数chapterId课程id值

@DeleteMapping(" {chapterId}")

//定义deleteChapter方法,在其中得到id

public R deleteChapter(@PathVariable String chapterId){

//添加一个Service中的deleteChapter方法删除,传入课程id。

chapterService.deleteChapter(chapterId);

//return一个值

return R.ok() ;

(1)首先创建方法

(2)定义方法

在 service 的 interface 中定义删除的方法。

l 代码如下:

void deleteChapter(String chapterId);

(3)EduChapterServiceImpl 实现类

创建后来到它的实现类中编写这个方法,思路为如果删除的章节中有小节,不让其进行删除。

如果没有小节才删除。首先根据章节 id 在小节表做个查询,如果有小节,则不删除,反之则删除。而小节表中有 chapter_id 字段,所以该字段进行查询是否有小节。

image.png

l 代码如下:

////删除章节的方法

@Override

public void deleteChapter(String chapterId){

//根据chapterid章节id查询小节表,如果查询数据,不进行删除

QueryWrapper<EduVideo> wrapper = new QueryWrapper<>();

//设置wrapper查询条件,根据查小节表的chapter_id与chapterId的值是否一致,来看其中有没有小节。

wrapper.eq( column:" chapter_id" , chapterId) ;

}

调用注入的 videoService 中的 count 方法,若使用 list 方法,写作:List<Eduvideo> list = videoService.list(wrapper);由集合判断也可以实现,但是并不好。

因为此时想要查询的为章节下是否有小节,而并非想将小节的数据全部取到,所以使用 list 查出的小节数据并没有用处。所以使用 videoServicecount (Wrapper<EduVideo> wrapper)方法最优,里面就只传了 wrapper 对象。

返回的int类型值表示根据条件能查出来几条记录。如此时要查出章节 id 为3的小节,有一条记录,返回值就是1;假设根据11章节 id 查小节,有两条记录,就是2。

所以 count 方法比较准确,不需得到数据,只得到值即可。

image.png

l 代码如下:

int count = videoService.count (wrapper) ;

最后做一个判断,如果 count 中值不为,0有数据,表示能查询出小节。那么不进行删除。else 表示 count 值为0,不能查询数据,进行删除。

l 代码如下:

//判断

if(count >0){V//查询出小节,不进行删除

//直接throw一个GuliException异常,状态码20001提示不能删除

throw new GuliException (20001,"不能删除");

}else { //不能查询数据,进行删除

//删除章节,调用baseMapper中的deleteById()方法,同时传入章节id,最后赋值给result

lint result = baseMapper. deleteById(chapterId);

Ø 更改为布尔类型

为了方便判断,在删除的接口代码 EduChapterController.java 中添加 boolean 类型的返回值。同时添加一个判断,如果为 true,则 return R.ok();如果为 false,则return R.error()

l 代码如下:

//删除的方法

//使用delete提交,传入参数chapterId课程id值

@DeleteMapping(" {chapterId}")

//定义deleteChapter方法,在其中得到id

public R deleteChapter(@PathVariable String chapterId){

//添加boolean类型返回值

boolean flag = chapterService.deleteChapter(chapterId);

//同时添加一个判断,如果为true,则return R.ok();如果为false,则return R.error()

if(flag){

return R.ok() ;

}else{

return R.error();

}

包括 interface 中,即 EduChapterService.java 中的删除章节的方法,都变为返回boolean 类型

l 代码如下:

boolean deleteChapter(String chapterId);

实现类中也返回布尔类型

l 代码如下:

public boolean deleteChapter(String chapterId){

最后在删除方法的实现类中对最后的值 result 作个判断,因为 result 表示影响行数,所以如果成功删除值为1,删除失败值为0。所以大于0为成功,0为失败。

当删除成功 result为1,1>0为 true,则 return true;如果为失败,result为0,0>0为false,则 return false;

l 代码如下:

//返回值,表示查不出章节中的小节则删除

return result>0;

删除方法的整体思路就是,根据章节 id 查小节,count>就是有小节,不能删。如果等于0,就是没有小节,删除章节,最后返回false。

l 完整代码如下-删除的方法:

////删除章节的方法

@Override

public boolean deleteChapter(String chapterId){

//根据chapterid章节id查询小节表,如果查询数据,不进行删除

QueryWrapper<EduVideo> wrapper = new QueryWrapper<>();

//设置wrapper查询条件,根据查小节表的chapter_id与chapterId的值是否一致,来看其中有没有小节。

wrapper.eq( column: " chapter_id" , chapterId) ;

//调用注入的videoService中的count方法,返回的int类型值count表示根据条件能查出来几条记录

int count = videoService.count(wrapper);

//判断

if(count >0){//查询出小节,不进行删除

//直接throw一个GuliException异常,状态码20001提示不能删除

throw new GuliException(20001,"不能删除");

} else {//不能查询数据,进行删除

//删除章节

int result = baseMapper.deleteById(chapterId);

//成功1>0  0>0

return result>0;

}

相关文章
|
4天前
|
Web App开发 JavaScript 前端开发
Node.js 是一种基于 Chrome V8 引擎的后端开发技术,以其高效、灵活著称。本文将介绍 Node.js 的基础概念
Node.js 是一种基于 Chrome V8 引擎的后端开发技术,以其高效、灵活著称。本文将介绍 Node.js 的基础概念,包括事件驱动、单线程模型和模块系统;探讨其安装配置、核心模块使用、实战应用如搭建 Web 服务器、文件操作及实时通信;分析项目结构与开发流程,讨论其优势与挑战,并通过案例展示 Node.js 在实际项目中的应用,旨在帮助开发者更好地掌握这一强大工具。
20 1
|
14天前
|
存储 SQL API
探索后端开发:构建高效API与数据库交互
【10月更文挑战第36天】在数字化时代,后端开发是连接用户界面和数据存储的桥梁。本文深入探讨如何设计高效的API以及如何实现API与数据库之间的无缝交互,确保数据的一致性和高性能。我们将从基础概念出发,逐步深入到实战技巧,为读者提供一个清晰的后端开发路线图。
|
8天前
|
JSON API 开发者
构建高效API:后端开发中的RESTful最佳实践####
在数字化时代,API作为不同系统间通信的桥梁,其重要性日益凸显。本文将深入探讨RESTful API的设计原则与最佳实践,通过实际案例分析,揭示如何构建高效、可维护且易于使用的API接口,助力后端开发者提升项目质量与用户体验。 ####
|
9天前
|
JSON 缓存 API
探索后端开发中的RESTful API设计原则
【10月更文挑战第41天】在后端开发的广阔天地中,API的设计如同绘制一幅精细的地图,指引着数据的流向和前端的交互。本文将带你走进RESTful API的世界,一起探索如何用简洁高效的设计原则来构建一个清晰、可维护且易于理解的API结构。我们将从RESTful API的基础概念出发,通过实际案例分析,揭示如何在实践中应用这些设计原则,并讨论如何在复杂的业务逻辑中保持API的简洁性和一致性。
|
13天前
|
JSON 前端开发 API
后端开发中的API设计与文档编写指南####
本文探讨了后端开发中API设计的重要性,并详细阐述了如何编写高效、可维护的API接口。通过实际案例分析,文章强调了清晰的API设计对于前后端分离项目的关键作用,以及良好的文档习惯如何促进团队协作和提升开发效率。 ####
|
15天前
|
存储 SQL 数据库
深入浅出后端开发之数据库优化实战
【10月更文挑战第35天】在软件开发的世界里,数据库性能直接关系到应用的响应速度和用户体验。本文将带你了解如何通过合理的索引设计、查询优化以及恰当的数据存储策略来提升数据库性能。我们将一起探索这些技巧背后的原理,并通过实际案例感受优化带来的显著效果。
31 4
|
14天前
|
Web App开发 JavaScript 前端开发
深入浅出Node.js后端开发
【10月更文挑战第36天】本文将引导您探索Node.js的世界,通过实际案例揭示其背后的原理和实践方法。从基础的安装到高级的异步处理,我们将一起构建一个简单的后端服务,并讨论如何优化性能。无论您是新手还是有经验的开发者,这篇文章都将为您提供新的视角和深入的理解。
|
15天前
|
监控 API 持续交付
后端开发中的微服务架构实践与挑战####
本文深入探讨了微服务架构在后端开发中的应用,分析了其优势、面临的挑战以及最佳实践策略。不同于传统的单体应用,微服务通过细粒度的服务划分促进了系统的可维护性、可扩展性和敏捷性。文章首先概述了微服务的核心概念及其与传统架构的区别,随后详细阐述了构建微服务时需考虑的关键技术要素,如服务发现、API网关、容器化部署及持续集成/持续部署(CI/CD)流程。此外,还讨论了微服务实施过程中常见的问题,如服务间通信复杂度增加、数据一致性保障等,并提供了相应的解决方案和优化建议。总之,本文旨在为开发者提供一份关于如何在现代后端系统中有效采用和优化微服务架构的实用指南。 ####
|
17天前
|
消息中间件 设计模式 运维
后端开发中的微服务架构实践与挑战####
本文深入探讨了微服务架构在现代后端开发中的应用,通过实际案例分析,揭示了其在提升系统灵活性、可扩展性及促进技术创新方面的显著优势。同时,文章也未回避微服务实施过程中面临的挑战,如服务间通信复杂性、数据一致性保障及部署运维难度增加等问题,并基于实践经验提出了一系列应对策略,为开发者在构建高效、稳定的微服务平台时提供有价值的参考。 ####
|
13天前
|
缓存 前端开发 API
探索后端开发中的API设计原则
【10月更文挑战第37天】本文旨在引导读者理解API设计的核心理念,通过简明的语言和直观的示例,揭示如何构建高效、稳定且易于维护的后端接口。我们将深入浅出地探讨RESTful API的设计规范,并通过一个简易的代码样例,展示如何在实战中应用这些原则。无论你是初学者还是有经验的开发者,这篇文章都将为你提供宝贵的参考和启示。

热门文章

最新文章

下一篇
无影云桌面