feat: 完成系统功能页面样式改造

This commit is contained in:
zhuoqinglian
2026-06-12 14:13:21 +08:00
parent c857a3164d
commit 0c73a8b6a4
11 changed files with 142 additions and 85 deletions
Binary file not shown.

After

Width:  |  Height:  |  Size: 227 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 669 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 213 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 232 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 255 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 682 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 508 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 253 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 256 KiB

@@ -38,7 +38,7 @@ export default {
color: #8099fc; color: #8099fc;
border-color: #adbdff; border-color: #adbdff;
box-shadow: 0 2px 8px rgba(128, 153, 252, 0.3); box-shadow: 0 2px 8px rgba(128, 153, 252, 0.3);
transform: translateY(-1px); transform: translateY(-2px);
} }
&.is-disabled, &.is-disabled,
@@ -57,7 +57,7 @@ export default {
background: linear-gradient(to right, #4a7cfd, #8154fc); background: linear-gradient(to right, #4a7cfd, #8154fc);
color: white; color: white;
border: none; border: none;
border-radius: 10px; border-radius: 6px;
transition: all 0.3s ease; transition: all 0.3s ease;
&.el-button--small { &.el-button--small {
@@ -69,7 +69,7 @@ export default {
color: white; color: white;
border-color: transparent; border-color: transparent;
box-shadow: 0 2px 8px rgba(74, 124, 253, 0.3); box-shadow: 0 2px 8px rgba(74, 124, 253, 0.3);
transform: translateY(-1px); transform: translateY(-2px);
} }
&.is-disabled, &.is-disabled,
+139 -82
View File
@@ -1,29 +1,22 @@
<template> <template>
<div class="welcome"> <div class="welcome">
<HeaderBar /> <HeaderBar />
<div class="operation-bar">
<h2 class="page-title">{{ $t('header.featureManagement') }}</h2>
</div>
<div class="main-wrapper"> <div class="main-wrapper">
<div class="content-panel"> <div class="content-panel">
<div class="content-area"> <div class="content-area">
<el-card class="feature-card" shadow="never"> <el-card class="feature-card" shadow="never">
<div class="config-header"> <div class="config-header">
<div class="header-icon"> <h2 class="page-title">{{ $t('header.featureManagement') }}</h2>
<img loading="lazy" src="@/assets/home/equipment.png" alt="" />
</div>
<div class="header-actions"> <div class="header-actions">
<el-button @click="!isSaving && toggleSelectAll()" class="btn-select-all" :disabled="isSaving"> <CustomButton size="small" @click="!isSaving && toggleSelectAll()" :disabled="isSaving">
{{ isAllSelected ? $t('featureManagement.deselectAll') : $t('featureManagement.selectAll') }} {{ isAllSelected ? $t('featureManagement.deselectAll') : $t('featureManagement.selectAll') }}
</el-button> </CustomButton>
<el-button type="primary" class="save-btn" @click="handleSave" :disabled="isSaving"> <CustomButton size="small" @click="handleReset" :disabled="isSaving">
{{ isSaving ? $t('featureManagement.saving') : $t('featureManagement.save') }}
</el-button>
<el-button class="reset-btn" @click="handleReset" :disabled="isSaving">
{{ $t('featureManagement.reset') }} {{ $t('featureManagement.reset') }}
</el-button> </CustomButton>
<CustomButton size="small" type="confirm" @click="handleSave" :disabled="isSaving">
{{ isSaving ? $t('featureManagement.saving') : $t('featureManagement.save') }}
</CustomButton>
</div> </div>
</div> </div>
<div class="divider"></div> <div class="divider"></div>
@@ -32,7 +25,14 @@
<div class="feature-groups-container"> <div class="feature-groups-container">
<!-- 功能管理分组 --> <!-- 功能管理分组 -->
<div v-if="featureManagementFeatures.length > 0" class="feature-group"> <div v-if="featureManagementFeatures.length > 0" class="feature-group">
<h3 class="group-title">{{ $t('featureManagement.group.featureManagement') }}</h3> <div class="group-title">
<img src="@/assets/setting/menu.png" alt="" width="28" height="28">
<div class="group-header">
<span class="group-name">功能模块开关</span>
<span class="module-count">{{ `${featureManagementFeatures.length} 个模块` }}</span>
</div>
</div>
<p class="group-description">控制系统核心功能模块的启用状态</p>
<div class="features-grid"> <div class="features-grid">
<div <div
v-for="feature in featureManagementFeatures" v-for="feature in featureManagementFeatures"
@@ -41,8 +41,16 @@
:class="{ 'feature-enabled': feature.enabled, 'feature-disabled': isSaving }" :class="{ 'feature-enabled': feature.enabled, 'feature-disabled': isSaving }"
@click="!isSaving && toggleFeature(feature)" @click="!isSaving && toggleFeature(feature)"
> >
<div class="feature-header"> <img :src="featureIcons[feature.id]" alt="" width="60" height="60">
<h3 class="feature-name">{{ $t(`feature.${feature.id}.name`) }}</h3> <div class="feature-content">
<div class="feature-header">
<h3 class="feature-name">{{ $t(`feature.${feature.id}.name`) }}</h3>
<span v-if="feature.enabled" class="feature-enabled-tag">已启用</span>
<span v-else class="feature-disabled-tag">未启用</span>
</div>
<p class="feature-description">{{ $t(`feature.${feature.id}.description`) }}</p>
</div>
<div class="feature-checkbox-container">
<el-checkbox <el-checkbox
v-model="feature.enabled" v-model="feature.enabled"
@change="!isSaving && toggleFeature(feature)" @change="!isSaving && toggleFeature(feature)"
@@ -50,14 +58,21 @@
:disabled="isSaving" :disabled="isSaving"
/> />
</div> </div>
<p class="feature-description">{{ $t(`feature.${feature.id}.description`) }}</p>
</div> </div>
</div> </div>
</div> </div>
<!-- 语音管理分组 --> <!-- 语音管理分组 -->
<div v-if="voiceManagementFeatures.length > 0" class="feature-group"> <div v-if="voiceManagementFeatures.length > 0" class="feature-group">
<h3 class="group-title">{{ $t('featureManagement.group.voiceManagement') }}</h3> <div class="group-title">
<img src="@/assets/setting/agent.png" alt="" width="28" height="28">
<div class="group-header">
<span class="group-name">智能体可见配置</span>
<span class="module-count">{{ `${voiceManagementFeatures.length} 个模块` }}</span>
</div>
</div>
<p class="group-description">配置哪些功能对智能体AI助手可见和可用</p>
<!-- <h3 class="group-title">{{ $t('featureManagement.group.voiceManagement') }}</h3> -->
<div class="features-grid"> <div class="features-grid">
<div <div
v-for="feature in voiceManagementFeatures" v-for="feature in voiceManagementFeatures"
@@ -66,8 +81,16 @@
:class="{ 'feature-enabled': feature.enabled, 'feature-disabled': isSaving }" :class="{ 'feature-enabled': feature.enabled, 'feature-disabled': isSaving }"
@click="!isSaving && toggleFeature(feature)" @click="!isSaving && toggleFeature(feature)"
> >
<div class="feature-header"> <img :src="voiceManagementIcons[feature.id]" alt="" width="60" height="60">
<h3 class="feature-name">{{ $t(`feature.${feature.id}.name`) }}</h3> <div class="feature-content">
<div class="feature-header">
<h3 class="feature-name">{{ $t(`feature.${feature.id}.name`) }}</h3>
<span v-if="feature.enabled" class="feature-enabled-tag">已启用</span>
<span v-else class="feature-disabled-tag">未启用</span>
</div>
<p class="feature-description">{{ $t(`feature.${feature.id}.description`) }}</p>
</div>
<div class="feature-checkbox-container">
<el-checkbox <el-checkbox
v-model="feature.enabled" v-model="feature.enabled"
@change="!isSaving && toggleFeature(feature)" @change="!isSaving && toggleFeature(feature)"
@@ -75,7 +98,6 @@
:disabled="isSaving" :disabled="isSaving"
/> />
</div> </div>
<p class="feature-description">{{ $t(`feature.${feature.id}.description`) }}</p>
</div> </div>
</div> </div>
</div> </div>
@@ -101,19 +123,41 @@
import HeaderBar from "@/components/HeaderBar.vue"; import HeaderBar from "@/components/HeaderBar.vue";
import VersionFooter from "@/components/VersionFooter.vue"; import VersionFooter from "@/components/VersionFooter.vue";
import featureManager from "@/utils/featureManager.js"; import featureManager from "@/utils/featureManager.js";
import CustomButton from "@/components/CustomButton.vue";
import voiceprintIcon from '@/assets/setting/voiceprint.png'
import voiceCloneIcon from '@/assets/setting/voiceclone.png'
import knowledgeBaseIcon from '@/assets/setting/knowledgeBase.png'
import mcpAccessPointIcon from '@/assets/setting/mcpAccessPoint.png'
import addressBookIcon from '@/assets/setting/addressBook.png'
import vadIcon from '@/assets/setting/vad.png'
import asrIcon from '@/assets/setting/asr.png'
export default { export default {
name: "FeatureManagement", name: "FeatureManagement",
components: { components: {
HeaderBar, HeaderBar,
VersionFooter VersionFooter,
CustomButton
}, },
data() { data() {
return { return {
pendingChanges: false, pendingChanges: false,
featureManagementFeatures: [], featureManagementFeatures: [],
voiceManagementFeatures: [], voiceManagementFeatures: [],
isSaving: false // 添加保存状态锁定 isSaving: false, // 添加保存状态锁定
// 功能模块图标映射
featureIcons: {
'voiceprintRecognition': voiceprintIcon,
'voiceClone': voiceCloneIcon,
'knowledgeBase': knowledgeBaseIcon,
'mcpAccessPoint': mcpAccessPointIcon,
'addressBook': addressBookIcon,
},
voiceManagementIcons: {
'vad': vadIcon,
'asr': asrIcon,
},
} }
}, },
computed: { computed: {
@@ -336,7 +380,7 @@ export default {
display: flex; display: flex;
justify-content: space-between; justify-content: space-between;
align-items: center; align-items: center;
padding: 16px 24px; padding: 22px 24px;
} }
.page-title { .page-title {
@@ -376,54 +420,13 @@ export default {
.divider { .divider {
height: 1px; height: 1px;
background: #e0e0e0; background: #f3f1f1;
margin-bottom: 20px; margin-bottom: 20px;
} }
.btn-select-all {
background: #e6ebff;
color: #5778ff;
border: 1px solid #adbdff;
border-radius: 18px;
padding: 8px 16px;
height: 32px;
font-size: 14px;
}
.btn-select-all:hover {
background: #d0d8ff;
}
.save-btn {
background: #5778ff;
color: white;
border: none;
border-radius: 18px;
padding: 8px 16px;
height: 32px;
font-size: 14px;
}
.save-btn:hover {
background: #4a6ae8;
}
.reset-btn {
background: #e6ebff;
color: #5778ff;
border: 1px solid #adbdff;
border-radius: 18px;
padding: 8px 16px;
height: 32px;
}
.reset-btn:hover {
background: #d0d8ff;
}
.main-wrapper { .main-wrapper {
height: calc(100vh - 63px - 35px - 58px); height: calc(100vh - 63px - 35px);
margin: 0 22px; margin: 20px 22px 0;
border-radius: 15px; border-radius: 15px;
box-shadow: 0 2px 12px rgba(0, 0, 0, 0.1); box-shadow: 0 2px 12px rgba(0, 0, 0, 0.1);
position: relative; position: relative;
@@ -478,9 +481,8 @@ export default {
.feature-card-item { .feature-card-item {
display: flex; display: flex;
flex-direction: column;
padding: 20px; padding: 20px;
border-radius: 12px; border-radius: 10px;
border: 2px solid #e0e0e0; border: 2px solid #e0e0e0;
background-color: white; background-color: white;
cursor: pointer; cursor: pointer;
@@ -491,25 +493,34 @@ export default {
.feature-card-item:hover { .feature-card-item:hover {
border-color: #869bf0; border-color: #869bf0;
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15); box-shadow: 0 4px 10px rgba(0, 0, 0, 0.15);
transform: translateY(-2px); transform: translateY(-2px);
} }
.feature-card-item.feature-enabled { .feature-card-item.feature-enabled {
border-color:#5778ff; border: 2px solid transparent;
box-shadow: 0 4px 16px rgba(95, 112, 243, 0.2); background: linear-gradient(white, white) padding-box,
linear-gradient(to right, #4a7cfd, #8154fc) border-box;
box-shadow: 0 4px 10px rgba(95, 112, 243, 0.2);
transform: translateY(-2px); transform: translateY(-2px);
} }
.feature-content {
margin-left: 16px;
}
.feature-header { .feature-header {
display: flex; display: flex;
justify-content: space-between;
align-items: center; align-items: center;
margin-bottom: 12px; margin-bottom: 6px;
}
.feature-checkbox-container {
display: flex;
align-items: center;
margin-left: 30px;
} }
.feature-checkbox ::v-deep .el-checkbox__input { .feature-checkbox ::v-deep .el-checkbox__input {
transform: scale(1.2); transform: scale(1.5);
} }
.feature-checkbox ::v-deep .el-checkbox__input.is-checked .el-checkbox__inner { .feature-checkbox ::v-deep .el-checkbox__input.is-checked .el-checkbox__inner {
@@ -521,9 +532,29 @@ export default {
color: #5778ff; color: #5778ff;
} }
.feature-enabled-tag {
background: #5778ff;
font-size: 14px;
color: #FFFFFF;
padding: 4px 8px;
border-radius: 10px;
margin-left: 10px;
font-weight: 500;
}
.feature-disabled-tag {
background: #DCDFE6;
font-size: 14px;
color: #FFFFFF;
padding: 4px 8px;
border-radius: 10px;
margin-left: 10px;
font-weight: 500;
}
.feature-name { .feature-name {
font-size: 18px; font-size: 18px;
line-height: 18px;
font-weight: 600; font-weight: 600;
color: #333; color: #333;
margin: 0; margin: 0;
@@ -535,7 +566,7 @@ export default {
font-size: 14px; font-size: 14px;
line-height: 1.6; line-height: 1.6;
color: #666; color: #666;
margin: 0 0 12px 0; margin: 0;
transition: color 0.3s ease; transition: color 0.3s ease;
text-align: left; text-align: left;
} }
@@ -571,14 +602,40 @@ export default {
} }
.group-title { .group-title {
margin-top: 0;
display: flex;
align-items: center;
font-size: 18px; font-size: 18px;
line-height: 18px;
font-weight: 600; font-weight: 600;
color: #303133; color: #303133;
margin-bottom: 12px; margin-bottom: 0;
padding-left: 12px;
border-left: 4px solid #5f70f3;
text-align: left; text-align: left;
} }
.group-name {
margin-left: 10px;
}
.group-header {
display: flex;
align-items: center;
}
.module-count {
margin-left: 13px;
font-size: 12px;
background: #ebebfe;
color: #5778ff;
padding: 2px 10px;
border-radius: 10px;
}
.group-description {
margin-top: 6px;
text-align: left;
font-size: 14px;
font-weight: 500;
}
.features-grid { .features-grid {
display: grid; display: grid;