Flex
2025-04-15 1f38a62a2e98390b1c5f629bd96097f8e77396fa
Merge branch 'master' of http://yykjgit.sdyyst.com/r/easegen
已修改3个文件
247 ■■■■■ 文件已修改
easegen-front/src/views/chooseTemplate/audioSelect.vue 208 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
easegen-front/src/views/chooseTemplate/index.vue 13 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
easegen-front/src/views/myCourse/index.vue 26 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
easegen-front/src/views/chooseTemplate/audioSelect.vue
@@ -7,76 +7,64 @@
    :close-on-click-modal="false"
  >
    <el-tabs v-model="activeName" @tab-change="handleClick">
      <el-tab-pane :label="child.label" :name="child.value" v-for="(child,ind) in voiceTypeList" :key="ind">
        <div class="language" v-if="activeName == 0">
      <div class="language" v-if="activeName == 0">
          <span
            v-for="(item, index) in languageList"
            :key="index"
            :class="{ isActive: item.isActive }"
            @click="handleLanguage(item)"
            >{{ item.label }}</span
          >
        </div>
        <div class="language">
          >{{ item.label }}</span>
      </div>
      <div class="language">
          <span
            v-for="(item, index) in audioType"
            :key="index"
            :class="{ isActive: item.isActive }"
            @click="handleAudio(item)"
            >{{ item.label }}</span
          >{{ item.label }}</span>
      </div>
      <div v-if="audioList && audioList.length > 0">
        <div class="table-container">
          <div
            class="table-list"
            :style="{ borderColor: item.isSelect ? '#0183f4' : '' }"
            :class="{ isHover: item.isHover }"
            v-for="(item, index) in audioList"
            :key="index"
            @mouseenter="handleMouseenter(item)"
            @mouseleave="handleMouseleave(item)"
            @click="handleSelect(item)"
          >
        </div>
        <div v-if="audioList && audioList.length > 0">
          <div class="table-container">
            <div
              class="table-list"
              :style="{ borderColor: item.isSelect ? '#0183f4' : '' }"
              :class="{ isHover: item.isHover }"
              v-for="(item, index) in audioList"
              :key="index"
              @mouseenter="handleMouseenter(item)"
              @mouseleave="handleMouseleave(item)"
              @click="handleSelect(item)"
            >
              <div class="item-head">
                <img :src="item.avatarUrl" />
                <!-- <div class="head-btn">高级</div> -->
              </div>
              <div class="item-name">
                <span>{{ item.name }}</span>
                <span>{{ item.introduction }}</span>
              </div>
              <img
                class="play-img"
                v-if="item.isHover && !item.isPlay"
                src="@/assets/imgs/play.png"
                alt=""
                @click.stop="playAudio(item)"
              />
              <img
                class="play-img"
                v-if="item.isHover && item.isPlay"
                src="@/assets/imgs/pause.png"
                alt=""
                @click.stop="pauseAudio(item)"
              />
            <div class="item-head">
              <img :src="item.avatarUrl" />
            </div>
            <div class="item-name">
              <span>{{ item.name }}</span>
              <span>{{ item.introduction }}</span>
            </div>
            <img
              class="play-img"
              v-if="item.isHover && !item.isPlay"
              src="@/assets/imgs/play.png"
              alt=""
              @click.stop="playAudio(item)"
            />
            <img
              class="play-img"
              v-if="item.isHover && item.isPlay"
              src="@/assets/imgs/pause.png"
              alt=""
              @click.stop="pauseAudio(item)"
            />
          </div>
          <!-- 分页 -->
          <Pagination
            :total="total"
            v-model:page="queryParams.pageNo"
            v-model:limit="queryParams.pageSize"
            @pagination="getList"
          />
        </div>
        <div v-else class="nodata">
          <img src="@/assets/imgs/nodata.png" alt="" />
        </div>
      </el-tab-pane>
      </div>
      <div v-else class="nodata">
        <img src="@/assets/imgs/nodata.png" alt="" />
      </div>
    </el-tabs>
    <template #footer>
      <el-button @click="audioSelectVisible = false">{{t('common.cancel')}}</el-button>
      <el-button @click="useOriginalSound">使用原声</el-button>
      <el-button type="primary" @click="submitForm">{{t('common.ok')}}</el-button>
    </template>
  </el-dialog>
