From 43f95dc1acae0b23febd0d602fbccbf9762c30f3 Mon Sep 17 00:00:00 2001
From: Flex <q1406482700@163.com>
Date: 星期四, 05 六月 2025 15:48:54 +0800
Subject: [PATCH] 修改声音选择

---
 easegen-front/src/views/chooseTemplate/index.vue |  675 ++++++++++++++++++++++++++++++++++++++++++++++----------
 easegen-front/src/locales/zh-CN.ts               |    1 
 easegen-front/src/assets/imgs/sound.png          |    0 
 easegen-front/src/locales/courseCenter/en.ts     |    1 
 easegen-front/src/locales/courseCenter/zh.ts     |    1 
 easegen-front/src/locales/en.ts                  |    1 
 easegen-front/src/assets/imgs/sound-active.png   |    0 
 7 files changed, 558 insertions(+), 121 deletions(-)

diff --git a/easegen-front/src/assets/imgs/sound-active.png b/easegen-front/src/assets/imgs/sound-active.png
new file mode 100644
index 0000000..f5924ca
--- /dev/null
+++ b/easegen-front/src/assets/imgs/sound-active.png
Binary files differ
diff --git a/easegen-front/src/assets/imgs/sound.png b/easegen-front/src/assets/imgs/sound.png
new file mode 100644
index 0000000..88c2b09
--- /dev/null
+++ b/easegen-front/src/assets/imgs/sound.png
Binary files differ
diff --git a/easegen-front/src/locales/courseCenter/en.ts b/easegen-front/src/locales/courseCenter/en.ts
index 3250b21..a00142d 100644
--- a/easegen-front/src/locales/courseCenter/en.ts
+++ b/easegen-front/src/locales/courseCenter/en.ts
@@ -113,6 +113,7 @@
     soundDriven:'Sound driven',
     template:'template',
     digitalPeople:'Digital people',
+    sound:'Sound',
 
 
     myModel:'My Model',
diff --git a/easegen-front/src/locales/courseCenter/zh.ts b/easegen-front/src/locales/courseCenter/zh.ts
index 6c5137b..3b7a1b3 100644
--- a/easegen-front/src/locales/courseCenter/zh.ts
+++ b/easegen-front/src/locales/courseCenter/zh.ts
@@ -112,6 +112,7 @@
     soundDriven:'澹伴煶椹卞姩',
     template:'妯℃澘',
     digitalPeople:'鏁板瓧浜�',
+    sound:'澹伴煶',
 
     myModel:'鎴戠殑妯″瀷',
     name:'鍚嶇О',
diff --git a/easegen-front/src/locales/en.ts b/easegen-front/src/locales/en.ts
index 215800c..40b4a90 100644
--- a/easegen-front/src/locales/en.ts
+++ b/easegen-front/src/locales/en.ts
@@ -14,6 +14,7 @@
     loginOutMessage: 'Exit the system?',
     back: 'Back',
     ok: 'OK',
+    originalSound:"Original Sound",
     save: 'Save',
     cancel: 'Cancel',
     close: 'Close',
diff --git a/easegen-front/src/locales/zh-CN.ts b/easegen-front/src/locales/zh-CN.ts
index a50d370..32a3172 100644
--- a/easegen-front/src/locales/zh-CN.ts
+++ b/easegen-front/src/locales/zh-CN.ts
@@ -14,6 +14,7 @@
     loginOutMessage: '鏄惁閫�鍑烘湰绯荤粺锛�',
     back: '杩斿洖',
     ok: '纭畾',
+    originalSound:"鍘熷0",
     save: '淇濆瓨',
     cancel: '鍙栨秷',
     close: '鍏抽棴',
diff --git a/easegen-front/src/views/chooseTemplate/index.vue b/easegen-front/src/views/chooseTemplate/index.vue
index 624c7ce..95833b3 100644
--- a/easegen-front/src/views/chooseTemplate/index.vue
+++ b/easegen-front/src/views/chooseTemplate/index.vue
@@ -33,15 +33,15 @@
         <span v-if="saveTime">{{ saveTime }} {{ t('courseCenter.saved') }}</span>
         <el-button size="small" @click="saveSubmit('save')">{{ t('common.save') }}</el-button>
         <el-button type="primary" size="small" @click="saveSubmit('')">{{
-            t('courseCenter.composeViode')
-          }}</el-button>
+          t('courseCenter.composeViode')
+        }}</el-button>
       </div>
     </div>
     <div class="template-main">
       <div class="template-box template-left">
         <div class="page">
           <div
