From d0f5a5f53f90acdd01abbb13a694c3cd333aea7b Mon Sep 17 00:00:00 2001
From: yinbangzhong <zhongbangyin@126.com>
Date: 星期六, 24 八月 2024 17:58:08 +0800
Subject: [PATCH] bug fix

---
 src/views/sessionManager/index.vue |  438 ++++++++++++++++++++++++++++--------------------------
 1 files changed, 225 insertions(+), 213 deletions(-)

diff --git a/src/views/sessionManager/index.vue b/src/views/sessionManager/index.vue
index 4d6842d..6654627 100644
--- a/src/views/sessionManager/index.vue
+++ b/src/views/sessionManager/index.vue
@@ -1,5 +1,5 @@
 <template>
-  <div class="container">
+  <div class="container" id="container">
     <!--    <AddSession-->
     <!--      :modalObj="modalObj"-->
     <!--      @addSession="addSession"-->
@@ -23,8 +23,16 @@
                 <!--                <span class="title">{{ agentTitle }}</span>-->
 
                 <a-popover position="bottom" trigger="click">
-                  <a-button border
-                    >{{ agentTitle }}
+                  <a-button border>
+                    <span
+                      style="
+                        width: 100px;
+                        overflow: hidden;
+                        text-overflow: ellipsis;
+                        white-space: nowrap;
+                      "
+                      >{{ from.name }}</span
+                    >
                     <icon-down style="margin-left: 4px" />
                   </a-button>
                   <template #content>
@@ -49,12 +57,13 @@
             ref="scrollbar"
             id="home"
             class="chat-list"
-            style="
-              width: 80%;
-              overflow: auto;
-              height: calc(100vh - 380px);
-              margin: 0px auto 20px;
-            "
+            style="width: 80%; overflow: auto; margin: 0px auto 20px"
+            :style="{
+              height:
+                uploaditemList.length > 0
+                  ? 'calc(100vh - 480px)'
+                  : 'calc(100vh - 380px)',
+            }"
           >
             <div
               class="chat-item"
@@ -83,25 +92,40 @@
                   />
                 </template>
                 <template #content>
-                  <!--                  <a-card :class="{ chatItemAnswer: theme === 'light' }">-->
-                  <!--                    <div-->
-                  <!--                      :class="{ light: theme === 'light' }"-->
-                  <!--                      v-html="sessionDetail.content.replace(/\n/g, '<br/>')"-->
-                  <!--                    >-->
-                  <!--                    </div>-->
-                  <!--                  </a-card>-->
-                  <a-textarea
-                    readonly
-                    auto-size
-                    v-model="sessionDetail.content"
-                    :class="{ chatItemAnswer: theme === 'light' }"
-                    :style="{
+                  <a-card v-if="isExistTip(sessionDetail.content)">
+                    <div  :class="{ chatItemAnswer: theme === 'light' }"
+                      :style="{backgroundColor: theme === 'light' ? '#ffffff' : '#000000'}" style="border: none;display: inline;"  v-for="(item,tipIndex) in tipMatch(sessionDetail)"
+                    >
+                      <span v-if="tipIndex == 0">
+                        {{ sessionDetail.content.substring(0, item.index) }}
+                        <a-tooltip background-color="#3491FA" :content="getTipContent(
+                          messagenList.reference,
+                          index
+                        )">
+                          <img style="width: 20px;height: 20px" :src="tipImage" />
+                        </a-tooltip>
+                      </span>
+                      <span v-else>
+                        {{ sessionDetail.content.substring(item.preIndex+item.item.length, item.index) }}
+                        <a-tooltip background-color="#3491FA" :content="getTipContent(
+                          messagenList.reference,
+                          index
+                        )">
+                          <img style="width: 20px;height: 20px" :src="tipImage" />
+                        </a-tooltip>
+                      </span>
+
+                    </div>
+                  </a-card>
+                  <a-card  v-else>
+                    <div :class="{ chatItemAnswer: theme === 'light' }"
+                         :style="{
                       backgroundColor:
                         theme === 'light' ? '#ffffff' : '#000000',
