|
@@ -2,6 +2,7 @@ package cn.iocoder.byzs.module.web.controller.admin.ai;
|
|
|
|
|
|
|
|
import cn.hutool.core.util.ObjUtil;
|
|
import cn.hutool.core.util.ObjUtil;
|
|
|
import cn.iocoder.byzs.framework.common.enums.CommonStatusEnum;
|
|
import cn.iocoder.byzs.framework.common.enums.CommonStatusEnum;
|
|
|
|
|
+import cn.iocoder.byzs.framework.common.exception.enums.GlobalErrorCodeConstants;
|
|
|
import cn.iocoder.byzs.framework.common.pojo.CommonResult;
|
|
import cn.iocoder.byzs.framework.common.pojo.CommonResult;
|
|
|
import cn.iocoder.byzs.framework.common.pojo.PageParam;
|
|
import cn.iocoder.byzs.framework.common.pojo.PageParam;
|
|
|
import cn.iocoder.byzs.framework.common.pojo.PageResult;
|
|
import cn.iocoder.byzs.framework.common.pojo.PageResult;
|
|
@@ -41,6 +42,7 @@ 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.controller.admin.ai.vo.WebAiChatRoleVO;
|
|
|
import cn.iocoder.byzs.module.web.service.ai.WebAiServiceImpl;
|
|
import cn.iocoder.byzs.module.web.service.ai.WebAiServiceImpl;
|
|
|
import com.volcengine.ark.runtime.model.responses.constant.ResponsesConstants;
|
|
import com.volcengine.ark.runtime.model.responses.constant.ResponsesConstants;
|
|
|
|
|
+import com.volcengine.ark.runtime.model.responses.content.InputContentItemAudio;
|
|
|
import com.volcengine.ark.runtime.model.responses.content.InputContentItemImage;
|
|
import com.volcengine.ark.runtime.model.responses.content.InputContentItemImage;
|
|
|
import com.volcengine.ark.runtime.model.responses.content.InputContentItemText;
|
|
import com.volcengine.ark.runtime.model.responses.content.InputContentItemText;
|
|
|
import com.volcengine.ark.runtime.model.responses.content.OutputContentItemText;
|
|
import com.volcengine.ark.runtime.model.responses.content.OutputContentItemText;
|
|
@@ -60,10 +62,16 @@ import jakarta.annotation.security.PermitAll;
|
|
|
import jakarta.validation.Valid;
|
|
import jakarta.validation.Valid;
|
|
|
import jodd.util.StringUtil;
|
|
import jodd.util.StringUtil;
|
|
|
import org.springframework.http.MediaType;
|
|
import org.springframework.http.MediaType;
|
|
|
|
|
+import reactor.core.publisher.Flux;
|
|
|
|
|
+
|
|
|
|
|
+import java.net.URL;
|
|
|
|
|
+import java.net.URLEncoder;
|
|
|
|
|
+import java.nio.charset.StandardCharsets;
|
|
|
|
|
+import java.util.Base64;
|
|
|
|
|
+import java.util.concurrent.TimeUnit;
|
|
|
import org.springframework.security.access.prepost.PreAuthorize;
|
|
import org.springframework.security.access.prepost.PreAuthorize;
|
|
|
import org.springframework.validation.annotation.Validated;
|
|
import org.springframework.validation.annotation.Validated;
|
|
|
import org.springframework.web.bind.annotation.*;
|
|
import org.springframework.web.bind.annotation.*;
|
|
|
-import reactor.core.publisher.Flux;
|
|
|
|
|
|
|
|
|
|
import java.util.List;
|
|
import java.util.List;
|
|
|
import java.util.Optional;
|
|
import java.util.Optional;
|
|
@@ -224,6 +232,9 @@ public class WebAiController {
|
|
|
ArkService arkService = ArkService.builder().apiKey(apiKey).baseUrl("https://ark.cn-beijing.volces.com/api/v3").build();
|
|
ArkService arkService = ArkService.builder().apiKey(apiKey).baseUrl("https://ark.cn-beijing.volces.com/api/v3").build();
|
|
|
|
|
|
|
|
List<String> promptImages = visionThinkReqVO.getPromptImage();
|
|
List<String> promptImages = visionThinkReqVO.getPromptImage();
|
|
|
|
|
+ if (promptImages == null || promptImages.isEmpty()) {
|
|
|
|
|
+
|
|
|
|
|
+ }
|
|
|
String prompt = visionThinkReqVO.getPrompt();
|
|
String prompt = visionThinkReqVO.getPrompt();
|
|
|
|
|
|
|
|
// 构建消息内容
|
|
// 构建消息内容
|
|
@@ -297,6 +308,61 @@ public class WebAiController {
|
|
|
return "";
|
|
return "";
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ // ================ 朗读评价 ================
|
|
|
|
|
+
|
|
|
|
|
+ @Operation(summary = "朗读评价", description = "前端直接传入Base64音频数据,后端直接调用AI模型评价")
|
|
|
|
|
+ @PostMapping("/reading-evaluate")
|
|
|
|
|
+ public CommonResult<AiVisionThinkRespVO> evaluateReading(@Valid @RequestBody AiVisionThinkReqVO visionThinkReqVO) {
|
|
|
|
|
+ String apiKey = "4bb6060f-b4a1-4e0a-bf7b-71dcaa6311cb";
|
|
|
|
|
+ ArkService arkService = ArkService.builder().apiKey(apiKey).baseUrl("https://ark.cn-beijing.volces.com/api/v3").build();
|
|
|
|
|
+
|
|
|
|
|
+ try {
|
|
|
|
|
+ // 前端已完成录音并转Base64,直接获取音频数据
|
|
|
|
|
+ String base64Audio = visionThinkReqVO.getAudioUrl();
|
|
|
|
|
+
|
|
|
|
|
+ // 调用AI模型进行评价
|
|
|
|
|
+ CreateResponsesRequest request = CreateResponsesRequest.builder()
|
|
|
|
|
+ .model("doubao-seed-2-0-lite-260428")
|
|
|
|
|
+ .input(ResponsesInput.builder()
|
|
|
|
|
+ .addListItem(ItemEasyMessage.builder()
|
|
|
|
|
+ .role(ResponsesConstants.MESSAGE_ROLE_SYSTEM)
|
|
|
|
|
+ .content(MessageContent.builder()
|
|
|
|
|
+ .addListItem(InputContentItemText.builder()
|
|
|
|
|
+ .text("你是小学老师,接下来你要评价学生朗读诗词语句并打分,请用小学生的年级水平来评价,回复字数尽量控制在20字以内")
|
|
|
|
|
+ .build())
|
|
|
|
|
+ .build())
|
|
|
|
|
+ .build())
|
|
|
|
|
+ .addListItem(ItemEasyMessage.builder()
|
|
|
|
|
+ .role(ResponsesConstants.MESSAGE_ROLE_USER)
|
|
|
|
|
+ .content(MessageContent.builder()
|
|
|
|
|
+ .addListItem(InputContentItemAudio.builder().audioUrl(base64Audio).build())
|
|
|
|
|
+ .addListItem(InputContentItemText.builder().text("请评价这段朗读").build())
|
|
|
|
|
+ .build())
|
|
|
|
|
+ .build())
|
|
|
|
|
+ .build())
|
|
|
|
|
+ .build();
|
|
|
|
|
+
|
|
|
|
|
+ ResponseObject resp = arkService.createResponse(request);
|
|
|
|
|
+ String text = extractTextFromResponse(resp);
|
|
|
|
|
+
|
|
|
|
|
+ AiVisionThinkRespVO response = new AiVisionThinkRespVO();
|
|
|
|
|
+ response.setResult(text);
|
|
|
|
|
+
|
|
|
|
|
+ // 调用 TTS 服务将评价结果转换为语音
|
|
|
|
|
+ Long roleId = visionThinkReqVO.getRoleId();
|
|
|
|
|
+ if (roleId != null) {
|
|
|
|
|
+ String ttsAudioData = webAiService.convertTextToSpeechBase64(roleId, text, null);
|
|
|
|
|
+ response.setAudioData(ttsAudioData);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ return success(response);
|
|
|
|
|
+ } catch (Exception e) {
|
|
|
|
|
+ return CommonResult.error(GlobalErrorCodeConstants.INTERNAL_SERVER_ERROR.getCode(), "音频处理失败: " + e.getMessage());
|
|
|
|
|
+ } finally {
|
|
|
|
|
+ arkService.shutdownExecutor();
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
// ================ 虚拟实验室 ================
|
|
// ================ 虚拟实验室 ================
|
|
|
|
|
|
|
|
@GetMapping("/selectVirtualDevice")
|
|
@GetMapping("/selectVirtualDevice")
|