mirror of
https://github.com/xinnan-tech/xiaozhi-esp32-server.git
synced 2026-07-29 16:33:56 +08:00
@@ -115,7 +115,6 @@ export default {
|
|||||||
},
|
},
|
||||||
// 删除
|
// 删除
|
||||||
deleteParam(ids, callback) {
|
deleteParam(ids, callback) {
|
||||||
console.log(4444,ids )
|
|
||||||
RequestService.sendRequest()
|
RequestService.sendRequest()
|
||||||
.url(`${getServiceUrl()}/admin/params/delete`)
|
.url(`${getServiceUrl()}/admin/params/delete`)
|
||||||
.method('POST')
|
.method('POST')
|
||||||
|
|||||||
@@ -1,11 +1,8 @@
|
|||||||
// timbre.js
|
|
||||||
import {getServiceUrl} from '../api';
|
import {getServiceUrl} from '../api';
|
||||||
import RequestService from '../httpRequest';
|
import RequestService from '../httpRequest';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
/**
|
// 获取音色
|
||||||
* 获取音色数据
|
|
||||||
*/
|
|
||||||
getVoiceList(params, callback) {
|
getVoiceList(params, callback) {
|
||||||
const queryParams = new URLSearchParams({
|
const queryParams = new URLSearchParams({
|
||||||
ttsModelId: params.ttsModelId,
|
ttsModelId: params.ttsModelId,
|
||||||
@@ -28,9 +25,7 @@ export default {
|
|||||||
});
|
});
|
||||||
}).send();
|
}).send();
|
||||||
},
|
},
|
||||||
/**
|
// 音色保存
|
||||||
* 音色保存
|
|
||||||
*/
|
|
||||||
saveVoice(params, callback) {
|
saveVoice(params, callback) {
|
||||||
RequestService.sendRequest()
|
RequestService.sendRequest()
|
||||||
.url(`${getServiceUrl()}/ttsVoice`)
|
.url(`${getServiceUrl()}/ttsVoice`)
|
||||||
@@ -54,15 +49,12 @@ export default {
|
|||||||
});
|
});
|
||||||
}).send();
|
}).send();
|
||||||
},
|
},
|
||||||
/**
|
// 音色删除
|
||||||
* 音色删除
|
deleteVoice(ids, callback) {
|
||||||
*/
|
|
||||||
deleteVoice(id, callback) {
|
|
||||||
console.log('尝试删除音色,ID:', id);
|
|
||||||
RequestService.sendRequest()
|
RequestService.sendRequest()
|
||||||
.url(`${getServiceUrl()}/ttsVoice`)
|
.url(`${getServiceUrl()}/ttsVoice/delete`)
|
||||||
.method('DELETE')
|
.method('POST')
|
||||||
.data({ ids: [id] })
|
.data(ids)
|
||||||
.success((res) => {
|
.success((res) => {
|
||||||
RequestService.clearRequestTime()
|
RequestService.clearRequestTime()
|
||||||
callback(res);
|
callback(res);
|
||||||
@@ -70,13 +62,11 @@ export default {
|
|||||||
.fail((err) => {
|
.fail((err) => {
|
||||||
console.error('删除音色失败:', err);
|
console.error('删除音色失败:', err);
|
||||||
RequestService.reAjaxFun(() => {
|
RequestService.reAjaxFun(() => {
|
||||||
this.deleteVoice(id, callback);
|
this.deleteVoice(ids, callback);
|
||||||
});
|
});
|
||||||
}).send();
|
}).send();
|
||||||
},
|
},
|
||||||
/**
|
// 音色修改
|
||||||
* 音色修改
|
|
||||||
*/
|
|
||||||
updateVoice(params, callback) {
|
updateVoice(params, callback) {
|
||||||
RequestService.sendRequest()
|
RequestService.sendRequest()
|
||||||
.url(`${getServiceUrl()}/ttsVoice/${params.id}`)
|
.url(`${getServiceUrl()}/ttsVoice/${params.id}`)
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
<template>
|
<template>
|
||||||
<el-dialog
|
<el-dialog
|
||||||
:visible.sync="localVisible"
|
:visible.sync="localVisible"
|
||||||
width="75%"
|
width="85%"
|
||||||
@close="handleClose"
|
@close="handleClose"
|
||||||
:show-close="false"
|
:show-close="false"
|
||||||
:append-to-body="true"
|
:append-to-body="true"
|
||||||
@@ -13,8 +13,7 @@
|
|||||||
<div
|
<div
|
||||||
class="table-container"
|
class="table-container"
|
||||||
ref="tableContainer"
|
ref="tableContainer"
|
||||||
@scroll="handleScroll"
|
@scroll="handleScroll">
|
||||||
>
|
|
||||||
<el-table
|
<el-table
|
||||||
v-loading="loading"
|
v-loading="loading"
|
||||||
:data="filteredTtsModels"
|
:data="filteredTtsModels"
|
||||||
@@ -45,7 +44,7 @@
|
|||||||
<span v-else>{{ scope.row.languageType }}</span>
|
<span v-else>{{ scope.row.languageType }}</span>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column label="试听" align="center" min-width="225" class-name="audio-column">
|
<el-table-column label="试听" align="center" min-width="100px" class-name="audio-column">
|
||||||
<template slot-scope="scope">
|
<template slot-scope="scope">
|
||||||
<div class="custom-audio-container">
|
<div class="custom-audio-container">
|
||||||
<el-input
|
<el-input
|
||||||
@@ -53,13 +52,13 @@
|
|||||||
v-model="scope.row.voiceDemo"
|
v-model="scope.row.voiceDemo"
|
||||||
placeholder="请输入MP3地址"
|
placeholder="请输入MP3地址"
|
||||||
size="mini"
|
size="mini"
|
||||||
class="audio-input"
|
class="audio-input">
|
||||||
></el-input>
|
</el-input>
|
||||||
<AudioPlayer v-else-if="isValidAudioUrl(scope.row.voiceDemo)" :audioUrl="scope.row.voiceDemo"/>
|
<AudioPlayer v-else-if="isValidAudioUrl(scope.row.voiceDemo)" :audioUrl="scope.row.voiceDemo"/>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column label="备注" align="center" min-width="120">
|
<el-table-column label="备注" align="center">
|
||||||
<template slot-scope="scope">
|
<template slot-scope="scope">
|
||||||
<el-input
|
<el-input
|
||||||
v-if="scope.row.editing"
|
v-if="scope.row.editing"
|
||||||
@@ -75,10 +74,10 @@
|
|||||||
<el-table-column label="操作" align="center" width="150">
|
<el-table-column label="操作" align="center" width="150">
|
||||||
<template slot-scope="scope">
|
<template slot-scope="scope">
|
||||||
<template v-if="!scope.row.editing">
|
<template v-if="!scope.row.editing">
|
||||||
<el-button type="primary" size="mini" @click="startEdit(scope.row)"
|
<el-button type="text" size="mini" @click="startEdit(scope.row)" class="edit-btn">
|
||||||
style="background: #5cca8e;border:None">编辑
|
编辑
|
||||||
</el-button>
|
</el-button>
|
||||||
<el-button type="primary" size="mini" @click="deleteRow(scope.row)" style="background: red;border:None">
|
<el-button type="text" size="mini" @click="deleteRow(scope.row)" class="delete-btn">
|
||||||
删除
|
删除
|
||||||
</el-button>
|
</el-button>
|
||||||
</template>
|
</template>
|
||||||
@@ -105,10 +104,14 @@
|
|||||||
<el-button type="primary" size="mini" @click="toggleSelectAll" style="background: #606ff3;border: None">
|
<el-button type="primary" size="mini" @click="toggleSelectAll" style="background: #606ff3;border: None">
|
||||||
{{ selectAll ? '取消全选' : '全选' }}
|
{{ selectAll ? '取消全选' : '全选' }}
|
||||||
</el-button>
|
</el-button>
|
||||||
<el-button type="primary" size="mini" @click="addNew" style="background: #f6cf79;border: None; color: #000012">
|
<el-button type="primary" size="mini" @click="addNew" style="background: #5bc98c;border: None;">
|
||||||
新增
|
新增
|
||||||
</el-button>
|
</el-button>
|
||||||
<el-button type="primary" size="mini" @click="batchDelete" style="background: red;border:None">删除</el-button>
|
<el-button type="primary"
|
||||||
|
size="mini"
|
||||||
|
@click="deleteRow(filteredTtsModels.filter(row => row.selected))"
|
||||||
|
style="background: red;border:None">删除
|
||||||
|
</el-button>
|
||||||
</div>
|
</div>
|
||||||
</el-dialog>
|
</el-dialog>
|
||||||
</template>
|
</template>
|
||||||
@@ -419,105 +422,57 @@ export default {
|
|||||||
},
|
},
|
||||||
|
|
||||||
deleteRow(row) {
|
deleteRow(row) {
|
||||||
this.$confirm("确定要删除该音色吗?", "警告", {
|
// 处理单个音色或音色数组
|
||||||
confirmButtonText: "确定",
|
const voices = Array.isArray(row) ? row : [row];
|
||||||
cancelButtonText: "取消",
|
|
||||||
type: "warning",
|
if (Array.isArray(row) && row.length === 0) {
|
||||||
})
|
this.$message.warning("请先选择需要删除的音色");
|
||||||
.then(() => {
|
return;
|
||||||
Api.timbre.deleteVoice(row.id, (response) => {
|
}
|
||||||
if (response.code === 0) {
|
|
||||||
this.$message.success({
|
|
||||||
message: "删除成功",
|
const voiceCount = voices.length;
|
||||||
showClose: true
|
this.$confirm(`确定要删除选中的${voiceCount}个音色吗?`, "警告", {
|
||||||
});
|
confirmButtonText: "确定",
|
||||||
this.loadData(); // 刷新数据
|
cancelButtonText: "取消",
|
||||||
} else {
|
type: "warning",
|
||||||
this.$message.error({
|
distinguishCancelAndClose: true
|
||||||
message: response.msg || "删除失败",
|
}).then(() => {
|
||||||
showClose: true
|
const ids = voices.map(voice => voice.id);
|
||||||
});
|
if (ids.some(id => !id)) {
|
||||||
|
this.$message.error("存在无效的音色ID");
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
});
|
|
||||||
})
|
|
||||||
.catch(() => {
|
|
||||||
this.$message.info("已取消删除");
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
batchDelete() {
|
Api.timbre.deleteVoice(ids, ({data}) => {
|
||||||
const selectedRows = this.filteredTtsModels.filter(row => row.selected);
|
if (data.code === 0) {
|
||||||
if (selectedRows.length === 0) {
|
this.$message.success({
|
||||||
this.$message.warning("请先选择需要删除的音色");
|
message: `成功删除${voiceCount}个参数`,
|
||||||
return;
|
showClose: true
|
||||||
}
|
|
||||||
|
|
||||||
this.$confirm(`确定要删除选中的${selectedRows.length}个音色吗?`, "警告", {
|
|
||||||
confirmButtonText: "确定",
|
|
||||||
cancelButtonText: "取消",
|
|
||||||
type: "warning",
|
|
||||||
})
|
|
||||||
.then(async () => {
|
|
||||||
const loading = this.$loading({
|
|
||||||
lock: true,
|
|
||||||
text: "正在删除中...",
|
|
||||||
spinner: "el-icon-loading",
|
|
||||||
background: "rgba(0, 0, 0, 0.7)",
|
|
||||||
});
|
|
||||||
|
|
||||||
try {
|
|
||||||
const results = await Promise.all(
|
|
||||||
selectedRows.map((row) => {
|
|
||||||
return new Promise((resolve) => {
|
|
||||||
Api.timbre.deleteVoice(row.id, (response) => {
|
|
||||||
if (response.code === 0) {
|
|
||||||
resolve({ success: true, id: row.id });
|
|
||||||
} else {
|
|
||||||
resolve({
|
|
||||||
success: false,
|
|
||||||
id: row.id,
|
|
||||||
msg: response.msg || '删除失败'
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
})
|
this.loadData(); // 刷新参数列表
|
||||||
);
|
|
||||||
|
|
||||||
const successCount = results.filter(r => r.success).length;
|
|
||||||
const failCount = results.length - successCount;
|
|
||||||
|
|
||||||
if (failCount === 0) {
|
|
||||||
this.$message.success({
|
|
||||||
message: `成功删除${successCount}个音色`,
|
|
||||||
showClose: true
|
|
||||||
});
|
|
||||||
} else if (successCount === 0) {
|
|
||||||
this.$message.error({
|
|
||||||
message: '删除失败,请重试',
|
|
||||||
showClose: true
|
|
||||||
});
|
|
||||||
} else {
|
} else {
|
||||||
this.$message.warning({
|
this.$message.error({
|
||||||
message: `成功删除${successCount}个音色,${failCount}个删除失败`,
|
message: data.msg || '删除失败,请重试',
|
||||||
showClose: true
|
showClose: true
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
this.loadData(); // 刷新数据
|
|
||||||
} catch (error) {
|
|
||||||
console.error('批量删除出错:', error);
|
|
||||||
this.$message.error({
|
|
||||||
message: '删除过程中发生错误',
|
|
||||||
showClose: true
|
|
||||||
});
|
|
||||||
} finally {
|
|
||||||
loading.close();
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.catch(() => {
|
|
||||||
this.$message.info("已取消删除");
|
|
||||||
});
|
});
|
||||||
|
}).catch(action => {
|
||||||
|
if (action === 'cancel') {
|
||||||
|
this.$message({
|
||||||
|
type: 'info',
|
||||||
|
message: '已取消删除操作',
|
||||||
|
duration: 1000
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
this.$message({
|
||||||
|
type: 'info',
|
||||||
|
message: '操作已关闭',
|
||||||
|
duration: 1000
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
isValidAudioUrl(url) {
|
isValidAudioUrl(url) {
|
||||||
@@ -532,7 +487,7 @@ export default {
|
|||||||
::v-deep .el-dialog {
|
::v-deep .el-dialog {
|
||||||
border-radius: 8px !important;
|
border-radius: 8px !important;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
top: 8vh !important;
|
top: 1vh !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
::v-deep .el-dialog__header {
|
::v-deep .el-dialog__header {
|
||||||
@@ -628,13 +583,13 @@ export default {
|
|||||||
.table-container {
|
.table-container {
|
||||||
flex: 1;
|
flex: 1;
|
||||||
overflow-y: scroll;
|
overflow-y: scroll;
|
||||||
scrollbar-width: none; /* Firefox */
|
scrollbar-width: none;
|
||||||
padding-right: 15px; /* 为滚动条留出空间 */
|
padding-right: 15px;
|
||||||
width: calc(100% - 16px); /* 减去滚动条宽度 */
|
width: calc(100% - 16px);
|
||||||
}
|
}
|
||||||
|
|
||||||
.table-container::-webkit-scrollbar {
|
.table-container::-webkit-scrollbar {
|
||||||
display: none; /* Chrome/Safari */
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 自定义滚动条 */
|
/* 自定义滚动条 */
|
||||||
@@ -684,10 +639,33 @@ export default {
|
|||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* 音频播放器容器样式 */
|
||||||
|
.custom-audio-container {
|
||||||
|
width: 280px;
|
||||||
|
margin: auto;
|
||||||
|
}
|
||||||
|
|
||||||
/* 新增按钮组样式 */
|
/* 新增按钮组样式 */
|
||||||
.action-buttons {
|
.action-buttons {
|
||||||
bottom: 20px;
|
bottom: 20px;
|
||||||
padding-top: 10px;
|
padding-top: 10px;
|
||||||
}
|
}
|
||||||
|
.edit-btn,
|
||||||
|
.delete-btn,
|
||||||
|
.save-btn {
|
||||||
|
margin: 0 8px;
|
||||||
|
color: #7079aa !important;
|
||||||
|
transition: all 0.3s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.edit-btn:hover,
|
||||||
|
.delete-btn:hover,
|
||||||
|
.save-btn:hover {
|
||||||
|
color: #5f70f3 !important;
|
||||||
|
transform: scale(1.05);
|
||||||
|
}
|
||||||
|
|
||||||
|
.save-btn {
|
||||||
|
color: #5cca8e !important;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
@@ -3,7 +3,7 @@
|
|||||||
<HeaderBar />
|
<HeaderBar />
|
||||||
|
|
||||||
<div class="operation-bar">
|
<div class="operation-bar">
|
||||||
<h2 class="page-title">模型配置</h2>
|
<h2 class="page-title">{{ modelTypeText }}</h2>
|
||||||
<!-- <div class="right-operations">-->
|
<!-- <div class="right-operations">-->
|
||||||
<!-- <el-button plain size="small" @click="handleImport" style="background: #7b9de5; color: white;">-->
|
<!-- <el-button plain size="small" @click="handleImport" style="background: #7b9de5; color: white;">-->
|
||||||
<!-- <img loading="lazy" alt="" src="@/assets/model/inner_conf.png">-->
|
<!-- <img loading="lazy" alt="" src="@/assets/model/inner_conf.png">-->
|
||||||
@@ -14,6 +14,21 @@
|
|||||||
<!-- 导出配置-->
|
<!-- 导出配置-->
|
||||||
<!-- </el-button>-->
|
<!-- </el-button>-->
|
||||||
<!-- </div>-->
|
<!-- </div>-->
|
||||||
|
<div class="action-group">
|
||||||
|
<div class="search-group">
|
||||||
|
<el-input
|
||||||
|
placeholder="请输入模型名称查询"
|
||||||
|
v-model="search"
|
||||||
|
class="search-input"
|
||||||
|
clearable
|
||||||
|
@keyup.enter.native="handleSearch"
|
||||||
|
style="width: 240px"
|
||||||
|
/>
|
||||||
|
<el-button class="btn-search" @click="handleSearch">
|
||||||
|
搜索
|
||||||
|
</el-button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- 主体内容 -->
|
<!-- 主体内容 -->
|
||||||
@@ -44,23 +59,6 @@
|
|||||||
|
|
||||||
<!-- 右侧内容 -->
|
<!-- 右侧内容 -->
|
||||||
<div class="content-area">
|
<div class="content-area">
|
||||||
<div class="title-bar">
|
|
||||||
<div class="title-wrapper">
|
|
||||||
<h2 class="model-title">{{ modelTypeText }}</h2>
|
|
||||||
<el-button type="primary" size="small" @click="addModel" class="add-btn">
|
|
||||||
添加
|
|
||||||
</el-button>
|
|
||||||
</div>
|
|
||||||
<div class="action-group">
|
|
||||||
<div class="search-group">
|
|
||||||
<el-input placeholder="请输入模型名称查询" v-model="search" size="small" class="search-input" clearable @keyup.enter.native="handleSearch" />
|
|
||||||
<el-button type="primary" size="small" class="search-btn" @click="handleSearch">
|
|
||||||
查询
|
|
||||||
</el-button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<el-table ref="modelTable" style="width: 100%" :header-cell-style="{ background: 'transparent' }"
|
<el-table ref="modelTable" style="width: 100%" :header-cell-style="{ background: 'transparent' }"
|
||||||
:data="modelList" class="data-table" header-row-class-name="table-header"
|
:data="modelList" class="data-table" header-row-class-name="table-header"
|
||||||
:header-cell-class-name="headerCellClassName" @selection-change="handleSelectionChange">
|
:header-cell-class-name="headerCellClassName" @selection-change="handleSelectionChange">
|
||||||
@@ -103,9 +101,13 @@
|
|||||||
|
|
||||||
<div class="table-footer">
|
<div class="table-footer">
|
||||||
<div class="batch-actions">
|
<div class="batch-actions">
|
||||||
<el-button size="mini" @click="selectAll" style="width: 75px; background: #606ff3">{{ isAllSelected ?
|
<el-button size="mini" type="primary" @click="selectAll" >
|
||||||
'取消全选' : '全选'
|
{{ isAllSelected ?
|
||||||
}}</el-button>
|
'取消全选' : '全选' }}
|
||||||
|
</el-button>
|
||||||
|
<el-button type="success" size="mini" @click="addModel" class="add-btn">
|
||||||
|
新增
|
||||||
|
</el-button>
|
||||||
<el-button size="mini" type="danger" icon="el-icon-delete" @click="batchDelete">
|
<el-button size="mini" type="danger" icon="el-icon-delete" @click="batchDelete">
|
||||||
删除
|
删除
|
||||||
</el-button>
|
</el-button>
|
||||||
@@ -456,7 +458,7 @@ export default {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.main-wrapper {
|
.main-wrapper {
|
||||||
margin: 5px 20px;
|
margin: 5px 22px;
|
||||||
border-radius: 15px;
|
border-radius: 15px;
|
||||||
min-height: 600px;
|
min-height: 600px;
|
||||||
box-shadow: 0 2px 12px rgba(0, 0, 0, 0.1);
|
box-shadow: 0 2px 12px rgba(0, 0, 0, 0.1);
|
||||||
@@ -517,7 +519,7 @@ export default {
|
|||||||
justify-content: flex-end;
|
justify-content: flex-end;
|
||||||
padding-right: 12px !important;
|
padding-right: 12px !important;
|
||||||
width: fit-content;
|
width: fit-content;
|
||||||
margin: 8px 0px 8px auto;
|
margin: 8px 0 8px auto;
|
||||||
min-width: unset;
|
min-width: unset;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -567,12 +569,6 @@ export default {
|
|||||||
flex-wrap: nowrap;
|
flex-wrap: nowrap;
|
||||||
}
|
}
|
||||||
|
|
||||||
.model-title {
|
|
||||||
font-size: 18px;
|
|
||||||
color: #303133;
|
|
||||||
margin: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.action-group {
|
.action-group {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
@@ -581,28 +577,42 @@ export default {
|
|||||||
|
|
||||||
.search-group {
|
.search-group {
|
||||||
display: flex;
|
display: flex;
|
||||||
gap: 8px;
|
gap: 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.search-input {
|
.search-input {
|
||||||
width: 240px;
|
width: 240px;
|
||||||
}
|
}
|
||||||
|
|
||||||
::v-deep .search-input .el-input__inner::placeholder {
|
.btn-search {
|
||||||
color: black;
|
background: linear-gradient(135deg, #6b8cff, #a966ff);
|
||||||
opacity: 0.6;
|
border: none;
|
||||||
|
color: white;
|
||||||
}
|
}
|
||||||
|
|
||||||
::v-deep .search-input .el-input__inner {
|
::v-deep .search-input .el-input__inner {
|
||||||
background: transparent;
|
border-radius: 4px;
|
||||||
|
border: 1px solid #DCDFE6;
|
||||||
|
background-color: white;
|
||||||
|
transition: border-color 0.2s;
|
||||||
}
|
}
|
||||||
|
|
||||||
.search-btn {
|
::v-deep .search-input .el-input__inner:focus {
|
||||||
background: linear-gradient(135deg, #6B8CFF, #A966FF);
|
border-color: #6b8cff;
|
||||||
|
outline: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-search {
|
||||||
|
background: linear-gradient(135deg, #6b8cff, #a966ff);
|
||||||
border: none;
|
border: none;
|
||||||
color: white;
|
color: white;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.btn-search:hover {
|
||||||
|
opacity: 0.9;
|
||||||
|
transform: translateY(-1px);
|
||||||
|
}
|
||||||
|
|
||||||
.data-table {
|
.data-table {
|
||||||
border-radius: 6px;
|
border-radius: 6px;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
@@ -647,20 +657,45 @@ export default {
|
|||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.add-btn {
|
|
||||||
background: #cce5f9;
|
|
||||||
width: 75px;
|
|
||||||
border: none;
|
|
||||||
color: black;
|
|
||||||
padding: 8px 16px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.title-wrapper {
|
.title-wrapper {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
gap: 8px;
|
gap: 8px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.batch-actions .el-button {
|
||||||
|
min-width: 72px;
|
||||||
|
height: 32px;
|
||||||
|
padding: 7px 12px 7px 10px;
|
||||||
|
font-size: 12px;
|
||||||
|
border-radius: 4px;
|
||||||
|
line-height: 1;
|
||||||
|
font-weight: 500;
|
||||||
|
border: none;
|
||||||
|
transition: all 0.3s ease;
|
||||||
|
box-shadow: 0 2px 6px rgba(0, 0, 0, 0.1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.batch-actions .el-button:hover {
|
||||||
|
transform: translateY(-1px);
|
||||||
|
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.15);
|
||||||
|
}
|
||||||
|
|
||||||
|
.batch-actions .el-button--primary {
|
||||||
|
background: #5f70f3 !important;
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
|
||||||
|
.batch-actions .el-button--success {
|
||||||
|
background: #5bc98c;
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
|
||||||
|
.batch-actions .el-button--danger {
|
||||||
|
background: #fd5b63;
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
|
||||||
.batch-actions .el-button:first-child {
|
.batch-actions .el-button:first-child {
|
||||||
background: linear-gradient(135deg, #409EFF, #6B8CFF);
|
background: linear-gradient(135deg, #409EFF, #6B8CFF);
|
||||||
border: none;
|
border: none;
|
||||||
@@ -686,7 +721,6 @@ export default {
|
|||||||
|
|
||||||
::v-deep .el-table .custom-selection-header .cell .el-checkbox__inner {
|
::v-deep .el-table .custom-selection-header .cell .el-checkbox__inner {
|
||||||
display: none !important;
|
display: none !important;
|
||||||
/* 使表头复选框不可见 */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
::v-deep .el-table .custom-selection-header .cell::before {
|
::v-deep .el-table .custom-selection-header .cell::before {
|
||||||
@@ -741,8 +775,8 @@ export default {
|
|||||||
}
|
}
|
||||||
|
|
||||||
::v-deep .el-checkbox__input.is-checked .el-checkbox__inner {
|
::v-deep .el-checkbox__input.is-checked .el-checkbox__inner {
|
||||||
background-color: #409EFF !important;
|
background-color: #5f70f3;
|
||||||
border-color: #409EFF !important;
|
border-color: #5f70f3;
|
||||||
}
|
}
|
||||||
|
|
||||||
.voice-management-btn {
|
.voice-management-btn {
|
||||||
|
|||||||
@@ -31,11 +31,12 @@
|
|||||||
|
|
||||||
<div class="table_bottom">
|
<div class="table_bottom">
|
||||||
<div class="ctrl_btn">
|
<div class="ctrl_btn">
|
||||||
<el-button size="mini" type="primary" class="select-all-btn"
|
<el-button size="mini" type="primary" class="select-all-btn" @click="handleSelectAll">
|
||||||
@click="handleSelectAll">全选</el-button>
|
{{ isAllSelected ? '取消全选' : '全选' }}
|
||||||
|
</el-button>
|
||||||
<el-button size="mini" type="success" @click="showAddDialog">新增</el-button>
|
<el-button size="mini" type="success" @click="showAddDialog">新增</el-button>
|
||||||
<el-button size="mini" type="danger" icon="el-icon-delete"
|
<el-button size="mini" type="danger" icon="el-icon-delete"
|
||||||
@click="deleteParam($refs.paramsTable.selection)">删除</el-button>
|
@click="deleteParam($refs.paramsTable.selection)">删除</el-button>
|
||||||
</div>
|
</div>
|
||||||
<div class="custom-pagination">
|
<div class="custom-pagination">
|
||||||
<button class="pagination-btn" :disabled="currentPage === 1" @click="goFirst">
|
<button class="pagination-btn" :disabled="currentPage === 1" @click="goFirst">
|
||||||
@@ -82,6 +83,7 @@ export default {
|
|||||||
total: 0,
|
total: 0,
|
||||||
dialogVisible: false,
|
dialogVisible: false,
|
||||||
dialogTitle: "新增参数",
|
dialogTitle: "新增参数",
|
||||||
|
isAllSelected: false,
|
||||||
paramForm: {
|
paramForm: {
|
||||||
id: null,
|
id: null,
|
||||||
paramCode: "",
|
paramCode: "",
|
||||||
@@ -136,7 +138,12 @@ export default {
|
|||||||
this.fetchParams();
|
this.fetchParams();
|
||||||
},
|
},
|
||||||
handleSelectAll() {
|
handleSelectAll() {
|
||||||
this.$refs.paramsTable.toggleAllSelection();
|
if (this.isAllSelected) {
|
||||||
|
this.$refs.paramsTable.clearSelection();
|
||||||
|
} else {
|
||||||
|
this.$refs.paramsTable.toggleAllSelection();
|
||||||
|
}
|
||||||
|
this.isAllSelected = !this.isAllSelected;
|
||||||
},
|
},
|
||||||
showAddDialog() {
|
showAddDialog() {
|
||||||
this.dialogTitle = "新增参数";
|
this.dialogTitle = "新增参数";
|
||||||
|
|||||||
@@ -41,7 +41,9 @@
|
|||||||
|
|
||||||
<div class="table_bottom">
|
<div class="table_bottom">
|
||||||
<div class="ctrl_btn">
|
<div class="ctrl_btn">
|
||||||
<el-button size="mini" type="primary" class="select-all-btn" @click="handleSelectAll">全选</el-button>
|
<el-button size="mini" type="primary" class="select-all-btn" @click="handleSelectAll">
|
||||||
|
{{ isAllSelected ? '取消全选' : '全选' }}
|
||||||
|
</el-button>
|
||||||
<el-button size="mini" type="success" icon="el-icon-circle-check" @click="batchEnable">启用</el-button>
|
<el-button size="mini" type="success" icon="el-icon-circle-check" @click="batchEnable">启用</el-button>
|
||||||
<el-button size="mini" type="warning" @click="batchDisable"><i
|
<el-button size="mini" type="warning" @click="batchDisable"><i
|
||||||
class="el-icon-remove-outline rotated-icon"></i>禁用</el-button>
|
class="el-icon-remove-outline rotated-icon"></i>禁用</el-button>
|
||||||
@@ -89,6 +91,7 @@ export default {
|
|||||||
currentPage: 1,
|
currentPage: 1,
|
||||||
pageSize: 5,
|
pageSize: 5,
|
||||||
total: 0,
|
total: 0,
|
||||||
|
isAllSelected: false
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
created() {
|
created() {
|
||||||
@@ -135,7 +138,12 @@ export default {
|
|||||||
this.fetchUsers();
|
this.fetchUsers();
|
||||||
},
|
},
|
||||||
handleSelectAll() {
|
handleSelectAll() {
|
||||||
this.$refs.userTable.toggleAllSelection();
|
if (this.isAllSelected) {
|
||||||
|
this.$refs.userTable.clearSelection();
|
||||||
|
} else {
|
||||||
|
this.$refs.userTable.toggleAllSelection();
|
||||||
|
}
|
||||||
|
this.isAllSelected = !this.isAllSelected;
|
||||||
},
|
},
|
||||||
batchDelete() {
|
batchDelete() {
|
||||||
const selectedUsers = this.$refs.userTable.selection;
|
const selectedUsers = this.$refs.userTable.selection;
|
||||||
|
|||||||
Reference in New Issue
Block a user