文章目录
- 内容管理模块 - 课程计划
- 一、介绍
- 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 测试
内容管理模块 - 课程计划
一、介绍
这一步是修改课程下一步展示的信息
1.1 需求分析
"修改课程"中点击“保存并进行下一步”就会出现下图的页面
很简单的可以看出也是一个树形接口,一个大章节里面有许多的小章节
1.2 数据模型
1.2.1 课程计划teachplan表
teachplan表
grade字段就是章节等级
parentid是课程计划的父级id
media_type字段是说明将来这个课程是视频的形式还是文档的形式,也就是媒体类型
/*** <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 新增/修改章节
下面圈出来的地方“添加章”是一级章节
下面所示圈出来的地方是添加小章节,也就是二级
修改一二级章节只需要点击就可以修改,当鼠标点击其他位置(文本框失去焦点时)就可以将修改的内容保存
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 测试
修改一级菜单、二级菜单、是否免费
初始时
修改后
新增一级菜单
新增二级菜单