查询所有计划

树型表使用自连接查询,使用Mybatis的一对多映射形成二级目录结构

接口信息如下

路径地址 http://localhost:63040/content/teachplan/1/tree-nodes
请求方式 GET
请求参数 路径参数Long
返回结果 List

定义TeachPlanVO

其中teachPlanMedia是关联媒体文件,只有根节点才有该属性。

/**
* 课程计划信息模型类
*/
@Data
@EqualsAndHashCode(callSuper = true)
public class TeachPlanVO extends TeachPlan {

private TeachPlanMedia teachplanMedia;
private List<TeachPlanVO> teachPlanTreeNodes;

}

定义Mapper

找到TeachPlanMapper接口,定义计划查询接口:

TeachPlanMapper
/**
* <p>
* 课程计划 Mapper 接口
* </p>
*
* @author sw-code
* @since 2023-08-18
*/
public interface TeachPlanMapper extends BaseMapper<TeachPlan> {

/**
* 查询课程计划
*
* @param courseId 课程Id
* @return 课程计划
*/
public List<TeachPlanVO> getTreeNodes(@Param("courseId") Long courseId);

}

找到TeachPlanMapper.xml文件,编写查询接口。

课程计划是固定二级结构,所以使用自连接查询,然后使用Mybatis的一对多映射和一对一映射实现二级目录查询。

TeachPlanMapper.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.swx.content.mapper.TeachPlanMapper">

<resultMap id="treeNodeResultMap" type="com.swx.content.model.vo.TeachPlanVO">
<id column="one_id" property="id" />
<result column="one_pname" property="pname" />
<result column="one_grade" property="grade" />
<result column="one_mediaType" property="mediaType" />
<result column="one_startTime" 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" />
<!-- 映射子节点,一对多映射 -->
<collection property="teachPlanTreeNodes" ofType="com.swx.content.model.vo.TeachPlanVO">
<id column="two_id" property="id" />
<result column="two_id" property="pname" />
<result column="two_grade" property="grade" />
<result column="two_mediaType" property="mediaType" />
<result column="two_startTime" 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" />
<!-- 映射子节点,一对一映射 -->
<association property="teachplanMedia" javaType="com.swx.content.model.po.TeachPlanMedia">
<id column="teachPlanMediaId" property="id" />
<result column="mediaFilename" property="mediaFilename" />
<result column="mediaId" property="mediaId" />
</association>
</collection>

</resultMap>

<select id="getTreeNodes" parameterType="long" resultMap="treeNodeResultMap">
SELECT one.id one_id,
one.pname one_pname,
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,
tm.media_fileName mediaFilename,
tm.id teachPlanMediaId,
tm.media_id mediaId
FROM teachplan one
LEFT JOIN teachplan two ON one.id = two.parentid
LEFT JOIN teachplan_media tm on two.id = tm.teachplan_id
WHERE one.parentid = 0
AND one.course_id = #{courseId}
</select>

</mapper>

定义Service

找到TeachPlanService接口,定义计划查询接口

TeachPlanService
/**
* <p>
* 课程计划 服务类
* </p>
*
* @author sw-code
* @since 2023-08-18
*/
public interface TeachPlanService extends IService<TeachPlan> {

/**
* 查询课程计划树形结构
*
* @param courseId 课程Id
* @return 课程计划树形结构
*/
public List<TeachPlanVO> getTreeNodes(Long courseId);

}

实现该方法,找到其实现类TeachPlanServiceImpl

TeachPlanServiceImpl
/**
* <p>
* 课程计划 服务实现类
* </p>
*
* @author sw-code
* @since 2023-08-18
*/
@Service
public class TeachPlanServiceImpl extends ServiceImpl<TeachPlanMapper, TeachPlan> implements TeachPlanService {

/**
* 查询课程计划树形结构
*
* @param courseId 课程Id
* @return 课程计划树形结构
*/
@Override
public List<TeachPlanVO> getTreeNodes(Long courseId) {
return baseMapper.getTreeNodes(courseId);
}
}

定义Controller

