Browse Source

更新用户端诗词类型显示逻辑和初步样式

liyanbo 1 tháng trước cách đây
mục cha
commit
2242881b82
1 tập tin đã thay đổi với 217 bổ sung25 xóa
  1. 217 25
      src/views/AIPage/aiGenerate/DialogContent.vue

+ 217 - 25
src/views/AIPage/aiGenerate/DialogContent.vue

@@ -61,6 +61,13 @@
         <div class="dialogue-content" v-html="parseMarkdown(currentDialogue.content)"></div>
       </div>
 
+      <!-- 诗词显示区域 -->
+      <div v-if="showPoem" class="poem-display">
+        <div class="poem-content">
+          <div class="poem-text" v-html="parseMarkdown(currentPoemContent)"></div>
+        </div>
+      </div>
+
       <!-- 用户输入卡片 -->
       <div
         v-if="currentDialogue.type === 'user'"
@@ -160,6 +167,10 @@ const voiceRecognizedText = ref("")
 const recordingStartCursorPos = ref(0)
 // 录音开始时的原始文本
 const recordingStartText = ref("")
+// 诗词显示状态
+const showPoem = ref(false)
+// 当前诗词内容
+const currentPoemContent = ref('')
 
 // 音频对象
 // 背景音频
@@ -321,6 +332,11 @@ const playDialogueAudio = (isAutoPlay = false) => {
     dialogueAudio.value.currentTime = 0
   }
   