-                    }"
-                    style="border: none"
-                  >
-                  </a-textarea>
+                    }" style="border: none">
+                      {{ sessionDetail.content }}
+                    </div>
+                  </a-card>
                 </template>
                 <!-- <div>{{ sessionDetail.role === 'assistant' }}</div> -->
                 <template #actions>
@@ -213,7 +237,11 @@
                 v-model="inputMsg"
                 @keydown.shift.enter="handleShiftEnter"
                 @keydown.enter="sendMessage"
-                placeholder="杈撳叆鎮ㄦ兂浜嗚В鐨勫唴瀹癸紝Shift+Enter鎹㈣锛孍nter鍙戦��"
+                :placeholder="
+                  uploaditemList.length > 0
+                    ? '鏁寸悊杩欎簺鏂囦欢鐨勬牳蹇冨唴瀹�'
+                    : '杈撳叆鎮ㄦ兂浜嗚В鐨勫唴瀹癸紝Shift+Enter鎹㈣锛孍nter鍙戦��'
+                "
                 allow-clear
                 show-word-limit
                 :disabled="chatDis"
@@ -227,27 +255,18 @@
                   maxRows: 5,
                 }"
               />
-              <div style="width: 100%;display: flex;justify-content: space-between">
-                <a-button
-                  :disabled="onFileSelectedLoading"
-                  @click="selectFile"
-                  type="text"
-                  style="border-radius: 24px"
-                >
-                  <icon-attachment
-                    size="28"
-                    style="color: #0960bd"
-                  />
-                  <input
-                    ref="fileInput"
-                    type="file"
-                    style="display: none"
-                    @change="onFileSelected"
-                  />
-                </a-button>
-                  <span
-                    style="cursor: pointer;margin-left: 20px;">
-                </span>
+              <div
+                style="
+                  width: 100%;
+                  display: flex;
+                  justify-content: space-between;
+                "
+              >
+                <updataFile
+                  ref="fileInput"
+                  :sessionId="activeSessionId"
+                  @selectFileCallback="selectFileCallback"
+                ></updataFile>
                 <a-button
                   :disabled="chatDis"
                   @click="sentClick"
@@ -258,62 +277,22 @@
                   <icon-send size="32" style="color: #0960bd" />
                 </a-button>
               </div>
-<!--              <div class="btn-send">-->
-<!--                <a-button-->
-<!--                  :disabled="chatDis"-->
-<!--                  @click="sentClick"-->
-<!--                  type="text"-->
-<!--                  style="border-radius: 24px"-->
-<!--                  :loading="loading"-->
-<!--                >-->
-<!--                  <icon-send size="32" style="color: #0960bd" />-->
-<!--                </a-button>-->
-<!--              </div>-->
             </div>
-            <!--            <div style="margin-top: 0px">-->
-            <!--              <a-upload-->
-            <!--                ref="uploadRef"-->
-            <!--                :file-list="uploadList"-->
-            <!--                :limit="1"-->
-            <!--                multiple-->
-            <!--                :custom-request="customRequest"-->
-            <!--                style="font-size: 24px;margin-bottom: 10px;position: relative;width: 200px">-->
-            <!--                <template #upload-button>-->
-            <!--                  <icon-attachment style="color: #0960bd;position: absolute;top:-50px;left: 20px;z-index: 10000"/>-->
-            <!--                </template>-->
-            <!--              </a-upload>-->
-            <!--            </div>-->
-<!--            <span-->
-<!--              style="-->
-<!--                position: absolute;-->
-<!--                top: 94px;-->
-<!--                left: 20px;-->
-<!--                z-index: 999;-->
-<!--                cursor: pointer;-->
-<!--              "-->
-<!--            >-->
-<!--              <icon-attachment-->
-<!--                size="28"-->
-<!--                @click="selectFile"-->
-<!--                style="color: #0960bd"-->
-<!--              />-->
-<!--              <input-->
-<!--                ref="fileInput"-->
-<!--                type="file"-->
-<!--                style="display: none"-->
-<!--                @change="onFileSelected"-->
-<!--              />-->
-<!--            </span>-->
-            <div class="uploadFileList">
+            <div class="uploadFileList" v-if="uploaditemList.length > 0">
               <div
                 class="files"
                 v-for="(item, index) in uploaditemList"
                 :key="index"
