3.3 内容管理模块 - 课程计划

news/2025/3/15 17:51:09/

文章目录

  • 内容管理模块 - 课程计划
  • 一、介绍
    • 1.1 需求分析
    • 1.2 数据模型
      • 1.2.1 课程计划teachplan表
      • 1.2.2 teachplan_media 课程计划视频关联表
  • 二、查询课程计划
    • 2.1 查询课程计划
    • 2.2 课程计划Dto
    • 2.3 TeachplanMapper
    • 2.4 TeachplanServiceImpl
    • 2.5 TeachPlanController
  • 三、新增/修改章节内容
    • 3.1 新增/修改章节
    • 3.2 SaveTeachplanDto
    • 3.3 TeachplanServiceImpl
    • 3.3 TeachPlanController
    • 3.4 测试

内容管理模块 - 课程计划

一、介绍

这一步是修改课程下一步展示的信息

image-20231215233053305

1.1 需求分析

"修改课程"中点击“保存并进行下一步”就会出现下图的页面

很简单的可以看出也是一个树形接口,一个大章节里面有许多的小章节

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

1.2 数据模型

1.2.1 课程计划teachplan表

teachplan表

image-20231215233251179

grade字段就是章节等级

parentid是课程计划的父级id

media_type字段是说明将来这个课程是视频的形式还是文档的形式,也就是媒体类型

image-20231215233459273

image-20231215233447977

/*** <p>* 课程计划* </p>** @author itcast*/
@Data
@TableName("teachplan")
public class Teachplan implements Serializable {private static final long serialVersionUID = 1L;@TableId(value = "id", type = IdType.AUTO)private Long id;/*** 课程计划名称*/private String pname;/*** 课程计划父级Id*/private Long parentid;/*** 层级,分为1、2、3级*/private Integer grade;/*** 课程类型:1视频、2文档*/private String mediaType;/*** 开始直播时间*/private LocalDateTime startTime;/*** 直播结束时间*/private LocalDateTime endTime;/*** 章节及课程时介绍*/private String description;/*** 时长,单位时:分:秒*/private String timelength;/*** 排序字段*/private Integer orderby;/*** 课程标识*/private Long courseId;/*** 课程发布标识*/private Long coursePubId;/*** 状态(1正常  0删除)*/private Integer status;/*** 是否支持试学或预览(试看)*/private String isPreview;/*** 创建时间*/@TableField(fill = FieldFill.INSERT)private LocalDateTime createDate;/*** 修改时间*/@TableField(fill = FieldFill.INSERT_UPDATE)private LocalDateTime changeDate;}

1.2.2 teachplan_media 课程计划视频关联表

课程计划如如果是关联视频的话有一张单独的表teachplan_media

media_id和teachplan_id是这张表的重点

为什么这样表中会有course_id课程id?

也很好理解,标识一下这段视频属于哪个课程的

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

/*** <p>* * </p>** @author itcast*/
@Data
@TableName("teachplan_media")
public class TeachplanMedia implements Serializable {private static final long serialVersionUID = 1L;/*** 主键*/@TableId(value = "id", type = IdType.AUTO)private Long id;/*** 媒资文件id*/private String mediaId;/*** 课程计划标识*/private Long teachplanId;/*** 课程标识*/private Long courseId;/*** 媒资文件原始名称*/@TableField("media_fileName")private String mediaFilename;@TableField(fill = FieldFill.INSERT)private LocalDateTime createDate;/*** 创建人*/private String createPeople;/*** 修改人*/private String changePeople;}

二、查询课程计划

2.1 查询课程计划

我们最终要实现这种形式

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

要完成如下形式的数据

