ソースを参照

学生端新增文字转语音、新增课程接口
移除课程类型名称重复校验

liyanbo 1 ヶ月 前
コミット
88e48d9143

+ 2 - 0
byzs-course/src/main/java/cn/iocoder/byzs/module/bjdx/controller/admin/coursetype/vo/CourseTypeListReqVO.java

@@ -25,4 +25,6 @@ public class CourseTypeListReqVO {
     @Schema(description = "课程类型描述")
     private String ctTypeDescribe;
 
+    private Long creator;
+
 }

+ 3 - 3
byzs-course/src/main/java/cn/iocoder/byzs/module/bjdx/service/coursetype/CourseTypeServiceImpl.java

@@ -45,8 +45,8 @@ public class CourseTypeServiceImpl implements CourseTypeService {
     public Long createCourseType(CourseTypeSaveReqVO createReqVO) {
         // 校验课程类型父级id的有效性
         validateParentCourseType(null, createReqVO.getCtParentId());
-        // 校验课程类型名称的唯一性
-        validateCourseTypeCtTypeUnique(null, createReqVO.getCtParentId(), createReqVO.getCtType());
+//        // 校验课程类型名称的唯一性
+//        validateCourseTypeCtTypeUnique(null, createReqVO.getCtParentId(), createReqVO.getCtType());
 
         // 插入
         CourseTypeDO courseType = BeanUtils.toBean(createReqVO, CourseTypeDO.class);
@@ -82,7 +82,7 @@ public class CourseTypeServiceImpl implements CourseTypeService {
         // 校验课程类型父级id的有效性
         validateParentCourseType(updateReqVO.getId(), updateReqVO.getCtParentId());
         // 校验课程类型名称的唯一性
-        validateCourseTypeCtTypeUnique(updateReqVO.getId(), updateReqVO.getCtParentId(), updateReqVO.getCtType());
+//        validateCourseTypeCtTypeUnique(updateReqVO.getId(), updateReqVO.getCtParentId(), updateReqVO.getCtType());
 
         // 更新
         CourseTypeDO updateObj = BeanUtils.toBean(updateReqVO, CourseTypeDO.class);

+ 14 - 0
byzs-web/src/main/java/cn/iocoder/byzs/module/web/controller/admin/ai/WebAiController.java

@@ -33,9 +33,11 @@ import cn.iocoder.byzs.module.ai.service.image.AiImageService;
 import cn.iocoder.byzs.module.ai.service.mapgame.MapGameService;
 import cn.iocoder.byzs.module.ai.service.model.AiChatRoleService;
 import cn.iocoder.byzs.module.ai.service.model.AiModelService;
+import cn.iocoder.byzs.module.ai.service.tts.AiTtsService;
 import cn.iocoder.byzs.module.ai.service.video.AiVideoService;
 import cn.iocoder.byzs.module.ai.service.virtualdevice.VirtualDeviceService;
 import cn.iocoder.byzs.module.web.controller.admin.ai.vo.MapGameVO;
+import cn.iocoder.byzs.module.web.controller.admin.ai.vo.TtsVo;
 import cn.iocoder.byzs.module.web.controller.admin.ai.vo.WebAiChatRoleVO;
 import cn.iocoder.byzs.module.web.service.ai.WebAiServiceImpl;
 import com.volcengine.ark.runtime.model.responses.constant.ResponsesConstants;
@@ -58,6 +60,7 @@ import jakarta.annotation.security.PermitAll;
 import jakarta.validation.Valid;
 import jodd.util.StringUtil;
 import org.springframework.http.MediaType;
+import org.springframework.security.access.prepost.PreAuthorize;
 import org.springframework.validation.annotation.Validated;
 import org.springframework.web.bind.annotation.*;
 import reactor.core.publisher.Flux;
@@ -92,6 +95,8 @@ public class WebAiController {
     private VirtualDeviceService virtualDeviceService;
     @Resource
     private MapGameService mapGameService;
+    @Resource
+    private AiTtsService ttsService;
 
 
     // ================ 模型数据 ================
@@ -119,6 +124,15 @@ public class WebAiController {
         }
         return success(list.get(0).getId());
     }
+
+    @PostMapping("/textToSpeech")
+    @Operation(summary = "文本转语音")
+    public CommonResult<String> convertTextToSpeech(@RequestBody @Valid TtsVo ttsVo) {
+        // 执行文本转语音
+        String audioUrl = ttsService.convertTextToSpeech(ttsVo.getRoleId(), ttsVo.getContent());
+        // 返回结果
+        return success(audioUrl);
+    }
     
     // ================ 智能问答 ================
 

+ 17 - 0
byzs-web/src/main/java/cn/iocoder/byzs/module/web/controller/admin/ai/vo/TtsVo.java

@@ -0,0 +1,17 @@
+package cn.iocoder.byzs.module.web.controller.admin.ai.vo;
+
+import com.baomidou.mybatisplus.annotation.TableId;
+import lombok.Data;
+
+@Data
+public class TtsVo {
+
+    /**
+     * 角色id
+     */
+    private Long roleId;
+    /**
+     * 内容
+     */
+    private String content;
+}

+ 11 - 0
byzs-web/src/main/java/cn/iocoder/byzs/module/web/controller/admin/course/WebCourseController.java

@@ -7,6 +7,7 @@ import cn.iocoder.byzs.module.bjdx.controller.admin.coursetype.vo.CourseTypeList
 import cn.iocoder.byzs.module.bjdx.controller.admin.coursetype.vo.CourseTypeRespVO;
 import cn.iocoder.byzs.module.bjdx.dal.dataobject.coursetype.CourseTypeDO;
 import cn.iocoder.byzs.module.bjdx.service.coursetype.CourseTypeService;
+import cn.iocoder.byzs.module.web.controller.admin.course.vo.WebCourseAIGenerateVO;
 import cn.iocoder.byzs.module.web.controller.admin.course.vo.WebCourseVO;
 import cn.iocoder.byzs.module.web.service.course.WebCourseServiceImpl;
 import jakarta.annotation.security.PermitAll;
@@ -171,4 +172,14 @@ public class WebCourseController {
         private String type; // courseType 或 course
         private List<TreeNode> children = new ArrayList<>();
     }
+
+
+    /**
+     * AI生成课程
+     */
+    @PostMapping("/aIGenerateCourse")
+    @Operation(summary = "AI生成课程")
+    public CommonResult<Boolean> generateCourseByAI(@RequestBody WebCourseAIGenerateVO reqVO) {
+        return success(webCourseService.generateCourseByAI(reqVO));
+    }
 }

+ 34 - 0
byzs-web/src/main/java/cn/iocoder/byzs/module/web/controller/admin/course/vo/WebCourseAIGenerateVO.java

@@ -0,0 +1,34 @@
+package cn.iocoder.byzs.module.web.controller.admin.course.vo;
+
+import lombok.Data;
+
+import java.util.List;
+
+@Data
+public class WebCourseAIGenerateVO {
+
+    // 所属年级
+    private Integer grade;
+
+    // 课程名称
+    private String courseName;
+
+    // 课程封面
+    private String coverImage;
+
+    //课程小节
+    private List<CourseVO> courseList;
+
+    @Data
+    public static class CourseVO {
+
+        // 课程名称
+        private String courseName;
+
+        // 课程标签
+        private String courseLabel;
+
+        // 课程内容
+        private String courseContent;
+    }
+}

+ 65 - 0
byzs-web/src/main/java/cn/iocoder/byzs/module/web/service/course/WebCourseServiceImpl.java

@@ -5,13 +5,21 @@ import cn.iocoder.byzs.framework.common.enums.CommonStatusEnum;
 import cn.iocoder.byzs.framework.common.util.object.BeanUtils;
 import cn.iocoder.byzs.module.bjdx.controller.admin.course.vo.CoursePageReqVO;
 import cn.iocoder.byzs.module.bjdx.controller.admin.courseconfig.vo.CourseConfigRespVO;
+import cn.iocoder.byzs.module.bjdx.controller.admin.coursetype.vo.CourseTypeSaveReqVO;
 import cn.iocoder.byzs.module.bjdx.service.course.CourseService;
 import cn.iocoder.byzs.module.bjdx.service.courseconfig.CourseConfigService;
+import cn.iocoder.byzs.module.bjdx.service.coursetype.CourseTypeService;
+import cn.iocoder.byzs.module.web.controller.admin.course.vo.WebCourseAIGenerateVO;
 import cn.iocoder.byzs.module.web.controller.admin.course.vo.WebCourseVO;
 import cn.iocoder.byzs.module.web.dal.mysql.course.WebCourseMapper;
 import cn.iocoder.byzs.module.web.service.role.WebAuthRoleServiceImpl;
+import cn.iocoder.byzs.framework.security.core.util.SecurityFrameworkUtils;
+import cn.iocoder.byzs.module.bjdx.controller.admin.course.vo.CourseSaveReqVO;
+import cn.iocoder.byzs.module.bjdx.controller.admin.coursetype.vo.CourseTypeListReqVO;
+import cn.iocoder.byzs.module.bjdx.dal.dataobject.coursetype.CourseTypeDO;
 import jakarta.annotation.Resource;
 import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
 import org.springframework.validation.annotation.Validated;
 
 import java.util.*;
@@ -29,6 +37,8 @@ public class WebCourseServiceImpl{
     @Resource
     private CourseService courseService;
     @Resource
+    private CourseTypeService courseTypeService;
+    @Resource
     private CourseConfigService courseConfigService;
     @Resource
     private WebCourseMapper webCourseMapper;
@@ -79,4 +89,59 @@ public class WebCourseServiceImpl{
         return courseVoList;
     }
 
+     /**
+      * AI生成课程
+      */
+    @Transactional(rollbackFor = Exception.class)
+    public Boolean generateCourseByAI(WebCourseAIGenerateVO aiGenerateVO) {
+
+        // 1. 获取登录用户ID
+        Long loginUserId = SecurityFrameworkUtils.getLoginUserId();
+        if (loginUserId == null) {
+            return false;
+        }
+
+        // 2. 获取课程类型的最大排序数
+        CourseTypeListReqVO listReqVO = new CourseTypeListReqVO();
+        listReqVO.setCtParentId(aiGenerateVO.getGrade());
+        listReqVO.setCtTypeNode("4");
+        listReqVO.setCreator(loginUserId);
+        List<CourseTypeDO> courseTypeList = courseTypeService.getCourseTypeSimpleList(listReqVO);
+        int maxSort = 0;
+        if (courseTypeList != null && !courseTypeList.isEmpty()) {
+            maxSort = courseTypeList.stream()
+                    .map(CourseTypeDO::getCtTypeSort)
+                    .filter(Objects::nonNull)
+                    .max(Integer::compare)
+                    .orElse(0);
+        }
+
+        // 3. 创建课程类型
+        CourseTypeSaveReqVO courseTypeSaveReqVO = new CourseTypeSaveReqVO();
+        courseTypeSaveReqVO.setCtParentId(Long.valueOf(aiGenerateVO.getGrade()));
+        courseTypeSaveReqVO.setCtType(aiGenerateVO.getCourseName());
+        courseTypeSaveReqVO.setCtTypeImage(aiGenerateVO.getCoverImage());
+        courseTypeSaveReqVO.setCtTypeNode("4"); // 设置 ctTypeNode 类型为4
+        courseTypeSaveReqVO.setCtTypeSort(maxSort + 1); // 最大排序加1
+        Long courseTypeId = courseTypeService.createCourseType(courseTypeSaveReqVO);
+
+        // 4. 循环创建课程
+        if (aiGenerateVO.getCourseList() != null && !aiGenerateVO.getCourseList().isEmpty()) {
+            int courseOrder = 1; // 课程排序从1开始
+            for (WebCourseAIGenerateVO.CourseVO courseVO : aiGenerateVO.getCourseList()) {
+                CourseSaveReqVO courseSaveReqVO = new CourseSaveReqVO();
+                courseSaveReqVO.setCourseName(courseVO.getCourseName());
+                courseSaveReqVO.setCourseLabel(courseVO.getCourseLabel());
+                courseSaveReqVO.setCourseContentType("ailab");
+                courseSaveReqVO.setCourseContent(courseVO.getCourseContent());
+                courseSaveReqVO.setCourseType(courseTypeId); // 补充课程类型id
+                courseSaveReqVO.setCourseOrder(courseOrder++); // 排序从1开始递增
+                courseSaveReqVO.setCourseStatus("0"); // 设置课程状态为启用
+                courseService.createCourse(courseSaveReqVO);
+            }
+        }
+
+        return true;
+    }
+
 }