2025-10-07 23:54:42 +08:00
|
|
|
<template>
|
2026-06-23 17:23:11 +08:00
|
|
|
<CustomDialog
|
|
|
|
|
:title="title"
|
|
|
|
|
:visible.sync="dialogVisible"
|
|
|
|
|
:close-on-click-modal="false"
|
|
|
|
|
width="600px"
|
|
|
|
|
@close="handleClose"
|
|
|
|
|
@open="handleOpen"
|
|
|
|
|
@cancel="handleCancel"
|
|
|
|
|
@confirm="handleSubmit"
|
|
|
|
|
>
|
|
|
|
|
<el-form ref="form" :model="form" :rules="rules" label-width="auto">
|
2025-10-07 23:54:42 +08:00
|
|
|
<el-form-item :label="$t('voiceClone.platformName')" prop="modelId">
|
|
|
|
|
<el-select v-model="form.modelId" :placeholder="$t('voiceClone.platformNamePlaceholder')" filterable
|
|
|
|
|
style="width: 100%" @change="handlePlatformChange">
|
|
|
|
|
<el-option v-for="model in platformList" :key="model.id" :label="model.modelName" :value="model.id">
|
|
|
|
|
</el-option>
|
|
|
|
|
</el-select>
|
|
|
|
|
</el-form-item>
|
|
|
|
|
|
|
|
|
|
<el-form-item :label="$t('voiceClone.voiceId')" prop="voiceIds">
|
|
|
|
|
<el-select v-model="form.voiceIds" :placeholder="$t('voiceClone.voiceIdPlaceholder')" filterable multiple
|
|
|
|
|
allow-create default-first-option style="width: 100%">
|
|
|
|
|
<el-option v-for="voiceId in voiceIdList" :key="voiceId" :label="voiceId" :value="voiceId">
|
|
|
|
|
</el-option>
|
|
|
|
|
</el-select>
|
|
|
|
|
</el-form-item>
|
|
|
|
|
|
|
|
|
|
<el-form-item :label="$t('voiceClone.userId')" prop="userId">
|
|
|
|
|
<el-select v-model="form.userId" :placeholder="$t('voiceClone.userIdPlaceholder')" filterable remote
|
|
|
|
|
:remote-method="remoteSearchUser" :loading="userLoading" style="width: 100%">
|
|
|
|
|
<el-option v-for="user in userList" :key="user.userid" :label="user.mobile" :value="user.userid">
|
|
|
|
|
</el-option>
|
|
|
|
|
</el-select>
|
|
|
|
|
</el-form-item>
|
2026-03-11 10:30:29 +08:00
|
|
|
|
|
|
|
|
<el-form-item :label="$t('voiceClone.languages')" prop="languages">
|
|
|
|
|
<el-input v-model="form.languages" :placeholder="$t('voiceClone.languagesPlaceholder')" style="width: 100%">
|
|
|
|
|
</el-input>
|
|
|
|
|
</el-form-item>
|
2025-10-07 23:54:42 +08:00
|
|
|
</el-form>
|
2026-06-23 17:23:11 +08:00
|
|
|
</CustomDialog>
|
2025-10-07 23:54:42 +08:00
|
|
|
</template>
|
|
|
|
|
|
|
|
|
|
<script>
|
|
|
|
|
import Api from '@/apis/api';
|
2026-06-23 17:23:11 +08:00
|
|
|
import CustomDialog from './CustomDialog.vue';
|
2025-10-07 23:54:42 +08:00
|
|
|
|
|
|
|
|
export default {
|
|
|
|
|
name: 'VoiceCloneDialog',
|
2026-06-23 17:23:11 +08:00
|
|
|
components: { CustomDialog },
|
2025-10-07 23:54:42 +08:00
|
|
|
props: {
|
|
|
|
|
visible: {
|
|
|
|
|
type: Boolean,
|
|
|
|
|
default: false
|
|
|
|
|
},
|
|
|
|
|
title: {
|
|
|
|
|
type: String,
|
|
|
|
|
default: ''
|
|
|
|
|
},
|
|
|
|
|
form: {
|
|
|
|
|
type: Object,
|
|
|
|
|
default: () => ({})
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
data() {
|
|
|
|
|
return {
|
|
|
|
|
dialogVisible: this.visible,
|
|
|
|
|
platformList: [],
|
|
|
|
|
voiceIdList: [],
|
|
|
|
|
userList: [],
|
|
|
|
|
userLoading: false,
|
|
|
|
|
rules: {
|
|
|
|
|
modelId: [
|
|
|
|
|
{ required: true, message: this.$t('voiceClone.platformNameRequired'), trigger: 'change' }
|
|
|
|
|
],
|
|
|
|
|
voiceIds: [
|
|
|
|
|
{ required: true, message: this.$t('voiceClone.voiceIdRequired'), trigger: 'change' }
|
|
|
|
|
],
|
|
|
|
|
userId: [
|
|
|
|
|
{ required: true, message: this.$t('voiceClone.userIdRequired'), trigger: 'change' }
|
2026-03-11 10:30:29 +08:00
|
|
|
],
|
|
|
|
|
languages: [
|
|
|
|
|
{ required: true, message: this.$t('voiceClone.languagesRequired'), trigger: 'blur' }
|
2025-10-07 23:54:42 +08:00
|
|
|
]
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
watch: {
|
|
|
|
|
visible(val) {
|
|
|
|
|
this.dialogVisible = val;
|
|
|
|
|
},
|
|
|
|
|
dialogVisible(val) {
|
|
|
|
|
this.$emit('update:visible', val);
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
methods: {
|
|
|
|
|
handleClose() {
|
|
|
|
|
this.dialogVisible = false;
|
|
|
|
|
this.$emit('cancel');
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
handleCancel() {
|
|
|
|
|
this.$refs.form.clearValidate();
|
|
|
|
|
this.$emit('cancel');
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
handleSubmit() {
|
|
|
|
|
this.$refs.form.validate(valid => {
|
|
|
|
|
if (valid) {
|
|
|
|
|
this.$emit('submit', this.form);
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
handleOpen() {
|
|
|
|
|
// 对话框打开时加载平台列表
|
|
|
|
|
this.fetchPlatformList();
|
|
|
|
|
// 重置音色ID列表
|
|
|
|
|
this.voiceIdList = [];
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
handlePlatformChange(modelId) {
|
|
|
|
|
// 清空音色ID选择
|
|
|
|
|
this.form.voiceIds = [];
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
// 获取TTS平台列表
|
|
|
|
|
fetchPlatformList() {
|
|
|
|
|
Api.voiceResource.getTtsPlatformList((res) => {
|
|
|
|
|
if (res.data.code === 0) {
|
|
|
|
|
this.platformList = res.data.data;
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
// 远程搜索用户
|
|
|
|
|
remoteSearchUser(query) {
|
|
|
|
|
if (query !== '') {
|
|
|
|
|
this.userLoading = true;
|
|
|
|
|
const params = {
|
|
|
|
|
page: 1,
|
|
|
|
|
limit: 20,
|
|
|
|
|
mobile: query
|
|
|
|
|
};
|
|
|
|
|
Api.admin.getUserList(params, (res) => {
|
|
|
|
|
this.userLoading = false;
|
|
|
|
|
if (res.data.code === 0) {
|
|
|
|
|
this.userList = res.data.data.list;
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
} else {
|
|
|
|
|
this.userList = [];
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
</script>
|