瀏覽代碼

Merge branch 'muzi'

liyanbo 1 月之前
父節點
當前提交
47cc632149
共有 3 個文件被更改,包括 57 次插入60 次删除
  1. 2 2
      .env
  2. 32 21
      src/components/ai/voice/VoiceInput.vue
  3. 23 37
      src/components/study/SelfDirectedLearning.vue

+ 2 - 2
.env

@@ -3,8 +3,8 @@ VITE_APP_TITLE=人工智能通识课平台
 
 # 请求路径
 # VITE_BASE_URL='http://59.110.91.129:8088/admin-api'
- VITE_BASE_URL='https://learn-ai.com.cn/admin-api'
-#VITE_BASE_URL='http://192.168.110.8:8080/admin-api'
+# VITE_BASE_URL='https://learn-ai.com.cn/admin-api'
+VITE_BASE_URL='http://192.168.110.8:8080/admin-api'
 
 # 默认账户密码
 VITE_APP_DEFAULT_LOGIN_TENANT=

+ 32 - 21
src/components/ai/voice/VoiceInput.vue

@@ -1,9 +1,9 @@
 <template>
   <div class="voice-input-container">
     <button
-      @click="toggleSpeechInput"
-      class="speech-btn"
-      :class="{ 'recording': isRecording }"
+        @click="toggleSpeechInput"
+        class="speech-btn"
+        :class="{ 'recording': isRecording }"
     >
       <el-icon v-if="!isRecording"><Microphone /></el-icon>
       <el-icon v-else><Mute /></el-icon>
@@ -11,13 +11,13 @@
       <span v-if="isRecording" class="countdown-text">{{ countdown }}s</span>
       <div class="waveform-container" v-if="isRecording">
         <LiveWaveform
-          :active="isRecording" 
-          :processing="false"
-          :height="25"
-          :barWidth="2"
-          :barGap="1"
-          :barRadius="1"
-          :sensitivity="1.2"
+            :active="isRecording"
+            :processing="false"
+            :height="25"
+            :barWidth="2"
+            :barGap="1"
+            :barRadius="1"
+            :sensitivity="1.2"
         />
       </div>
     </button>
@@ -71,7 +71,7 @@ const initSpeechRecognition = () => {
   if (!checkBrowserSupport()) {
     return null
   }
-  
+
   const SpeechRecognition = window.SpeechRecognition || window.webkitSpeechRecognition
 
   const instance = new SpeechRecognition()
@@ -90,6 +90,11 @@ const initSpeechRecognition = () => {
     }
   }
 
