xueyiming 1 week ago
parent
commit
795f95b7a5
5 changed files with 5132 additions and 627 deletions
  1. 212 25
      src/components/AppNavbar.vue
  2. 814 91
      src/views/KnowledgeBase.vue
  3. 895 199
      src/views/KnowledgeContent.vue
  4. 1844 185
      src/views/QAndA.vue
  5. 1367 127
      src/views/SearchPage.vue

+ 212 - 25
src/components/AppNavbar.vue

@@ -1,11 +1,38 @@
 <template>
-  <el-header>
-    <el-menu :default-active="activeRoute" mode="horizontal" @select="handleSelect">
-      <el-menu-item index="/">知识库</el-menu-item>
-      <el-menu-item index="/search">搜索</el-menu-item>
-      <el-menu-item index="/qanda">问答</el-menu-item>
-    </el-menu>
-  </el-header>
+  <div class="navbar-container">
+    <div class="navbar-background">
+      <div class="navbar-content">
+        <div class="navbar-logo">
+          <h1 class="logo-text">智能知识库</h1>
+        </div>
+        <el-menu
+            :default-active="activeRoute"
+            mode="horizontal"
+            @select="handleSelect"
+            class="custom-nav-menu"
+        >
+          <el-menu-item index="/" class="nav-item">
+            <span class="nav-icon">📚</span>
+            知识库
+          </el-menu-item>
+          <el-menu-item index="/search" class="nav-item">
+            <span class="nav-icon">🔍</span>
+            搜索
+          </el-menu-item>
+          <el-menu-item index="/qanda" class="nav-item">
+            <span class="nav-icon">💬</span>
+            问答
+          </el-menu-item>
+        </el-menu>
+<!--        <div class="navbar-actions">-->
+<!--          <div class="user-info">-->
+<!--            <span class="user-avatar">👤</span>-->
+<!--            <span class="user-name">用户</span>-->
+<!--          </div>-->
+<!--        </div>-->
+      </div>
+    </div>
+  </div>
 </template>
 
 <script lang="ts">