-                style="position: relative; width: 200px; margin-top: 10px"
+                style="
+                  position: relative;
+                  width: 200px;
+                  margin-top: 10px;
+                  margin-right: 20px;
+                "
               >
                 <a-comment
                   :author="item.name"
-                  :content="(item.size/1024).toFixed(2) + 'K'"
+                  :content="item.size"
                   style="
                     background: var(--color-bg-2);
                     padding: 10px;
@@ -331,9 +310,10 @@
                       </template>
                     </a-spin>
                     <!--                    <a-button type="text" :loading="onFileSelectedLoading" v-if="onFileSelectedLoading"></a-button>-->
-                    <a-avatar v-if="!onFileSelectedLoading">
-                      <icon-file style="color: #0960bd" />
-                    </a-avatar>
+                    <!--                    <a-avatar v-if="!onFileSelectedLoading">-->
+                    <!--                      <icon-file style="color: #0960bd" />-->
+                    <!--                    </a-avatar>-->
+                    <img :src="getIconByExtension(item.name)" alt="" />
                   </template>
                 </a-comment>
                 <icon-close-circle-fill
@@ -383,14 +363,9 @@
       :footer="false"
       title-align="start"
     >
-      <a-form
-        ref="formRef"
-        :rules="rules"
-        :model="chatObj"
-        @submit="handleSubmit"
-      >
+      <a-form ref="formRef" :rules="rules" :model="from" @submit="handleSubmit">
         <a-form-item field="name" label="鍚嶇О">
-          <a-input v-model="agentTitle" placeholder="璇疯緭鍏ュ悕绉�" />
+          <a-input v-model="from.name" placeholder="璇疯緭鍏ュ悕绉�" />
         </a-form-item>
         <a-form-item>
           <div style="width: 100%; text-align: right">
@@ -408,11 +383,6 @@
   </div>
 </template>
 <script setup lang="ts">