-          >{{ t('courseCenter.page') }}:({{ PPTArr ? PPTArr.length : 1 }}){{
+            >{{ t('courseCenter.page') }}:({{ PPTArr ? PPTArr.length : 1 }}){{
               t('courseCenter.pageTitle')
             }}</div
           >
@@ -174,18 +174,21 @@
           <div class="list">
             <div
               class="main-image-box"
-              :style="{ width: viewSize.width + 'px', height: viewSize.height + 'px',position: 'relative' }"
+              :style="{
+                width: viewSize.width + 'px',
+                height: viewSize.height + 'px',
+                position: 'relative'
+              }"
             >
-
               <!-- 鑳屾櫙(蹇呮樉绀�) -->
               <el-image
-                v-show="selectPPT.pictureUrl && selectPPT.digitalHuman.show==false"
+                v-show="selectPPT.pictureUrl && selectPPT.digitalHuman.show == false"
                 class="background1"
                 :src="selectPPT.pictureUrl"
                 style="z-index: 2"
               />
               <el-image
-                v-show="selectPPT.pictureUrl && selectPPT.digitalHuman.show==true"
+                v-show="selectPPT.pictureUrl && selectPPT.digitalHuman.show == true"
                 class="background1"
                 :src="selectPPT.pictureUrl"
                 style="z-index: 1"
@@ -214,7 +217,7 @@
                 @resize-end="print('PPT resize-end')"
                 style="z-index: 3"
               >
-                <el-image class="ppt-bg" :src="selectPPT.innerPicture.src"  />
+                <el-image class="ppt-bg" :src="selectPPT.innerPicture.src" />
                 <el-icon
                   v-if="selectPPT.innerPicture.active"
                   size="20"
@@ -227,7 +230,7 @@
               </Vue3DraggableResizable>
               <!-- 鏁板瓧浜� -->
               <Vue3DraggableResizable
-                v-if="selectPPT.digitalHuman.show==true && selectPPT.digitalHuman?.host"
+                v-if="selectPPT.digitalHuman.show == true && selectPPT.digitalHuman?.host"
                 :parent="false"
                 :lockAspectRatio="true"
                 :minW="350"
@@ -266,7 +269,7 @@
                 </el-icon>
               </Vue3DraggableResizable>
               <Vue3DraggableResizable
-                v-if="selectPPT.digitalHuman.show==false && selectPPT.digitalHuman?.host"
+                v-if="selectPPT.digitalHuman.show == false && selectPPT.digitalHuman?.host"
                 :parent="false"
                 :lockAspectRatio="true"
                 :minW="350"
@@ -360,12 +363,12 @@
         </div>
         <div class="voice-main">
           <el-text class="mx-1" type="primary" size="small">{{
-              t('courseCenter.oralBroadcastingContent')
-            }}</el-text>
+            t('courseCenter.oralBroadcastingContent')
+          }}</el-text>
           <div class="media-box">
             <el-button type="primary" :icon="Mic" size="small" @click="openSelect">{{
-                selectPPT.selectAudio ? selectPPT.selectAudio.name : t('courseCenter.notSelect')
-              }}</el-button>
+              selectPPT.selectAudio ? selectPPT.selectAudio.name : t('courseCenter.notSelect')
+            }}</el-button>
             <el-button
               type="success"
               :icon="Headset"
@@ -376,15 +379,21 @@
         </div>
         <div v-if="selectPPT.driverType == 1" style="position: relative">
           <div class="middle-textarea">
-            <Editor style="height: 196px; overflow-y: hidden;" v-model="selectPPT.pptRemark" :defaultConfig="editorConfig" mode="simple" @on-created="handleCreated" />
+            <Editor
+              style="height: 196px; overflow-y: hidden"
+              v-model="selectPPT.pptRemark"
+              :defaultConfig="editorConfig"
+              mode="simple"
+              @on-created="handleCreated"
+            />
           </div>
           <div class="tool-box">
             <div class="tool-btn">
               <div></div>
             </div>
             <el-button type="primary" :icon="VideoPlay" size="small" @click="createAudio">{{
-                t('courseCenter.tryListening')
-              }}</el-button>
+              t('courseCenter.tryListening')
+            }}</el-button>
           </div>
           <div class="audio-play" v-if="showAudioPlay">
             <div>{{ t('courseCenter.listeningTrial') }}...</div>
@@ -416,13 +425,14 @@
             >
               <template #trigger>
                 <el-button type="primary" :icon="Upload">{{
-                    t('courseCenter.uploadAudio')
-                  }}</el-button>
+                  t('courseCenter.uploadAudio')
+                }}</el-button>
               </template>
             </el-upload>
           </el-tooltip>
         </div>
       </div>
+      <!-- 鏁板瓧浜� -->
       <div class="template-box template-right" v-if="showDigitalHumanTool">
         <div class="tabs-1">
           <div
@@ -474,7 +484,7 @@
               }"
             />
           </div>
-          <el-empty v-if="hostList.length==0" description="鏆傛棤鏁版嵁" />
+          <el-empty v-if="hostList.length == 0" description="鏆傛棤鏁版嵁" />
           <Pagination
             small="true"
             :total="total"
@@ -504,9 +514,9 @@
             v-for="(template, index) in templates"
             :key="index"
             :style="{
-                width: '90%',
-                maxWidth: '90%',
-              }"
+              width: '90%',
+              maxWidth: '90%'
+            }"
             @click="handleTemplateSelection(template)"
           >
             <div class="list-index" :style="template.isActive ? 'background: #409eff' : ''">
@@ -514,11 +524,95 @@
             </div>
             <el-image class="background" :src="template.previewImage" fit="contain" />
           </div>
-          <el-empty v-if="templates.length==0" description="鏆傛棤鏁版嵁" />
+          <el-empty v-if="templates.length == 0" description="鏆傛棤鏁版嵁" />
         </div>
