丸子 пре 1 месец
родитељ
комит
137a453dfc
2 измењених фајлова са 130 додато и 41 уклоњено
  1. 23 8
      src/views/AIPage/AIDevelop.vue
  2. 107 33
      src/views/AIPage/aiGenerate/DialogContent.vue

+ 23 - 8
src/views/AIPage/AIDevelop.vue

@@ -992,14 +992,29 @@ $text-color: #483d8b; // 文本颜色:靛蓝色
   cursor: pointer; // 添加鼠标指针样式
 }
 .box-icon {
-  width: 100%;
-  height: 100%;
-  flex: 1;
-  display: flex; // 添加 flex 布局
-  align-items: center; // 垂直居中
-  color: white; // 设置图标颜色为白色
-  padding-left: rpx(15);
-  font-size: rpx(10); // 设置图标大小,可按需调整
+  display: flex;
+  align-items: center;
+  gap: rpx(5);
+  padding: rpx(5) rpx(10);
+  background-color: rgba(255, 255, 255, 80%);
+  border-radius: rpx(30);
+  backdrop-filter: blur(10px);
+  cursor: pointer;
+  transition: all 0.3s ease;
+  font-size: rpx(8);
+  color: #333;
+  font-weight: 900;
+  width: fit-content;
+  margin-left: rpx(15);
+}
+
+.box-icon:hover {
+  background-color: rgba(255, 255, 255, 90%);
+  transform: translateX(-3px);
+}
+
+.left-icon {
+  font-size: rpx(10);
 }
 // .box-icon .left-icon {
 //   margin-left: rpx(10);

+ 107 - 33
src/views/AIPage/aiGenerate/DialogContent.vue

@@ -1,13 +1,21 @@
 <template>
   <div class="dialog-content-wrapper">
+    <!-- 遮罩层 -->
+    <div v-if="showMask" class="mask-layer" ref="maskLayer">
+      <div class="play-button-container">
+        <button class="play-button" @click="startPlayback">
+          <el-icon class="play-icon"><VideoPlay /></el-icon>
+        </button>
+      </div>
+    </div>
     <!-- 标题 -->
     <div class="title-box">
       <!-- 返回 -->
       <div class="title-left">
-        <div class="back-icon-circle" @click="goBackToMain">
-          <el-icon class="back-icon"><ArrowLeftBold /></el-icon>
+        <div class="box-icon" @click="goBackToMain">
+          <el-icon class="left-icon"><ArrowLeftBold /></el-icon>
+          {{ backText }}
         </div>
-        <span class="back-text" @click="goBackToMain">{{ backText }}</span>
       </div>
       <!-- 标题 -->
       <div class="title-center">
@@ -99,7 +107,7 @@
 <script setup>
 import { ref, computed, onMounted, onUnmounted, watch } from 'vue'
 import { useRouter } from 'vue-router'
-import { ArrowLeftBold, CaretLeft, CaretRight, Grid } from '@element-plus/icons-vue'
+import { ArrowLeftBold, CaretLeft, CaretRight, Grid, VideoPlay } from '@element-plus/icons-vue'
 import VoiceInput from '@/components/ai/voice/VoiceInput.vue'
 import { marked } from 'marked'
 import {CreateDialogue, sendChatMessageStream} from "@/api/questions.js";
@@ -151,6 +159,8 @@ const recordingStartText = ref("")
 const backgroundAudio = ref(null)
 // 对话音频
 const dialogueAudio = ref(null)
+// 遮罩层显示状态
+const showMask = ref(true)
 
 // 计算属性
 // 当前章节信息
@@ -451,6 +461,21 @@ const goBackToMain = () => {
   router.push('/ai-general-course')
 }
 
