LAPTOP-1LHD2FP6\joeny 5 mesiacov pred
rodič
commit
3c971e12aa
3 zmenil súbory, kde vykonal 183 pridanie a 14 odobranie
  1. 1 1
      .env.development
  2. 34 9
      src/components/SearchResults/index.vue
  3. 148 4
      src/views/report.vue

+ 1 - 1
.env.development

@@ -1,2 +1,2 @@
 NODE_ENV=development
-VITE_BASE_AI_API=http://58.246.234.210:8082
+VITE_BASE_AI_API=http://127.0.0.1:8082

+ 34 - 9
src/components/SearchResults/index.vue

@@ -62,6 +62,7 @@ import { defineComponent, ref, watch } from 'vue';
 import { FileSearchOutlined } from '@ant-design/icons-vue';
 import dayjs from 'dayjs';
 import axios from 'axios';
+
 export default defineComponent({
   name: 'SearchResults',
   components: {
@@ -80,17 +81,23 @@ export default defineComponent({
       type: Number,
       default: 0
     },
-    message:{
-      type:String,
-      default:''
-    }
+    message: {
+      type: String,
+      default: ''
+    },
+    enableWebSearch: {
+      type: Boolean,
+      default: true,
+    },
   },
+  emits: ['update:total', 'update:enableWebSearch'],
   setup(props, { emit }) {
     const displayResults = ref([]);
     const hasMore = ref(false);
     const searchQuery = ref('');
     const isSearching = ref(false);
     const localTotal = ref(props.total);
+    const isSearchEnabled = ref(props.enableWebSearch);
 
     // 监听props中的total变化
     watch(() => props.total, (newTotal) => {
@@ -105,12 +112,23 @@ export default defineComponent({
 
     // 监听 message prop 的变化
     watch(() => props.message, (newMessage) => {
-      if (newMessage) {
+      if (newMessage && props.enableWebSearch) {
         searchQuery.value = newMessage;
-        // 可选:当 message 更新时自动触发搜索
-        handleSearch();
+        handleSearch(); // 自动触发搜索
       }
-    }, { immediate: true });
+    });
+
+    // 添加监听器
+    watch(
+      () => props.enableWebSearch,
+      (newVal) => {
+        isSearchEnabled.value = newVal;
+        if (!newVal) {
+          // 当搜索被关闭时,清空搜索结果
+          clearSearch();
+        }
+      }
+    );
 
     // 格式化日期
     const formatDate = (date) => {
@@ -119,7 +137,7 @@ export default defineComponent({
 
     // 更新搜索处理函数
     const handleSearch = async () => {
-      if (!searchQuery.value.trim() || isSearching.value) return;
+      if (!searchQuery.value.trim() || isSearching.value || !props.enableWebSearch) return;
       
       isSearching.value = true;
       try {
@@ -162,6 +180,11 @@ export default defineComponent({
       emit('update:total', 0);
     };
 
+    const toggleSearch = () => {
+      isSearchEnabled.value = !isSearchEnabled.value;
+      emit('update:enableWebSearch', isSearchEnabled.value);
+    };
+
     return {
       displayResults,
       loading: props.loading,
@@ -172,6 +195,8 @@ export default defineComponent({
       isSearching,
       handleSearch,
       clearSearch,
+      isSearchEnabled,
+      toggleSearch,
     };
   }
 });

+ 148 - 4
src/views/report.vue

@@ -402,6 +402,7 @@
             class="message-input"
             v-model="inputContent"
             @keyup.enter="sendMessage"
+            @input="handleInputChange"
             placeholder="Type a message..."
           />
           <button
@@ -415,7 +416,7 @@
       </div>
     </div>
 
-    <div class="right_menu" :class="{ collapsed: isRightMenuCollapsed }" :style="{ width: rightMenuWidth + 'px' }">
+    <div class="right_menu" :class="{ collapsed: isRightMenuCollapsed || !enableWebSearch }" :style="{ width: rightMenuWidth + 'px' }">
       <!-- 添加拖动条 -->
       <div 
         class="resize-handle"
@@ -437,10 +438,29 @@
         />
       </div>
       <div class="right-menu-content">
+        <div class="search-header">
+          <span>搜索结果</span>
+          <div class="web-search-toggle">
+            <input
+              type="checkbox"
+              id="searchToggle"
+              v-model="enableWebSearch"
+              class="toggle-input"
+              @change="handleSearchToggle"
+            />
+            <label for="searchToggle" class="toggle-label">
+              {{ enableWebSearch ? '搜索已开启' : '搜索已关闭' }}
+            </label>
+          </div>
+        </div>
         <SearchResults
+          v-if="enableWebSearch"
           :searchResults="searchResults"
           :loading="isSearchLoading"
           :total="searchTotal"
+          :enableWebSearch="enableWebSearch"
+          :message="currentSearchQuery"
+          @update:enableWebSearch="handleSearchToggle"
         />
       </div>
     </div>
@@ -464,6 +484,7 @@ import {
   FileOutlined,
   ArrowUpOutlined,
   UploadOutlined,
+  FileSearchOutlined,
 } from "@ant-design/icons-vue";
 import leftIcon from "../assets/svg/left.svg";
 import rightIcon from "../assets/svg/right.svg";
@@ -485,6 +506,7 @@ import SearchResults from "../components/SearchResults/index.vue";
 import VoiceConfig from "../components/VoiceConfig/index.vue";
 import KnowledgeConfig from "../components/KnowledgeConfig/index.vue";
 import ExportButton from "../components/ExportButton/index.vue";
+import dayjs from 'dayjs';
 
 // 初始化 markdown-it
 const md = new MarkdownIt({
@@ -871,6 +893,11 @@ const sendMessage = async () => {
   )
     return;
 
+  // 如果启用了网络搜索,更新搜索查询
+  if (enableWebSearch.value) {
+    currentSearchQuery.value = inputContent.value;
+  }
+
   // 构建消息内容,包含文件信息
   let messageContent = inputContent.value.trim();
 
@@ -1230,6 +1257,66 @@ const startResize = (e) => {
   document.addEventListener('touchend', handleEnd);
 };
 
+// 添加搜索开关状态
+const isSearchEnabled = ref(true);
+
+// 添加切换搜索方法 
+const toggleSearch = () => {
+  isSearchEnabled.value = !isSearchEnabled.value;
+};
+
+// 修改 toggleWebSearch 方法
+const toggleWebSearch = () => {
+  enableWebSearch.value = !enableWebSearch.value;
+  isSearchEnabled.value = enableWebSearch.value;
+  
+  // 当关闭搜索时,自动折叠右侧菜单
+  if (!enableWebSearch.value) {
+    isRightMenuCollapsed.value = true;
+    currentSearchQuery.value = '';
+    if (document.querySelector('.chat')) {
+      document.querySelector('.chat').style.right = '0';
+    }
+  } else if (inputContent.value.trim()) {
+    isRightMenuCollapsed.value = false;
+    currentSearchQuery.value = inputContent.value;
+    if (document.querySelector('.chat')) {
+      document.querySelector('.chat').style.right = `${rightMenuWidth.value}px`;
+    }
+  }
+};
+
+// 添加新的响应式变量
+const currentSearchQuery = ref('');
+
+// 添加输入变化处理方法
+const handleInputChange = () => {
+  if (enableWebSearch.value && inputContent.value.trim()) {
+    currentSearchQuery.value = inputContent.value;
+  }
+};
+
+// 添加处理搜索开关的方法
+const handleSearchToggle = (value) => {
+  enableWebSearch.value = value;
+  isSearchEnabled.value = value;
+  
+  // 当关闭搜索时,自动折叠右侧菜单
+  if (!value) {
+    isRightMenuCollapsed.value = true;
+    // 更新聊天区域的样式
+    if (document.querySelector('.chat')) {
+      document.querySelector('.chat').style.right = '0';
+    }
+  } else {
+    isRightMenuCollapsed.value = false;
+    // 展开时更新聊天区域的样式
+    if (document.querySelector('.chat')) {
+      document.querySelector('.chat').style.right = `${rightMenuWidth.value}px`;
+    }
+  }
+};
+
 </script>
 
 <style scoped>
@@ -1963,13 +2050,13 @@ const startResize = (e) => {
   background: #f7f7f8;
   border-left: 1px solid rgba(0, 0, 0, 0.06);
   transform: translateX(0);
-  transition: transform 0.3s ease;
+  transition: transform 0.3s ease, width 0.3s ease;
   z-index: 2;
 }
 
 .right_menu.collapsed {
-  transform: translateX(100%); /* 使用 transform 代替 width */
-  width: 600px; /* 保持固定宽度 */
+  transform: translateX(100%);
+  width: 0;
 }
 
 /* 当右侧菜单展开时,给聊天区域添加右边距 */
@@ -2843,6 +2930,63 @@ button,
     width: 100% !important;
   }
 }
+
+.search-header {
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+  padding: 16px;
+  border-bottom: 1px solid #f0f0f0;
+}
+
+.search-header span {
+  font-size: 16px;
+  font-weight: bold;
+}
+
+/* 添加开关样式 */
+.web-search-toggle {
+  display: flex;
+  align-items: center;
+}
+
+.toggle-input {
+  position: relative;
+  width: 36px;
+  height: 20px;
+  margin-right: 8px;
+  appearance: none;
+  background: #ccc;
+  border-radius: 10px;
+  cursor: pointer;
+  transition: background 0.3s;
+}
+
+.toggle-input:checked {
+  background: #1677ff;
+}
+
+.toggle-input::before {
+  content: "";
+  position: absolute;
+  top: 2px;
+  left: 2px;
+  width: 16px;
+  height: 16px;
+  background: white;
+  border-radius: 50%;
+  transition: transform 0.3s;
+}
+
+.toggle-input:checked::before {
+  transform: translateX(16px);
+}
+
+.toggle-label {
+  font-size: 14px;
+  color: rgba(0, 0, 0, 0.88);
+  cursor: pointer;
+}
 </style>
 <style lang="less" scoped>
 ::v-deep .message-content {