-<!--        <div class="apply-all">-->
-<!--          <el-checkbox v-model="applyAllTemplate" :label="t('courseCenter.uploadAudio')" />-->
-<!--        </div>-->
+        <!--        <div class="apply-all">-->
+        <!--          <el-checkbox v-model="applyAllTemplate" :label="t('courseCenter.uploadAudio')" />-->
+        <!--        </div>-->
+      </div>
+      <!-- 澹伴煶 -->
+      <div class="template-box template-right" v-if="SoundTool">
+        <div class="SoundArea">
+          <div class="SoundClassArea">
+            <!-- 璇 -->
+            <div>
+              <el-select
+                v-model="selectLanguage.value"
+                placeholder="璇烽�夋嫨璇"
+                @change="LanguageChange"
+              >
+                <el-option
+                  v-for="item in languageList"
+                  :key="item.value"
+                  :label="item.label"
+                  :value="item.value"
+                />
+              </el-select>
+            </div>
+            <!-- 鎬у埆 -->
+            <div>
+              <el-select v-model="changeAudio" placeholder="璇烽�夋嫨鎬у埆" @change="AudioChange()">
+                <el-option
+                  v-for="item in audioType"
+                  :key="item.value"
+                  :label="item.label"
+                  :value="item.value"
+                />
+              </el-select>
+            </div>
+            <!-- 绫诲瀷 -->
+            <div>
+              <el-select
+                v-model="ChangeSoundTypeList.value"
+                placeholder="璇烽�夋嫨澹伴煶绫诲瀷"
+                @change="SoundTypeChange"
+              >
+                <el-option
+                  v-for="item in SoundTypeList"
+                  :key="item.value"
+                  :label="item.label"
+                  :value="item.value"
+                />
+              </el-select>
+            </div>
+          </div>
+          <div class="SoundModelArea" v-loading="soundLoading">
+            <div
+              class="ModealBox"
+              v-for="(item, index) in audioList"
+              :key="index"
+              @click="handleSelect(item)"
+              @mouseenter="handleMouseenter(item)"
+              @mouseleave="handleMouseleave(item)"
+              :class="item.isSelect ? 'slectModel' : ''"
+            >
+              <div class="ImgBox">
+                <img :src="item.avatarUrl" alt="" />
+              </div>
+              <div class="TextArea">
+                <p> {{ item.name }} </p>
+                <p> {{ item.introduction }} </p>
+              </div>
+              <img
+                class="play-img"
+                v-if="item.isHover && !item.isPlay"
+                src="@/assets/imgs/play.png"
+                alt=""
+                @click.stop="playAudio(item)"
+              />
+              <img
+                class="play-img"
+                v-if="item.isHover && item.isPlay"
+                src="@/assets/imgs/pause.png"
+                alt=""
+                @click.stop="SoundpauseAudio(item)"
+              />
+            </div>
+          </div>
+          <div class="ButtonArea">
+            <el-button type="primary" @click="submitForm">{{ t('common.ok') }}</el-button>
+          </div>
+        </div>
       </div>
       <!-- 鑳屾櫙璁剧疆 -->
       <div class="template-box template-right" v-if="showHeadImageTool">
@@ -553,20 +647,32 @@
     <mergeWarningDialog ref="warningDialog" />
     <ReplaceDialog ref="replaceDialog" :ppt-arr="PPTArr" @submit="handleReplacement" />
     <!-- 澶氶煶瀛� -->
-    <el-dialog v-model="dialogVisible" title="鐐瑰嚮闇�瑕佺籂姝g殑澶氶煶瀛楋紝閫夋嫨姝g‘鐨勫彂闊�" width="500" @close="dialogVisible = false">
-      <el-tag v-for="(item, index) in textList" :key="index" type="primary" effect="dark" style="margin-right: 10px;cursor: pointer;" @click="handleTag(item)">
+    <el-dialog
+      v-model="dialogVisible"
+      title="鐐瑰嚮闇�瑕佺籂姝g殑澶氶煶瀛楋紝閫夋嫨姝g‘鐨勫彂闊�"
+      width="500"
+      @close="dialogVisible = false"
+    >
+      <el-tag
+        v-for="(item, index) in textList"
+        :key="index"
+        type="primary"
+        effect="dark"
+        style="margin-right: 10px; cursor: pointer"
+        @click="handleTag(item)"
+      >
         {{ item }}
       </el-tag>
     </el-dialog>
     <el-dialog v-model="dialogVisible1" title="鎻愮ず" width="500px" style="height: 150px">
-      <p style="margin-bottom: 20px;font-size: 18px">鏄惁瑕佸皢姝ゆā鏉垮簲鐢ㄥ埌鎵�鏈夐〉闈�</p>
+      <p style="margin-bottom: 20px; font-size: 18px">鏄惁瑕佸皢姝ゆā鏉垮簲鐢ㄥ埌鎵�鏈夐〉闈�</p>
       <span class="dialog-footer">
         <el-button @click="handleTemplateSelection1(1)">搴旂敤褰撳墠椤�</el-button>
         <el-button type="primary" @click="handleTemplateSelection1(2)">搴旂敤鎵�鏈夐〉</el-button>
       </span>
     </el-dialog>
     <el-dialog v-model="dialogVisible2" title="鎻愮ず" width="500px" style="height: 150px">
-      <p style="margin-bottom: 20px;font-size: 18px">鏄惁瑕佸皢姝ゆ暟瀛椾汉搴旂敤鍒版墍鏈夐〉闈�</p>
+      <p style="margin-bottom: 20px; font-size: 18px">鏄惁瑕佸皢姝ゆ暟瀛椾汉搴旂敤鍒版墍鏈夐〉闈�</p>
       <span class="dialog-footer">
         <el-button @click="chooseHost1(1)">搴旂敤褰撳墠椤�</el-button>
         <el-button type="primary" @click="chooseHost1(2)">搴旂敤鎵�鏈夐〉</el-button>
@@ -594,6 +700,8 @@
 import templateActive from '@/assets/imgs/template-active.png'
 import user from '@/assets/imgs/user.png'
 import userActive from '@/assets/imgs/user-active.png'
+import sound from '@/assets/imgs/sound.png'
+import soundActive from '@/assets/imgs/sound-active.png'
 import bg from '@/assets/imgs/bg.png'
 import bgActive from '@/assets/imgs/bg-active.png'
 import innerPicture from '@/assets/imgs/inner-picture.png'
