界面原型
第一步: 在课程计划界面,点击添加章
新增第一级课程计划,点击添加小节
可以向某个第一级课程计划下添加小节
第二步: 点击章/节
的名称可以修改名称和选择是否免费
章/节
名称时文本框会自动聚焦,此时用户可以修改名称,失去焦点后会自动发起请求更新数据库中对应字段的信息请求模型类
新增章/节
课程计划
### 新增章,默认添加到所属课程的最后一个章节
POST {{content_host}}/content/teachplan
Content-Type: application/json
{
"courseId" : 74,
"parentid": 0,
"grade" : 1,# 章节等级,当grade为1时parentid为0
"pname" : "新章名称 [点击修改]"# 默认名称
}
#### 新增节,默认添加到所属章节的最后一个小节
POST {{content_host}}/content/teachplan
Content-Type: application/json
{
"courseId" : 74,
"parentid": 247,
"grade" : 2,
"pname" : "新小节名称 [点击修改]"# 默认名称
}
修改节
课程计划的名称和收费规则
#### 修改节,设置是否免费
POST {{content_host}}/content/teachplan
Content-Type: application/json
{
"id": 293,
"pname": "3.1Nacos作配置中心",
"parentid": 292,
"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": null,
"teachPlanTreeNodes": null,
"ctlEditTitle": true,
"ctlBarShow": false
}
新增和修改的唯一区别就是请求参数是否有Id,可以通过同一个接口
接收新增和修改两个业务的请求,这里可以直接使用PO类Teachplan
作为请求参数的模型类
package com.xuecheng.content.model.po;
@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;
}
业务开发
第一步: 定义新增/修改
课程计划(章/节)的接口
@ApiOperation("课程计划创建或修改")
@PostMapping("/teachplan")
public void saveTeachplan(@RequestBody Teachplan teachplanDto) {
teachplanService.saveTeachplan(teachplan);
}
第二步: 编写Servcie接口及其实现类
void saveTeachplan(Teachplan teachplan);
@Transactional// 设置多条DML语句,需要控制事务
@Override
public void saveTeachplan(Teachplan teachplan) {
Long teachplanId = teachplan.getId();
if (teachplanId == null) {
// 课程计划id为null表示需要新增章/节,拷贝属性将请求参数中课程计划的信息封装到创建的Teachplan对象中
Teachplan plan = new Teachplan();
BeanUtils.copyProperties(teachplan, plan);
// 设置创建时间和排序号
plan.setCreateDate(LocalDateTime.now());
// 设置新增章节的排序号.默认排在同等级的最后
plan.setOrderby(getTeachplanCount(plan.getCourseId(), plan.getParentid()) + 1);
// 如果新增失败会返回0,抛出异常
int flag = teachplanMapper.insert(plan);
if (flag <= 0) XueChengPlusException.cast("新增失败");
} else {
// 课程计划id不为null表示需要修改课程,拷贝属性将请求参数中的课程计划信息更新到查询的Teachplan对象中
Teachplan plan = teachplanMapper.selectById(teachplanId);
BeanUtils.copyProperties(teachplan, plan);
// 设置更新时间
plan.setChangeDate(LocalDateTime.now());
// 如果修改失败会返回0,抛出异常
int flag = teachplanMapper.updateById(plan);
if (flag <= 0) XueChengPlusException.cast("修改失败");
}
}
从当前课程关联的所有课程计划中获取与当前章/节
同父同级别的课程计划数量
private int getTeachplanCount(Long courseId, Long parentId) {
LambdaQueryWrapper<Teachplan> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(Teachplan::getCourseId, courseId);
queryWrapper.eq(Teachplan::getParentid, parentId);
return teachplanMapper.selectCount(queryWrapper);
}