@@ -99,9 +87,6 @@
    Reflect.set(item, "isActive", false);
  });
  languageList.value = list;
  // selectLanguage.value = list[0];
  // selectLanguage.value.isActive = true;
  // 移除默认选中
  selectLanguage.value = { value: '' };
};
const audioType = ref();
@@ -115,9 +100,6 @@
  });
  audioType.value = list;
  audioTypeCustom.value = list;
  // selectAudio.value = list[0];
  // selectAudio.value.isActive = true;
  // 移除默认选中
  selectAudio.value = { value: '' };
};
//获取声音类别
@@ -152,9 +134,7 @@
      item.isPlay = false;
      item.isSelect = false;
    });
    console.log(data.list)
    audioList.value = data.list;
    total.value = data.total;
  } finally {
    loading.value = false;
@@ -162,8 +142,8 @@
};
//声音模型类型过滤
const handleClick = (item)=>{
   activeName.value = item;
   getList();
  activeName.value = item;
  getList();
}
//语言过滤
const handleLanguage = (item) => {
@@ -194,12 +174,10 @@
};
const handleMouseleave = (item) => {
  item.isHover = false;
  item.isPlay = false;
};
//选择声音模型
const selectList = ref();
const handleSelect = (item) => {
  console.log(item)
  selectList.value = [item];
  audioList.value.forEach((child) => {
    if (child.id == item.id) {
@@ -220,30 +198,84 @@
    audioSelectVisible.value = false;
  }
};
//播放声音
const currentAudio = ref();
const playAudio = async (item) => {
  item.isPlay = !item.isPlay;
  await nextTick();
  // currentAudio.value[0].play();
  if (currentAudio.value && currentAudio.value.auditionUrl === item.auditionUrl) {
    currentAudio.value.play();
  } else {
    currentAudio.value = new Audio(item.auditionUrl);
    currentAudio.value.play();
// 使用原声
const useOriginalSound = () => {
  // 清除选中的音频
  selectList.value = null;
  // 清除列表中所有选中状态
  if (audioList.value) {
    audioList.value.forEach(item => {
      item.isSelect = false;
    });
  }
  // 停止当前播放的音频
  if (currentAudio.value) {
    currentAudio.value.pause();
    currentAudio.value = null;
  }
  // 重置当前播放状态
  if (currentlyPlaying.value) {
    currentlyPlaying.value.isPlay = false;
    currentlyPlaying.value = null;
  }
  // 关闭对话框
  audioSelectVisible.value = false;
  // 触发事件通知父组件使用原声
  emit('success', undefined);
};
// 音频管理
const currentAudio = ref<HTMLAudioElement | null>(null);
const currentlyPlaying = ref<any>(null);
const playAudio = async (item: any) => {
  // 如果点击的是当前正在播放的项目,则暂停
  if (currentlyPlaying.value && currentlyPlaying.value.id === item.id) {
    pauseAudio(item);
    return;
  }
  // 停止当前播放的音频
  if (currentAudio.value) {
    currentAudio.value.pause();
    currentAudio.value = null;
  }
  // 如果之前有播放的项目,重置其状态
  if (currentlyPlaying.value) {
    currentlyPlaying.value.isPlay = false;
  }
  // 设置新的播放项目
  currentlyPlaying.value = item;
  item.isPlay = true;
  // 创建新的音频对象并播放
  currentAudio.value = new Audio(item.auditionUrl);
  currentAudio.value.play();
  // 添加播放结束事件监听
  currentAudio.value.addEventListener('ended', () => {
    item.isPlay = false;
    currentlyPlaying.value = null;
    currentAudio.value = null;
  });
};
const pauseAudio = (item: any) => {
  if (currentAudio.value && currentlyPlaying.value && currentlyPlaying.value.id === item.id) {
    currentAudio.value.pause();
    item.isPlay = false;
    currentlyPlaying.value = null;
  }
};
const pauseAudio = async (item) => {
  item.isPlay = !item.isPlay;
  await nextTick();
  // currentAudio.value[0].pause();
  if (currentAudio.value && currentAudio.value.auditionUrl === item.auditionUrl) {
    currentAudio.value.pause();
  } else {
    currentAudio.value = new Audio(item.auditionUrl);
    currentAudio.value.pause();
  }
};
const open = () => {
  audioSelectVisible.value = true
}
easegen-front/src/views/chooseTemplate/index.vue
@@ -1303,12 +1303,19 @@
  audioSelect.value.open()
}
const selectAudio = (data) => {
  console.log(data)
  audioSelectData.value = data
  // selectPPT.value.selectAudio = data[0]
  // 遍历所有场景,应用相同的声音模型
  PPTArr.value.forEach((scene) => {
    scene.selectAudio = data[0]
  })
  if (data==undefined){
    selectPPT.value.selectAudio.name=''
    return {}
  }else {
    PPTArr.value.forEach((scene) => {
      scene.selectAudio = data[0]
    })
  }
}
//生成课程id
const coursesCreate = () => {
easegen-front/src/views/myCourse/index.vue
@@ -40,10 +40,16 @@
<!--          {{ formatDuration(scope.row.duration) }}-->
<!--        </template>-->
<!--      </el-table-column>-->
      <el-table-column label="排队个数" align="center" prop="pos" />
      <el-table-column label="排队个数" align="center" prop="pos" >
        <template #default="scope">
         <span v-if="scope.row.pos==0">视频正在合成...</span>
          <span v-else>{{ scope.row.pos }}</span>
        </template>
      </el-table-column>
      <el-table-column label="进度" align="center" prop="progressVideo">
        <template #default="scope">
          {{ calculateProgress(scope.row.progressVideo) }}%
          <span v-if="scope.row.status==2">100%</span>
          <span v-else>{{ calculateProgress(scope.row.progressVideo) }}%</span>
        </template>
      </el-table-column>
@@ -448,17 +454,25 @@
    subtitleDialogVisible.value = true
    subtitleForm.videoId = videoId
    const videoDetail = await pptTemplateApi.myCourseDetail(videoId)
    console.log('视频详情:', videoDetail)
    // 立即获取视频详情检查字幕状态
    subtitleForm.subtitlesAddStatus=videoDetail.subtitlesAddStatus
    if (videoDetail.subtitlesAddStatus === 2) {
      subtitleForm.videoUrl = videoDetail.videoUrl || ''
      generating.value=false
      polling.value=false
    }else if (videoDetail.subtitlesAddStatus === 1) {
      generating.value=true
      polling.value=true
    }
    if (videoDetail.subtitlesStatus === 2) { // 2 表示字幕已生成
      if (videoDetail.subtitlesUrl) {
        subtitleForm.subtitlesUrl = videoDetail.subtitlesUrl
        subtitleForm.courseName=videoDetail.courseName
        generating.value=false
        polling.value=false
        try {
          // 尝试从URL获取字幕内容
          const response = await fetch(videoDetail.subtitlesUrl)
@@ -477,15 +491,19 @@
        // 直接使用字幕内容
        subtitleForm.content = videoDetail.subtitlesContent
      }
    } else {
    } else if (videoDetail.subtitlesStatus === 3) {
      // 字幕未生成或生成失败,清空内容
      subtitleForm.content = ''
    }else if (videoDetail.subtitlesStatus === 1) {
      generating.value=true
      polling.value=true
    }
  } catch (error) {
    console.error('获取视频详情失败:', error)
    message.error('获取视频详情失败,请重试')
    subtitleDialogVisible.value = false
  }
  console.log('视频详情:', generating)
}
// 重置字幕表单