@@ -622,6 +730,8 @@
 import { polyphonic } from 'pinyin-pro'
 import { useEditorHtml } from '@/hooks/web/useEditorHtml'
 import { ElMessage, ElMessageBox } from 'element-plus'
+import { DICT_TYPE, getIntDictOptions, getStrDictOptions } from '@/utils/dict'
+import { measureMemory } from 'vm'
 
 const editorHtml = useEditorHtml()
 const router = useRouter()
@@ -629,8 +739,8 @@
 const userStore = useUserStore()
 const userId = computed(() => userStore.user.id)
 const message = useMessage()
-const dialogVisible1=ref(false)
-const dialogVisible2=ref(false)
+const dialogVisible1 = ref(false)
+const dialogVisible2 = ref(false)
 const isEditing = ref(false)
 const inputRef = ref(null)
 const editName = ref('')
@@ -647,17 +757,17 @@
     inputRef.value.focus()
   })
 }
-const hostValue=ref({})
+const hostValue = ref({})
 const chooseHost = (item) => {
   dialogVisible2.value = true
   hostValue.value = item
 }
 const chooseHost1 = (index) => {
-  if (index==1){
+  if (index == 1) {
     applyAllHost.value = false
     applyHostToPages(hostValue.value)
     dialogVisible2.value = false
-  }else if(index==2){
+  } else if (index == 2) {
     applyAllHost.value = true
     applyHostToPages(hostValue.value)
     dialogVisible2.value = false
@@ -670,7 +780,7 @@
 
   const pagesToUpdate = applyAllHost.value ? PPTArr.value : [selectPPT.value]
 
-  pagesToUpdate.forEach(page => {
+  pagesToUpdate.forEach((page) => {
     page.digitalHuman.host = host
     initHumanPositon(host, page.digitalHuman)
   })
@@ -785,7 +895,7 @@
 }
 const tabs4Click = (item) => {
   tabs4ActiveNum.value = item.itemValue
-  queryParams1.zg=tabs4ActiveNum.value
+  queryParams1.zg = tabs4ActiveNum.value
   getList1()
 }
 
@@ -812,6 +922,13 @@
     activeUrl: userActive,
     isActive: false
   },
+  // 澹伴煶绫诲瀷
+  {
+    name: t('courseCenter.sound'),
+    url: sound,
+    activeUrl: soundActive,
+    isActive: false
+  }
   // {
   //   name: t('courseCenter.background'),
   //   url: bg,
@@ -828,26 +945,28 @@
 
 const showHeadImageTool = ref(false)
 const showDigitalHumanTool = ref(false)
+// 澹伴煶
+const SoundTool = ref(false)
 const showTemplateTool = ref(false)
 const showInnerPictureTool = ref(false)
 const applyAllTemplate = ref(false)
-const templateSelection=ref({})
+const templateSelection = ref({})
 const handleTemplateSelection = (template) => {
   console.log(template)
-  dialogVisible1.value=true
-  templateSelection.value=template
+  dialogVisible1.value = true
+  templateSelection.value = template
   console.log(templateSelection.value)
 }
 
 const handleTemplateSelection1 = (index) => {
-  if (index==2){
+  if (index == 2) {
     applyAllTemplate.value = true
     chooseTemplate(templateSelection.value)
-    dialogVisible1.value=false
-  }else if(index==1){
+    dialogVisible1.value = false
+  } else if (index == 1) {
     applyAllTemplate.value = false
     chooseTemplate(templateSelection.value)
-    dialogVisible1.value=false
+    dialogVisible1.value = false
   }
 }
 const handleChangeTool = (item) => {
@@ -861,15 +980,239 @@
   if (item.name == t('courseCenter.digitalPeople')) {
     tabs1ActiveNum.value = '0'
     getList()
-  }else if (item.name == t('courseCenter.template')) {
+  } else if (item.name == t('courseCenter.template')) {
     tabs4ActiveNum.value = '2'
-    queryParams1.zg=tabs4ActiveNum.value
+    queryParams1.zg = tabs4ActiveNum.value
     getList1()
+  } else if (item.name == t('courseCenter.sound')) {
+    // 澹伴煶鐨勫鐞�       selectAudio
+    // 鑾峰彇璇█绉嶇被
+    getLanguageList()
+    //鑾峰彇鎬у埆绉嶇被
+    getAudioType()
+    // 鑾峰彇澹伴煶绫诲埆
+    getVoiceType()
+    // 鑾峰彇妯″瀷鍒楄〃
+    getSoundModelList()
+    // 鑾峰彇鍙�夌殑澹伴煶绫诲瀷鍒楄〃
+    GetSoundTypeList()
   }
   showHeadImageTool.value = item.name === t('courseCenter.background')
   showTemplateTool.value = item.name === t('courseCenter.template')
   showDigitalHumanTool.value = item.name === t('courseCenter.digitalPeople')
+  SoundTool.value = item.name === t('courseCenter.sound')
   showInnerPictureTool.value = item.name === t('courseCenter.pictureInPicture')
+}
+// 褰撳墠閫夋嫨鐨勮绉�
+const selectLanguage = ref<any>()
+// 鍙�夌殑璇鍒楄〃
+const languageList = ref()
+// 鑾峰彇璇█瀛楀吀
+const getLanguageList = () => {
+  let res = getStrDictOptions(DICT_TYPE.DIGITALCOURSE_VOICES_LANGUAGE)
+  languageList.value = res
+  selectLanguage.value = { ...languageList.value[0] }
+}
+// 鍙�夌殑鎬у埆鍒楄〃
+const audioType = ref()
+// 褰撳墠閫夋嫨鐨勬�у埆
+const changeAudio = ref<any>({ value: '' })
+//鑾峰彇鎬у埆瀛楀吀
+const getAudioType = () => {
+  const list = getIntDictOptions(DICT_TYPE.SYSTEM_USER_SEX)
+  audioType.value = list
+  changeAudio.value = list[0].value
+}
+
+// 鍙�夌殑澹伴煶绫诲埆鍒楄〃
+const SoundTypeList = ref()
+// 褰撳墠閫夋嫨鐨勫0闊崇被鍒�
+const ChangeSoundTypeList = ref()
+// 鑾峰彇鍙�夌殑澹伴煶绫诲瀷鍒楄〃
+const GetSoundTypeList = () => {
+  const res = getIntDictOptions(DICT_TYPE.DIGITALCOURSE_VOICES_TYPE)
+  SoundTypeList.value = res
+  ChangeSoundTypeList.value = { ...res[0] }
+}
+
+//鍙�夌殑澹伴煶妯″瀷鐨勫0闊崇被鍒垪琛�
+const SoundvoiceTypeList = ref()
+// 褰撳墠閫夋嫨鐨勫0闊虫ā鍨嬬殑澹伴煶绫诲埆
+const activeSoundType = ref<any>({ value: '' })
+//鑾峰彇鐨勫0闊虫ā鍨嬬殑澹伴煶绫诲埆
+const getVoiceType = () => {
+  const list1 = getIntDictOptions(DICT_TYPE.DIGITALCOURSE_VOICES_TYPE)
+  SoundvoiceTypeList.value = list1
+  activeSoundType.value = { ...list1[0] }
+}
+// 鑾峰彇澹伴煶妯″瀷鍒楄〃璇锋眰鍙傛暟
+const soundQueryParams = reactive({
+  pageNo: 1,
+  pageSize: 32,
+  language: '',
+  gender: '',
+  voiceType: '',
+  status: 0 // 鐘舵�侊細0姝e父锛�1寮傚父
+})
+// 鍙�夋嫨鐨勫0闊虫ā鍨嬪垪琛�
+const audioList = ref()
+// 鏄惁姝e湪鍔犺浇妯″瀷鍒楄〃
+const soundLoading = ref(false)
+// 鑾峰彇澹伴煶妯″瀷鍒楄〃
+const getSoundModelList = async () => {
+  try {
+    soundLoading.value = true
+    // 璇█绫诲瀷
+    soundQueryParams.language = selectLanguage?.value.value ?? ''
+    // 鎬у埆
+    soundQueryParams.gender = changeAudio?.value ?? ''
+    // 澹伴煶绫诲瀷
+    soundQueryParams.voiceType = activeSoundType?.value.value ?? ''
+    const data = await pptTemplateApi.videlPageList(soundQueryParams)
+    data.list.forEach((item) => {
+      item.isHover = false
+      item.isPlay = false
+      item.isSelect = false
+    })
+    audioList.value = data.list
+    total.value = data.total
+  } finally {
+    soundLoading.value = false
+  }
+}
+// 璇閫夋嫨
+const LanguageChange = (event) => {
+  languageList.value.forEach((element) => {
+    if (element.value === event) {
+      selectLanguage.value = { ...element }
+    }
+  })
+  getSoundModelList()
+}
+// 鎬у埆閫夋嫨
+const AudioChange = () => {
+  getSoundModelList()
+}
+// 绫诲埆閫夋嫨
+const SoundTypeChange = (event) => {
+  SoundTypeList.value.forEach((element) => {
+    if (element.value === event) {
+      ChangeSoundTypeList.value = { ...element }
+    }
+  })
+  getSoundModelList()
+}
+//閫夋嫨澹伴煶妯″瀷
+const selectList = ref()
+const handleSelect = (item) => {
+  selectList.value = [item]
+  audioList.value.forEach((child) => {
+    if (child.id == item.id) {
+      child.isSelect = true
+    } else {
+      child.isSelect = false
+    }
+  })
+}
+// 纭畾鎸夐挳鐐瑰嚮澶勭悊鍑芥暟
+const submitForm = () => {
+  if (ChangeSoundTypeList.value.value === 2) {
+    //姝ゆ椂涓洪�氱敤
+    if (activeSoundType.value === 1 && selectList.value.length === 0) {
+      message.warning('璇烽�夋嫨澹伴煶妯″瀷')
+      return false
+    }
+
+    selectAudio(selectList.value)
+  } else if (ChangeSoundTypeList.value.value === 1) {
+    // 娓呴櫎閫変腑鐨勯煶棰�
+    selectList.value = null
+    // 娓呴櫎鍒楄〃涓墍鏈夐�変腑鐘舵��
+    if (audioList.value) {
+      audioList.value.forEach((item) => {
+        item.isSelect = false
+      })
+    }
+
+    // 鍋滄褰撳墠鎾斁鐨勯煶棰�
+    if (SoundcurrentAudio.value) {
+      SoundcurrentAudio.value.pause()
+      SoundcurrentAudio.value = null
+    }
+
+    // 閲嶇疆褰撳墠鎾斁鐘舵��
+    if (SoundcurrentlyPlaying.value) {
+      SoundcurrentlyPlaying.value.isPlay = false
+      SoundcurrentlyPlaying.value = null
+    }
+
+    selectAudio(undefined)
+  }
+}
+// 榧犳爣绉诲叆涓庣Щ鍑�
+const handleMouseenter = (item) => {
+  audioList.value.forEach((child) => {
+    if (child.id == item.id) {
+      child.isHover = true
+    }
+  })
+}
+const handleMouseleave = (item) => {
+  audioList.value.forEach((child) => {
+    if (child.id == item.id) {
+      child.isHover = false
+    }
+  })
+}
+
+// 闊抽绠$悊
+const SoundcurrentAudio = ref<HTMLAudioElement | null>(null)
+const SoundcurrentlyPlaying = ref<any>(null)
+
+const playAudio = async (item: any) => {
+  // 濡傛灉鐐瑰嚮鐨勬槸褰撳墠姝e湪鎾斁鐨勯」鐩紝鍒欐殏鍋�
+  if (SoundcurrentlyPlaying.value && SoundcurrentlyPlaying.value.id === item.id) {
+    SoundpauseAudio(item)
+    return
+  }
+
+  // 鍋滄褰撳墠鎾斁鐨勯煶棰�
+  if (SoundcurrentAudio.value) {
+    SoundcurrentAudio.value.pause()
+    SoundcurrentAudio.value = null
+  }
+
+  // 濡傛灉涔嬪墠鏈夋挱鏀剧殑椤圭洰锛岄噸缃叾鐘舵��
+  if (SoundcurrentlyPlaying.value) {
+    SoundcurrentlyPlaying.value.isPlay = false
+  }
+
+  // 璁剧疆鏂扮殑鎾斁椤圭洰
+  SoundcurrentlyPlaying.value = item
+  item.isPlay = true
+
+  // 鍒涘缓鏂扮殑闊抽瀵硅薄骞舵挱鏀�
+  SoundcurrentAudio.value = new Audio(item.auditionUrl)
+  SoundcurrentAudio.value.play()
+
+  // 娣诲姞鎾斁缁撴潫浜嬩欢鐩戝惉
+  SoundcurrentAudio.value.addEventListener('ended', () => {
+    item.isPlay = false
+    SoundcurrentlyPlaying.value = null
+    SoundcurrentAudio.value = null
+  })
+}
+
+const SoundpauseAudio = (item: any) => {
+  if (
+    SoundcurrentAudio.value &&
+    SoundcurrentlyPlaying.value &&
+    SoundcurrentlyPlaying.value.id === item.id
+  ) {
+    SoundcurrentAudio.value.pause()
+    item.isPlay = false
+    SoundcurrentlyPlaying.value = null
+  }
 }
 
 const PPTArr = ref([])
@@ -979,13 +1322,13 @@
   return selectPPT.value?.pictureUrl || ''
 })
 //ppt浜鸿劯鏍¢獙鏂规硶
-const PPtIsHaveFace = async ()=>{
+const PPtIsHaveFace = async () => {
   IsEndCheckFace.value = false
   //娣诲姞ppt涓汉鑴告牎楠�
   //鍚戝師濮媝pt娣诲姞鏁版嵁锛岀敤浣滃悗缁璸pt涓槸鍚﹀寘鍚汉鑴哥殑鏁版嵁鏍¢獙鍘熷鏁版嵁
-  const InitPpt = PPTArr.value.map( (item)=>{
-      return item.innerPicture.src
-  } )
+  const InitPpt = PPTArr.value.map((item) => {
+    return item.innerPicture.src
+  })
   const { detectFacesInImages } = useFaceDetection()
   IsHaveFace.value = await detectFacesInImages(InitPpt)
   IsEndCheckFace.value = true
@@ -1154,47 +1497,44 @@
 }
 
 const copyDocument = (item, index) => {
-  ElMessageBox.confirm(
-    '鏄惁澶嶅埗璇ラ〉闈紵',
-    '鎻愮ず',
-    {
-      confirmButtonText: '鏄�',
-      cancelButtonText: '鍚�',
-      type: 'warning',
-    }).then(() => {
-    let copyItem = cloneDeep(item)
-    copyItem.id = generateUUID()
-    copyItem.isActive = false
-    // 娣辨嫹璐濇暟瀛椾汉閰嶇疆
-    copyItem.digitalHuman = {...item.digitalHuman}
-    PPTArr.value.splice(index + 1, 0, copyItem)
-  }).catch(() => {
-    ElMessage({
-      type: 'info',
-      message: '宸插彇娑堝鍒�',
-    })
+  ElMessageBox.confirm('鏄惁澶嶅埗璇ラ〉闈紵', '鎻愮ず', {
+    confirmButtonText: '鏄�',
+    cancelButtonText: '鍚�',
+    type: 'warning'
   })
+    .then(() => {
+      let copyItem = cloneDeep(item)
+      copyItem.id = generateUUID()
+      copyItem.isActive = false
+      // 娣辨嫹璐濇暟瀛椾汉閰嶇疆
+      copyItem.digitalHuman = { ...item.digitalHuman }
+      PPTArr.value.splice(index + 1, 0, copyItem)
+    })
+    .catch(() => {
+      ElMessage({
+        type: 'info',
+        message: '宸插彇娑堝鍒�'
+      })
+    })
 }
 
 const deleteDocument = (item) => {
-  ElMessageBox.confirm(
-    '鏄惁鍒犻櫎璇ラ〉闈紵',
-    '鎻愮ず',
-    {
-      confirmButtonText: '鏄�',
-      cancelButtonText: '鍚�',
-      type: 'warning',
-    }
-  ).then(() => {
-    PPTArr.value = PPTArr.value.filter((child) => child.id !== item.id)
-    //宸茬粡杩涜杩囧垹闄ゆ搷浣�
-    DeleteD.value = true
-  }).catch(() => {
-    ElMessage({
-      type: 'info',
-      message: '宸插彇娑堝垹闄�',
-    })
+  ElMessageBox.confirm('鏄惁鍒犻櫎璇ラ〉闈紵', '鎻愮ず', {
+    confirmButtonText: '鏄�',
+    cancelButtonText: '鍚�',
+    type: 'warning'
   })
+    .then(() => {
+      PPTArr.value = PPTArr.value.filter((child) => child.id !== item.id)
+      //宸茬粡杩涜杩囧垹闄ゆ搷浣�
+      DeleteD.value = true
+    })
+    .catch(() => {
+      ElMessage({
+        type: 'info',
+        message: '宸插彇娑堝垹闄�'
+      })
+    })
 }
 
 const deleteDigitalHuman = () => {
@@ -1227,7 +1567,7 @@
 const queryParams1 = reactive({
   pageNo: 1,
   pageSize: 100,
-  zg:''
+  zg: ''
 })
 const selectHost = ref(null)
 
@@ -1295,6 +1635,7 @@
 }
 
 const selectAudio = (data) => {
+  console.log(data)
   audioSelectData.value = data
   if (data == undefined) {
     selectPPT.value.selectAudio.name = ''
@@ -1354,27 +1695,23 @@
 const removeHtmlTags = (html) => {
   const parser = new DOMParser()
   const doc = parser.parseFromString(html, 'text/html')
-  return doc.body.textContent || ""
+  return doc.body.textContent || ''
 }
 
 const saveSubmit = async (type) => {
-
-  console.log( "鏄惁鍒犻櫎", DeleteD.value )
+  console.log('鏄惁鍒犻櫎', DeleteD.value)
 
   if (!PPTArr.value || PPTArr.value.length === 0) {
     message.warning('鍦烘櫙涓虹┖锛岃鍏堜笂浼燩PT锛�')
     return false
   }
 
-
   //浜鸿劯鏍¢獙
-  while(!IsEndCheckFace.value){} //涓�涓┖寰幆锛屼富瑕佷负浜嗛伩鍏嶆瀬绔儏鍐典笅褰撶敤鎴风偣鍑讳繚瀛樻寜閽垨鑰呰棰戝悎鎴愭寜閽椂锛屼汉鑴告牎楠屾湭瀹屾垚鐨勯棶棰�
-  if( IsHaveFace.value && !DeleteD.value ){
+  while (!IsEndCheckFace.value) {} //涓�涓┖寰幆锛屼富瑕佷负浜嗛伩鍏嶆瀬绔儏鍐典笅褰撶敤鎴风偣鍑讳繚瀛樻寜閽垨鑰呰棰戝悎鎴愭寜閽椂锛屼汉鑴告牎楠屾湭瀹屾垚鐨勯棶棰�
+  if (IsHaveFace.value && !DeleteD.value) {
     message.warning('褰撳墠ppt涓瓨鍦ㄤ汉鑴稿厓绱狅紝涓烘柟渚垮悗缁棰戠敓鎴愶紝璇峰幓闄よ鍏冪礌')
     return
   }
-
-
 
   //淇濆瓨璇剧▼
   let saveSubmitForm = {
@@ -1453,15 +1790,19 @@
             marker: 1,
             status: item.digitalHuman?.show ? 0 : 1
           },
-          ...(item.innerPicture?.src ? [{
-            ...cloneDeep(item.innerPicture),
-            width: item.innerPicture.width * scaleRatio.value.width,
-            height: item.innerPicture.height * scaleRatio.value.height,
-            top: item.innerPicture.top * scaleRatio.value.height,
-            marginLeft: item.innerPicture.marginLeft * scaleRatio.value.width,
-            category: 1,
-            id: undefined
-          }] : [])
+          ...(item.innerPicture?.src
+            ? [
+                {
+                  ...cloneDeep(item.innerPicture),
+                  width: item.innerPicture.width * scaleRatio.value.width,
+                  height: item.innerPicture.height * scaleRatio.value.height,
+                  top: item.innerPicture.top * scaleRatio.value.height,
+                  marginLeft: item.innerPicture.marginLeft * scaleRatio.value.width,
+                  category: 1,
+                  id: undefined
+                }
+              ]
+            : [])
         ],
         driverType: item.driverType,
         duration: '',
@@ -1472,7 +1813,7 @@
           speech_rate: voiceData.speechRate,
           volume: voiceData.volume,
           smartSpeed: '',
-          textJson: item.pptRemark,
+          textJson: item.pptRemark
         },
         audioDriver: {
           fileName: item.fileList && item.fileList[0]?.name,
@@ -1503,13 +1844,12 @@
   saveSubmitForm.scenes = cloneDeep(scenes)
 
   if (type == 'save') {
-
-    if( DeleteD.value ){
+    if (DeleteD.value) {
       //濡傛灉杩涜杩噋pt鍒犻櫎鎿嶄綔鍒欓渶瑕佽繘琛屼簩娆℃煡鐪�
       await PPtIsHaveFace()
-      if( IsHaveFace.value ){
-          message.warning('褰撳墠ppt涓瓨鍦ㄤ汉鑴稿厓绱狅紝涓烘柟渚垮悗缁棰戠敓鎴愶紝璇峰幓闄よ鍏冪礌')
-          return
+      if (IsHaveFace.value) {
+        message.warning('褰撳墠ppt涓瓨鍦ㄤ汉鑴稿厓绱狅紝涓烘柟渚垮悗缁棰戠敓鎴愶紝璇峰幓闄よ鍏冪礌')
+        return
       }
     }
 
@@ -1528,6 +1868,11 @@
     }
   } else {
     try {
+      if (ChangeSoundTypeList.value?.value === undefined || selectLanguage.value?.value === undefined) {
+        message.error('璇峰厛閫夋嫨璇涓庡0闊崇被鍨�')
+        return
+      }
+
       const saveResult = await saveSubmit('save')
       if (!saveResult) {
         message.error('淇濆瓨澶辫触锛岃閲嶈瘯鍚庡啀鍚堟垚瑙嗛')
@@ -1538,8 +1883,8 @@
       for (let i = 0; i < PPTArr.value.length; i++) {
         const item = PPTArr.value[i]
         console.log(item)
-        console.log( "瀹藉害", item.width )
-        console.log( "楂樺害", item.height )
+        console.log('瀹藉害', item.width)
+        console.log('楂樺害', item.height)
         // 鏍¢獙鑳屾櫙瀹介珮
         if (!item.width || !item.height) {
           message.warning('鑳屾櫙灏哄鏃犳晥锛岃妫�鏌ュ楂樿缃紝鎴栬�呴噸鏂伴�夋嫨妯℃澘')
@@ -1606,7 +1951,7 @@
           originHeight: courseInfo.value.height,
           originWidth: courseInfo.value.width,
           entityId: 1,
-          templateId: template.id,
+          templateId: template.id
         }
       }
     } else {
@@ -1665,6 +2010,11 @@
 const currentAudio = ref()
 
 const createAudio = async () => {
+  if (ChangeSoundTypeList.value?.value === undefined || selectLanguage.value?.value === undefined) {
+    message.error('璇峰厛閫夋嫨璇涓庡0闊崇被鍨�')
+    return
+  }
+
   const text = editorRef.value.getText()
   if (!text) {
     message.warning('璇疯緭鍏ラ渶瑕佽瘯鍚枃鏈殑鍐呭鈥�')
@@ -1677,7 +2027,7 @@
     text: truncatedText,
     humanId: selectPPT.value.digitalHuman?.host?.id || null,
     // voiceId: audioSelectData.value == undefined ? null : audioSelectData.value[0].id,
-    voiceId: 'zh-CN',
+    voiceId: 'zh-CN'
   }
 
   try {
@@ -1799,12 +2149,12 @@
 
   // 闄愬埗鍧愭爣
   if (data.x < -100) {
-    data.x = -100; // 鍙互璁剧疆鏈�灏忓潗鏍囦负 -100
+    data.x = -100 // 鍙互璁剧疆鏈�灏忓潗鏍囦负 -100
   }
   if (data.y < -100) {
-    data.y = -100; // 鍙互璁剧疆鏈�灏忓潗鏍囦负 -100
+    data.y = -100 // 鍙互璁剧疆鏈�灏忓潗鏍囦负 -100
   }
-};
+}
 
 const getCourseDetail = async (id) => {
   const res = await pptTemplateApi.coursesDetail(id)
@@ -1831,7 +2181,7 @@
             h: hostInfo.height / scaleRatio.value.height,
             active: false,
             host: {
-              ...hostList.value.find(h => h.code === hostInfo.entityId),
+              ...hostList.value.find((h) => h.code === hostInfo.entityId),
               code: hostInfo.entityId,
               type: hostInfo.entityType
             }
@@ -1901,7 +2251,6 @@
     }))
     templates.value = TEMPLATE_PRESETS.value.map((template) => cloneDeep(template))
     selectTemplate.value = cloneDeep(templates.value[0])
-
   }
 }
 onMounted(async () => {
@@ -2452,7 +2801,91 @@
     background-color: #1989fa;
   }
 }
-.dialog-footer{
+.dialog-footer {
   float: right;
 }
+
+// 澹伴煶閮ㄥ垎
+.SoundArea {
+  margin-top: 10px;
+  height: 100%;
+  .SoundClassArea {
+    width: 100%;
+    display: flex;
+    justify-content: space-around;
+    align-items: center;
+    > div {
+      width: 30%;
+    }
+  }
+  .SoundModelArea {
+    width: 100%;
+    height: 86%;
+    margin: 10px 0;
+    overflow-y: scroll;
+    display: flex;
+    flex-wrap: wrap;
+    align-content: flex-start;
+    > .ModealBox {
+      width: 30%;
+      margin: 10px 1%;
+      position: relative;
+      > .ImgBox {
+        width: 70%;
+        margin: 0 auto;
+        img {
+          width: 100%;
+        }
+      }
+      > .TextArea {
+        width: 100%;
+        p {
+          margin: 3px 0;
+          padding-left: 6px;
+          box-sizing: border-box;
+          text-align: left;
+          word-wrap: break-word;
+        }
+      }
+      > .play-img {
+        width: 32px;
+        height: 32px;
+        cursor: pointer;
+        position: absolute;
+        top: 0;
+        right: 0;
+        left: 0;
+        bottom: 0;
+        margin: auto;
+        z-index: +10;
+      }
+    }
+    .ModealBox:hover {
+      background-color: #000;
+      opacity: 0.5;
+      border: 2px solid #0183f4;
+      > .TextArea {
+        p {
+          color: #fff;
+        }
+      }
+    }
+    > .slectModel {
+      border: 2px solid #1989fa;
+      border-radius: 6px;
+    }
+  }
+  .ButtonArea {
+    width: 90%;
+    margin: 0 auto;
+    display: flex;
+    justify-content: space-around;
+    align-items: center;
+    button {
+      width: 90%;
+      padding: 20px 0;
+      box-sizing: border-box;
+    }
+  }
+}
 </style>

--
Gitblit v1.9.3