Ver código fonte

feat: 克隆声音流程调整

sheldon 2 meses atrás
pai
commit
c8f1ecbcf5

+ 144 - 0
src/views/voice-management/components/EditClone.vue

@@ -0,0 +1,144 @@
+<script setup lang="ts">
+import { ElDialog, ElForm, ElFormItem, ElInput, ElDatePicker, ElButton, ElMessage, ElRadio } from 'element-plus'
+import { Plus } from '@element-plus/icons-vue'
+import type { FormInstance, FormRules } from 'element-plus'
+import { toast } from 'vue-sonner'
+import AudioFileUploader from '@/components/Uploader/AudioFileUploader.vue'
+import { cloneVoice } from '@/api/modules/voice'
+// 定义组件的属性
+interface Props {
+  visible: boolean
+}
+
+// 定义组件的事件
+interface Emits {
+  (e: 'update:visible', value: boolean): void
+  (e: 'cancel'): void
+  (e: 'refresh'): void
+}
+
+// 接收属性和事件
+const props = withDefaults(defineProps<Props>(), {
+  visible: false,
+})
+
+const emit = defineEmits<Emits>()
+
+const dialogVisible = computed({
+  get: () => props.visible,
+  set: (value) => {
+    // 这里可以触发一个事件来通知父组件更新 visible 的值
+    emit('update:visible', value);
+  },
+});
+// 表单引用
+const editFormRef = ref<FormInstance>();
+const cloneLoading = ref(false)
+const formData = ref<{gender: number, voiceName: string, audioUrl: string}>({
+  gender: 1,
+  voiceName: '',
+  audioUrl: '',
+});
+
+// 表单验证规则
+const formRules = ref<FormRules>({
+  voiceName: [
+    { required: true, message: '请输入名称', trigger: 'blur' },
+  ],
+  audioUrl: [
+    { required: true, message: '请输上传声音', trigger: 'blur' },
+  ],
+
+})
+
+function handleCancel() {
+  emit('cancel')
+  emit('update:visible', false)
+}
+
+function handleClose() {
+  emit('update:visible', false)
+}
+
+
+
+const handleUploadSuccess = (res: { code: number, data: { src: string, srcName: string, duration: number } }, file: any) => {
+  console.log(res, file)
+  if (res.code === 0) {
+    formData.value.voiceName = res.data.srcName
+    formData.value.audioUrl = res.data.src
+  }
+}
+
+const handleConfirm = async () => {
+  if(!editFormRef.value) return
+  const valid = await editFormRef.value.validate().catch(() => false)
+  if (!valid) {
+    return
+  }
+
+  cloneLoading.value = true
+
+  const {code, data} =  await cloneVoice({
+    name: formData.value.voiceName,
+    audioUrl: formData.value.audioUrl,
+    gender: formData.value.gender
+  })
+  cloneLoading.value = false
+  console.log(code, data)
+  if(code === 0){
+    toast.success('克隆成功')
+    emit('refresh')
+  }
+
+  // 关闭对话框
+  emit('update:visible', false)
+}
+
+// 监听可见性变化
+watch(() => props.visible, (newVisible) => {
+  resetForm()
+})
+
+
+// 重置表单
+function resetForm() {
+  console.log('reset')
+  if (editFormRef.value) {
+    editFormRef.value.resetFields()
+  }
+  formData.value = {
+    audioUrl: '',
+    voiceName: '',
+    gender: 1,
+  }
+}
+
+
+</script>
+<template>
+  <ElDialog title="克隆声音" v-model="dialogVisible" align-center @close="handleClose"
+      width="400" :z-index="2000">
+      <ElForm ref="editFormRef" :model="formData" :rules="formRules" label-width="120px" class="mt-4 space-y-4 w-full" :disabled="cloneLoading">
+        <ElFormItem label="voice" prop="audioUrl" label-width="120">
+           <AudioFileUploader :disabled="cloneLoading" @on-success="handleUploadSuccess"><ElButton type="primary" :icon="Plus">上传声音</ElButton></AudioFileUploader>
+        </ElFormItem>
+
+        <ElFormItem label="voice name" prop="voiceName" label-width="120">
+           <ElInput v-model="formData.voiceName" :disabled="!formData.audioUrl.length" placeholder="Enter name"  />
+        </ElFormItem>
+        <ElFormItem label="gender" prop="gender" label-width="120">
+        <ElSelect v-model="formData.gender" placeholder="选择性别" style="width: 120px; margin-bottom: 20px;">
+          <ElOption label="男声" :value="1"></ElOption>
+          <ElOption label="女声" :value="2"></ElOption>
+        </ElSelect>
+        </ElFormItem>
+      </ElForm>
+
+      <template #footer>
+        <div class="flex justify-end space-x-2">
+          <ElButton :loading="cloneLoading" type="primary" @click="handleConfirm"  :disabled="cloneLoading">确定</ElButton>
+        </div>
+      </template>
+    </ElDialog>
+</template>