+  // 如果是诗词类型,不播放音频
+  if (currentDialogue.value?.type === 'poem') {
+    return
+  }
+  
   // 播放当前对话的语音
   if (currentDialogue.value?.voiceoverUrl) {
     const audio = new Audio(currentDialogue.value.voiceoverUrl)
@@ -343,16 +359,16 @@ const playDialogueAudio = (isAutoPlay = false) => {
     // 播放音频
     audio.play().catch(e => {
       console.error('对话语音播放失败:', e)
-      // 播放失败时,2秒后跳转(暂时注销,因为会导致user类型数字人回复播报跳转后语音播报报错,直接2秒跳转)
-      // if (isAutoPlay && isPlaying.value) {
-      //   setTimeout(() => {
-      //     if (!playNext(true)) {
-      //       // 播放完毕
-      //       isPlaying.value = false
-      //       stopAllAudio()
-      //     }
-      //   }, 2000)
-      // }
+      // 播放失败时,2秒后跳转
+      if (isAutoPlay && isPlaying.value) {
+        setTimeout(() => {
+          if (!playNext(true)) {
+            // 播放完毕
+            isPlaying.value = false
+            stopAllAudio()
+          }
+        }, 2000)
+      }
     })
   } else {
     // 如果没有语音文件,2秒后跳转
@@ -388,8 +404,23 @@ const playSequence = () => {
   // 如果当前是用户输入卡片,暂停播放等待用户输入
   if (currentDialogue.value?.type === 'user') return
 
-  // 播放当前对话语音,传递isAutoPlay参数
-  playDialogueAudio(true)
+  // 检查当前对话是否为诗词类型
+  if (currentDialogue.value?.type === 'poem') {
+    // 显示诗词并替换内容为最新的诗词
+    showPoem.value = true
+    currentPoemContent.value = currentDialogue.value.content
+    // 自动切换到下一条对话
+    setTimeout(() => {
+      if (!playNext(true)) {
+        // 播放完毕
+        isPlaying.value = false
+        stopAllAudio()
+      }
+    }, 500)
+  } else {
+    // 播放当前对话语音,传递isAutoPlay参数
+    playDialogueAudio(true)
+  }
 }
 
 const playPrevious = () => {
@@ -409,15 +440,28 @@ const playPrevious = () => {
     currentSectionIndex.value--
     const section = props.scriptData.sections[currentSectionIndex.value]
     currentDialogueIndex.value = section.dialogues.length - 1
+    // 切换环节时隐藏诗词
+    showPoem.value = false
+    currentPoemContent.value = ''
   }
 
+  // 检查当前对话是否为诗词类型
+  if (currentDialogue.value?.type === 'poem') {
+    // 显示诗词并替换内容为最新的诗词
+    showPoem.value = true
+    currentPoemContent.value = currentDialogue.value.content
+  }
+  // 如果不是诗词类型,保持诗词显示(不做任何操作)
+
   // 播放背景音
   playBackgroundAudio()
-  // 播放当前对话语音
-  if (isPlaying.value) {
-    playDialogueAudio(true)
-  } else {
-    playDialogueAudio()
+  // 播放当前对话语音(非诗词类型)
+  if (currentDialogue.value?.type !== 'poem') {
+    if (isPlaying.value) {
+      playDialogueAudio(true)
+    } else {
+      playDialogueAudio()
+    }
   }
 }
 
@@ -437,6 +481,19 @@ const playNext = (isAutoPlay = false) => {
 
   if (currentSection.value && currentDialogueIndex.value < currentSection.value.dialogues.length - 1) {
     currentDialogueIndex.value++
+    
+    // 检查当前对话是否为诗词类型
+    if (currentDialogue.value?.type === 'poem') {
+      // 显示诗词并替换内容为最新的诗词
+      showPoem.value = true
+      currentPoemContent.value = currentDialogue.value.content
+      // 自动切换到下一条对话,不需要播放音频
+      setTimeout(() => {
+        playNext(isAutoPlay)
+      }, 500)
+      return true
+    }
+    
     // 根据是否为自动播放状态决定如何播放语音
     if (isPlaying.value) {
       playDialogueAudio(true)
@@ -447,13 +504,27 @@ const playNext = (isAutoPlay = false) => {
   } else if (currentSectionIndex.value < props.scriptData.sections.length - 1) {
     currentSectionIndex.value++
     currentDialogueIndex.value = 0
+    // 切换环节时隐藏诗词
+    showPoem.value = false
+    currentPoemContent.value = ''
     // 播放背景音
     playBackgroundAudio()
-    // 根据是否为自动播放状态决定如何播放语音
-    if (isPlaying.value) {
-      playDialogueAudio(true)
+    // 检查新环节的第一个对话是否为诗词类型
+    if (currentDialogue.value?.type === 'poem') {
+      // 显示诗词
+      showPoem.value = true
+      currentPoemContent.value = currentDialogue.value.content
+      // 自动切换到下一条对话,不需要播放音频
+      setTimeout(() => {
+        playNext(isAutoPlay)
+      }, 500)
     } else {
-      playDialogueAudio()
+      // 根据是否为自动播放状态决定如何播放语音
+      if (isPlaying.value) {
+        playDialogueAudio(true)
+      } else {
+        playDialogueAudio()
+      }
     }
     return true
   }
@@ -479,8 +550,20 @@ const startPlayback = () => {
       showMask.value = false
     }, 500)
   }
-  // 播放当前对话语音
-  playDialogueAudio()
+  
+  // 检查当前对话是否为诗词类型
+  if (currentDialogue.value?.type === 'poem') {
+    // 显示诗词
+    showPoem.value = true
+    currentPoemContent.value = currentDialogue.value.content
+    // 自动切换到下一条对话
+    setTimeout(() => {
+      playNext()
+    }, 500)
+  } else {
+    // 播放当前对话语音
+    playDialogueAudio()
+  }
 }
 
 // 键盘事件处理,键盘左右箭头控制对话
@@ -538,6 +621,9 @@ watch(() => props.scriptData, (newVal, oldVal) => {
     userInput.value = ''
     // 清空对话缓存
     currentDialogueCache.value = null
+    // 隐藏诗词
+    showPoem.value = false
+    currentPoemContent.value = ''
   }
 }, { deep: true })
 
@@ -1524,8 +1610,114 @@ onUnmounted(() => {
   }
 
   .keyboard-icon {
-    font-size: rpx(14);
-    color: #0064BE;
+        font-size: rpx(14);
+        color: #0064BE;
+      }
+}
+
+/* 诗词显示样式 */
+.poem-display {
+  position: absolute;
+  top: 25%;
+  left: 50%;
+  transform: translate(-50%, -50%);
+  width: 100%;
+  max-width: rpx(600);
+  padding: rpx(20);
+  display: flex;
+  justify-content: center;
+  align-items: center;
+  z-index: 5;
+}
+
+.poem-content {
+  text-align: center;
+  animation: poemFadeIn 1s ease-in-out;
+  transition: all 0.5s ease-in-out;
+}
+
+.poem-text {
+  font-family: 'STKaiti', 'KaiTi', '楷体', 'Ma Shan Zheng', cursive;
+  font-size: rpx(30);
+  line-height: 1.5;
+  color: white;
+  text-shadow: 2px 2px 4px rgba(0, 0, 0, 0.5);
+  padding: rpx(20);
+  background-color: #ffffff1a;
+  border-radius: rpx(10);
+  position: relative;
+  overflow: hidden;
+  transition: all 0.5s ease-in-out;
+  white-space: nowrap;
+}
+
+.poem-text::before {
+  content: '';
+  position: absolute;
+  top: 0;
+  left: 0;
+  right: 0;
+  bottom: 0;
+  background: linear-gradient(45deg, rgba(255, 255, 255, 0.1) 0%, rgba(255, 255, 255, 0) 100%);
+  animation: poemShine 3s ease-in-out infinite;
+}
+
+@keyframes poemFadeIn {
+  from {
+    opacity: 0;
+    transform: scale(0.8) translateY(20px);
+  }
+  to {
+    opacity: 1;
+    transform: scale(1) translateY(0);
+  }
+}
+
+@keyframes poemShine {
+  0% {
+    transform: translateX(-100%) rotate(45deg);
+  }
+  100% {
+    transform: translateX(100%) rotate(45deg);
+  }
+}
+
+.poem-text p {
+  margin: rpx(10) 0;
+  opacity: 0;
+  animation: poemSlideIn 0.5s ease forwards;
+  font-weight: 500;
+  letter-spacing: rpx(2);
+}
+
+.poem-text p:nth-child(1) {
+  animation-delay: 0.2s;
+}
+
+.poem-text p:nth-child(2) {
+  animation-delay: 0.4s;
+}
+
+.poem-text p:nth-child(3) {
+  animation-delay: 0.6s;
+}
+
+.poem-text p:nth-child(4) {
+  animation-delay: 0.8s;
+}
+
+.poem-text p:nth-child(5) {
+  animation-delay: 1s;
+}
+
+@keyframes poemSlideIn {
+  from {
+    opacity: 0;
+    transform: translateY(10px);
+  }
+  to {
+    opacity: 1;
+    transform: translateY(0);
   }
 }
 </style>