yangg 1 сар өмнө
parent
commit
e28228b462

+ 1 - 1
index.html

@@ -4,7 +4,7 @@
     <meta charset="UTF-8" />
     <meta charset="UTF-8" />
     <link rel="icon" type="image/svg+xml" href="/vite.svg" />
     <link rel="icon" type="image/svg+xml" href="/vite.svg" />
     <meta name="viewport" content="width=device-width, initial-scale=1.0" />
     <meta name="viewport" content="width=device-width, initial-scale=1.0" />
-    <title>Vite + Vue</title>
+    <title></title>
   </head>
   </head>
   <body>
   <body>
     <div id="app"></div>
     <div id="app"></div>

+ 12 - 5
src/components/KnowledgeConfig/index.vue

@@ -92,15 +92,16 @@ const fetchKnowledgeItems = async (kbId) => {
     params.append('kb_id', kbId);
     params.append('kb_id', kbId);
     params.append('pageSize', 9999);
     params.append('pageSize', 9999);
     
     
-    const response = await axios.post(`http://58.246.234.210:8084/docType/selectTypeList`, 
+    const response = await axios.post(`${import.meta.env.VITE_BASE_AI_API}/docType/selectTypeList`, 
       params,
       params,
       {
       {
         headers: {
         headers: {
-          'Content-Type': 'application/x-www-form-urlencoded'
+          'Content-Type': 'application/x-www-form-urlencoded',
+          'Authorization': `JWT ${localStorage.getItem('token')}`
         }
         }
       }
       }
     );
     );
-    return response.data.data.dataList || []; // 假设返回数据在 records 字段中,根据实际调整
+    return response.data.data || []; // 假设返回数据在 records 字段中,根据实际调整
   } catch (error) {
   } catch (error) {
     console.error('获取知识库子项失败:', error);
     console.error('获取知识库子项失败:', error);
     return [];
     return [];
@@ -111,9 +112,15 @@ const fetchKnowledgeItems = async (kbId) => {
 const fetchKnowledgeGroups = async () => {
 const fetchKnowledgeGroups = async () => {
   try {
   try {
     const userId = 2;
     const userId = 2;
-    const response = await axios.post(`http://58.246.234.210:8084/kbm/selectBucketInfo`, {
+    const response = await axios.post(`${import.meta.env.VITE_BASE_AI_API}/kbm/selectBucketInfo`, {
       user_id: userId
       user_id: userId
-    });
+    },
+    {
+      headers: {
+        'Authorization': `JWT ${localStorage.getItem('token')}`
+      }
+    }
+    );
     
     
     // 获取每个知识库的子项
     // 获取每个知识库的子项
     const groupsWithItems = await Promise.all(
     const groupsWithItems = await Promise.all(

+ 158 - 111
src/views/report.vue

@@ -7,14 +7,27 @@
     
     
     <div class="header">
     <div class="header">
       <div class="user-profile-bar">
       <div class="user-profile-bar">
+         <div class="logo">
+          <img
+            src="../assets/logos.JPG"
+            
+            alt="logo"
+            class="logo-img"
+          />
+       <!--  <span>Raycos Tech</span> -->
+      </div>
+      <div class="user-info-bar">
         <div class="user-info" @click="toggleDropdown">
         <div class="user-info" @click="toggleDropdown">
-          <div class="user-name">{{ userInfo.username || '未登录用户' }}</div>
+          <div class="user-name">商户名称:{{ userInfo.merchant?.merchant_name || '未登录用户' }}</div>
+          <div class="user-name">当前用户:{{ userInfo.username || '未登录用户' }}</div>
           <!-- <div class="user-role">{{ userInfo.role || '未设置角色' }}</div> -->
           <!-- <div class="user-role">{{ userInfo.role || '未设置角色' }}</div> -->
         </div>
         </div>
         <div class="avatar" @click="toggleDropdown">
         <div class="avatar" @click="toggleDropdown">
           <img src="../assets/avter.png" alt="用户头像" />
           <img src="../assets/avter.png" alt="用户头像" />
         </div>
         </div>
-        
+      </div>
+           <!-- Logo :draggable="false"-->
+     
         <!-- 下拉菜单 -->
         <!-- 下拉菜单 -->
         <div class="dropdown-menu" v-show="showDropdown">
         <div class="dropdown-menu" v-show="showDropdown">
           <div class="dropdown-item" @click="handleModifyPassword">
           <div class="dropdown-item" @click="handleModifyPassword">
@@ -47,16 +60,7 @@
       <!-- 添加收缩按钮 -->
       <!-- 添加收缩按钮 -->
       
       
 
 
-      <!-- Logo -->
-      <div class="logo">
-        <img
-          src="../assets/logos.JPG"
-          :draggable="false"
-          alt="logo"
-          class="logo-img"
-        />
-       <!--  <span>Raycos Tech</span> -->
-      </div>
+   
 
 
       <!-- New Conversation 按钮 -->
       <!-- New Conversation 按钮 -->
       <button class="new-conversation-btn" @click="addNewConversation">
       <button class="new-conversation-btn" @click="addNewConversation">
@@ -811,7 +815,12 @@ const fetchDocumentSummary = async () => {
   isLoadingSummary.value = true;
   isLoadingSummary.value = true;
   try {
   try {
     const response = await axios.get(
     const response = await axios.get(
-      `${import.meta.env.VITE_BASE_AI_API}/api/document/summary`
+      `${import.meta.env.VITE_BASE_AI_API}/api/document/summary`,
+      {
+        headers: {
+          'Authorization': `JWT ${localStorage.getItem('token')}`
+        }
+      }
     );
     );
     console.log("API Response:", response.data);
     console.log("API Response:", response.data);
 
 
@@ -1086,10 +1095,10 @@ const sendMessage = async () => {
   // 根据开启的搜索类型执行相应的搜索
   // 根据开启的搜索类型执行相应的搜索
   if (enableWebSearch.value) {
   if (enableWebSearch.value) {
     currentSearchQuery.value = currentMessage;
     currentSearchQuery.value = currentMessage;
-    // 执行互联网搜索
+   /*  // 执行互联网搜索
     sendMessageS(currentMessage).catch((error) => {
     sendMessageS(currentMessage).catch((error) => {
       console.error("Web search failed:", error);
       console.error("Web search failed:", error);
-    });
+    }); */
   } else if (enableKnowledgeSearch.value) {
   } else if (enableKnowledgeSearch.value) {
     currentSearchQuery.value = currentMessage;
     currentSearchQuery.value = currentMessage;
     // 执行知识库搜索
     // 执行知识库搜索
@@ -1127,7 +1136,7 @@ const sendMessage = async () => {
     displayContent: messageContent,
     displayContent: messageContent,
     files: attachedFiles.value.map((file) => ({
     files: attachedFiles.value.map((file) => ({
       name: file.name,
       name: file.name,
-      size: file.sizeFormatted, // 使用格式化后的大小
+      size: file.sizeFormatted,
       type: file.type,
       type: file.type,
       url: file.url,
       url: file.url,
     })),
     })),
@@ -1164,54 +1173,47 @@ const sendMessage = async () => {
       merchant_id:JSON.parse(localStorage.getItem('userInfo')).merchant.merchant_id,
       merchant_id:JSON.parse(localStorage.getItem('userInfo')).merchant.merchant_id,
       model_type: selectedModelInfo.value.type,
       model_type: selectedModelInfo.value.type,
       model_name: selectedModelInfo.value.name
       model_name: selectedModelInfo.value.name
-    });
-    if(!enableWebSearch.value){
-        // 更新 session_id
-      if (response.data.session_id) {
-        session_id.value = response.data.session_id;
+    },
+    {
+      headers: {
+        'Authorization': `JWT ${localStorage.getItem('token')}`
       }
       }
+    }
+  );
 
 
-      // 移除时消息并添加AI响应
-      messages.value = messages.value.filter(
-        (msg) => msg.id !== tempAiMessage.id
-      );
-      const aiMessage = reactive({
-        id: Date.now() + 2,
-        role: "assistant",
-        content:response.data.choices[0].message.content,
-        displayContent: "",
-        audioData: response.data.audio_info?.audio || null, // 保存音频数据
-      });
-      messages.value.push(aiMessage);
-      // 如果有音频数据,自动播放
-      if (aiMessage.audioData) {
-        playAudioMessage(aiMessage.audioData);
-      }
-      await typeMessage(aiMessage);
-    }else{
-   
-      if (response.data.data.session_id) {
-        session_id.value = response.data.data.session_id;
-      }
+    // 移除临时消息
+    messages.value = messages.value.filter(
+      (msg) => msg.id !== tempAiMessage.id
+    );
 
 
-      // 移除时消息并添加AI响应
-      messages.value = messages.value.filter(
-        (msg) => msg.id !== tempAiMessage.id
-      );
-      const aiMessage = reactive({
-        id: Date.now() + 2,
-        role: "assistant",
-        content:response.data.data.answer,
-        displayContent: "",
-        audioData: response.data.data.audio_info?.audio || null, // 保存音频数据
-      });
-      messages.value.push(aiMessage);
-      // 如果有音频数据,自动播放
-      if (aiMessage.audioData) {
-        playAudioMessage(aiMessage.audioData);
-      }
-      await typeMessage(aiMessage);
+    // 统一处理响应数据
+    const responseData = enableWebSearch.value ? response.data.data : response.data;
+    const messageContent = enableWebSearch.value ? responseData.answer : responseData.choices[0].message.content;
+    const audioInfo = enableWebSearch.value ? responseData.audio_info?.audio : responseData.audio_info?.audio;
+    const sessionId = enableWebSearch.value ? responseData.session_id : responseData.session_id;
+
+    // 更新 session_id
+    if (sessionId) {
+      session_id.value = sessionId;
+    }
+
+    // 创建新的AI消息
+    const aiMessage = reactive({
+      id: Date.now() + 2,
+      role: "assistant",
+      content: messageContent,
+      displayContent: "",
+      audioData: audioInfo || null,
+    });
+    messages.value.push(aiMessage);
+
+    // 如果有音频数据,自动播放
+    if (aiMessage.audioData && !isPlaying.value) {
+      await playAudioMessage(aiMessage.audioData, aiMessage.id);
     }
     }
+
+    // 显示打字效果
+    await typeMessage(aiMessage);
     
     
   } catch (error) {
   } catch (error) {
     console.error("发送消息失败:", error);
     console.error("发送消息失败:", error);
@@ -1391,18 +1393,27 @@ const handleAudioClick = (message) => {
     }  
     }  
   }else{
   }else{
     // 用户消息的文本转语音处理
     // 用户消息的文本转语音处理
-    playUserMessage(message.content, message.id);
+    if (currentPlayingId.value === message.id) {
+      stopAudio();
+    } else {
+      playUserMessage(message.content, message.id);
+    }
   }
   }
 };
 };
 
 
 // 添加播放用户消息的方法
 // 添加播放用户消息的方法
 const playUserMessage = async (text, messageId) => {
 const playUserMessage = async (text, messageId) => {
   try {
   try {
-    // 如果当前有音频在播放,先停止
-    if (currentPlayingId.value) {
+    // 如果当前有其他音频在播放,先停止
+    if (currentPlayingId.value && currentPlayingId.value !== messageId) {
       stopAudio();
       stopAudio();
     }
     }
 
 
+    // 如果已经在播放这条消息,直接返回(这种情况应该不会发生,因为会被上面的 handleAudioClick 处理)
+    if (currentPlayingId.value === messageId) {
+      return;
+    }
+
     const response = await axios.post(`${import.meta.env.VITE_BASE_AI_API}/api/voices/play_text`, {
     const response = await axios.post(`${import.meta.env.VITE_BASE_AI_API}/api/voices/play_text`, {
       text: text
       text: text
     }, {
     }, {
@@ -1418,11 +1429,22 @@ const playUserMessage = async (text, messageId) => {
       // 保存当前播放的音频和ID
       // 保存当前播放的音频和ID
       currentAudioSource.value = audio;
       currentAudioSource.value = audio;
       currentPlayingId.value = messageId;
       currentPlayingId.value = messageId;
+      isPlaying.value = true;
       
       
       // 播放结束时清理
       // 播放结束时清理
       audio.onended = () => {
       audio.onended = () => {
         currentPlayingId.value = null;
         currentPlayingId.value = null;
         currentAudioSource.value = null;
         currentAudioSource.value = null;
+        isPlaying.value = false;
+      };
+
+      // 播放错误时清理
+      audio.onerror = (e) => {
+        console.error('播放文本失败:', e);
+        message.error('播放失败,请稍后重试');
+        currentPlayingId.value = null;
+        currentAudioSource.value = null;
+        isPlaying.value = false;
       };
       };
       
       
       // 开始播放
       // 开始播放
@@ -1431,46 +1453,9 @@ const playUserMessage = async (text, messageId) => {
   } catch (error) {
   } catch (error) {
     console.error('播放文本失败:', error);
     console.error('播放文本失败:', error);
     message.error('播放失败,请稍后重试');
     message.error('播放失败,请稍后重试');
-  }
-};
-
-/* // 停止音频播放的函数
-const stopAudio = () => {
-  if (currentAudioSource.value) {
-    currentAudioSource.value.pause();
-    currentAudioSource.value.currentTime = 0;
-    currentAudioSource.value = null;
     currentPlayingId.value = null;
     currentPlayingId.value = null;
-  }
-} */
-
-// 修改音频播放方法
-const playAudioMessage = async (audioBase64, messageId) => {
-  try {
-    // 停止当前播放的音频
-    stopAudio();
-
-    // 创建新的音频元素
-    const audio = new Audio(audioBase64);
-    audioPlayer.value = audio;
-    currentPlayingId.value = messageId;
-
-    // 添加事件监听
-    audio.addEventListener("ended", () => {
-      stopAudio();
-    });
-
-    audio.addEventListener("error", (e) => {
-      console.error("音频播放错误:", e);
-      stopAudio();
-    });
-
-    // 播放音频
-    await audio.play();
-    isPlaying.value = true;
-  } catch (error) {
-    console.error("音频播放失败:", error);
-    stopAudio();
+    currentAudioSource.value = null;
+    isPlaying.value = false;
   }
   }
 };
 };
 
 
@@ -1478,6 +1463,7 @@ const playAudioMessage = async (audioBase64, messageId) => {
 const stopAudio = () => {
 const stopAudio = () => {
   if (audioPlayer.value) {
   if (audioPlayer.value) {
     audioPlayer.value.pause();
     audioPlayer.value.pause();
+    audioPlayer.value.currentTime = 0;
     audioPlayer.value = null;
     audioPlayer.value = null;
   }
   }
   if (currentAudioSource.value) {
   if (currentAudioSource.value) {
@@ -1579,9 +1565,9 @@ const handleInputChange = () => {
     
     
     // 根据当前选中的搜索类型执行相应的搜索
     // 根据当前选中的搜索类型执行相应的搜索
     if (enableWebSearch.value) {
     if (enableWebSearch.value) {
-      sendMessageS(inputContent.value).catch((error) => {
+     /*  sendMessageS(inputContent.value).catch((error) => {
         console.error("Web search failed:", error);
         console.error("Web search failed:", error);
-      });
+      }); */
     } else if (enableKnowledgeSearch.value) {
     } else if (enableKnowledgeSearch.value) {
       handleKnowledgeSearch({
       handleKnowledgeSearch({
         query: inputContent.value,
         query: inputContent.value,
@@ -1675,13 +1661,18 @@ const updateCollapsedState = () => {
     isKnowledgeLoading.value = true;
     isKnowledgeLoading.value = true;
     try {
     try {
       const response = await axios.post(
       const response = await axios.post(
-        `${import.meta.env.VITE_BASE_AI_F_API}/chataids/mysql_fuzzy_search/`,
+        `${import.meta.env.VITE_BASE_AI_API}/chataids/mysql_fuzzy_search/`,
         {
         {
-          collection_names: ["25"], // 固定使用 "25" 作为 collection name
+         // collection_names: ["25"], // 固定使用 "25" 作为 collection name
           keywords: params.query, // 使用查询关键词
           keywords: params.query, // 使用查询关键词
           documents: [], // 保持空数组
           documents: [], // 保持空数组
           document_ids: [], // 保持空数组
           document_ids: [], // 保持空数组
           limit: 5 // 固定返回5条结果
           limit: 5 // 固定返回5条结果
+        },
+        {
+          headers: {
+            'Authorization': `JWT ${localStorage.getItem('token')}`
+          }
         }
         }
       );
       );
         console.log(response);
         console.log(response);
@@ -1709,9 +1700,9 @@ const updateCollapsedState = () => {
       // 如果有输入内容,执行互联网搜索
       // 如果有输入内容,执行互联网搜索
       if (inputContent.value.trim()) {
       if (inputContent.value.trim()) {
         currentSearchQuery.value = inputContent.value;
         currentSearchQuery.value = inputContent.value;
-        sendMessageS(inputContent.value).catch((error) => {
+       /*  sendMessageS(inputContent.value).catch((error) => {
           console.error("Web search failed:", error);
           console.error("Web search failed:", error);
-        });
+        }); */
       }
       }
     }
     }
   };
   };
@@ -1888,6 +1879,54 @@ const updateCollapsedState = () => {
   /* const currentAudioSource = ref(null);
   /* const currentAudioSource = ref(null);
   const currentPlayingId = ref(null); */
   const currentPlayingId = ref(null); */
 
 
+  // 添加播放音频消息的方法
+  const playAudioMessage = async (audioData, messageId) => {
+    try {
+      // 如果当前有其他音频在播放,先停止
+      if (currentPlayingId.value && currentPlayingId.value !== messageId) {
+        stopAudio();
+      }
+
+      // 如果已经在播放这条消息,直接返回
+      if (currentPlayingId.value === messageId) {
+        return;
+      }
+
+      // 创建新的音频元素
+      const audio = new Audio(audioData);
+      
+      // 保存当前播放的音频和ID
+      currentAudioSource.value = audio;
+      currentPlayingId.value = messageId;
+      isPlaying.value = true;
+      
+      // 播放结束时清理
+      audio.onended = () => {
+        currentPlayingId.value = null;
+        currentAudioSource.value = null;
+        isPlaying.value = false;
+      };
+
+      // 播放错误时清理
+      audio.onerror = (e) => {
+        console.error('播放音频失败:', e);
+        message.error('播放失败,请稍后重试');
+        currentPlayingId.value = null;
+        currentAudioSource.value = null;
+        isPlaying.value = false;
+      };
+      
+      // 开始播放
+      await audio.play();
+    } catch (error) {
+      console.error('播放音频失败:', error);
+      message.error('播放失败,请稍后重试');
+      currentPlayingId.value = null;
+      currentAudioSource.value = null;
+      isPlaying.value = false;
+    }
+  };
+
  </script>
  </script>
 
 
 <style scoped>
 <style scoped>
@@ -1915,12 +1954,20 @@ const updateCollapsedState = () => {
   position: relative;
   position: relative;
   display: flex;
   display: flex;
   align-items: center;
   align-items: center;
-  justify-content: flex-end;
+  justify-content:  space-between;
   cursor: pointer;
   cursor: pointer;
-  padding: 8px;
+ 
+ 
+}
+.user-info-bar{
+  display: flex;
+  align-items: center;
+  justify-content: flex-end;
+  width: 100%;
+  height: 100%;
+  background-color: #f7f7f8;
  
  
 }
 }
-
 .avatar {
 .avatar {
   width: 40px;
   width: 40px;
   height: 40px;
   height: 40px;