-  import {
-    IconClose,
-    IconSearch,
-    IconTiktokColor,
-  } from '@arco-design/web-vue/es/icon';
   import { useAppStore, useUserStore } from '@/store';
   import {
     computed,
@@ -433,7 +403,7 @@
   import agentSession from '@/views/sessionManager/components/agentSession.vue';
   import historySession from '@/views/sessionManager/components/historySession.vue';
   import smartAi from '@/views/sessionManager/components/smartAi.vue';
-  import setName from '@/views/sessionManager/components/setName.vue';
+  import updataFile from '@/views/sessionManager/components/updataFile.vue';
   import EventBus from '@/utils/EventBus';
   import {
     addSessionApi,
@@ -452,10 +422,17 @@
   import pdfImg3 from '@/assets/session/execl.png';
   import pdfImg4 from '@/assets/session/icon-txt.png';
   import pdfImg5 from '@/assets/session/txt.png';
+  import tipImage from '@/assets/session/tip.png';
+  import { number } from "@intlify/core-base";
 
   // const url = ref('../../assets/session/PDF.png');
 
-  const sessionDetailList = ref([]); //鏍规嵁浼氳瘽id鍑烘潵鐨勪細璇濊鎯�
+  const sessionDetailList = ref([
+    {
+      content: '浣犲ソ锛� 鎴戞槸浣犵殑鍔╃悊锛屾湁浠�涔堝彲浠ュ府鍒颁綘鐨勫悧锛�',
+      role: 'assistant',
+    },
+  ]); //鏍规嵁浼氳瘽id鍑烘潵鐨勪細璇濊鎯�
   const messagenList = ref({});
   const sessionList = ref([]); //浼氳瘽鍒楄〃
   const modalObj = reactive({ add: false });
@@ -465,6 +442,9 @@
   const agentType = ref('1');
   const agentTitle = ref('鏈懡鍚嶄細璇�');
   let chatObj = reactive({});
+  let from = reactive({
+    name: '鏈懡鍚嶄細璇�',
+  });
   const isStopChat = ref(false);
   const currIndex = ref(0);
   const displayedText = ref(''); // 姝e湪鏄剧ず鐨勬枃瀛�
@@ -487,6 +467,7 @@
   const fileInput = ref(null);
   const chatDataMeg = reactive({});
   const visible = ref(false);
+  let toStop = false;
 
   const rules = {
     name: [
@@ -499,12 +480,10 @@
 
   const handleSubmit = async ({ values, errors }) => {
     if (errors) return;
-    // chatObj.name = agentTitle.value;
-    // chatObj.conversation_id = chatObj.id;
     let chatData = {
       id: chatObj.id,
       conversation_id: chatObj.id,
-      name: agentTitle.value,
+      name: from.name,
     };
     const { code, data } = await addSessionApi(chatData);
     if (data) {
@@ -514,14 +493,31 @@
     }
   };
   let dataItem = [];
+  const isExistTip=(message:string):boolean=>{
+    if (/##[0-9]\$\$/.test(message)) {
+      return true;
+    } else {
+      return false;
+    }
+  }
+
+  const tipMatch = (session: any): any[] => {
+    //match session.content涓殑##[0-9]$$鐨勭储寮�
+    let indexs: any[] = [];
+    let preTip=0;
+    session.content.match(/##([0-9]+)\$\$/g)?.map((item) => {
+      let i = session.content.indexOf(item);
+      indexs.push({ index: i, item: item, preIndex: preTip });
+      preTip = i;
+    });
+    return indexs;
+  }
+
   const getTxt = (data, role, message, index) => {
-    if (/##0\$\$/.test(message)) {
+    if (isExistTip(message)) {
       if (role == 'assistant' && index) {
-        data.forEach((item) => {
-          if (Object.keys(item).length !== 0 && item?.doc_aggs.length > 0) {
-            dataItem = item.doc_aggs;
-          }
-        });
+        let i = index / 2 - 1 > 0 ? index / 2 - 1 : 0;
+        dataItem = data[i].doc_aggs;
       }
     } else {
       dataItem = [];
@@ -530,9 +526,51 @@
     return dataItem;
   };
 
+  const getTipContent = (data, index): string => {
+    let maxSimilarityContent = "";
+    let i = index / 2 - 1 > 0 ? index / 2 - 1 : 0;
+    let maxSimilarity = 0;
+    data[i].chunks.forEach((chunk) => {
+        if (chunk.similarity > maxSimilarity) {
+          maxSimilarity = chunk.similarity;
+          maxSimilarityContent = chunk.content_with_weight;
+        }
+      }
+    );
+    return maxSimilarityContent;
+  };
+
   const clickHref = (item) => {
     // return Message.warning('鏆傛棤娉曟煡鐪�');
-    window.open(`/api/v1/document/show/${item.doc_id}`, '_blank');
+    // window.open(`/api/v1/document/get/${item.doc_id}`, '_blank');
+    downloadFile({
+      url: `/api/v1/document/get/${item.doc_id}`,
+      filename: item.doc_name,
+    });
+  };
+
+  const downloadFile = ({
+    url,
+    filename,
+    target,
+  }: {
+    url: string;
+    filename?: string;
+    target?: string;
+  }) => {
+    const downloadElement = document.createElement('a');
+    downloadElement.style.display = 'none';
+    downloadElement.href = url;
+    if (target) {
+      downloadElement.target = '_blank';
+    }
+    downloadElement.rel = 'noopener noreferrer';
+    if (filename) {
+      downloadElement.download = filename;
+    }
+    document.body.appendChild(downloadElement);
+    downloadElement.click();
+    document.body.removeChild(downloadElement);
   };
 
   const getIconByExtension = computed(() => (extension) => {
@@ -570,74 +608,21 @@
     // formRef.value.resetFields();
   };
 
-  const selectFile = () => {
-    fileInput.value.click();
+  const selectFileCallback = (data) => {
+    console.log(data, 'selectFileCallback');
+    uploaditemList.value = data;
   };
 
   let onFileSelectedLoading = ref(false);
-  const onFileSelected = (event) => {
-    const file = event.target.files[0];
-    uploaditemList.value = [
-      {
-        name: file.name,
-        size: file.size,
-      },
-    ];
-    if (file) {
-      onFileSelectedLoading.value = true;
-      const formData = new FormData();
-      formData.append('file', file);
-      formData.append('conversation_id', activeSessionId.value);
-      uploadWithoutKb(formData).then((res) => {
-        // console.log(res);
-        if (res.code == 200) {
-          console.log(res);
-          console.log(uploaditemList.value);
-          onFileSelectedLoading.value = false;
-          fileInput.value.value = '';
-          uploaditemList.value = [];
-          Message.success('涓婁紶鎴愬姛');
-        } else {
-          Message.error('涓婁紶澶辫触');
-        }
-      });
-    }
-  };
 
   const deleteFile = (item) => {
     console.log(uploaditemList.value);
-    uploaditemList.value = [];
+    uploaditemList.value.splice(item.index, 1);
   };
 
   const { toClipboard } = useClipboard();
   const copy = async (text) => {
     await toClipboard(text); //鍙傛暟涓鸿澶嶅埗鐨勬枃鏈�
-  };
-
-  const onChange = (fileList) => {
-    // files.value = fileList;
-  };
-
-  // 涓婁紶鏂囦欢
-  const customRequest = async (option) => {
-    const { onProgress, onError, onSuccess, fileItem, name } = option;
-    fileItem.status = 'ready';
-    if (fileItem.file) {
-      const formData = new FormData();
-      formData.append('file', fileItem.file);
-      formData.append('conversation_id', activeSessionId.value);
-      uploadWithoutKb(formData).then((res) => {
-        // console.log(res);
-        if (res.code == 200) {
-          console.log(res);
-          console.log(uploadList.value);
-          fileItem.status = 'done';
-          // uploadList.value = [];
-        } else {
-          fileItem.status = 'error';
-        }
-      });
-    }
   };
 
   const DialogList = async () => {
@@ -706,26 +691,6 @@
     event.preventDefault();
     inputMsg.value += '\n';
   };
-  const dialogChange = (val) => {
-    // 鍒ゆ柇褰撳墠鏄櫤鑳戒綋鎴朼gent
-    // console.log(val, 'val');
-    dialogId.value = val;
-    dialogs.value.forEach((item) => {
-      if (item.id === val) {
-        Object.assign(dialogObj, item);
-      }
-    });
-    console.log(dialogObj.type, 'dialogObj');
-    if (dialogObj.type == 1) {
-      agentType.value = '1';
-      querySessionList();
-    } else {
-      agentType.value = '2';
-      queryAgentSessionList();
-    }
-
-    // querySessionList();
-  };
 
   // 鍙戦��
   const sentClick = () => {
@@ -746,21 +711,34 @@
           event.preventDefault(); // 闃绘榛樿琛屼负锛屽嵆涓嶆崲琛�
         }
 
-        // if (!activeSessionId.value) {
-        //   Message.warning("璇烽�夋嫨浼氳瘽");
-        //   chatDis.value = false;
-        //   loading.value = false;
-        //   return;
-        // }
-
         // if (displayedText.value) {
         //   querySessionList();
         // }
 
         if (inputMsg.value) {
-          startChat(inputMsg.value);
+          if (!activeSessionId.value) {
+            //鏂板缓浼氳瘽
+            // 濡傛灉鏈変細璇漣d
+            console.log(inputMsg.value, '鏂板缓浼氳瘽鍚嶇О');
 
-          inputMsg.value = '';
+            const res = await addSessionApi({
+              dialog_id: '',
+              conversation_desc: inputMsg.value,
+            });
+            // console.log(res, "res");
+            if (res.code == 200) {
+              // console.log(res.data.conversation_id);
+              activeSessionId.value = res.data?.conversation_id;
+              startChat(inputMsg.value);
+              inputMsg.value = '';
+              // queryNewSessionDetail(res.data?.conversation_id);
+            } else {
+              Message.error('鍒涘缓浼氳瘽澶辫触锛岃閲嶈瘯');
+            }
+          } else {
+            startChat(inputMsg.value);
+            inputMsg.value = '';
+          }
         } else {
           Message.warning('娑堟伅涓嶈兘涓虹┖');
         }
@@ -771,6 +749,7 @@
   const startChat = async (valMsg) => {
     chatDis.value = true;
     loading.value = true;
+    toStop = false;
     sessionDetailList.value.push({
       content: valMsg,
       role: 'user',
@@ -798,6 +777,11 @@
       .getReader();
     currIndex.value = 0;
     while (true) {
+      if (toStop) {
+        displayedText.value = '';
+        setChatDataMeg(chatDataMeg);
+        break;
+      }
       const x = await reader?.read();
       if (x) {
         const { done, value } = x;
@@ -840,6 +824,7 @@
     loading.value = false;
     chatDis.value = false;
     isStopChat.value = true;
+    toStop = true;
     console.log('stopChat');
     console.log(displayedText.value, 'displayedText');
     console.log(sessionDetailList.value, 'sessionDetailList');
@@ -890,6 +875,7 @@
       sessionDetailList.value = data.message;
       messagenList.value = data;
       agentTitle.value = data.name;
+      from.name = data.name;
       refreshScroll(); //鍒锋柊婊氬姩鏉′綅缃�
       isStopChat.value = false;
     }
@@ -903,6 +889,7 @@
   const querySessionDetail = async (session) => {
     sectionList.value = session;
     activeSessionId.value = session.id;
+    from.name = session.name;
     const { code, data } = await getSessionDetailsApi(session.id);
     if (code === 200) {
       sessionDetailList.value = data.message;
@@ -953,14 +940,24 @@
     querySessionList();
   };
   onBeforeMount(() => {
-    // DialogList();
-    //鏂板缓浼氳瘽
-    createSession('');
+    activeSessionId.value = '';
   });
   onMounted(() => {
+    let container = document.getElementById('container');
+    container.addEventListener('click', () => {
+      fileInput.value.cancel();
+    });
     EventBus.on('newChat', () => {
       agentType.value = '1';
-      createSession('');
+      // createSession('');
+      activeSessionId.value = '';
+      sessionDetailList.value = [
+        {
+          content: '浣犲ソ锛� 鎴戞槸浣犵殑鍔╃悊锛屾湁浠�涔堝彲浠ュ府鍒颁綘鐨勫悧锛�',
+          role: 'assistant',
+        },
+      ];
+      from.name = '鏈懡鍚嶄細璇�';
     });
   });
   onBeforeUnmount(() => {
@@ -1319,4 +1316,19 @@
   :deep(.arco-upload-list-item-operation) {
     //display: none;
   }
+  .uploadFileList {
+    width: 100%;
+    max-height: 140px;
+    overflow-y: auto;
+    padding: 10px;
+    display: flex;
+    flex-wrap: wrap;
+    :deep(.arco-comment-author) {
+      width: 100px;
+      display: inline-block;
+      overflow: hidden; /* 闅愯棌瓒呭嚭鐨勫唴瀹� */
+      text-overflow: ellipsis; /* 浣跨敤鐪佺暐鍙锋潵浠f浛琚殣钘忕殑鏂囧瓧 */
+      white-space: nowrap; /* 涓嶆崲琛岋紝浣垮唴瀹瑰湪涓�琛屽唴鏄剧ず */
+    }
+  }
 </style>

--
Gitblit v1.8.0