[{"id":268,"pname":"1.配置管理","parentid":0,"grade":1,"mediaType":null,"startTime":null,"endTime":null,"description":null,"timelength":null,"orderby":1,"courseId":117,"coursePubId":null,"status":null,"isPreview":null,"createDate":null,"changeDate":null,"teachplanMedia":null,"teachPlanTreeNodes":[{"id":269,"pname":"1.1 什么是配置中心","parentid":null,"grade":2,"mediaType":null,"startTime":null,"endTime":null,"description":null,"timelength":null,"orderby":1,"courseId":117,"coursePubId":null,"status":null,"isPreview":null,"createDate":null,"changeDate":null,"teachplanMedia":{"id":40,"mediaId":"3a5a861d1c745d05166132c47b44f9e4","teachplanId":null,"courseId":null,"mediaFilename":"01-Nacos配置管理-内容介绍.avi","createDate":null,"createPeople":null,"changePeople":null},"teachPlanTreeNodes":null},{"id":270,"pname":"1.2Nacos简介","parentid":null,"grade":2,"mediaType":null,"startTime":null,"endTime":null,"description":null,"timelength":null,"orderby":2,"courseId":117,"coursePubId":null,"status":null,"isPreview":null,"createDate":null,"changeDate":null,"teachplanMedia":{"id":41,"mediaId":"23f83ae728bd1269eee7ea2236e79644","teachplanId":null,"courseId":null,"mediaFilename":"16-Nacos配置管理-课程总结.avi","createDate":null,"createPeople":null,"changePeople":null},"teachPlanTreeNodes":null},{"id":271,"pname":"1.3安装Nacos Server","parentid":null,"grade":2,"mediaType":null,"startTime":null,"endTime":null,"description":null,"timelength":null,"orderby":3,"courseId":117,"coursePubId":null,"status":null,"isPreview":null,"createDate":null,"changeDate":null,"teachplanMedia":{"id":42,"mediaId":"3a5a861d1c745d05166132c47b44f9e4","teachplanId":null,"courseId":null,"mediaFilename":"01-Nacos配置管理-内容介绍.avi","createDate":null,"createPeople":null,"changePeople":null},"teachPlanTreeNodes":null},{"id":272,"pname":"1.4Nacos配置入门","parentid":null,"grade":2,"mediaType":null,"startTime":null,"endTime":null,"description":null,"timelength":null,"orderby":4,"courseId":117,"coursePubId":null,"status":null,"isPreview":null,"createDate":null,"changeDate":null,"teachplanMedia":{"id":43,"mediaId":"3a5a861d1c745d05166132c47b44f9e4","teachplanId":null,"courseId":null,"mediaFilename":"01-Nacos配置管理-内容介绍.avi","createDate":null,"createPeople":null,"changePeople":null},"teachPlanTreeNodes":null},{"id":273,"pname":"1.5命名空间管理","parentid":null,"grade":2,"mediaType":null,"startTime":null,"endTime":null,"description":null,"timelength":null,"orderby":5,"courseId":117,"coursePubId":null,"status":null,"isPreview":null,"createDate":null,"changeDate":null,"teachplanMedia":{"id":44,"mediaId":"23f83ae728bd1269eee7ea2236e79644","teachplanId":null,"courseId":null,"mediaFilename":"16-Nacos配置管理-课程总结.avi","createDate":null,"createPeople":null,"changePeople":null},"teachPlanTreeNodes":null}]},{"id":274,"pname":"2.服务发现","parentid":0,"grade":1,"mediaType":null,"startTime":null,"endTime":null,"description":null,"timelength":null,"orderby":2,"courseId":117,"coursePubId":null,"status":null,"isPreview":null,"createDate":null,"changeDate":null,"teachplanMedia":null,"teachPlanTreeNodes":[{"id":275,"pname":"2.1什么是服务发现","parentid":null,"grade":2,"mediaType":null,"startTime":null,"endTime":null,"description":null,"timelength":null,"orderby":1,"courseId":117,"coursePubId":null,"status":null,"isPreview":null,"createDate":null,"changeDate":null,"teachplanMedia":{"id":45,"mediaId":"1f229319d6fed3431d2f9d06193a433b","teachplanId":null,"courseId":null,"mediaFilename":"01-分布式事务专题课程介绍.avi","createDate":null,"createPeople":null,"changePeople":null},"teachPlanTreeNodes":null},{"id":276,"pname":"2.2服务发现快速入门","parentid":null,"grade":2,"mediaType":null,"startTime":null,"endTime":null,"description":null,"timelength":null,"orderby":2,"courseId":117,"coursePubId":null,"status":null,"isPreview":null,"createDate":null,"changeDate":null,"teachplanMedia":{"id":46,"mediaId":"6ad24a762f67c18f61966c1b8c55abe6","teachplanId":null,"courseId":null,"mediaFilename":"07-分布式事务基础理论-BASE理论.avi","createDate":null,"createPeople":null,"changePeople":null},"teachPlanTreeNodes":null},{"id":277,"pname":"2.3服务发现数据模型","parentid":null,"grade":2,"mediaType":null,"startTime":null,"endTime":null,"description":null,"timelength":null,"orderby":3,"courseId":117,"coursePubId":null,"status":null,"isPreview":null,"createDate":null,"changeDate":null,"teachplanMedia":{"id":47,"mediaId":"1f229319d6fed3431d2f9d06193a433b","teachplanId":null,"courseId":null,"mediaFilename":"01-分布式事务专题课程介绍.avi","createDate":null,"createPeople":null,"changePeople":null},"teachPlanTreeNodes":null},{"id":278,"pname":"2.4服务列表管理","parentid":null,"grade":2,"mediaType":null,"startTime":null,"endTime":null,"description":null,"timelength":null,"orderby":4,"courseId":117,"coursePubId":null,"status":null,"isPreview":null,"createDate":null,"changeDate":null,"teachplanMedia":{"id":48,"mediaId":"6ad24a762f67c18f61966c1b8c55abe6","teachplanId":null,"courseId":null,"mediaFilename":"07-分布式事务基础理论-BASE理论.avi","createDate":null,"createPeople":null,"changePeople":null},"teachPlanTreeNodes":null}]}
]