TeachPlanController
/**
* <p>
* 课程计划信息 前端控制器
* </p>
*
* @author sw-code
* @since 2023-08-20
*/
@Api(value = "课程计划信息编辑接口", tags = "课程计划信息编辑接口")
@RestController
@ResponseResult
@RequestMapping("/teachplan")
public class TeachPlanController {

private final TeachPlanService teachPlanService;

public TeachPlanController(TeachPlanService teachPlanService) {
this.teachPlanService = teachPlanService;
}

@ApiOperation("查询课程计划树形结构")
@GetMapping("/{courseId}/tree-nodes")
public List<TeachPlanVO> getTreeNodes(@PathVariable("courseId") Long courseId) {
return teachPlanService.getTreeNodes(courseId);
}
}

课程查询信息服务以提供,打开前端项目查看是否成功

Push到Git

commit "完成课程计划查询功能"

更新课程计划

接口信息如下

路径地址 http://localhost:63040/content/teachplan/1/tree-nodes
请求方式 POST
请求参数 SaveTeachPlan
返回结果 List

定义TeachPlanVO

其中teachPlanMedia是关联媒体文件,只有根节点才有该属性。

/**
* 课程计划信息模型类
*/
@Data
@EqualsAndHashCode(callSuper = true)
public class TeachPlanVO extends TeachPlan {

private TeachPlanMedia teachPlanMedia;
private List<TeachPlanVO> teachPlanTreeNodes;

}

定义Mapper

找到TeachPlanMapper接口,定义计划查询接口:

TeachPlanMapper
/**
* <p>
* 课程计划 Mapper 接口
* </p>
*
* @author sw-code
* @since 2023-08-18
*/
public interface TeachPlanMapper extends BaseMapper<TeachPlan> {

/**
* 查询课程计划
*
* @param courseId 课程Id
* @return 课程计划
*/
public List<TeachPlanVO> getTreeNodes(@Param("courseId") Long courseId);

}

找到TeachPlanMapper.xml文件,编写查询接口。

课程计划是固定二级结构,所以使用自连接查询,然后使用Mybatis的一对多映射和一对一映射实现二级目录查询。

TeachPlanMapper.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.swx.content.mapper.TeachPlanMapper">

<resultMap id="treeNodeResultMap" type="com.swx.content.model.vo.TeachPlanVO">
<id column="one_id" property="id" />
<result column="one_pname" property="pname" />
<result column="one_grade" property="grade" />
<result column="one_mediaType" property="mediaType" />
<result column="one_startTime" 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" />
<!-- 映射子节点,一对多映射 -->
<collection property="teachPlanTreeNodes" ofType="com.swx.content.model.vo.TeachPlanVO">
<id column="two_id" property="id" />
<result column="two_id" property="pname" />
<result column="two_grade" property="grade" />
<result column="two_mediaType" property="mediaType" />
<result column="two_startTime" 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" />
<!-- 映射子节点,一对一映射 -->
<association property="teachPlanMedia" javaType="com.swx.content.model.po.TeachPlanMedia">
<id column="teachPlanMediaId" property="id" />
<result column="mediaFilename" property="mediaFilename" />
<result column="mediaId" property="mediaId" />
</association>
</collection>

</resultMap>

<select id="getTreeNodes" parameterType="long" resultMap="treeNodeResultMap">
SELECT one.id one_id,
one.pname one_pname,
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,
tm.media_fileName mediaFilename,
tm.id teachPlanMediaId,
tm.media_id mediaId
FROM teachplan one
INNER JOIN teachplan two ON one.id = two.parentid
LEFT JOIN teachplan_media tm on two.id = tm.teachplan_id
WHERE one.parentid = 0
AND one.course_id = #{courseId}
</select>

</mapper>

定义Service

找到TeachPlanService接口,定义计划查询接口

TeachPlanService
/**
* <p>
* 课程计划 服务类
* </p>
*
* @author sw-code
* @since 2023-08-18
*/
public interface TeachPlanService extends IService<TeachPlan> {

/**
* 查询课程计划树形结构
*
* @param courseId 课程Id
* @return 课程计划树形结构
*/
public List<TeachPlanVO> getTreeNodes(Long courseId);

}

实现该方法,找到其实现类TeachPlanServiceImpl