+  // 识别器真正开始监听时触发
+  instance.onstart = () => {
+    console.log('语音识别已开始监听')
+  }
+
   // 识别器结束时清除定时器
   instance.onend = () => {
     clearInterval(countdownTimer.value)
@@ -155,20 +160,26 @@ const toggleSpeechInput = () => {
     recognition.value = initSpeechRecognition()
     if (!recognition.value) return
 
+    // 重新绑定onstart事件,确保系统就绪后才开始计时
+    recognition.value.onstart = () => {
+      console.log('语音识别已开始监听')
+      // 系统真正就绪后才启动倒计时
+      countdownTimer.value = setInterval(() => {
+        countdown.value--
+        if (countdown.value <= 0) {
+          clearInterval(countdownTimer.value) // 倒计时结束清除
+          recognition.value.stop()
+        }
+      }, 1000)
+    }
+
     navigator.mediaDevices.getUserMedia({ audio: true })
         .then(() => {
-          recognition.value.start()
+          // 先设置UI状态,让用户知道系统正在准备
           isRecording.value = true
           emit('recordingStatusChanged', true)
-
-          // 启动新的倒计时定时器
-          countdownTimer.value = setInterval(() => {
-            countdown.value--
-            if (countdown.value <= 0) {
-              clearInterval(countdownTimer.value) // 倒计时结束清除
-              recognition.value.stop()
-            }
-          }, 1000)
+          // 启动语音识别
+          recognition.value.start()
         })
         .catch((err) => {
           console.error('麦克风权限获取失败:', err)

+ 23 - 37
src/components/study/SelfDirectedLearning.vue

@@ -253,57 +253,43 @@ const generateScript = async () => {
   try {
     isGenerating.value = true
 
-    const role = localScriptRoles.value.find((r) => r.name === selectedMainTeacher.value)
-
-    let content =
-        prompt.value +
-        '(主讲人:' + role.name +
-        ',主讲人角色定位:' + role.description +
-        ';助讲有:'
-    let zhujiang = []
-    selectedAssistants.value.forEach((rName) => {
-      const assistantRole = localScriptRoles.value.find((r) => r.name === rName)
-      zhujiang.push(assistantRole.name + '[' + assistantRole.description + ']')
-    })
-    content += zhujiang.join(',') + ');注意:给我的背景图提示词不允许出现主讲人和助讲人物形象。'
+    // 1. 生成课程
+    await createAiRoleIdConversation(100)
+    debugger
+    progressSteps.value[0].visible = true;
+    progressSteps.value[0].active = true;
+    let courseInfo = {}//存储课程信息
+    await doSendMessageStream(activeConversationId.value, prompt.value, courseInfo)
+    console.log("生成课程信息:", courseInfo)
+    scriptData.courseName = courseInfo.courseName
+    scriptData.coverImage = courseInfo.coverImage
+    progressSteps.value[0].completed = true;
+    progressSteps.value[0].active = false;
 
-    // 1. 创建对话
+    //2、生成课程小节
+    progressSteps.value[1].visible = true;
+    progressSteps.value[1].active = true;
     await createAiRoleIdConversation(13)
+    const role = localScriptRoles.value.find((r) => r.name === selectedMainTeacher.value)
+    const assistants = selectedAssistants.value.map(rName => {
+        const assistantRole = localScriptRoles.value.find(r => r.name === rName)
+        return `${assistantRole.name}[${assistantRole.description}]`
+      }).join(',')
+    let content = `${prompt.value}(主讲人:${role.name},主讲人角色定位:${role.description};助讲有:${assistants});`
+    content += `我需要让你生成${lessonList.value.length}节课程;${lessonList.value.map((lesson, index) => `第${index+1}节课程是${lesson.name};`).join('')}`
 
-    //2、生成课程信息
-    content += "注意:我需要让你生成"+lessonList.value.length+"节课程,";
-    for (let i = 1; i <= lessonList.value.length; i++) {
-      content+="第"+i+"节课程是"+lessonList.value[i-1].name+";"
-    }
-
-    //3、生成课程小节
-    progressSteps.value[0].visible = true;
-    progressSteps.value[0].active = true;
     let courseLessons = [];//存储课程小节信息
     scriptData.lessons = []
     for (let i = 0; i < lessonList.value.length; i++) {
       let lesson = lessonList.value[i]
-      progressSteps.value[0].next = "生成课程小节【" + lesson.name + "】..."
-
+      progressSteps.value[1].text = "生成课程小节【" + lesson.name + "】..."
       content = i === 0 ? content + `现在开始生成第${i+1}节课:${lesson.name}` : content
-
       let lessonInfo = {courseName: lesson.name, courseLabel: lesson.id};
       await doSendMessageStream(activeConversationId.value, content, lessonInfo)
       console.log("生成课程小节信息:", lessonInfo)
       courseLessons.push(lessonInfo)
     }
     scriptData.lessons = courseLessons;
-    progressSteps.value[0].completed = true;
-    progressSteps.value[0].active = false;
-
-    content = "最后请给我围绕着这几节课的课程封面图描述词(coverImage)和课程名称(courseName),课程名字不能超过10个字。"
-    progressSteps.value[1].visible = true;
-    progressSteps.value[1].active = true;
-    let courseInfo = {}//存储课程信息
-    await doSendMessageStream(activeConversationId.value, content, courseInfo)
-    console.log("生成课程信息:", courseInfo)
-    scriptData.courseName = courseInfo.courseName
-    scriptData.coverImage = courseInfo.coverImage
     progressSteps.value[1].completed = true;
     progressSteps.value[1].active = false;