From ccb4a8b96d68e2546ade9752ee5173c4a3e4e000 Mon Sep 17 00:00:00 2001
From: shenrongliang <1328040932@qq.com>
Date: 星期五, 23 五月 2025 15:26:12 +0800
Subject: [PATCH] Merge remote-tracking branch 'origin/master'

---
 easegen-front/src/views/chooseTemplate/index.vue                                                                                                                | 2009 ++++++++++++++++++++++----------------------------------
 easegen-front/src/views/myCourse/index.vue                                                                                                                      |   21 
 easegen-front/src/views/File/index.vue                                                                                                                          |   10 
 yudao-module-digitalcourse/yudao-module-digitalcourse-biz/src/main/java/cn/iocoder/yudao/module/digitalcourse/service/coursescenes/CourseScenesServiceImpl.java |    3 
 yudao-module-digitalcourse/yudao-module-digitalcourse-biz/src/main/java/cn/iocoder/yudao/module/digitalcourse/service/courses/CoursesServiceImpl.java           |   10 
 easegen-front/src/views/pptTemplateList/index.vue                                                                                                               |    2 
 easegen-front/src/views/Login/Login.vue                                                                                                                         |    1 
 easegen-front/src/views/chooseTemplate/audioSelect.vue                                                                                                          |    3 
 easegen-front/src/views/digitalcourse/template/index.vue                                                                                                        |    2 
 9 files changed, 828 insertions(+), 1,233 deletions(-)

diff --git a/easegen-front/src/views/File/index.vue b/easegen-front/src/views/File/index.vue
index 9330ee0..a555dfe 100644
--- a/easegen-front/src/views/File/index.vue
+++ b/easegen-front/src/views/File/index.vue
@@ -199,6 +199,15 @@
 
 // 鏂板鎸夐挳鎿嶄綔
 const handleAdd = () => {
+  form.id = undefined
+  form.name = ''
+  form.url = ''
+  form.type = ''
+  form.createBy = undefined
+  dialogTitle.value = '鏂板鏂囦欢'
+  if (formRef.value) {
+    formRef.value.resetFields()
+  }
   open.value = true
 }
 