TeachPlanServiceImpl
/**
* <p>
* 课程计划 服务实现类
* </p>
*
* @author sw-code
* @since 2023-08-18
*/
@Service
public class TeachPlanServiceImpl extends ServiceImpl<TeachPlanMapper, TeachPlan> implements TeachPlanService {

/**
* 查询课程计划树形结构
*
* @param courseId 课程Id
* @return 课程计划树形结构
*/
@Override
public List<TeachPlanVO> getTreeNodes(Long courseId) {
return baseMapper.getTreeNodes(courseId);
}
}

定义Controller

TeachPlanController
/**
* <p>
* 课程计划信息 前端控制器
* </p>
*
* @author sw-code
* @since 2023-08-20
*/
@Api(value = "课程计划信息编辑接口", tags = "课程计划信息编辑接口")
@RestController
@ResponseResult
@RequestMapping("/teachplan")
public class TeachPlanController {

private final TeachPlanService teachPlanService;

public TeachPlanController(TeachPlanService teachPlanService) {
this.teachPlanService = teachPlanService;
}

@ApiOperation("查询课程计划树形结构")
@GetMapping("/{courseId}/tree-nodes")
public List<TeachPlanVO> getTreeNodes(@PathVariable("courseId") Long courseId) {
return teachPlanService.getTreeNodes(courseId);
}
}

课程查询信息服务以提供,打开前端项目查看是否成功

Push到Git

commit "完成课程计划查询功能"

绑定媒资文件

该部分需要实现媒资管理服务,请先转到媒资管理工程,完成该部分开发。

接口信息如下

路径地址 http://localhost:63040/content/teachplan/association/media
请求方式 POST
请求参数 BindTeachPlanMediaDTO
返回结果 TeachPlanMedia

定义TeachPlanDTO

其中teachPlanMedia是关联媒体文件,只有根节点才有该属性。

BindTeachPlanMediaDTO
@Data
public class BindTeachPlanMediaDTO implements Serializable {

private static final long serialVersionUID = 1L;

/**
* 媒资文件ID
*/
@NotBlank(message = "媒资文件不能为空")
private String mediaId;

/**
* 媒资文件名称
*/
private String fileName;

/**
* 课程计划标识
*/
@NotNull(message = "课程计划信息不能为空")
private Long teachplanId;
}

定义Service

找到TeachPlanService接口,定义计划查询接口

TeachPlanService
/**
* 课程计划和媒资信息绑定
*
* @param dto 绑定信息
*/
public TeachPlanMedia associationMedia(BindTeachPlanMediaDTO dto);

实现该方法,找到其实现类TeachPlanServiceImpl

TeachPlanServiceImpl
/**
* 课程计划和媒资信息绑定
*
* @param dto 绑定信息
*/
@Override
@Transactional(rollbackFor = Exception.class)
public TeachPlanMedia associationMedia(BindTeachPlanMediaDTO dto) {
TeachPlan dbTeachPlan = Optional.ofNullable(getById(dto.getTeachplanId())).orElseThrow(() -> new BizException(ResultCodeEnum.DATA_NOT_EXIST));
if (dbTeachPlan.getGrade() != 2) {
throw new BizException("只允许第二级教学计划绑定媒资文件");
}
// 删除原有记录,根据课程计划ID删除其绑定的媒资
teachPlanMediaService.remove(Wrappers.<TeachPlanMedia>lambdaQuery().eq(TeachPlanMedia::getTeachplanId, dto.getTeachplanId()));
// 新增记录
TeachPlanMedia teachPlanMedia = new TeachPlanMedia();
teachPlanMedia.setMediaId(dto.getMediaId());
teachPlanMedia.setMediaFilename(dto.getFileName());
teachPlanMedia.setTeachplanId(dto.getTeachplanId());
teachPlanMedia.setCreateDate(LocalDateTime.now());
teachPlanMedia.setCourseId(dbTeachPlan.getCourseId());
teachPlanMediaService.save(teachPlanMedia);
return teachPlanMedia;
}

定义Controller

TeachPlanController
@ApiOperation("课程计划和媒资信息绑定")
@PostMapping("/association/media")
public TeachPlanMedia associateMedia(@RequestBody @Validated BindTeachPlanMediaDTO dto) {
return teachPlanService.associationMedia(dto);
}

课程计划绑定媒资信息服务以提供,打开前端项目查看是否成功

Push到Git

commit "完成媒资信息绑定服务"