+ 1 - 2
src/views/voice-management/components/SearchForm.vue

@@ -65,7 +65,6 @@ function handleClear() {
           <ElFormItem label="性别" prop="gender" label-width="120">
             <ElSelect v-model="searchParams.gender" style="width: 120px;">
               <ElOption :value="-1" label="全部">全部</ElOption>
-              <!-- <ElOption :value="0" label="全部">全部</ElOption> -->
               <ElOption :value="1" label="女">女</ElOption>
               <ElOption :value="2" label="男">男</ElOption>
             </ElSelect>
@@ -74,7 +73,7 @@ function handleClear() {
             <ElSelect v-model="searchParams.type" style="width: 120px;">
               <ElOption :value="1" label="系统">系统</ElOption>
               <ElOption :value="2" label="系统克隆">系统克隆</ElOption>
-              <ElOption :value="3" label="系统克隆">用户</ElOption>
+              <ElOption :value="3" label="用户">用户</ElOption>
             </ElSelect>
           </ElFormItem>
           <ElFormItem>

+ 5 - 3
src/views/voice-management/index.vue

@@ -8,7 +8,8 @@ import { ElButton, ElDialog, ElEmpty, ElInput, ElOption, ElPagination, ElSelect,
 import SearchForm from './components/SearchForm.vue'
 import type { TSearchParams } from './components/SearchForm.vue'
 import EditForm from './components/EditForm.vue'
-import AudioFileUploader from '@/components/Uploader/AudioFileUploader.vue'
+import EditClone from './components/EditClone.vue'
+
 import type { TVoice } from '@/types/voice'
 import { toast } from 'vue-sonner'
 import { voiceList, cloneVoice } from '@/api/modules/voice'
@@ -28,6 +29,7 @@ const searchParams = ref<TSearchParams>({
 })
 const dataList = ref<TVoice[]>([]);
 const editFormVisible = ref(false)
+const editCloneVisible = ref(false)
 const editMode = ref<'create' | 'edit'>('create')
 const currentData = ref<{
     "id": string|undefined,
@@ -192,8 +194,7 @@ onMounted(async () => {
     <FaPageMain class="flex-1 overflow-auto" main-class="flex-1 flex flex-col overflow-auto">
       <div class="pb-4">
         <ElSpace>
-          <AudioFileUploader :disabled="cloneLoading" @on-success="handleUploadSuccess"><ElButton type="primary" :icon="Plus">克隆声音</ElButton></AudioFileUploader>
-          <!-- <ElButton type="primary" :icon="Plus" @click="handleClone">克隆声音</ElButton> -->
+          <ElButton type="primary" :icon="Plus" @click="()=> editCloneVisible = true">克隆声音</ElButton>
         </ElSpace>
       </div>
       <ElTable
@@ -237,6 +238,7 @@ onMounted(async () => {
       </div>
     </FaPageMain>
     <EditForm v-model="currentData" v-model:visible="editFormVisible" :mode="editMode" @refresh="fetchData"></EditForm>
+    <EditClone v-model:visible="editCloneVisible" @refresh="fetchData"></EditClone>
   </div>
 </template>
 <style scoped>