@@ -239,6 +248,7 @@
     open.value = false
     if (res) {
       message.success(form.id ? "淇敼鎴愬姛" : "鏂板鎴愬姛")
+      reset()
       getList()
     }
   } catch (error) {
diff --git a/easegen-front/src/views/Login/Login.vue b/easegen-front/src/views/Login/Login.vue
index f34cffe..0b2f5cb 100644
--- a/easegen-front/src/views/Login/Login.vue
+++ b/easegen-front/src/views/Login/Login.vue
@@ -76,6 +76,7 @@
   float: left;
   width: 50%;
   margin-top: 4vh;
+  margin-left: 60px;
 }
 
 .Left-img img{
diff --git a/easegen-front/src/views/chooseTemplate/audioSelect.vue b/easegen-front/src/views/chooseTemplate/audioSelect.vue
index 78d2521..fc56793 100644
--- a/easegen-front/src/views/chooseTemplate/audioSelect.vue
+++ b/easegen-front/src/views/chooseTemplate/audioSelect.vue
@@ -203,7 +203,6 @@
 const useOriginalSound = () => {
   // 娓呴櫎閫変腑鐨勯煶棰�
   selectList.value = null;
-
   // 娓呴櫎鍒楄〃涓墍鏈夐�変腑鐘舵��
   if (audioList.value) {
     audioList.value.forEach(item => {
@@ -222,7 +221,7 @@
     currentlyPlaying.value.isPlay = false;
     currentlyPlaying.value = null;
   }
-
+  getList();
   // 鍏抽棴瀵硅瘽妗�
   audioSelectVisible.value = false;
 
diff --git a/easegen-front/src/views/chooseTemplate/index.vue b/easegen-front/src/views/chooseTemplate/index.vue
index 2e7d676..49a269f 100644
--- a/easegen-front/src/views/chooseTemplate/index.vue
+++ b/easegen-front/src/views/chooseTemplate/index.vue
@@ -31,19 +31,17 @@
       </div>
       <div class="top-right">
         <span v-if="saveTime">{{ saveTime }} {{ t('courseCenter.saved') }}</span>
-        <!-- 淇濆瓨鎸夐挳 -->
-        <el-button size="small" @click="saveSubmit('save')" :loading="SaveLoading" >{{ t('common.save') }}</el-button>
-        <!-- 鍚堟垚瑙嗛 -->
-        <el-button type="primary" size="small" @click="saveSubmit('')" :loading="MakeLoading" >{{
-          t('courseCenter.composeViode')
-        }}</el-button>
+        <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>
       </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
           >
@@ -112,15 +110,15 @@
                     />
                     <!-- 鏁板瓧浜�(鏈夊垯鏄剧ず) -->
                     <el-image
-                      v-if="element.showDigitalHuman"
+                      v-if="element.digitalHuman?.show && element.digitalHuman?.host"
                       class="host"
                       :style="{
-                        width: PPTpositon.w * (thumViewSize.width / 800) + 'px',
-                        height: PPTpositon.h * (thumViewSize.height / 450) + 'px',
-                        top: PPTpositon.y * (thumViewSize.width / 800) + 'px',
-                        left: PPTpositon.x * (thumViewSize.height / 450) + 'px'
+                        width: element.digitalHuman.w * (thumViewSize.width / 800) + 'px',
+                        height: element.digitalHuman.h * (thumViewSize.height / 450) + 'px',
+                        top: element.digitalHuman.y * (thumViewSize.width / 800) + 'px',
+                        left: element.digitalHuman.x * (thumViewSize.height / 450) + 'px'
                       }"
-                      :src="selectHost?.pictureUrl"
+                      :src="element.digitalHuman.host.pictureUrl"
                     />
                     <div class="list-index" :style="element.isActive ? 'background: #409eff' : ''">
                       {{ index + 1 }}
@@ -154,7 +152,6 @@
           </div>
         </div>
         <div class="left-upload-setting" v-if="!showLeftList">
-          <!-- <img src="" alt=""> -->
           <div>ppt{{ t('courseCenter.analyzing') }}...</div>
           <el-progress :percentage="percentagePPT" />
           <el-button @click="cancelAnalyze">{{ t('common.cancel') }}</el-button>
@@ -179,19 +176,21 @@
               class="main-image-box"
               :style="{ width: viewSize.width + 'px', height: viewSize.height + 'px',position: 'relative' }"
             >
+
               <!-- 鑳屾櫙(蹇呮樉绀�) -->
               <el-image
-                v-show="selectPPT.pictureUrl && selectPPT.showDigitalHuman==false"
+                v-show="selectPPT.pictureUrl && selectPPT.digitalHuman.show==0"
                 class="background1"
                 :src="selectPPT.pictureUrl"
                 style="z-index: 2"
               />
               <el-image
-                v-show="selectPPT.pictureUrl && selectPPT.showDigitalHuman==true"
+                v-show="selectPPT.pictureUrl && selectPPT.digitalHuman.show==1"
                 class="background1"
                 :src="selectPPT.pictureUrl"
                 style="z-index: 1"
               />
+
               <!-- 鐢讳腑鐢� -->
               <Vue3DraggableResizable
                 v-if="selectPPT.innerPicture && selectPPT.innerPicture.src"
@@ -217,7 +216,7 @@
               >
                 <el-image class="ppt-bg" :src="selectPPT.innerPicture.src"  />
                 <el-icon
-                  v-if="PPTpositon.active"
+                  v-if="selectPPT.innerPicture.active"
                   size="20"
                   color="#409eff"
                   style="position: absolute; top: 5px; right: 5px; z-index: 4"
@@ -226,60 +225,59 @@
                   <Delete />
                 </el-icon>
               </Vue3DraggableResizable>
-                <Vue3DraggableResizable
-                  v-if="selectPPT.showDigitalHuman==true"
-                  :parent="false"
-                  :lockAspectRatio="true"
-                  :minW="350"
-                  :initW="PPTpositon.w"
-                  :initH="PPTpositon.h"
-                  @drag-move="onDragMove"
-                  v-model:x="PPTpositon.x"
-                  v-model:y="PPTpositon.y"
-                  v-model:w="PPTpositon.w"
-                  v-model:h="PPTpositon.h"
-                  v-model:active="PPTpositon.active"
-                  :draggable="true"
-                  :resizable="true"
-                  @activated="print('activated')"
-                  @deactivated="print('deactivated')"
-                  @drag-start="print('drag-start')"
-                  @resize-start="print('resize-start')"
-                  @dragging="print('dragging')"
-                  @resizing="print('resizing')"
-                  @drag-end="print('drag-end')"
-                  @resize-end="print('resize-end')"
-                  style="z-index: 4"
-                >
-                  <!--                {{PPTpositon.w}}{{PPTpositon.h}}-->
-                  <el-image
-                    class="minddle-host-image"
-                    :src="selectHost ? selectHost.pictureUrl : ''"
-                  />
-
-                  <el-icon
-                    v-if="PPTpositon.active"
-                    size="20"
-                    color="#409eff"
-                    style="position: absolute; top: 5px; right: 5px; z-index: 4"
-                    @click.stop="deleteDigitalHuman"
-                  >
-                    <Delete />
-                  </el-icon>
-                </Vue3DraggableResizable>
+              <!-- 鏁板瓧浜� -->
               <Vue3DraggableResizable
-                v-if="selectPPT.showDigitalHuman==false"
+                v-if="selectPPT.digitalHuman.show==1 && selectPPT.digitalHuman?.host"
                 :parent="false"
                 :lockAspectRatio="true"
                 :minW="350"
-                :initW="PPTpositon.w"
-                :initH="PPTpositon.h"
+                :initW="selectPPT.digitalHuman.w"
+                :initH="selectPPT.digitalHuman.h"
                 @drag-move="onDragMove"
-                v-model:x="PPTpositon.x"
-                v-model:y="PPTpositon.y"
-                v-model:w="PPTpositon.w"
-                v-model:h="PPTpositon.h"
-                v-model:active="PPTpositon.active"
+                v-model:x="selectPPT.digitalHuman.x"
+                v-model:y="selectPPT.digitalHuman.y"
+                v-model:w="selectPPT.digitalHuman.w"
+                v-model:h="selectPPT.digitalHuman.h"
+                v-model:active="selectPPT.digitalHuman.active"
+                :draggable="true"
+                :resizable="true"
+                @activated="print('activated')"
+                @deactivated="print('deactivated')"
+                @drag-start="print('drag-start')"
+                @resize-start="print('resize-start')"
+                @dragging="print('dragging')"
+                @resizing="print('resizing')"
+                @drag-end="print('drag-end')"
+                @resize-end="print('resize-end')"
+                style="z-index: 4"
+              >
+                <el-image
+                  class="minddle-host-image"
+                  :src="selectPPT.digitalHuman.host.pictureUrl"
+                />
+                <el-icon
+                  v-if="selectPPT.digitalHuman.active"
+                  size="20"
+                  color="#409eff"
+                  style="position: absolute; top: 5px; right: 5px; z-index: 4"
+                  @click.stop="deleteDigitalHuman"
+                >
+                  <Delete />
+                </el-icon>
+              </Vue3DraggableResizable>
+              <Vue3DraggableResizable
+                v-if="selectPPT.digitalHuman.show==0 && selectPPT.digitalHuman?.host"
+                :parent="false"
+                :lockAspectRatio="true"
+                :minW="350"
+                :initW="selectPPT.digitalHuman.w"
+                :initH="selectPPT.digitalHuman.h"
+                @drag-move="onDragMove"
+                v-model:x="selectPPT.digitalHuman.x"
+                v-model:y="selectPPT.digitalHuman.y"
+                v-model:w="selectPPT.digitalHuman.w"
+                v-model:h="selectPPT.digitalHuman.h"
+                v-model:active="selectPPT.digitalHuman.active"
                 :draggable="true"
                 :resizable="true"
                 @activated="print('activated')"
@@ -292,14 +290,12 @@
                 @resize-end="print('resize-end')"
                 style="z-index: 1"
               >
-                <!--                {{PPTpositon.w}}{{PPTpositon.h}}-->
                 <el-image
                   class="minddle-host-image"
-                  :src="selectHost ? selectHost.pictureUrl : ''"
+                  :src="selectPPT.digitalHuman.host.pictureUrl"
                 />
-
                 <el-icon
-                  v-if="PPTpositon.active"
+                  v-if="selectPPT.digitalHuman.active"
                   size="20"
                   color="#409eff"
                   style="position: absolute; top: 5px; right: 5px; z-index: 4"
@@ -364,21 +360,12 @@
         </div>
         <div class="voice-main">
           <el-text class="mx-1" type="primary" size="small">{{
-            t('courseCenter.oralBroadcastingContent')
-          }}</el-text>
-<!--          <div class="voice-item">-->
-<!--            <span-->
-<!--              :class="selectPPT.driverType == item.itemValue ? 'active-item' : ''"-->
-<!--              v-for="(item, index) in driveType"-->
-<!--              :key="index"-->
-<!--              @click="driveTypeChange(item)"-->
-<!--              >{{ item.name }}</span-->
-<!--            >-->
-<!--          </div>-->
+              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"
@@ -389,55 +376,15 @@
         </div>
         <div v-if="selectPPT.driverType == 1" style="position: relative">
           <div class="middle-textarea">
-            <!-- <el-input
-              v-model="selectPPT.pptRemark"
-              ref="textareaRef"
-              @select="handlePptRemarkSelection"
-              :rows="5"
-              type="textarea"
-              :placeholder="t('common.inputText') + t('courseCenter.oralBroadcastingContent')"
-              show-word-limit
-              maxlength="1200"
-              resize="none"
-            /> -->
             <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">
-              <!-- 鏂板鏅鸿兘璁茬鎸夐挳 -->
-<!--              <el-button type="primary" size="small" @click="openScriptRewriter">{{-->
-<!--                t('courseCenter.intelligentSpeech')-->
-<!--              }}</el-button>-->
-<!--              <el-button type="primary" @click="openReplaceDialog" size="small">{{-->
-<!--                t('courseCenter.batchReplace')-->
-<!--              }}</el-button>-->
-<!--              <el-button type="primary" size="small" @click="handleWord">{{-->
-<!--                t('courseCenter.polyphonicCharacters')-->
-<!--              }}</el-button>-->
-<!--              <el-dropdown placement="bottom" @command="handleNumber" style="margin: 0 12px;">-->
-<!--                  <el-button type="primary" size="small">{{ t('courseCenter.number') }}</el-button>-->
-<!--                  <template #dropdown>-->
-<!--                      <el-dropdown-menu>-->
-<!--                          <el-dropdown-item command="璇绘暟瀛�">璇绘暟瀛�</el-dropdown-item>-->
-<!--                          <el-dropdown-item command="璇绘暟鍊�">璇绘暟鍊�</el-dropdown-item>-->
-<!--                      </el-dropdown-menu>-->
-<!--                  </template>-->
-<!--              </el-dropdown>-->
-<!--              <el-dropdown placement="bottom" @command="handleBreak">-->
-<!--                  <el-button type="primary" size="small">{{ t('courseCenter.pause') }}</el-button>-->
-<!--                  <template #dropdown>-->
-<!--                      <el-dropdown-menu>-->
-<!--                          <el-dropdown-item command="0.5绉�">0.5绉�</el-dropdown-item>-->
-<!--                          <el-dropdown-item command="1绉�">1绉�</el-dropdown-item>-->
-<!--                          <el-dropdown-item command="2绉�">2绉�</el-dropdown-item>-->
-<!--                      </el-dropdown-menu>-->
-<!--                  </template>-->
-<!--              </el-dropdown>-->
               <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>
@@ -469,8 +416,8 @@
             >
               <template #trigger>
                 <el-button type="primary" :icon="Upload">{{
-                  t('courseCenter.uploadAudio')
-                }}</el-button>
+                    t('courseCenter.uploadAudio')
+                  }}</el-button>
               </template>
             </el-upload>
           </el-tooltip>
@@ -544,7 +491,7 @@
             class="template-item"
             v-for="(template, index) in templates"
             :key="index"
-            @click="chooseTemplate(template)"
+            @click="handleTemplateSelection(template)"
           >
             <div class="list-index" :style="template.isActive ? 'background: #409eff' : ''">
               {{ index + 1 }}
@@ -559,8 +506,6 @@
       <!-- 鑳屾櫙璁剧疆 -->
       <div class="template-box template-right" v-if="showHeadImageTool">
         <div class="image-setting">
-          <!--          涓婁紶鍥剧墖鎴愬姛鍚庯紝灏嗗綋鍓嶅満鏅殑鑳屾櫙淇敼涓轰笂浼犵殑鍥剧墖url-->
-
           <div>{{ t('courseCenter.uploadImage') }}</div>
           <UploadImg v-model="selectPPT.pictureUrl" :limit="1" />
         </div>
@@ -568,29 +513,8 @@
       <!-- 鐢讳腑鐢昏缃� -->
       <div class="template-box template-right" v-if="showInnerPictureTool">
         <div class="image-setting">
-          <!--          涓婁紶鍥剧墖鎴愬姛鍚庯紝灏嗗綋鍓嶅満鏅殑鐢讳腑鐢讳慨鏀逛负涓婁紶鐨勫浘鐗噓rl-->
-
           <div>{{ t('courseCenter.uploadImage') }}</div>
           <UploadImg v-model="selectPPT.innerPicture.src" :limit="1" />
-        </div>
-      </div>
-      <div class="template-box template-right" v-if="showImageSet">
-        <div class="image-setting">
-          <div>{{ t('courseCenter.imageProperties') }}</div>
-          <div class="img-setting">
-            <span class="setting-label">{{ t('courseCenter.position') }}</span>
-            X <el-input v-model="PPTpositon.x" type="number" :min="20" :max="460" /> Y
-            <el-input v-model="PPTpositon.y" type="number" :min="20" :max="180" />
-          </div>
-          <div class="img-setting">
-            <span class="setting-label">{{ t('courseCenter.hierarchicalStructure') }}</span>
-            <el-input v-model="PPTpositon.depth" type="number" :min="0" :max="999" />
-          </div>
-          <div class="img-setting">
-            <span class="setting-label">{{ t('courseCenter.size') }}</span>
-            W <el-input v-model="PPTpositon.w" type="number" :min="20" :max="760" /> H
-            <el-input v-model="PPTpositon.h" type="number" :min="20" :max="360" />
-          </div>
         </div>
       </div>
       <div class="template-box template-tool">
@@ -611,28 +535,35 @@
     <AudioSelect ref="audioSelect" @success="selectAudio" />
     <mergeWarningDialog ref="warningDialog" />
     <ReplaceDialog ref="replaceDialog" :ppt-arr="PPTArr" @submit="handleReplacement" />
-    <!-- 娣诲姞鏅鸿兘璁茬缁勪欢 -->
-    <Rewriter
-      ref="rewriterRef"
-      :image-url="currentImageUrl"
-      :title="''"
-      :content="selectPPT.pptRemark"
-      @confirm="handleRewritten"
-    />
-     <!-- 澶氶煶瀛� -->
-     <el-dialog v-model="dialogVisible" title="鐐瑰嚮闇�瑕佺籂姝g殑澶氶煶瀛楋紝閫夋嫨姝g‘鐨勫彂闊�" width="500" @close="dialogVisible = false">
+    <!-- 澶氶煶瀛� -->
+    <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 }}
+        {{ 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>
+      <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>
+      <span class="dialog-footer">
+        <el-button @click="chooseHost1(1)">搴旂敤褰撳墠椤�</el-button>
+        <el-button type="primary" @click="chooseHost1(2)">搴旂敤鎵�鏈夐〉</el-button>
+      </span>
     </el-dialog>
   </div>
 </template>
+
 <script lang="ts" setup>
-import { ref, reactive, onMounted } from 'vue'
+import { ref, reactive, onMounted, computed, watch, nextTick, shallowRef } from 'vue'
 import draggable from 'vuedraggable'
-import { ElMessage, ElMessageBox } from 'element-plus'
 import Vue3DraggableResizable from 'vue3-draggable-resizable'
 import 'vue3-draggable-resizable/dist/Vue3DraggableResizable.css'
+import { useFaceDetection } from '@/utils/HaveFace'
 import { config } from '@/config/axios/config'
 import { genFileId } from 'element-plus'
 import type { UploadRawFile } from 'element-plus'
@@ -641,8 +572,7 @@
 import uploadExplain from './uploadExplain.vue'
 import AudioSelect from './audioSelect.vue'
 import mergeWarningDialog from './mergeWarningDialog.vue'
-import ReplaceDialog from './replaceDialog.vue' // 寮曞叆鎵归噺鏇挎崲缁勪欢
-import Rewriter from './rewriter.vue'
+import ReplaceDialog from './replaceDialog.vue'
 import template from '@/assets/imgs/template.png'
 import templateActive from '@/assets/imgs/template-active.png'
 import user from '@/assets/imgs/user.png'
@@ -652,8 +582,7 @@
 import innerPicture from '@/assets/imgs/inner-picture.png'
 import innerPictureActive from '@/assets/imgs/inner-picture-active.png'
 import { TemplateApi } from '@/api/digitalcourse/template'
-const { t } = useI18n() // 鍥介檯鍖�
-//鐢ㄦ埛淇℃伅
+const { t } = useI18n()
 import { useUserStore } from '@/store/modules/user'
 import {
   Edit,
@@ -662,40 +591,37 @@
   Mic,
   Headset,
   Delete,
-  QuestionFilled,
   VideoPlay,
   CopyDocument
 } from '@element-plus/icons-vue'
 import { generateUUID } from '@/utils'
 import { useRoute, useRouter } from 'vue-router'
 import { cloneDeep } from 'lodash-es'
-// 瀵屾枃鏈紪杈戝櫒
-import '@wangeditor/editor/dist/css/style.css' // 寮曞叆 css
 import { Editor } from '@wangeditor/editor-for-vue'
+import '@wangeditor/editor/dist/css/style.css'
 import { Boot } from '@wangeditor/editor'
-import TitleBlack from './title-black/index.js';  // 杩欎釜璺緞鏍规嵁浣犵殑閰嶇疆鏉�
+import TitleBlack from './title-black/index.js'
 Boot.registerModule(TitleBlack)
-//澶氶煶瀛�
-import { polyphonic } from 'pinyin-pro';
-//缂栬緫鍣ㄥ唴瀹硅浆鎹sml
-import { useEditorHtml } from '@/hooks/web/useEditorHtml';
-//寮曞叆浜鸿劯璇嗗埆鏂规硶
-import { useFaceDetection } from '@/utils/HaveFace'
-import {coursesDelete} from "@/api/pptTemplate";
-import { tr } from 'element-plus/es/locale'
+import { polyphonic } from 'pinyin-pro'
+import { useEditorHtml } from '@/hooks/web/useEditorHtml'
+import { ElMessage, ElMessageBox } from 'element-plus'
+
 const editorHtml = useEditorHtml()
-const router = useRouter() // 璺敱
-const route = useRoute() //
-//鐢ㄦ埛淇℃伅
+const router = useRouter()
+const route = useRoute()
 const userStore = useUserStore()
 const userId = computed(() => userStore.user.id)
 const message = useMessage()
+const dialogVisible1=ref(false)
+const dialogVisible2=ref(false)
 const isEditing = ref(false)
 const inputRef = ref(null)
-//淇濆瓨鐨勫姞杞藉姩鐢�
-const SaveLoading = ref(false)
-//瑙嗛鍚堟垚鐨勫姞杞藉姩鐢�
-const MakeLoading = ref(false)
+const editName = ref('')
+const applyAllHost = ref(false)
+//褰撳墠鏄惁瀛樺湪浜鸿劯
+const IsHaveFace = ref(false)
+//褰撳墠鏄惁瀹屾垚ppt浜鸿劯鏍¢獙
+const IsEndCheckFace = ref(true)
 // 鍒囨崲鍒扮紪杈戞ā寮�
 const toggleEdit = () => {
   isEditing.value = true
@@ -703,27 +629,62 @@
   nextTick(() => {
     inputRef.value.focus()
   })
-};
-const onDragMove = (evt, data) => {
-  console.log(evt)
-  console.log(data)
+}
+const hostValue=ref({})
+const chooseHost = (item) => {
+  dialogVisible2.value = true
+  hostValue.value = item
+}
+const chooseHost1 = (index) => {
+  if (index==1){
+    applyAllHost.value = false
+    applyHostToPages(hostValue.value)
+    dialogVisible2.value = false
+  }else if(index==2){
+    applyAllHost.value = true
+    applyHostToPages(hostValue.value)
+    dialogVisible2.value = false
+  }
+}
+const applyHostToPages = (host) => {
+  hostList.value.forEach((el) => {
+    el.isActive = el.id === host.id
+  })
 
-  // 闄愬埗鍧愭爣
-  if (data.x < -100) {
-    data.x = -100; // 鍙互璁剧疆鏈�灏忓潗鏍囦负 -100
-  }
-  if (data.y < -100) {
-    data.y = -100; // 鍙互璁剧疆鏈�灏忓潗鏍囦负 -100
-  }
-};
-// 淇濆瓨缂栬緫鍚庣殑鍚嶇О
+  const pagesToUpdate = applyAllHost.value ? PPTArr.value : [selectPPT.value]
+
+  pagesToUpdate.forEach(page => {
+    page.digitalHuman.host = host
+    initHumanPositon(host, page.digitalHuman)
+  })
+}
 const saveEdit = () => {
   isEditing.value = false
   courseInfo.value.name = editName.value
 }
-let humanId = 0
+const print = (val) => {
+  console.log(val)
+}
+const viewSize = reactive({
+  width: 800,
+  height: (800 * 9) / 16
+})
 
-//璇剧▼鍩烘湰淇℃伅
+const thumViewSize = reactive({
+  width: 152,
+  height: (152 * 9) / 16
+})
+
+const digitalHumanSize = reactive({
+  width: 640,
+  height: 360
+})
+
+const scaleRatio = computed(() => ({
+  width: courseInfo.value.width / viewSize.width,
+  height: courseInfo.value.height / viewSize.height
+}))
+
 const courseInfo = ref({
   id: 0,
   accountId: userId.value,
@@ -731,12 +692,12 @@
   name: '鏈懡鍚嶈崏绋�',
   duration: 0,
   status: 0,
-  pageMode: 2,//ppt璇句欢瑙嗛
+  pageMode: 2,
   matting: 1,
   width: 1920,
   height: 1080
 })
-// 褰撴瘮渚嬫敼鍙樻椂鏇存柊瀹藉害鍜岄珮搴�
+
 watch(
   () => courseInfo.value.aspect,
   (newAspect) => {
@@ -745,83 +706,14 @@
   }
 )
 
-const editName = ref(courseInfo.value.name)
-const viewSize = reactive({
-  width: 800,
-  height: (800 * 9) / 16
-})
-const thumViewSize = reactive({
-  width: 152,
-  height: (152 * 9) / 16
-})
-const digitalHumanSize = reactive({
-  width: 640,
-  height: 360
-})
-// 娣诲姞缂╂斁姣斾緥璁$畻
-const scaleRatio = computed(() => ({
-  width: courseInfo.value.width / viewSize.width, // 1920/800 = 2.4
-  height: courseInfo.value.height / viewSize.height // 1080/450 = 2.4
-}))
-
-const PPTpositon = reactive({
-  x: viewSize.width - digitalHumanSize.width,
-  y: viewSize.height - digitalHumanSize.height,
-  w: digitalHumanSize.width,
-  h: digitalHumanSize.height,
-  depth: 0,
-  active: false
-})
-
-const componentsInfo = reactive({
-  width: PPTpositon.w / 5,
-  height: PPTpositon.h / 4,
-  marginLeft: PPTpositon.x / 4,
-  top: PPTpositon.y / 4.5,
-  depth: PPTpositon.depth
-})
-//鑳屾櫙璁剧疆
-const showHeadImageTool = ref(false)
-//鏁板瓧浜鸿缃�
-const showDigitalHumanTool = ref(false)
-//妯℃澘璁剧疆
-const showTemplateTool = ref(false)
-//鐢讳腑鐢昏缃�
-const showInnerPictureTool = ref(false)
-//鍥剧墖灞炴��
-const showImageSet = ref(false)
-//鏄惁灏嗘ā鏉垮簲鐢ㄥ埌鎵�鏈夐〉闈�
-const applyAllTemplate = ref(false)
-
-const xScale = viewSize.width / thumViewSize.width
-// const yScale = viewSize.height / thumViewSize.height
-//宸︿晶ppt鏁板瓧浜轰綅缃�
-const leftWidth = computed(() => {
-  return PPTpositon.w / xScale + 'px'
-})
-const leftHeight = computed(() => {
-  return PPTpositon.h / xScale + 'px'
-})
-const leftTop = computed(() => {
-  return PPTpositon.y / xScale + 'px'
-})
-const leftLeft = computed(() => {
-  return PPTpositon.x / xScale + 'px'
-})
-const print = (val) => {
-  console.log(val)
-}
 const state = reactive({
   dragging: false
 })
 
-//棰勮妯℃澘
 const TEMPLATE_PRESETS = ref([])
 const templates = ref([])
-
 const selectTemplate = ref([])
 
-//鏁板瓧浜簍ab
 const tabs1 = [
   {
     itemName: t('courseCenter.model'),
@@ -859,40 +751,22 @@
     itemValue: '2'
   }
 ]
+
 const tabs1Click = (item) => {
   tabs1ActiveNum.value = item.itemValue
   getList()
 }
+
 const tabs2Click = (item) => {
   tabs2ActiveNum.value = item.itemValue
   getList()
 }
+
 const tabs3Click = (item) => {
   tabs3ActiveNum.value = item.itemValue
   getList()
 }
-//椹卞姩绫诲瀷
-const selectDriveType = ref({
-  name: t('courseCenter.textDriven'),
-  itemValue: 1,
-  isActive: true
-})
-const driveType = reactive([
-  {
-    name: t('courseCenter.textDriven'),
-    itemValue: 1,
-    isActive: true
-  },
-  {
-    name: t('courseCenter.soundDriven'),
-    isActive: false,
-    itemValue: 2
-  }
-])
-const driveTypeChange = (item) => {
-  selectPPT.value.driverType = item.itemValue
-}
-//鍙充晶璁剧疆
+
 const rightTools = reactive([
   {
     name: t('courseCenter.template'),
@@ -919,6 +793,30 @@
     isActive: false
   }
 ])
+
+const showHeadImageTool = ref(false)
+const showDigitalHumanTool = ref(false)
+const showTemplateTool = ref(false)
+const showInnerPictureTool = ref(false)
+const applyAllTemplate = ref(false)
+const templateSelection=ref({})
+const handleTemplateSelection = (template) => {
+  dialogVisible1.value=true
+  templateSelection.value=template
+  console.log(templateSelection.value)
+}
+
+const handleTemplateSelection1 = (index) => {
+  if (index==2){
+    applyAllTemplate.value = true
+    chooseTemplate(templateSelection.value)
+    dialogVisible1.value=false
+  }else if(index==1){
+    applyAllTemplate.value = false
+    chooseTemplate(templateSelection.value)
+    dialogVisible1.value=false
+  }
+}
 const handleChangeTool = (item) => {
   rightTools.forEach((child) => {
     if (child.name == item.name) {
@@ -927,39 +825,23 @@
       child.isActive = false
     }
   })
-  if (item.name == t('courseCenter.background')) {
-    showHeadImageTool.value = true
-    showTemplateTool.value = false
-    showDigitalHumanTool.value = false
-    showInnerPictureTool.value = false
-  } else if (item.name == t('courseCenter.digitalPeople')) {
-    showHeadImageTool.value = false
-    showTemplateTool.value = false
-    showDigitalHumanTool.value = true
-    showInnerPictureTool.value = false
-  } else if (item.name == t('courseCenter.template')) {
-    showHeadImageTool.value = false
-    showTemplateTool.value = true
-    showDigitalHumanTool.value = false
-    showInnerPictureTool.value = false
-  } else if (item.name == t('courseCenter.pictureInPicture')) {
-    showHeadImageTool.value = false
-    showTemplateTool.value = false
-    showDigitalHumanTool.value = false
-    showInnerPictureTool.value = true
-  }
+
+  showHeadImageTool.value = item.name === t('courseCenter.background')
+  showTemplateTool.value = item.name === t('courseCenter.template')
+  showDigitalHumanTool.value = item.name === t('courseCenter.digitalPeople')
+  showInnerPictureTool.value = item.name === t('courseCenter.pictureInPicture')
 }
 
-const PPTArr = ref()
-//ppt瑙f瀽杩涘害
+const PPTArr = ref([])
 const percentagePPT = ref(0)
 const showLeftList = ref(true)
 
+//鏄惁杩涜杩囧垹闄ゆ搷浣�
+const DeleteD = ref(false)
+
 const selectPPT = ref({
-  id:"",
   pictureUrl: '',
   innerPicture: {
-    //瀹氫箟鐢讳腑鐢诲璞★紝灞炴�т笌鏁板瓧浜虹浉鍚�
     name: '鐢讳腑鐢�',
     src: '',
     cover: '',
@@ -968,7 +850,7 @@
     originWidth: 0,
     originHeight: 0,
     category: 1,
-    depth: 1, //鐢讳腑鐢�1-100
+    depth: 1,
     top: 0,
     marginLeft: 0,
     businessId: generateUUID(),
@@ -978,32 +860,62 @@
   pptRemark: '',
   driverType: 1,
   uploadAudioUrl: '',
-  fileList: [] as any,
+  fileList: [],
   selectAudio: {
     id: '',
     code: '',
     name: ''
   },
-  showDigitalHuman: true
-}) //閫夋嫨鐨凱PT
-const checked5 = ref(false)
-const options = [
-  {
-    value: '1',
-    label: '16:9'
-  },
-  {
-    value: '2',
-    label: '9:16'
+  digitalHuman: {
+    show: true,
+    x: viewSize.width - digitalHumanSize.width,
+    y: viewSize.height - digitalHumanSize.height,
+    w: digitalHumanSize.width,
+    h: digitalHumanSize.height,
+    active: false,
+    host: null
   }
-]
+})
+
+const videoText = ref(0)
+const videoDuration = ref('')
+
+watch(
+  () => PPTArr.value,
+  (val) => {
+    if (!val) return
+
+    videoText.value = val.reduce((prev, curr) => {
+      if (!curr.pptRemark) return prev
+      const plainText = curr.pptRemark.replace(/<[^>]+>/g, '')
+      return prev + plainText.length
+    }, 0)
+
+    let videoTime = (videoText.value / 200) * 60
+    videoDuration.value = formateVideoTime(Math.ceil(videoTime))
+  },
+  { deep: true }
+)
+
+const formateVideoTime = (times: any) => {
+  let hours: any = parseInt(`${times / 60 / 60}`)
+  let restMinutes: any = parseInt(`${(times / 60) % 60}`)
+  let seconds: any = parseInt(`${times % 60}`)
+
+  if (hours < 10) hours = '0' + hours
+  if (restMinutes < 10) restMinutes = '0' + restMinutes
+  if (seconds < 10) seconds = '0' + seconds
+
+  return hours + ':' + restMinutes + ':' + seconds
+}
+
 const uploadRef = ref()
 const headers = {
   Accept: 'application/json, text/plain, */*',
   Authorization: 'Bearer ' + getAccessToken(),
   'tenant-id': getTenantId()
 }
-//涓婁紶鏂囦欢瀵硅薄
+
 const uploadFileObj = reactive({
   filename: '',
   size: 0,
@@ -1015,6 +927,7 @@
   extInfo: '{"addMode":true,"docType":1,"pptNotes":true,"pptContent":false,"notesPolish":false}',
   resolveType: 1
 })
+
 //鏅鸿兘璁茬缁勪欢begin
 //娣诲姞ref
 const rewriterRef = ref()
@@ -1025,6 +938,18 @@
   }
   return selectPPT.value?.pictureUrl || ''
 })
