From 13cc38755055989c86bf16fceaaf5bd3d6c5515a Mon Sep 17 00:00:00 2001
From: zhangxiao <898441624@qq.com>
Date: 星期四, 08 八月 2024 17:05:45 +0800
Subject: [PATCH] Merge branch 'master' of http://192.168.5.5:10010/r/web/flow_web

---
 src/views/dmx/IntelligentAgent/components/agentConfig.vue |   80 +---
 src/views/authority/users/index.vue                       |   83 +++-
 src/views/dmx/IntelligentAgent/index.vue                  |    8 
 src/views/dmx/knowledgeLib/config1.vue                    |  510 +++++++++++++++++++++++++++++++
 yarn.lock                                                 |    5 
 src/views/dmx/knowledgeLib/test.vue                       |   10 
 package.json                                              |    1 
 src/views/session/sessionRecordsManager/index.vue         |   63 ++-
 src/views/dmx/knowledgeLib/index.vue                      |   48 +-
 src/api/authority.ts                                      |    1 
 config/vite.config.prod.ts                                |   23 -
 src/views/dmx/knowledgeLib/config.vue                     |  110 ++----
 12 files changed, 710 insertions(+), 232 deletions(-)

diff --git a/config/vite.config.prod.ts b/config/vite.config.prod.ts
index 9083aae..79a8864 100644
--- a/config/vite.config.prod.ts
+++ b/config/vite.config.prod.ts
@@ -14,29 +14,6 @@
       configArcoResolverPlugin(),
       configImageminPlugin(),
     ],