2.2 课程计划Dto

首先定义一个查询课程计划返回的Dto表

@Data
@ToString
public class TeachplanDto extends Teachplan {private static final long serialVersionUID = 1586804545070538974L;//课程计划关联的媒资信息private TeachplanMedia teachplanMedia;//子节点private List<TeachplanDto> teachPlanTreeNodes;}

2.3 TeachplanMapper

完成课程计划查询的树状结构

我们在本篇文章中的“课程分类”有介绍树状结构查询,可以重新看看

public interface TeachplanMapper extends BaseMapper<Teachplan> {//课程计划查询 - 树状结构public List<TeachplanDto> selectTreeNodes(@Param("courseId") Long courseId);}
<!--简单说明:把数据库查询结果中的column one_id字段映射到TeachplanDto类的id属性property--><!--<id>表示主键字段--><!--<result>表示普通字段--><resultMap id="treeNodeResultMap" type="com.xuecheng.content.model.dto.TeachplanDto"><id column="one_id" property="id"/><result column="one_pname" property="pname"/><result column="one_parentid" property="parentid"/><result column="one_grade" property="grade"/><result column="one_mediaType" property="mediaType"/><result column="one_stratTime" property="startTime"/><result column="one_endTime" property="endTime"/><result column="one_orderby" property="orderby"/><result column="one_courseId" property="courseId"/><result column="one_coursePubId" property="coursePubId"/><!--映射子节点,一对多映射,ofType list中的对象类型--><collection property="teachPlanTreeNodes" ofType="com.xuecheng.content.model.dto.TeachplanDto"><id column="two_id" property="id"/><result column="two_pname" property="pname"/><result column="two_parentid" property="parentid"/><result column="two_grade" property="grade"/><result column="two_mediaType" property="mediaType"/><result column="two_stratTime" property="startTime"/><result column="two_endTime" property="endTime"/><result column="two_orderby" property="orderby"/><result column="two_courseId" property="courseId"/><result column="two_coursePubId" property="coursePubId"/><!--javaType一对一映射 (小章节和视频直接的关系是一对一)--><association property="teachplanMedia" javaType="com.xuecheng.content.model.po.TeachplanMedia"><id column="teachplanMeidaId" property="id"/><result column="mediaFilename" property="mediaFilename"/><result column="mediaId" property="mediaId"/></association></collection></resultMap><select id="selectTreeNodes" resultMap="treeNodeResultMap">select one.id            one_id,one.pname         one_pname,one.parentid      one_parentid,one.grade         one_grade,one.media_type    one_mediaType,one.start_time    one_startTime,one.end_time      one_endTime,one.orderby       one_orderby,one.course_id     one_courseId,one.course_pub_id one_coursePubId,two.id            two_id,two.pname         two_pname,two.grade         two_grade,two.media_type    two_mediaType,two.start_time    two_startTime,two.end_time      two_endTime,two.orderby       two_orderby,two.course_id     two_courseId,two.course_pub_id two_coursePubId,m1.media_fileName mediaFilename,m1.id             teachplanMeidaId,m1.media_id       mediaIdFROM teachplan oneLEFT JOIN teachplan two on two.parentid = one.idLEFT JOIN teachplan_media m1 on two.id = m1.teachplan_idwhere one.parentid = 0and one.course_id = #{courseId}</select>

2.4 TeachplanServiceImpl

@Service
public class TeachplanServiceImpl implements TeachplanService {@Autowiredprivate TeachplanMapper teachplanMapper;/*** 查询课程计划树形结构* @param courseId 课程id* @return 课程计划树形结构*/@Overridepublic List<TeachplanDto> findTeachplanTree(long courseId) {return teachplanMapper.selectTreeNodes(courseId);}
}

2.5 TeachPlanController

/*** 课程计划相关接口*/
@Api(value = "课程计划编辑接口",tags = "课程计划编辑接口")
@RestController
public class TeachPlanController {@Autowiredprivate TeachplanServiceImpl teachplanService;//查询课程计划@ApiOperation("查询课程计划树形结构")@GetMapping("/teachplan/{courseId}/tree-nodes")//针对参数进行说明@ApiImplicitParam(value = "courseId",name = "课程id",required = true,dataType = "Long",paramType = "path")public List<TeachplanDto> getTreeNodes(@PathVariable Long courseId) {return teachplanService.findTeachplanTree(courseId);}
}

三、新增/修改章节内容

3.1 新增/修改章节

image-20231216210056412

下面圈出来的地方“添加章”是一级章节

image-20231216204015027

下面所示圈出来的地方是添加小章节,也就是二级

image-20231216205005853

修改一二级章节只需要点击就可以修改,当鼠标点击其他位置(文本框失去焦点时)就可以将修改的内容保存

3.2 SaveTeachplanDto

/*** @description 新增大章节、小章节、修改章节信息*/
@Data
public class SaveTeachplanDto {/**** 教学计划id*/private Long id;/*** 课程计划名称*/private String pname;/*** 课程计划父级Id*/private Long parentid;/*** 层级,分为1、2、3级*/private Integer grade;/*** 课程类型:1视频、2文档*/private String mediaType;/*** 课程标识*/private Long courseId;/*** 课程发布标识*/private Long coursePubId;/*** 是否支持试学或预览(试看)*/private String isPreview;
}

3.3 TeachplanServiceImpl

