feat(admin): 优化导航菜单布局与Dashboard使用说明卡片

- 将系统配置下拉菜单改为直接展示的菜单项,提升操作便捷性

- Dashboard使用说明区域扩展为9个功能卡片

- 所有卡片支持点击跳转到对应功能页面

- 优化响应式布局,支持3列/2列/1列自适应
This commit is contained in:
MerCry 2026-02-28 14:16:48 +08:00
parent aa02ab79d2
commit d30043e5e3
2 changed files with 91 additions and 105 deletions

View File

@ -30,53 +30,30 @@
<span>会话监控</span> <span>会话监控</span>
</router-link> </router-link>
<div class="nav-divider"></div> <div class="nav-divider"></div>
<el-dropdown trigger="hover" placement="bottom-start"> <router-link to="/admin/embedding" class="nav-item" :class="{ active: isActive('/admin/embedding') }">
<div class="nav-item dropdown-trigger" :class="{ active: isAdminActive }"> <el-icon><Connection /></el-icon>
<el-icon><Setting /></el-icon> <span>嵌入模型</span>
<span>系统配置</span> </router-link>
<el-icon class="dropdown-arrow"><ArrowDown /></el-icon> <router-link to="/admin/llm" class="nav-item" :class="{ active: isActive('/admin/llm') }">
</div> <el-icon><ChatDotSquare /></el-icon>
<template #dropdown> <span>LLM 配置</span>
<el-dropdown-menu class="admin-dropdown-menu"> </router-link>
<el-dropdown-item> <router-link to="/admin/prompt-templates" class="nav-item" :class="{ active: isActive('/admin/prompt-templates') }">
<router-link to="/admin/embedding" class="dropdown-link"> <el-icon><Document /></el-icon>
<el-icon><Connection /></el-icon> <span>Prompt 模板</span>
嵌入模型 </router-link>
</router-link> <router-link to="/admin/intent-rules" class="nav-item" :class="{ active: isActive('/admin/intent-rules') }">
</el-dropdown-item> <el-icon><Aim /></el-icon>
<el-dropdown-item> <span>意图规则</span>
<router-link to="/admin/llm" class="dropdown-link"> </router-link>
<el-icon><ChatDotSquare /></el-icon> <router-link to="/admin/script-flows" class="nav-item" :class="{ active: isActive('/admin/script-flows') }">
LLM 配置 <el-icon><Share /></el-icon>
</router-link> <span>话术流程</span>
</el-dropdown-item> </router-link>
<el-dropdown-item divided> <router-link to="/admin/guardrails" class="nav-item" :class="{ active: isActive('/admin/guardrails') }">
<router-link to="/admin/prompt-templates" class="dropdown-link"> <el-icon><Warning /></el-icon>
<el-icon><Document /></el-icon> <span>输出护栏</span>
Prompt 模板 </router-link>
</router-link>
</el-dropdown-item>
<el-dropdown-item>
<router-link to="/admin/intent-rules" class="dropdown-link">
<el-icon><Aim /></el-icon>
意图规则
</router-link>
</el-dropdown-item>
<el-dropdown-item>
<router-link to="/admin/script-flows" class="dropdown-link">
<el-icon><Share /></el-icon>
话术流程
</router-link>
</el-dropdown-item>
<el-dropdown-item>
<router-link to="/admin/guardrails" class="dropdown-link">
<el-icon><Warning /></el-icon>
输出护栏
</router-link>
</el-dropdown-item>
</el-dropdown-menu>
</template>
</el-dropdown>
</nav> </nav>
</div> </div>
<div class="header-right"> <div class="header-right">
@ -105,11 +82,11 @@
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { ref, computed, onMounted } from 'vue' import { ref, onMounted } from 'vue'
import { useRoute } from 'vue-router' import { useRoute } from 'vue-router'
import { useTenantStore } from '@/stores/tenant' import { useTenantStore } from '@/stores/tenant'
import { getTenantList, type Tenant } from '@/api/tenant' import { getTenantList, type Tenant } from '@/api/tenant'
import { Odometer, FolderOpened, Cpu, Monitor, Connection, ChatDotSquare, Setting, ArrowDown, Document, Aim, Share, Warning } from '@element-plus/icons-vue' import { Odometer, FolderOpened, Cpu, Monitor, Connection, ChatDotSquare, Document, Aim, Share, Warning } from '@element-plus/icons-vue'
import { ElMessage } from 'element-plus' import { ElMessage } from 'element-plus'
const route = useRoute() const route = useRoute()
@ -123,10 +100,6 @@ const isActive = (path: string) => {
return route.path === path || route.path.startsWith(path + '/') return route.path === path || route.path.startsWith(path + '/')
} }
const isAdminActive = computed(() => {
return route.path.startsWith('/admin')
})
const handleTenantChange = (val: string) => { const handleTenantChange = (val: string) => {
tenantStore.setTenant(val) tenantStore.setTenant(val)
// //
@ -255,21 +228,6 @@ onMounted(() => {
font-size: 16px; font-size: 16px;
} }
.dropdown-trigger {
cursor: pointer;
}
.dropdown-arrow {
font-size: 12px;
margin-left: 4px;
transition: transform 0.2s;
}
.dropdown-trigger:hover .dropdown-arrow,
.dropdown-trigger.active .dropdown-arrow {
transform: rotate(180deg);
}
.nav-divider { .nav-divider {
width: 1px; width: 1px;
height: 20px; height: 20px;
@ -332,32 +290,3 @@ onMounted(() => {
} }
} }
</style> </style>
<style>
.admin-dropdown-menu {
min-width: 160px;
}
.admin-dropdown-menu .el-dropdown-menu__item {
padding: 0;
}
.dropdown-link {
display: flex;
align-items: center;
gap: 8px;
padding: 8px 16px;
width: 100%;
color: var(--text-primary, #1E293B);
text-decoration: none;
font-size: 14px;
}
.dropdown-link:hover {
color: var(--primary-color, #4F7CFF);
}
.dropdown-link .el-icon {
font-size: 16px;
}
</style>

View File

@ -320,7 +320,7 @@
</div> </div>
</template> </template>
<div class="help-content"> <div class="help-content">
<div class="help-item"> <div class="help-item" @click="navigateTo('/admin/knowledge-bases')">
<div class="help-icon primary"> <div class="help-icon primary">
<el-icon><FolderOpened /></el-icon> <el-icon><FolderOpened /></el-icon>
</div> </div>
@ -329,7 +329,7 @@
<p>上传文档并建立向量索引支持 PDFWordTXT 等格式</p> <p>上传文档并建立向量索引支持 PDFWordTXT 等格式</p>
</div> </div>
</div> </div>
<div class="help-item"> <div class="help-item" @click="navigateTo('/rag-lab')">
<div class="help-icon success"> <div class="help-icon success">
<el-icon><Cpu /></el-icon> <el-icon><Cpu /></el-icon>
</div> </div>
@ -338,24 +338,69 @@
<p>测试检索增强生成效果查看检索结果和 AI 响应</p> <p>测试检索增强生成效果查看检索结果和 AI 响应</p>
</div> </div>
</div> </div>
<div class="help-item"> <div class="help-item" @click="navigateTo('/monitoring')">
<div class="help-icon warning"> <div class="help-icon warning">
<el-icon><Monitor /></el-icon>
</div>
<div class="help-text">
<h4>会话监控</h4>
<p>实时监控用户会话查看对话记录和系统响应</p>
</div>
</div>
<div class="help-item" @click="navigateTo('/admin/embedding')">
<div class="help-icon info">
<el-icon><Connection /></el-icon> <el-icon><Connection /></el-icon>
</div> </div>
<div class="help-text"> <div class="help-text">
<h4>嵌入模型配置</h4> <h4>嵌入模型</h4>
<p>配置文本嵌入模型用于文档向量化</p> <p>配置文本嵌入模型用于文档向量化</p>
</div> </div>
</div> </div>
<div class="help-item"> <div class="help-item" @click="navigateTo('/admin/llm')">
<div class="help-icon info"> <div class="help-icon primary">
<el-icon><ChatDotSquare /></el-icon> <el-icon><ChatDotSquare /></el-icon>
</div> </div>
<div class="help-text"> <div class="help-text">
<h4>LLM 模型配置</h4> <h4>LLM 配置</h4>
<p>配置大语言模型支持 OpenAIDeepSeekOllama </p> <p>配置大语言模型支持 OpenAIDeepSeekOllama </p>
</div> </div>
</div> </div>
<div class="help-item" @click="navigateTo('/admin/prompt-templates')">
<div class="help-icon success">
<el-icon><DocumentCopy /></el-icon>
</div>
<div class="help-text">
<h4>Prompt 模板</h4>
<p>管理和配置提示词模板优化 AI 响应效果</p>
</div>
</div>
<div class="help-item" @click="navigateTo('/admin/intent-rules')">
<div class="help-icon warning">
<el-icon><Aim /></el-icon>
</div>
<div class="help-text">
<h4>意图规则</h4>
<p>配置意图识别规则实现智能对话路由</p>
</div>
</div>
<div class="help-item" @click="navigateTo('/admin/script-flows')">
<div class="help-icon info">
<el-icon><Share /></el-icon>
</div>
<div class="help-text">
<h4>话术流程</h4>
<p>设计和管理对话流程实现多轮对话控制</p>
</div>
</div>
<div class="help-item" @click="navigateTo('/admin/guardrails')">
<div class="help-icon danger">
<el-icon><Warning /></el-icon>
</div>
<div class="help-text">
<h4>输出护栏</h4>
<p>配置敏感词过滤和内容审核规则保障输出安全</p>
</div>
</div>
</div> </div>
</el-card> </el-card>
</el-col> </el-col>
@ -891,7 +936,7 @@ onMounted(() => {
.help-content { .help-content {
display: grid; display: grid;
grid-template-columns: repeat(2, 1fr); grid-template-columns: repeat(3, 1fr);
gap: 20px; gap: 20px;
} }
@ -902,6 +947,7 @@ onMounted(() => {
background-color: var(--bg-tertiary); background-color: var(--bg-tertiary);
border-radius: 12px; border-radius: 12px;
transition: all 0.2s ease; transition: all 0.2s ease;
cursor: pointer;
} }
.help-item:hover { .help-item:hover {
@ -939,6 +985,11 @@ onMounted(() => {
color: #4F46E5; color: #4F46E5;
} }
.help-icon.danger {
background-color: #FEE2E2;
color: #DC2626;
}
.help-text h4 { .help-text h4 {
margin: 0 0 4px 0; margin: 0 0 4px 0;
font-size: 14px; font-size: 14px;
@ -953,6 +1004,12 @@ onMounted(() => {
line-height: 1.5; line-height: 1.5;
} }
@media (max-width: 1024px) {
.help-content {
grid-template-columns: repeat(2, 1fr);
}
}
@media (max-width: 768px) { @media (max-width: 768px) {
.dashboard-page { .dashboard-page {
padding: 16px; padding: 16px;