浏览代码

修改bug并调整部分样式

yangg 8 月之前
父节点
当前提交
1b26932a0a

+ 1 - 1
.env.development

@@ -2,5 +2,5 @@
 ENV = 'development'
 port = 8080
 # base api
-VUE_APP_BASE_API = 'http://58.246.234.210:8084'
+VUE_APP_BASE_API = 'http://192.168.1.200:8084'
 #192.168.1.199

文件差异内容过多而无法显示
+ 0 - 0
dist/index.html


文件差异内容过多而无法显示
+ 0 - 0
dist/static/css/app.242c7ebe.css


文件差异内容过多而无法显示
+ 0 - 0
dist/static/css/chunk-013c991d.6d459198.css


+ 1 - 0
dist/static/css/chunk-30d42db8.ace6ea25.css

@@ -0,0 +1 @@
+.midd-page[data-v-0a490a6a]{padding:20px}.el-icon-edit[data-v-0a490a6a]{font-size:14px;color:#409eff}

+ 0 - 1
dist/static/css/chunk-4c8a845d.8f6b9a72.css

@@ -1 +0,0 @@
-.header[data-v-0d32e408]{margin-left:20px}.header h2[data-v-0d32e408]{margin-bottom:0}.center[data-v-0d32e408]{margin:10px}.center[data-v-0d32e408] .el-form--inline .el-form-item{display:block}.center[data-v-0d32e408] .el-input-number--medium{width:150px}.footer[data-v-0d32e408]{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-pack:end;-ms-flex-pack:end;justify-content:flex-end;margin:0 100px 20px}

+ 1 - 0
dist/static/css/chunk-5769ee95.7ea8397f.css

@@ -0,0 +1 @@
+.header[data-v-eeb410b2]{margin-left:20px}.header h2[data-v-eeb410b2]{margin-bottom:0}.center[data-v-eeb410b2]{margin:10px}.center[data-v-eeb410b2] .el-form--inline .el-form-item{display:block}.center[data-v-eeb410b2] .el-input-number--medium{width:150px}.footer[data-v-eeb410b2]{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-pack:end;-ms-flex-pack:end;justify-content:flex-end;margin:0 100px 20px}

+ 0 - 1
dist/static/css/chunk-ec77a450.41449618.css

@@ -1 +0,0 @@
-.midd-page[data-v-374fa465]{padding:20px}.el-icon-edit[data-v-374fa465]{font-size:14px;color:#409eff}

文件差异内容过多而无法显示
+ 0 - 0
dist/static/js/app.45f5cfeb.js


文件差异内容过多而无法显示
+ 0 - 0
dist/static/js/app.dfb01286.js


文件差异内容过多而无法显示
+ 0 - 0
dist/static/js/chunk-013c991d.7b5257d7.js


+ 0 - 0
dist/static/js/chunk-05d6d838.4d242ace.js → dist/static/js/chunk-05d6d838.89db2932.js


文件差异内容过多而无法显示
+ 0 - 0
dist/static/js/chunk-30d42db8.24a40fd5.js


文件差异内容过多而无法显示
+ 0 - 0
dist/static/js/chunk-4c8a845d.9da913e6.js


文件差异内容过多而无法显示
+ 0 - 0
dist/static/js/chunk-5769ee95.d435ed4d.js


文件差异内容过多而无法显示
+ 0 - 0
dist/static/js/chunk-74c8073e.78b699c1.js


文件差异内容过多而无法显示
+ 0 - 0
dist/static/js/chunk-82c6794c.6a6d8d62.js


文件差异内容过多而无法显示
+ 0 - 0
dist/static/js/chunk-ec77a450.b7c6967a.js


+ 221 - 0
src/components/DataTable/index.vue

@@ -0,0 +1,221 @@
+<template>
+    <div>
+      <el-table :data="filteredTableData" style="width: 100%">
+        <el-table-column
+          label="工作类型"
+          prop="workType"
+          :filters="workTypeFilters"
+          :filter-method="filterWorkType"
+          filter-placement="bottom-end"
+        >
+          <template #default="scope">
+            <el-select
+              v-model="scope.row.workType"
+              placeholder="请选择"
+              v-if="scope.row.isEdit"
+            >
+              <el-option
+                v-for="filter in workTypeFilters"
+                :key="filter.value"
+                :label="filter.text"
+                :value="filter.value"
+              ></el-option>
+            </el-select>
+            <span v-else>{{ scope.row.workType }}</span>
+          </template>
+        </el-table-column>
+        <el-table-column
+          label="项目"
+          prop="project"
+          :filters="projectFilters"
+          :filter-method="filterProject"
+          filter-placement="bottom-end"
+        >
+          <template #default="scope">
+            <el-input
+              v-model="scope.row.project"
+              v-if="scope.row.isEdit"
+            ></el-input>
+            <span v-else>{{ scope.row.project }}</span>
+          </template>
+        </el-table-column>
+        <el-table-column label="说明" prop="description">
+          <template #default="scope">
+            <el-input
+              v-model="scope.row.description"
+              v-if="scope.row.isEdit"
+            ></el-input>
+            <span v-else>{{ scope.row.description }}</span>
+          </template>
+        </el-table-column>
+        <el-table-column label="范例" prop="example">
+          <template #default="scope">
+            <el-input
+              v-model="scope.row.example"
+              v-if="scope.row.isEdit"
+            ></el-input>
+            <span v-else>
+              {{ scope.row.example }}
+              <i
+                class="el-icon-edit"
+                @click="openExampleDialog(scope.row)"
+                style="cursor: pointer; margin-left: 5px"
+              ></i>
+            </span>
+          </template>
+        </el-table-column>
+        <el-table-column label="操作">
+          <template #default="scope">
+            <el-button
+              size="small"
+              @click="handleEdit(scope.$index, scope.row)"
+              v-if="!scope.row.isEdit"
+            >
+              编辑
+            </el-button>
+            <el-button
+              size="small"
+              type="success"
+              @click="handleSave(scope.$index, scope.row)"
+              v-else
+            >
+              保存
+            </el-button>
+            <el-button
+              size="small"
+              type="danger"
+              @click="handleDelete(scope.$index, scope.row)"
+            >
+              删除
+            </el-button>
+          </template>
+        </el-table-column>
+      </el-table>
+      <el-button type="primary" @click="handleAdd" style="margin-top: 20px"
+        >新增行</el-button
+      >
+  
+      <el-dialog :visible.sync="dialogVisible" title="编辑范例" width="30%">
+        <el-input v-model="currentExample" type="textarea" :rows="4"></el-input>
+        <template #footer>
+          <span class="dialog-footer">
+            <el-button @click="dialogVisible = false">取消</el-button>
+            <el-button type="primary" @click="saveExample">确定</el-button>
+          </span>
+        </template>
+      </el-dialog>
+    </div>
+  </template>
+  
+  <script>
+  export default {
+    name: "DataTable",
+    props: {
+      tableData: {
+        type: Array,
+        required: true,
+      },
+      workTypeFilters: {
+        type: Array,
+        required: true,
+      },
+    },
+    data() {
+      return {
+        localTableData: [...this.tableData],
+        projectFilters: [],
+        activeFilters: {
+          workType: [],
+          project: [],
+        },
+        dialogVisible: false,
+        currentExample: "",
+        currentRow: null,
+      };
+    },
+    computed: {
+      filteredTableData() {
+        return this.localTableData.filter((data) => {
+          return (
+            (!this.activeFilters.workType.length ||
+              this.activeFilters.workType.includes(data.workType)) &&
+            (!this.activeFilters.project.length ||
+              this.activeFilters.project.includes(data.project))
+          );
+        });
+      },
+    },
+    created() {
+      this.updateProjectFilters();
+    },
+    methods: {
+      openExampleDialog(row) {
+        this.dialogVisible = true;
+        this.currentExample = row.example;
+        this.currentRow = row;
+      },
+      saveExample() {
+        if (this.currentRow) {
+          this.currentRow.example = this.currentExample;
+        }
+        this.dialogVisible = false;
+        this.emitUpdate();
+      },
+      handleEdit(index, row) {
+        row.isEdit = true;
+      },
+      handleSave(index, row) {
+        row.isEdit = false;
+        this.updateProjectFilters();
+        this.emitUpdate();
+      },
+      handleDelete(index, row) {
+        this.localTableData.splice(index, 1);
+        this.updateProjectFilters();
+        this.emitUpdate();
+      },
+      handleAdd() {
+        this.localTableData.push({
+          workType: "",
+          project: "",
+          description: "",
+          example: "",
+          isEdit: true,
+        });
+        this.emitUpdate();
+      },
+      filterWorkType(value, row) {
+        return row.workType === value;
+      },
+      filterProject(value, row) {
+        return row.project === value;
+      },
+      updateProjectFilters() {
+        const projects = [...new Set(this.localTableData.map((item) => item.project))];
+        this.projectFilters = projects.map((project) => ({
+          text: project,
+          value: project,
+        }));
+      },
+      emitUpdate() {
+        this.$emit('update-table', this.localTableData);
+      },
+    },
+    watch: {
+      tableData: {
+        handler(newValue) {
+          this.localTableData = [...newValue];
+          this.updateProjectFilters();
+        },
+        deep: true,
+      },
+    },
+  };
+  </script>
+  
+  <style scoped>
+  .el-icon-edit {
+    font-size: 14px;
+    color: #409eff;
+  }
+  </style>

+ 45 - 23
src/components/FilePreview/index.vue

@@ -18,9 +18,13 @@
       />
 
       <!-- Word 文档预览 -->
-      <div v-if="isWord && wordLoaded" v-html="wordContent" class="word-preview"></div>
+      <div
+        v-if="isWord && wordLoaded"
+        v-html="wordContent"
+        class="word-preview"
+      ></div>
       <div v-else-if="isWord && !wordLoaded" class="loading-word">
-        {{ wordLoadingError ? '加载失败,请重试' : '加载中...' }}
+        {{ wordLoadingError ? "加载失败,请重试" : "加载中..." }}
       </div>
 
       <!-- 其他 Office 文档预览 -->
@@ -45,6 +49,7 @@
 </template>
   
   <script>
+  import { searchTaskInfo } from "@/api/knowledge";
 import mammoth from "mammoth";
 export default {
   props: {
@@ -77,12 +82,14 @@ export default {
       ],
       wordLoaded: false,
       wordLoadingError: false,
+      internalFileUrl: '', // 新增:内部使用的 URL
     };
   },
   watch: {
     fileUrl: {
       immediate: true,
-      handler() {
+      handler(newValue) {
+        /* this.internalFileUrl = newValue; */
         if (this.isWord) {
           this.loadWordContent();
         }
@@ -112,27 +119,42 @@ export default {
   },
   methods: {
     async loadWordContent() {
-      this.wordLoaded = false;
-      this.wordLoadingError = false;
-      this.fileUrl=localStorage.getItem('href')
-      try {
-        const response = await fetch(this.fileUrl);
-        if (!response.ok) {
-          throw new Error(`HTTP error! status: ${response.status}`);
-        }
-        const blob = await response.blob();
-        const arrayBuffer = await this.blobToArrayBuffer(blob);
-        const result = await mammoth.convertToHtml({ arrayBuffer });
-        this.wordContent = result.value;
-        this.wordLoaded = true;
-      } catch (error) {
-        console.error("加载Word文档内容时出错:", error);
-        this.wordContent = "无法加载Word文档内容";
-        this.wordLoadingError = true;
-      } finally {
-        this.wordLoaded = true;
+    this.wordLoaded = false;
+    this.wordLoadingError = false;
+    try {
+      // 获取文档 URL
+      const res = await searchTaskInfo({
+        page: 1,
+        page_size: 10,
+        document_id: this.$route.query.id,
+      });
+      this.internalFileUrl = res.data.documentUrl;
+
+      // 使用 fetch 获取文件内容,指定 responseType 为 'arraybuffer'
+      const response = await fetch(this.internalFileUrl, {
+        method: 'GET',
+        headers: {
+          'Content-Type': 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
+        },
+      });
+
+      if (!response.ok) {
+        throw new Error(`HTTP error! status: ${response.status}`);
       }
-    },
+
+      const arrayBuffer = await response.arrayBuffer();
+      const result = await mammoth.convertToHtml({ arrayBuffer });
+      this.wordContent = result.value;
+      this.wordLoaded = true;
+    } catch (error) {
+      console.error("加载Word文档内容时出错:", error);
+      this.wordContent = `无法加载Word文档内容: ${error.message}`;
+      this.wordLoadingError = true;
+      this.$message.error(`文档加载失败: ${error.message}`);
+    } finally {
+      this.wordLoaded = true;
+    }
+  },
     blobToArrayBuffer(blob) {
       return new Promise((resolve, reject) => {
         const reader = new FileReader();

+ 2 - 2
src/components/ai.vue

@@ -312,8 +312,8 @@ export default {
           });
           const result = await response.json();
           this.session_id = result.data.session_id;
-          console.log(result.status);
-          if (result.status !== "success") {
+          console.log(result);
+          if (result.code !== 200) {
             const errorText = await response.text(); // 获取错误文本
             throw new Error(
               `HTTP error! status: ${response.status}, message: ${errorText}`

+ 36 - 13
src/components/chartIcon/index.vue

@@ -1,9 +1,9 @@
 <template>
   <div class="chat-icon" @click="toggleChat">
-    <i class="el-icon-chat-dot-round"></i>
-    <div v-if="showChat" class="chat-window">
+    <i class="el-icon-chat-dot-round animate-pulse"></i>
+    <div v-if="$store.state.app.showChat" class="chat-window">
       <div class="chat-header">
-        <i class="el-icon-close close-icon" @click.stop="closeChat"></i>
+        <i class="el-icon-minus close-icon" @click.stop="closeChat"></i>
       </div>
       <ChatBox />
     </div>
@@ -32,9 +32,11 @@ export default {
 
   methods: {
     toggleChat() {
+      this.$store.state.app.showChat= true;
       this.showChat = true;
     },
     closeChat() {
+      this.$store.state.app.showChat= false;
       this.showChat = false;
     },
   },
@@ -58,12 +60,27 @@ export default {
 .el-icon-chat-dot-round {
   color: white;
 }
+@keyframes pulse {
+  0% {
+    transform: scale(1);
+  }
+  50% {
+    transform: scale(1.1);
+  }
+  100% {
+    transform: scale(1);
+  }
+}
+
+.animate-pulse {
+  animation: pulse 1.5s infinite ease-in-out;
+}
 .chat-window {
   position: absolute;
   bottom: 60px;
   right: 0;
   width: 500px;
-  height: 600px;
+  height: 625px;
   background-color: white;
   border: 1px solid #dcdfe6;
   border-radius: 4px;
@@ -108,13 +125,19 @@ export default {
 .chat-input {
   margin-top: 10px;
 }
-::v-deep .messages{
-    height: calc(100vh - 515px);
-}
-::v-deep .input-container{
-    left: 50%;
-}
-::v-deep .sender-name{
-    font-size: 14px;
-}
+::v-deep .chat-container .content{
+    flex-direction: column;
+  }
+  ::v-deep .messages{
+      height:445px; /* calc(100vh - 500px); */
+  }
+  ::v-deep .input-container{
+    margin: 0 auto;
+    position: unset;
+      left: 50%;
+      transform: translateX(0%);
+  }
+  ::v-deep .sender-name{
+      font-size: 14px;
+  }
 </style>

+ 1 - 1
src/components/webAi/index.vue

@@ -467,7 +467,7 @@
                 v-for="(count, type) in card.knowledge_base_names"
                 :key="type"
                 class="knowledge-base-name"
-                >{{ count }}</span
+                >{{ getKnowledgeBaseName(count) }}</span
               >
             </div>
           </div>

+ 5 - 1
src/components/webAi/js/ChatBox.js

@@ -187,6 +187,10 @@ export default {
     }
   },
   methods: {
+    getKnowledgeBaseName(kbId) {
+      const kb = this.kneList.find(kb => kb.id === kbId);
+      return kb ? kb.name : kbId;
+    },
     /* 检索知识库名称 */
     getKnowledgeBaseNamesForView(knowledgeBaseIds) {
       return knowledgeBaseIds.map(id => {
@@ -850,7 +854,7 @@ newChat() {
           const result = await response.json();
           this.session_id=result.data.session_id
           console.log(result.status);
-          if (result.status!=='success') {
+          if (result.code !== 200) {
             const errorText = await response.text(); // 获取错误文本
             throw new Error(
               `HTTP error! status: ${response.status}, message: ${errorText}`

+ 4 - 3
src/layout/components/Navbar.vue

@@ -44,9 +44,9 @@
         </el-dropdown-menu>
       </el-dropdown>
     </div>
-    <el-dialog  :close-on-click-modal="false" top="20px" width="80%" :visible.sync="chatDialogVisible" append-to-body v-el-drag-dialog>
+    <!-- <el-dialog  :close-on-click-modal="false" top="20px" width="80%" :visible.sync="chatDialogVisible" append-to-body v-el-drag-dialog>
       <ChatBox />
-    </el-dialog>
+    </el-dialog> -->
   </div>
 </template>
 
@@ -69,7 +69,7 @@ export default {
     Screenfull,
     SizeSelect,
     Search,
-    ChatBox,
+    ChatBox
   },
   directives: { elDragDialog },
   data() {
@@ -82,6 +82,7 @@ export default {
   },
   methods: {
     openChatDialog() {
+      this.$store.state.app.showChat= true;
       this.chatDialogVisible = true;
       /* this.$router.push({
         path: "/knowledge/chatPage/index",

+ 8 - 1
src/store/modules/app.js

@@ -6,7 +6,8 @@ const state = {
     withoutAnimation: false
   },
   device: 'desktop',
-  size: Cookies.get('size') || 'small'
+  size: Cookies.get('size') || 'small',
+  showChat:false
 }
 
 const mutations = {
@@ -30,6 +31,9 @@ const mutations = {
   SET_SIZE: (state, size) => {
     state.size = size
     Cookies.set('size', size)
+  },
+  SET_showChat:(state,chat)=>{
+    console.log(state,chat);
   }
 }
 
@@ -45,6 +49,9 @@ const actions = {
   },
   setSize({ commit }, size) {
     commit('SET_SIZE', size)
+  },
+  showChat({ commit }, chat){
+    commit('SET_showChat', chat)
   }
 }
 

+ 115 - 23
src/views/appConfig/index.vue

@@ -115,7 +115,9 @@
                 :disabled="isDocumentSelectDisabled"
                 clearable
                 filterable
+                @change="handleDocumentChange"
               >
+                <el-option label="全部" value="all"></el-option>
                 <el-option
                   v-for="(doc, index) in documentList"
                   :label="doc.name"
@@ -274,7 +276,7 @@
               <div class="hint">AI考虑的上下文token数量</div>
             </el-form-item>
           </el-col>
-          <el-col :span="12">
+          <!-- <el-col :span="12">
             <el-form-item label="会话ID:" prop="session_id">
               <el-input
                 style="width: 55%"
@@ -283,7 +285,7 @@
               ></el-input>
               <div class="hint">特定会话的唯一标识符,如果有的话</div>
             </el-form-item>
-          </el-col>
+          </el-col> -->
         </el-row>
         <el-row :gutter="24">
           <el-col :span="12">
@@ -531,7 +533,9 @@
                 :disabled="editForm.document_directories == ''"
                 clearable
                 filterable
+                @change="handleEditDocumentChange"
               >
+                <el-option label="全部" value="all"></el-option>
                 <el-option
                   v-for="(doc, index) in editDocumentList"
                   :label="doc.name"
@@ -690,7 +694,7 @@
               <div class="hint">AI考虑的上下文token数量</div>
             </el-form-item>
           </el-col>
-          <el-col :span="12">
+          <!-- <el-col :span="12">
             <el-form-item label="会话ID:" prop="session_id">
               <el-input
                 style="width: 55%"
@@ -699,7 +703,7 @@
               ></el-input>
               <div class="hint">特定会话的唯一标识符,如果有的话</div>
             </el-form-item>
-          </el-col>
+          </el-col> -->
         </el-row>
         <el-row :gutter="24">
           <el-col :span="12">
@@ -1117,7 +1121,7 @@
               <div class="hint">AI考虑的上下文token数量</div>
             </el-form-item>
           </el-col>
-          <el-col :span="12">
+          <!-- <el-col :span="12">
             <el-form-item label="会话ID:" prop="session_id">
               <el-input
                 disabled
@@ -1127,7 +1131,7 @@
               ></el-input>
               <div class="hint">特定会话的唯一标识符,如果有的话</div>
             </el-form-item>
-          </el-col>
+          </el-col> -->
         </el-row>
         <el-row :gutter="24">
           <el-col :span="12">
@@ -1314,7 +1318,7 @@ export default {
         role_description: "",
         role_permissions: "",
         custom_variables: "",
-        custom_prompt: "",
+        custom_prompt: "使用以下上下文来回答问题。如果你不知道答案,就说你不知道,不要试图编造答案。上下文: {context} 人类: {question}AI助手: 让我根据提供的上下文来回答你的问题。{custom_greeting}",
         application_type: "",
         is_default: false,
         generate_new_api_key: true,
@@ -1380,7 +1384,7 @@ export default {
         role_description: "",
         role_permissions: "",
         custom_variables: "",
-        custom_prompt: "",
+        custom_prompt: "使用以下上下文来回答问题。如果你不知道答案,就说你不知道,不要试图编造答案。上下文: {context} 人类: {question}AI助手: 让我根据提供的上下文来回答你的问题。{custom_greeting}",
         application_type: "",
         is_default: false,
         generate_new_api_key: true,
@@ -1412,7 +1416,7 @@ export default {
         role_description: "",
         role_permissions: "",
         custom_variables: "",
-        custom_prompt: "",
+        custom_prompt: "使用以下上下文来回答问题。如果你不知道答案,就说你不知道,不要试图编造答案。上下文: {context} 人类: {question}AI助手: 让我根据提供的上下文来回答你的问题。{custom_greeting}",
         application_type: "",
         is_default: false,
         generate_new_api_key: true,
@@ -1462,9 +1466,10 @@ export default {
     this.init();
     this.type = this.$route.query.type;
     this.id = this.$route.query.id;
-    if (this.type == "edit") {
-      this.initEdit();
-    } else if (this.type == "view") {
+    /* if (this.type == "edit") {
+       this.initEdit();
+     
+    } else */ if (this.type == "view") {
       this.initView();
     }
   },
@@ -1472,16 +1477,39 @@ export default {
   /*组件方法*/
   methods: {
     /* 编辑 */
+    handleEditDocumentChange(selectedValues) {
+      if (selectedValues.includes("all")) {
+        // 如果选择了"全部",则清空其他选项
+        this.editForm.documents = ["all"];
+      } else {
+        // 如果没有选择"全部",则限制最多选择10个文档
+        if (selectedValues.length > 10) {
+          this.editForm.documents = selectedValues.slice(0, 10);
+          this.$message.warning("最多只能选择10个文档");
+        }
+      }
+    },
     /* 编辑确认修改 */
     submitEdit() {
       this.$refs.editFormRef.validate(async (valid) => {
         if (valid) {
           try {
             const convertedForm = { ...this.editForm };
-            console.log(this.editForm);
             // 转换知识库、文档目录和文档的ID为名称
             /*  convertedForm.knowledge_base_names = this.safeGetNamesByIds(this.editForm.knowledge_base_names, this.kneList); */
             /*  convertedForm.documents = this.safeGetNamesByIds(this.editForm.documents, this.editDocumentList); */
+            // 处理文档选择
+            if (
+              convertedForm.documents.includes("all") ||
+              convertedForm.documents.length === 0
+            ) {
+              convertedForm.documents = []; // 全选或未选择时传空数组给后台
+            } else {
+              convertedForm.documents = this.safeGetNamesByIds(
+                convertedForm.documents,
+                this.editDocumentList
+              );
+            }
             convertedForm.document_directories = this.safeGetNamesByIds(
               this.editForm.document_directories,
               this.editDirectoryList
@@ -1652,7 +1680,7 @@ export default {
         role_description: "",
         role_permissions: "",
         custom_variables: "",
-        custom_prompt: "",
+        custom_prompt: "使用以下上下文来回答问题。如果你不知道答案,就说你不知道,不要试图编造答案。上下文: {context} 人类: {question}AI助手: 让我根据提供的上下文来回答你的问题。{custom_greeting}",
         application_type: "",
         is_default: false,
         generate_new_api_key: true,
@@ -1676,6 +1704,18 @@ export default {
           .catch((_) => {});
       }
     },
+    handleDocumentChange(selectedValues) {
+      if (selectedValues.includes("all")) {
+        // 如果选择了"全部",则清空其他选项
+        this.AIform.documents = ["all"];
+      } else {
+        // 如果没有选择"全部",则限制最多选择10个文档
+        if (selectedValues.length > 10) {
+          this.AIform.documents = selectedValues.slice(0, 10);
+          this.$message.warning("最多只能选择10个文档");
+        }
+      }
+    },
     /* 新增聊天应用 */
     generateApplication() {
       this.$refs.AIformRef.validate(async (valid) => {
@@ -1685,16 +1725,28 @@ export default {
             const convertedForm = { ...this.AIform };
 
             // 将知识库 ID 转换为名称
-            convertedForm.knowledge_base_names = this.safeGetNamesByIds(
+            /* convertedForm.knowledge_base_names = this.safeGetNamesByIds(
               this.AIform.knowledge_base_names,
               this.kneList
-            );
+            ); */
 
-            // 将文档 ID 转换为名称
+            /* // 将文档 ID 转换为名称
             convertedForm.documents = this.safeGetNamesByIds(
               this.AIform.documents,
               this.documentList
-            );
+            ); */
+            // 处理文档选择
+            if (
+              convertedForm.documents.includes("all") ||
+              convertedForm.documents.length === 0
+            ) {
+              convertedForm.documents = []; // 全选或未选择时传空数组给后台
+            } else {
+              convertedForm.documents = this.safeGetNamesByIds(
+                convertedForm.documents,
+                this.documentList
+              );
+            }
 
             // 将文档目录 ID 转换为名称,如果为空则传递 '全部'
             convertedForm.document_directories = this.safeGetNamesByIds(
@@ -1851,6 +1903,9 @@ export default {
       /* 知识库 */
       listBuckets({ user_id: this.$store.state.user.id }).then((res) => {
         this.kneList = res.data;
+        if (this.$route.query.type == "edit") {
+          this.initEdit();
+        }
       });
       /* 应用列表 */
       configList().then((res) => {
@@ -1869,12 +1924,12 @@ export default {
       this.editForm = JSON.parse(JSON.stringify(this.$route.query.card)); // 深拷贝以避免直接修改原对象
 
       // 处理 knowledge_base_names
-      this.editForm.knowledge_base_names =
+      /* this.editForm.knowledge_base_names =
         this.editForm.knowledge_base_names.map((name) => {
-          const kb = this.kneList.find((kb) => kb.name === name);
+          const kb = this.kneList.find((kb) => kb.name == name);
+          console.log(this.kneList);
           return kb ? kb.id : name; // 如果找不到对应的知识库,保留原名称
-        });
-
+        }); */
       // 处理 role_permissions
       if (this.editForm.role_permissions) {
         if (typeof this.editForm.role_permissions !== "string") {
@@ -1901,7 +1956,34 @@ export default {
       }
 
       // 加载知识库对应的目录列表
-      this.loadEditDirectoryList(this.editForm.knowledge_base_names);
+      this.loadEditDirectoryList(this.editForm.knowledge_base_names).then(
+        () => {
+          // 在目录列表加载完成后,设置选中的目录
+          if (
+            this.editForm.document_directories &&
+            this.editForm.document_directories.length > 0
+          ) {
+            const dirId = this.editDirectoryList.find(
+              (dir) => dir.name === this.editForm.document_directories[0]
+            )?.id;
+            if (dirId) {
+              this.editForm.document_directories = dirId;
+              // 加载文档列表
+              this.loadEditDocumentList(dirId).then(() => {
+                // 在文档列表加载完成后,设置选中的文档
+                if (
+                  this.editForm.documents &&
+                  this.editForm.documents.length > 0
+                ) {
+                  this.editForm.documents = this.editDocumentList
+                    .filter((doc) => this.editForm.documents.includes(doc.name))
+                    .map((doc) => doc.id);
+                }
+              });
+            }
+          }
+        }
+      );
       /* this.loadEditDocumentList(this.editForm.document_directories[0]); */
     },
     /* 查看 */
@@ -1941,6 +2023,16 @@ export default {
         this.viewForm.custom_variables = "";
       }
 
+      /* // 处理文档选择
+       if (this.editForm.documents.length === 0 || this.editForm.documents.includes('全部')) {
+        this.editForm.documents = ['all'];
+      } else {
+        // 将文档名称转换为ID
+        this.editForm.documents = this.editForm.documents.map(docName => {
+          const doc = this.editDocumentList.find(d => d.name === docName);
+          return doc ? doc.id : docName;
+        });
+      } */
       // 加载知识库对应的目录列表
       this.loadEditDirectoryList(this.viewForm.knowledge_base_names);
     },

+ 9 - 8
src/views/knowledgeMenu/category/knowledgeSet.vue

@@ -88,6 +88,7 @@
             label="文件名称"
             align="center"
             sortable="custom"
+            width="300"
           >
             <template #default="scope">
               <span>{{ scope.row.name }}</span>
@@ -111,7 +112,7 @@
               <div v-if="scope.row.run == 6">文件异常</div>
             </template>
           </el-table-column>
-          <el-table-column label="操作" align="center" width="330">
+          <el-table-column label="操作" align="center" width="300">
             <template #default="scope">
               <div>
                 <el-tooltip
@@ -126,7 +127,7 @@
                     circle
                     icon="el-icon-view"
                     v-if="checkAuth('/document/update')"
-                    style="font-size: 20px"
+                    style="font-size: 15px;"
                     @click="getName(scope.row)"
                   ></el-button
                 ></el-tooltip>
@@ -144,7 +145,7 @@
                     icon="el-icon-caret-right"
                     circle
                     @click="analysis(scope.row)"
-                    style="font-size: 20px"
+                    style="font-size: 15px;"
                   >
                   </el-button>
                   <el-button
@@ -153,7 +154,7 @@
                     icon="el-icon-loading"
                     circle
                     :disabled="true"
-                    style="font-size: 20px"
+                    style="font-size: 15px;"
                   >
                   </el-button>
                 </el-tooltip>
@@ -169,7 +170,7 @@
                     circle
                     icon="el-icon-tickets"
                     v-if="checkAuth('/document/update')"
-                    style="font-size: 20px"
+                    style="font-size: 15px;"
                     @click="Analytical(scope.row)"
                   ></el-button
                 ></el-tooltip>
@@ -185,7 +186,7 @@
                     circle
                     icon="el-icon-edit"
                     v-if="checkAuth('/document/update')"
-                    style="font-size: 20px"
+                    style="font-size: 15px;"
                     @click="btnEdit(scope.row)"
                   ></el-button
                 ></el-tooltip>
@@ -202,7 +203,7 @@
                     icon="el-icon-download"
                     @click="btnDown(scope.row)"
                     :loading="scope.row.downloading"
-                    style="font-size: 20px"
+                    style="font-size: 15px;"
                   ></el-button
                 ></el-tooltip>
                 <el-tooltip
@@ -218,7 +219,7 @@
                     icon="el-icon-delete"
                     v-if="checkAuth('/document/delete')"
                     @click="btnDelete(scope.row.id)"
-                    style="font-size: 20px"
+                    style="font-size: 15px;"
                   ></el-button
                 ></el-tooltip>
               </div>

+ 214 - 143
src/views/middPage/index.vue

@@ -1,65 +1,105 @@
 <template>
-    <div class="midd-page">
-      <el-table :data="filteredTableData" style="width: 100%">
-        <el-table-column
-          label="工作类型"
-          prop="workType"
-          :filters="workTypeFilters"
-          :filter-method="filterWorkType"
-          filter-placement="bottom-end"
-        >
-          <template #default="scope">
-            <el-select v-model="scope.row.workType" placeholder="请选择" v-if="scope.row.isEdit">
-              <el-option label="类型1" value="type1"></el-option>
-              <el-option label="类型2" value="type2"></el-option>
-              <el-option label="类型3" value="type3"></el-option>
-            </el-select>
-            <span v-else>{{ scope.row.workType }}</span>
-          </template>
-        </el-table-column>
-        <el-table-column
-          label="项目"
-          prop="project"
-          :filters="projectFilters"
-          :filter-method="filterProject"
-          filter-placement="bottom-end"
-        >
-          <template #default="scope">
-            <el-input v-model="scope.row.project" v-if="scope.row.isEdit"></el-input>
-            <span v-else>{{ scope.row.project }}</span>
-          </template>
-        </el-table-column>
-        <el-table-column label="说明" prop="description">
-          <template #default="scope">
-            <el-input v-model="scope.row.description" v-if="scope.row.isEdit"></el-input>
-            <span v-else>{{ scope.row.description }}</span>
-          </template>
-        </el-table-column>
-        <el-table-column label="范例" prop="example">
-          <template #default="scope">
-            <el-input v-model="scope.row.example" v-if="scope.row.isEdit"></el-input>
-            <span v-else>
+  <div class="midd-page">
+    <el-tabs v-model="activeName" @tab-click="handleClick">
+      <el-tab-pane label="AED数据表" name="first">
+        <el-table :data="filteredTableData" style="width: 100%">
+          <el-table-column
+            label="工作类型"
+            prop="workType"
+            :filters="workTypeFilters"
+            :filter-method="filterWorkType"
+            filter-placement="bottom-end"
+          >
+            <template #default="scope">
+              <el-select
+                v-model="scope.row.workType"
+                placeholder="请选择"
+                v-if="scope.row.isEdit"
+              >
+                <el-option label="类型1" value="type1"></el-option>
+                <el-option label="类型2" value="type2"></el-option>
+                <el-option label="类型3" value="type3"></el-option>
+              </el-select>
+              <span v-else>{{ scope.row.workType }}</span>
+            </template>
+          </el-table-column>
+          <el-table-column
+            label="项目"
+            prop="project"
+            :filters="projectFilters"
+            :filter-method="filterProject"
+            filter-placement="bottom-end"
+          >
+            <template #default="scope">
+              <el-input
+                v-model="scope.row.project"
+                v-if="scope.row.isEdit"
+              ></el-input>
+              <span v-else>{{ scope.row.project }}</span>
+            </template>
+          </el-table-column>
+          <el-table-column label="说明" prop="description">
+            <template #default="scope">
+              <el-input
+                v-model="scope.row.description"
+                v-if="scope.row.isEdit"
+              ></el-input>
+              <span v-else>{{ scope.row.description }}</span>
+            </template>
+          </el-table-column>
+          <el-table-column label="范例" prop="example">
+            <template #default="scope">
+              <el-input
+                v-model="scope.row.example"
+                v-if="scope.row.isEdit"
+              ></el-input>
+              <span v-else>
                 {{ scope.row.example }}
-                <i class="el-icon-edit" @click="openExampleDialog(scope.row)" style="cursor: pointer; margin-left: 5px;"></i>
-            </span>
-          </template>
-        </el-table-column>
-        <el-table-column label="操作">
-          <template #default="scope">
-            <el-button size="small" @click="handleEdit(scope.$index, scope.row)" v-if="!scope.row.isEdit">
-              编辑
-            </el-button>
-            <el-button size="small" type="success" @click="handleSave(scope.$index, scope.row)" v-else>
-              保存
-            </el-button>
-            <el-button size="small" type="danger" @click="handleDelete(scope.$index, scope.row)">
-              删除
-            </el-button>
-          </template>
-        </el-table-column>
-      </el-table>
-      <el-button type="primary" @click="handleAdd" style="margin-top: 20px;">新增行</el-button>
-      <el-dialog :visible.sync="dialogVisible" title="编辑范例" width="30%">
+                <i
+                  class="el-icon-edit"
+                  @click="openExampleDialog(scope.row)"
+                  style="cursor: pointer; margin-left: 5px"
+                ></i>
+              </span>
+            </template>
+          </el-table-column>
+          <el-table-column label="操作">
+            <template #default="scope">
+              <el-button
+                size="small"
+                @click="handleEdit(scope.$index, scope.row)"
+                v-if="!scope.row.isEdit"
+              >
+                编辑
+              </el-button>
+              <el-button
+                size="small"
+                type="success"
+                @click="handleSave(scope.$index, scope.row)"
+                v-else
+              >
+                保存
+              </el-button>
+              <el-button
+                size="small"
+                type="danger"
+                @click="handleDelete(scope.$index, scope.row)"
+              >
+                删除
+              </el-button>
+            </template>
+          </el-table-column>
+        </el-table>
+        <el-button type="primary" @click="handleAdd" style="margin-top: 20px"
+          >新增行</el-button
+        >
+      </el-tab-pane>
+      <el-tab-pane label="SOTA数据表" name="second"></el-tab-pane>
+      <el-tab-pane label="SOTA内容表" name="third"></el-tab-pane>
+      <el-tab-pane label="SOTA汇总表" name="fourth"></el-tab-pane>
+    </el-tabs>
+
+    <el-dialog :visible.sync="dialogVisible" title="编辑范例" width="30%">
       <el-input v-model="currentExample" type="textarea" :rows="4"></el-input>
       <template #footer>
         <span class="dialog-footer">
@@ -68,48 +108,76 @@
         </span>
       </template>
     </el-dialog>
-    </div>
-  </template>
+  </div>
+</template>
   
   <script>
-  export default {
-    name: 'MiddPage',
-    data() {
-      return {
-        tableData: [
-          { workType: '复制', project: 'indication', description: '器械在文献中使用的适应症,按照器械分析,也需要添加器械使用部位以区分', example: 't1d: n=191;', isEdit: false },
-          { workType: '总结', project: 'Study Design/ Method', description: '患者/试验者的人种,国家地区,以查阅是否存在数据上人种差异', example: 'white non-hispanic: n=247;african american:n=25;hispanic or latino: n=34', isEdit: false },
-          { workType: '总结和数据提取;', project: 'Alternative device(treatment)', description: 'Device name + model name如无,可写疗法(以评价的器械的替代疗法)', example: 'Capillary blood by BMG;Venous blood by YSI(此处为CGM的替代疗法)', isEdit: false },
-        ],
-        workTypeFilters: [
-          { text: '类型1', value: 'type1' },
-          { text: '类型2', value: 'type2' },
-          { text: '类型3', value: 'type3' },
-        ],
-        projectFilters: [],
-        activeFilters: {
-          workType: [],
-          project: [],
+export default {
+  name: "MiddPage",
+  data() {
+    return {
+      activeName: "first",
+      tableData: [
+        {
+          workType: "复制",
+          project: "indication",
+          description:
+            "器械在文献中使用的适应症,按照器械分析,也需要添加器械使用部位以区分",
+          example: "t1d: n=191;",
+          isEdit: false,
         },
-        dialogVisible: false,
-      currentExample: '',
-      currentRow: null,
-      }
-    },
-    computed: {
-      filteredTableData() {
-        return this.tableData.filter(data => {
-          return (!this.activeFilters.workType.length || this.activeFilters.workType.includes(data.workType)) &&
-                 (!this.activeFilters.project.length || this.activeFilters.project.includes(data.project));
-        });
+        {
+          workType: "总结",
+          project: "Study Design/ Method",
+          description:
+            "患者/试验者的人种,国家地区,以查阅是否存在数据上人种差异",
+          example:
+            "white non-hispanic: n=247;african american:n=25;hispanic or latino: n=34",
+          isEdit: false,
+        },
+        {
+          workType: "总结和数据提取;",
+          project: "Alternative device(treatment)",
+          description:
+            "Device name + model name如无,可写疗法(以评价的器械的替代疗法)",
+          example:
+            "Capillary blood by BMG;Venous blood by YSI(此处为CGM的替代疗法)",
+          isEdit: false,
+        },
+      ],
+      workTypeFilters: [
+        { text: "类型1", value: "type1" },
+        { text: "类型2", value: "type2" },
+        { text: "类型3", value: "type3" },
+      ],
+      projectFilters: [],
+      activeFilters: {
+        workType: [],
+        project: [],
       },
+      dialogVisible: false,
+      currentExample: "",
+      currentRow: null,
+    };
+  },
+  computed: {
+    filteredTableData() {
+      return this.tableData.filter((data) => {
+        return (
+          (!this.activeFilters.workType.length ||
+            this.activeFilters.workType.includes(data.workType)) &&
+          (!this.activeFilters.project.length ||
+            this.activeFilters.project.includes(data.project))
+        );
+      });
     },
-    created() {
-      this.updateProjectFilters();
-    },
-    methods: {
-        openExampleDialog(row) {
-            console.log(112);
+  },
+  created() {
+    this.updateProjectFilters();
+  },
+  methods: {
+    openExampleDialog(row) {
+      console.log(112);
       this.dialogVisible = true;
       this.currentExample = row.example;
       this.currentRow = row;
@@ -120,56 +188,59 @@
       }
       this.dialogVisible = false;
     },
-      handleEdit(index, row) {
-        row.isEdit = true;
-      },
-      handleSave(index, row) {
-        row.isEdit = false;
-        this.updateProjectFilters();
-        // 在这里可以添加保存到后端的逻辑
-      },
-      handleDelete(index, row) {
-        this.tableData.splice(index, 1);
+    handleEdit(index, row) {
+      row.isEdit = true;
+    },
+    handleSave(index, row) {
+      row.isEdit = false;
+      this.updateProjectFilters();
+      // 在这里可以添加保存到后端的逻辑
+    },
+    handleDelete(index, row) {
+      this.tableData.splice(index, 1);
+      this.updateProjectFilters();
+      // 在这里可以添加从后端删除的逻辑
+    },
+    handleAdd() {
+      this.tableData.push({
+        workType: "",
+        project: "",
+        description: "",
+        example: "",
+        isEdit: true,
+      });
+    },
+    filterWorkType(value, row) {
+      return row.workType === value;
+    },
+    filterProject(value, row) {
+      return row.project === value;
+    },
+    updateProjectFilters() {
+      const projects = [...new Set(this.tableData.map((item) => item.project))];
+      this.projectFilters = projects.map((project) => ({
+        text: project,
+        value: project,
+      }));
+    },
+  },
+  watch: {
+    tableData: {
+      handler() {
         this.updateProjectFilters();
-        // 在这里可以添加从后端删除的逻辑
-      },
-      handleAdd() {
-        this.tableData.push({
-          workType: '',
-          project: '',
-          description: '',
-          example: '',
-          isEdit: true
-        });
-      },
-      filterWorkType(value, row) {
-        return row.workType === value;
-      },
-      filterProject(value, row) {
-        return row.project === value;
-      },
-      updateProjectFilters() {
-        const projects = [...new Set(this.tableData.map(item => item.project))];
-        this.projectFilters = projects.map(project => ({ text: project, value: project }));
       },
+      deep: true,
     },
-    watch: {
-      tableData: {
-        handler() {
-          this.updateProjectFilters();
-        },
-        deep: true
-      }
-    }
-  }
-  </script>
+  },
+};
+</script>
   
   <style scoped>
-  .midd-page {
-    padding: 20px;
-  }
-  .el-icon-edit {
+.midd-page {
+  padding: 20px;
+}
+.el-icon-edit {
   font-size: 14px;
-  color: #409EFF;
+  color: #409eff;
 }
-  </style>
+</style>

部分文件因为文件数量过多而无法显示