|
After Width: | Height: | Size: 227 KiB |
|
After Width: | Height: | Size: 669 B |
|
After Width: | Height: | Size: 213 KiB |
|
After Width: | Height: | Size: 232 KiB |
|
After Width: | Height: | Size: 255 KiB |
|
After Width: | Height: | Size: 682 B |
|
After Width: | Height: | Size: 508 KiB |
|
After Width: | Height: | Size: 253 KiB |
|
After Width: | Height: | Size: 256 KiB |
@@ -0,0 +1,85 @@
|
|||||||
|
<template>
|
||||||
|
<el-button
|
||||||
|
:class="['custom-button', `custom-button--${type}`]"
|
||||||
|
v-bind="$attrs"
|
||||||
|
@click="$emit('click', $event)"
|
||||||
|
>
|
||||||
|
<slot />
|
||||||
|
</el-button>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
name: 'CustomButton',
|
||||||
|
props: {
|
||||||
|
type: {
|
||||||
|
type: String,
|
||||||
|
default: 'default',
|
||||||
|
validator: (val) => ['default', 'confirm'].includes(val)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.custom-button--default {
|
||||||
|
background: transparent;
|
||||||
|
color: #8099fc;
|
||||||
|
border: 1px solid #adbdff;
|
||||||
|
border-radius: 6px;
|
||||||
|
transition: all 0.3s ease;
|
||||||
|
|
||||||
|
&.el-button--small {
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background: #f1f2ff;
|
||||||
|
color: #8099fc;
|
||||||
|
border-color: #adbdff;
|
||||||
|
box-shadow: 0 2px 8px rgba(128, 153, 252, 0.3);
|
||||||
|
transform: translateY(-2px);
|
||||||
|
}
|
||||||
|
|
||||||
|
&.is-disabled,
|
||||||
|
&.is-disabled:hover {
|
||||||
|
background: transparent;
|
||||||
|
color: #c0c4cc;
|
||||||
|
border-color: #e4e7ed;
|
||||||
|
box-shadow: none;
|
||||||
|
transform: none;
|
||||||
|
cursor: not-allowed;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.custom-button--confirm {
|
||||||
|
width: fit-content;
|
||||||
|
background: linear-gradient(to right, #4a7cfd, #8154fc);
|
||||||
|
color: white;
|
||||||
|
border: none;
|
||||||
|
border-radius: 6px;
|
||||||
|
transition: all 0.3s ease;
|
||||||
|
|
||||||
|
&.el-button--small {
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background: linear-gradient(to right, #6b8cff, #9a7cff);
|
||||||
|
color: white;
|
||||||
|
border-color: transparent;
|
||||||
|
box-shadow: 0 2px 8px rgba(74, 124, 253, 0.3);
|
||||||
|
transform: translateY(-2px);
|
||||||
|
}
|
||||||
|
|
||||||
|
&.is-disabled,
|
||||||
|
&.is-disabled:hover {
|
||||||
|
background: linear-gradient(to right, #a0b4fd, #b8a4fd);
|
||||||
|
color: rgba(255, 255, 255, 0.6);
|
||||||
|
border-color: transparent;
|
||||||
|
box-shadow: none;
|
||||||
|
transform: none;
|
||||||
|
cursor: not-allowed;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -1414,6 +1414,14 @@ export default {
|
|||||||
'featureManagement.cancel': 'Abbrechen',
|
'featureManagement.cancel': 'Abbrechen',
|
||||||
'featureManagement.resetSuccess': 'Funktionskonfiguration erfolgreich zurückgesetzt',
|
'featureManagement.resetSuccess': 'Funktionskonfiguration erfolgreich zurückgesetzt',
|
||||||
'featureManagement.noChanges': 'Keine Änderungen zum Speichern',
|
'featureManagement.noChanges': 'Keine Änderungen zum Speichern',
|
||||||
|
'featureManagement.saving': 'Speichern...',
|
||||||
|
'featureManagement.groupName.featureManagement': 'Funktionsmodul-Schalter',
|
||||||
|
'featureManagement.groupName.voiceManagement': 'Agent-Sichtbarkeitskonfiguration',
|
||||||
|
'featureManagement.groupDescription.featureManagement': 'Aktivierungsstatus der Kernfunktionsmodule steuern',
|
||||||
|
'featureManagement.groupDescription.voiceManagement': 'Konfigurieren, welche Funktionen für Agenten (KI-Assistenten) sichtbar und verfügbar sind',
|
||||||
|
'featureManagement.moduleCount': '{count} Module insgesamt',
|
||||||
|
'featureManagement.enabled': 'Aktiviert',
|
||||||
|
'featureManagement.disabled': 'Deaktiviert',
|
||||||
|
|
||||||
// Feature names and descriptions
|
// Feature names and descriptions
|
||||||
'feature.voiceprintRecognition.name': 'Stimmerkennung',
|
'feature.voiceprintRecognition.name': 'Stimmerkennung',
|
||||||
|
|||||||
@@ -1414,6 +1414,14 @@ export default {
|
|||||||
'featureManagement.cancel': 'Cancel',
|
'featureManagement.cancel': 'Cancel',
|
||||||
'featureManagement.resetSuccess': 'Feature configuration reset successfully',
|
'featureManagement.resetSuccess': 'Feature configuration reset successfully',
|
||||||
'featureManagement.noChanges': 'No changes to save',
|
'featureManagement.noChanges': 'No changes to save',
|
||||||
|
'featureManagement.saving': 'Saving...',
|
||||||
|
'featureManagement.groupName.featureManagement': 'Feature Module Switch',
|
||||||
|
'featureManagement.groupName.voiceManagement': 'Agent Visible Configuration',
|
||||||
|
'featureManagement.groupDescription.featureManagement': 'Control the enable status of core feature modules',
|
||||||
|
'featureManagement.groupDescription.voiceManagement': 'Configure which features are visible and available to agents (AI assistants)',
|
||||||
|
'featureManagement.moduleCount': '{count} modules in total',
|
||||||
|
'featureManagement.enabled': 'Enabled',
|
||||||
|
'featureManagement.disabled': 'Disabled',
|
||||||
|
|
||||||
// Feature names and descriptions
|
// Feature names and descriptions
|
||||||
'feature.voiceprintRecognition.name': 'Voiceprint Recognition',
|
'feature.voiceprintRecognition.name': 'Voiceprint Recognition',
|
||||||
|
|||||||
@@ -1414,6 +1414,14 @@ export default {
|
|||||||
'featureManagement.cancel': 'Cancelar',
|
'featureManagement.cancel': 'Cancelar',
|
||||||
'featureManagement.resetSuccess': 'Configuração de funcionalidades redefinida com sucesso',
|
'featureManagement.resetSuccess': 'Configuração de funcionalidades redefinida com sucesso',
|
||||||
'featureManagement.noChanges': 'Nenhuma alteração para salvar',
|
'featureManagement.noChanges': 'Nenhuma alteração para salvar',
|
||||||
|
'featureManagement.saving': 'Salvando...',
|
||||||
|
'featureManagement.groupName.featureManagement': 'Interruptor de Módulo de Funcionalidade',
|
||||||
|
'featureManagement.groupName.voiceManagement': 'Configuração de Visibilidade do Agente',
|
||||||
|
'featureManagement.groupDescription.featureManagement': 'Controlar o status de ativação dos módulos de funcionalidade principal',
|
||||||
|
'featureManagement.groupDescription.voiceManagement': 'Configurar quais funcionalidades são visíveis e disponíveis para agentes (assistentes de IA)',
|
||||||
|
'featureManagement.moduleCount': '{count} módulos no total',
|
||||||
|
'featureManagement.enabled': 'Ativado',
|
||||||
|
'featureManagement.disabled': 'Desativado',
|
||||||
|
|
||||||
// Nomes e descrições de funcionalidades
|
// Nomes e descrições de funcionalidades
|
||||||
'feature.voiceprintRecognition.name': 'Reconhecimento de Impressão Vocal',
|
'feature.voiceprintRecognition.name': 'Reconhecimento de Impressão Vocal',
|
||||||
|
|||||||
@@ -1414,6 +1414,14 @@ export default {
|
|||||||
'featureManagement.cancel': 'Hủy bỏ',
|
'featureManagement.cancel': 'Hủy bỏ',
|
||||||
'featureManagement.resetSuccess': 'Cấu hình tính năng đã được đặt lại thành công',
|
'featureManagement.resetSuccess': 'Cấu hình tính năng đã được đặt lại thành công',
|
||||||
'featureManagement.noChanges': 'Không có thay đổi nào để lưu',
|
'featureManagement.noChanges': 'Không có thay đổi nào để lưu',
|
||||||
|
'featureManagement.saving': 'Đang lưu...',
|
||||||
|
'featureManagement.groupName.featureManagement': 'Công tắc mô-đun tính năng',
|
||||||
|
'featureManagement.groupName.voiceManagement': 'Cấu hình hiển thị Agent',
|
||||||
|
'featureManagement.groupDescription.featureManagement': 'Kiểm soát trạng thái kích hoạt của các mô-đun tính năng cốt lõi',
|
||||||
|
'featureManagement.groupDescription.voiceManagement': 'Cấu hình các tính năng hiển thị và khả dụng cho agent (trợ lý AI)',
|
||||||
|
'featureManagement.moduleCount': 'Tổng cộng {count} mô-đun',
|
||||||
|
'featureManagement.enabled': 'Đã bật',
|
||||||
|
'featureManagement.disabled': 'Chưa bật',
|
||||||
|
|
||||||
// Feature names and descriptions
|
// Feature names and descriptions
|
||||||
'feature.voiceprintRecognition.name': 'Nhận dạng giọng nói',
|
'feature.voiceprintRecognition.name': 'Nhận dạng giọng nói',
|
||||||
|
|||||||
@@ -1412,6 +1412,14 @@ export default {
|
|||||||
'featureManagement.cancel': '取消',
|
'featureManagement.cancel': '取消',
|
||||||
'featureManagement.resetSuccess': '功能配置重置成功',
|
'featureManagement.resetSuccess': '功能配置重置成功',
|
||||||
'featureManagement.noChanges': '没有需要保存的更改',
|
'featureManagement.noChanges': '没有需要保存的更改',
|
||||||
|
'featureManagement.saving': '保存中...',
|
||||||
|
'featureManagement.groupName.featureManagement': '功能模块开关',
|
||||||
|
'featureManagement.groupName.voiceManagement': '智能体可见配置',
|
||||||
|
'featureManagement.groupDescription.featureManagement': '控制系统核心功能模块的启用状态',
|
||||||
|
'featureManagement.groupDescription.voiceManagement': '配置哪些功能对智能体(AI助手)可见和可用',
|
||||||
|
'featureManagement.moduleCount': '共 {count} 个模块',
|
||||||
|
'featureManagement.enabled': '已启用',
|
||||||
|
'featureManagement.disabled': '未启用',
|
||||||
|
|
||||||
// 功能名称和描述
|
// 功能名称和描述
|
||||||
'feature.voiceprintRecognition.name': '声纹识别',
|
'feature.voiceprintRecognition.name': '声纹识别',
|
||||||
|
|||||||
@@ -1414,6 +1414,14 @@ export default {
|
|||||||
'featureManagement.cancel': '取消',
|
'featureManagement.cancel': '取消',
|
||||||
'featureManagement.resetSuccess': '功能配置重置成功',
|
'featureManagement.resetSuccess': '功能配置重置成功',
|
||||||
'featureManagement.noChanges': '沒有需要儲存的更改',
|
'featureManagement.noChanges': '沒有需要儲存的更改',
|
||||||
|
'featureManagement.saving': '儲存中...',
|
||||||
|
'featureManagement.groupName.featureManagement': '功能模組開關',
|
||||||
|
'featureManagement.groupName.voiceManagement': '智能體可見配置',
|
||||||
|
'featureManagement.groupDescription.featureManagement': '控制系統核心功能模組的啟用狀態',
|
||||||
|
'featureManagement.groupDescription.voiceManagement': '配置哪些功能對智能體(AI助手)可見和可用',
|
||||||
|
'featureManagement.moduleCount': '共 {count} 個模組',
|
||||||
|
'featureManagement.enabled': '已啟用',
|
||||||
|
'featureManagement.disabled': '未啟用',
|
||||||
|
|
||||||
// 功能名稱和描述
|
// 功能名稱和描述
|
||||||
'feature.voiceprintRecognition.name': '聲紋識別',
|
'feature.voiceprintRecognition.name': '聲紋識別',
|
||||||
|
|||||||
@@ -1,38 +1,38 @@
|
|||||||
<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>
|
||||||
|
|
||||||
<!-- 功能分组容器 - 左右布局 -->
|
<!-- 功能分组容器 - 左右布局 -->
|
||||||
<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">{{ $t('featureManagement.groupName.featureManagement') }}</span>
|
||||||
|
<span class="module-count">{{ $t('featureManagement.moduleCount', { count: featureManagementFeatures.length }) }}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<p class="group-description">{{ $t('featureManagement.groupDescription.featureManagement') }}</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">{{ $t('featureManagement.enabled') }}</span>
|
||||||
|
<span v-else class="feature-disabled-tag">{{ $t('featureManagement.disabled') }}</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,20 @@
|
|||||||
: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">{{ $t('featureManagement.groupName.voiceManagement') }}</span>
|
||||||
|
<span class="module-count">{{ $t('featureManagement.moduleCount', { count: voiceManagementFeatures.length }) }}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<p class="group-description">{{ $t('featureManagement.groupDescription.voiceManagement') }}</p>
|
||||||
<div class="features-grid">
|
<div class="features-grid">
|
||||||
<div
|
<div
|
||||||
v-for="feature in voiceManagementFeatures"
|
v-for="feature in voiceManagementFeatures"
|
||||||
@@ -66,8 +80,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">{{ $t('featureManagement.enabled') }}</span>
|
||||||
|
<span v-else class="feature-disabled-tag">{{ $t('featureManagement.disabled') }}</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 +97,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 +122,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 +379,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 +419,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 +480,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 +492,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 +531,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 +565,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 +601,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;
|
||||||
|
|||||||