+// 开始播放
+const maskLayer = ref(null)
+const startPlayback = () => {
+  // 消失动画
+  if (maskLayer.value) {
+    maskLayer.value.classList.add('fade-out')
+    // 等待动画完成后隐藏遮罩层
+    setTimeout(() => {
+      showMask.value = false
+    }, 500)
+  }
+  // 播放当前对话语音
+  playDialogueAudio()
+}
+
 // 键盘事件处理,键盘左右箭头控制对话
 const handleKeydown = (event) => {
   // 如果当前是用户输入对话,不处理键盘事件,让默认行为生效(在输入框中左右移动光标)
@@ -470,12 +495,12 @@ watch(currentSectionIndex, () => {
   playBackgroundAudio()
 })
 
-// 监听对话变化
-watch(currentDialogue, () => {
-  if (!isPlaying.value) {
-    playDialogueAudio()
-  }
-})
+// // 监听对话变化
+// watch(currentDialogue, () => {
+//   if (!isPlaying.value) {
+//     playDialogueAudio()
+//   }
+// })
 
 // 会话ID
 const activeConversationId = ref(null)
@@ -657,8 +682,8 @@ onMounted(() => {
   window.addEventListener('keydown', handleKeydown)
   // 播放背景音
   playBackgroundAudio()
-  // 播放当前对话语音
-  playDialogueAudio()
+  // // 播放当前对话语音
+  // playDialogueAudio()
   // 设置音频播放完成回调
   setOnPlaybackComplete(handleAudioPlaybackComplete)
 })
@@ -706,37 +731,31 @@ onUnmounted(() => {
   height: 100%;
   display: flex;
   align-items: center;
-  justify-content: flex-start;
   gap: rpx(5);
-  .back-icon-circle {
-    width: rpx(20);
-    height: rpx(20);
-    border-radius: 50%;
-    border: rpx(1) solid rgba(0, 100, 192);
-    background: linear-gradient(135deg, #A0DCF0, #50BEF0);
+  .box-icon {
     display: flex;
     align-items: center;
-    justify-content: center;
+    color: #0064BE;
+    gap: rpx(5);
+    padding: rpx(5) rpx(10);
+    background: linear-gradient(135deg, #A0DCF0, #50BEF0);
+    border: rpx(1) solid rgba(0, 100, 192);
+    border-radius: rpx(30);
+    backdrop-filter: blur(10px);
     cursor: pointer;
     transition: all 0.3s ease;
+    font-size: rpx(9);
+    font-weight: 500;
+    width: fit-content;
   }
   
-  .back-icon-circle:hover {
-    transform: scale(1.1);
-    box-shadow: 0 rpx(1) rpx(6) rgba(0, 0, 0, 0.3);
+  .box-icon:hover {
+    background-color: rgba(255, 255, 255, 90%);
+    transform: translateX(-3px);
   }
   
-  .back-icon-circle:active {
-    transform: scale(0.95);
-  }
-  .back-icon {
-    font-size: rpx(13);
-    color: #0064BE;
-  }
-  .back-text {
+  .left-icon {
     font-size: rpx(12);
-    color: #0064BE;
-    cursor: pointer;
   }
 }
 
@@ -806,6 +825,61 @@ onUnmounted(() => {
   position: relative;
 }
 
+/* 遮罩层样式 */
+.mask-layer {
+  position: absolute;
+  top: 0;
+  left: 0;
+  right: 0;
+  bottom: 0;
+  background-color: rgba(0, 0, 0, 0.7);
+  z-index: 20;
+  display: flex;
+  justify-content: center;
+  align-items: center;
+  opacity: 1;
+  transition: all 0.5s ease-out;
+}
+
+.mask-layer.fade-out {
+  opacity: 0;
+  transform: scale(1.1);
+  z-index: -1;
+}
+
+.play-button-container {
+  display: flex;
+  justify-content: center;
+  align-items: center;
+}
+
+.play-button {
+  width: rpx(80);
+  height: rpx(80);
+  border-radius: 50%;
+  border: none;
+  background: transparent;
+  display: flex;
+  justify-content: center;
+  align-items: center;
+  cursor: pointer;
+  outline: none;
+  -webkit-tap-highlight-color: transparent;
+}
+
+.play-icon {
+  font-size: rpx(40);
+  color: #A0DCF0;
+  transition: all 0.3s ease;
+  cursor: pointer;
+}
+
+.play-icon:hover {
+  transform: scale(1.2);
+  color: #50BEF0;
+  text-shadow: 0 0 rpx(10) rgba(64, 158, 255, 0.5);
+}
+
 .content-box {
   position: absolute;
   top: rpx(60);