updata:智控台页面添加语言切换,支持中英繁。

This commit is contained in:
rainv123
2025-09-11 17:10:50 +08:00
parent a9b0775469
commit 98a1483032
41 changed files with 3800 additions and 1061 deletions
+102 -54
View File
@@ -3,23 +3,23 @@
<HeaderBar />
<div class="operation-bar">
<h2 class="page-title">字段管理</h2>
<h2 class="page-title">{{ $t('header.providerManagement') }}</h2>
<div class="right-operations">
<el-dropdown trigger="click" @command="handleSelectModelType" @visible-change="handleDropdownVisibleChange">
<el-button class="category-btn">
类别筛选 {{ selectedModelTypeLabel }}<i class="el-icon-arrow-down el-icon--right"
{{ $t('providerManagement.categoryFilter') }} {{ selectedModelTypeLabel }}<i class="el-icon-arrow-down el-icon--right"
:class="{ 'rotate-down': DropdownVisible }"></i>
</el-button>
<el-dropdown-menu slot="dropdown">
<el-dropdown-item command="">全部</el-dropdown-item>
<el-dropdown-item v-for="item in modelTypes" :key="item.value" :command="item.value">
<el-dropdown-item command="">{{ $t('common.all') }}</el-dropdown-item>
<el-dropdown-item v-for="item in translatedModelTypes" :key="item.value" :command="item.value">
{{ item.label }}
</el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
<el-input placeholder="请输入供应器名称查询" v-model="searchName" class="search-input" @keyup.enter.native="handleSearch"
<el-input :placeholder="$t('providerManagement.searchPlaceholder')" v-model="searchName" class="search-input" @keyup.enter.native="handleSearch"
clearable />
<el-button class="btn-search" @click="handleSearch">搜索</el-button>
<el-button class="btn-search" @click="handleSearch">{{ $t('common.search') }}</el-button>
</div>
</div>
@@ -30,23 +30,23 @@
<el-table ref="providersTable" :data="filteredProvidersList" class="transparent-table" v-loading="loading"
element-loading-text="拼命加载中" element-loading-spinner="el-icon-loading"
element-loading-background="rgba(255, 255, 255, 0.7)" :header-cell-class-name="headerCellClassName">
<el-table-column label="选择" align="center" width="120">
<el-table-column :label="$t('modelConfig.select')" align="center" width="120">
<template slot-scope="scope">
<el-checkbox v-model="scope.row.selected"></el-checkbox>
</template>
</el-table-column>
<el-table-column label="类别" prop="modelType" align="center" width="200">
<el-table-column :label="$t('providerManagement.category')" prop="modelType" align="center" width="200">
<template slot="header" slot-scope="scope">
<el-dropdown trigger="click" @command="handleSelectModelType"
@visible-change="isDropdownOpen = $event">
<span class="dropdown-trigger" :class="{ 'active': isDropdownOpen }">
类别{{ selectedModelTypeLabel }} <i class="dropdown-arrow"
{{ $t('providerManagement.category') }}{{ selectedModelTypeLabel }} <i class="dropdown-arrow"
:class="{ 'is-active': isDropdownOpen }"></i>
</span>
<el-dropdown-menu slot="dropdown">
<el-dropdown-item command="">全部</el-dropdown-item>
<el-dropdown-item v-for="item in modelTypes" :key="item.value" :command="item.value">
<el-dropdown-item command="">{{ $t('common.all') }}</el-dropdown-item>
<el-dropdown-item v-for="item in translatedModelTypes" :key="item.value" :command="item.value">
{{ item.label }}
</el-dropdown-item>
</el-dropdown-menu>
@@ -58,25 +58,25 @@
</el-tag>
</template>
</el-table-column>
<el-table-column label="供应器编码" prop="providerCode" align="center" width="150"></el-table-column>
<el-table-column label="名称" prop="name" align="center"></el-table-column>
<el-table-column label="字段配置" align="center">
<el-table-column :label="$t('providerManagement.providerCode')" prop="providerCode" align="center" width="150"></el-table-column>
<el-table-column :label="$t('common.name')" prop="name" align="center"></el-table-column>
<el-table-column :label="$t('providerManagement.fieldConfig')" align="center">
<template slot-scope="scope">
<el-popover placement="top-start" width="400" trigger="hover">
<div v-for="field in scope.row.fields" :key="field.key" class="field-item">
<span class="field-label">{{ field.label }}:</span>
<span class="field-type">{{ field.type }}</span>
<span v-if="isSensitiveField(field.key)" class="sensitive-tag">敏感</span>
<span v-if="isSensitiveField(field.key)" class="sensitive-tag">{{ $t('common.sensitive') }}</span>
</div>
<el-button slot="reference" size="mini" type="text">查看字段</el-button>
<el-button slot="reference" size="mini" type="text">{{ $t('providerManagement.viewFields') }}</el-button>
</el-popover>
</template>
</el-table-column>
<el-table-column label="排序" prop="sort" align="center" width="80"></el-table-column>
<el-table-column label="操作" align="center" width="180">
<el-table-column :label="$t('common.sort')" prop="sort" align="center" width="80"></el-table-column>
<el-table-column :label="$t('common.action')" align="center" width="180">
<template slot-scope="scope">
<el-button size="mini" type="text" @click="editProvider(scope.row)">编辑</el-button>
<el-button size="mini" type="text" @click="deleteProvider(scope.row)">删除</el-button>
<el-button size="mini" type="text" @click="editProvider(scope.row)">{{ $t('common.edit') }}</el-button>
<el-button size="mini" type="text" @click="deleteProvider(scope.row)">{{ $t('common.delete') }}</el-button>
</template>
</el-table-column>
</el-table>
@@ -84,31 +84,31 @@
<div class="table_bottom">
<div class="ctrl_btn">
<el-button size="mini" type="primary" class="select-all-btn" @click="handleSelectAll">
{{ isAllSelected ? '取消全选' : '全选' }}
{{ isAllSelected ? $t('common.deselectAll') : $t('common.selectAll') }}
</el-button>
<el-button size="mini" type="success" @click="showAddDialog">新增</el-button>
<el-button size="mini" type="danger" icon="el-icon-delete" @click="deleteSelectedProviders">删除
<el-button size="mini" type="success" @click="showAddDialog">{{ $t('common.add') }}</el-button>
<el-button size="mini" type="danger" icon="el-icon-delete" @click="deleteSelectedProviders">{{ $t('common.delete') }}
</el-button>
</div>
<div class="custom-pagination">
<el-select v-model="pageSize" @change="handlePageSizeChange" class="page-size-select">
<el-option v-for="item in pageSizeOptions" :key="item" :label="`${item}条/页`" :value="item">
<el-option v-for="item in pageSizeOptions" :key="item" :label="$t('common.perPage', { number: item })" :value="item">
</el-option>
</el-select>
<button class="pagination-btn" :disabled="currentPage === 1" @click="goFirst">
首页
{{ $t('common.firstPage') }}
</button>
<button class="pagination-btn" :disabled="currentPage === 1" @click="goPrev">
上一页
{{ $t('common.prevPage') }}
</button>
<button v-for="page in visiblePages" :key="page" class="pagination-btn"
:class="{ active: page === currentPage }" @click="goToPage(page)">
{{ page }}
</button>
<button class="pagination-btn" :disabled="currentPage === pageCount" @click="goNext">
下一页
{{ $t('common.nextPage') }}
</button>
<span class="total-text">{{ total }}条记录</span>
<span class="total-text">{{ $t('common.totalRecords', { number: total }) }}</span>
</div>
</div>
</el-card>
@@ -140,14 +140,14 @@ export default {
searchModelType: "",
providersList: [],
modelTypes: [
{ value: "ASR", label: "语音识别" },
{ value: "TTS", label: "语音合成" },
{ value: "LLM", label: "大语言模型" },
{ value: "VLLM", label: "视觉大语言模型" },
{ value: "Intent", label: "意图识别" },
{ value: "Memory", label: "记忆模块" },
{ value: "VAD", label: "语音活动检测" },
{ value: "Plugin", label: "插件工具" }
{ value: "ASR", labelKey: 'providerManagement.modelType.ASR' },
{ value: "TTS", labelKey: 'providerManagement.modelType.TTS' },
{ value: "LLM", labelKey: 'providerManagement.modelType.LLM' },
{ value: "VLLM", labelKey: 'providerManagement.modelType.VLLM' },
{ value: "Intent", labelKey: 'providerManagement.modelType.Intent' },
{ value: "Memory", labelKey: 'providerManagement.modelType.Memory' },
{ value: "VAD", labelKey: 'providerManagement.modelType.VAD' },
{ value: "Plugin", labelKey: 'providerManagement.modelType.Plugin' }
],
currentPage: 1,
loading: false,
@@ -174,10 +174,16 @@ export default {
this.fetchProviders();
},
computed: {
translatedModelTypes() {
return this.modelTypes.map(type => ({
value: type.value,
label: this.$t(type.labelKey)
}));
},
selectedModelTypeLabel() {
if (!this.searchModelType) return "(全部)";
if (!this.searchModelType) return `${this.$t('providerManagement.all')}`;
const selectedType = this.modelTypes.find(item => item.value === this.searchModelType);
return selectedType ? `${selectedType.label}` : "";
return selectedType ? `${this.$t(selectedType.labelKey)}` : "";
},
pageCount() {
return Math.ceil(this.total / this.pageSize);
@@ -259,7 +265,7 @@ export default {
});
},
showAddDialog() {
this.dialogTitle = "新增供应器";
this.dialogTitle = this.$t('common.addProvider');
this.providerForm = {
id: null,
modelType: "",
@@ -271,7 +277,7 @@ export default {
this.dialogVisible = true;
},
editProvider(row) {
this.dialogTitle = "编辑供应器";
this.dialogTitle = this.$t('common.editProvider');
this.providerForm = {
...row,
fields: JSON.parse(JSON.stringify(row.fields))
@@ -287,9 +293,9 @@ export default {
if (data.code === 0) {
this.fetchProviders(); // 刷新表格
this.$message.success({
message: "修改成功",
showClose: true
});
message: this.$t('common.updateSuccess'),
showClose: true
});
}
});
} else {
@@ -298,9 +304,9 @@ export default {
if (data.code === 0) {
this.fetchProviders(); // 刷新表格
this.$message.success({
message: "新增成功",
showClose: true
});
message: this.$t('common.addSuccess'),
showClose: true
});
this.total += 1;
}
});
@@ -313,7 +319,7 @@ export default {
const selectedRows = this.providersList.filter(row => row.selected);
if (selectedRows.length === 0) {
this.$message.warning({
message: "请先选择需要删除的供应器",
message: this.$t('providerManagement.selectToDelete'),
showClose: true
});
return;
@@ -324,9 +330,9 @@ export default {
const providers = Array.isArray(row) ? row : [row];
const providerCount = providers.length;
this.$confirm(`确定要删除选中的${providerCount}个供应器吗?`, '警告', {
confirmButtonText: '确定',
cancelButtonText: '取消',
this.$confirm(this.$t('providerManagement.confirmDelete', { count: providerCount }), this.$t('common.warning'), {
confirmButtonText: this.$t('common.confirm'),
cancelButtonText: this.$t('common.cancel'),
type: 'warning',
}).then(() => {
const ids = providers.map(provider => provider.id);
@@ -337,12 +343,12 @@ export default {
this.fetchProviders(); // 刷新表格
this.$message.success({
message: `成功删除${providerCount}个参数`,
message: this.$t('common.deleteSuccess'),
showClose: true
});
} else {
this.$message.error({
message: data.msg || '删除失败,请重试',
message: data.msg || this.$t('common.deleteFailure'),
showClose: true
});
}
@@ -350,7 +356,7 @@ export default {
}).catch(() => {
this.$message({
type: 'info',
message: '已取消删除',
message: this.$t('common.deleteCancelled'),
showClose: true,
duration: 1000
});
@@ -369,7 +375,7 @@ export default {
},
getModelTypeLabel(type) {
const typeItem = this.modelTypes.find(item => item.value === type);
return typeItem ? typeItem.label : type;
return typeItem ? this.$t(typeItem.labelKey) : type;
},
isSensitiveField(fieldKey) {
if (typeof fieldKey !== 'string') return false;
@@ -388,6 +394,26 @@ export default {
}
return "";
},
selectionCellClassName() {
return "custom-selection-cell";
},
updateSelectionHeaderText() {
// 确保表格已渲染
this.$nextTick(() => {
if (this.$refs.providersTable && this.$refs.providersTable.$el) {
const headerCheckbox = this.$refs.providersTable.$el.querySelector('.custom-selection-header .el-checkbox .el-checkbox__label');
if (headerCheckbox) {
headerCheckbox.textContent = this.$t('modelConfig.select');
}
}
});
},
mounted() {
this.updateSelectionHeaderText();
},
updated() {
this.updateSelectionHeaderText();
},
goFirst() {
this.currentPage = 1;
this.fetchProviders();
@@ -875,4 +901,26 @@ export default {
.dropdown-trigger.active {
color: #409EFF;
}
/* 确保选择列标题样式正确 */
.custom-selection-header {
position: relative;
}
:deep(.custom-selection-header .el-checkbox) {
display: flex !important;
align-items: center;
justify-content: center;
}
:deep(.custom-selection-header .el-checkbox__label) {
position: relative;
white-space: nowrap;
}
:deep(.custom-selection-cell) {
display: flex;
align-items: center;
justify-content: center;
}
</style>