    /*** 新增/修改/保存课程计划** @param saveTeachplanDto*/@Overridepublic void saveTeachplan(SaveTeachplanDto saveTeachplanDto) {//通过课程计划id判断是新增还是修改(新增新增课程的时候不会有id)//教学计划idLong teachplanId = saveTeachplanDto.getId();if (teachplanId == null) {//新增Teachplan teachplan = new Teachplan();BeanUtils.copyProperties(saveTeachplanDto, teachplan);//确定排序的字段// 大章节的添加: 查询某个课程id下有多少个大章节即可// select count(1) from teachplan where course_id = 117 and parentid = 0// 小章节的添加:(我们只需要找到同级节点有几个即可,也就是parentId相同的就是同级的)//select count(1) from teachplan where course_id = 117 and parentid = 父级idLong parentId = saveTeachplanDto.getParentid();Long courseId = saveTeachplanDto.getCourseId();int count = this.getTeachplanCount(courseId, parentId);// 确定排序字段teachplan.setOrderby(count + 1);teachplanMapper.insert(teachplan);} else {//修改Teachplan teachplan = teachplanMapper.selectById(teachplanId);//将要修改的参数复制到teachplan里BeanUtils.copyProperties(saveTeachplanDto, teachplan);teachplanMapper.updateById(teachplan);}}
}private int getTeachplanCount(long courseId, long parentId) {LambdaQueryWrapper<Teachplan> queryWrapper = new LambdaQueryWrapper<>();queryWrapper.eq(Teachplan::getCourseId, courseId).eq(Teachplan::getParentid, parentId);return teachplanMapper.selectCount(queryWrapper);}

3.3 TeachPlanController

@ApiOperation("课程计划创建或修改")
@PostMapping("/teachplan")
public void saveTeachplan(@RequestBody SaveTeachplanDto teachplanDto){teachplanService.saveTeachplan(teachplanDto);
}

3.4 测试

修改一级菜单、二级菜单、是否免费

初始时

image-20231216235620261

修改后

image-20231216235715602


新增一级菜单

image-20231217002433534

新增二级菜单

image-20231217000004794


http://www.ppmy.cn/news/1274801.html

相关文章

算法通关第十九关-青铜挑战理解动态规划

大家好我是苏麟 , 今天聊聊动态规划 . 动态规划是最热门、最重要的算法思想之一&#xff0c;在面试中大量出现&#xff0c;而且题目整体都偏难一些对于大部人来说&#xff0c;最大的问题是不知道动态规划到底是怎么回事。很多人看教程等&#xff0c;都被里面的状态子问题、状态…

CentOS:Docker 创建及镜像删除

1、安装docker 远程连接服务器&#xff0c;可以直接下载netsarang比较好用 家庭/学校免费 - NetSarang Website 如果有残留docker未删除干净&#xff0c;请使用 sudo yum -y remove docker docker-common docker-selinux docker-engine Step1&#xff1a;安装必要的一些…

C# CSV文件(逗号分隔符)的读取和写入

1.CSV文件的写入原理&#xff1a; ①csv文件文件为逗号分隔符方式写入&#xff0c;起始写入的坐标位置为单元格的&#xff08;0,0&#xff09;假设用x,y分别表示单元格的横纵坐标&#xff0c;每次追加写入时&#xff0c;默认x坐标不变&#xff0c;y坐标都会1。 ②默认csv文件…

一文快速了解oCPX

01 什么是oCPX o是Optimized&#xff0c;优化一词的首字母。 CPX即Cost Per X&#xff0c;“X”即泛指传统的那些按不同方式进行结算的模式&#xff0c;如&#xff1a;CPC&#xff08;Cost Per Click&#xff0c;按点击付费&#xff09;、CPM&#xff08;Cost Per Mille&…

Spring学习?这一篇文章就够,史上最全!

文章目录 前言一、IOC概述及底层原理1.概述和原理 二、思路分析三、IOC操作bean管理&#xff08;基于xml&#xff0c;使用的是IDEA2022.3.3&#xff0c;maven仓库&#xff09;1.xml实现bean管理&#xff08;1&#xff09;创建对象&#xff08;2&#xff09;注入属性&#xff08…

Hugging Face实战-系列教程20:文本摘要建模实战2 之 Tokenizer处理

&#x1f6a9;&#x1f6a9;&#x1f6a9;Hugging Face 实战系列 总目录 有任何问题欢迎在下面留言 本篇文章的代码运行界面均在Jupyter Notebook中进行 本篇文章配套的代码资源已经上传 文本摘要建模实战1 之 数据清洗 文本摘要建模实战2 之 Tokenizer处理 3 Tokenizer处理 …

vue 项目配置反向代理导致项目白屏

问题&#xff1a;vue 项目配置反向代理导致项目白屏 一、现象描述 添加反向代理代码后&#xff0c;前端运行白屏 // 设置baseURL&#xff0c;8888是后端端口号&#xff0c;前端请求默认发送到baseURL的地址 var axios require(axios) axios.defaults.baseURL http://local…

【Linux】进程状态、进程优先级和进程切换

> 作者简介&#xff1a;დ旧言~&#xff0c;目前大二&#xff0c;现在学习Java&#xff0c;c&#xff0c;c&#xff0c;Python等 > 座右铭&#xff1a;松树千年终是朽&#xff0c;槿花一日自为荣。 > 目标&#xff1a;了解冯诺依曼体系结构与操作系统&#xff0c;掌握…