@@ -20,14 +47,12 @@ export default defineComponent({
 
     // 动态计算激活的路由
     const activeRoute = computed(() => {
-      // 这里可以根据实际情况,判断当前路径是否包含某些部分来保持激活项
       if (route.path.startsWith('/knowledge/content')) {
         return '/'; // 知识库页面时,设置为高亮 "知识库"
       }
       return route.path;
     });
 
-
     const handleSelect = (index: string) => {
       router.push(index);
     };
@@ -41,29 +66,191 @@ export default defineComponent({
 </script>
 
 <style scoped>
-.el-header {
-  padding: 0;
+.navbar-container {
+  width: 100%;
+  z-index: 1000;
+}
+
+.navbar-background {
+  background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
+  backdrop-filter: blur(20px);
+  border-bottom: 1px solid rgba(255, 255, 255, 0.1);
+  box-shadow: 0 4px 20px rgba(0, 0, 0, 0.1);
+}
+
+.navbar-content {
+  max-width: 1400px;
+  margin: 0 auto;
+  padding: 0 24px;
+  display: flex;
+  align-items: center;
+  justify-content: space-between;
+  height: 70px;
+}
+
+.navbar-logo {
+  display: flex;
+  align-items: center;
+}
+
+.logo-text {
+  color: white;
+  font-size: 1.5rem;
+  font-weight: 700;
+  margin: 0;
+  text-shadow: 0 2px 10px rgba(0, 0, 0, 0.3);
+  background: linear-gradient(135deg, #fff 0%, #e2e8f0 100%);
+  -webkit-background-clip: text;
+  -webkit-text-fill-color: transparent;
+  background-clip: text;
+}
+
+/* 自定义导航菜单样式 */
+.custom-nav-menu {
+  background: transparent !important;
+  border: none !important;
+  display: flex;
+  align-items: center;
+  gap: 8px;
+  flex: 1;
+  justify-content: center;
+}
+
+.custom-nav-menu :deep(.el-menu--horizontal) {
+  border: none;
+  background: transparent;
+}
+
+.custom-nav-menu :deep(.el-menu-item) {
+  background: rgba(255, 255, 255, 0.1) !important;
+  color: rgba(255, 255, 255, 0.9) !important;
+  border: 1px solid rgba(255, 255, 255, 0.2) !important;
+  border-radius: 12px !important;
+  padding: 12px 24px !important;
+  margin: 0 8px !important;
+  font-size: 16px !important;
+  font-weight: 500 !important;
+  transition: all 0.3s ease !important;
+  display: flex !important;
+  align-items: center !important;
+  gap: 8px !important;
+  height: auto !important;
+  line-height: 1.5 !important;
+}
+
+.custom-nav-menu :deep(.el-menu-item:hover) {
+  background: rgba(255, 255, 255, 0.2) !important;
+  color: white !important;
+  border-color: rgba(255, 255, 255, 0.3) !important;
+  transform: translateY(-2px) !important;
+  box-shadow: 0 4px 15px rgba(255, 255, 255, 0.2) !important;
 }
 
-.logo-container {
-  width: 50px;
-  height: 50px;
+.custom-nav-menu :deep(.el-menu-item.is-active) {
+  background: rgba(255, 255, 255, 0.25) !important;
+  color: white !important;
+  border-color: rgba(255, 255, 255, 0.4) !important;
+  box-shadow: 0 4px 20px rgba(255, 255, 255, 0.3) !important;
+}
+
+.nav-icon {
+  font-size: 1.2rem;
+  filter: drop-shadow(0 2px 4px rgba(0, 0, 0, 0.2));
+}
+
+.navbar-actions {
   display: flex;
   align-items: center;
-  padding: 10px 20px;
 }
 
-.el-menu {
-  font-size: 18px; /* 增大菜单字体 */
+.user-info {
   display: flex;
-  justify-content: center; /* 水平居中菜单 */
-  align-items: center; /* 垂直居中菜单 */
-  height: 100%;
+  align-items: center;
+  gap: 12px;
+  background: rgba(255, 255, 255, 0.1);
+  padding: 8px 16px;
+  border-radius: 12px;
+  border: 1px solid rgba(255, 255, 255, 0.2);
+  color: white;
+  transition: all 0.3s ease;
+}
+
+.user-info:hover {
+  background: rgba(255, 255, 255, 0.2);
+  transform: translateY(-1px);
+}
+
+.user-avatar {
+  font-size: 1.2rem;
 }
 
-.el-menu-item {
-  font-size: 18px;
-  text-align: center;
-  padding: 14px 20px;
+.user-name {
+  font-weight: 500;
+  font-size: 14px;
+}
+
+/* 响应式设计 */
+@media (max-width: 768px) {
+  .navbar-content {
+    padding: 0 16px;
+    height: 60px;
+  }
+
+  .logo-text {
+    font-size: 1.25rem;
+  }
+
+  .custom-nav-menu :deep(.el-menu-item) {
+    padding: 10px 16px !important;
+    font-size: 14px !important;
+    margin: 0 4px !important;
+  }
+
+  .nav-icon {
+    font-size: 1rem;
+  }
+
+  .user-info {
+    padding: 6px 12px;
+  }
+
+  .user-name {
+    display: none;
+  }
+}
+
+@media (max-width: 480px) {
+  .navbar-content {
+    flex-wrap: wrap;
+    height: auto;
+    padding: 12px 16px;
+  }
+
+  .navbar-logo {
+    order: 1;
+    flex: 1;
+  }
+
+  .custom-nav-menu {
+    order: 3;
+    width: 100%;
+    margin-top: 12px;
+    justify-content: space-around;
+  }
+
+  .navbar-actions {
+    order: 2;
+  }
+
+  .custom-nav-menu :deep(.el-menu-item) {
+    flex: 1;
+    justify-content: center;
+    margin: 0 2px !important;
+    padding: 8px 12px !important;
+  }
+
+  .nav-icon {
+    margin-right: 4px;
+  }
 }
-</style>
+</style>

+ 814 - 91
src/views/KnowledgeBase.vue

@@ -1,86 +1,192 @@
 <template>
-  <el-container style="height: 100vh; padding: 20px;">
-    <!-- Header -->
-    <el-header style="display: flex; justify-content: space-between; align-items: center; padding: 20px;">
-      <div style="font-size: 28px; font-weight: bold; color: #333;">知识库</div>
-      <el-button
-          type="primary"
-          @click="showCreateModal"
-          style="border-radius: 20px;"
-          :loading="loading.create"
-      >
-        创建知识库
-      </el-button>
-    </el-header>
-
-    <!-- Content Area -->
-    <el-main style="padding: 20px;">
-      <div class="knowledge-base-grid">
-        <el-card
-            v-for="item in knowledgeBaseList"
-            :key="item.dataset_id"
-            :body-style="{ padding: '20px', borderRadius: '12px', position: 'relative' }"
-            class="box-card"
-        >
-          <!-- 美观的删除按钮 -->
-          <el-button
-              circle
-              size="small"
-              style="position: absolute; top: 10px; right: 10px; width: 28px; height: 28px;"
-              @click.stop="confirmDelete(item.dataset_id, item.name)"
-          >
-            <el-icon><CloseBold /></el-icon>
-          </el-button>
+  <div class="app-container">
+    <!-- 顶部导航 -->
+    <div class="app-header">
+      <div class="header-content">
+        <div class="header-main">
+          <h1 class="app-title">知识库管理</h1>
+          <p class="app-subtitle">创建和管理您的知识库</p>
+        </div>
+        <div class="header-stats">
+          <div class="stat-item">
+            <span class="stat-number">{{ knowledgeBaseList.length }}</span>
+            <span class="stat-label">知识库</span>
+          </div>
+          <div class="stat-item">
+            <span class="stat-number">{{ totalDocuments }}</span>
+            <span class="stat-label">总文档</span>
+          </div>
+        </div>
+      </div>
+    </div>
+
+    <div class="main-content">
+      <!-- 操作栏 -->
+      <div class="action-section">
+        <div class="action-card">
+          <div class="action-header">
+            <h2>📚 知识库管理</h2>
+            <p>创建新的知识库或管理现有知识库</p>
+          </div>
+          <div class="action-buttons">
+            <el-button
+                type="primary"
+                @click="showCreateModal"
+                class="create-button"
+                :loading="loading.create"
+            >
+              <span class="button-content">
+                <span class="button-icon">➕</span>
+                创建知识库
+              </span>
+            </el-button>
+          </div>
+        </div>
+      </div>
 
-          <!-- 点击卡片跳转详情 -->
+      <!-- 知识库网格 -->
+      <div class="knowledge-grid-section">
+        <div class="section-header">
+          <h2>我的知识库</h2>
+          <p>共 {{ knowledgeBaseList.length }} 个知识库</p>
+        </div>
+
+        <!-- 加载状态 -->
+        <div v-if="knowledgeBaseList.length === 0 && !loading.create" class="empty-state">
+          <div class="empty-content">
+            <div class="empty-icon">📚</div>
+            <h3>暂无知识库</h3>
+            <p>创建您的第一个知识库开始使用</p>
+            <el-button @click="showCreateModal" type="primary" class="create-first-btn">
+              <span class="button-icon">➕</span>
+              创建知识库
+            </el-button>
+          </div>
+        </div>
+
+        <!-- 知识库卡片网格 -->
+        <div v-else class="knowledge-grid">
           <div
-              style="cursor: pointer"
-              @click="goToDetailPage(item.dataset_id, item.name)"
+              v-for="item in knowledgeBaseList"
+              :key="item.dataset_id"
+              class="knowledge-card"
           >
-            <div style="font-size: 18px; font-weight: bold; margin-bottom: 10px; color: #2c3e50;">
-              {{ item.name }}
+            <!-- 删除按钮 -->
+            <div class="card-actions">
+              <el-button
+                  circle
+                  size="small"
+                  class="delete-btn"
+                  @click.stop="confirmDelete(item.dataset_id, item.name)"
+                  :loading="loading.delete[item.dataset_id]"
+                  :disabled="loading.delete[item.dataset_id]"
+              >
+                <template #default>
+                  <el-icon v-if="!loading.delete[item.dataset_id]"><CloseBold /></el-icon>
+                  <span v-else class="loading-spinner-small"></span>
+                </template>
+              </el-button>
             </div>
-            <div style="color: #7f8c8d;">文档数量:{{ item.count }}</div>
-            <div style="color: #7f8c8d;">创建时间:{{ item.created_at }}</div>
-          </div>
-        </el-card>
-
 
+            <!-- 卡片内容 -->
+            <div
+                class="card-content"
+                @click="goToDetailPage(item.dataset_id, item.name)"
+            >
+              <div class="card-icon">📖</div>
+              <div class="card-info">
+                <h3 class="knowledge-name">{{ item.name }}</h3>
+                <div class="knowledge-stats">
+                  <div class="stat">
+                    <span class="stat-icon">📄</span>
+                    <span class="stat-text">{{ item.count }} 个文档</span>
+                  </div>
+                  <div class="stat">
+                    <span class="stat-icon">🕒</span>
+                    <span class="stat-text">{{ formatDate(item.created_at) }}</span>
+                  </div>
+                </div>
+              </div>
+<!--              <div class="card-arrow">-->
+<!--                <span class="arrow-icon">➡️</span>-->
+<!--              </div>-->
+            </div>
+          </div>
+        </div>
       </div>
-    </el-main>
+    </div>
 
     <!-- 创建知识库弹窗 -->
-    <el-dialog v-model="createModalVisible" title="创建知识库" width="400px" style="border-radius: 12px;">
-      <el-input
-          v-model="newKnowledgeBaseTitle"
-          placeholder="请输入知识库名称"
-          maxlength="64"
-          style="border-radius: 10px; padding: 10px;"
-          :disabled="loading.create"
-      />
-      <div style="text-align: right; margin-top: 5px; font-size: 12px; color: #999;">
-        {{ newKnowledgeBaseTitle.length }}/64
+    <el-dialog
+        v-model="createModalVisible"
+        width="500px"
+        class="create-dialog"
+        :close-on-click-modal="false"
+    >
+      <template #header>
+        <div class="dialog-header">
+          <div class="dialog-title">
+            <div class="title-icon">➕</div>
+            <div class="title-content">
+              <h3>创建知识库</h3>
+              <p>为您的文档创建一个新的知识库</p>
+            </div>
+          </div>
+        </div>
+      </template>
+
+      <div class="dialog-content">
+        <div class="input-section">
+          <label class="input-label">知识库名称</label>
+          <el-input
+              v-model="newKnowledgeBaseTitle"
+              placeholder="请输入知识库名称"
+              maxlength="64"
+              size="large"
+              class="name-input"
+              :disabled="loading.create"
+          />
+          <div class="input-tips">
+            {{ newKnowledgeBaseTitle.length }}/64
+          </div>
+        </div>
       </div>
+
       <template #footer>
-        <el-button @click="createModalVisible = false" style="border-radius: 20px;" :disabled="loading.create">
-          取消
-        </el-button>
-        <el-button
-            type="primary"
-            @click="createKnowledgeBase"
-            style="border-radius: 20px; background-color: #409EFF; border-color: #409EFF;"
-            :loading="loading.create"
-        >
-          创建
-        </el-button>
+        <div class="dialog-footer">
+          <div class="footer-actions">
+            <el-button
+                class="action-btn secondary"
+                @click="createModalVisible = false"
+                :disabled="loading.create"
+            >
+              取消
+            </el-button>
+            <el-button
+                type="primary"
+                class="action-btn primary"
+                @click="createKnowledgeBase"
+                :loading="loading.create"
+            >
+              <span v-if="!loading.create" class="button-content">
+                <span class="button-icon">✅</span>
+                创建
+              </span>
+              <span v-else class="button-loading">
+                <span class="loading-spinner"></span>
+                创建中...
+              </span>
+            </el-button>
+          </div>
+        </div>
       </template>
     </el-dialog>
-  </el-container>
+  </div>
 </template>
 
 <script lang="ts">
 import { API_BASE_URL } from "@/config";
-import {defineComponent, ref, reactive} from 'vue';
+import {defineComponent, ref, reactive, computed} from 'vue';
 import axios from 'axios';
 import {ElMessage, ElMessageBox} from 'element-plus';
 import { CloseBold } from '@element-plus/icons-vue';
@@ -96,7 +202,6 @@ interface KnowledgeBaseItem {
 export default defineComponent({
   name: 'KnowledgeBase',
   components: {CloseBold},
-  // components: { CloseBold },
   setup() {
     const router = useRouter();
     const knowledgeBaseList = ref<KnowledgeBaseItem[]>([]);
@@ -109,6 +214,11 @@ export default defineComponent({
       delete: {} as Record<number, boolean>
     });
 
+    // 计算总文档数
+    const totalDocuments = computed(() => {
+      return knowledgeBaseList.value.reduce((total, item) => total + item.count, 0);
+    });
+
     const fetchKnowledgeBaseList = async () => {
       try {
         const res = await axios.get(`${API_BASE_URL}/dataset/list`);
@@ -120,6 +230,7 @@ export default defineComponent({
 
     const showCreateModal = () => {
       createModalVisible.value = true;
+      newKnowledgeBaseTitle.value = '';
     };
 
     const createKnowledgeBase = async () => {
@@ -146,12 +257,14 @@ export default defineComponent({
     const confirmDelete = async (datasetId: number, datasetName: string) => {
       try {
         await ElMessageBox.confirm(
-            `确定要删除知识库 "${datasetName}" 吗?`,
+            `确定要删除知识库 "${datasetName}" 吗?此操作不可恢复。`,
             '删除确认',
             {
               confirmButtonText: '删除',
               cancelButtonText: '取消',
               type: 'warning',
+              confirmButtonClass: 'delete-confirm-btn',
+              cancelButtonClass: 'delete-cancel-btn'
             }
         );
         await deleteKnowledgeBase(datasetId);
@@ -183,6 +296,15 @@ export default defineComponent({
       });
     };
 
+    const formatDate = (dateString: string) => {
+      const date = new Date(dateString);
+      return date.toLocaleDateString('zh-CN', {
+        year: 'numeric',
+        month: 'short',
+        day: 'numeric'
+      });
+    };
+
     // 初始化加载
     fetchKnowledgeBaseList();
 
@@ -191,59 +313,660 @@ export default defineComponent({
       newKnowledgeBaseTitle,
       createModalVisible,
       loading,
+      totalDocuments,
       showCreateModal,
       createKnowledgeBase,
       confirmDelete,
       goToDetailPage,
+      formatDate,
     };
   }
 });
 </script>
 
 <style scoped>
-.el-card {
+/* 基础样式 - 与RAG搜索页面保持一致 */
+.app-container {
+  min-height: 100vh;
+  background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
+  font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
+}
+
+/* 顶部导航样式 */
+.app-header {
+  background: rgba(255, 255, 255, 0.1);
+  backdrop-filter: blur(20px);
+  padding: 16px 0;
+  border-bottom: 1px solid rgba(255, 255, 255, 0.1);
+}
+
+.header-content {
+  max-width: 1400px;
+  margin: 0 auto;
+  padding: 0 24px;
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+}
+
+.header-main {
+  display: flex;
+  align-items: center;
+  gap: 16px;
+  flex: 1;
+}
+
+.app-title {
+  color: white;
+  font-size: 2.25rem;
+  font-weight: 800;
+  margin: 0;
+  text-shadow: 0 2px 10px rgba(0, 0, 0, 0.3);
+  background: linear-gradient(135deg, #fff 0%, #e2e8f0 100%);
+  -webkit-background-clip: text;
+  -webkit-text-fill-color: transparent;
+  background-clip: text;
+}
+
+.app-subtitle {
+  color: rgba(255, 255, 255, 0.8);
+  font-size: 1.1rem;
+  margin: 8px 0 0 0;
+}
+
+.header-stats {
+  display: flex;
+  gap: 24px;
+}
+
+.stat-item {
+  display: flex;
+  flex-direction: column;
+  align-items: center;
+}
+
+.stat-number {
+  color: white;
+  font-size: 1.5rem;
+  font-weight: 700;
+}
+
+.stat-label {
+  color: rgba(255, 255, 255, 0.7);
+  font-size: 0.8rem;
+  margin-top: 4px;
+}
+
+/* 主内容区 */
+.main-content {
+  max-width: 1400px;
+  margin: 0 auto;
+  padding: 24px;
+  display: flex;
+  flex-direction: column;
+  gap: 24px;
+}
+
+/* 操作区域 */
+.action-section {
+  width: 100%;
+}
+
+.action-card {
+  background: white;
+  padding: 32px;
+  border-radius: 24px;
+  box-shadow: 0 12px 40px rgba(0, 0, 0, 0.12);
+}
+
+.action-header {
+  margin-bottom: 24px;
+}
+
+.action-header h2 {
+  margin: 0 0 8px 0;
+  color: #2d3748;
+  font-size: 1.75rem;
+  font-weight: 700;
+}
+
+.action-header p {
+  margin: 0;
+  color: #718096;
+  font-size: 1rem;
+}
+
+.action-buttons {
+  display: flex;
+  gap: 16px;
+}
+
+.create-button {
+  border-radius: 16px;
+  padding: 16px 32px;
+  font-weight: 600;
+  font-size: 1rem;
+  transition: all 0.3s ease;
+  height: 56px;
+}
+
+.create-button:not(:disabled):hover {
+  transform: translateY(-2px);
+  box-shadow: 0 8px 25px rgba(66, 153, 225, 0.4);
+}
+
+.button-content {
+  display: flex;
+  align-items: center;
+  gap: 8px;
+}
+
+.button-icon {
+  font-size: 1.1rem;
+}
+
+.button-loading {
+  display: flex;
+  align-items: center;
+  gap: 8px;
+}
+
+.loading-spinner {
+  width: 16px;
+  height: 16px;
+  border: 2px solid transparent;
+  border-top: 2px solid white;
+  border-radius: 50%;
+  animation: spin 1s linear infinite;
+}
+
+.loading-spinner-small {
+  width: 12px;
+  height: 12px;
+  border: 2px solid transparent;
+  border-top: 2px solid currentColor;
+  border-radius: 50%;
+  animation: spin 1s linear infinite;
+}
+
+@keyframes spin {
+  0% {
+    transform: rotate(0deg);
+  }
+  100% {
+    transform: rotate(360deg);
+  }
+}
+
+/* 知识库网格区域 */
+.knowledge-grid-section {
+  background: white;
+  border-radius: 24px;
+  padding: 32px;
+  box-shadow: 0 12px 40px rgba(0, 0, 0, 0.12);
+}
+
+.section-header {
+  margin-bottom: 24px;
+}
+
+.section-header h2 {
+  margin: 0 0 8px 0;
+  color: #2d3748;
+  font-size: 1.5rem;
+  font-weight: 700;
+}
+
+.section-header p {
+  margin: 0;
+  color: #718096;
+  font-size: 0.95rem;
+}
+
+/* 知识库网格 */
+.knowledge-grid {
+  display: grid;
+  grid-template-columns: repeat(auto-fill, minmax(320px, 1fr));
+  gap: 20px;
+}
+
+.knowledge-card {
+  background: white;
+  border-radius: 16px;
+  border: 1px solid #e2e8f0;
+  box-shadow: 0 4px 16px rgba(0, 0, 0, 0.06);
+  transition: all 0.3s ease;
+  position: relative;
+  overflow: hidden;
+}
+
+.knowledge-card:hover {
+  transform: translateY(-4px);
+  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.15);
+  border-color: #4299e1;
+}
+
+/* 卡片操作按钮 */
+.card-actions {
+  position: absolute;
+  top: 12px;
+  right: 12px;
+  z-index: 10;
+}
+
+/* 修复圆形按钮样式 */
+.delete-btn {
+  width: 32px;
+  height: 32px;
+  border-radius: 50%;
+  background: rgba(255, 255, 255, 0.9);
+  backdrop-filter: blur(10px);
+  border: 1px solid #e2e8f0;
+  transition: all 0.3s ease;
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  padding: 0;
+  min-width: auto;
+}
+
+/* 确保 Element Plus 的圆形按钮样式不被覆盖 */
+.delete-btn:deep(.el-button) {
+  border-radius: 50%;
+}
+
+.delete-btn:hover {
+  background: #fed7d7;
+  border-color: #feb2b2;
+  transform: scale(1.1);
+}
+
+/* 确保图标在圆形按钮中居中 */
+.delete-btn :deep(.el-icon) {
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  width: 16px;
+  height: 16px;
+}
+
+/* 卡片内容 */
+.card-content {
+  padding: 24px;
   cursor: pointer;
-  transition: transform 0.3s ease;
-  box-shadow: 0 4px 10px rgba(0, 0, 0, 0.1);
+  display: flex;
+  align-items: flex-start;
+  gap: 16px;
+}
+
+.card-icon {
+  font-size: 2rem;
+  width: 60px;
+  height: 60px;
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  background: #f7fafc;
   border-radius: 12px;
-  background-color: #fff;
-  width: 250px;
-  margin-top: 20px;
+  flex-shrink: 0;
+}
+
+.card-info {
+  flex: 1;
+  min-width: 0;
+}
+
+.knowledge-name {
+  margin: 0 0 12px 0;
+  color: #2d3748;
+  font-size: 1.2rem;
+  font-weight: 700;
+  line-height: 1.4;
+  word-break: break-word;
+}
+
+.knowledge-stats {
+  display: flex;
+  flex-direction: column;
+  gap: 6px;
+}
+
+.stat {
+  display: flex;
+  align-items: center;
+  gap: 8px;
+  color: #718096;
+  font-size: 0.9rem;
+}
+
+.stat-icon {
+  font-size: 0.8rem;
+  width: 16px;
+  text-align: center;
+}
+
+.card-arrow {
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  width: 32px;
+  height: 32px;
+  background: #f7fafc;
+  border-radius: 8px;
+  transition: all 0.3s ease;
+}
+
+.knowledge-card:hover .card-arrow {
+  background: #4299e1;
+  transform: translateX(4px);
+}
+
+.arrow-icon {
+  font-size: 0.8rem;
+  transition: all 0.3s ease;
+}
+
+.knowledge-card:hover .arrow-icon {
+  filter: brightness(0) invert(1);
+}
+
+/* 空状态 */
+.empty-state {
+  padding: 80px 32px;
+  text-align: center;
 }
 
-.el-card:hover {
-  transform: translateY(-10px);
+.empty-content {
+  max-width: 400px;
+  margin: 0 auto;
 }
 
-.el-dialog {
-  z-index: 9999;
+.empty-icon {
+  font-size: 4rem;
+  margin-bottom: 20px;
+}
+
+.empty-state h3 {
+  margin: 0 0 12px 0;
+  color: #2d3748;
+  font-size: 1.5rem;
+  font-weight: 700;
+}
+
+.empty-state p {
+  margin: 0 0 24px 0;
+  color: #718096;
+  font-size: 1rem;
+  line-height: 1.5;
+}
+
+.create-first-btn {
   border-radius: 12px;
+  padding: 12px 28px;
+  font-weight: 600;
+}
+
+/* 弹窗样式 */
+.create-dialog :deep(.el-dialog) {
+  border-radius: 24px;
+  overflow: hidden;
+  box-shadow: 0 25px 50px rgba(0, 0, 0, 0.2);
 }
 
-.el-button {
-  border-radius: 20px;
+.create-dialog :deep(.el-dialog__header) {
+  padding: 0;
+  margin: 0;
 }
 
-.el-input {
-  border-radius: 10px;
+.create-dialog :deep(.el-dialog__headerbtn) {
+  top: 24px;
+  right: 24px;
+  width: 32px;
+  height: 32px;
+  border-radius: 8px;
+  background: #f7fafc;
 }
 
-.knowledge-base-grid {
+.create-dialog :deep(.el-dialog__headerbtn:hover) {
+  background: #e2e8f0;
+}
+
+.dialog-header {
+  padding: 0;
+}
+
+.dialog-title {
   display: flex;
-  flex-wrap: wrap;
-  gap: 20px;
-  justify-content: flex-start;
+  align-items: flex-start;
+  gap: 16px;
+  padding: 32px 32px 0;
+}
+
+.title-icon {
+  font-size: 2.5rem;
+  width: 60px;
+  height: 60px;
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
+  border-radius: 16px;
+  color: white;
+  flex-shrink: 0;
+}
+
+.title-content {
+  flex: 1;
+  min-width: 0;
+}
+
+.title-content h3 {
+  margin: 0 0 8px 0;
+  color: #2d3748;
+  font-size: 1.5rem;
+  font-weight: 700;
+  line-height: 1.4;
+}
+
+.title-content p {
+  margin: 0;
+  color: #718096;
+  font-size: 0.95rem;
+}
+
+.dialog-content {
+  padding: 0 32px;
+}
+
+.input-section {
+  margin-top: 24px;
+}
+
+.input-label {
+  display: block;
+  margin-bottom: 8px;
+  color: #2d3748;
+  font-weight: 600;
+  font-size: 0.95rem;
+}
+
+.name-input {
+  border-radius: 16px;
+}
+
+.name-input :deep(.el-input__wrapper) {
+  border-radius: 16px;
+  padding: 16px 20px;
+  box-shadow: 0 4px 16px rgba(0, 0, 0, 0.08);
+  border: 1px solid #e2e8f0;
+  transition: all 0.3s ease;
+  height: 56px;
+  display: flex;
+  align-items: center;
+}
+
+.name-input :deep(.el-input__wrapper:hover) {
+  border-color: #4299e1;
+  box-shadow: 0 4px 20px rgba(66, 153, 225, 0.15);
+}
+
+.name-input :deep(.el-input__wrapper.is-focus) {
+  border-color: #4299e1;
+  box-shadow: 0 4px 20px rgba(66, 153, 225, 0.2);
+}
+
+.input-tips {
+  font-size: 0.8rem;
+  color: #718096;
+  margin-top: 8px;
+  text-align: right;
+}
+
+.dialog-footer {
+  padding: 0 32px 24px;
+}
+
+.footer-actions {
+  display: flex;
+  justify-content: flex-end;
+  gap: 12px;
+}
+
+.action-btn {
+  border-radius: 12px;
+  padding: 10px 24px;
+  font-weight: 500;
+  transition: all 0.3s ease;
+}
+
+.action-btn.secondary {
+  border: 1px solid #e2e8f0;
+  background: white;
+  color: #718096;
+}
+
+.action-btn.secondary:hover {
+  background: #f7fafc;
+  border-color: #cbd5e0;
+}
+
+.action-btn.primary {
+  background: #4299e1;
+  border: 1px solid #4299e1;
+  color: white;
+}
+
+.action-btn.primary:hover {
+  background: #3182ce;
+  border-color: #3182ce;
+  transform: translateY(-1px);
+  box-shadow: 0 4px 12px rgba(66, 153, 225, 0.3);
+}
+
+/* 响应式设计 */
+@media (max-width: 1200px) {
+  .knowledge-grid {
+    grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
+  }
 }
 
 @media (max-width: 768px) {
-  .el-card {
-    width: 230px;
+  .app-title {
+    font-size: 1.75rem;
+  }
+
+  .main-content {
+    padding: 16px;
+  }
+
+  .action-card {
+    padding: 24px;
+  }
+
+  .knowledge-grid-section {
+    padding: 24px;
+  }
+
+  .knowledge-grid {
+    grid-template-columns: 1fr;
+  }
+
+  .dialog-title {
+    flex-direction: column;
+    text-align: center;
+    gap: 12px;
+  }
+
+  .title-content h3 {
+    font-size: 1.3rem;
+  }
+
+  .dialog-content {
+    padding: 0 20px;
+  }
+
+  .header-stats {
+    gap: 32px;
   }
 }
 
 @media (max-width: 480px) {
-  .el-card {
-    width: 100%;
+  .app-title {
+    font-size: 1.5rem;
+  }
+
+  .action-card {
+    padding: 20px;
   }
+
+  .knowledge-grid-section {
+    padding: 20px;
+  }
+
+  .create-dialog :deep(.el-dialog) {
+    width: 95% !important;
+    margin: 20px auto;
+  }
+
+  .card-content {
+    flex-direction: column;
+    text-align: center;
+    gap: 12px;
+  }
+
+  .card-icon {
+    align-self: center;
+  }
+}
+
+/* 删除确认对话框样式 */
+:deep(.delete-confirm-btn) {
+  border-radius: 12px;
+  background: #e53e3e;
+  border-color: #e53e3e;
+}
+
+:deep(.delete-confirm-btn:hover) {
+  background: #c53030;
+  border-color: #c53030;
+}
+
+:deep(.delete-cancel-btn) {
+  border-radius: 12px;
+}
+
+/* 深度选择器确保圆形按钮样式正确 */
+:deep(.delete-btn.el-button) {
+  border-radius: 50%;
+  padding: 0;
+  min-width: 32px;
+  width: 32px;
+  height: 32px;
+}
+
+:deep(.delete-btn.el-button .el-icon) {
+  display: flex;
+  align-items: center;
+  justify-content: center;
 }
-</style>
+</style>

+ 895 - 199
src/views/KnowledgeContent.vue

@@ -1,180 +1,263 @@
 <template>
-  <el-container style="height: 100vh;">
-    <!-- 上方的 Header -->
-    <el-header
-        style="height: 50px; background: linear-gradient(to right, #6db3f2, #1e69e8); color: white; display: flex; align-items: center; padding: 0 20px;">
-      <!-- 返回按钮 -->
-      <el-button @click="goBack"
-                 style="margin-right: 20px; background-color: #fff; color: #409EFF; border: 1px solid #409EFF;">
-        返回
-      </el-button>
-
-      <!-- 知识库名称 -->
-      <div style="font-size: 18px; font-weight: bold; flex-grow: 1;">
-        {{ datasetName }}
+  <div class="app-container">
+    <!-- 顶部导航 -->
+    <div class="app-header">
+      <div class="header-content">
+        <div class="header-main">
+          <h1 class="app-title">知识库内容管理</h1>
+          <p class="app-subtitle">管理知识库中的文档和内容</p>
+        </div>
+        <div class="header-stats">
+          <div class="stat-item">
+            <span class="stat-number">{{ totalItems }}</span>
+            <span class="stat-label">总文档</span>
+          </div>
+          <div class="stat-item">
+            <span class="stat-number">{{ currentPageItems.length }}</span>
+            <span class="stat-label">本页</span>
+          </div>
+        </div>
       </div>
+    </div>
 
-      <!-- 添加新知识按钮 -->
-      <el-button @click="openDialog"
-                 style="border-radius: 20px; background-color: #fff; color: #409EFF; border: 1px solid #409EFF;">
-        添加新知识
-      </el-button>
-    </el-header>
-
-    <el-container>
-      <!-- 左侧菜单栏 -->
-      <el-aside
-          width="330px"
-          style="background-color: #f4f4f4; padding: 10px; display: flex; flex-direction: column; overflow-y: auto; height: calc(100vh - 60px);"
-      >
-        <!-- 左侧标题,居中显示 -->
-        <div
-            style="font-size: 18px; font-weight: bold; margin-bottom: 10px; text-align: center; width: 100%;"
-        >
-          内容列表
+    <div class="main-layout">
+      <!-- 左侧文档列表 -->
+      <div class="sidebar">
+        <div class="sidebar-header">
+          <div class="sidebar-title">
+            <h3>📚 文档列表</h3>
+            <p class="sidebar-subtitle">{{ datasetName }} - 共 {{ totalItems }} 篇文档</p>
+          </div>
+          <el-button
+              class="add-btn"
+              type="primary"
+              @click="openDialog"
+          >
+            <span class="button-icon">➕</span>
+            添加文档
+          </el-button>
         </div>
 
-        <!-- 菜单,只有在有数据时才渲染 -->
-        <el-menu
-            v-if="currentPageItems && currentPageItems.length > 0"
-            :default-active="activeItem"
-            @select="handleSelect"
-            style="border-right: none; flex-grow: 1;"
-        >
-          <el-menu-item
+        <div class="knowledge-list">
+          <div
               v-for="item in currentPageItems"
               :key="item.doc_id"
-              :index="String(item.doc_id)"
-              style="display: flex; justify-content: space-between; align-items: center;"
+              :class="['document-card', { 'active': activeItem === String(item.doc_id) }]"
+              @click="handleSelect(String(item.doc_id))"
           >
-            <span v-if="item.statusDesc" style="margin-right: 8px; display: flex; align-items: center;">
-            <span :style="{
-              width: '12px',
-              height: '12px',
-              borderRadius: '50%',
-              backgroundColor: item.statusDesc === '可用' ? '#4fc280' : '#f56c6c',
-              marginRight: '5px'
-              }">
-            </span>
-            </span>
-            <!-- 左边文字:固定宽度 + 超出省略号 -->
-            <span class="menu-text">{{ item.title || item.text }}</span>
-
-            <!-- 删除按钮 -->
-            <el-icon
-                style="cursor: pointer; font-size: 18px; color: #f56c6c; display: flex; align-items: center; justify-content: center;"
-                @click.stop="confirmDelete(item.doc_id, item.title)"
-            >
-              <Delete/>
-            </el-icon>
-          </el-menu-item>
-        </el-menu>
-
-        <!-- 没有数据时的占位 -->
-        <div v-else style="text-align: center; color: #999; padding: 20px;">
-          暂无内容
+            <div class="card-content">
+              <div class="document-icon">
+                <span v-if="item.statusDesc === '可用'" class="status-available">✅</span>
+                <span v-else class="status-unavailable">❌</span>
+              </div>
+              <div class="document-info">
+                <span class="document-name">{{ item.title || item.text }}</span>
+<!--                <span class="document-status" :class="item.statusDesc === '可用' ? 'available' : 'unavailable'">-->
+<!--                  {{ item.statusDesc || '未知状态' }}-->
+<!--                </span>-->
+              </div>
+              <div class="document-actions">
+                <el-tooltip content="删除文档" placement="top">
+                  <el-button
+                      text
+                      class="delete-btn"
+                      @click.stop="confirmDelete(item.doc_id, item.title)"
+                  >
+                    🗑️
+                  </el-button>
+                </el-tooltip>
+              </div>
+            </div>
+          </div>
         </div>
 
         <!-- 分页 -->
-        <el-pagination
-            v-model:current-page="pageIndex"
-            :page-size="pageSize"
-            :total="totalItems"
-            :pager-count="5"
-            layout="prev, pager, next"
-            @current-change="handlePageChange"
-            style="margin-top: 20px; text-align: center;"
-        />
-      </el-aside>
-
-      <!-- 右侧内容区域 -->
-      <el-main style="padding: 20px; overflow-y: auto; height: calc(100vh - 60px); position: relative;">
-        <el-button
-            v-if="selectedContent"
-            size="small"
-            type="primary"
-            style="position: absolute; top: 10px; right: 10px;"
-            @click="openChunkDialog"
-        >
-          展示分段
-        </el-button>
-        <h2>{{ selectedTitle }}</h2>
-        <p>{{ selectedContent }}</p>
-      </el-main>
-
-      <!-- 分段展示弹窗 -->
-      <el-dialog
-          title="文档分段"
-          v-model="chunkDialogVisible"
-          width="80%"
-          :destroy-on-close="true"
-          :top="'5vh'"
-      >
-        <div style="max-height: 80%; overflow-y: auto;">
-          <!-- 延迟渲染,避免动画阶段触发 ResizeObserver -->
-          <el-table
-              v-if="chunkDialogVisible && chunkList.length > 0"
-              :data="chunkList"
-              style="width: 100%; min-height: 100px;"
-          >
-            <el-table-column prop="chunk_id" label="分段ID" width="100" header-align="center" align="center"/>
-            <el-table-column prop="summary" label="总结" width="300" header-align="center"/>
-            <el-table-column prop="text" label="内容" header-align="center"/>
-            <el-table-column prop="statusDesc" label="状态" width="100" header-align="center" align="center"/>
-          </el-table>
-
-
-          <!-- 分页器 -->
-          <div style="margin-top: 10px; text-align: center;">
-            <el-pagination
-                v-model:current-page="chunkPage"
-                :page-size="chunkPageSize"
-                :total="chunkTotal"
-                layout="prev, pager, next"
-                @current-change="fetchChunks"
-            />
+        <div class="sidebar-footer">
+          <div class="pagination-info">
+            共 {{ totalItems }} 篇文档
           </div>
+          <el-pagination
+              v-model:current-page="pageIndex"
+              :page-size="pageSize"
+              :total="totalItems"
+              :pager-count="5"
+              layout="prev, pager, next"
+              @current-change="handlePageChange"
+              class="custom-pagination"
+          />
         </div>
-      </el-dialog>
+      </div>
 
+      <!-- 右侧内容区域 -->
+      <div class="content-area">
+        <div class="content-section">
+          <div class="content-header">
+            <div class="content-title">
+              <h2>{{ selectedTitle || '选择文档查看内容' }}</h2>
+              <span v-if="statusDesc" class="content-status" :class="statusDesc === '可用' ? 'available' : 'unavailable'">
+                {{ statusDesc }}
+              </span>
+            </div>
+            <el-button
+                v-if="selectedContent"
+                type="primary"
+                class="chunk-btn"
+                @click="openChunkDialog"
+            >
+              <span class="button-icon">📖</span>
+              查看分段
+            </el-button>
+          </div>
 
-    </el-container>
+          <div class="content-body">
+            <div v-if="selectedContent" class="content-text">
+              <pre>{{ selectedContent }}</pre>
+            </div>
+            <div v-else class="empty-content">
+              <div class="empty-icon">📄</div>
+              <h3>选择左侧文档查看内容</h3>
+              <p>点击左侧文档列表中的项目查看详细内容</p>
+            </div>
+          </div>
+        </div>
+      </div>
+    </div>
 
-    <!-- 弹窗 -->
-    <el-dialog title="添加新知识" v-model="dialogVisible" @close="resetForm">
-      <el-form :model="formData" ref="formRef" label-width="80px">
-        <el-form-item label="标题" :rules="[{ required: true, message: '请输入标题', trigger: 'blur' }]">
-          <el-input v-model="formData.title" placeholder="请输入标题"></el-input>
-        </el-form-item>
+    <!-- 添加文档弹窗 -->
+    <el-dialog
+        title="添加新文档"
+        v-model="dialogVisible"
+        width="600px"
+        class="content-dialog"
+        @close="resetForm"
+    >
+      <div class="dialog-content">
+        <el-form :model="formData" ref="formRef" label-width="100px">
+          <el-form-item label="📝 文档标题" :rules="[{ required: true, message: '请输入标题', trigger: 'blur' }]">
+            <el-input
+                v-model="formData.title"
+                placeholder="请输入文档标题"
+                size="large"
+            ></el-input>
+          </el-form-item>
 
-        <el-form-item label="文本" :rules="[{ required: true, message: '请输入文本内容', trigger: 'blur' }]">
-          <el-input type="textarea" v-model="formData.text" placeholder="请输入文本" rows="6"></el-input>
-        </el-form-item>
+          <el-form-item label="📄 文档内容" :rules="[{ required: true, message: '请输入文本内容', trigger: 'blur' }]">
+            <el-input
+                type="textarea"
+                v-model="formData.text"
+                placeholder="请输入文档内容"
+                :rows="8"
+                resize="none"
+            ></el-input>
+          </el-form-item>
 
-        <!-- 新增:是否分块开关 -->
-        <el-form-item label="是否分块">
-          <el-switch v-model="formData.isChunk"></el-switch>
-        </el-form-item>
-      </el-form>
+          <el-form-item label="🔗 是否分块">
+            <el-switch
+                v-model="formData.isChunk"
+                active-text="启用分块"
+                inactive-text="禁用分块"
+            ></el-switch>
+          </el-form-item>
+        </el-form>
+      </div>
 
-      <!-- 使用 <template> 标签来声明插槽 -->
       <template #footer>
-        <el-button @click="dialogVisible = false">取 消</el-button>
-        <el-button type="primary" @click="submitData">确 定</el-button>
+        <div class="dialog-footer">
+          <el-button
+              class="action-btn secondary"
+              @click="dialogVisible = false"
+          >
+            取消
+          </el-button>
+          <el-button
+              type="primary"
+              class="action-btn primary"
+              @click="submitData"
+          >
+            💾 保存文档
+          </el-button>
+        </div>
       </template>
     </el-dialog>
-  </el-container>
+
+    <!-- 分段展示弹窗 -->
+    <el-dialog
+        title="📑 文档分段"
+        v-model="chunkDialogVisible"
+        width="90%"
+        class="content-dialog"
+        :destroy-on-close="true"
+    >
+      <div class="chunk-content">
+        <el-table
+            v-if="chunkDialogVisible && chunkList.length > 0"
+            :data="chunkList"
+            style="width: 100%"
+            class="chunk-table"
+        >
+          <el-table-column
+              prop="chunk_id"
+              label="分段ID"
+              width="100"
+              header-align="center"
+              align="center"
+          />
+          <el-table-column
+              prop="summary"
+              label="内容摘要"
+              width="300"
+              header-align="center"
+              show-overflow-tooltip
+          />
+          <el-table-column
+              prop="text"
+              label="完整内容"
+              header-align="center"
+              show-overflow-tooltip
+          />
+          <el-table-column
+              prop="statusDesc"
+              label="状态"
+              width="100"
+              header-align="center"
+              align="center"
+          >
+            <template #default="scope">
+              <span :class="scope.row.statusDesc === '可用' ? 'status-available' : 'status-unavailable'">
+                {{ scope.row.statusDesc }}
+              </span>
+            </template>
+          </el-table-column>
+        </el-table>
+
+        <div v-else class="empty-chunks">
+          <div class="empty-icon">📝</div>
+          <h3>暂无分段内容</h3>
+          <p>该文档没有分块或分块内容为空</p>
+        </div>
+
+        <!-- 分页器 -->
+        <div v-if="chunkTotal > 0" class="pagination-section">
+          <el-pagination
+              v-model:current-page="chunkPage"
+              :page-size="chunkPageSize"
+              :total="chunkTotal"
+              layout="prev, pager, next"
+              @current-change="fetchChunks"
+          />
+        </div>
+      </div>
+    </el-dialog>
+  </div>
 </template>
 
 <script lang="ts">
 import {API_BASE_URL} from "@/config";
 import {defineComponent, onMounted, ref, computed} from 'vue';
-import {useRouter} from 'vue-router'; // 引入 vue-router 用于路由跳转
+import {useRouter} from 'vue-router';
 import axios from 'axios';
 import {ElMessage, ElMessageBox} from 'element-plus';
-import {Delete} from '@element-plus/icons-vue';
 
-// 定义接口类型
 interface Item {
   doc_id: string;
   title: string | null;
@@ -188,9 +271,7 @@ export default defineComponent({
     const router = useRouter();
     const datasetId = ref<number | null>(null);
     const datasetName = ref<string | null>('');
-    // 当前选中的菜单项
     const activeItem = ref('');
-    // 当前选中的内容的标题和内容
     const selectedTitle = ref('');
     const selectedContent = ref('');
     const statusDesc = ref('');
@@ -200,7 +281,6 @@ export default defineComponent({
     const pageSize = ref(10);
     const totalItems = ref(0);
 
-    // 使用 Item[] 来明确 allItems 数组的类型
     const allItems = ref<Item[]>([]);
 
     // 新知识表单数据
@@ -210,7 +290,8 @@ export default defineComponent({
       isChunk: true
     });
 
-    const dialogVisible = ref(false); // 控制弹窗的显示和隐藏
+    const dialogVisible = ref(false);
+    const formRef = ref();
 
     // 分段弹窗
     const chunkDialogVisible = ref(false);
@@ -227,21 +308,22 @@ export default defineComponent({
           params: {
             page: pageIndex.value,
             pageSize: pageSize.value,
-            datasetId: datasetId, // 可以传递 datasetId 作为查询参数
+            datasetId: datasetId,
           }
         });
         const data = response.data.data;
         allItems.value = data.entities;
         totalItems.value = data.total_count;
-        console.log(data);  // 输出数据查看
+        console.log(data);
       } catch (error) {
         console.error('Error fetching data:', error);
+        ElMessage.error('获取文档列表失败');
       }
     };
 
     // 当前页面的项目
     const currentPageItems = computed(() => {
-      return allItems.value; // 不再切片,由后端控制分页
+      return allItems.value;
     });
 
     // 处理菜单项选择
@@ -249,17 +331,17 @@ export default defineComponent({
       activeItem.value = doc_id;
       const selected = allItems.value.find(item => item.doc_id === doc_id);
       if (selected) {
-        selectedTitle.value = selected.title || ''; // 如果 title 为 null,使用默认值
+        selectedTitle.value = selected.title || '';
         selectedContent.value = selected.text;
-        statusDesc.value = selected.statusDesc
+        statusDesc.value = selected.statusDesc;
       }
     };
 
     // 处理页码变更
     const handlePageChange = (newPage: number) => {
       pageIndex.value = newPage;
-      if (datasetId.value !== null) { // 确保 datasetId 不是 null
-        fetchData(datasetId.value);  // 重新获取数据
+      if (datasetId.value !== null) {
+        fetchData(datasetId.value);
       } else {
         console.error('datasetId is null');
       }
@@ -269,9 +351,8 @@ export default defineComponent({
     onMounted(() => {
       const query = new URLSearchParams(window.location.search);
       datasetId.value = query.get('datasetId') ? parseInt(query.get('datasetId')!) : null;
-      datasetName.value = query.get('datasetName')
+      datasetName.value = query.get('datasetName');
 
-      // 只有在 datasetId 存在时才调用 fetchData
       if (datasetId.value !== null) {
         fetchData(datasetId.value);
       } else {
@@ -281,11 +362,6 @@ export default defineComponent({
       console.log(`知识库 ID: ${datasetId.value}`);
     });
 
-    // 返回首页路由
-    const goBack = () => {
-      router.push('/');  // 跳转到首页
-    };
-
     // 打开弹窗
     const openDialog = () => {
       dialogVisible.value = true;
@@ -300,7 +376,6 @@ export default defineComponent({
     // 提交表单数据
     const submitData = async () => {
       if (!formData.value.title || !formData.value.text) {
-        // 如果标题或文本为空,提示用户
         ElMessage.error('标题和文本不能为空');
         return;
       }
@@ -314,21 +389,19 @@ export default defineComponent({
         });
 
         console.log('提交成功:', response.data);
-        // 提交成功后隐藏弹窗
         dialogVisible.value = false;
-        // 重新加载数据
-        if (datasetId.value !== null) { // 确保 datasetId 不是 null
-          fetchData(datasetId.value);  // 重新获取数据
+
+        if (datasetId.value !== null) {
+          fetchData(datasetId.value);
         } else {
           console.error('datasetId is null');
         }
 
-        // 显示提交成功的提示
-        ElMessage.success('新知识添加成功!');
+        ElMessage.success('文档添加成功!');
+        resetForm();
 
       } catch (error) {
         console.error('提交失败:', error);
-        // 提交失败时给用户提示
         ElMessage.error('提交失败,请稍后再试!');
       }
     };
@@ -342,6 +415,8 @@ export default defineComponent({
             confirmButtonText: '删除',
             cancelButtonText: '取消',
             type: 'warning',
+            confirmButtonClass: 'delete-confirm-btn',
+            cancelButtonClass: 'delete-cancel-btn'
           }
       ).then(() => {
         deleteDoc(doc_id);
@@ -359,7 +434,7 @@ export default defineComponent({
         });
         ElMessage.success('删除成功');
         if (datasetId.value !== null) {
-          fetchData(datasetId.value); // 刷新列表
+          fetchData(datasetId.value);
         }
       } catch (error) {
         console.error(error);
@@ -377,7 +452,7 @@ export default defineComponent({
       await fetchChunks(chunkPage.value);
     };
 
-// 获取分段数据
+    // 获取分段数据
     const fetchChunks = async (page: number) => {
       if (!activeItem.value) return;
       try {
@@ -409,7 +484,6 @@ export default defineComponent({
       handleSelect,
       handlePageChange,
       datasetName,
-      goBack,
       formData,
       dialogVisible,
       openDialog,
@@ -417,7 +491,6 @@ export default defineComponent({
       resetForm,
       confirmDelete,
       deleteDoc,
-      Delete,
       chunkDialogVisible,
       chunkList,
       chunkPage,
@@ -426,44 +499,667 @@ export default defineComponent({
       openChunkDialog,
       fetchChunks,
       statusDesc,
+      formRef
     };
   },
 });
 </script>
 
 <style scoped>
-.el-container {
+/* 基础样式 */
+.app-container {
+  min-height: 100vh;
+  background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
+  font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
+}
+
+/* 顶部导航样式 */
+.app-header {
+  background: rgba(255, 255, 255, 0.1);
+  backdrop-filter: blur(20px);
+  padding: 16px 0;
+  border-bottom: 1px solid rgba(255, 255, 255, 0.1);
+}
+
+.header-content {
+  max-width: 1400px;
+  margin: 0 auto;
+  padding: 0 24px;
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+}
+
+.header-main {
+  flex: 1;
+}
+
+.app-title {
+  color: white;
+  font-size: 2.25rem;
+  font-weight: 800;
+  margin: 0;
+  text-shadow: 0 2px 10px rgba(0, 0, 0, 0.3);
+  background: linear-gradient(135deg, #fff 0%, #e2e8f0 100%);
+  -webkit-background-clip: text;
+  -webkit-text-fill-color: transparent;
+  background-clip: text;
+}
+
+.app-subtitle {
+  color: rgba(255, 255, 255, 0.9);
+  font-size: 1rem;
+  margin: 8px 0 0 0;
+  font-weight: 500;
+}
+
+.header-stats {
+  display: flex;
+  gap: 24px;
+}
+
+.stat-item {
+  display: flex;
+  flex-direction: column;
+  align-items: center;
+}
+
+.stat-number {
+  color: white;
+  font-size: 1.5rem;
+  font-weight: 700;
+}
+
+.stat-label {
+  color: rgba(255, 255, 255, 0.7);
+  font-size: 0.8rem;
+  margin-top: 4px;
+}
+
+/* 主布局 */
+.main-layout {
   display: flex;
-  height: calc(100vh - 60px); /* 减去导航栏的高度 */
+  max-width: 1400px;
+  margin: 0 auto;
+  padding: 24px;
+  gap: 24px;
+  min-height: calc(100vh - 120px);
+  align-items: flex-start;
 }
 
-.el-aside {
-  background-color: #f4f4f4;
-  padding: 10px;
-  overflow-y: auto; /* 允许纵向滚动 */
+/* 侧边栏样式 */
+.sidebar {
+  width: 400px;
+  flex-shrink: 0;
+  display: flex;
+  flex-direction: column;
+  position: sticky;
+  top: 24px;
+  max-height: calc(100vh - 120px);
+  overflow-y: auto;
 }
 
-.el-main {
-  background-color: #fff;
+.sidebar-header {
+  background: white;
   padding: 20px;
-  overflow-y: auto; /* 允许纵向滚动 */
+  border-radius: 20px;
+  margin-bottom: 16px;
+  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.1);
+  display: flex;
+  justify-content: space-between;
+  align-items: flex-start;
+  flex-shrink: 0;
+}
+
+.sidebar-title h3 {
+  margin: 0 0 6px 0;
+  color: #2d3748;
+  font-size: 1.25rem;
+  font-weight: 700;
+}
+
+.sidebar-subtitle {
+  margin: 0;
+  color: #718096;
+  font-size: 0.85rem;
+}
+
+.add-btn {
+  border-radius: 12px;
+  padding: 8px 16px;
+  font-weight: 500;
+}
+
+.button-icon {
+  margin-right: 6px;
+}
+
+.knowledge-list {
+  flex: 1;
+  display: flex;
+  flex-direction: column;
+  gap: 12px;
+  overflow-y: auto;
+  min-height: 0;
+}
+
+.document-card {
+  background: white;
+  border-radius: 16px;
+  cursor: pointer;
+  transition: all 0.3s ease;
+  border: 2px solid transparent;
+  box-shadow: 0 4px 16px rgba(0, 0, 0, 0.08);
+  overflow: hidden;
+}
+
+.document-card:hover {
+  transform: translateY(-2px);
+  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.15);
+}
+
+.document-card.active {
+  border-color: #4299e1;
+  background: linear-gradient(135deg, #ebf8ff 0%, #ffffff 100%);
+}
+
+.card-content {
+  padding: 5px;
+  display: flex;
+  align-items: center;
+  gap: 12px;
+}
+
+.document-icon {
+  font-size: 1.25rem;
+  width: 40px;
+  height: 40px;
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  background: #f7fafc;
+  border-radius: 10px;
+  flex-shrink: 0;
+}
+
+.document-info {
+  flex: 1;
+  min-width: 0;
+}
+
+.document-name {
+  display: block;
+  font-weight: 600;
+  color: #2d3748;
+  margin-bottom: 4px;
+  font-size: 0.95rem;
+  line-height: 1.4;
+  overflow: hidden;
+  text-overflow: ellipsis;
+  white-space: nowrap;
+}
+
+.document-status {
+  font-size: 0.75rem;
+  font-weight: 500;
+  padding: 2px 8px;
+  border-radius: 8px;
+}
+
+.document-status.available {
+  background: #f0fff4;
+  color: #2f855a;
+  border: 1px solid #c6f6d5;
+}
+
+.document-status.unavailable {
+  background: #fed7d7;
+  color: #c53030;
+  border: 1px solid #feb2b2;
+}
+
+.document-actions {
+  display: flex;
+  align-items: center;
+}
+
+.delete-btn {
+  padding: 6px;
+  border-radius: 8px;
+  color: #e53e3e;
+  transition: all 0.3s ease;
+}
+
+.delete-btn:hover {
+  background: #fed7d7;
+  transform: scale(1.1);
+}
+
+.sidebar-footer {
+  background: white;
+  padding: 16px 20px;
+  border-radius: 16px;
+  margin-top: 16px;
+  box-shadow: 0 4px 16px rgba(0, 0, 0, 0.08);
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+  flex-shrink: 0;
+}
+
+.pagination-info {
+  color: #718096;
+  font-size: 0.85rem;
+  font-weight: 500;
+}
+
+.custom-pagination {
+  margin: 0;
+}
+
+.custom-pagination :deep(.el-pagination) {
+  justify-content: flex-end;
+}
+
+/* 主内容区样式 */
+.content-area {
+  flex: 1;
+  display: flex;
+  flex-direction: column;
+  min-height: 0;
+}
+
+.content-section {
+  background: white;
+  border-radius: 24px;
+  padding: 32px;
+  box-shadow: 0 12px 40px rgba(0, 0, 0, 0.12);
+  flex: 1;
+  display: flex;
+  flex-direction: column;
 }
 
-.el-menu-item {
+.content-header {
+  display: flex;
+  justify-content: space-between;
+  align-items: flex-start;
+  margin-bottom: 24px;
+  padding-bottom: 20px;
+  border-bottom: 1px solid #e2e8f0;
+}
+
+.content-title {
+  flex: 1;
+}
+
+.content-title h2 {
+  margin: 0 0 8px 0;
+  color: #2d3748;
+  font-size: 1.75rem;
+  font-weight: 700;
+  line-height: 1.4;
+}
+
+.content-status {
+  font-size: 0.85rem;
+  font-weight: 500;
+  padding: 4px 12px;
+  border-radius: 12px;
+}
+
+.content-status.available {
+  background: #f0fff4;
+  color: #2f855a;
+  border: 1px solid #c6f6d5;
+}
+
+.content-status.unavailable {
+  background: #fed7d7;
+  color: #c53030;
+  border: 1px solid #feb2b2;
+}
+
+.chunk-btn {
+  border-radius: 12px;
   padding: 10px 20px;
-  font-size: 14px; /* 控制菜单项的字体大小 */
-  height: auto;
-  white-space: nowrap; /* 不换行 */
-  overflow: hidden; /* 超出部分隐藏 */
-  text-overflow: ellipsis; /* 使用省略号代替超出的文本 */
+  font-weight: 500;
+}
+
+.content-body {
+  flex: 1;
+  display: flex;
+  flex-direction: column;
+}
+
+.content-text {
+  background: #f7fafc;
+  border-radius: 12px;
+  border: 1px solid #e2e8f0;
+  padding: 24px;
+  flex: 1;
+  overflow-y: auto;
+}
+
+.content-text pre {
+  margin: 0;
+  color: #4a5568;
+  line-height: 1.6;
+  font-size: 0.95rem;
+  white-space: pre-wrap;
+  word-wrap: break-word;
+  font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
+}
+
+.empty-content {
+  flex: 1;
+  display: flex;
+  flex-direction: column;
+  align-items: center;
+  justify-content: center;
+  padding: 60px 20px;
+  text-align: center;
+}
+
+.empty-icon {
+  font-size: 4rem;
+  margin-bottom: 20px;
+  opacity: 0.6;
+}
+
+.empty-content h3 {
+  margin: 0 0 12px 0;
+  color: #2d3748;
+  font-size: 1.5rem;
+  font-weight: 600;
+}
+
+.empty-content p {
+  margin: 0;
+  color: #718096;
+  font-size: 1rem;
+  line-height: 1.5;
+}
+
+/* 弹窗样式 */
+.content-dialog :deep(.el-dialog) {
+  border-radius: 24px;
+  overflow: hidden;
+  box-shadow: 0 25px 50px rgba(0, 0, 0, 0.2);
+}
+
+.content-dialog :deep(.el-dialog__header) {
+  padding: 0;
+  margin: 0;
+  border-bottom: 1px solid #e2e8f0;
+}
+
+.content-dialog :deep(.el-dialog__headerbtn) {
+  top: 24px;
+  right: 24px;
+  width: 32px;
+  height: 32px;
+  border-radius: 8px;
+  background: #f7fafc;
+}
+
+.content-dialog :deep(.el-dialog__headerbtn:hover) {
+  background: #e2e8f0;
+}
+
+.content-dialog :deep(.el-dialog__title) {
+  font-size: 1.5rem;
+  font-weight: 700;
+  color: #2d3748;
+}
+
+.dialog-content {
+  padding: 0;
+}
+
+.content-dialog :deep(.el-form-item__label) {
+  font-weight: 600;
+  color: #2d3748;
+}
+
+.content-dialog :deep(.el-input__wrapper) {
+  border-radius: 12px;
+  padding: 12px 16px;
+  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
+  border: 1px solid #e2e8f0;
+}
+
+.content-dialog :deep(.el-textarea__inner) {
+  border-radius: 12px;
+  padding: 12px 16px;
+  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
+  border: 1px solid #e2e8f0;
+  font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
+}
+
+.content-dialog :deep(.el-switch) {
+  --el-switch-on-color: #4299e1;
+}
+
+.dialog-footer {
+  padding: 0;
+  margin-top: 24px;
+  display: flex;
+  justify-content: flex-end;
+  gap: 12px;
+}
+
+.action-btn {
+  border-radius: 12px;
+  padding: 10px 24px;
+  font-weight: 500;
+  transition: all 0.3s ease;
+}
+
+.action-btn.secondary {
+  border: 1px solid #e2e8f0;
+  background: white;
+  color: #718096;
+}
+
+.action-btn.secondary:hover {
+  background: #f7fafc;
+  border-color: #cbd5e0;
+}
+
+.action-btn.primary {
+  background: #4299e1;
+  border: 1px solid #4299e1;
+  color: white;
 }
 
-.menu-text {
-  max-width: 200px; /* 固定宽度 */
-  display: inline-block;
-  white-space: nowrap; /* 不换行 */
-  overflow: hidden; /* 超出隐藏 */
-  text-overflow: ellipsis; /* 显示省略号 */
+.action-btn.primary:hover {
+  background: #3182ce;
+  border-color: #3182ce;
+  transform: translateY(-1px);
+  box-shadow: 0 4px 12px rgba(66, 153, 225, 0.3);
 }
 
-</style>
+/* 分段弹窗样式 */
+.chunk-content {
+  padding: 0;
+}
+
+.chunk-table :deep(.el-table) {
+  border-radius: 12px;
+  overflow: hidden;
+}
+
+.chunk-table :deep(.el-table__header) {
+  background: #f7fafc;
+}
+
+.chunk-table :deep(.el-table th) {
+  background: #f7fafc;
+  color: #2d3748;
+  font-weight: 600;
+}
+
+.status-available {
+  color: #2f855a;
+  font-weight: 500;
+}
+
+.status-unavailable {
+  color: #c53030;
+  font-weight: 500;
+}
+
+.empty-chunks {
+  padding: 60px 20px;
+  text-align: center;
+}
+
+.empty-chunks .empty-icon {
+  font-size: 3rem;
+  margin-bottom: 16px;
+}
+
+.empty-chunks h3 {
+  margin: 0 0 8px 0;
+  color: #2d3748;
+  font-size: 1.25rem;
+  font-weight: 600;
+}
+
+.empty-chunks p {
+  margin: 0;
+  color: #718096;
+  font-size: 0.95rem;
+}
+
+.pagination-section {
+  margin-top: 20px;
+  text-align: center;
+  padding-top: 20px;
+  border-top: 1px solid #e2e8f0;
+}
+
+/* 响应式设计 */
+@media (max-width: 1200px) {
+  .main-layout {
+    flex-direction: column;
+  }
+
+  .sidebar {
+    width: 100%;
+    position: static;
+    max-height: none;
+    margin-bottom: 20px;
+  }
+
+  .sidebar-footer {
+    position: static;
+  }
+}
+
+@media (max-width: 768px) {
+  .app-title {
+    font-size: 1.75rem;
+  }
+
+  .header-content {
+    flex-direction: column;
+    gap: 16px;
+    text-align: center;
+  }
+
+  .header-stats {
+    gap: 32px;
+  }
+
+  .main-layout {
+    padding: 16px;
+  }
+
+  .content-section {
+    padding: 24px;
+  }
+
+  .content-header {
+    flex-direction: column;
+    gap: 16px;
+    align-items: stretch;
+  }
+
+  .chunk-btn {
+    width: 100%;
+  }
+
+  .sidebar-header {
+    flex-direction: column;
+    gap: 12px;
+    align-items: stretch;
+  }
+
+  .add-btn {
+    width: 100%;
+  }
+}
+
+@media (max-width: 480px) {
+  .app-title {
+    font-size: 1.5rem;
+  }
+
+  .content-section {
+    padding: 20px;
+  }
+
+  .sidebar {
+    width: 100%;
+  }
+}
+
+/* 侧边栏滚动条样式 */
+.sidebar::-webkit-scrollbar {
+  width: 6px;
+}
+
+.sidebar::-webkit-scrollbar-track {
+  background: #f1f1f1;
+  border-radius: 3px;
+}
+
+.sidebar::-webkit-scrollbar-thumb {
+  background: #c1c1c1;
+  border-radius: 3px;
+}
+
+.sidebar::-webkit-scrollbar-thumb:hover {
+  background: #a8a8a8;
+}
+
+.knowledge-list::-webkit-scrollbar {
+  width: 4px;
+}
+
+.knowledge-list::-webkit-scrollbar-track {
+  background: transparent;
+}
+
+.knowledge-list::-webkit-scrollbar-thumb {
+  background: #d1d1d1;
+  border-radius: 2px;
+}
+
+/* 删除确认按钮样式 */
+:deep(.delete-confirm-btn) {
+  background: #e53e3e;
+  border-color: #e53e3e;
+}
+
+:deep(.delete-confirm-btn:hover) {
+  background: #c53030;
+  border-color: #c53030;
+}
+
+:deep(.delete-cancel-btn) {
+  color: #718096;
+  border-color: #e2e8f0;
+}
+</style>

+ 1844 - 185
src/views/QAndA.vue

@@ -1,131 +1,551 @@
 <template>
-  <div class="container">
-    <!-- 左侧知识库列表 -->
-    <div class="knowledge-base">
-      <h3>选择知识库</h3>
-      <div
-          v-for="item in knowledgeBaseList"
-          :key="item.dataset_id"
-          :class="['knowledge-item', { 'active': selectedDatasetIds.includes(item.dataset_id) }]"
-          @click="toggleDatasetSelection(item.dataset_id)"
-      >
-        {{ item.name }}
+  <div class="app-container">
+    <!-- 顶部导航 -->
+    <div class="app-header">
+      <div class="header-content">
+        <div class="header-main">
+          <h1 class="app-title">智能知识库助手</h1>
+          <p style="color: rgba(255, 255, 255, 0.8);
+  font-size: 1rem;
+  margin: 8px 0 0 0;
+  font-weight: 500;">基于RAG技术的智能问答系统</p>
+        </div>
+        <div class="header-stats">
+          <div class="stat-item">
+            <span class="stat-number">{{ knowledgeBaseList.length }}</span>
+            <span class="stat-label">知识库</span>
+          </div>
+          <div class="stat-item">
+            <span class="stat-number">{{ selectedDatasetIds.length }}</span>
+            <span class="stat-label">已选择</span>
+          </div>
+        </div>
       </div>
     </div>
 
-    <!-- 右侧搜索框和搜索结果 -->
-    <div class="search-area">
-      <!-- 搜索框 + 提问按钮 -->
-      <div class="search-container">
-        <el-input
-            v-model="query"
-            placeholder="请输入提问内容"
-            suffix-icon="el-icon-search"
-            class="search-input"
-        ></el-input>
-        <!-- 当 loading 时禁用按钮 -->
-        <el-button
-            @click="chat"
-            type="primary"
-            :disabled="loading"
-            style="margin-left: 15px"
-        >
-          {{ "提问" }}
-        </el-button>
-      </div>
+    <div class="main-layout">
+      <!-- 左侧知识库侧边栏 -->
+      <div class="sidebar">
+        <div class="sidebar-header">
+          <div class="sidebar-title">
+            <h3>📚 知识库选择</h3>
+            <p class="sidebar-subtitle">选择要查询的知识库</p>
+          </div>
+          <!--          <el-button-->
+          <!--              class="refresh-btn"-->
+          <!--              size="small"-->
+          <!--              @click="getKnowledgeBaseList"-->
+          <!--              :loading="refreshing"-->
+          <!--          >-->
+          <!--            <span v-if="!refreshing">🔄</span>-->
+          <!--            <span v-else>...</span>-->
+          <!--          </el-button>-->
+        </div>
 
+        <div class="knowledge-list">
+          <div
+              v-for="item in knowledgeBaseList"
+              :key="item.dataset_id"
+              :class="['knowledge-card', { 'active': selectedDatasetIds.includes(item.dataset_id) }]"
+              @click="toggleDatasetSelection(item.dataset_id)"
+          >
+            <div class="card-content">
+              <div class="knowledge-icon">
+                <span v-if="selectedDatasetIds.includes(item.dataset_id)">✅</span>
+                <span v-else>📖</span>
+              </div>
+              <div class="knowledge-info">
+                <span class="knowledge-name">{{ item.name }}</span>
+                <span class="knowledge-desc" v-if="item.description">{{ item.description }}</span>
+                <span class="knowledge-status" :class="{ 'active': selectedDatasetIds.includes(item.dataset_id) }">
+                  {{ selectedDatasetIds.includes(item.dataset_id) ? '已选择' : '点击选择' }}
+                </span>
+              </div>
+            </div>
+          </div>
+        </div>
 
-      <!-- 搜索中的提示 -->
-      <div v-if="loading" class="loading-spinner">回答中...</div>
-      <!-- 展示 chat_res 数据 -->
-      <div v-if="chatSummary" class="chat-summary">
-        <h4>回答内容</h4>
-        <div v-html="parsedChatSummary"></div> <!-- 这里将解析后的内容渲染到页面 -->
+        <div class="sidebar-footer">
+          <div class="selected-count">
+            <span class="count-number">{{ selectedDatasetIds.length }}</span>
+            <span class="count-label">个知识库已选择</span>
+          </div>
+          <el-button
+              v-if="selectedDatasetIds.length > 0"
+              class="clear-btn"
+              size="small"
+              @click="clearSelection"
+          >
+            清空选择
+          </el-button>
+        </div>
       </div>
-      <div class="search-results">
-        <!-- 只有当 searchResults 不为空时才显示外层的卡片 -->
-        <el-card v-if="searchResults.length > 0" class="search-card">
-          <h4>搜索内容</h4> <!-- 新增标题 "搜索内容" -->
-
-          <!-- 现有的搜索结果卡片循环 -->
-          <div v-for="result in searchResults" :key="result.contentSummary">
-            <el-card
-                class="result-card"
-                @click="handleDetails(result)"
-            >
-              <h3>{{ result.contentSummary }}</h3>
-              <p>{{ result.content.substring(0, 100) }}...</p>
-              <div class="meta">
-                <span>相似度: {{ result.score.toFixed(2) }}</span>
-                <span>知识库: {{ result.datasetName }}</span>
+
+      <!-- 右侧主内容区 -->
+      <div class="content-area">
+        <!-- 搜索区域 -->
+        <div class="search-section">
+          <div class="search-card">
+            <div class="search-header">
+              <div class="search-title">
+                <h2>💬 开始提问</h2>
+                <p>输入您的问题,AI将基于选定的知识库为您解答</p>
+              </div>
+              <div class="search-tips">
+                <span class="tip-item">🔍 智能检索</span>
+                <span class="tip-item">🤖 AI分析</span>
+                <span class="tip-item">📚 多源参考</span>
+              </div>
+            </div>
+
+            <div class="search-input-group">
+              <div class="input-container">
+                <el-input
+                    v-model="query"
+                    placeholder="例如:请介绍一下机器学习的基本概念..."
+                    size="large"
+                    class="search-input"
+                    @keyup.enter="chat"
+                    :disabled="loading"
+                >
+                  <template #prefix>
+                    <span class="input-icon">💭</span>
+                  </template>
+                </el-input>
+                <div class="input-tips" v-if="selectedDatasetIds.length > 0">
+                  将在 {{ selectedDatasetIds.length }} 个知识库中搜索答案
+                </div>
+              </div>
+
+              <el-button
+                  @click="chat"
+                  type="primary"
+                  :disabled="loading || !query.trim() || selectedDatasetIds.length === 0"
+                  size="large"
+                  class="search-button"
+              >
+                <span v-if="loading" class="button-loading">
+                  <span class="loading-spinner"></span>
+                  思考中...
+                </span>
+                <span v-else class="button-content">
+                  <span class="button-icon">🚀</span>
+                  开始提问
+                </span>
+              </el-button>
+            </div>
+
+            <!-- 快速提问示例 -->
+            <!--            <div class="quick-questions" v-if="!loading">-->
+            <!--              <p class="quick-title">💡 试试这些问题:</p>-->
+            <!--              <div class="question-chips">-->
+            <!--                <el-tag-->
+            <!--                    v-for="question in quickQuestions"-->
+            <!--                    :key="question"-->
+            <!--                    class="question-chip"-->
+            <!--                    @click="query = question; chat()"-->
+            <!--                    :disabled="loading"-->
+            <!--                >-->
+            <!--                  {{ question }}-->
+            <!--                </el-tag>-->
+            <!--              </div>-->
+            <!--            </div>-->
+          </div>
+        </div>
+
+        <!-- 加载状态 -->
+        <div v-if="loading" class="loading-section">
+          <div class="loading-content">
+            <div class="loading-animation">
+              <div class="thinking-robot">🤖</div>
+              <div class="thinking-dots">
+                <span></span>
+                <span></span>
+                <span></span>
+              </div>
+            </div>
+            <p class="loading-text">AI正在分析您的问题,请稍候...</p>
+            <p class="loading-subtext">正在从 {{ selectedDatasetIds.length }} 个知识库中检索相关信息</p>
+          </div>
+        </div>
+
+        <!-- 最终回答 - 始终展开 -->
+        <div v-if="chatSummary && !loading" class="thinking-card answer-card">
+          <div class="card-header">
+            <div class="header-icon">💡</div>
+            <div class="header-content">
+              <h3>最终回答</h3>
+              <p>基于知识库内容生成的完整答案</p>
+            </div>
+            <div class="header-actions">
+              <el-tooltip content="复制回答" placement="top">
+                <el-button text class="action-btn" @click="copyToClipboard(chatSummary)">
+                  📋
+                </el-button>
+              </el-tooltip>
+            </div>
+          </div>
+          <div class="card-body">
+            <div v-html="parsedChatSummary" class="thinking-content"></div>
+          </div>
+        </div>
+
+        <!-- 思考过程展示 - 可折叠 -->
+        <div v-if="showThinkingProcess && !loading" class="thinking-section">
+          <!-- RAG 思考过程 - 可折叠 -->
+          <div v-if="ragSummary" class="collapsible-section">
+            <div class="collapsible-header" @click="toggleSection('rag')">
+              <div class="header-main">
+                <div class="header-icon">🔍</div>
+                <div class="header-content">
+                  <h3>检索增强分析</h3>
+                  <p>从知识库中检索相关信息并进行分析</p>
+                </div>
+              </div>
+              <div class="header-actions">
+                <div class="collapse-icon" :class="{ rotated: expandedSections.rag }">
+                  <span>▼</span>
+                </div>
+              </div>
+            </div>
+            <div v-show="expandedSections.rag" class="collapsible-content">
+              <div class="card-body">
+                <div v-html="parsedRagSummary" class="thinking-content"></div>
+              </div>
+            </div>
+          </div>
+
+          <!-- LLM 思考过程 - 可折叠 -->
+          <div v-if="llmSummary" class="collapsible-section">
+            <div class="collapsible-header" @click="toggleSection('llm')">
+              <div class="header-main">
+                <div class="header-icon">🤔</div>
+                <div class="header-content">
+                  <h3>智能推理</h3>
+                  <p>基于检索内容进行深度分析和推理</p>
+                </div>
+              </div>
+              <div class="header-actions">
+                <div class="collapse-icon" :class="{ rotated: expandedSections.llm }">
+                  <span>▼</span>
+                </div>
+              </div>
+            </div>
+            <div v-show="expandedSections.llm" class="collapsible-content">
+              <div class="card-body">
+                <div v-html="parsedLlmSummary" class="thinking-content"></div>
+              </div>
+            </div>
+          </div>
+        </div>
+
+        <!-- 搜索结果 - 可折叠 -->
+        <div v-if="searchResults.length > 0 && !loading" class="collapsible-section results-section">
+          <div class="collapsible-header" @click="toggleSection('results')">
+            <div class="header-main">
+              <div class="header-icon">📋</div>
+              <div class="header-content">
+                <h3>参考内容</h3>
+                <p>AI回答时参考的知识库内容 ({{ searchResults.length }} 条)</p>
+              </div>
+            </div>
+            <div class="header-actions">
+              <div class="collapse-icon" :class="{ rotated: expandedSections.results }">
+                <span>▼</span>
+              </div>
+            </div>
+          </div>
+          <div v-show="expandedSections.results" class="collapsible-content">
+            <div class="results-container">
+              <div class="results-stats">
+                <span class="stat">共找到 {{ searchResults.length }} 条相关内容</span>
+                <span class="stat">平均相关度: {{ averageScore }}%</span>
+              </div>
+              <div class="results-grid">
+                <div
+                    v-for="(result, index) in searchResults"
+                    :key="result.contentSummary + index"
+                    class="result-card"
+                    @click="handleDetails(result)"
+                >
+                  <div class="result-badge">#{{ index + 1 }}</div>
+                  <div class="result-header">
+                    <h4 class="result-title">{{ result.contentSummary }}</h4>
+                    <div class="result-meta">
+                      <span class="score-badge" :class="getScoreClass(result.score)">
+                        {{ (result.score * 100).toFixed(1) }}%
+                      </span>
+                      <span class="source-tag">{{ result.datasetName }}</span>
+                    </div>
+                  </div>
+                  <p class="result-preview">{{ result.content.substring(0, 150) }}...</p>
+                  <div class="result-footer">
+                    <span class="view-details">
+                      <span class="view-icon">🔍</span>
+                      查看详情
+                    </span>
+                  </div>
+                </div>
+              </div>
+            </div>
+          </div>
+        </div>
+
+        <!-- 空状态 -->
+        <div v-if="!loading && !showThinkingProcess && searchResults.length === 0 && hasSearched" class="empty-state">
+          <div class="empty-content">
+            <div class="empty-icon">🔍</div>
+            <h3>未找到相关内容</h3>
+            <p>请尝试调整问题关键词或选择其他知识库</p>
+            <el-button @click="query = ''" class="retry-btn">
+              重新提问
+            </el-button>
+          </div>
+        </div>
+
+        <!-- 初始状态 -->
+        <div v-if="!loading && !hasSearched" class="welcome-state">
+          <div class="welcome-content">
+            <div class="welcome-icon">🤖</div>
+            <h3>欢迎使用智能知识库助手</h3>
+            <p>选择左侧的知识库,输入您的问题,AI将为您提供精准的答案</p>
+            <div class="feature-list">
+              <div class="feature-item">
+                <span class="feature-icon">🔍</span>
+                <span>智能检索多个知识库</span>
+              </div>
+              <div class="feature-item">
+                <span class="feature-icon">🤔</span>
+                <span>展示AI思考过程</span>
               </div>
-            </el-card>
+              <div class="feature-item">
+                <span class="feature-icon">📚</span>
+                <span>提供参考来源</span>
+              </div>
+            </div>
           </div>
-        </el-card>
+        </div>
       </div>
     </div>
-  </div>
 
-  <!-- 弹窗:展示完整内容 -->
-  <el-dialog v-model="dialogVisible" width="80%">
-    <div>
-      <h3>{{ selectedResult.contentSummary }}</h3>
-      <p>{{ selectedResult.content }}</p>
-      <hr />
-      <div>
-        <h4>原文内容:</h4>
-        <p>{{ originalContent }}</p>
+    <!-- 美化后的弹窗 -->
+    <el-dialog
+        v-model="dialogVisible"
+        width="85%"
+        class="content-dialog"
+        :close-on-click-modal="false"
+    >
+      <template #header>
+        <div class="dialog-header">
+          <div class="dialog-title">
+            <div class="title-icon">📄</div>
+            <div class="title-content">
+              <h3>{{ selectedResult.contentSummary }}</h3>
+              <div class="title-meta">
+                <span class="meta-badge knowledge-badge">
+                  <span class="badge-icon">📚</span>
+                  {{ selectedResult.datasetName }}
+                </span>
+                <span class="meta-badge score-badge" :class="getScoreClass(selectedResult.score)">
+                  <span class="badge-icon">🎯</span>
+                  相关度: {{ (selectedResult.score * 100).toFixed(1) }}%
+                </span>
+              </div>
+            </div>
+          </div>
+        </div>
+      </template>
+
+      <div class="dialog-content">
+        <div class="content-tabs">
+          <div
+              class="tab-item"
+              :class="{ active: activeTab === 'summary' }"
+              @click="activeTab = 'summary'"
+          >
+            <span class="tab-icon">📝</span>
+            摘要内容
+          </div>
+          <div
+              class="tab-item"
+              :class="{ active: activeTab === 'original' }"
+              @click="activeTab = 'original'"
+          >
+            <span class="tab-icon">📖</span>
+            完整原文
+          </div>
+        </div>
+
+        <div class="tab-content">
+          <div v-show="activeTab === 'summary'" class="content-section summary-section">
+            <div class="section-header">
+              <h4>内容摘要</h4>
+              <el-button
+                  text
+                  class="copy-btn"
+                  @click="copyToClipboard(selectedResult.content)"
+              >
+                📋 复制内容
+              </el-button>
+            </div>
+            <div class="summary-content">
+              {{ selectedResult.content }}
+            </div>
+          </div>
+
+          <div v-show="activeTab === 'original'" class="content-section original-section">
+            <div class="section-header">
+              <h4>完整原文</h4>
+              <el-button
+                  text
+                  class="copy-btn"
+                  @click="copyToClipboard(originalContent)"
+              >
+                📋 复制原文
+              </el-button>
+            </div>
+            <div class="original-content">
+              <pre>{{ originalContent }}</pre>
+            </div>
+          </div>
+        </div>
       </div>
-    </div>
-    <template #footer>
-      <el-button @click="dialogVisible = false">关闭</el-button>
-    </template>
-  </el-dialog>
+
+      <template #footer>
+        <div class="dialog-footer">
+          <div class="footer-actions">
+            <el-button
+                class="action-btn secondary"
+                @click="dialogVisible = false"
+            >
+              取消
+            </el-button>
+            <el-button
+                type="primary"
+                class="action-btn primary"
+                @click="dialogVisible = false"
+            >
+              关闭
+            </el-button>
+          </div>
+        </div>
+      </template>
+    </el-dialog>
+  </div>
 </template>
 
 <script setup>
-import { ref, onMounted, computed } from 'vue';
-import { ElMessage } from 'element-plus';
-import { marked } from 'marked';
-import {API_BASE_URL} from "@/config";  // 使用命名导入
+import {ref, onMounted, computed} from 'vue';
+import {ElMessage, ElMessageBox} from 'element-plus';
+import {marked} from 'marked';
+import {API_BASE_URL} from "@/config";
 
-// 存储选择的知识库数据
+// 响应式数据
 const knowledgeBaseList = ref([]);
-const selectedDatasetIds = ref([11,12]);
-
-// 搜索框输入内容
+const selectedDatasetIds = ref([11, 12]);
 const query = ref('');
-
-// 存储搜索结果
 const searchResults = ref([]);
-
-// 存储chat_res总结
 const chatSummary = ref('');
-
-// 弹窗显示状态
+const ragSummary = ref('');
+const llmSummary = ref('');
 const dialogVisible = ref(false);
-
-// 存储选中的搜索结果
 const selectedResult = ref({});
-
-// 存储原文内容
 const originalContent = ref('');
-
-// 搜索加载状态
 const loading = ref(false);
+const refreshing = ref(false);
+const hasSearched = ref(false);
+const activeTab = ref('summary');
+
+// 可折叠区域的展开状态
+const expandedSections = ref({
+  rag: false,
+  llm: false,
+  results: false
+});
+
+// 快速提问示例
+const quickQuestions = ref([
+  "请总结一下主要概念",
+  "有哪些重要的注意事项?",
+  "请提供相关的示例说明",
+  "这个主题的核心要点是什么?"
+]);
+
+// 计算属性
+const showThinkingProcess = computed(() => {
+  return chatSummary.value || ragSummary.value || llmSummary.value;
+});
+
+const averageScore = computed(() => {
+  if (searchResults.value.length === 0) return 0;
+  const total = searchResults.value.reduce((sum, result) => sum + result.score, 0);
+  return (total / searchResults.value.length * 100).toFixed(1);
+});
+
+// 解析 Markdown 内容
+const parseMarkdown = (content) => {
+  if (!content) return '';
+  const markdownSymbols = /[#*+\-`>!]/;
+  const isMarkdown = markdownSymbols.test(content);
+  return isMarkdown ? marked(content) : content;
+};
+
+const parsedChatSummary = computed(() => parseMarkdown(chatSummary.value));
+const parsedRagSummary = computed(() => parseMarkdown(ragSummary.value));
+const parsedLlmSummary = computed(() => parseMarkdown(llmSummary.value));
+
+// 根据分数获取样式类
+const getScoreClass = (score) => {
+  if (score >= 0.8) return 'high';
+  if (score >= 0.6) return 'medium';
+  return 'low';
+};
 
-// 请求知识库列表
+// 复制到剪贴板
+const copyToClipboard = async (text) => {
+  try {
+    await navigator.clipboard.writeText(text);
+    ElMessage.success('已复制到剪贴板');
+  } catch (err) {
+    ElMessage.error('复制失败');
+  }
+};
+
+// 切换可折叠区域
+const toggleSection = (section) => {
+  expandedSections.value[section] = !expandedSections.value[section];
+};
+
+// 清空选择
+const clearSelection = async () => {
+  try {
+    await ElMessageBox.confirm('确定要清空所有选中的知识库吗?', '提示', {
+      confirmButtonText: '确定',
+      cancelButtonText: '取消',
+      type: 'warning'
+    });
+    selectedDatasetIds.value = [];
+    ElMessage.success('已清空选择');
+  } catch {
+    // 用户取消操作
+  }
+};
+
+// 方法
 const getKnowledgeBaseList = async () => {
+  refreshing.value = true;
   try {
     const response = await fetch(`${API_BASE_URL}/dataset/list`);
     const data = await response.json();
     knowledgeBaseList.value = data.data;
+    // ElMessage.success('知识库列表已更新');
   } catch (error) {
     ElMessage.error('获取知识库列表失败');
+  } finally {
+    refreshing.value = false;
   }
 };
 
-// 选择或取消选择知识库
 const toggleDatasetSelection = (datasetId) => {
   const index = selectedDatasetIds.value.indexOf(datasetId);
   if (index === -1) {
@@ -135,56 +555,59 @@ const toggleDatasetSelection = (datasetId) => {
   }
 };
 
-// 执行搜索操作
 const chat = async () => {
-  if (loading.value) return; // 防止重复调用
-  if (!query.value.trim()) {
-    ElMessage.warning('请输入提问内容');
-    return;
-  }
+  if (loading.value || !query.value.trim()) return;
 
   if (selectedDatasetIds.value.length === 0) {
     ElMessage.warning('请先选择知识库');
     return;
   }
 
+  // 重置状态
   chatSummary.value = '';
+  ragSummary.value = '';
+  llmSummary.value = '';
   searchResults.value = [];
-  selectedResult.value = {};
-  originalContent.value = '';
+  hasSearched.value = true;
+  // 重置展开状态
+  expandedSections.value = {
+    rag: false,
+    llm: false,
+    results: false
+  };
+  loading.value = true;
 
-  loading.value = true; // 开始搜索时显示加载提示
-  const datasetIds = selectedDatasetIds.value.join(',');
   try {
-    const response = await fetch(`${API_BASE_URL}/chat?query=${query.value}&datasetIds=${datasetIds}`);
+    const datasetIds = selectedDatasetIds.value.join(',');
+    const response = await fetch(`${API_BASE_URL}/chat?query=${encodeURIComponent(query.value)}&datasetIds=${datasetIds}`);
     const data = await response.json();
-    searchResults.value = data.data.results.map((item) => ({
-      ...item,
-    }));
 
-    // 获取并设置 chat_res
-    if (data.data.chat_res) {
-      chatSummary.value = data.data.chat_res;
+    if (data.data) {
+      searchResults.value = data.data.results || [];
+      chatSummary.value = data.data.chat_res || '';
+      ragSummary.value = data.data.rag_summary || '';
+      llmSummary.value = data.data.llm_summary || '';
+    } else {
+      ElMessage.error('未获取到有效数据');
     }
 
   } catch (error) {
-    ElMessage.error('搜索失败');
+    ElMessage.error('请求失败,请稍后重试');
   } finally {
-    loading.value = false; // 搜索结束后隐藏加载提示
+    loading.value = false;
   }
 };
 
-// 展示选中的搜索结果的完整内容
 const handleDetails = async (result) => {
   selectedResult.value = result;
-  dialogVisible.value = true; // 打开弹窗
+  dialogVisible.value = true;
+  activeTab.value = 'summary';
 
-  // 请求完整内容
   try {
     const response = await fetch(`${API_BASE_URL}/content/get?docId=${result.docId}`);
     const data = await response.json();
     if (data.status_code === 200) {
-      originalContent.value = data.data.text; // 显示原文内容
+      originalContent.value = data.data.text;
     } else {
       ElMessage.error('获取原文内容失败');
     }
@@ -193,119 +616,1355 @@ const handleDetails = async (result) => {
   }
 };
 
-// 计算属性:解析 chatSummary(如果是 Markdown 则解析)
-const parsedChatSummary = computed(() => {
-  if (chatSummary.value) {
-    // 分开检查 Markdown 格式的常见符号
-    const markdownSymbols = /[#*+\-`>!]/;  // 检测 Markdown 中常见的特殊字符
-    const isMarkdown = markdownSymbols.test(chatSummary.value);
-
-    // 如果检测到 Markdown 符号,解析为 Markdown 格式
-    if (isMarkdown) {
-      return marked(chatSummary.value);  // 使用 marked 库解析 Markdown
-    }
-  }
-  return chatSummary.value;  // 如果不是 Markdown 格式,直接返回文本
-});
-
-
-// 页面初始化加载知识库列表
+// 生命周期
 onMounted(() => {
   getKnowledgeBaseList();
 });
 </script>
 
 <style scoped>
-.container {
+/* 基础样式 */
+.app-container {
+  min-height: 100vh;
+  background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
+  font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
+}
+
+/* 顶部导航样式 */
+.app-header {
+  background: rgba(255, 255, 255, 0.1);
+  backdrop-filter: blur(20px);
+  padding: 16px 0;
+  border-bottom: 1px solid rgba(255, 255, 255, 0.1);
+}
+
+.header-content {
+  max-width: 1400px;
+  margin: 0 auto;
+  padding: 0 24px;
   display: flex;
   justify-content: space-between;
+  align-items: center;
+}
+
+.header-main {
+  flex: 1;
+}
+
+.app-title {
+  color: white;
+  font-size: 2.25rem;
+  font-weight: 800;
+  margin: 0;
+  text-shadow: 0 2px 10px rgba(0, 0, 0, 0.3);
+  background: linear-gradient(135deg, #fff 0%, #e2e8f0 100%);
+  -webkit-background-clip: text;
+  -webkit-text-fill-color: transparent;
+  background-clip: text;
+}
+
+.app-subtitle {
+  color: rgba(255, 255, 255, 0.8);
+  font-size: 1rem;
+  margin: 8px 0 0 0;
+  font-weight: 500;
+}
+
+.header-stats {
+  display: flex;
+  gap: 24px;
+}
+
+.stat-item {
+  display: flex;
+  flex-direction: column;
+  align-items: center;
+}
+
+.stat-number {
+  color: white;
+  font-size: 1.5rem;
+  font-weight: 700;
+}
+
+.stat-label {
+  color: rgba(255, 255, 255, 0.7);
+  font-size: 0.8rem;
+  margin-top: 4px;
+}
+
+/* 主布局 */
+.main-layout {
+  display: flex;
+  max-width: 1400px;
+  margin: 0 auto;
+  padding: 24px;
+  gap: 24px;
+  min-height: calc(100vh - 120px);
+  align-items: flex-start;
+}
+
+/* 侧边栏样式 - 固定位置 */
+.sidebar {
+  width: 320px;
+  flex-shrink: 0;
+  display: flex;
+  flex-direction: column;
+  position: sticky;
+  top: 24px;
+  max-height: calc(100vh - 120px);
+  overflow-y: auto;
+}
+
+.sidebar-header {
+  background: white;
   padding: 20px;
-  height: 100vh; /* 设置容器高度为视口高度 */
+  border-radius: 20px;
+  margin-bottom: 16px;
+  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.1);
+  display: flex;
+  justify-content: space-between;
+  align-items: flex-start;
+  flex-shrink: 0;
 }
 
-.knowledge-base {
-  width: 20%;
-  background-color: #f9f9f9;
-  padding: 15px;
-  border-radius: 8px;
-  height: 100%; /* 确保高度为100% */
-  overflow-y: auto; /* 启用垂直滚动 */
+.sidebar-title h3 {
+  margin: 0 0 6px 0;
+  color: #2d3748;
+  font-size: 1.25rem;
+  font-weight: 700;
+}
+
+.sidebar-subtitle {
+  margin: 0;
+  color: #718096;
+  font-size: 0.85rem;
+}
+
+.refresh-btn {
+  padding: 8px;
+  border-radius: 10px;
+  border: 1px solid #e2e8f0;
+  background: white;
+  transition: all 0.3s ease;
+}
+
+.refresh-btn:hover {
+  background: #f7fafc;
+  transform: rotate(90deg);
+}
+
+.knowledge-list {
+  flex: 1;
+  display: flex;
+  flex-direction: column;
+  gap: 12px;
+  overflow-y: auto;
+  min-height: 0;
 }
 
-.knowledge-item {
-  padding: 10px;
-  border-radius: 5px;
+.knowledge-card {
+  background: white;
+  border-radius: 16px;
   cursor: pointer;
-  margin: 5px 0;
-  transition: background-color 0.3s ease;
+  transition: all 0.3s ease;
+  border: 2px solid transparent;
+  box-shadow: 0 4px 16px rgba(0, 0, 0, 0.08);
+  overflow: hidden;
 }
 
-.knowledge-item:hover {
-  background-color: #e6f7ff;
+.knowledge-card:hover {
+  transform: translateY(-4px);
+  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.15);
 }
 
-.knowledge-item.active {
-  background-color: #b3d8ff;
+.knowledge-card.active {
+  border-color: #4299e1;
+  background: linear-gradient(135deg, #ebf8ff 0%, #ffffff 100%);
 }
 
-.search-area {
-  width: 75%;
-  background-color: #ffffff;
-  padding: 20px;
-  border-radius: 8px;
-  box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
-  height: 100%; /* 确保高度为100% */
-  overflow-y: auto; /* 启用垂直滚动 */
+.card-content {
+  padding: 16px;
+  display: flex;
+  align-items: flex-start;
+  gap: 12px;
 }
 
-.search-container {
+.knowledge-icon {
+  font-size: 1.25rem;
+  width: 40px;
+  height: 40px;
   display: flex;
+  align-items: center;
   justify-content: center;
+  background: #f7fafc;
+  border-radius: 10px;
+  flex-shrink: 0;
+}
+
+.knowledge-info {
+  flex: 1;
+  min-width: 0;
+}
+
+.knowledge-name {
+  display: block;
+  font-weight: 600;
+  color: #2d3748;
+  margin-bottom: 4px;
+  font-size: 0.95rem;
+  line-height: 1.4;
+}
+
+.knowledge-desc {
+  display: block;
+  color: #718096;
+  font-size: 0.8rem;
+  line-height: 1.4;
+  margin-bottom: 6px;
+}
+
+.knowledge-status {
+  font-size: 0.75rem;
+  color: #a0aec0;
+  font-weight: 500;
+}
+
+.knowledge-status.active {
+  color: #4299e1;
+  font-weight: 600;
+}
+
+.sidebar-footer {
+  background: white;
+  padding: 16px 20px;
+  border-radius: 16px;
+  margin-top: 16px;
+  box-shadow: 0 4px 16px rgba(0, 0, 0, 0.08);
+  display: flex;
+  justify-content: space-between;
   align-items: center;
-  margin-bottom: 20px;
+  flex-shrink: 0;
+  position: sticky;
+  bottom: 0;
+  z-index: 10;
 }
 
-.search-input {
-  width: 60%; /* 控制搜索框的宽度 */
+.selected-count {
+  display: flex;
+  align-items: center;
+  gap: 8px;
 }
 
-.result-card {
-  margin-top: 10px;
-  cursor: pointer;
+.count-number {
+  background: #4299e1;
+  color: white;
+  padding: 4px 10px;
+  border-radius: 12px;
+  font-size: 0.85rem;
+  font-weight: 700;
 }
 
-.result-card:hover {
-  background-color: #f5f5f5;
+.count-label {
+  color: #718096;
+  font-size: 0.85rem;
+}
+
+.clear-btn {
+  font-size: 0.8rem;
+  padding: 6px 12px;
+  border-radius: 8px;
+}
+
+/* 主内容区样式 */
+.content-area {
+  flex: 1;
+  display: flex;
+  flex-direction: column;
+  gap: 24px;
+  min-height: 0;
+}
+
+.search-section {
+  width: 100%;
 }
 
-.meta {
+.search-card {
+  background: white;
+  padding: 32px;
+  border-radius: 24px;
+  box-shadow: 0 12px 40px rgba(0, 0, 0, 0.12);
+}
+
+.search-header {
   display: flex;
   justify-content: space-between;
-  font-size: 12px;
-  color: #888;
+  align-items: flex-start;
+  margin-bottom: 28px;
+}
+
+.search-title h2 {
+  margin: 0 0 8px 0;
+  color: #2d3748;
+  font-size: 1.75rem;
+  font-weight: 700;
+}
+
+.search-title p {
+  margin: 0;
+  color: #718096;
+  font-size: 1rem;
+}
+
+.search-tips {
+  display: flex;
+  gap: 12px;
+}
+
+.tip-item {
+  background: #f7fafc;
+  padding: 6px 12px;
+  border-radius: 12px;
+  font-size: 0.8rem;
+  color: #718096;
+  border: 1px solid #e2e8f0;
+}
+
+/* 搜索框和按钮高度统一 */
+.search-input-group {
+  display: flex;
+  gap: 16px;
+  margin-bottom: 24px;
+  align-items: stretch;
+}
+
+.input-container {
+  flex: 1;
+  display: flex;
+  flex-direction: column;
+}
+
+.search-input {
+  border-radius: 16px;
+  height: 100%;
+}
+
+.search-input :deep(.el-input__wrapper) {
+  border-radius: 16px;
+  padding: 16px 20px;
+  box-shadow: 0 4px 16px rgba(0, 0, 0, 0.08);
+  border: 1px solid #e2e8f0;
+  transition: all 0.3s ease;
+  height: 56px;
+  display: flex;
+  align-items: center;
+}
+
+.search-input :deep(.el-input__wrapper:hover) {
+  border-color: #4299e1;
+  box-shadow: 0 4px 20px rgba(66, 153, 225, 0.15);
+}
+
+.search-input :deep(.el-input__wrapper.is-focus) {
+  border-color: #4299e1;
+  box-shadow: 0 4px 20px rgba(66, 153, 225, 0.2);
+}
+
+.input-icon {
+  font-size: 1.25rem;
+  margin-right: 8px;
+}
+
+.input-tips {
+  font-size: 0.8rem;
+  color: #718096;
+  margin-top: 8px;
+  text-align: center;
+}
+
+.search-button {
+  border-radius: 16px;
+  padding: 16px 32px;
+  font-weight: 600;
+  transition: all 0.3s ease;
+  min-width: 140px;
+  height: 56px;
+  display: flex;
+  align-items: center;
+  justify-content: center;
+}
+
+.search-button:not(:disabled):hover {
+  transform: translateY(-2px);
+  box-shadow: 0 8px 25px rgba(66, 153, 225, 0.4);
+}
+
+.button-loading {
+  display: flex;
+  align-items: center;
+  gap: 8px;
 }
 
 .loading-spinner {
+  width: 16px;
+  height: 16px;
+  border: 2px solid transparent;
+  border-top: 2px solid white;
+  border-radius: 50%;
+  animation: spin 1s linear infinite;
+}
+
+@keyframes spin {
+  0% {
+    transform: rotate(0deg);
+  }
+  100% {
+    transform: rotate(360deg);
+  }
+}
+
+.button-content {
+  display: flex;
+  align-items: center;
+  gap: 8px;
+}
+
+.button-icon {
+  font-size: 1.1rem;
+}
+
+.quick-questions {
+  border-top: 1px solid #e2e8f0;
+  padding-top: 20px;
+}
+
+.quick-title {
+  margin: 0 0 12px 0;
+  color: #718096;
+  font-size: 0.9rem;
+  font-weight: 600;
+}
+
+.question-chips {
+  display: flex;
+  flex-wrap: wrap;
+  gap: 8px;
+}
+
+.question-chip {
+  cursor: pointer;
+  border-radius: 20px;
+  padding: 8px 16px;
+  transition: all 0.3s ease;
+  border: 1px solid #e2e8f0;
+  background: white;
+  font-size: 0.85rem;
+}
+
+.question-chip:hover {
+  background: #4299e1;
+  color: white;
+  transform: translateY(-1px);
+  box-shadow: 0 4px 12px rgba(66, 153, 225, 0.3);
+}
+
+/* 加载状态 */
+.loading-section {
+  background: white;
+  border-radius: 24px;
+  padding: 60px 32px;
   text-align: center;
-  font-size: 16px;
-  color: #888;
-  margin-top: 20px;
+  box-shadow: 0 12px 40px rgba(0, 0, 0, 0.12);
 }
 
-.chat-summary {
-  background-color: #f0f8ff;
-  padding: 15px;
-  border-radius: 8px;
-  margin-bottom: 20px;
+.loading-content {
+  max-width: 400px;
+  margin: 0 auto;
 }
 
-.chat-summary h4 {
-  font-size: 18px;
-  font-weight: bold;
+.loading-animation {
+  margin-bottom: 24px;
 }
 
-.chat-summary p {
-  font-size: 14px;
-  line-height: 1.5;
+.thinking-robot {
+  font-size: 4rem;
+  margin-bottom: 16px;
+  animation: bounce 2s infinite;
+}
+
+@keyframes bounce {
+  0%, 20%, 50%, 80%, 100% {
+    transform: translateY(0);
+  }
+  40% {
+    transform: translateY(-10px);
+  }
+  60% {
+    transform: translateY(-5px);
+  }
+}
+
+.thinking-dots {
+  display: flex;
+  justify-content: center;
+  gap: 8px;
+  margin-bottom: 20px;
+}
+
+.thinking-dots span {
+  width: 12px;
+  height: 12px;
+  border-radius: 50%;
+  background: #4299e1;
+  animation: bounce 1.4s infinite ease-in-out;
+}
+
+.thinking-dots span:nth-child(1) {
+  animation-delay: -0.32s;
+}
+
+.thinking-dots span:nth-child(2) {
+  animation-delay: -0.16s;
+}
+
+.loading-text {
+  color: #2d3748;
+  font-size: 1.2rem;
+  font-weight: 600;
+  margin: 0 0 8px 0;
+}
+
+.loading-subtext {
+  color: #718096;
+  font-size: 0.95rem;
+  margin: 0;
+}
+
+/* 最终回答卡片 */
+.thinking-card.answer-card {
+  background: white;
+  border-radius: 20px;
+  overflow: hidden;
+  box-shadow: 0 12px 40px rgba(0, 0, 0, 0.12);
+  border-left: 6px solid #48bb78;
+}
+
+.answer-card .card-header {
+  display: flex;
+  align-items: center;
+  justify-content: space-between;
+  padding: 24px 28px;
+  background: linear-gradient(135deg, #f0fff4 0%, #ffffff 100%);
+  border-bottom: 1px solid #e2e8f0;
+}
+
+.answer-card .card-body {
+  padding: 0 28px 28px;
+}
+
+/* 可折叠区域样式 */
+.collapsible-section {
+  background: white;
+  border-radius: 20px;
+  overflow: hidden;
+  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.1);
+  margin-bottom: 16px;
+  transition: all 0.3s ease;
+}
+
+.collapsible-section:hover {
+  box-shadow: 0 12px 40px rgba(0, 0, 0, 0.15);
+}
+
+.collapsible-header {
+  display: flex;
+  align-items: center;
+  justify-content: space-between;
+  padding: 20px 28px;
+  cursor: pointer;
+  transition: background-color 0.3s ease;
+  border-bottom: 1px solid transparent;
+}
+
+.collapsible-header:hover {
+  background: rgba(0, 0, 0, 0.02);
+}
+
+.collapsible-section:has(.collapsible-content:not([style*="display: none"])) .collapsible-header {
+  border-bottom-color: #e2e8f0;
+}
+
+.header-main {
+  display: flex;
+  align-items: center;
+  gap: 16px;
+  flex: 1;
+}
+
+.header-actions {
+  display: flex;
+  align-items: center;
+  gap: 12px;
+}
+
+.action-btn {
+  padding: 8px;
+  border-radius: 10px;
+  transition: all 0.3s ease;
+}
+
+.action-btn:hover {
+  background: #f7fafc;
+}
+
+.collapse-icon {
+  transition: transform 0.3s ease;
+  color: #718096;
+  font-size: 14px;
+}
+
+.collapse-icon.rotated {
+  transform: rotate(180deg);
+}
+
+.collapsible-content {
+  padding: 0;
+}
+
+/* 为不同部分设置不同的左侧边框颜色 */
+.collapsible-section:nth-child(1) .collapsible-header {
+  border-left: 6px solid #4299e1;
+}
+
+.collapsible-section:nth-child(2) .collapsible-header {
+  border-left: 6px solid #9f7aea;
+}
+
+.collapsible-section:nth-child(3) .collapsible-header {
+  border-left: 6px solid #ed8936;
+}
+
+.header-icon {
+  font-size: 1.75rem;
+  width: 52px;
+  height: 52px;
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  background: white;
+  border-radius: 12px;
+  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
+}
+
+.header-content h3 {
+  margin: 0 0 6px 0;
+  color: #2d3748;
+  font-size: 1.3rem;
+  font-weight: 700;
+}
+
+.header-content p {
+  margin: 0;
+  color: #718096;
+  font-size: 0.9rem;
+}
+
+.card-body {
+  padding: 0 28px 28px;
+}
+
+.thinking-content {
+  line-height: 1.7;
+  color: #4a5568;
+  font-size: 1rem;
+}
+
+.thinking-content :deep(h1),
+.thinking-content :deep(h2),
+.thinking-content :deep(h3) {
+  color: #2d3748;
+  margin-top: 1.5em;
+  margin-bottom: 0.5em;
+}
+
+.thinking-content :deep(p) {
+  margin-bottom: 1em;
+}
+
+.thinking-content :deep(ul),
+.thinking-content :deep(ol) {
+  margin: 1em 0;
+  padding-left: 1.5em;
+}
+
+.thinking-content :deep(li) {
+  margin-bottom: 0.5em;
+}
+
+.thinking-content :deep(code) {
+  background: #f7fafc;
+  padding: 2px 6px;
+  border-radius: 4px;
+  font-family: 'Monaco', 'Consolas', monospace;
+  color: #e53e3e;
+  font-size: 0.9em;
+}
+
+.thinking-content :deep(pre) {
+  background: #2d3748;
+  color: #e2e8f0;
+  padding: 20px;
+  border-radius: 12px;
+  overflow-x: auto;
+  margin: 1.5em 0;
+  font-size: 0.9em;
+}
+
+.thinking-content :deep(blockquote) {
+  border-left: 4px solid #4299e1;
+  margin: 1.5em 0;
+  padding-left: 20px;
+  color: #718096;
+  font-style: italic;
+}
+
+/* 搜索结果样式 */
+.results-container {
+  padding: 0;
+}
+
+.results-stats {
+  padding: 20px 28px;
+  background: #f7fafc;
+  border-bottom: 1px solid #e2e8f0;
+  display: flex;
+  gap: 24px;
+}
+
+.results-stats .stat {
+  color: #718096;
+  font-size: 0.9rem;
+  font-weight: 500;
+}
+
+.results-grid {
+  padding: 24px 28px;
+  display: grid;
+  grid-template-columns: repeat(auto-fit, minmax(380px, 1fr));
+  gap: 20px;
+}
+
+.result-card {
+  background: white;
+  border-radius: 16px;
+  padding: 20px;
+  cursor: pointer;
+  transition: all 0.3s ease;
+  border: 1px solid #e2e8f0;
+  box-shadow: 0 4px 16px rgba(0, 0, 0, 0.06);
+  position: relative;
+  overflow: hidden;
+}
+
+.result-card:hover {
+  transform: translateY(-4px);
+  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.15);
+  border-color: #4299e1;
+}
+
+.result-badge {
+  position: absolute;
+  top: 12px;
+  right: 12px;
+  background: #4299e1;
+  color: white;
+  padding: 4px 10px;
+  border-radius: 12px;
+  font-size: 0.8rem;
+  font-weight: 700;
+}
+
+.result-header {
+  margin-bottom: 12px;
+}
+
+.result-title {
+  margin: 0 0 12px 0;
+  color: #2d3748;
+  font-size: 1.1rem;
+  font-weight: 600;
+  line-height: 1.4;
+}
+
+.result-meta {
+  display: flex;
+  gap: 8px;
+  align-items: center;
+}
+
+.score-badge {
+  padding: 4px 10px;
+  border-radius: 12px;
+  font-size: 0.8rem;
+  font-weight: 700;
+  color: white;
+}
+
+.score-badge.high {
+  background: #48bb78;
+}
+
+.score-badge.medium {
+  background: #ed8936;
+}
+
+.score-badge.low {
+  background: #e53e3e;
+}
+
+.source-tag {
+  background: #f7fafc;
+  padding: 4px 10px;
+  border-radius: 12px;
+  font-size: 0.8rem;
+  color: #718096;
+  border: 1px solid #e2e8f0;
+}
+
+.result-preview {
+  margin: 0 0 16px 0;
+  color: #718096;
+  line-height: 1.5;
+  font-size: 0.9rem;
+  display: -webkit-box;
+  -webkit-line-clamp: 3;
+  -webkit-box-orient: vertical;
+  overflow: hidden;
+}
+
+.result-footer {
+  display: flex;
+  justify-content: flex-end;
+}
+
+.view-details {
+  color: #4299e1;
+  font-weight: 600;
+  font-size: 0.9rem;
+  transition: color 0.3s ease;
+  display: flex;
+  align-items: center;
+  gap: 6px;
+}
+
+.view-icon {
+  font-size: 0.8rem;
+}
+
+.result-card:hover .view-details {
+  color: #2b6cb0;
+}
+
+/* 空状态 */
+.empty-state {
+  background: white;
+  border-radius: 24px;
+  padding: 80px 32px;
+  text-align: center;
+  box-shadow: 0 12px 40px rgba(0, 0, 0, 0.12);
+}
+
+.empty-content {
+  max-width: 400px;
+  margin: 0 auto;
+}
+
+.empty-icon {
+  font-size: 4rem;
+  margin-bottom: 20px;
+}
+
+.empty-state h3 {
+  margin: 0 0 12px 0;
+  color: #2d3748;
+  font-size: 1.5rem;
+  font-weight: 700;
+}
+
+.empty-state p {
+  margin: 0 0 24px 0;
+  color: #718096;
+  font-size: 1rem;
+  line-height: 1.5;
+}
+
+.retry-btn {
+  border-radius: 12px;
+  padding: 10px 24px;
+}
+
+/* 欢迎状态 */
+.welcome-state {
+  background: white;
+  border-radius: 24px;
+  padding: 80px 32px;
+  text-align: center;
+  box-shadow: 0 12px 40px rgba(0, 0, 0, 0.12);
+}
+
+.welcome-content {
+  max-width: 500px;
+  margin: 0 auto;
+}
+
+.welcome-icon {
+  font-size: 5rem;
+  margin-bottom: 24px;
+  animation: float 3s ease-in-out infinite;
+}
+
+@keyframes float {
+  0%, 100% {
+    transform: translateY(0px);
+  }
+  50% {
+    transform: translateY(-10px);
+  }
+}
+
+.welcome-state h3 {
+  margin: 0 0 16px 0;
+  color: #2d3748;
+  font-size: 1.75rem;
+  font-weight: 700;
+}
+
+.welcome-state p {
+  margin: 0 0 32px 0;
+  color: #718096;
+  font-size: 1.1rem;
+  line-height: 1.6;
+}
+
+.feature-list {
+  display: flex;
+  flex-direction: column;
+  gap: 12px;
+  max-width: 300px;
+  margin: 0 auto;
+}
+
+.feature-item {
+  display: flex;
+  align-items: center;
+  gap: 12px;
+  padding: 12px 16px;
+  background: #f7fafc;
+  border-radius: 12px;
+  color: #4a5568;
+  font-size: 0.95rem;
+}
+
+.feature-icon {
+  font-size: 1.2rem;
+}
+
+/* 弹窗样式 */
+.content-dialog :deep(.el-dialog) {
+  border-radius: 24px;
+  overflow: hidden;
+  box-shadow: 0 25px 50px rgba(0, 0, 0, 0.2);
+}
+
+.content-dialog :deep(.el-dialog__header) {
+  padding: 0;
+  margin: 0;
+}
+
+.content-dialog :deep(.el-dialog__headerbtn) {
+  top: 24px;
+  right: 24px;
+  width: 32px;
+  height: 32px;
+  border-radius: 8px;
+  background: #f7fafc;
+}
+
+.content-dialog :deep(.el-dialog__headerbtn:hover) {
+  background: #e2e8f0;
+}
+
+.dialog-header {
+  padding: 0;
+}
+
+.dialog-title {
+  display: flex;
+  align-items: flex-start;
+  gap: 16px;
+  padding: 32px 32px 0;
+}
+
+.title-icon {
+  font-size: 2.5rem;
+  width: 60px;
+  height: 60px;
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
+  border-radius: 16px;
+  color: white;
+  flex-shrink: 0;
+}
+
+.title-content {
+  flex: 1;
+  min-width: 0;
+}
+
+.title-content h3 {
+  margin: 0 0 12px 0;
+  color: #2d3748;
+  font-size: 1.5rem;
+  font-weight: 700;
+  line-height: 1.4;
+}
+
+.title-meta {
+  display: flex;
+  gap: 12px;
+  flex-wrap: wrap;
+}
+
+.meta-badge {
+  display: flex;
+  align-items: center;
+  gap: 6px;
+  padding: 6px 12px;
+  border-radius: 12px;
+  font-size: 0.85rem;
+  font-weight: 500;
+}
+
+.knowledge-badge {
+  background: #ebf8ff;
+  color: #2b6cb0;
+  border: 1px solid #bee3f8;
+}
+
+.score-badge.high {
+  background: #f0fff4;
+  color: #2f855a;
+  border: 1px solid #c6f6d5;
+}
+
+.score-badge.medium {
+  background: #fffaf0;
+  color: #c05621;
+  border: 1px solid #feebc8;
+}
+
+.score-badge.low {
+  background: #fff5f5;
+  color: #c53030;
+  border: 1px solid #fed7d7;
+}
+
+.badge-icon {
+  font-size: 0.8rem;
+}
+
+.dialog-content {
+  padding: 0;
+}
+
+.content-tabs {
+  display: flex;
+  padding: 0 32px;
+  border-bottom: 1px solid #e2e8f0;
+  margin-top: 24px;
+}
+
+.tab-item {
+  display: flex;
+  align-items: center;
+  gap: 8px;
+  padding: 12px 20px;
+  cursor: pointer;
+  border-bottom: 2px solid transparent;
+  color: #718096;
+  font-weight: 500;
+  transition: all 0.3s ease;
+}
+
+.tab-item:hover {
+  color: #4299e1;
+}
+
+.tab-item.active {
+  color: #4299e1;
+  border-bottom-color: #4299e1;
+}
+
+.tab-icon {
+  font-size: 1.1rem;
+}
+
+.tab-content {
+  padding: 0 32px 32px;
+}
+
+.content-section {
+  margin-top: 24px;
+}
+
+.section-header {
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+  margin-bottom: 16px;
+}
+
+.section-header h4 {
+  margin: 0;
+  color: #2d3748;
+  font-size: 1.2rem;
+  font-weight: 600;
+}
+
+.copy-btn {
+  font-size: 0.9rem;
+  padding: 6px 12px;
+  border-radius: 8px;
+}
+
+.summary-content {
+  background: #f7fafc;
+  padding: 20px;
+  border-radius: 12px;
+  color: #4a5568;
+  line-height: 1.6;
+  font-size: 0.95rem;
+  border: 1px solid #e2e8f0;
+}
+
+.original-content {
+  background: #f7fafc;
+  border-radius: 12px;
+  border: 1px solid #e2e8f0;
+  max-height: 500px;
+  overflow-y: auto;
+}
+
+.original-content pre {
+  margin: 0;
+  padding: 20px;
+  color: #4a5568;
+  line-height: 1.6;
+  font-size: 0.9rem;
+  white-space: pre-wrap;
+  word-wrap: break-word;
+}
+
+.dialog-footer {
+  padding: 0 32px 24px;
+}
+
+.footer-actions {
+  display: flex;
+  justify-content: flex-end;
+  gap: 12px;
+}
+
+.action-btn {
+  border-radius: 12px;
+  padding: 10px 24px;
+  font-weight: 500;
+  transition: all 0.3s ease;
+}
+
+.action-btn.secondary {
+  border: 1px solid #e2e8f0;
+  background: white;
+  color: #718096;
+}
+
+.action-btn.secondary:hover {
+  background: #f7fafc;
+  border-color: #cbd5e0;
+}
+
+.action-btn.primary {
+  background: #4299e1;
+  border: 1px solid #4299e1;
+  color: white;
+}
+
+.action-btn.primary:hover {
+  background: #3182ce;
+  border-color: #3182ce;
+  transform: translateY(-1px);
+  box-shadow: 0 4px 12px rgba(66, 153, 225, 0.3);
+}
+
+/* 响应式设计 */
+@media (max-width: 1200px) {
+  .main-layout {
+    flex-direction: column;
+  }
+
+  .sidebar {
+    width: 100%;
+    position: static;
+    max-height: none;
+    margin-bottom: 20px;
+  }
+
+  .sidebar-footer {
+    position: static;
+  }
+
+  .results-grid {
+    grid-template-columns: repeat(auto-fit, minmax(350px, 1fr));
+  }
+}
+
+@media (max-width: 768px) {
+  .app-title {
+    font-size: 1.75rem;
+  }
+
+  .header-content {
+    flex-direction: column;
+    gap: 16px;
+    text-align: center;
+  }
+
+  .header-stats {
+    gap: 32px;
+  }
+
+  .main-layout {
+    padding: 16px;
+  }
+
+  .search-card {
+    padding: 24px;
+  }
+
+  .search-header {
+    flex-direction: column;
+    gap: 16px;
+    text-align: center;
+  }
+
+  .search-tips {
+    justify-content: center;
+  }
+
+  .search-input-group {
+    flex-direction: column;
+  }
+
+  .search-button {
+    width: 100%;
+  }
+
+  .collapsible-header {
+    padding: 16px 20px;
+  }
+
+  .header-main {
+    gap: 12px;
+  }
+
+  .header-icon {
+    width: 44px;
+    height: 44px;
+    font-size: 1.5rem;
+  }
+
+  .results-grid {
+    grid-template-columns: 1fr;
+  }
+
+  .dialog-title {
+    flex-direction: column;
+    text-align: center;
+    gap: 12px;
+  }
+
+  .title-content h3 {
+    font-size: 1.3rem;
+  }
+
+  .content-tabs {
+    padding: 0 20px;
+  }
+
+  .tab-content {
+    padding: 0 20px 20px;
+  }
+}
+
+@media (max-width: 480px) {
+  .app-title {
+    font-size: 1.5rem;
+  }
+
+  .search-card {
+    padding: 20px;
+  }
+
+  .thinking-card .card-header,
+  .collapsible-header {
+    padding: 16px;
+  }
+
+  .card-body {
+    padding: 0 16px 16px;
+  }
+
+  .results-grid {
+    grid-template-columns: 1fr;
+  }
+
+  .content-dialog :deep(.el-dialog) {
+    width: 95% !important;
+    margin: 20px auto;
+  }
+}
+
+/* 侧边栏滚动条样式 */
+.sidebar::-webkit-scrollbar {
+  width: 6px;
+}
+
+.sidebar::-webkit-scrollbar-track {
+  background: #f1f1f1;
+  border-radius: 3px;
+}
+
+.sidebar::-webkit-scrollbar-thumb {
+  background: #c1c1c1;
+  border-radius: 3px;
+}
+
+.sidebar::-webkit-scrollbar-thumb:hover {
+  background: #a8a8a8;
+}
+
+.knowledge-list::-webkit-scrollbar {
+  width: 4px;
+}
+
+.knowledge-list::-webkit-scrollbar-track {
+  background: transparent;
+}
+
+.knowledge-list::-webkit-scrollbar-thumb {
+  background: #d1d1d1;
+  border-radius: 2px;
 }
-</style>
+</style>

+ 1367 - 127
src/views/SearchPage.vue

@@ -1,94 +1,367 @@
 <template>
-  <div class="container">
-    <!-- 左侧知识库列表 -->
-    <div class="knowledge-base">
-      <h3>选择知识库</h3>
-      <div
-          v-for="item in knowledgeBaseList"
-          :key="item.dataset_id"
-          :class="['knowledge-item', { 'active': selectedDatasetIds.includes(item.dataset_id) }]"
-          @click="toggleDatasetSelection(item.dataset_id)"
-      >
-        {{ item.name }}
+  <div class="app-container">
+    <!-- 顶部导航 -->
+    <div class="app-header">
+      <div class="header-content">
+        <div class="header-main">
+          <h1 class="app-title">智能知识库搜索</h1>
+          <p class="app-subtitle">基于RAG技术的智能搜索系统</p>
+        </div>
+        <div class="header-stats">
+          <div class="stat-item">
+            <span class="stat-number">{{ knowledgeBaseList.length }}</span>
+            <span class="stat-label">知识库</span>
+          </div>
+          <div class="stat-item">
+            <span class="stat-number">{{ selectedDatasetIds.length }}</span>
+            <span class="stat-label">已选择</span>
+          </div>
+        </div>
       </div>
     </div>
 
-    <!-- 右侧搜索框和搜索结果 -->
-    <div class="search-area">
-      <div class="search-container">
-        <el-input
-            v-model="query"
-            placeholder="请输入搜索内容"
-            suffix-icon="el-icon-search"
-            class="search-input"
-        ></el-input>
-        <el-button @click="search" type="primary" style="margin-left: 15px">搜索</el-button>
+    <div class="main-layout">
+      <!-- 左侧知识库侧边栏 -->
+      <div class="sidebar">
+        <div class="sidebar-header">
+          <h3>📚 知识库选择</h3>
+          <p class="sidebar-subtitle">选择要搜索的知识库</p>
+        </div>
+
+        <div class="knowledge-list">
+          <div
+              v-for="item in knowledgeBaseList"
+              :key="item.dataset_id"
+              :class="['knowledge-card', { 'active': selectedDatasetIds.includes(item.dataset_id) }]"
+              @click="toggleDatasetSelection(item.dataset_id)"
+          >
+            <div class="knowledge-icon">
+              <span v-if="selectedDatasetIds.includes(item.dataset_id)">✅</span>
+              <span v-else>📖</span>
+            </div>
+            <div class="knowledge-info">
+              <span class="knowledge-name">{{ item.name }}</span>
+              <span class="knowledge-status" :class="{ 'active': selectedDatasetIds.includes(item.dataset_id) }">
+                {{ selectedDatasetIds.includes(item.dataset_id) ? '已选择' : '点击选择' }}
+              </span>
+            </div>
+          </div>
+        </div>
+
+        <div class="selected-count">
+          已选择 {{ selectedDatasetIds.length }} 个知识库
+        </div>
       </div>
-      <!-- 搜索中的提示 -->
-      <div v-if="loading" class="loading-spinner">搜索中...</div>
-      <div class="search-results">
-        <el-card
-            v-for="result in searchResults"
-            :key="result.contentSummary"
-            class="result-card"
-            @click="handleDetails(result)"
-        >
-          <h3>{{ result.contentSummary }}</h3>
-          <p>{{ result.content.substring(0, 100) }}...</p>
-          <div class="meta">
-            <span>相似度: {{ result.score.toFixed(2) }}</span>
-            <span>知识库: {{ result.datasetName }}</span>
+
+      <!-- 右侧主内容区 -->
+      <div class="content-area">
+        <!-- 搜索区域 -->
+        <div class="search-section">
+          <div class="search-card">
+            <div class="search-header">
+              <h2>🔍 开始搜索</h2>
+              <p>输入您要搜索的内容,系统将在选定的知识库中查找相关信息</p>
+            </div>
+
+            <div class="search-input-group">
+              <div class="input-container">
+                <el-input
+                    v-model="query"
+                    placeholder="例如:机器学习的基本概念..."
+                    size="large"
+                    class="search-input"
+                    @keyup.enter="search"
+                    :disabled="loading"
+                >
+                  <template #prefix>
+                    <span class="input-icon">🔍</span>
+                  </template>
+                </el-input>
+                <div class="input-tips" v-if="selectedDatasetIds.length > 0">
+                  将在 {{ selectedDatasetIds.length }} 个知识库中搜索
+                </div>
+              </div>
+
+              <el-button
+                  @click="search"
+                  type="primary"
+                  :disabled="loading || !query.trim() || selectedDatasetIds.length === 0"
+                  size="large"
+                  class="search-button"
+              >
+                <span v-if="loading" class="button-loading">
+                  <span class="loading-spinner"></span>
+                  搜索中...
+                </span>
+                <span v-else class="button-content">
+                  <span class="button-icon">🚀</span>
+                  开始搜索
+                </span>
+              </el-button>
+            </div>
+
+            <!-- 快速搜索示例 -->
+<!--            <div class="quick-questions" v-if="!loading">-->
+<!--              <p class="quick-title">💡 试试搜索这些内容:</p>-->
+<!--              <div class="question-chips">-->
+<!--                <el-tag-->
+<!--                    v-for="question in quickQuestions"-->
+<!--                    :key="question"-->
+<!--                    class="question-chip"-->
+<!--                    @click="query = question; search()"-->
+<!--                    :disabled="loading"-->
+<!--                >-->
+<!--                  {{ question }}-->
+<!--                </el-tag>-->
+<!--              </div>-->
+<!--            </div>-->
+          </div>
+        </div>
+
+        <!-- 加载状态 -->
+        <div v-if="loading" class="loading-section">
+          <div class="loading-content">
+            <div class="loading-animation">
+              <div class="thinking-robot">🔍</div>
+              <div class="thinking-dots">
+                <span></span>
+                <span></span>
+                <span></span>
+              </div>
+            </div>
+            <p class="loading-text">正在搜索中,请稍候...</p>
+            <p class="loading-subtext">正在从 {{ selectedDatasetIds.length }} 个知识库中检索信息</p>
           </div>
-        </el-card>
+        </div>
+
+        <!-- 搜索结果 -->
+        <div v-if="searchResults.length > 0 && !loading" class="results-section">
+          <div class="section-header">
+            <h2>📋 搜索结果</h2>
+            <p>共找到 {{ searchResults.length }} 条相关内容</p>
+          </div>
+
+          <div class="results-grid">
+            <div
+                v-for="(result, index) in searchResults"
+                :key="result.contentSummary + index"
+                class="result-card"
+                @click="handleDetails(result)"
+            >
+              <div class="result-badge">#{{ index + 1 }}</div>
+              <div class="result-header">
+                <h4 class="result-title">{{ result.contentSummary }}</h4>
+                <div class="result-meta">
+                  <span class="score-badge" :class="getScoreClass(result.score)">
+                    {{ (result.score * 100).toFixed(1) }}%
+                  </span>
+                  <span class="source-tag">{{ result.datasetName }}</span>
+                </div>
+              </div>
+              <p class="result-preview">{{ result.content.substring(0, 150) }}...</p>
+              <div class="result-footer">
+                <span class="view-details">
+                  <span class="view-icon">📖</span>
+                  查看详情
+                </span>
+              </div>
+            </div>
+          </div>
+        </div>
+
+        <!-- 空状态 -->
+        <div v-if="!loading && searchResults.length === 0 && hasSearched" class="empty-state">
+          <div class="empty-content">
+            <div class="empty-icon">🔍</div>
+            <h3>未找到相关内容</h3>
+            <p>请尝试调整搜索关键词或选择其他知识库</p>
+            <el-button @click="query = ''" class="retry-btn">
+              重新搜索
+            </el-button>
+          </div>
+        </div>
+
+        <!-- 初始状态 -->
+        <div v-if="!loading && !hasSearched" class="welcome-state">
+          <div class="welcome-content">
+            <div class="welcome-icon">🔍</div>
+            <h3>欢迎使用智能知识库搜索</h3>
+            <p>选择左侧的知识库,输入您要搜索的内容,系统将为您查找相关信息</p>
+            <div class="feature-list">
+              <div class="feature-item">
+                <span class="feature-icon">📚</span>
+                <span>多知识库联合搜索</span>
+              </div>
+              <div class="feature-item">
+                <span class="feature-icon">🎯</span>
+                <span>智能相似度匹配</span>
+              </div>
+              <div class="feature-item">
+                <span class="feature-icon">📖</span>
+                <span>查看完整原文内容</span>
+              </div>
+            </div>
+          </div>
+        </div>
       </div>
     </div>
-  </div>
 
-  <!-- 弹窗:展示完整内容 -->
-  <el-dialog v-model="dialogVisible" width="80%">
-    <div>
-      <h3>{{ selectedResult.contentSummary }}</h3>
-      <p>{{ selectedResult.content }}</p>
-      <hr />
-      <div>
-        <h4>原文内容:</h4>
-        <p>{{ originalContent }}</p>
+    <!-- 美化后的弹窗 -->
+    <el-dialog
+        v-model="dialogVisible"
+        width="85%"
+        class="content-dialog"
+        :close-on-click-modal="false"
+    >
+      <template #header>
+        <div class="dialog-header">
+          <div class="dialog-title">
+            <div class="title-icon">📄</div>
+            <div class="title-content">
+              <h3>{{ selectedResult.contentSummary }}</h3>
+              <div class="title-meta">
+                <span class="meta-badge knowledge-badge">
+                  <span class="badge-icon">📚</span>
+                  {{ selectedResult.datasetName }}
+                </span>
+                <span class="meta-badge score-badge" :class="getScoreClass(selectedResult.score)">
+                  <span class="badge-icon">🎯</span>
+                  相关度: {{ (selectedResult.score * 100).toFixed(1) }}%
+                </span>
+              </div>
+            </div>
+          </div>
+        </div>
+      </template>
+
+      <div class="dialog-content">
+        <div class="content-tabs">
+          <div
+              class="tab-item"
+              :class="{ active: activeTab === 'summary' }"
+              @click="activeTab = 'summary'"
+          >
+            <span class="tab-icon">📝</span>
+            摘要内容
+          </div>
+          <div
+              class="tab-item"
+              :class="{ active: activeTab === 'original' }"
+              @click="activeTab = 'original'"
+          >
+            <span class="tab-icon">📖</span>
+            完整原文
+          </div>
+        </div>
+
+        <div class="tab-content">
+          <div v-show="activeTab === 'summary'" class="content-section summary-section">
+            <div class="section-header">
+              <h4>内容摘要</h4>
+              <el-button
+                  text
+                  class="copy-btn"
+                  @click="copyToClipboard(selectedResult.content)"
+              >
+                📋 复制内容
+              </el-button>
+            </div>
+            <div class="summary-content">
+              {{ selectedResult.content }}
+            </div>
+          </div>
+
+          <div v-show="activeTab === 'original'" class="content-section original-section">
+            <div class="section-header">
+              <h4>完整原文</h4>
+              <el-button
+                  text
+                  class="copy-btn"
+                  @click="copyToClipboard(originalContent)"
+              >
+                📋 复制原文
+              </el-button>
+            </div>
+            <div class="original-content">
+              <pre>{{ originalContent }}</pre>
+            </div>
+          </div>
+        </div>
       </div>
-    </div>
-    <template #footer>
-      <el-button @click="dialogVisible = false">关闭</el-button>
-    </template>
-  </el-dialog>
+
+      <template #footer>
+        <div class="dialog-footer">
+          <div class="footer-actions">
+            <el-button
+                class="action-btn secondary"
+                @click="dialogVisible = false"
+            >
+              取消
+            </el-button>
+            <el-button
+                type="primary"
+                class="action-btn primary"
+                @click="dialogVisible = false"
+            >
+              关闭
+            </el-button>
+          </div>
+        </div>
+      </template>
+    </el-dialog>
+  </div>
 </template>
 
 <script setup>
-import { ref, onMounted } from 'vue';
-import { ElMessage } from 'element-plus';
+import {ref, onMounted, computed} from 'vue';
+import {ElMessage} from 'element-plus';
 import {API_BASE_URL} from "@/config";
 
-// 存储选择的知识库数据
+// 响应式数据
 const knowledgeBaseList = ref([]);
 const selectedDatasetIds = ref([11,12]);
-
-// 搜索框输入内容
 const query = ref('');
-
-// 存储搜索结果
 const searchResults = ref([]);
-
-// 弹窗显示状态
 const dialogVisible = ref(false);
-
-// 存储选中的搜索结果
 const selectedResult = ref({});
-
-// 存储原文内容
 const originalContent = ref('');
-
-// 搜索加载状态
 const loading = ref(false);
+const hasSearched = ref(false);
+const activeTab = ref('summary');
+
+// 快速搜索示例
+const quickQuestions = ref([
+  "机器学习基本概念",
+  "深度学习应用场景",
+  "自然语言处理技术",
+  "人工智能发展历程"
+]);
+
+// 计算属性
+const averageScore = computed(() => {
+  if (searchResults.value.length === 0) return 0;
+  const total = searchResults.value.reduce((sum, result) => sum + result.score, 0);
+  return (total / searchResults.value.length * 100).toFixed(1);
+});
 
-// 请求知识库列表
+// 根据分数获取样式类
+const getScoreClass = (score) => {
+  if (score >= 0.8) return 'high';
+  if (score >= 0.6) return 'medium';
+  return 'low';
+};
+
+// 复制到剪贴板
+const copyToClipboard = async (text) => {
+  try {
+    await navigator.clipboard.writeText(text);
+    ElMessage.success('已复制到剪贴板');
+  } catch (err) {
+    ElMessage.error('复制失败');
+  }
+};
+
+// 方法
 const getKnowledgeBaseList = async () => {
   try {
     const response = await fetch(`${API_BASE_URL}/dataset/list`);
@@ -99,7 +372,6 @@ const getKnowledgeBaseList = async () => {
   }
 };
 
-// 选择或取消选择知识库
 const toggleDatasetSelection = (datasetId) => {
   const index = selectedDatasetIds.value.indexOf(datasetId);
   if (index === -1) {
@@ -109,45 +381,47 @@ const toggleDatasetSelection = (datasetId) => {
   }
 };
 
-// 执行搜索操作
 const search = async () => {
-  if (!query.value.trim()) {
-    ElMessage.warning('请输入搜索内容');
-    return;
-  }
+  if (loading.value || !query.value.trim()) return;
 
   if (selectedDatasetIds.value.length === 0) {
     ElMessage.warning('请先选择知识库');
     return;
   }
 
-  loading.value = true; // 开始搜索时显示加载提示
-  const datasetIds = selectedDatasetIds.value.join(',');
+  // 重置状态
+  searchResults.value = [];
+  hasSearched.value = true;
+  loading.value = true;
+
   try {
-    const response = await fetch(`${API_BASE_URL}/query?query=${query.value}&datasetIds=${datasetIds}`);
+    const datasetIds = selectedDatasetIds.value.join(',');
+    const response = await fetch(`${API_BASE_URL}/query?query=${encodeURIComponent(query.value)}&datasetIds=${datasetIds}`);
     const data = await response.json();
-    searchResults.value = data.data.results.map((item) => ({
-      ...item,
-      // 这里只是简化了展示,可以将 datasetName 从返回结果中提取
-    }));
+
+    if (data.data) {
+      searchResults.value = data.data.results || [];
+    } else {
+      ElMessage.error('未获取到有效数据');
+    }
+
   } catch (error) {
-    ElMessage.error('搜索失败');
+    ElMessage.error('搜索失败,请稍后重试');
   } finally {
-    loading.value = false; // 搜索结束后隐藏加载提示
+    loading.value = false;
   }
 };
 
-// 展示选中的搜索结果的完整内容
 const handleDetails = async (result) => {
   selectedResult.value = result;
-  dialogVisible.value = true; // 打开弹窗
+  dialogVisible.value = true;
+  activeTab.value = 'summary';
 
-  // 请求完整内容
   try {
     const response = await fetch(`${API_BASE_URL}/content/get?docId=${result.docId}`);
     const data = await response.json();
     if (data.status_code === 200) {
-      originalContent.value = data.data.text; // 显示原文内容
+      originalContent.value = data.data.text;
     } else {
       ElMessage.error('获取原文内容失败');
     }
@@ -156,87 +430,1053 @@ const handleDetails = async (result) => {
   }
 };
 
-// 页面初始化加载知识库列表
+// 生命周期
 onMounted(() => {
   getKnowledgeBaseList();
 });
 </script>
 
 <style scoped>
-.container {
+/* 基础样式 */
+.app-container {
+  min-height: 100vh;
+  background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
+  font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
+}
+
+/* 顶部导航样式 */
+.app-header {
+  background: rgba(255, 255, 255, 0.1);
+  backdrop-filter: blur(20px);
+  padding: 16px 0;
+  border-bottom: 1px solid rgba(255, 255, 255, 0.1);
+}
+
+.header-content {
+  max-width: 1400px;
+  margin: 0 auto;
+  padding: 0 24px;
   display: flex;
   justify-content: space-between;
+  align-items: center;
+}
+
+.header-main {
+  display: flex;
+  align-items: center;
+  gap: 16px;
+  flex: 1;
+}
+
+.app-title {
+  color: white;
+  font-size: 2.25rem;
+  font-weight: 800;
+  margin: 0;
+  text-shadow: 0 2px 10px rgba(0, 0, 0, 0.3);
+  background: linear-gradient(135deg, #fff 0%, #e2e8f0 100%);
+  -webkit-background-clip: text;
+  -webkit-text-fill-color: transparent;
+  background-clip: text;
+}
+
+.app-subtitle {
+  color: rgba(255, 255, 255, 0.8);
+  font-size: 1.1rem;
+  margin: 8px 0 0 0;
+}
+
+.header-stats {
+  display: flex;
+  gap: 24px;
+}
+
+.stat-item {
+  display: flex;
+  flex-direction: column;
+  align-items: center;
+}
+
+.stat-number {
+  color: white;
+  font-size: 1.5rem;
+  font-weight: 700;
+}
+
+.stat-label {
+  color: rgba(255, 255, 255, 0.7);
+  font-size: 0.8rem;
+  margin-top: 4px;
+}
+
+/* 主布局 */
+.main-layout {
+  display: flex;
+  max-width: 1400px;
+  margin: 0 auto;
+  padding: 24px;
+  gap: 24px;
+  min-height: calc(100vh - 120px);
+  align-items: flex-start;
+}
+
+/* 侧边栏样式 - 固定位置 */
+.sidebar {
+  width: 320px;
+  flex-shrink: 0;
+  display: flex;
+  flex-direction: column;
+  position: sticky;
+  top: 24px;
+  max-height: calc(100vh - 120px);
+  overflow-y: auto;
+}
+
+.sidebar-header {
+  background: white;
   padding: 20px;
-  height: 100vh; /* 设置容器高度为视口高度 */
+  border-radius: 20px;
+  margin-bottom: 16px;
+  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.1);
 }
 
-.knowledge-base {
-  width: 20%;
-  background-color: #f9f9f9;
-  padding: 15px;
-  border-radius: 8px;
-  height: 100%; /* 确保高度为100% */
-  overflow-y: auto; /* 启用垂直滚动 */
+.sidebar-header h3 {
+  margin: 0 0 8px 0;
+  color: #2d3748;
+  font-size: 1.25rem;
+  font-weight: 700;
 }
 
-.knowledge-item {
-  padding: 10px;
-  border-radius: 5px;
+.sidebar-subtitle {
+  margin: 0;
+  color: #718096;
+  font-size: 0.9rem;
+}
+
+.knowledge-list {
+  flex: 1;
+  display: flex;
+  flex-direction: column;
+  gap: 12px;
+  overflow-y: auto;
+  min-height: 0;
+}
+
+.knowledge-card {
+  background: white;
+  padding: 16px;
+  border-radius: 16px;
   cursor: pointer;
-  margin: 5px 0;
-  transition: background-color 0.3s ease;
+  transition: all 0.3s ease;
+  border: 2px solid transparent;
+  display: flex;
+  align-items: center;
+  gap: 12px;
+  box-shadow: 0 4px 16px rgba(0, 0, 0, 0.08);
 }
 
-.knowledge-item:hover {
-  background-color: #e6f7ff;
+.knowledge-card:hover {
+  transform: translateY(-2px);
+  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.15);
 }
 
-.knowledge-item.active {
-  background-color: #b3d8ff;
+.knowledge-card.active {
+  border-color: #4299e1;
+  background: linear-gradient(135deg, #ebf8ff 0%, #fff5f5 100%);
 }
 
-.search-area {
-  width: 75%;
-  background-color: #ffffff;
-  padding: 20px;
-  border-radius: 8px;
-  box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
-  height: 100%; /* 确保高度为100% */
-  overflow-y: auto; /* 启用垂直滚动 */
+.knowledge-icon {
+  font-size: 1.5rem;
+  width: 40px;
+  height: 40px;
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  background: #f7fafc;
+  border-radius: 10px;
+  flex-shrink: 0;
+}
+
+.knowledge-info {
+  flex: 1;
+}
+
+.knowledge-name {
+  display: block;
+  font-weight: 600;
+  color: #2d3748;
+  margin-bottom: 4px;
+  font-size: 0.95rem;
+}
+
+.knowledge-status {
+  font-size: 0.8rem;
+  color: #a0aec0;
+}
+
+.knowledge-status.active {
+  color: #4299e1;
+  font-weight: 600;
 }
 
-.search-container {
+.selected-count {
+  background: white;
+  padding: 16px;
+  border-radius: 16px;
+  text-align: center;
+  color: #4299e1;
+  font-weight: 600;
+  margin-top: 16px;
+  box-shadow: 0 4px 16px rgba(0, 0, 0, 0.08);
+}
+
+/* 主内容区样式 */
+.content-area {
+  flex: 1;
+  display: flex;
+  flex-direction: column;
+  gap: 24px;
+  min-height: 0;
+}
+
+.search-section {
+  width: 100%;
+}
+
+.search-card {
+  background: white;
+  padding: 32px;
+  border-radius: 24px;
+  box-shadow: 0 12px 40px rgba(0, 0, 0, 0.12);
+}
+
+.search-header {
+  text-align: center;
+  margin-bottom: 28px;
+}
+
+.search-header h2 {
+  margin: 0 0 8px 0;
+  color: #2d3748;
+  font-size: 1.75rem;
+  font-weight: 700;
+}
+
+.search-header p {
+  margin: 0;
+  color: #718096;
+  font-size: 1rem;
+}
+
+/* 搜索框和按钮高度统一 */
+.search-input-group {
+  display: flex;
+  gap: 16px;
+  margin-bottom: 24px;
+  align-items: stretch;
+}
+
+.input-container {
+  flex: 1;
+  display: flex;
+  flex-direction: column;
+}
+
+.search-input {
+  border-radius: 16px;
+  height: 100%;
+}
+
+.search-input :deep(.el-input__wrapper) {
+  border-radius: 16px;
+  padding: 16px 20px;
+  box-shadow: 0 4px 16px rgba(0, 0, 0, 0.08);
+  border: 1px solid #e2e8f0;
+  transition: all 0.3s ease;
+  height: 56px;
+  display: flex;
+  align-items: center;
+}
+
+.search-input :deep(.el-input__wrapper:hover) {
+  border-color: #4299e1;
+  box-shadow: 0 4px 20px rgba(66, 153, 225, 0.15);
+}
+
+.search-input :deep(.el-input__wrapper.is-focus) {
+  border-color: #4299e1;
+  box-shadow: 0 4px 20px rgba(66, 153, 225, 0.2);
+}
+
+.input-icon {
+  font-size: 1.25rem;
+  margin-right: 8px;
+}
+
+.input-tips {
+  font-size: 0.8rem;
+  color: #718096;
+  margin-top: 8px;
+  text-align: center;
+}
+
+.search-button {
+  border-radius: 16px;
+  padding: 16px 32px;
+  font-weight: 600;
+  transition: all 0.3s ease;
+  min-width: 140px;
+  height: 56px;
   display: flex;
+  align-items: center;
   justify-content: center;
+}
+
+.search-button:not(:disabled):hover {
+  transform: translateY(-2px);
+  box-shadow: 0 8px 25px rgba(66, 153, 225, 0.4);
+}
+
+.button-loading {
+  display: flex;
   align-items: center;
+  gap: 8px;
+}
+
+.loading-spinner {
+  width: 16px;
+  height: 16px;
+  border: 2px solid transparent;
+  border-top: 2px solid white;
+  border-radius: 50%;
+  animation: spin 1s linear infinite;
+}
+
+@keyframes spin {
+  0% {
+    transform: rotate(0deg);
+  }
+  100% {
+    transform: rotate(360deg);
+  }
+}
+
+.button-content {
+  display: flex;
+  align-items: center;
+  gap: 8px;
+}
+
+.button-icon {
+  font-size: 1.1rem;
+}
+
+.quick-questions {
+  border-top: 1px solid #e2e8f0;
+  padding-top: 20px;
+}
+
+.quick-title {
+  margin: 0 0 12px 0;
+  color: #718096;
+  font-size: 0.9rem;
+  font-weight: 600;
+}
+
+.question-chips {
+  display: flex;
+  flex-wrap: wrap;
+  gap: 8px;
+}
+
+.question-chip {
+  cursor: pointer;
+  border-radius: 20px;
+  padding: 8px 16px;
+  transition: all 0.3s ease;
+  border: 1px solid #e2e8f0;
+  background: white;
+  font-size: 0.85rem;
+}
+
+.question-chip:hover {
+  background: #4299e1;
+  color: white;
+  transform: translateY(-1px);
+  box-shadow: 0 4px 12px rgba(66, 153, 225, 0.3);
+}
+
+/* 加载状态 */
+.loading-section {
+  background: white;
+  border-radius: 24px;
+  padding: 60px 32px;
+  text-align: center;
+  box-shadow: 0 12px 40px rgba(0, 0, 0, 0.12);
+}
+
+.loading-content {
+  max-width: 400px;
+  margin: 0 auto;
+}
+
+.loading-animation {
+  margin-bottom: 24px;
+}
+
+.thinking-robot {
+  font-size: 4rem;
+  margin-bottom: 16px;
+  animation: bounce 2s infinite;
+}
+
+@keyframes bounce {
+  0%, 20%, 50%, 80%, 100% {
+    transform: translateY(0);
+  }
+  40% {
+    transform: translateY(-10px);
+  }
+  60% {
+    transform: translateY(-5px);
+  }
+}
+
+.thinking-dots {
+  display: flex;
+  justify-content: center;
+  gap: 8px;
   margin-bottom: 20px;
 }
 
-.search-input {
-  width: 60%; /* 控制搜索框的宽度 */
+.thinking-dots span {
+  width: 12px;
+  height: 12px;
+  border-radius: 50%;
+  background: #4299e1;
+  animation: bounce 1.4s infinite ease-in-out;
+}
+
+.thinking-dots span:nth-child(1) {
+  animation-delay: -0.32s;
+}
+
+.thinking-dots span:nth-child(2) {
+  animation-delay: -0.16s;
+}
+
+.loading-text {
+  color: #2d3748;
+  font-size: 1.2rem;
+  font-weight: 600;
+  margin: 0 0 8px 0;
+}
+
+.loading-subtext {
+  color: #718096;
+  font-size: 0.95rem;
+  margin: 0;
+}
+
+/* 搜索结果样式 */
+.results-section {
+  background: white;
+  border-radius: 24px;
+  padding: 32px;
+  box-shadow: 0 12px 40px rgba(0, 0, 0, 0.12);
+}
+
+.section-header {
+  margin-bottom: 24px;
+}
+
+.section-header h2 {
+  margin: 0 0 8px 0;
+  color: #2d3748;
+  font-size: 1.5rem;
+  font-weight: 700;
+}
+
+.section-header p {
+  margin: 0;
+  color: #718096;
+  font-size: 0.95rem;
+}
+
+.results-grid {
+  display: grid;
+  grid-template-columns: repeat(auto-fit, minmax(380px, 1fr));
+  gap: 20px;
 }
 
 .result-card {
-  margin-top: 10px;
+  background: white;
+  border-radius: 16px;
+  padding: 20px;
   cursor: pointer;
+  transition: all 0.3s ease;
+  border: 1px solid #e2e8f0;
+  box-shadow: 0 4px 16px rgba(0, 0, 0, 0.06);
+  position: relative;
+  overflow: hidden;
 }
 
 .result-card:hover {
-  background-color: #f5f5f5;
+  transform: translateY(-4px);
+  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.15);
+  border-color: #4299e1;
+}
+
+.result-badge {
+  position: absolute;
+  top: 12px;
+  right: 12px;
+  background: #4299e1;
+  color: white;
+  padding: 4px 10px;
+  border-radius: 12px;
+  font-size: 0.8rem;
+  font-weight: 700;
+}
+
+.result-header {
+  margin-bottom: 12px;
+}
+
+.result-title {
+  margin: 0 0 12px 0;
+  color: #2d3748;
+  font-size: 1.1rem;
+  font-weight: 600;
+  line-height: 1.4;
 }
 
-.meta {
+.result-meta {
   display: flex;
-  justify-content: space-between;
-  font-size: 12px;
-  color: #888;
+  gap: 8px;
+  align-items: center;
 }
 
-.loading-spinner {
+.score-badge {
+  padding: 4px 10px;
+  border-radius: 12px;
+  font-size: 0.8rem;
+  font-weight: 700;
+  color: white;
+}
+
+.score-badge.high {
+  background: #48bb78;
+}
+
+.score-badge.medium {
+  background: #ed8936;
+}
+
+.score-badge.low {
+  background: #e53e3e;
+}
+
+.source-tag {
+  background: #f7fafc;
+  padding: 4px 10px;
+  border-radius: 12px;
+  font-size: 0.8rem;
+  color: #718096;
+  border: 1px solid #e2e8f0;
+}
+
+.result-preview {
+  margin: 0 0 16px 0;
+  color: #718096;
+  line-height: 1.5;
+  font-size: 0.9rem;
+  display: -webkit-box;
+  -webkit-line-clamp: 3;
+  -webkit-box-orient: vertical;
+  overflow: hidden;
+}
+
+.result-footer {
+  display: flex;
+  justify-content: flex-end;
+}
+
+.view-details {
+  color: #4299e1;
+  font-weight: 600;
+  font-size: 0.9rem;
+  transition: color 0.3s ease;
+  display: flex;
+  align-items: center;
+  gap: 6px;
+}
+
+.view-icon {
+  font-size: 0.8rem;
+}
+
+.result-card:hover .view-details {
+  color: #2b6cb0;
+}
+
+/* 空状态 */
+.empty-state {
+  background: white;
+  border-radius: 24px;
+  padding: 80px 32px;
   text-align: center;
-  font-size: 16px;
-  color: #888;
-  margin-top: 20px;
+  box-shadow: 0 12px 40px rgba(0, 0, 0, 0.12);
+}
+
+.empty-content {
+  max-width: 400px;
+  margin: 0 auto;
+}
+
+.empty-icon {
+  font-size: 4rem;
+  margin-bottom: 20px;
 }
 
-</style>
+.empty-state h3 {
+  margin: 0 0 12px 0;
+  color: #2d3748;
+  font-size: 1.5rem;
+  font-weight: 700;
+}
+
+.empty-state p {
+  margin: 0 0 24px 0;
+  color: #718096;
+  font-size: 1rem;
+  line-height: 1.5;
+}
+
+.retry-btn {
+  border-radius: 12px;
+  padding: 10px 24px;
+}
+
+/* 欢迎状态 */
+.welcome-state {
+  background: white;
+  border-radius: 24px;
+  padding: 80px 32px;
+  text-align: center;
+  box-shadow: 0 12px 40px rgba(0, 0, 0, 0.12);
+}
+
+.welcome-content {
+  max-width: 500px;
+  margin: 0 auto;
+}
+
+.welcome-icon {
+  font-size: 5rem;
+  margin-bottom: 24px;
+  animation: float 3s ease-in-out infinite;
+}
+
+@keyframes float {
+  0%, 100% {
+    transform: translateY(0px);
+  }
+  50% {
+    transform: translateY(-10px);
+  }
+}
+
+.welcome-state h3 {
+  margin: 0 0 16px 0;
+  color: #2d3748;
+  font-size: 1.75rem;
+  font-weight: 700;
+}
+
+.welcome-state p {
+  margin: 0 0 32px 0;
+  color: #718096;
+  font-size: 1.1rem;
+  line-height: 1.6;
+}
+
+.feature-list {
+  display: flex;
+  flex-direction: column;
+  gap: 12px;
+  max-width: 300px;
+  margin: 0 auto;
+}
+
+.feature-item {
+  display: flex;
+  align-items: center;
+  gap: 12px;
+  padding: 12px 16px;
+  background: #f7fafc;
+  border-radius: 12px;
+  color: #4a5568;
+  font-size: 0.95rem;
+}
+
+.feature-icon {
+  font-size: 1.2rem;
+}
+
+/* 弹窗样式 */
+.content-dialog :deep(.el-dialog) {
+  border-radius: 24px;
+  overflow: hidden;
+  box-shadow: 0 25px 50px rgba(0, 0, 0, 0.2);
+}
+
+.content-dialog :deep(.el-dialog__header) {
+  padding: 0;
+  margin: 0;
+}
+
+.content-dialog :deep(.el-dialog__headerbtn) {
+  top: 24px;
+  right: 24px;
+  width: 32px;
+  height: 32px;
+  border-radius: 8px;
+  background: #f7fafc;
+}
+
+.content-dialog :deep(.el-dialog__headerbtn:hover) {
+  background: #e2e8f0;
+}
+
+.dialog-header {
+  padding: 0;
+}
+
+.dialog-title {
+  display: flex;
+  align-items: flex-start;
+  gap: 16px;
+  padding: 32px 32px 0;
+}
+
+.title-icon {
+  font-size: 2.5rem;
+  width: 60px;
+  height: 60px;
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
+  border-radius: 16px;
+  color: white;
+  flex-shrink: 0;
+}
+
+.title-content {
+  flex: 1;
+  min-width: 0;
+}
+
+.title-content h3 {
+  margin: 0 0 12px 0;
+  color: #2d3748;
+  font-size: 1.5rem;
+  font-weight: 700;
+  line-height: 1.4;
+}
+
+.title-meta {
+  display: flex;
+  gap: 12px;
+  flex-wrap: wrap;
+}
+
+.meta-badge {
+  display: flex;
+  align-items: center;
+  gap: 6px;
+  padding: 6px 12px;
+  border-radius: 12px;
+  font-size: 0.85rem;
+  font-weight: 500;
+}
+
+.knowledge-badge {
+  background: #ebf8ff;
+  color: #2b6cb0;
+  border: 1px solid #bee3f8;
+}
+
+.score-badge.high {
+  background: #f0fff4;
+  color: #2f855a;
+  border: 1px solid #c6f6d5;
+}
+
+.score-badge.medium {
+  background: #fffaf0;
+  color: #c05621;
+  border: 1px solid #feebc8;
+}
+
+.score-badge.low {
+  background: #fff5f5;
+  color: #c53030;
+  border: 1px solid #fed7d7;
+}
+
+.badge-icon {
+  font-size: 0.8rem;
+}
+
+.dialog-content {
+  padding: 0;
+}
+
+.content-tabs {
+  display: flex;
+  padding: 0 32px;
+  border-bottom: 1px solid #e2e8f0;
+  margin-top: 24px;
+}
+
+.tab-item {
+  display: flex;
+  align-items: center;
+  gap: 8px;
+  padding: 12px 20px;
+  cursor: pointer;
+  border-bottom: 2px solid transparent;
+  color: #718096;
+  font-weight: 500;
+  transition: all 0.3s ease;
+}
+
+.tab-item:hover {
+  color: #4299e1;
+}
+
+.tab-item.active {
+  color: #4299e1;
+  border-bottom-color: #4299e1;
+}
+
+.tab-icon {
+  font-size: 1.1rem;
+}
+
+.tab-content {
+  padding: 0 32px 32px;
+}
+
+.content-section {
+  margin-top: 24px;
+}
+
+.section-header {
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+  margin-bottom: 16px;
+}
+
+.section-header h4 {
+  margin: 0;
+  color: #2d3748;
+  font-size: 1.2rem;
+  font-weight: 600;
+}
+
+.copy-btn {
+  font-size: 0.9rem;
+  padding: 6px 12px;
+  border-radius: 8px;
+}
+
+.summary-content {
+  background: #f7fafc;
+  padding: 20px;
+  border-radius: 12px;
+  color: #4a5568;
+  line-height: 1.6;
+  font-size: 0.95rem;
+  border: 1px solid #e2e8f0;
+}
+
+.original-content {
+  background: #f7fafc;
+  border-radius: 12px;
+  border: 1px solid #e2e8f0;
+  max-height: 500px;
+  overflow-y: auto;
+}
+
+.original-content pre {
+  margin: 0;
+  padding: 20px;
+  color: #4a5568;
+  line-height: 1.6;
+  font-size: 0.9rem;
+  white-space: pre-wrap;
+  word-wrap: break-word;
+}
+
+.dialog-footer {
+  padding: 0 32px 24px;
+}
+
+.footer-actions {
+  display: flex;
+  justify-content: flex-end;
+  gap: 12px;
+}
+
+.action-btn {
+  border-radius: 12px;
+  padding: 10px 24px;
+  font-weight: 500;
+  transition: all 0.3s ease;
+}
+
+.action-btn.secondary {
+  border: 1px solid #e2e8f0;
+  background: white;
+  color: #718096;
+}
+
+.action-btn.secondary:hover {
+  background: #f7fafc;
+  border-color: #cbd5e0;
+}
+
+.action-btn.primary {
+  background: #4299e1;
+  border: 1px solid #4299e1;
+  color: white;
+}
+
+.action-btn.primary:hover {
+  background: #3182ce;
+  border-color: #3182ce;
+  transform: translateY(-1px);
+  box-shadow: 0 4px 12px rgba(66, 153, 225, 0.3);
+}
+
+/* 响应式设计 */
+@media (max-width: 1200px) {
+  .main-layout {
+    flex-direction: column;
+  }
+
+  .sidebar {
+    width: 100%;
+    position: static;
+    max-height: none;
+    margin-bottom: 20px;
+  }
+
+  .results-grid {
+    grid-template-columns: repeat(auto-fit, minmax(350px, 1fr));
+  }
+}
+
+@media (max-width: 768px) {
+  .app-title {
+    font-size: 1.75rem;
+  }
+
+  .main-layout {
+    padding: 16px;
+  }
+
+  .search-card {
+    padding: 24px;
+  }
+
+  .search-input-group {
+    flex-direction: column;
+  }
+
+  .search-button {
+    width: 100%;
+  }
+
+  .results-grid {
+    grid-template-columns: 1fr;
+  }
+
+  .dialog-title {
+    flex-direction: column;
+    text-align: center;
+    gap: 12px;
+  }
+
+  .title-content h3 {
+    font-size: 1.3rem;
+  }
+
+  .content-tabs {
+    padding: 0 20px;
+  }
+
+  .tab-content {
+    padding: 0 20px 20px;
+  }
+
+  .header-stats {
+    gap: 32px;
+  }
+}
+
+@media (max-width: 480px) {
+  .app-title {
+    font-size: 1.5rem;
+  }
+
+  .search-card {
+    padding: 20px;
+  }
+
+  .results-grid {
+    grid-template-columns: 1fr;
+  }
+
+  .content-dialog :deep(.el-dialog) {
+    width: 95% !important;
+    margin: 20px auto;
+  }
+}
+
+/* 侧边栏滚动条样式 */
+.sidebar::-webkit-scrollbar {
+  width: 6px;
+}
+
+.sidebar::-webkit-scrollbar-track {
+  background: #f1f1f1;
+  border-radius: 3px;
+}
+
+.sidebar::-webkit-scrollbar-thumb {
+  background: #c1c1c1;
+  border-radius: 3px;
+}
+
+.sidebar::-webkit-scrollbar-thumb:hover {
+  background: #a8a8a8;
+}
+
+.knowledge-list::-webkit-scrollbar {
+  width: 4px;
+}
+
+.knowledge-list::-webkit-scrollbar-track {
+  background: transparent;
+}
+
+.knowledge-list::-webkit-scrollbar-thumb {
+  background: #d1d1d1;
+  border-radius: 2px;
+}
+</style>