update:智控台音色克隆

This commit is contained in:
hrz
2025-10-07 23:54:42 +08:00
parent bef7f79f40
commit 3249970b7b
42 changed files with 4140 additions and 531 deletions
+138 -86
View File
@@ -16,6 +16,34 @@
:style="{ filter: $route.path === '/home' || $route.path === '/role-config' || $route.path === '/device-management' ? 'brightness(0) invert(1)' : 'None' }" />
<span class="nav-text">{{ $t('header.smartManagement') }}</span>
</div>
<!-- 普通用户显示音色克隆 -->
<div v-if="!isSuperAdmin" class="equipment-management"
:class="{ 'active-tab': $route.path === '/voice-clone-management' }" @click="goVoiceCloneManagement">
<img loading="lazy" alt="" src="@/assets/header/voice.png"
:style="{ filter: $route.path === '/voice-clone-management' ? 'brightness(0) invert(1)' : 'None' }" />
<span class="nav-text">{{ $t('header.voiceCloneManagement') }}</span>
</div>
<!-- 超级管理员显示音色克隆下拉菜单 -->
<el-dropdown v-if="isSuperAdmin" trigger="click" class="equipment-management more-dropdown"
:class="{ 'active-tab': $route.path === '/voice-clone-management' || $route.path === '/voice-resource-management' }"
@visible-change="handleVoiceCloneDropdownVisibleChange">
<span class="el-dropdown-link">
<img loading="lazy" alt="" src="@/assets/header/voice.png"
:style="{ filter: $route.path === '/voice-clone-management' || $route.path === '/voice-resource-management' ? 'brightness(0) invert(1)' : 'None' }" />
<span class="nav-text">{{ $t('header.voiceCloneManagement') }}</span>
<i class="el-icon-arrow-down el-icon--right" :class="{ 'rotate-down': voiceCloneDropdownVisible }"></i>
</span>
<el-dropdown-menu slot="dropdown">
<el-dropdown-item @click.native="goVoiceCloneManagement">
{{ $t('header.voiceCloneManagement') }}
</el-dropdown-item>
<el-dropdown-item @click.native="goVoiceResourceManagement">
{{ $t('header.voiceResourceManagement') }}
</el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
<div v-if="isSuperAdmin" class="equipment-management" :class="{ 'active-tab': $route.path === '/model-config' }"
@click="goModelConfig">
<img loading="lazy" alt="" src="@/assets/header/model_config.png"
@@ -28,22 +56,19 @@
:style="{ filter: $route.path === '/user-management' ? 'brightness(0) invert(1)' : 'None' }" />
<span class="nav-text">{{ $t('header.userManagement') }}</span>
</div>
<div v-if="isSuperAdmin" class="equipment-management"
:class="{ 'active-tab': $route.path === '/ota-management' }" @click="goOtaManagement">
<img loading="lazy" alt="" src="@/assets/header/firmware_update.png"
:style="{ filter: $route.path === '/ota-management' ? 'brightness(0) invert(1)' : 'None' }" />
<span class="nav-text">{{ $t('header.otaManagement') }}</span>
</div>
<el-dropdown v-if="isSuperAdmin" trigger="click" class="equipment-management more-dropdown"
:class="{ 'active-tab': $route.path === '/dict-management' || $route.path === '/params-management' || $route.path === '/provider-management' || $route.path === '/server-side-management' || $route.path === '/agent-template-management' }"
:class="{ 'active-tab': $route.path === '/dict-management' || $route.path === '/params-management' || $route.path === '/provider-management' || $route.path === '/server-side-management' || $route.path === '/agent-template-management' || $route.path === '/ota-management' }"
@visible-change="handleParamDropdownVisibleChange">
<span class="el-dropdown-link">
<img loading="lazy" alt="" src="@/assets/header/param_management.png"
:style="{ filter: $route.path === '/dict-management' || $route.path === '/params-management' || $route.path === '/provider-management' || $route.path === '/server-side-management' || $route.path === '/agent-template-management' ? 'brightness(0) invert(1)' : 'None' }" />
:style="{ filter: $route.path === '/dict-management' || $route.path === '/params-management' || $route.path === '/provider-management' || $route.path === '/server-side-management' || $route.path === '/agent-template-management' || $route.path === '/ota-management' ? 'brightness(0) invert(1)' : 'None' }" />
<span class="nav-text">{{ $t('header.paramDictionary') }}</span>
<i class="el-icon-arrow-down el-icon--right" :class="{ 'rotate-down': paramDropdownVisible }"></i>
</span>
<el-dropdown-menu slot="dropdown">
<el-dropdown-item @click.native="goOtaManagement">
{{ $t('header.otaManagement') }}
</el-dropdown-item>
<el-dropdown-item @click.native="goParamManagement">
{{ $t('header.paramManagement') }}
</el-dropdown-item>
@@ -91,37 +116,18 @@
</div>
</div>
<!-- 语言切换下拉菜单 -->
<el-dropdown trigger="click" class="language-dropdown" @visible-change="handleLanguageDropdownVisibleChange">
<span class="el-dropdown-link">
<span class="current-language-text">{{ currentLanguageText }}</span>
<i class="el-icon-arrow-down el-icon--right" :class="{ 'rotate-down': languageDropdownVisible }"></i>
</span>
<el-dropdown-menu slot="dropdown">
<el-dropdown-item @click.native="changeLanguage('zh_CN')">
{{ $t('language.zhCN') }}
</el-dropdown-item>
<el-dropdown-item @click.native="changeLanguage('zh_TW')">
{{ $t('language.zhTW') }}
</el-dropdown-item>
<el-dropdown-item @click.native="changeLanguage('en')">
{{ $t('language.en') }}
</el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
<img loading="lazy" alt="" src="@/assets/home/avatar.png" class="avatar-img" />
<el-dropdown trigger="click" class="user-dropdown" @visible-change="handleUserDropdownVisibleChange">
<span class="el-dropdown-link">
{{ userInfo.username || '加载中...' }}
<i class="el-icon-arrow-down el-icon--right" :class="{ 'rotate-down': userDropdownVisible }"></i>
</span>
<el-dropdown-menu slot="dropdown">
<el-dropdown-item @click.native="showChangePasswordDialog">{{ $t('header.changePassword')
}}</el-dropdown-item>
<el-dropdown-item @click.native="handleLogout">{{ $t('header.logout') }}</el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
<img loading="lazy" alt="" src="@/assets/home/avatar.png" class="avatar-img" @click="handleAvatarClick" />
<span class="el-dropdown-link" @click="handleAvatarClick">
{{ userInfo.username || '加载中...' }}
<i class="el-icon-arrow-down el-icon--right"></i>
</span>
<el-cascader :options="userMenuOptions" trigger="click" :props="cascaderProps"
style="width: 0px;overflow: hidden;" :show-all-levels="false" @change="handleCascaderChange"
ref="userCascader">
<template slot-scope="{ data }">
<span>{{ data.label }}</span>
</template>
</el-cascader>
</div>
</div>
@@ -150,15 +156,21 @@ export default {
mobile: ''
},
isChangePasswordDialogVisible: false, // 控制修改密码弹窗的显示
userDropdownVisible: false,
paramDropdownVisible: false,
languageDropdownVisible: false,
voiceCloneDropdownVisible: false,
isSmallScreen: false,
// 搜索历史相关
searchHistory: [],
showHistory: false,
SEARCH_HISTORY_KEY: 'xiaozhi_search_history',
MAX_HISTORY_COUNT: 3
MAX_HISTORY_COUNT: 3,
// Cascader 配置
cascaderProps: {
expandTrigger: 'click',
value: 'value',
label: 'label',
children: 'children'
}
}
},
computed: {
@@ -183,6 +195,37 @@ export default {
default:
return this.$t('language.zhCN');
}
},
// 用户菜单选项
userMenuOptions() {
return [
{
label: this.currentLanguageText,
value: 'language',
children: [
{
label: this.$t('language.zhCN'),
value: 'zh_CN'
},
{
label: this.$t('language.zhTW'),
value: 'zh_TW'
},
{
label: this.$t('language.en'),
value: 'en'
}
]
},
{
label: this.$t('header.changePassword'),
value: 'changePassword'
},
{
label: this.$t('header.logout'),
value: 'logout'
}
];
}
},
mounted() {
@@ -207,6 +250,9 @@ export default {
goModelConfig() {
this.$router.push('/model-config')
},
goVoiceCloneManagement() {
this.$router.push('/voice-clone-management')
},
goParamManagement() {
this.$router.push('/params-management')
},
@@ -222,6 +268,11 @@ export default {
goServerSideManagement() {
this.$router.push('/server-side-management')
},
// 跳转到音色资源管理
goVoiceResourceManagement() {
this.$router.push('/voice-resource-management')
},
// 添加默认角色模板管理导航方法
goAgentTemplateManagement() {
this.$router.push('/agent-template-management')
@@ -364,27 +415,55 @@ export default {
});
}
},
handleUserDropdownVisibleChange(visible) {
this.userDropdownVisible = visible;
},
// 监听第二个下拉菜单的可见状态变化
// 监听参数字典下拉菜单的可见状态变化
handleParamDropdownVisibleChange(visible) {
this.paramDropdownVisible = visible;
},
// 监听语言下拉菜单的可见状态变化
handleLanguageDropdownVisibleChange(visible) {
this.languageDropdownVisible = visible;
// 监听音色克隆下拉菜单的可见状态变化
handleVoiceCloneDropdownVisibleChange(visible) {
this.voiceCloneDropdownVisible = visible;
},
// 处理 Cascader 选择变化
handleCascaderChange(value) {
if (!value || value.length === 0) {
return;
}
const action = value[value.length - 1];
// 处理语言切换
if (value.length === 2 && value[0] === 'language') {
this.changeLanguage(action);
return;
}
// 处理其他操作
switch (action) {
case 'changePassword':
this.showChangePasswordDialog();
break;
case 'logout':
this.handleLogout();
break;
}
},
// 切换语言
changeLanguage(lang) {
changeLanguage(lang);
this.languageDropdownVisible = false;
this.$message.success({
message: this.$t('message.success'),
showClose: true
});
},
// 点击头像触发cascader下拉菜单
handleAvatarClick() {
if (this.$refs.userCascader) {
this.$refs.userCascader.toggleDropDownVisible();
}
},
// 使用 mapActions 引入 Vuex 的 logout action
...mapActions(['logout'])
}
@@ -430,7 +509,7 @@ export default {
align-items: center;
gap: 25px;
position: absolute;
left: 44%;
left: 50%;
transform: translateX(-50%);
}
@@ -542,6 +621,13 @@ export default {
visibility: hidden;
}
.more-dropdown .el-dropdown-link {
display: flex;
align-items: center;
gap: 7px;
}
.search-history-item:hover .clear-item-icon {
visibility: visible;
}
@@ -579,41 +665,7 @@ export default {
width: 21px;
height: 21px;
flex-shrink: 0;
}
.user-dropdown {
flex-shrink: 0;
}
.language-dropdown {
flex-shrink: 0;
margin-right: 5px;
}
.current-language-text {
margin-left: 4px;
margin-right: 4px;
font-size: 12px;
color: #3d4566;
}
.more-dropdown {
padding-right: 20px;
}
.more-dropdown .el-dropdown-link {
display: flex;
align-items: center;
gap: 7px;
}
.rotate-down {
transform: rotate(180deg);
transition: transform 0.3s ease;
}
.el-icon-arrow-down {
transition: transform 0.3s ease;
cursor: pointer;
}
/* 导航文本样式 - 支持中英文换行 */