-    server: {
-      open: true, // 椤圭洰鍚姩鍚庯紝鑷姩鎵撳紑
-      fs: {
-        strict: true,
-      },
-      proxy: {
-        '/base': {
-          target: 'http://192.168.20.116:8089',
-          changeOrigin: true,
-          ws: true,
-        },
-        '/api': {
-          target: 'http://192.168.20.116:8089',
-          changeOrigin: true,
-          ws: true,
-        },
-        '/api/v1': {
-          target: 'http://192.168.20.116:8089',
-          changeOrigin: true,
-          ws: true,
-        },
-      },
-    },
     build: {
       rollupOptions: {
         output: {
diff --git a/package.json b/package.json
index cf1fdeb..b85599f 100644
--- a/package.json
+++ b/package.json
@@ -34,6 +34,7 @@
     "axios": "^0.24.0",
     "dayjs": "^1.11.5",
     "echarts": "^5.4.0",
+    "eventsource-parser": "^2.0.1",
     "js-base64": "^3.7.5",
     "jsencrypt": "^3.3.2",
     "lodash": "^4.17.21",
diff --git a/src/api/authority.ts b/src/api/authority.ts
index 64cb6ca..f3a9039 100644
--- a/src/api/authority.ts
+++ b/src/api/authority.ts
@@ -8,6 +8,7 @@
   email: string;
   phoneNumber: string;
   dept: any;
+  deptName:string;
   resources: any;
   knowledges: any;
   dialogs: any;
diff --git a/src/views/authority/users/index.vue b/src/views/authority/users/index.vue
index 45fb9e7..1509a15 100644
--- a/src/views/authority/users/index.vue
+++ b/src/views/authority/users/index.vue
@@ -369,6 +369,7 @@
   let editform = ref<User>({
     createTime: '',
     dept: undefined,
+    deptName:"",
     email: '',
     nickName: '',
     phoneNumber: '',
@@ -499,8 +500,8 @@
       slotName: 'index',
     },
     {
-      title: t('鐢ㄦ埛鍚�'),
-      dataIndex: 'userName',
+      title: t('鐧诲綍鍚�'),
+      dataIndex: 'email',
     },
     {
       title: t('鍒涘缓鏃堕棿'),
@@ -508,8 +509,8 @@
     },
     {
       title: t('鎵�灞為儴闂�'),
-      dataIndex: 'dept',
-      slotName: 'dept',
+      dataIndex: 'deptName',
+      slotName: 'deptName',
     },
     {
       title: t('鐘舵��'),
@@ -630,7 +631,7 @@
     //鍒犻櫎
     if (t == 3) {
       await UserDelete(record.userId).then((res) => {
-        if (res.code == 20000) {
+        if (res.code == 200) {
           fetchData();
         }
       });
@@ -646,28 +647,35 @@
       checkStrictlyDialog.value = [];
       checkedKeysDialog.value = [];
       selectUser.value = record;
-      record.resources.forEach((val) => {
-        checkStrictlyMenu.value.push({
-          menuId: val.menuId,
-          menuName: val.menuName,
+      if (record.resources) {
+        record.resources.forEach((val) => {
+          checkStrictlyMenu.value.push({
+            menuId: val.menuId,
+            menuName: val.menuName
+          });
+          checkedKeysMenu.value.push(val.menuId);
+          expandKdysMenu.value.push(val.menuId);
         });
-        checkedKeysMenu.value.push(val.menuId);
-        expandKdysMenu.value.push(val.menuId);
-      });
-      record.knowledges.forEach((val) => {
-        checkStrictlyKnowledge.value.push({
-          knowledgeId: val.id,
-          knowledgeName: val.name,
+      }
+      if (record.knowledges) {
+        record.knowledges.forEach((val) => {
+          checkStrictlyKnowledge.value.push({
+            knowledgeId: val.id,
+            knowledgeName: val.name
+          });
+          checkedKeysKnowledge.value.push(val.id);
         });
-        checkedKeysKnowledge.value.push(val.id);
-      });
-      record.dialogs.forEach((val) => {
-        checkStrictlyDialog.value.push({
-          dialogId: val.id,
-          dialogName: val.name,
+      }
+      if (record.dialogs) {
+        record.dialogs.forEach((val) => {
+          checkStrictlyDialog.value.push({
+            dialogId: val.id,
+            dialogName: val.name
+          });
+          checkedKeysDialog.value.push(val.id);
         });
-        checkedKeysDialog.value.push(val.id);
-      });
+      }
+
     }
     //鏈烘瀯
     if (t == 5) {
@@ -677,14 +685,16 @@
       checkStrictly.value = [];
       selectUser.value = record;
       expandKdys.value.push('0');
-      record.dept.forEach((val) => {
-        checkStrictly.value.push({
-          deptId: val.deptId,
-          deptName: val.deptName,
+      if (record.dept) {
+        record.dept.forEach((val) => {
+          checkStrictly.value.push({
+            deptId: val.deptId,
+            deptName: val.deptName
+          });
+          checkedKeys.value.push(val.deptId);
+          expandKdys.value.push(val.deptId);
         });
-        checkedKeys.value.push(val.deptId);
-        expandKdys.value.push(val.deptId);
-      });
+      }
     }
   };
 
@@ -694,6 +704,17 @@
     setLoading(true);
     try {
       await UserList(params).then((res) => {
+        for (const user of res.rows) {
+          if (user.dept) {
+            for (const d of user.dept) {
+              if (user.deptName) {
+                user.deptName += d.deptName + ",";
+              } else {
+                user.deptName = d.deptName + ",";
+              }
+            }
+          }
+        }
         renderData.value = res.rows;
         console.log(renderData);
         pagination.current = params.current;
diff --git a/src/views/dmx/IntelligentAgent/components/agentConfig.vue b/src/views/dmx/IntelligentAgent/components/agentConfig.vue
index 9710bcc..427dcf9 100644
--- a/src/views/dmx/IntelligentAgent/components/agentConfig.vue
+++ b/src/views/dmx/IntelligentAgent/components/agentConfig.vue
@@ -48,49 +48,13 @@
                 </a-form-item>
                 <a-form-item label="鏅鸿兘浣撳浘鏍�">
                   <a-space direction="vertical" :style="{ width: '100%' }">
-                    <a-upload
-                      :auto-upload="false"
-                      :fileList="file ? [file] : []"
-                      :show-file-list="false"
-                      @change="onChange"
-                      @progress="onProgress"
-                    >
-                      <template #upload-button>
-                        <div
-                          :class="`arco-upload-list-item${
-                      file && file.status === 'error' ? ' arco-upload-list-item-error' : ''
-                    }`"
-                        >
-                          <div
-                            class="arco-upload-list-picture custom-upload-avatar"
-                            v-if="file && file.url"
-                          >
-                            <img :src="file.url" />
-                            <div class="arco-upload-list-picture-mask">
-                              <IconEdit />
-                            </div>
-                            <a-progress
-                              v-if="file.status === 'uploading' && file.percent < 100"
-                              :percent="file.percent"
-                              type="circle"
-                              size="mini"
-                              :style="{
-                          position: 'absolute',
-                          left: '50%',
-                          top: '50%',
-                          transform: 'translateX(-50%) translateY(-50%)',
-                        }"
-                            />
-                          </div>
-                          <div class="arco-upload-picture-card" v-else>
-                            <div class="arco-upload-picture-card-text">
-                              <IconPlus />
-                              <div style="margin-top: 10px; font-weight: 600">涓婁紶</div>
-                            </div>
-                          </div>
-                        </div>
-                      </template>
-                    </a-upload>
+                    <Upload
+                      :action="uploadAction"
+                      :limit="1"
+                      :url="form.icon"
+                      @update:fileList="updateFileList"
+                      @success="handleSuccess"
+                    ></Upload>
                   </a-space>
                 </a-form-item>
                 <a-form-item label="绌哄洖澶�">
@@ -370,26 +334,18 @@
   return `${(value / 100).toFixed(2)}`
 };
 
-const onChange = (_, currentFile) => {
-  file.value = currentFile;
-  convertImageToBase64(file.value.file).then((result) => {
-    form.icon = result;
-  });
+const uploadAction = '/api/v1/llm/upload'; // 鏇挎崲涓轰綘鐨勪笂浼燗PI
+const fileList = ref([]);
+const imageUrls = ref([]);
+
+const updateFileList = (newFileList) => {
+  fileList.value = newFileList;
+  console.log(newFileList, 88);
 };
 
-function convertImageToBase64(file) {
-  return new Promise((resolve, reject) => {
-    const reader = new FileReader();
-    reader.onloadend = function() {
-      resolve(reader.result);
-    };
-    reader.onerror = reject;
-    reader.readAsDataURL(file);
-  });
-}
-
-const onProgress = (currentFile) => {
-  file.value = currentFile;
+const handleSuccess = (urls) => {
+  imageUrls.value = urls; // 鎷垮埌涓婁紶鐨勫浘鐗囧湴鍧�
+  form.icon = urls[0];
 };
 
 const rules = {
@@ -517,7 +473,7 @@
   nextTick(()=>{
     // console.log(props.formData,'浼犲叆鏁版嵁');
     Object.assign(form, props.formData);
-    // console.log(form,'琛ㄥ崟鏁版嵁');
+    console.log(form,'琛ㄥ崟鏁版嵁');
   })
 };
 
diff --git a/src/views/dmx/IntelligentAgent/index.vue b/src/views/dmx/IntelligentAgent/index.vue
index 4357e17..f775fb0 100644
--- a/src/views/dmx/IntelligentAgent/index.vue
+++ b/src/views/dmx/IntelligentAgent/index.vue
@@ -15,7 +15,7 @@
           <a-divider style="margin: 10px 0" />
           <a-row justify="space-between">
             <a-col :span="24">
-              <div style="display: flex; flex-wrap: wrap">
+              <a-spin :loading="loading" style="display: flex; flex-wrap: wrap" :style="{height: documentHeight + 'px'}">
 <!--                <div-->
 <!--                  class="card-wrap"-->
 <!--                  style="cursor: pointer"-->
@@ -56,7 +56,7 @@
                   :key="item.id"
                 >
                   <a-card :bordered="false" hoverable>
-                    <a-avatar :style="{ backgroundColor: '#3370ff' }">
+                    <a-avatar :style="{ backgroundColor: '#5b99da' }">
                       <img
                         :style="{ width: '100%' }"
                         alt="dessert"
@@ -113,7 +113,7 @@
                     </div>
                   </a-card>
                 </div>
-              </div>
+              </a-spin>
             </a-col>
           </a-row>
         </a-card>
@@ -130,7 +130,7 @@
   const { loading, setLoading } = useLoading(true);
   import EventBus from '@/utils/EventBus';
   import AgentConfig from "@/views/dmx/IntelligentAgent/components/agentConfig.vue";
-
+  let documentHeight = window.innerHeight - 360
   let count = 5;
   const activeKey = ref(1);
   const addAgents = ref();
diff --git a/src/views/dmx/knowledgeLib/config.vue b/src/views/dmx/knowledgeLib/config.vue
index fe9a7ca..2ef615a 100644
--- a/src/views/dmx/knowledgeLib/config.vue
+++ b/src/views/dmx/knowledgeLib/config.vue
@@ -14,49 +14,14 @@
           </a-form-item>
           <a-form-item field="section" label="鐭ヨ瘑搴撳浘鐗�">
             <a-space direction="vertical" :style="{ width: '100%' }">
-              <a-upload
-                :auto-upload="false"
-                :fileList="file ? [file] : []"
-                :show-file-list="false"
-                @change="onChange"
-                @progress="onProgress"
-              >
-                <template #upload-button>
-                  <div
-                    :class="`arco-upload-list-item${
-                      file && file.status === 'error' ? ' arco-upload-list-item-error' : ''
-                    }`"
-                  >
-                    <div
-                      class="arco-upload-list-picture custom-upload-avatar"
-                      v-if="file && file.url"
-                    >
-                      <img :src="form.avatar" />
-                      <div class="arco-upload-list-picture-mask">
-                        <IconEdit />
-                      </div>
-                      <a-progress
-                        v-if="file.status === 'uploading' && file.percent < 100"
-                        :percent="file.percent"
-                        type="circle"
-                        size="mini"
-                        :style="{
-                          position: 'absolute',
-                          left: '50%',
-                          top: '50%',
-                          transform: 'translateX(-50%) translateY(-50%)',
-                        }"
-                      />
-                    </div>
-                    <div class="arco-upload-picture-card" v-else>
-                      <div class="arco-upload-picture-card-text">
-                        <IconPlus />
-                        <div style="margin-top: 10px; font-weight: 600">涓婁紶</div>
-                      </div>
-                    </div>
-                  </div>
-                </template>
-              </a-upload>
+              <Upload
+                v-if="avatarShow"
+                :action="uploadAction"
+                :limit="1"
+                :url="form.avatar"
+                @update:fileList="updateFileList"
+                @success="handleSuccess"
+              ></Upload>
             </a-space>
           </a-form-item>
           <a-form-item field="section" label="鎻忚堪">
@@ -131,7 +96,7 @@
             <div style="width: 100%;text-align: right">
               <a-space>
                 <a-button @click="cancelConfig">鍙栨秷</a-button>
-                <a-button type="primary" html-type="submit">淇濆瓨</a-button>
+                <a-button :loading="loading" type="primary" html-type="submit">淇濆瓨</a-button>
               </a-space>
             </div>
           </a-form-item>
@@ -208,10 +173,11 @@
 });
 
 let kbObj = reactive({});
+let avatarShow = ref(true);
 
 const form = reactive({
-  name: kbObj.name,
-  avatar: '',//
+  name: '',
+  avatar: '',//澶村儚
   max_token: 600,
   threshold: 0.32,
   max_cluster: 233,
@@ -226,7 +192,7 @@
   language: "English",
   permission: "",
   embd_id: "BAAI/bge-large-zh-v1.5",
-  parser_id: kbObj.parser_id,
+  parser_id: '',
   layout_recognize: true
 });
 
@@ -261,26 +227,18 @@
 const modelList = ref({});
 const file = ref();
 
-const onChange = (_, currentFile) => {
-  file.value = currentFile;
-  convertImageToBase64(file.value.file).then((result)=>{
-    form.avatar = result;
-  })
+const uploadAction = '/api/v1/llm/upload'; // 鏇挎崲涓轰綘鐨勪笂浼燗PI
+const fileList = ref([]);
+const imageUrls = ref([]);
+
+const updateFileList = (newFileList) => {
+  fileList.value = newFileList;
+  console.log(newFileList, 88);
 };
 
-function convertImageToBase64(file) {
-  return new Promise((resolve, reject) => {
-    const reader = new FileReader();
-    reader.onloadend = function() {
-      resolve(reader.result);
-    };
-    reader.onerror = reject;
-    reader.readAsDataURL(file);
-  });
-}
-
-const onProgress = (currentFile) => {
-  file.value = currentFile;
+const handleSuccess = (urls) => {
+  imageUrls.value = urls; // 鎷垮埌涓婁紶鐨勫浘鐗囧湴鍧�
+  form.avatar = urls[0];
 };
 
 
@@ -313,7 +271,7 @@
      };
    }
    try {
-    
+     setLoading(true)
     const data = await kbUpdate(parms);
     if(data.code == '0'){
       Message.success("閰嶇疆鎴愬姛");
@@ -321,10 +279,11 @@
       emit('saveConfig')
 
     }
-    // emit('upTabdateItem')
+    setLoading(false)
 
   } catch (err) {
     Message.error(err.message);
+     setLoading(false)
   }
 
 
@@ -377,15 +336,11 @@
   formRef.value.resetFields();
   kbObj = value;
   console.log(kbObj, 'kbObj');
-  if(kbObj.avatar){
-    file.value.url = kbObj.avatar
-  }else{
-    // file.value.url = '';
-  }
   let configObj = {
     name: kbObj.name,
     avatar: kbObj.avatar,
     pages:  kbObj.parser_config.pages,
+    chunk_token_num:  kbObj.parser_config.chunk_token_num,
     description: kbObj.description,
     language: "English",
     permission: kbObj.permission,
@@ -402,9 +357,17 @@
       use_raptor: kbObj.parser_config.raptor.use_raptor,
     });
   }else{
-    Object.assign(form,configObj);
+    Object.assign(form,{
+      ...configObj,
+      use_raptor: false,
+    });
   }
+  imageUrls.value = [kbObj.avatar];
   console.log(form,'閰嶇疆椤甸潰琛ㄥ崟淇℃伅');
+  avatarShow.value = false;
+  setTimeout(() => {
+    avatarShow.value = true;
+  },100);
 }
 
 defineExpose({
@@ -413,6 +376,7 @@
 
 
 onBeforeMount(()=>{
+  setLoading(false)
   queryModel({})
 })
 onMounted(()=>{
diff --git a/src/views/dmx/knowledgeLib/config1.vue b/src/views/dmx/knowledgeLib/config1.vue
new file mode 100644
index 0000000..fe9a7ca
--- /dev/null
+++ b/src/views/dmx/knowledgeLib/config1.vue
@@ -0,0 +1,510 @@
+<template>
+  <div class="main-container">
+    <div style="position: absolute;top: 0;left: 0;width: 100%;padding: 0 20px">
+      <h4 style="margin-bottom: 10px"></h4>
+      <div style="color: #666666;">鍦ㄨ繖閲屾洿鏂版偍鐨勭煡璇嗗簱璇︾粏淇℃伅锛屽挨鍏舵槸瑙f瀽鏂规硶銆�</div>
+      <a-divider style="margin-top: 20px" />
+    </div>
+    <div class="main-container-lf">
+      <div class="main-container-lf-down">
+        <a-form ref="formRef" :rules="rules" :model="form" :style="{width:'100%'}" layout="vertical"
+                @submit="handleSubmit">
+          <a-form-item field="name" label="鐭ヨ瘑搴撳悕绉�">
+            <a-input v-model="form.name" placeholder="璇疯緭鍏�" />
+          </a-form-item>
+          <a-form-item field="section" label="鐭ヨ瘑搴撳浘鐗�">
+            <a-space direction="vertical" :style="{ width: '100%' }">
+              <a-upload
+                :auto-upload="false"
+                :fileList="file ? [file] : []"
+                :show-file-list="false"
+                @change="onChange"
+                @progress="onProgress"
+              >
+                <template #upload-button>
+                  <div
+                    :class="`arco-upload-list-item${
+                      file && file.status === 'error' ? ' arco-upload-list-item-error' : ''
+                    }`"
+                  >
+                    <div
+                      class="arco-upload-list-picture custom-upload-avatar"
+                      v-if="file && file.url"
+                    >
+                      <img :src="form.avatar" />
+                      <div class="arco-upload-list-picture-mask">
+                        <IconEdit />
+                      </div>
+                      <a-progress
+                        v-if="file.status === 'uploading' && file.percent < 100"
+                        :percent="file.percent"
+                        type="circle"
+                        size="mini"
+                        :style="{
+                          position: 'absolute',
+                          left: '50%',
+                          top: '50%',
+                          transform: 'translateX(-50%) translateY(-50%)',
+                        }"
+                      />
+                    </div>
+                    <div class="arco-upload-picture-card" v-else>
+                      <div class="arco-upload-picture-card-text">
+                        <IconPlus />
+                        <div style="margin-top: 10px; font-weight: 600">涓婁紶</div>
+                      </div>
+                    </div>
+                  </div>
+                </template>
+              </a-upload>
+            </a-space>
+          </a-form-item>
+          <a-form-item field="section" label="鎻忚堪">
+            <a-textarea placeholder=""  v-model="form.description" allow-clear />
+          </a-form-item>
+<!--          <a-form-item field="section" label="璇█" :rules="[{match:/section one/,message:'璇烽�夋嫨'}]">-->
+<!--            <a-select v-model="form.section" placeholder="璇烽�夋嫨" allow-clear>-->
+<!--              <a-option value="0">涓枃</a-option>-->
+<!--              <a-option value="1">鑻辨枃</a-option>-->
+<!--            </a-select>-->
+<!--          </a-form-item>-->
+          <a-form-item field="embd_id" label="宓屽叆妯″瀷">
+            <a-space direction="vertical" size="large">
+              <a-select :size="'large'" v-model="form.embd_id" :style="{width:'100%'}" placeholder="璇烽�夋嫨 ..." :disabled="kbObj.chunk_num==0 && kbObj.token_num==0" allow-clear>
+                <a-optgroup  :label="index" v-for="(item,index) in modelList" :key=index>
+                  <a-option
+                    v-for="(obj) in item"
+                    :key='obj.fid'
+                    :value="obj.llm_name"
+                  >
+                    {{obj.llm_name}}
+                  </a-option>
+                </a-optgroup>
+              </a-select>
+            </a-space>
+          </a-form-item>
+          <a-form-item field="parser_id" label="瑙f瀽鏂规硶">
+            <a-select v-model="form.parser_id" placeholder="璇烽�夋嫨" :disabled="kbObj.chunk_num==0 && kbObj.token_num==0" allow-clear>
+              <a-option v-for="item in parser_ids" :key="item.value" :label="item.name" :value="item.value"></a-option>
+            </a-select>
+          </a-form-item>
+          <a-form-item field="slider" label="鍧桾oken鏁�">
+            <a-slider v-model="form.chunk_token_num" :min="0" :max="2048"  show-input />
+          </a-form-item>
+          <a-form-item  label="甯冨眬璇嗗埆" >
+            <a-space direction="vertical">
+              <a-switch v-model="form.layout_recognize" size="small" />
+            </a-space>
+          </a-form-item>
+          <a-form-item field="raptor" label="浣跨敤鍙洖澧炲己RAPTOR绛栫暐">
+            <a-space direction="vertical" >
+              <a-switch v-model="form.use_raptor" size="small" />
+            </a-space>
+          </a-form-item>
+          <div v-if="form.use_raptor">
+            <a-form-item field="prompt" label="鎻愮ず璇�">
+              <a-textarea
+                v-model="form.prompt"
+                style="height: 10rem;border: 1px solid  var(--color-fill-3);border-radius: 4px" placeholder="璇峰~鍐欐彁绀鸿瘝"  />
+            </a-form-item>
+            <a-form-item field="slider" label="鏈�澶oken鏁�">
+              <a-slider v-model="form.max_token" :min="0" :max="2048" show-input/>
+            </a-form-item>
+            <a-form-item field="slider" label="闃堝��" >
+              <a-slider v-model="form.threshold"  :step="0.01" :min="0" :max="1"  show-input/>
+            </a-form-item>
+            <a-form-item field="slider" label="鏈�澶ц仛绫绘暟">
+              <a-slider v-model="form.max_cluster" :min="1" :max="1024" show-input/>
+            </a-form-item>
+            <a-form-item field="slider" label="闅忔満绉嶅瓙" v-model="form.random_seed">
+              <a-input-number v-model="form.random_seed" :style="{width:'300px',marginRight:'1rem',borderRadius:'4px'}"
+                              placeholder="璇疯緭鍏�" class="input-demo" :min="10" :max="100" />
+              <a-button type="primary" @click="randomNumber">
+                <icon-plus />
+              </a-button>
+            </a-form-item>
+
+          </div>
+
+
+          <a-form-item>
+            <div style="width: 100%;text-align: right">
+              <a-space>
+                <a-button @click="cancelConfig">鍙栨秷</a-button>
+                <a-button type="primary" html-type="submit">淇濆瓨</a-button>
+              </a-space>
+            </div>
+          </a-form-item>
+        </a-form>
+      </div>
+    </div>
+    <div class="main-container-rt">
+      <section data-inspector-line="34" data-inspector-column="4"
+               data-inspector-relative-path="src\pages\add-knowledge\components\knowledge-setting\category-panel.tsx"
+               class="categoryPanelWrapper___yI4rY"><h4
+        class="ant-typography topTitle___tNiB9 css-dev-only-do-not-override-1wxecgq" data-inspector-line="37"
+        data-inspector-column="10"
+        data-inspector-relative-path="src\pages\add-knowledge\components\knowledge-setting\category-panel.tsx">"General"
+        鍒嗗潡鏂规硶璇存槑</h4>
+        <p data-inspector-line="40" data-inspector-column="10"
+           data-inspector-relative-path="src\pages\add-knowledge\components\knowledge-setting\category-panel.tsx"><p>
+          鏀寔鐨勬枃浠舵牸寮忎负<b>DOCX銆丒XCEL銆丳PT銆両MAGE銆丳DF銆乀XT</b>銆�</p>
+          <p>姝ゆ柟娉曞皢绠�鍗曠殑鏂规硶搴旂敤浜庡潡鏂囦欢锛�</p>
+          <p>
+          </p>
+          <li>绯荤粺灏嗕娇鐢ㄨ瑙夋娴嬫ā鍨嬪皢杩炵画鏂囨湰鍒嗗壊鎴愬涓墖娈点��</li>
+          <li>鎺ヤ笅鏉ワ紝杩欎簺杩炵画鐨勭墖娈佃鍚堝苟鎴怲oken鏁颁笉瓒呰繃鈥淭oken鏁扳�濈殑鍧椼��</li>
+          <p></p></p>
+        <h4 class="ant-typography css-dev-only-do-not-override-1wxecgq" data-inspector-line="45"
+            data-inspector-column="10"
+            data-inspector-relative-path="src\pages\add-knowledge\components\knowledge-setting\category-panel.tsx">
+          "General" 绀轰緥</h4><span class="ant-typography css-dev-only-do-not-override-1wxecgq" data-inspector-line="48"
+                                   data-inspector-column="10"
+                                   data-inspector-relative-path="src\pages\add-knowledge\components\knowledge-setting\category-panel.tsx">鎻愬嚭浠ヤ笅灞忓箷鎴浘浠ヤ績杩涚悊瑙c��</span>
+        <div data-inspector-line="49" data-inspector-column="10"
+             data-inspector-relative-path="src\pages\add-knowledge\components\knowledge-setting\category-panel.tsx"
+             class="ant-row imageRow___C3Xpb css-dev-only-do-not-override-1wxecgq"
+             style="margin-left: -5px; margin-right: -5px; row-gap: 10px;display: flex; margin-top: 20px;width: 100%">
+          <img
+            data-inspector-line="32" data-inspector-column="8"
+            data-inspector-relative-path="src\components\svg-icon.tsx" src="../../../assets/images/step1.png" alt=""
+            width="50%">
+          <img
+            data-inspector-line="32" data-inspector-column="8"
+            data-inspector-relative-path="src\components\svg-icon.tsx" src="../../../assets/images/step2.png" alt=""
+            width="50%">
+        </div>
+        <h4 class="ant-typography css-dev-only-do-not-override-1wxecgq" data-inspector-line="60"
+            data-inspector-column="10"
+            data-inspector-relative-path="src\pages\add-knowledge\components\knowledge-setting\category-panel.tsx">
+          General 瀵硅瘽绀轰緥</h4>
+        <div class="ant-divider css-dev-only-do-not-override-1wxecgq ant-divider-horizontal" data-inspector-line="63"
+             data-inspector-column="10"
+             data-inspector-relative-path="src\pages\add-knowledge\components\knowledge-setting\category-panel.tsx"
+             role="separator"></div>
+        <a-divider style="margin-top: 20px" />
+      </section>
+    </div>
+  </div>
+</template>
+
+<script lang="ts" setup>
+import { onMounted, onBeforeMount, reactive, ref } from "vue";
+import { Message } from "@arco-design/web-vue";
+import { queryModelList,kbUpdate } from "@/api/kbList";
+import message from "@arco-design/web-vue/es/message";
+import useLoading from "@/hooks/loading";
+const { loading,setLoading } = useLoading(true);
+
+const props =  defineProps(['kbtenantInfo'])
+const emit =  defineEmits(['cancleConfig','saveConfig'])
+// 瑙f瀽鏂规硶鍒楄〃
+let parser_ids = props.kbtenantInfo.parser_ids.split(",").map((item) => {
+  const [value1, value2] = item.split(":");
+  return {
+    name: value2,
+    value: value1
+  };
+});
+
+let kbObj = reactive({});
+
+const form = reactive({
+  name: kbObj.name,
+  avatar: '',//
+  max_token: 600,
+  threshold: 0.32,
+  max_cluster: 233,
+  random_seed: 1500,
+  chunk_token_num: 384,
+  use_raptor: false,
+  pages: {},
+  prompt: "璇锋�荤粨浠ヤ笅娈佃惤銆� 灏忓績鏁板瓧锛屼笉瑕佺紪閫犮�� 娈佃惤濡備笅锛歕n" +
+    "      {cluster_content}\n" +
+    "浠ヤ笂灏辨槸浣犻渶瑕佹�荤粨鐨勫唴瀹广��",
+  description: "",
+  language: "English",
+  permission: "",
+  embd_id: "BAAI/bge-large-zh-v1.5",
+  parser_id: kbObj.parser_id,
+  layout_recognize: true
+});
+
+const rules = {
+  name: [
+    {
+      required: true,
+      message:'鐭ヨ瘑搴撳悕绉颁笉鍏佽涓虹┖',
+    },
+  ],
+  embd_id: [
+    {
+      required: true,
+      message:'璇烽�夋嫨',
+    },
+  ],
+  parser_id: [
+    {
+      required: true,
+      message:'璇烽�夋嫨',
+    },
+  ],
+  prompt: [
+    {
+      required: true,
+      message:'鎻愮ず璇嶄笉鍏佽涓虹┖',
+    },
+  ],
+}
+let visible = ref(false);
+const formRef = ref(null);
+const modelList = ref({});
+const file = ref();
+
+const onChange = (_, currentFile) => {
+  file.value = currentFile;
+  convertImageToBase64(file.value.file).then((result)=>{
+    form.avatar = result;
+  })
+};
+
+function convertImageToBase64(file) {
+  return new Promise((resolve, reject) => {
+    const reader = new FileReader();
+    reader.onloadend = function() {
+      resolve(reader.result);
+    };
+    reader.onerror = reject;
+    reader.readAsDataURL(file);
+  });
+}
+
+const onProgress = (currentFile) => {
+  file.value = currentFile;
+};
+
+
+const handleSubmit = async ({ values, errors }) => {
+  if (errors){
+    return;
+  }
+  let parms = {
+      name: form.name,
+      avatar: form.avatar,
+      description: form.description,
+      language: form.language,
+      permission: form.permission,
+      embd_id: form.embd_id,
+      parser_id: form.parser_id,
+      parser_config: {
+        chunk_token_num: form.chunk_token_num,
+        layout_recognize: form.layout_recognize,
+      },
+      kb_id: kbObj.id,
+   }
+   if(form.use_raptor){
+     parms.parser_config.raptor = {
+       use_raptor: form.use_raptor,
+       prompt: form.prompt,
+       max_token: form.max_token,
+       threshold: form.threshold,
+       max_cluster: form.max_cluster,
+       random_seed: form.random_seed,
+     };
+   }
+   try {
+    
+    const data = await kbUpdate(parms);
+    if(data.code == '0'){
+      Message.success("閰嶇疆鎴愬姛");
+      // window.location.reload();
+      emit('saveConfig')
+
+    }
+    // emit('upTabdateItem')
+
+  } catch (err) {
+    Message.error(err.message);
+  }
+
+
+
+};
+
+const cancelConfig = () => {
+    emit('cancleConfig')
+}
+
+
+function randomNumber() {
+  // 鐢熸垚涓�涓粙浜巑in鍜宮ax涔嬮棿鐨勯殢鏈烘暣鏁帮紙鍖呭惈min鍜宮ax锛�
+  const min = 1; // 鏈�灏忓��
+  const max = 10000; // 鏈�澶у��
+  form.random_seed = Math.floor(Math.random() * (max - min + 1)) + min;
+}
+
+const handleBeforeOk = (done) => {
+  formRef.value.validate().then(res => {
+    console.log("form:", form);
+    if (!form.name) {
+      done(false);
+    } else {
+      console.log("璇锋眰鏁版嵁");
+
+    }
+  });
+};
+const handleOpened =(el) => {
+  Object.assign(form,{
+
+  });
+  formRef.value.resetFields();
+}
+
+const queryModel = async (params) => {
+  try {
+    const data = await queryModelList(params);
+    // console.log(data.data, '澶фā鍨嬪垪琛�');
+    modelList.value = data.data
+  } catch (err) {
+    // you can report use errorHandler or other
+  } finally {
+
+  }
+};
+
+const changekbObj = (value) => {
+  formRef.value.resetFields();
+  kbObj = value;
+  console.log(kbObj, 'kbObj');
+  if(kbObj.avatar){
+    file.value.url = kbObj.avatar
+  }else{
+    // file.value.url = '';
+  }
+  let configObj = {
+    name: kbObj.name,
+    avatar: kbObj.avatar,
+    pages:  kbObj.parser_config.pages,
+    description: kbObj.description,
+    language: "English",
+    permission: kbObj.permission,
+    embd_id: props.kbtenantInfo.embd_id || kbObj.embd_id,
+    parser_id: kbObj.parser_id,
+    layout_recognize: true,
+  }
+  let raptor = {}
+  if(kbObj.parser_config && kbObj.parser_config.raptor){
+    raptor = kbObj.parser_config.raptor;
+    Object.assign(form,{
+      ...configObj,
+      ...raptor,
+      use_raptor: kbObj.parser_config.raptor.use_raptor,
+    });
+  }else{
+    Object.assign(form,configObj);
+  }
+  console.log(form,'閰嶇疆椤甸潰琛ㄥ崟淇℃伅');
+}
+
+defineExpose({
+  changekbObj
+})
+
+
+onBeforeMount(()=>{
+  queryModel({})
+})
+onMounted(()=>{
+
+
+})
+
+</script>
+
+<script lang="ts">
+import { IconEdit, IconPlus } from "@arco-design/web-vue/es/icon";
+
+export default {
+  name: "config",
+  components: { IconPlus, IconEdit },
+  methods: {}
+};
+</script>
+<style scoped lang="less">
+.main-container {
+  position: relative;
+  display: flex;
+  justify-content: space-between;
+  height: 100%;
+  overflow: auto;
+  //background: #626aea;
+  background: var(--color-bg-2);
+  padding-top: 80px;
+
+  &-lf {
+    width: 40%;
+    //height: 100%;
+    //border: 1px solid #cccccc;
+    border-radius: 10px;
+    //border: 1px solid var(--color-fill-3);
+    &-top {
+      width: 100%;
+      height: 60px;
+      line-height: 60px;
+      //background: rgb(var(--primary-6));
+      //color: #ffffff;
+      //text-align: center;
+    }
+
+    &-down {
+      padding: 20px;
+      width: 100%;
+    }
+  }
+
+  &-form-item-extra {
+    width: 100%;
+    height: 20rem;
+    border: 1px solid var(--color-fill-3);
+    border-radius: 6px;
+    overflow: hidden;
+
+    &-top {
+      width: 100%;
+      height: 40px;
+      line-height: 40px;
+      border-bottom: 1px solid var(--color-fill-3);
+      //background: rgb(var(--primary-6));
+      color: #999999;
+      text-align: center;
+    }
+
+    &-down {
+      width: 92%;
+      margin-left: 4%;
+      margin-top: 30px;
+    }
+
+    &-btn {
+      width: 96%;
+      text-align: right;
+      margin-top: 1rem;
+    }
+  }
+
+  &-rt {
+    width: 60%;
+    //background: #626aea;
+    //border: 1px solid #cccccc;
+    border-radius: 10px;
+    overflow: hidden;
+    padding: 20px;
+    section {
+      width: 100%;
+      //color: #333333;
+      color: var(--color-text-1);
+    }
+  }
+}
+</style>
\ No newline at end of file
diff --git a/src/views/dmx/knowledgeLib/index.vue b/src/views/dmx/knowledgeLib/index.vue
index c5f134d..953c249 100644
--- a/src/views/dmx/knowledgeLib/index.vue
+++ b/src/views/dmx/knowledgeLib/index.vue
@@ -10,7 +10,7 @@
           />
           <addKnow @getknowledge="getknowledge" @getKbdetail="getKbdetail"></addKnow>
         </div>
-        <div class="lf-container-down">
+        <a-spin :loading="listloading" class="lf-container-down">
           <a-scrollbar style="height:56rem;overflow: auto;">
             <div
               class="tab"
@@ -23,15 +23,15 @@
               <a-popover position="bl">
                 <icon-more  :style="{position: 'absolute',top:'10px',right:'20px'}"/>
                 <template #content>
-                  <a-popconfirm content="纭畾鍒犻櫎鍚�?" @ok="deleteKnowledge(tab.id)" type="warning">
-                    <span style="cursor: pointer;color: #4977ba;font-size: 12px"><icon-delete style="font-size: 14px"/>鍒犻櫎</span>
-                  </a-popconfirm>
-<!--                  <span style="cursor: pointer;color: #0960bd;font-size: 12px" @click="deleteKnowledge(tab.id)"><icon-delete />鍒犻櫎</span>-->
+<!--                  <a-popconfirm content="纭畾鍒犻櫎鍚�?" @ok="deleteKnowledge(tab.id)" type="warning">-->
+<!--                    <span style="cursor: pointer;color: #4977ba;font-size: 12px"><icon-delete style="font-size: 14px"/>鍒犻櫎</span>-->
+<!--                  </a-popconfirm>-->
+                  <span style="cursor: pointer;color: #4977ba;font-size: 12px" @click="deleteKnowledge(tab.id)"><icon-delete style="font-size: 14px" />鍒犻櫎</span>
                 </template>
               </a-popover>
             </div>
           </a-scrollbar>
-          </div>
+          </a-spin>
       </div>
       <div class="rt-container" v-if="tabs.length > 0">
         <a-tabs :activeKey="activeKey" @change="handleTabChange">
@@ -257,7 +257,7 @@
           </a-tab-pane>
           <a-tab-pane key="3" :title="t('dmx.list.disposition')">
             <div class="rt-container-main">
-              <config ref="configForm" :kbtenantInfo="kbtenantInfo"  :kbobj="kbobj"  @cancleConfig="cancleConfig" @saveConfig="saveConfig"></config>
+              <config ref="configForm" :kbtenantInfo="kbtenantInfo" @cancleConfig="cancleConfig" @saveConfig="saveConfig"></config>
             </div>
           </a-tab-pane>
         </a-tabs>
@@ -335,8 +335,9 @@
   import docx from '@/views/dmx/knowledgeLib/components/docx.vue'
   import excel from '@/views/dmx/knowledgeLib/components/excel.vue'
   import txtPdf from '@/views/dmx/knowledgeLib/components/txtPdf.vue'
-  import { Message } from "@arco-design/web-vue";
+import { Message, Modal } from "@arco-design/web-vue";
   import { parseTime } from "@/utils";
+import { deleteLlm } from "@/api/model";
   type SizeProps = 'mini' | 'small' | 'medium' | 'large';
   type Column = TableColumnData & { checked?: true };
   const account = ref(null)
@@ -359,6 +360,7 @@
 
   const size = ref<SizeProps>('medium');
   let visible = ref(false)
+  let listloading = ref(false)
   let keywords = ref('')
   let activeKey = ref('1')
   let detailsShow = ref(false)
@@ -550,7 +552,7 @@
   const knowledgeData = async (
     params = { page: 1, page_size: 20 }
   ) => {
-    setLoading(true);
+    listloading.value = true;
     try {
       const { data } = await queryKbList(params);
       // console.log(data, 'data');
@@ -576,7 +578,7 @@
     } catch (err) {
       // you can report use errorHandler or other
     } finally {
-      setLoading(false);
+      listloading.value = false;
     }
   };
 
@@ -619,14 +621,24 @@
   }
 };
 
-  const deleteKnowledge = async (id) => {
-    let data = await deleteKnow({
-      kb_id:id
-    })
-    if(data.code == 0){
-      Message.success('鍒犻櫎鎴愬姛');
-      knowledgeData()
-    }
+  const deleteKnowledge = (id) => {
+    Modal.confirm({
+      title: '鎻愮ず淇℃伅',
+      content: '纭鍒犻櫎鍚�',
+      okText: '纭畾',
+      cancelText: '鍙栨秷',
+      hideTitle: true,
+      onOk: async () => {
+        let data = await deleteKnow({
+          kb_id:id
+        })
+        if(data.code == 0){
+          Message.success('鍒犻櫎鎴愬姛');
+          knowledgeData()
+        }
+      },
+      onCancel: () => {},
+    });
   }
   const reset = () => {
     formModel.value = generateFormModel();
diff --git a/src/views/dmx/knowledgeLib/test.vue b/src/views/dmx/knowledgeLib/test.vue
index 75ce0af..b340e87 100644
--- a/src/views/dmx/knowledgeLib/test.vue
+++ b/src/views/dmx/knowledgeLib/test.vue
@@ -39,7 +39,7 @@
                   <a-textarea v-model="form.question" style="height: 10rem;border: 1px solid  var(--color-fill-3);border-radius: 4px" placeholder="" allow-clear/>
                 </div>
                 <div class="main-container-form-item-extra-btn">
-                  <a-button :disabled="!form.question" type="primary" html-type="submit">娴嬭瘯</a-button>
+                  <a-button :disabled="!form.question" :loading="loading" type="primary" html-type="submit">娴嬭瘯</a-button>
                 </div>
               </div>
             </a-form-item>
@@ -110,9 +110,17 @@
     delete formObj.rerank_id;
   }
   try {
+    loading.value = true;
     const data = await kbretrievalTest(formObj);
+    if(data.code == 0){
+      Message.success('娴嬭瘯鎴愬姛');
+    }else{
+      Message.error('娴嬭瘯澶辫触');
+    }
+    loading.value = false;
   }catch (err){
     Message.error(err.message);
+    loading.value = false;
   }
 
 }
diff --git a/src/views/session/sessionRecordsManager/index.vue b/src/views/session/sessionRecordsManager/index.vue
index d64b2df..4b22809 100644
--- a/src/views/session/sessionRecordsManager/index.vue
+++ b/src/views/session/sessionRecordsManager/index.vue
@@ -306,6 +306,7 @@
   import { useAppStore } from '@/store';
   import { computed, nextTick, onMounted, reactive, ref } from 'vue';
   import { Message } from '@arco-design/web-vue';
+  import { EventSourceParserStream } from 'eventsource-parser/stream';
   import moment from 'moment';
   import AddSession from '@/views/session/sessionManager/components/addSession.vue';
   import {
@@ -314,6 +315,8 @@
     getSessionDetailsApi,
     sessionListApi,
   } from '@/api/session';
+  import { getAuthorization } from "@/utils/auth";
+
 
   const sessionDetailList = ref([]); //鏍规嵁浼氳瘽id鍑烘潵鐨勪細璇濊鎯�
   const sessionList = ref([]); //浼氳瘽鍒楄〃
@@ -353,30 +356,49 @@
       return;
     }
     if (inputMsg.value) {
-      const data = await chatApi({
-        conversation_id: activeSessionId.value,
-        messages: inputMsg.value,
+      sessionDetailList.value.push({ "content": inputMsg.value, "role": "user" });
+      sessionDetailList.value.push({  "role": "last" });
+      refreshScroll();
+      const response = await fetch("/api/tech/cloudminds/query?modeltype=localragflow", {
+        method: 'POST',
+        headers: {
+          'Authorization': getAuthorization(),
+          'Content-Type': 'application/json',
+        },
+        body: JSON.stringify({
+          conversation_id: activeSessionId.value,
+          messages: inputMsg.value,
+        }),
       });
-      if (data) {
-        chatDis.value = false;
 
-        // inputMsg.value = '';
-        // querySessionDetail({ id: activeSessionId.value });
-      }
-      const res = await getSessionDetailsApi(activeSessionId.value);
-      if (res.code === 200) {
-        sessionDetailList.value = res.data.message.map((item, index) => {
-          if (index === res.data.message.length - 1) {
-            item.role = 'last';
-            displayedText.value = '';
-            currIndex.value = 0;
-            streamStr.value = item.content;
-            startDisplayStr();
+      const reader = response?.body
+        ?.pipeThrough(new TextDecoderStream())
+        .pipeThrough(new EventSourceParserStream())
+        .getReader();
+      currIndex.value = 0;
+      while (true) {
+        const x = await reader?.read();
+        if (x) {
+          const { done, value } = x;
+          try {
+            const val = JSON.parse(value?.data || '');
+            const d = val?.data;
+            if (typeof d !== "boolean") {
+
+              console.info("data:", d);
+              streamStr.value = d.content;
+              startDisplayStr();
+            }
+          } catch (e) {
+            console.warn(e);
           }
-          return item;
-        });
-        refreshScroll();
+          if (done) {
+            console.info('done');
+            break;
+          }
+        }
       }
+      chatDis.value=false;
       inputMsg.value = '';
     } else {
       Message.warning('娑堟伅涓嶈兘涓虹┖');
@@ -428,6 +450,7 @@
       displayedText.value += res[currIndex.value];
       currIndex.value++;
       setTimeout(startDisplayStr, 100);
+      refreshScroll();
     } else {
       clearTimeout(timer!);
       timer = null;
diff --git a/yarn.lock b/yarn.lock
index 7ee4e52..6cb148f 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -3253,6 +3253,11 @@
   resolved "https://registry.npmmirror.com/eventemitter3/-/eventemitter3-5.0.1.tgz"
   integrity sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==
 
+eventsource-parser@^2.0.1:
+  version "2.0.1"
+  resolved "https://registry.npmmirror.com/eventsource-parser/-/eventsource-parser-2.0.1.tgz#6464341d64de5bea9f31d8063dd312b616146c7a"
+  integrity sha512-gMaRLm5zejEH9mNXC54AnIteFI9YwL/q5JKMdBnoG+lEI1JWVGFVk0Taaj9Xb5SKgzIBDZoQX5IzMe44ILWODg==
+
 exec-buffer@^3.0.0:
   version "3.2.0"
   resolved "https://registry.npmmirror.com/exec-buffer/-/exec-buffer-3.2.0.tgz"

--
Gitblit v1.8.0