+//ppt浜鸿劯鏍¢獙鏂规硶
+const PPtIsHaveFace = async ()=>{
+  IsEndCheckFace.value = false
+  //娣诲姞ppt涓汉鑴告牎楠�
+  //鍚戝師濮媝pt娣诲姞鏁版嵁锛岀敤浣滃悗缁璸pt涓槸鍚﹀寘鍚汉鑴哥殑鏁版嵁鏍¢獙鍘熷鏁版嵁
+  const InitPpt = PPTArr.value.map( (item)=>{
+      return item.innerPicture.src
+  } )
+  const { detectFacesInImages } = useFaceDetection()
+  IsHaveFace.value = await detectFacesInImages(InitPpt)
+  IsEndCheckFace.value = true
+}
 // 鎵撳紑鏅鸿兘璁茬寮圭獥
 const openScriptRewriter = () => {
   if (!selectPPT.value?.pptRemark && !currentImageUrl.value) {
@@ -1045,12 +970,8 @@
   uploadRef.value!.handleStart(file)
 }
 
-// 涓婁紶鐩稿叧鐨勫鐞嗗嚱鏁�
 const handleChange = (files) => {
-  // 鑾峰彇鏂囦欢鎵╁睍鍚�
   const extension = files.name.split('.').pop().toLowerCase()
-
-  // 璁剧疆鏂囨。绫诲瀷 1:ppt 2:pdf
   uploadFileObj.docType = extension === 'pdf' ? 2 : 1
   uploadFileObj.filename = files.name
   uploadFileObj.size = files.size
@@ -1069,37 +990,25 @@
   console.error('Upload error:', err)
 }
 
-//涓婁紶闊抽
-const uploadAudioRef = ref()
-const handleAudioSuccess = (rawFile) => {
-  console.log('--------', rawFile)
-  message.success('涓婁紶鎴愬姛锛�')
-  selectPPT.value.uploadAudioUrl = rawFile.data
-  // uploadAudioRef.value!.clearFiles();
-  selectPPT.value.fileList = [
-    {
-      name: uploadAudioFile.value,
-      url: rawFile.data
-    }
-  ]
-}
-const uploadAudioFile = ref()
-const handleAudioChange = (files) => {
-  uploadAudioFile.value = files.name
-}
-//ppt涓婁紶璇存槑鍥炶皟
 const uploadSubmit = (uploadForm) => {
-  console.log('-------ppt涓婁紶璇存槑', uploadForm)
   pptTemplateApi.createPPT(uploadFileObj).then((res) => {
     if (res) {
-      //灏嗚绋嬪悕绉颁慨鏀逛负闄勪欢鍚嶇О
       courseInfo.value.name = uploadFileObj.filename.split('.').slice(0, -1).join('.')
       editName.value = courseInfo.value.name
       schedulePPT(res)
     }
   })
 }
-//瑙f瀽ppt
+
+const chooseTemplate = (currTemplate) => {
+  selectTemplate.value = cloneDeep(currTemplate)
+  templates.value.forEach((item) => {
+    item.isActive = false
+  })
+  currTemplate.isActive = true
+  applyTemplate()
+}
+
 const schedulePPTTimer = ref()
 const schedulePPT = (id) => {
   percentagePPT.value = 0
@@ -1111,7 +1020,6 @@
     pptTemplateApi.getSchedule(id).then((res) => {
       if (res && typeof res == 'string') {
         const progress = Number(res)
-        // 娣诲姞瑙f瀽澶辫触鐨勫垽鏂�
         if (progress < 0) {
           clearInterval(schedulePPTTimer.value)
           showLeftList.value = true
@@ -1120,8 +1028,6 @@
         }
         percentagePPT.value = parseInt(`${progress * 100}`)
       } else if (res && res.length > 0) {
-        console.log('瑙f瀽鎴愬姛', res)
-        console.log('courseInfo', courseInfo.value)
         res.forEach((item) => {
           item.isActive = false
           item.isChecked = false
@@ -1132,18 +1038,25 @@
           item.businessId = generateUUID()
           item.width = courseInfo.value.width
           item.height = courseInfo.value.height
+
+          // 鍒濆鍖栫嫭绔嬬殑鏁板瓧浜洪厤缃�
+          item.digitalHuman = {
+            show: true,
+            x: viewSize.width - digitalHumanSize.width,
+            y: viewSize.height - digitalHumanSize.height,
+            w: digitalHumanSize.width,
+            h: digitalHumanSize.height,
+            active: false,
+            host: selectHost.value
+          }
+
           let ppturl = item.pictureUrl
-          //鏄惁灞曠ず鑳屾櫙 濡傛灉灞曠ず鑳屾櫙锛屽垯鑳屾櫙绛変簬妯℃澘鑳屾櫙锛屽惁鍒欎负绌�
           if (selectTemplate.value.showBackground) {
             item.pictureUrl = selectTemplate.value.bgImage
           } else {
             item.pictureUrl = ''
           }
-          // 濡傛灉灞曠ず鑳屾櫙锛屽苟涓斿睍绀簆pt锛屽垯ppt鏀惧埌鐢讳腑鐢�
-          // console.log('selectTemplate',selectTemplate.value)
-          // console.log('selectTemplate.value.pptW',selectTemplate.value.pptW
-          // ,'selectTemplate.value.pptH',selectTemplate.value.pptH
-          // )
+
           if (item.pictureUrl && selectTemplate.value.showPpt) {
             item.innerPicture = {
               name: '鐢讳腑鐢�',
@@ -1161,9 +1074,7 @@
               entityType: 0,
               entityId: '0'
             }
-          }
-          //濡傛灉涓嶅睍绀鸿儗鏅紝鍒檖pt鏀惧埌鑳屾櫙锛岀敾涓敾涓虹┖
-          else if (!item.pictureUrl && selectTemplate.value.showPpt) {
+          } else if (!item.pictureUrl && selectTemplate.value.showPpt) {
             item.pictureUrl = ppturl
             item.innerPicture = {
               src: '',
@@ -1175,21 +1086,17 @@
               category: 1
             }
           }
-          // 鍒濆鍖栨槸鍚﹀睍绀烘暟瀛椾汉
-          item.showDigitalHuman = true
-          // 鏁板瓧浜轰綅缃拰灏哄涔熼渶瑕佺缉鏀�
-          console.log(selectTemplate.value)
-          PPTpositon.w = selectTemplate.value.humanW
-          PPTpositon.h = selectTemplate.value.humanH
-          PPTpositon.x = selectTemplate.value.humanX
-          PPTpositon.y = selectTemplate.value.humanY
         })
+
         PPTArr.value = res
-        console.log('PPTArr.value', PPTArr.value)
         PPTArr.value[0].isActive = true
         selectPPT.value = PPTArr.value[0]
         showLeftList.value = true
         clearInterval(schedulePPTTimer.value)
+
+        //ppt浜鸿劯鏍¢獙
+        PPtIsHaveFace()
+
         //杞淇濆瓨璇剧▼
         /**
          * 鍚庣鏁版嵁搴撳帇鍔涜繃澶э紝鏆傛椂鍋滄瀹氭椂淇濆瓨
@@ -1199,114 +1106,76 @@
     })
   }, 2000)
 }
-//瑙嗛鎬诲瓧鏁般�佹椂闀�
-const videoText = ref(0)
-const videoDuration = ref('')
-watch(
-  () => PPTArr.value,
-  (val) => {
-    if (!val) {
-      return
-    }
-    // 璁$畻鎬诲瓧鏁� - 淇敼涓哄幓闄SML鏍囩鍚庡啀璁$畻闀垮害
-    videoText.value = val.reduce((prev, curr) => {
-      if (!curr.pptRemark) return prev;
 
-      // 鍘婚櫎鎵�鏈塖SML鏍囩,鍙繚鐣欐枃鏈唴瀹�
-      const plainText = curr.pptRemark;
-      return prev + plainText.length;
-    }, 0)
-    //瑙嗛鏃堕暱鎹㈢畻
-    let videoTime = (videoText.value / 200) * 60
-    videoDuration.value = formateVideoTime(Math.ceil(videoTime))
-  },
-  { deep: true }
-)
-//瑙嗛鏃堕暱鎹㈢畻
-const formateVideoTime = (times: any) => {
-  let hours: any = parseInt(`${times / 60 / 60}`) // 璁$畻灏忔椂鏁�
-  let restMinutes: any = parseInt(`${(times / 60) % 60}`) // 鍒嗛挓鏁板彇浣欙紝寰楀埌鍓╀綑鍒嗛挓鏁�
-  let seconds: any = parseInt(`${times % 60}`) // 灏嗗墿浣欏垎閽熸暟杞崲涓虹鏁�
-  if (hours < 10) {
-    hours = '0' + hours
-  }
-  if (restMinutes < 10) {
-    restMinutes = '0' + restMinutes
-  }
-  if (seconds < 10) {
-    seconds = '0' + seconds
-  }
-  return hours + ':' + restMinutes + ':' + seconds
-}
-//鍙栨秷瑙f瀽ppt
 const cancelAnalyze = () => {
   showLeftList.value = true
   clearInterval(schedulePPTTimer.value)
 }
+
 const copyDocument = (item, index) => {
   ElMessageBox.confirm(
-    '鏄惁澶嶅埗杩欓〉PPT锛�',
+    '鏄惁澶嶅埗璇ラ〉闈紵',
     '鎻愮ず',
     {
       confirmButtonText: '鏄�',
       cancelButtonText: '鍚�',
       type: 'warning',
     }
-  )
-    .then(() => {
-      let copyItem = cloneDeep(item)
-      copyItem.id = generateUUID()
-      copyItem.isActive = false
-      PPTArr.value.splice(index + 1, 0, copyItem)
+  ).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: '宸插彇娑堝鍒�',
     })
-    .catch(() => {
-      ElMessage({
-        type: 'info',
-        message: '宸插彇娑堝鍒�',
-      })
-    })
-
+  })
 }
+
 const deleteDocument = (item) => {
   ElMessageBox.confirm(
-    '鏄惁鍒犻櫎杩欓〉PPT锛�',
+    '鏄惁鍒犻櫎璇ラ〉闈紵',
     '鎻愮ず',
     {
       confirmButtonText: '鏄�',
       cancelButtonText: '鍚�',
       type: 'warning',
     }
-  )
-      .then(() => {
-      PPTArr.value = PPTArr.value.filter((child) => child.id !== item.id)
-      }).catch(() => {
-      ElMessage({
-        type: 'info',
-        message: '宸插彇娑堝垹闄�',
-      })
+  ).then(() => {
+    PPTArr.value = PPTArr.value.filter((child) => child.id !== item.id)
+    //宸茬粡杩涜杩囧垹闄ゆ搷浣�
+    DeleteD.value = true
+  }).catch(() => {
+    ElMessage({
+      type: 'info',
+      message: '宸插彇娑堝垹闄�',
+    })
   })
+}
 
-}
 const deleteDigitalHuman = () => {
-  selectPPT.value.showDigitalHuman = false
+  selectPPT.value.digitalHuman.show = false
 }
-//鍒犻櫎鐢讳腑鐢�
+
 const deleteInnerPicture = () => {
   selectPPT.value.innerPicture.src = ''
 }
-//鍒犻櫎澶氫釜ppt
+
 const deleteMore = () => {
   let selected = PPTArr.value.filter((child) => child.isChecked == true)
   if (selected.length == 0) {
     message.warning('璇峰厛閫夋嫨瑕佸垹闄ょ殑ppt')
   } else {
-    let newPPTArr = PPTArr.value.filter((child) => child.isChecked !== true)
-    PPTArr.value = newPPTArr
+    PPTArr.value = PPTArr.value.filter((child) => child.isChecked !== true)
   }
 }
-/** 鏌ヨ鏁板瓧浜哄垪琛� */
-const hostList = ref()
-const loading = ref(true) // 鍒楄〃鐨勫姞杞戒腑
+
+const hostList = ref([])
+const loading = ref(true)
 const total = ref(0)
 const queryParams = reactive({
   pageNo: 1,
@@ -1315,6 +1184,9 @@
   gender: '',
   posture: ''
 })
+
+const selectHost = ref(null)
+
 const getList = async () => {
   loading.value = true
   try {
@@ -1322,94 +1194,85 @@
     queryParams.gender = tabs2ActiveNum.value
     queryParams.posture = tabs3ActiveNum.value
     queryParams.status = 0
+
     let data = await pptTemplateApi.pageList(queryParams)
-    //濡傛灉鏁板瓧浜哄垪琛� data涓虹┖ 鍒欏垏鎹ype鍐嶆煡璇竴娆�
+
     if (data.list.length == 0) {
       queryParams.type = tabs1ActiveNum.value == '0' ? '1' : '0'
       tabs1ActiveNum.value = queryParams.type
       data = await pptTemplateApi.pageList(queryParams)
       if (data.list.length == 0) {
-        //濡傛灉杩樻槸娌℃湁锛屽垯鎻愮ず娌℃湁鏈夋晥鐨勬暟瀛椾汉锛岃鑱旂郴绠$悊鍛�
         message.error('娌℃湁鏈夋晥鐨勬暟瀛椾汉锛岃鑱旂郴绠$悊鍛�')
         return
       }
     }
+
     data.list.forEach((item) => {
       item.isActive = false
     })
+
     hostList.value = data.list
-    humanId=hostList.value[0].id
-    selectHost.value = hostList.value[0]
-    // 鍒囨崲鏁板瓧浜哄Э鍔挎潯浠舵椂锛屼慨鏀规暟瀛椾汉鍦╬pt鐨勪綅缃�
-    initHumanPositon(selectHost.value)
+    if (hostList.value.length > 0 && !selectHost.value) {
+      selectHost.value = hostList.value[0]
+      // 鏇存柊褰撳墠閫変腑PPT鐨勬暟瀛椾汉
+      if (selectPPT.value) {
+        selectPPT.value.digitalHuman.host = selectHost.value
+      }
+    }
+
     total.value = data.total
   } finally {
     loading.value = false
   }
 }
+
 const choosePPt = (item) => {
   PPTArr.value.forEach((child) => {
-    if (child.id == item.id) {
-      child.isActive = true
-    } else {
-      child.isActive = false
-    }
+    child.isActive = child.id === item.id
   })
   selectPPT.value = item
 }
-const selectHost = ref() // 閫夋嫨鐨勬暟瀛椾汉
-const chooseHost = (item) => {
-  console.log(item)
-  //灏嗘暟瀛椾汉id鍙樻垚鍏ㄥ眬鍙橀噺
-  humanId=item.id
-  hostList.value.forEach((el) => {
-    if (el.id == item.id) {
-      el.isActive = true
-    } else {
-      el.isActive = false
-    }
-  })
-  selectHost.value = item
-  // 鐐瑰嚮鏁板瓧浜哄垪琛ㄤ腑鐨勫浘鍍忔椂锛屼慨鏀规暟瀛椾汉鍦╬pt鐨勪綅缃�
-  initHumanPositon(item)
-}
-// 鏍规嵁鏁板瓧浜虹殑涓嶅悓濮垮娍鍒濆鍖栧叾鍦╬pt鐨勪綅缃�
-const initHumanPositon = (data) => {
-  console.log(digitalHumanSize)
-  if (data.posture === 1) {
-    PPTpositon.x = viewSize.width - digitalHumanSize.width
-    PPTpositon.y = viewSize.height - digitalHumanSize.height
-    PPTpositon.w = digitalHumanSize.width
-    PPTpositon.h = digitalHumanSize.height
-  } else if (data.posture === 2) {
-    PPTpositon.x = viewSize.width - digitalHumanSize.width
-    PPTpositon.y = viewSize.height - digitalHumanSize.height
-    PPTpositon.w = digitalHumanSize.width
-    PPTpositon.h = digitalHumanSize.height
+
+// const chooseHost = (item) => {
+//   hostList.value.forEach((el) => {
+//     el.isActive = el.id === item.id
+//   })
+//
+//   // 鍙洿鏂板綋鍓嶉�変腑鐨凱PT椤电殑鏁板瓧浜�
+//   if (selectPPT.value) {
+//     selectPPT.value.digitalHuman.host = item
+//     initHumanPositon(item, selectPPT.value.digitalHuman)
+//   }
+// }
+
+const initHumanPositon = (hostData, digitalHuman) => {
+  if (hostData.posture === 1) {
+    digitalHuman.x = viewSize.width - digitalHuman.w
+    digitalHuman.y = viewSize.height - digitalHuman.h
+  } else if (hostData.posture === 2) {
+    digitalHuman.x = viewSize.width - digitalHuman.w
+    digitalHuman.y = viewSize.height - digitalHuman.h
   }
 }
-//鎵撳紑寮规
+
 const audioSelect = ref()
 const audioSelectData = ref()
+
 const openSelect = () => {
   audioSelect.value.open()
 }
+
 const selectAudio = (data) => {
-  console.log(data)
   audioSelectData.value = data
-  // selectPPT.value.selectAudio = data[0]
-  // 閬嶅巻鎵�鏈夊満鏅紝搴旂敤鐩稿悓鐨勫0闊虫ā鍨�
-  if (data==undefined){
-    selectPPT.value.selectAudio.name=''
-    return {}
-  }else {
+  if (data == undefined) {
+    selectPPT.value.selectAudio.name = ''
+  } else {
     PPTArr.value.forEach((scene) => {
       scene.selectAudio = data[0]
     })
   }
-
 }
-//鐢熸垚璇剧▼id
+
 const coursesCreate = () => {
   const params = {
     accountId: userId.value
@@ -1421,41 +1284,23 @@
   })
 }
 
-
-//ppt浜鸿劯鏍¢獙
-const PPtIsHaveFace = async ()=>{
-  //娣诲姞ppt涓汉鑴告牎楠�
-  //鍚戝師濮媝pt娣诲姞鏁版嵁锛岀敤浣滃悗缁璸pt涓槸鍚﹀寘鍚汉鑴哥殑鏁版嵁鏍¢獙鍘熷鏁版嵁
-  const InitPpt = PPTArr.value.map( (item)=>{
-      return item.innerPicture.src
-  } )
-  const { detectFacesInImages } = useFaceDetection()
-  const IsHaveFace = await detectFacesInImages(InitPpt)
-  return IsHaveFace
-}
-
-
-//鑾峰彇淇濆瓨鏃堕棿
 const saveTime = ref()
+
 const getSaveTime = () => {
   const date = new Date()
-  let h: any = date.getHours() //hour
-  let m: any = date.getMinutes() //minute
-  let s: any = date.getSeconds() //second
-  if (h < 10) {
-    h = '0' + h
-  }
-  if (m < 10) {
-    m = '0' + m
-  }
-  if (s < 10) {
-    s = '0' + s
-  }
+  let h: any = date.getHours()
+  let m: any = date.getMinutes()
+  let s: any = date.getSeconds()
+
+  if (h < 10) h = '0' + h
+  if (m < 10) m = '0' + m
+  if (s < 10) s = '0' + s
+
   return h + ':' + m + ':' + s
 }
+
 const warningDialog = ref()
 
-// 璇�� 闊抽噺
 const voiceData = reactive({
   show: false,
   speechRate: 1,
@@ -1473,31 +1318,32 @@
     2: '2'
   }
 })
-const removeHtmlTags= (html) =>{
-  const parser = new DOMParser();
-  const doc = parser.parseFromString(html, 'text/html');
-  return doc.body.textContent || "";
+
+const removeHtmlTags = (html) => {
+  const parser = new DOMParser()
+  const doc = parser.parseFromString(html, 'text/html')
+  return doc.body.textContent || ""
 }
 
-//浼犲叆 save 鍒欎唬琛ㄤ繚瀛橈紝绌哄瓧绗︿紶鍒欐槸鍚堟垚瑙嗛
 const saveSubmit = async (type) => {
-  if( type.length === 0 ){
-    //姝ゆ椂涓鸿棰戝悎鎴�
-    MakeLoading.value = true
-    SaveLoading.value = true
-  }else{
-    //姝ゆ椂涓轰繚瀛�
-    SaveLoading.value = true
-  }
 
-  // 妫�鏌ュ満鏅槸鍚︿负绌�
+  console.log( "鏄惁鍒犻櫎", DeleteD.value )
+
   if (!PPTArr.value || PPTArr.value.length === 0) {
     message.warning('鍦烘櫙涓虹┖锛岃鍏堜笂浼燩PT锛�')
-    //鍏抽棴瑙嗛鍚堟垚涓庝繚瀛樻寜閽殑loading鍔ㄧ敾
-    MakeLoading.value = false
-    SaveLoading.value = false
     return false
   }
+  
+
+  //浜鸿劯鏍¢獙
+  while(!IsEndCheckFace.value){} //涓�涓┖寰幆锛屼富瑕佷负浜嗛伩鍏嶆瀬绔儏鍐典笅褰撶敤鎴风偣鍑讳繚瀛樻寜閽垨鑰呰棰戝悎鎴愭寜閽椂锛屼汉鑴告牎楠屾湭瀹屾垚鐨勯棶棰�
+  if( IsHaveFace.value && !DeleteD.value ){
+    message.warning('褰撳墠ppt涓瓨鍦ㄤ汉鑴稿厓绱狅紝涓烘柟渚垮悗缁棰戠敓鎴愶紝璇峰幓闄よ鍏冪礌')
+    return
+  }
+
+
+
   //淇濆瓨璇剧▼
   let saveSubmitForm = {
     accountId: courseInfo.value.accountId,
@@ -1515,675 +1361,201 @@
     thumbnail: '',
     subtitlesStyle: '{}'
   }
-  // if(type == "save"){
-  Reflect.set(saveSubmitForm, 'id', courseInfo.value.id)
-  // }else{
-  //   Reflect.set(saveSubmitForm, "courseMediaId", courseInfo.value.id);
-  // }
 
-  //缁勮鏁版嵁
-  const scenes: any = []
+  saveSubmitForm.id = courseInfo.value.id
+
+  const scenes = []
   const pageInfo = {
     docInfo: {
       docType: 1,
       fileName: uploadFileObj.filename,
       fileSize: uploadFileObj.size
     },
-    scenes: [] as any[]
+    scenes: []
   }
+
   let thumbnail = ''
-  const { name, pictureUrl, code, type: digitalHumanType } = selectHost.value // 瑙f瀯浠ラ伩鍏嶅惊鐜紩鐢�
-  const digitalHumanComponents = {
-    name,
-    src: pictureUrl,
-    cover: pictureUrl,
-    width: PPTpositon.w * scaleRatio.value.width,
-    height: PPTpositon.h * scaleRatio.value.height,
-    originWidth: PPTpositon.w * scaleRatio.value.width,
-    originHeight: PPTpositon.h * scaleRatio.value.height,
-    category: 2, // 1: PPT, 2: 鏁板瓧浜�, 3: 鍏朵粬
-    depth: componentsInfo.depth,
-    top: PPTpositon.y * scaleRatio.value.height,
-    marginLeft: PPTpositon.x * scaleRatio.value.width,
-    entityId: code,
-    entityType: digitalHumanType, // 濡傛灉鏄暟瀛椾汉锛屽垯鏄暟瀛椾汉绫诲瀷 0: 鏅��, 1: 涓撳睘
-    businessId: generateUUID(),
-    digitbotType: tabs1ActiveNum.value,
-    matting: 1,
-    marker: 1
-  }
-  let pageNum = 1
-  if (PPTArr.value && PPTArr.value.length > 0) {
-    console.log('寮�濮嬪鐞哖PTArr鏁版嵁')
-    PPTArr.value.forEach((item, index) => {
-      console.log(`澶勭悊绗� ${index + 1} 涓満鏅痐)
-      try {
-        pageInfo.scenes.push(item.businessId)
-        if (pageNum == 1) {
-          thumbnail = item.pictureUrl
-          pageNum++
-        }
-        console.log(item)
 
-        const innerPictureCom = item.innerPicture
-        console.log('innerPictureCom:', JSON.stringify(innerPictureCom))
-        item.pptRemark = removeHtmlTags(item.pptRemark)
-        // item.pptRemark = editorRef.value.getText()
-        // item.pptRemark=item.pptRemark.replace(/<[^>]+>/g, '')
-        const formatItem = {
-          background: {
-            backgroundType: item.backgroundType,
-            entityId: '',
-            width: courseInfo.value.width,
-            height: courseInfo.value.height,
-            depth: 0,
-            src: item.pictureUrl,
-            cover: item.pictureUrl,
-            originWidth: item.width,
-            originHeight: item.height,
-            color: '#ffffff',
-            pptRemark: item.pptRemark
-          },
-          hasPerson: item.showDigitalHuman==true? 1 : 2,
-          components: [
-            {
-              ...cloneDeep(digitalHumanComponents), // 娣辨嫹璐�
-              status: item.showDigitalHuman ? 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
-                  }
-                ]
-              : [])
-          ],
-          driverType: item.driverType,
-          duration: '',
-          orderNo: index + 1,
-          textDriver: {
-            pitch: '',
-            speed: '',
-            speech_rate: voiceData.speechRate,
-            volume: voiceData.volume,
-            smartSpeed: '',
-            textJson: item.pptRemark,
-          },
-          audioDriver: {
-            fileName: item.fileList && item.fileList[0]?.name,
-            audioId: '',
-            audioUrl: item.uploadAudioUrl,
-            useVideoBackgroundAudio: ''
-          },
-          voice: {
-            voiceId:audioSelectData.value == undefined ? null : audioSelectData.value[0].id,
-            entityId: item.selectAudio && item.selectAudio.code,
-            tonePitch: '',
-            voiceType: item.selectAudio && item.selectAudio.voiceType,
-            speechRate: '',
-            name: item.selectAudio && item.selectAudio.name
-          },
-          businessId: item.businessId
-        }
-        scenes.push(formatItem)
-      } catch (error) {
-        console.error(`澶勭悊绗� ${index + 1} 涓満鏅椂鍑洪敊:`, error)
-        //鍏抽棴瑙嗛鍚堟垚涓庝繚瀛樻寜閽殑loading鍔ㄧ敾
-        MakeLoading.value = false
-        SaveLoading.value = false
-        //鎶涘嚭寮傚父
-        throw error
+  PPTArr.value.forEach((item, index) => {
+    try {
+      pageInfo.scenes.push(item.businessId)
+      if (index === 0) {
+        thumbnail = item.pictureUrl
       }
-    })
-  }
 
-  try {
-    saveSubmitForm.pageInfo = JSON.stringify(pageInfo)
-    saveSubmitForm.thumbnail = thumbnail
-    saveSubmitForm.scenes = cloneDeep(scenes)
-    console.log('saveSubmitForm:', cloneDeep(saveSubmitForm))
-  } catch (error) {
-    //鍏抽棴瑙嗛鍚堟垚涓庝繚瀛樻寜閽殑loading鍔ㄧ敾
-    MakeLoading.value = false
-    SaveLoading.value = false
-    console.error('淇濆瓨琛ㄥ崟鏁版嵁鏃跺嚭閿�:', error)
-  }
+      item.pptRemark = removeHtmlTags(item.pptRemark)
+
+      const formatItem = {
+        background: {
+          backgroundType: item.backgroundType,
+          entityId: '',
+          width: courseInfo.value.width,
+          height: courseInfo.value.height,
+          depth: 0,
+          src: item.pictureUrl,
+          cover: item.pictureUrl,
+          originWidth: item.width,
+          originHeight: item.height,
+          color: '#ffffff',
+          pptRemark: item.pptRemark
+        },
+        hasPerson: item.digitalHuman?.show ? 1 : 2,
+        components: [
+          {
+            name: item.digitalHuman?.host?.name,
+            src: item.digitalHuman?.host?.pictureUrl,
+            cover: item.digitalHuman?.host?.pictureUrl,
+            width: item.digitalHuman?.w * scaleRatio.value.width,
+            height: item.digitalHuman?.h * scaleRatio.value.height,
+            originWidth: item.digitalHuman?.w * scaleRatio.value.width,
+            originHeight: item.digitalHuman?.h * scaleRatio.value.height,
+            category: 2,
+            depth: 0,
+            top: item.digitalHuman?.y * scaleRatio.value.height,
+            marginLeft: item.digitalHuman?.x * scaleRatio.value.width,
+            entityId: item.digitalHuman?.host?.code,
+            entityType: item.digitalHuman?.host?.type,
+            businessId: generateUUID(),
+            digitbotType: tabs1ActiveNum.value,
+            matting: 1,
+            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
+          }] : [])
+        ],
+        driverType: item.driverType,
+        duration: '',
+        orderNo: index + 1,
+        textDriver: {
+          pitch: '',
+          speed: '',
+          speech_rate: voiceData.speechRate,
+          volume: voiceData.volume,
+          smartSpeed: '',
+          textJson: item.pptRemark,
+        },
+        audioDriver: {
+          fileName: item.fileList && item.fileList[0]?.name,
+          audioId: '',
+          audioUrl: item.uploadAudioUrl,
+          useVideoBackgroundAudio: ''
+        },
+        voice: {
+          voiceId: audioSelectData.value == undefined ? null : audioSelectData.value[0].id,
+          entityId: item.selectAudio && item.selectAudio.code,
+          tonePitch: '',
+          voiceType: item.selectAudio && item.selectAudio.voiceType,
+          speechRate: '',
+          name: item.selectAudio && item.selectAudio.name
+        },
+        businessId: item.businessId
+      }
+
+      scenes.push(formatItem)
+    } catch (error) {
+      console.error(`澶勭悊绗� ${index + 1} 涓満鏅椂鍑洪敊:`, error)
+      throw error
+    }
+  })
+
+  saveSubmitForm.pageInfo = JSON.stringify(pageInfo)
+  saveSubmitForm.thumbnail = thumbnail
+  saveSubmitForm.scenes = cloneDeep(scenes)
+
   if (type == 'save') {
-    //鍙嶆鎬庝箞璧伴兘浼氳蛋save杩欎竴姝ワ紝閭e氨鍙湪杩欎竴姝ヨ繘琛屼竴娆′汉鑴告牎楠岋紝濡傛灉鍚庣画鍚堟垚瑙嗛鎸夐挳涓嶅啀璧颁繚瀛橈紝璇峰皢杩欎竴姝ヤ篃涓�骞惰繘琛屾洿鏀�
-    //涓昏鍥犱负wangEditor杩囦簬鏁忔劅
-    const isHaveFace = await PPtIsHaveFace()
-    if( isHaveFace ){
-      message.warning('褰撳墠ppt涓寘鍚汉鑴稿厓绱�, 涓烘柟渚垮悗缁棰戠敓鎴� ,璇峰幓闄よ鍏冪礌')
-      //鍏抽棴瑙嗛鍚堟垚涓庝繚瀛樻寜閽殑loading鍔ㄧ敾
-      MakeLoading.value = false
-      SaveLoading.value = false
-      return false
+
+    if( DeleteD.value ){
+      //濡傛灉杩涜杩噋pt鍒犻櫎鎿嶄綔鍒欓渶瑕佽繘琛屼簩娆℃煡鐪�
+      await PPtIsHaveFace()
+      if( IsHaveFace.value ){
+          message.warning('褰撳墠ppt涓瓨鍦ㄤ汉鑴稿厓绱狅紝涓烘柟渚垮悗缁棰戠敓鎴愶紝璇峰幓闄よ鍏冪礌')
+          return
+      }
     }
 
     try {
-      const res = await pptTemplateApi.coursesSave(stringifySafely(saveSubmitForm))
+      const res = await pptTemplateApi.coursesSave(JSON.stringify(saveSubmitForm))
       if (res) {
         message.success('淇濆瓨鎴愬姛锛�')
         saveTime.value = getSaveTime()
-        MakeLoading.value = false
-        SaveLoading.value = false
-        return true // 杩斿洖淇濆瓨鎴愬姛鏍囧織
+        return true
       }
       return false
     } catch (error) {
       console.error('淇濆瓨璇剧▼鏃跺嚭閿�:', error)
       message.error('淇濆瓨澶辫触锛岃閲嶈瘯')
-      //鍏抽棴瑙嗛鍚堟垚涓庝繚瀛樻寜閽殑loading鍔ㄧ敾
-      MakeLoading.value = false
-      SaveLoading.value = false
       return false
     }
-
   } else {
-    // 鍚堟垚瑙嗛鍓嶅厛淇濆瓨
     try {
       const saveResult = await saveSubmit('save')
       if (!saveResult) {
         message.error('淇濆瓨澶辫触锛岃閲嶈瘯鍚庡啀鍚堟垚瑙嗛')
-        //鍏抽棴瑙嗛鍚堟垚涓庝繚瀛樻寜閽殑loading鍔ㄧ敾
-        MakeLoading.value = false
-        SaveLoading.value = false
         return
       }
-      // 鏍¢獙鍦烘櫙鏁版嵁
-      let warningStrArr: any = []
+
+      let warningStrArr = []
       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 )
         // 鏍¢獙鑳屾櫙瀹介珮
         if (!item.width || !item.height) {
           message.warning('鑳屾櫙灏哄鏃犳晥锛岃妫�鏌ュ楂樿缃紝鎴栬�呴噸鏂伴�夋嫨妯℃澘')
-          //鍏抽棴瑙嗛鍚堟垚涓庝繚瀛樻寜閽殑loading鍔ㄧ敾
-          MakeLoading.value = false
-          SaveLoading.value = false
           return
         }
         if (item.driverType == 1) {
-          // 鍘婚櫎鎵�鏈塇TML鏍囩鍜孲SML鏍囩鍚庡啀鍒ゆ柇鍐呭鏄惁涓虹┖
           const plainText = item.pptRemark ? item.pptRemark.replace(/<[^>]+>/g, '') : ''
           if (!plainText || plainText.trim() === '') {
             warningStrArr.push(
               `鍦烘櫙<span style="color: red; font-weight: bold;">${i + 1}</span>鏃犳湁鏁堢殑鍙f挱鍐呭`
             )
-          }
-          else {
-            //鍒ゆ柇鍘婚櫎鏍囩鍚庣殑鍐呭闀垮害鏄惁瓒呰繃2000瀛�
-            if (plainText.length > 2000) {
-              warningStrArr.push(
-                `鍦烘櫙<span style="color: red; font-weight: bold;">${i + 1}</span>鍙f挱鍐呭瓒呰繃2000瀛楋紝璇峰噺灏戞垨鎷嗗垎鍦烘櫙`
-              )
-            }
+          } else if (plainText.length > 2000) {
+            warningStrArr.push(
+              `鍦烘櫙<span style="color: red; font-weight: bold;">${i + 1}</span>鍙f挱鍐呭瓒呰繃2000瀛楋紝璇峰噺灏戞垨鎷嗗垎鍦烘櫙`
+            )
           }
         }
       }
+
       if (warningStrArr.length > 0) {
         warningDialog.value.open(warningStrArr.map((warning) => `<div>${warning}</div>`).join(''))
-        //鍏抽棴瑙嗛鍚堟垚涓庝繚瀛樻寜閽殑loading鍔ㄧ敾
-        MakeLoading.value = false
-        SaveLoading.value = false
         return
       }
-      // 鍚堟垚瑙嗛
+
       try {
         const res = await pptTemplateApi.megerMedia(saveSubmitForm)
         if (res) {
-          //鍏抽棴瑙嗛鍚堟垚涓庝繚瀛樻寜閽殑loading鍔ㄧ敾
-          MakeLoading.value = false
-          SaveLoading.value = false
           message.success('鍚堟垚瑙嗛浠诲姟鎻愪氦鎴愬姛锛岃鍒版垜鐨勮棰戜腑鏌ョ湅锛�')
         }
       } catch (error) {
-        //鍏抽棴瑙嗛鍚堟垚涓庝繚瀛樻寜閽殑loading鍔ㄧ敾
-        MakeLoading.value = false
-        SaveLoading.value = false
         console.error('鍚堟垚瑙嗛澶辫触:', error)
         message.error('鍚堟垚瑙嗛澶辫触锛岃閲嶈瘯')
       }
     } catch (error) {
-      //鍏抽棴瑙嗛鍚堟垚涓庝繚瀛樻寜閽殑loading鍔ㄧ敾
-      MakeLoading.value = false
-      SaveLoading.value = false
       console.error('淇濆瓨鎴栧悎鎴愯繃绋嬪嚭閿�:', error)
       message.error('鎿嶄綔澶辫触锛岃閲嶈瘯')
     }
   }
-
-}
-
-function stringifySafely(obj) {
-  const seen = new WeakSet()
-  return JSON.stringify(obj, (key, value) => {
-    if (typeof value === 'object' && value !== null) {
-      if (seen.has(value)) {
-        return // 寰幆寮曠敤鏃惰繑鍥� undefined
-      }
-      seen.add(value)
-    }
-    return value
-  })
-}
-//瀹氭椂淇濆瓨
-// const saveTimer = ref()
-// const saveInter = () => {
-//   if (saveTimer.value) {
-//     clearInterval(saveTimer.value)
-//   }
-//   saveTimer.value = setInterval(() => {
-//     saveSubmit('save')
-//   }, 60000)
-// }
-//鐢熸垚璇曞惉
-const showAudioPlay = ref(false) //鏄剧ず璇曞惉
-const showAudioPlay1 = ref(false) //鏄剧ず璇曞惉
-//鏄剧ず澹伴煶椹卞姩鐨勬枃浠舵挱鏀惧脊妗�
-const startAudioPlay = ref(false)
-const textareaRef = ref()
-const selectTextarea = ref('')
-//涓婁紶闊抽鏂囦欢瓒呭嚭闄愬埗鍚庣殑鎻愮ず
-const audioExceed = () => {
-  message.warning('鏈�澶氫笂浼犱竴涓0闊抽┍鍔ㄦ枃浠讹紒')
-}
-const currentAudio = ref()
-
-const handlePptRemarkSelection = () => {
-  if (textareaRef.value) {
-    const textarea = textareaRef.value.$el.querySelector('textarea')
-    if (textarea) {
-      // 浣跨敤浜嬩欢瀵硅薄涓殑閫変腑鏂囨湰
-      selectTextarea.value = textarea.value.substring(textarea.selectionStart, textarea.selectionEnd)
-      console.log('閫変腑鐨勬枃鏈�:', selectTextarea.value)
-    }
-  }
-}
-
-//瀵屾枃鏈紪杈戝櫒  -start
-// 缂栬緫鍣ㄥ疄渚嬶紝蹇呴』鐢� shallowRef
-const editorRef = shallowRef()
-const editorConfig = { placeholder: '璇疯緭鍏ュ唴瀹�...' }
-const handleCreated = (editor) => {
-    editorRef.value = editor // editor 瀹炰緥
-}
-//鍋滈】
-const handleBreak = (e) => {
-    //鑺傜偣鎻掑叆
-    const node = {
-        type: 'title-black',
-        children: [{ text: e }]
-    }
-    editorRef.value.restoreSelection() // 鎭㈠閫夊尯
-    editorRef.value.insertNode(node);
-    editorRef.value.move(1);
-}
-//鏁板瓧
-const handleNumber = (e) => {
-    editorRef.value.focus()
-    selectTextarea.value = editorRef.value.getSelectionText()
-    let reg = /^\d+$/
-    if (!selectTextarea.value || selectTextarea.value.length == 0 || !reg.test(selectTextarea.value)) {
-      message.warning('璇峰厛閫変腑闇�鎸囧畾璇绘硶鐨勬暟瀛�')
-        return false
-    }
-    //鑺傜偣鎻掑叆
-    const node = {
-        type: 'number-value',
-        numberVal: selectTextarea.value,
-        children: [{ text: e }]
-    }
-    editorRef.value.restoreSelection() // 鎭㈠閫夊尯
-    editorRef.value.insertNode(node);
-    editorRef.value.move(1);
-}
-//澶氶煶瀛�
-const dialogVisible = ref(false)
-const textList = ref([])
-const handleWord = () => {
-    editorRef.value.focus()
-    selectTextarea.value = editorRef.value.getSelectionText()
-    if (!selectTextarea.value) {
-      message.warning('璇峰厛閫変腑闇�鎸囧畾璇绘硶鐨勬枃鏈�')
-        return false
-    }
-    if (selectTextarea.value.length > 1) {
-      message.warning('鍙兘閫夋嫨涓�涓瓧')
-        return false
-    }
-    let textPinyin = polyphonic(selectTextarea.value, { toneType: 'num', type: 'array' })[0];
-    if (textPinyin.length > 1) {
-        textList.value = textPinyin;
-        dialogVisible.value = true
-    } else {
-      message.warning(`${selectTextarea.value}涓嶆槸澶氶煶瀛梎)
-    }
-}
-const handleTag = (name) => {
-    dialogVisible.value = false
-    //鑺傜偣鎻掑叆
-    const node = {
-        type: 'text-value',
-        textVal: selectTextarea.value,
-        children: [{ text: name }]
-    }
-    editorRef.value.restoreSelection() // 鎭㈠閫夊尯
-    editorRef.value.insertNode(node);
-    editorRef.value.move(1);
-}
-const createAudio = async () => {
-  // 鑾峰彇缂栬緫鍣ㄦ枃鏈唴瀹�
-  const text = editorRef.value.getText();
-
-  // 妫�鏌ユ枃鏈槸鍚︿负绌�
-  if (!text) {
-    message.warning('璇疯緭鍏ラ渶瑕佽瘯鍚枃鏈殑鍐呭鈥�');
-    return false;
-  }
-
-  // 鎴彇鏂囨湰闀垮害涓嶈秴杩� 100
-  const truncatedText = text.length > 100 ? text.substring(0, 100) : text;
-  console.log(audioSelectData.value)
-  if (audioSelectData.value == undefined) {
-    const params = {
-      text: truncatedText,
-      humanId: humanId,
-      voiceId: null,
-    };
-    try {
-      // 鏄剧ず闊抽鎾斁鍔犺浇鐘舵��
-      showAudioPlay1.value = true;
-
-      // 璋冪敤 API 鍒涘缓闊抽
-      const res = await pptTemplateApi.createAudio(params);
-
-      // 妫�鏌ュ搷搴旀槸鍚︽湁鏁堜笖鏃犻敊璇�
-      if (res && !res.error) {
-        console.log(res);
-        // 闅愯棌鍔犺浇鐘舵�侊紝鏄剧ず闊抽鎾斁鐘舵��
-        showAudioPlay1.value = false;
-        showAudioPlay.value = true;
-
-        // 鍒濆鍖� Audio 瀵硅薄
-        currentAudio.value = new Audio(res);
-
-        // 娣诲姞鎾斁缁撴潫浜嬩欢鐩戝惉鍣�
-        currentAudio.value.addEventListener('ended', () => {
-          showAudioPlay.value = false;
-          currentAudio.value = null;
-        });
-
-        // 鎾斁闊抽
-        currentAudio.value.play();
-      } else {
-        // 鍝嶅簲鏃犳晥鎴栨湁閿欒锛岄殣钘忓姞杞界姸鎬�
-        showAudioPlay1.value = false;
-      }
-    } catch (error) {
-      // 鎹曡幏璇锋眰閿欒锛岄殣钘忓姞杞界姸鎬佸苟鎵撳嵃閿欒淇℃伅
-      console.error('API 璇锋眰澶辫触锛�', error);
-      showAudioPlay1.value = false;
-    }
-  }else {
-    const params = {
-      text: truncatedText,
-      humanId: null,
-      voiceId: audioSelectData.value[0].id,
-    };
-    try {
-      // 鏄剧ず闊抽鎾斁鍔犺浇鐘舵��
-      showAudioPlay1.value = true;
-
-      // 璋冪敤 API 鍒涘缓闊抽
-      const res = await pptTemplateApi.createAudio(params);
-
-      // 妫�鏌ュ搷搴旀槸鍚︽湁鏁堜笖鏃犻敊璇�
-      if (res && !res.error) {
-        console.log(res);
-        // 闅愯棌鍔犺浇鐘舵�侊紝鏄剧ず闊抽鎾斁鐘舵��
-        showAudioPlay1.value = false;
-        showAudioPlay.value = true;
-
-        // 鍒濆鍖� Audio 瀵硅薄
-        currentAudio.value = new Audio(res);
-
-        // 娣诲姞鎾斁缁撴潫浜嬩欢鐩戝惉鍣�
-        currentAudio.value.addEventListener('ended', () => {
-          showAudioPlay.value = false;
-          currentAudio.value = null;
-        });
-
-        // 鎾斁闊抽
-        currentAudio.value.play();
-      } else {
-        // 鍝嶅簲鏃犳晥鎴栨湁閿欒锛岄殣钘忓姞杞界姸鎬�
-        showAudioPlay1.value = false;
-      }
-    } catch (error) {
-      // 鎹曡幏璇锋眰閿欒锛岄殣钘忓姞杞界姸鎬佸苟鎵撳嵃閿欒淇℃伅
-      console.error('API 璇锋眰澶辫触锛�', error);
-      showAudioPlay1.value = false;
-    }
-  }
-  // 鏋勫缓璇锋眰鍙傛暟
-
-
-
-}
-//鍙栨秷璇曞惉
-const pauseAudio = () => {
-  currentAudio.value.pause()
-  currentAudio.value = null
-  showAudioPlay.value = false
-}
-//澹伴煶椹卞姩鐨勬枃浠�
-const currentAudioFile = ref()
-//澹伴煶椹卞姩鐨勬枃浠舵挱鏀�
-const audioPlay = (file) => {
-  // 纭繚 file.response.data 鏄竴涓湁鏁堢殑 URL
-  if (!file.response.data) {
-    message.error('鏈幏鍙栧埌鏂囦欢')
-    return
-  }
-  // 鍋滄褰撳墠鎾斁鐨勯煶棰戯紙濡傛灉瀛樺湪锛�
-  if (currentAudioFile.value) {
-    currentAudioFile.value.pause()
-    currentAudioFile.value.currentTime = 0 // 閲嶇疆鎾斁浣嶇疆
-  }
-
-  // 鍒涘缓鏂扮殑 Audio 瀹炰緥
-  const audio = new Audio(file.response.data)
-  currentAudioFile.value = audio
-
-  // 鐩戝惉鎾斁缁撴潫浜嬩欢
-  audio.addEventListener('ended', () => {
-    cancelAudio()
-  })
-
-  // 寮�濮嬫挱鏀�
-  startAudioPlay.value = true
-  audio.play()
-}
-//鍙栨秷澹伴煶椹卞姩鐨勬枃浠舵挱鏀�
-const cancelAudio = () => {
-  if (currentAudioFile.value) {
-    currentAudioFile.value.pause()
-    // 鍙�夛細閲嶇疆鎾斁浣嶇疆
-    currentAudioFile.value.currentTime = 0
-    currentAudioFile.value = null
-  }
-  startAudioPlay.value = false
-}
-//杩斿洖
-const goBack = () => {
-  console.log(PPTArr.value,courseInfo.value.id)
-  if (!PPTArr.value) {
-  //  鍒犻櫎褰撳墠璇剧▼
-    pptTemplateApi.coursesDelete(courseInfo.value.id).then((res) => {
-      console.log(res)
-    })
-  }
-  router.go(-1)
-}
-const getCourseDetail = (id) => {
-  pptTemplateApi.coursesDetail(id).then((res) => {
-    console.log(res)
-    if (res) {
-      //鍥炴樉鏁版嵁澶勭悊
-      // 璇剧▼鍩烘湰淇℃伅
-      courseInfo.value = res
-      if (res.scenes && res.scenes.length > 0) {
-        //宸︿晶鏁版嵁鍒楄〃
-        res.scenes.forEach((item) => {
-          item.isActive = false
-          item.isChecked = false
-          item.pictureUrl = item.background.src
-          item.pptRemark = editorHtml.parseElemHtml(item.background.pptRemark);
-          item.backgroundType = item.background.backgroundType
-          item.width = item.background.width
-          item.height = item.background.height
-          item.showDigitalHuman = item.components.find((p) => p.category == 2).status == 0 //鏍规嵁鏁板瓧浜烘ā鏉跨殑status鍒ゆ柇鏄惁鏄剧ず鏁板瓧浜�
-          // 鐢讳腑鐢讳綅缃拰灏哄缂╁皬
-          const innerPicture = item.components.find((p) => p.category == 1)
-          if (innerPicture) {
-            item.innerPicture = {
-              ...innerPicture,
-              width: innerPicture.width / scaleRatio.value.width,
-              height: innerPicture.height / scaleRatio.value.height,
-              top: innerPicture.top / scaleRatio.value.height,
-              marginLeft: innerPicture.marginLeft / scaleRatio.value.width
-            }
-          }
-        })
-        PPTArr.value = res.scenes
-        PPTArr.value[0].isActive = true
-        selectPPT.value = PPTArr.value[0]
-        console.log('getCourseDetail selectPPT.value:', selectPPT.value)
-        // selectPPT.value.uploadAudioUrl = PPTArr.value[0].audioDriver?.audioUrl;
-        // selectPPT.value.selectAudio = PPTArr.value[0].voice;
-        // 閬嶅巻鎵�鏈夊満鏅紝搴旂敤鐩稿悓鐨勫0闊虫ā鍨�
-        PPTArr.value.forEach((scene, index) => {
-          //濡傛灉res.scenes[index] 鏈塿oice涓斾笉涓虹┖
-          if (res.scenes[index].voice) {
-            scene.selectAudio = res.scenes[index].voice
-            scene.selectAudio.code = res.scenes[index].voice.entityId
-            scene.selectAudio.id = res.scenes[index].voice.voiceId
-          }
-          scene.uploadAudioUrl = res.scenes[index].audioDriver?.audioUrl
-        })
-        if (PPTArr.value[0].audioDriver?.fileName && PPTArr.value[0].audioDriver?.audioUrl) {
-          selectPPT.value.fileList = [
-            {
-              name: PPTArr.value[0].audioDriver?.fileName,
-              url: PPTArr.value[0].audioDriver?.audioUrl
-            }
-          ]
-        }
-        //閫夋嫨鐨勬暟瀛椾汉淇℃伅
-        const hostInfo = res.scenes[0].components.find((component) => component.category === 2)
-        // 鍏堝湪褰撳墠鏁板瓧浜哄垪琛ㄤ腑鏌ユ壘
-        let foundHost = hostList.value.find(item => item.code === hostInfo.entityId)
-
-        // 濡傛灉鍦ㄥ綋鍓嶅垪琛ㄤ腑娌℃壘鍒�,涓斿綋鍓嶆槸鍏叡鏁板瓧浜哄垪琛�,鍒欏垏鎹㈠埌鎴戠殑鏁板瓧浜哄垪琛ㄩ噸鏂拌幏鍙�
-        if (!foundHost && tabs1ActiveNum.value === '0') {
-          // 淇濆瓨鍏叡鏁板瓧浜哄垪琛ㄧ殑绗竴涓暟瀛椾汉浣滀负榛樿鍊�
-          const defaultPublicHost = hostList.value[0]
-
-          // 鍒囨崲鍒�"鎴戠殑"鏁板瓧浜�
-          tabs1ActiveNum.value = '1'
-          // 閲嶆柊鑾峰彇鏁板瓧浜哄垪琛�
-          getList().then(() => {
-            // 鍦ㄦ柊鍒楄〃涓煡鎵�
-            foundHost = hostList.value.find(item => item.code === hostInfo.entityId)
-
-            // 濡傛灉鍦�"鎴戠殑"鏁板瓧浜轰腑涔熸病鎵惧埌,鍒欎娇鐢ㄩ粯璁ゅ叕鍏辨暟瀛椾汉
-            if (!foundHost) {
-              tabs1ActiveNum.value = '0' // 鍒囧洖鍏叡鏁板瓧浜簍ab
-              foundHost = defaultPublicHost // 浣跨敤涔嬪墠淇濆瓨鐨勯粯璁ゅ叕鍏辨暟瀛椾汉
-              message.warning('鏈壘鍒板師鏁板瓧浜�,宸蹭娇鐢ㄩ粯璁ゅ叕鍏辨暟瀛椾汉鏇夸唬')
-            }
-
-            // 璁剧疆閫変腑鐨勬暟瀛椾汉
-            selectHost.value = foundHost || hostList.value[0]
-          })
-        } else {
-          // 璁剧疆閫変腑鐨勬暟瀛椾汉
-          selectHost.value = foundHost || hostList.value[0]
-        }
-
-        // 璁剧疆閫変腑鐨勬暟瀛椾汉
-        selectHost.value = foundHost || hostList.value[0]
-        if (hostInfo) {
-          PPTpositon.w = hostInfo.width / scaleRatio.value.width
-          PPTpositon.h = hostInfo.height / scaleRatio.value.height
-          PPTpositon.x = hostInfo.marginLeft / scaleRatio.value.width
-          PPTpositon.y = hostInfo.top / scaleRatio.value.height
-        }
-        // selectHost.value.name = hostInfo.name;
-        // selectHost.value.pictureUrl = hostInfo.src;
-        // selectHost.value.id = hostInfo.entityId;
-        //鏁板瓧浜轰綅缃俊鎭�
-        componentsInfo.width = hostInfo.width
-        componentsInfo.height = hostInfo.height
-        componentsInfo.top = hostInfo.top
-        componentsInfo.marginLeft = hostInfo.marginLeft
-        componentsInfo.depth = hostInfo.depth
-        //鏁板瓧浜虹被鍨�
-        tabs1ActiveNum.value = hostInfo.digitbotType
-        driveType.forEach((child) => {
-          if (child.name == hostInfo.driverType) {
-            selectDriveType.value = child
-          }
-        })
-        //閫夋嫨澹伴煶淇℃伅
-        const voiceInfo = res.scenes[0].voice
-        audioSelectData.value = [
-          {
-            id: voiceInfo.voiceId,
-            entityId: voiceInfo.entityId,
-            name: voiceInfo.name
-          }
-        ]
-      }
-      //涓婁紶鏂囦欢淇℃伅
-      const pageInfo = res.pageInfo ? JSON.parse(res.pageInfo) : ''
-      uploadFileObj.filename = pageInfo ? pageInfo.docInfo.fileName : ''
-      uploadFileObj.size = pageInfo ? pageInfo.docInfo.fileSize : ''
-
-      //搴旂敤妯℃澘 杩欓噷鐢ㄦ埛鍙兘宸茬粡璋冩暣浜嗘ā鏉匡紝鎵�浠ヨ繖閲屼笉搴旂敤妯℃澘
-      // applyTemplate()
-    }
-  })
-}
-//閫夋嫨妯℃澘
-const chooseTemplate = (currTemplate) => {
-  selectTemplate.value = cloneDeep(currTemplate)
-  console.log('閫夋嫨鐨勬ā鏉夸俊鎭�:', currTemplate)
-  console.log(templates.value)
-  templates.value.forEach((item) => {
-    item.isActive = false
-  })
-  currTemplate.isActive = true
-  applyTemplate()
 }
 
 const applyTemplate = (ppt = null) => {
   const template = selectTemplate.value
+  console.log('template', template)
   const pptList = applyAllTemplate.value ? PPTArr.value : [selectPPT.value]
 
-  // 鏁板瓧浜烘槸缁熶竴鐢熸晥鐨勶紝鍏堝鐞�
-  console.log(template)
   pptList.forEach((item) => {
-    // 淇濆瓨鍘熷ppt鍥剧墖
     const originalPPT = item.innerPicture?.src || item.pictureUrl
-    console.log('originalPPT', originalPPT)
+
     if (template.showBackground) {
       item.pictureUrl = template.bgImage
       if (template.showPpt) {
@@ -2210,10 +1582,12 @@
       item.innerPicture.src = ''
     }
 
-    item.showDigitalHuman = template.showDigitalHuman
-    // 娣诲姞鍚屾瀹介珮鐨勯�昏緫
-    const targetTemplate = selectTemplate.value
-    console.log(PPTArr)
+    item.digitalHuman.show = template.showDigitalHuman
+    item.digitalHuman.w = template.humanW
+    item.digitalHuman.h = template.humanH
+    item.digitalHuman.x = template.humanX
+    item.digitalHuman.y = template.humanY
+
     PPTArr.value.forEach((otherItem) => {
       if (otherItem.templateId === item.templateId) {
         otherItem.width = item.width
@@ -2221,32 +1595,24 @@
       }
     })
   })
-
-  // 鏁板瓧浜轰綅缃篃闇�瑕佺缉鏀�
-  PPTpositon.w = selectTemplate.value.humanW
-  PPTpositon.h = selectTemplate.value.humanH
-  PPTpositon.x = selectTemplate.value.humanX
-  PPTpositon.y = selectTemplate.value.humanY
 }
 
 const replaceDialog = ref(null)
 
-// 鎵撳紑寮瑰嚭妗�
 const openReplaceDialog = () => {
   replaceDialog.value.open()
 }
 
-// 澶勭悊鎻愪氦鐨勬浛鎹㈣鍒�
 const escapeRegExp = (string) => {
-  return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&') // 杞箟姝e垯涓殑鐗规畩瀛楃
+  return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')
 }
 
 const handleReplacement = (replacements) => {
   PPTArr.value.forEach((item) => {
     if (item.pptRemark) {
       replacements.forEach((replacement) => {
-        const fromEscaped = escapeRegExp(replacement.from) // 杞箟鐗规畩瀛楃
-        const regExp = new RegExp(fromEscaped, 'g') // 浣跨敤杞箟鍚庣殑瀛楃涓叉瀯閫犳鍒欒〃杈惧紡
+        const fromEscaped = escapeRegExp(replacement.from)
+        const regExp = new RegExp(fromEscaped, 'g')
         item.pptRemark = item.pptRemark.replace(regExp, replacement.to)
       })
     }
@@ -2254,39 +1620,276 @@
   message.success('鎵归噺鏇挎崲鎴愬姛锛�')
 }
 
+const showAudioPlay = ref(false)
+const showAudioPlay1 = ref(false)
+const startAudioPlay = ref(false)
+const textareaRef = ref()
+const selectTextarea = ref('')
+
+const audioExceed = () => {
+  message.warning('鏈�澶氫笂浼犱竴涓0闊抽┍鍔ㄦ枃浠讹紒')
+}
+
+const currentAudio = ref()
+
+const createAudio = async () => {
+  const text = editorRef.value.getText()
+  if (!text) {
+    message.warning('璇疯緭鍏ラ渶瑕佽瘯鍚枃鏈殑鍐呭鈥�')
+    return false
+  }
+
+  const truncatedText = text.length > 100 ? text.substring(0, 100) : text
+
+  const params = {
+    text: truncatedText,
+    humanId: selectPPT.value.digitalHuman?.host?.id || null,
+    voiceId: audioSelectData.value == undefined ? null : audioSelectData.value[0].id,
+  }
+
+  try {
+    showAudioPlay1.value = true
+    const res = await pptTemplateApi.createAudio(params)
+
+    if (res && !res.error) {
+      showAudioPlay1.value = false
+      showAudioPlay.value = true
+
+      currentAudio.value = new Audio(res)
+      currentAudio.value.addEventListener('ended', () => {
+        showAudioPlay.value = false
+        currentAudio.value = null
+      })
+
+      currentAudio.value.play()
+    } else {
+      showAudioPlay1.value = false
+    }
+  } catch (error) {
+    console.error('API 璇锋眰澶辫触锛�', error)
+    showAudioPlay1.value = false
+  }
+}
+
+const pauseAudio = () => {
+  currentAudio.value.pause()
+  currentAudio.value = null
+  showAudioPlay.value = false
+}
+
+const currentAudioFile = ref()
+
+const audioPlay = (file) => {
+  if (!file.response.data) {
+    message.error('鏈幏鍙栧埌鏂囦欢')
+    return
+  }
+
+  if (currentAudioFile.value) {
+    currentAudioFile.value.pause()
+    currentAudioFile.value.currentTime = 0
+  }
+
+  const audio = new Audio(file.response.data)
+  currentAudioFile.value = audio
+
+  audio.addEventListener('ended', () => {
+    cancelAudio()
+  })
+
+  startAudioPlay.value = true
+  audio.play()
+}
+
+const cancelAudio = () => {
+  if (currentAudioFile.value) {
+    currentAudioFile.value.pause()
+    currentAudioFile.value.currentTime = 0
+    currentAudioFile.value = null
+  }
+  startAudioPlay.value = false
+}
+
+const goBack = () => {
+  if (!PPTArr.value) {
+    pptTemplateApi.coursesDelete(courseInfo.value.id).then((res) => {
+      console.log(res)
+    })
+  }
+  router.go(-1)
+}
+
+const editorRef = shallowRef()
+const editorConfig = { placeholder: '璇疯緭鍏ュ唴瀹�...' }
+
+const handleCreated = (editor) => {
+  editorRef.value = editor
+}
+
+const dialogVisible = ref(false)
+const textList = ref([])
+
+const handleWord = () => {
+  editorRef.value.focus()
+  selectTextarea.value = editorRef.value.getSelectionText()
+  if (!selectTextarea.value) {
+    message.warning('璇峰厛閫変腑闇�鎸囧畾璇绘硶鐨勬枃鏈�')
+    return false
+  }
+  if (selectTextarea.value.length > 1) {
+    message.warning('鍙兘閫夋嫨涓�涓瓧')
+    return false
+  }
+  let textPinyin = polyphonic(selectTextarea.value, { toneType: 'num', type: 'array' })[0]
+  if (textPinyin.length > 1) {
+    textList.value = textPinyin
+    dialogVisible.value = true
+  } else {
+    message.warning(`${selectTextarea.value}涓嶆槸澶氶煶瀛梎)
+  }
+}
+
+const handleTag = (name) => {
+  dialogVisible.value = false
+  const node = {
+    type: 'text-value',
+    textVal: selectTextarea.value,
+    children: [{ text: name }]
+  }
+  editorRef.value.restoreSelection()
+  editorRef.value.insertNode(node)
+  editorRef.value.move(1)
+}
+const onDragMove = (evt, data) => {
+  console.log(evt)
+  console.log(data)
+
+  // 闄愬埗鍧愭爣
+  if (data.x < -100) {
+    data.x = -100; // 鍙互璁剧疆鏈�灏忓潗鏍囦负 -100
+  }
+  if (data.y < -100) {
+    data.y = -100; // 鍙互璁剧疆鏈�灏忓潗鏍囦负 -100
+  }
+};
+
+const getCourseDetail = async (id) => {
+  const res = await pptTemplateApi.coursesDetail(id)
+  if (res) {
+    courseInfo.value = res
+
+    if (res.scenes && res.scenes.length > 0) {
+      res.scenes.forEach((item) => {
+        item.isActive = false
+        item.isChecked = false
+        item.pictureUrl = item.background.src
+        item.pptRemark = editorHtml.parseElemHtml(item.background.pptRemark)
+        item.backgroundType = item.background.backgroundType
+        item.width = item.background.width
+        item.height = item.background.height
+
+        const hostInfo = item.components.find((p) => p.category == 2)
+        if (hostInfo) {
+          item.digitalHuman = {
+            show: hostInfo.status === 0,
+            x: hostInfo.marginLeft / scaleRatio.value.width,
+            y: hostInfo.top / scaleRatio.value.height,
+            w: hostInfo.width / scaleRatio.value.width,
+            h: hostInfo.height / scaleRatio.value.height,
+            active: false,
+            host: {
+              ...hostList.value.find(h => h.code === hostInfo.entityId),
+              code: hostInfo.entityId,
+              type: hostInfo.entityType
+            }
+          }
+        }
+
+        const innerPicture = item.components.find((p) => p.category == 1)
+        if (innerPicture) {
+          item.innerPicture = {
+            ...innerPicture,
+            width: innerPicture.width / scaleRatio.value.width,
+            height: innerPicture.height / scaleRatio.value.height,
+            top: innerPicture.top / scaleRatio.value.height,
+            marginLeft: innerPicture.marginLeft / scaleRatio.value.width
+          }
+        }
+      })
+
+      PPTArr.value = res.scenes
+      PPTArr.value[0].isActive = true
+      selectPPT.value = PPTArr.value[0]
+
+      PPTArr.value.forEach((scene, index) => {
+        if (res.scenes[index].voice) {
+          scene.selectAudio = res.scenes[index].voice
+          scene.selectAudio.code = res.scenes[index].voice.entityId
+          scene.selectAudio.id = res.scenes[index].voice.voiceId
+        }
+        scene.uploadAudioUrl = res.scenes[index].audioDriver?.audioUrl
+      })
+
+      if (PPTArr.value[0].audioDriver?.fileName && PPTArr.value[0].audioDriver?.audioUrl) {
+        selectPPT.value.fileList = [
+          {
+            name: PPTArr.value[0].audioDriver?.fileName,
+            url: PPTArr.value[0].audioDriver?.audioUrl
+          }
+        ]
+      }
+
+      // 璁剧疆闊抽閫夋嫨鏁版嵁
+      const firstScene = res.scenes[0]
+      if (firstScene.voice) {
+        audioSelectData.value = [
+          {
+            id: firstScene.voice.voiceId,
+            entityId: firstScene.voice.entityId,
+            name: firstScene.voice.name
+          }
+        ]
+      }
+    }
+
+    const pageInfo = res.pageInfo ? JSON.parse(res.pageInfo) : ''
+    uploadFileObj.filename = pageInfo ? pageInfo.docInfo.fileName : ''
+    uploadFileObj.size = pageInfo ? pageInfo.docInfo.fileSize : ''
+  }
+}
+
 onMounted(async () => {
   let data = await TemplateApi.getTemplatePage(queryParams)
-  TEMPLATE_PRESETS.value = data.list.map((item) => {
-    return {
-      ...item,
-      showBackground: item.showBackground === 1,
-      showDigitalHuman: item.showDigitalHuman === 1,
-      showPpt: item.showPpt === 1
-    }
-  })
-  if (templates.value.length > 0) selectTemplate.value = cloneDeep(templates.value[0])
+  TEMPLATE_PRESETS.value = data.list.map((item) => ({
+    ...item,
+    showBackground: item.showBackground === 1,
+    showDigitalHuman: item.showDigitalHuman === 1,
+    showPpt: item.showPpt === 1
+  }))
+
   templates.value = TEMPLATE_PRESETS.value.map((template) => cloneDeep(template))
   selectTemplate.value = cloneDeep(templates.value[0])
-  // console.log('onMounted selectTemplate.value',selectTemplate.value)
+
   await getList()
-  console.log(route.query.id)
+
   if (route.query.id) {
     await getCourseDetail(route.query.id)
-    // saveInter() // 鍚姩瀹氭椂淇濆瓨
   } else {
     coursesCreate()
   }
 })
+
 onUnmounted(() => {
-  // clearInterval(saveTimer.value)
-  console.log(schedulePPTTimer.value)
-  clearInterval(schedulePPTTimer.value)
+  if (schedulePPTTimer.value) {
+    clearInterval(schedulePPTTimer.value)
+  }
   if (currentAudioFile.value) {
     currentAudioFile.value.removeEventListener('ended', cancelAudio)
     currentAudioFile.value = null
   }
 })
 </script>
+
 <style scoped lang="scss">
 .pages {
   height: 100%;
@@ -2353,7 +1956,6 @@
       margin: 0;
 
       div {
-        // height: 30px;
         padding: 5px 10px;
         margin: 0;
         line-height: 30px;
@@ -2403,7 +2005,7 @@
 
       .list {
         position: relative;
-        height: calc(152px * 9 / 16); // 浣跨敤缂╃暐鍥剧殑鍥哄畾楂樺害
+        height: calc(152px * 9 / 16);
         margin: 20px 0;
         box-sizing: content-box;
 
@@ -2421,7 +2023,6 @@
           border-radius: 5px;
         }
 
-        // 纭繚鑳屾櫙鍥剧墖濉厖鏁翠釜瀹瑰櫒
         .background {
           position: absolute;
           width: 100%;
@@ -2436,8 +2037,6 @@
 
         .ppt-bg {
           z-index: 2;
-          // width: 152px;
-          // height: 100%;
         }
 
         .host {
@@ -2470,7 +2069,7 @@
     width: 56%;
     background-color: #fff;
     box-shadow: 0 3px 6px rgb(175 175 175 / 16%);
-    flex-grow: 1; // 纭繚涓棿鍖哄煙鍙互鑷�傚簲楂樺害
+    flex-grow: 1;
     flex-direction: column;
     justify-content: flex-start;
 
@@ -2486,8 +2085,6 @@
 
       .main-image-box {
         position: relative;
-        // width: 760px;
-        // height: 360px;
         border: 1px solid #ebeef5;
         box-sizing: content-box;
       }
@@ -2518,39 +2115,9 @@
       justify-content: space-between;
       padding: 10px;
 
-      .voice-item {
-        width: 180px;
-        height: 30px;
-        overflow: hidden;
-        cursor: pointer;
-        background-color: #c9c9c9;
-        border-radius: 12px;
-
-        span {
-          display: inline-block;
-          width: 50%;
-          height: 30px;
-          line-height: 30px;
-          text-align: center;
-        }
-
-        .active-item {
-          color: #fff;
-          background-color: #409eff;
-        }
-      }
-
       .media-box {
         display: flex;
         align-items: center;
-
-        .mic {
-          display: flex;
-          align-items: center;
-          width: 50px;
-          justify-content: space-around;
-          padding: 5px 10px;
-        }
       }
     }
 
@@ -2668,10 +2235,10 @@
           position: absolute;
           top: 0;
           left: 0;
-          z-index: 1; /* 鑳屾櫙鍦ㄥ簳灞� */
+          z-index: 1;
           width: 100%;
           height: 100%;
-          background-color: #f0f1fa; /* 璁剧疆搴曡壊 */
+          background-color: #f0f1fa;
         }
 
         .host-name {
@@ -2689,7 +2256,7 @@
         }
 
         .ppt-bg {
-          z-index: 2; /* 鍥剧墖鍦ㄨ儗鏅箣涓� */
+          z-index: 2;
           width: 100%;
           height: 100%;
         }
@@ -2744,12 +2311,12 @@
       }
       .ppt-bg {
         position: absolute;
-        z-index: 2; /* 鍥剧墖鍦ㄨ儗鏅箣涓� */
+        z-index: 2;
       }
 
       .human-image {
         position: absolute;
-        z-index: 3; /* 鍥剧墖鍦ㄨ儗鏅箣涓� */
+        z-index: 3;
       }
     }
   }
@@ -2758,10 +2325,10 @@
     position: absolute;
     top: 0;
     left: 0;
-    z-index: 1; /* 鑳屾櫙鍦ㄥ簳灞� */
+    z-index: 1;
     width: 100%;
     height: 100%;
-    background-color: #f0f1fa; /* 璁剧疆搴曡壊 */
+    background-color: #f0f1fa;
   }
 
   .template-tool {
@@ -2798,25 +2365,22 @@
   bottom: 0;
 }
 
-/* 婊氬姩鏉℃牱寮� */
 ::-webkit-scrollbar {
   width: 4px;
 }
 
-/* 婊戝潡鏍峰紡 */
 ::-webkit-scrollbar-thumb {
   background-color: #888;
   border-radius: 6px;
 }
 
-/* 婊氬姩鏉¤建閬撴牱寮� */
 ::-webkit-scrollbar-track {
   background-color: #f2f2f2;
   border-radius: 6px;
 }
 
 .voice-card {
-  z-index: 1000 !important; // 娣诲姞鏇撮珮鐨剒-index纭繚鍦ㄦ渶椤跺眰
+  z-index: 1000 !important;
 }
 
 .voice-card :deep(.el-card__body) {
@@ -2843,4 +2407,7 @@
     background-color: #1989fa;
   }
 }
+.dialog-footer{
+  float: right;
+}
 </style>
diff --git a/easegen-front/src/views/digitalcourse/template/index.vue b/easegen-front/src/views/digitalcourse/template/index.vue
index 2a15a58..8e83552 100644
--- a/easegen-front/src/views/digitalcourse/template/index.vue
+++ b/easegen-front/src/views/digitalcourse/template/index.vue
@@ -74,7 +74,6 @@
       <el-table-column label="鑳屾櫙鍥剧墖" align="center" prop="bgImage">
         <template #default="scope">
           <el-image
-            style="width: 100px; height: 60px"
             :src="scope.row.bgImage"
             :preview-src-list="[scope.row.bgImage]"
             fit="cover"
@@ -85,7 +84,6 @@
       <el-table-column label="棰勮鍥剧墖" align="center" prop="previewImage">
         <template #default="scope">
           <el-image
-            style="width: 100px; height: 60px"
             :src="scope.row.previewImage"
             :preview-src-list="[scope.row.previewImage]"
             fit="cover"
diff --git a/easegen-front/src/views/myCourse/index.vue b/easegen-front/src/views/myCourse/index.vue
index 733bbab..3fe32c4 100644
--- a/easegen-front/src/views/myCourse/index.vue
+++ b/easegen-front/src/views/myCourse/index.vue
@@ -534,6 +534,9 @@
 const currentPlayUrl = ref('')
 const videoRefs = ref<HTMLVideoElement[]>([])
 
+//璁℃椂鍣�
+const Timer = ref()
+
 // 鑾峰彇瑙嗛鍒楄〃
 const getList = async () => {
   loading.value = true
@@ -1167,10 +1170,28 @@
   stopPolling()
 })
 
+//璁℃椂鍣ㄨ疆璇�
+const TimerList = ( () => {
+  Timer.value = setInterval( ()=>{getList()}, 5000 )
+} )
+
+//娓呮璁℃椂鍣�
+const ClearTimerList = ( () => {
+  clearInterval(Timer.value)
+  Timer.value = null 
+} )
+
 // 鍒濆鍖�
 onMounted(() => {
+  //鍔犺浇鏁版嵁
   getList()
+  //璋冪敤璁℃椂鍣�
+  TimerList()
 })
+//娓呮璁℃椂鍣�
+onUnmounted( ()=>{
+  ClearTimerList()
+} )
 
 // 鎾斁棰勮
 const playPreview = (type: 'titles' | 'trailer') => {
diff --git a/easegen-front/src/views/pptTemplateList/index.vue b/easegen-front/src/views/pptTemplateList/index.vue
index 501f98c..cceed5d 100644
--- a/easegen-front/src/views/pptTemplateList/index.vue
+++ b/easegen-front/src/views/pptTemplateList/index.vue
@@ -116,7 +116,7 @@
           <!--          <el-icon size="20" color="#ffffff" style="margin-right: 5px" @click.stop="copyItem(item.id)">-->
           <!--            <CopyDocument />-->
           <!--          </el-icon>-->
-          <el-icon size="20" color="#ffffff" style="margin-right: 5px" @click.stop="deleteItem(item.id)">
+          <el-icon size="20" color="#ffcf49" style="margin-right: 5px" @click.stop="deleteItem(item.id)">
             <Delete />
           </el-icon>
         </div>
diff --git a/yudao-module-digitalcourse/yudao-module-digitalcourse-biz/src/main/java/cn/iocoder/yudao/module/digitalcourse/service/courses/CoursesServiceImpl.java b/yudao-module-digitalcourse/yudao-module-digitalcourse-biz/src/main/java/cn/iocoder/yudao/module/digitalcourse/service/courses/CoursesServiceImpl.java
index 941486d..71247ff 100644
--- a/yudao-module-digitalcourse/yudao-module-digitalcourse-biz/src/main/java/cn/iocoder/yudao/module/digitalcourse/service/courses/CoursesServiceImpl.java
+++ b/yudao-module-digitalcourse/yudao-module-digitalcourse-biz/src/main/java/cn/iocoder/yudao/module/digitalcourse/service/courses/CoursesServiceImpl.java
@@ -181,7 +181,7 @@
         // 鏍规嵁浼犲叆鐨剈serid鍒涘缓鏌ヨ鏉′欢
         LambdaQueryWrapper<CoursesDO> queryWrapper = new LambdaQueryWrapper<CoursesDO>()
                 .eq(CoursesDO::getCreator, Long.valueOf(userid));
-        
+
         // 浣跨敤甯︽湁鏌ヨ鏉′欢鐨勫垎椤垫煡璇�
         PageResult<CoursesDO> pageResult = coursesMapper.selectPage(pageReqVO, queryWrapper);
 
@@ -297,12 +297,12 @@
     private void refreshCourseCache(String courseId) {
         // 鑾峰彇璇剧▼瀹屾暣淇℃伅
         AppCoursesUpdateReqVO courseInfo = getCourses(Long.parseLong(courseId));
-        
+
         if (courseInfo == null || CollectionUtil.isEmpty(courseInfo.getScenes())) {
             log.error("璇剧▼淇℃伅涓嶅瓨鍦ㄦ垨鍦烘櫙涓虹┖锛宑ourseId: {}", courseId);
             return;
         }
-    
+
         // 鏋勫缓鍦烘櫙缂撳瓨鏁版嵁
         Map<String, Map<String, String>> scenesMap = new HashMap<>();
         courseInfo.getScenes().forEach(scene -> {
@@ -311,7 +311,7 @@
             sceneData.put("background", scene.getBackground().getSrc());
             scenesMap.put(String.valueOf(scene.getOrderNo()), sceneData);
         });
-    
+
         // 搴忓垪鍖栧苟瀛樺偍鍦烘櫙鏁版嵁
         String sceneRedisKey = COURSE_SCENE_TEXT_KEY + courseId;
 
@@ -481,4 +481,4 @@
         }
     }
 
-}
\ No newline at end of file
+}
diff --git a/yudao-module-digitalcourse/yudao-module-digitalcourse-biz/src/main/java/cn/iocoder/yudao/module/digitalcourse/service/coursescenes/CourseScenesServiceImpl.java b/yudao-module-digitalcourse/yudao-module-digitalcourse-biz/src/main/java/cn/iocoder/yudao/module/digitalcourse/service/coursescenes/CourseScenesServiceImpl.java
index 1e88be7..7883fa8 100644
--- a/yudao-module-digitalcourse/yudao-module-digitalcourse-biz/src/main/java/cn/iocoder/yudao/module/digitalcourse/service/coursescenes/CourseScenesServiceImpl.java
+++ b/yudao-module-digitalcourse/yudao-module-digitalcourse-biz/src/main/java/cn/iocoder/yudao/module/digitalcourse/service/coursescenes/CourseScenesServiceImpl.java
@@ -168,7 +168,6 @@
     }
 
     @Override
-    @Async
     public void batchRemoveCouseScenes(Long id) {
         System.out.println(System.currentTimeMillis()+"      鍒犻櫎寮�濮�");
         List<CourseScenesDO> courseScenesDOS = courseScenesMapper.selectList(new QueryWrapperX<CourseScenesDO>().lambda().eq(CourseScenesDO::getCourseId, id));
@@ -247,4 +246,4 @@
         return courseScenesMapper.selectPage(pageReqVO);
     }
 
-}
\ No newline at end of file
+}

--
Gitblit v1.9.3