课程强制发布

This commit is contained in:
2026-01-14 11:25:51 +08:00
parent d18a09e639
commit 109f552613
11 changed files with 327 additions and 8 deletions

View File

@@ -166,4 +166,12 @@ public class CourseController {
return courseService.incrementLearnCount(courseID);
}
/**
* 强制发布课程(跳过敏感词校验)
*/
@PostMapping("/{courseID}/force-publish")
public ResultDomain<TbCourse> forcePublishCourse(@PathVariable("courseID") String courseID) {
return courseService.forcePublishCourse(courseID);
}
}

View File

@@ -154,6 +154,72 @@ public class SCCourseServiceImpl implements SCCourseService {
return resultDomain;
}
// 验证课程基本信息
if (courseItemVO.getName() == null || courseItemVO.getName().trim().isEmpty()) {
resultDomain.fail("课程名称不能为空");
return resultDomain;
}
// 验证章节
List<CourseItemVO> chapterVOs = courseItemVO.getChapters();
if (chapterVOs == null || chapterVOs.isEmpty()) {
resultDomain.fail("课程至少需要一个章节");
return resultDomain;
}
// 验证每个章节
for (int i = 0; i < chapterVOs.size(); i++) {
CourseItemVO chapterVO = chapterVOs.get(i);
if (chapterVO.getName() == null || chapterVO.getName().trim().isEmpty()) {
resultDomain.fail("" + (i + 1) + "个章节名称不能为空");
return resultDomain;
}
// 验证章节节点
List<CourseItemVO> nodeVOs = chapterVO.getChapters();
if (nodeVOs == null || nodeVOs.isEmpty()) {
resultDomain.fail("章节「" + chapterVO.getName() + "」至少需要一个学习节点");
return resultDomain;
}
// 验证每个节点
for (int j = 0; j < nodeVOs.size(); j++) {
CourseItemVO nodeVO = nodeVOs.get(j);
if (nodeVO.getName() == null || nodeVO.getName().trim().isEmpty()) {
resultDomain.fail("章节「" + chapterVO.getName() + "」的第" + (j + 1) + "个节点名称不能为空");
return resultDomain;
}
// 根据节点类型验证内容
Integer nodeType = nodeVO.getNodeType();
if (nodeType == null) {
resultDomain.fail("章节「" + chapterVO.getName() + "」的节点「" + nodeVO.getName() + "」类型不能为空");
return resultDomain;
}
// 类型1文章需要resourceID
// 类型2文件/视频需要resourceID或videoUrl
// 类型3文本需要content
if (nodeType == 1) {
if (nodeVO.getResourceID() == null || nodeVO.getResourceID().trim().isEmpty()) {
resultDomain.fail("章节「" + chapterVO.getName() + "」的节点「" + nodeVO.getName() + "」需要关联文章");
return resultDomain;
}
} else if (nodeType == 2) {
if ((nodeVO.getResourceID() == null || nodeVO.getResourceID().trim().isEmpty())
&& (nodeVO.getVideoUrl() == null || nodeVO.getVideoUrl().trim().isEmpty())) {
resultDomain.fail("章节「" + chapterVO.getName() + "」的节点「" + nodeVO.getName() + "」需要上传文件或视频");
return resultDomain;
}
} else if (nodeType == 3) {
if (nodeVO.getContent() == null || nodeVO.getContent().trim().isEmpty()) {
resultDomain.fail("章节「" + chapterVO.getName() + "」的节点「" + nodeVO.getName() + "」内容不能为空");
return resultDomain;
}
}
}
}
// 转换为课程实体并保存
TbCourse course = courseItemVO.toCourse();
String courseID = IDUtils.generateID();
@@ -763,4 +829,72 @@ public class SCCourseServiceImpl implements SCCourseService {
}
return resultDomain;
}
@Override
@Transactional(rollbackFor = Exception.class)
public ResultDomain<TbCourse> forcePublishCourse(String courseID) {
ResultDomain<TbCourse> resultDomain = new ResultDomain<>();
try {
// 参数验证
if (courseID == null || courseID.isEmpty()) {
resultDomain.fail("课程ID不能为空");
return resultDomain;
}
// 查询课程
TbCourse course = courseMapper.selectByCourseId(courseID);
if (course == null) {
resultDomain.fail("课程不存在");
return resultDomain;
}
// 获取所有课程节点,强制设置为已审核
List<TbCourseNode> nodeList = courseNodeMapper.selectByCourseId(courseID);
if (nodeList != null && !nodeList.isEmpty()) {
List<TbCourseNode> nodesToUpdate = new ArrayList<>();
for (TbCourseNode node : nodeList) {
if (!node.getIsAudited()) {
node.setIsAudited(true);
nodesToUpdate.add(node);
// 如果是文章类型节点,同时更新文章的审核状态
if (node.getNodeType() == 1 && node.getResourceID() != null) {
try {
ResourceVO resource = new ResourceVO();
resource.setResource(new TbResource());
resource.getResource().setResourceID(node.getResourceID());
resource.getResource().setIsAudited(true);
resourceService.updateResource(resource);
} catch (Exception e) {
logger.warn("更新节点关联文章审核状态失败: {}", e.getMessage());
}
}
}
}
// 批量更新节点审核状态
if (!nodesToUpdate.isEmpty()) {
courseNodeMapper.batchUpdateNodeAudited(nodesToUpdate);
}
}
// 强制发布:跳过敏感词校验,直接设置为已发布
course.setStatus(1);
course.setUpdateTime(new Date());
int result = courseMapper.updateCourse(course);
if (result > 0) {
logger.info("强制发布课程成功: {}", courseID);
// 重新查询返回完整数据
TbCourse updated = courseMapper.selectByCourseId(courseID);
resultDomain.success("强制发布课程成功", updated);
} else {
resultDomain.fail("强制发布课程失败");
}
} catch (Exception e) {
logger.error("强制发布课程异常: {}", e.getMessage(), e);
resultDomain.fail("强制发布课程失败: " + e.getMessage());
}
return resultDomain;
}
}

View File

@@ -241,8 +241,8 @@
<!-- batchUpdateNodeAudited -->
<update id="batchUpdateNodeAudited">
<foreach collection="courseNodeList" item="item" separator=";">
UPDATE tb_course_node
SET is_audited = #{item.isAudited}
UPDATE tb_course_node
SET is_audited = #{item.isAudited}
WHERE node_id = #{item.nodeID}
</foreach>
</update>